Uploaded image for project: 'Lustre'
  1. Lustre
  2. LU-2880

ldiskfs getdents() returns invalid d_types

Details

    • Bug
    • Resolution: Fixed
    • Minor
    • Lustre 2.6.0
    • Lustre 2.4.0
    • 3
    • 6955

    Description

      Note this is not a bug in lustre but in ldisks as a top level filesystem. The d_types returned have an extra bit set (perhaps from putting FIDs in dirents). The most annoying symptom of this is that it breaks find.

      # llmount.sh
      ...
      # mkdir -p /mnt/lustre/D/D/D/D/D/D
      # touch /mnt/lustre/D/D/D/D/D/D/XXX
      # find /mnt/lustre
      /mnt/lustre
      /mnt/lustre/.lustre
      /mnt/lustre/D
      /mnt/lustre/D/D
      /mnt/lustre/D/D/D
      /mnt/lustre/D/D/D/D
      /mnt/lustre/D/D/D/D/D
      /mnt/lustre/D/D/D/D/D/D
      /mnt/lustre/D/D/D/D/D/D/XXX
      # umount /mnt/lustre /mnt/mds1
      #
      # mount /tmp/lustre-mdt1 /mnt/mds1 -t ldiskfs -o loop,ro
      # find /mnt/mds1/ROOT -name XXX
      # stat /mnt/mds1/ROOT/D/D/D/D/D/D/XXX
        File: `/mnt/mds1/ROOT/D/D/D/D/D/D/XXX'
        Size: 0               Blocks: 0          IO Block: 4096   regular empty file
      Device: 700h/1792d      Inode: 111         Links: 1
      Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
      Access: 2013-02-26 21:37:51.000000000 -0600
      Modify: 2013-02-26 21:37:51.000000000 -0600
      Change: 2013-02-26 21:37:51.000000000 -0600
      # find /mnt/mds1/ROOT
      /mnt/mds1/ROOT
      /mnt/mds1/ROOT/.lustre
      /mnt/mds1/ROOT/D
      # sys_getdents --verbose /mnt/mds1/ROOT
      d_type =   4 (d), d_ino =                  2, d_off =  2085404527983360875, d_reclen =   24, d_name = '..'
      d_type =   4 (d), d_ino =              50013, d_off =  3188331865672730665, d_reclen =   24, d_name = '.'
      dirent '.lustre' has unknown d_type 20
      d_type =  20 (!), d_ino =              50014, d_off =  8374721202256512604, d_reclen =   32, d_name = '.lustre'
      dirent 'D' has unknown d_type 20
      d_type =  20 (!), d_ino =              50015, d_off =  9223372036854775807, d_reclen =   24, d_name = 'D'
      #
      # sys_getdents --verbose /mnt/mds1/ROOT/D/D/D/D/D/D/
      dirent '..' has unknown d_type 20
      d_type =  20 (!), d_ino =              50019, d_off =  2085404527983360875, d_reclen =   24, d_name = '..'
      d_type =   4 (d), d_ino =              50020, d_off =  6678178485617948048, d_reclen =   24, d_name = '.'
      dirent 'XXX' has unknown d_type 24
      d_type =  24 (!), d_ino =                111, d_off =  9223372036854775807, d_reclen =   24, d_name = 'XXX'
      

      Attachments

        Issue Links

          Activity

            [LU-2880] ldiskfs getdents() returns invalid d_types

            Patch landed to Master.

            jlevi Jodi Levi (Inactive) added a comment - Patch landed to Master.
            pjones Peter Jones added a comment -

            Bob will take over this one

            pjones Peter Jones added a comment - Bob will take over this one

            Patch http://review.whamcloud.com/#/c/6411/ is related to this ticket.

            bobbielind Bobbie Lind (Inactive) added a comment - Patch http://review.whamcloud.com/#/c/6411/ is related to this ticket.

            We ran into this with our purge utility. Do you mind if I update the patch and try it out on our SuSE boxes.

            simmonsja James A Simmons added a comment - We ran into this with our purge utility. Do you mind if I update the patch and try it out on our SuSE boxes.

            Thanks Andreas, I have raised the code review request for it:
            http://review.whamcloud.com/#change,6495
            Similar changes need to be done for sles11sp2.

            manisha Manisha salve (Inactive) added a comment - Thanks Andreas, I have raised the code review request for it: http://review.whamcloud.com/#change,6495 Similar changes need to be done for sles11sp2.

            It makes more sense to add a mount option to enable the dirdata options in the ext4_data_in_dirent, and then set this mount option to osd_ldiskfs/osd_handler.c::osd_mount(). This will make the dirdata only available for Lustre, and will not require non-Lustre mounts to specify an option in order to work properly.

            Instead of passing a text mount option in osd_mount() (which adds complexity and is prone to errors if ldiskfs is packaged separately and wasn't patched for this option) it is also possible to set this option directly in the superblock:

             #define EXT4_MOUNT_ERRORS_MASK          0x00070
             #define EXT4_MOUNT_MINIX_DF             0x00080 /* Mimics the Minix statfs */
             #define EXT4_MOUNT_NOLOAD               0x00100 /* Don't use existing journal*/
            +#define EXT4_MOUNT_DIRDATA              0x00200 /* Data in directory entries */
             #define EXT4_MOUNT_DATA_FLAGS           0x00C00 /* Mode for data writes: */
             #define EXT4_MOUNT_JOURNAL_DATA         0x00400 /* Write data to journal */
             #define EXT4_MOUNT_ORDERED_DATA         0x00800 /* Flush data before commit */
            
             static int osd_mount(...)
             {
                     if (lmd_flags & LMD_FLG_NOSCRUB)
                             o->od_noscrub = 1;
             
            +#ifdef EXT4_MOUNT_OPT_DIRDATA
            +        if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_DIRDATA))
            +                set_opt(o->od_mnt->mnt_sb, DIRDATA);
            +#endif
             out:
                     if (__page)
                             OBD_PAGE_FREE(__page);
            

            This value for EXT4_MOUNT_DIRDATA appears to be unused for all of the relevant kernels. In get_dtype() it can just check for this mount option instead of checking the feature flag each time:

                   if (!test_opt(sb, DIRDATA))
                           return ext4_filetype_table[fl_index];
            
                   return (ext4_filetype_table[fl_index]) |
                           (filetype & EXT4_DIRENT_LUFID);
            
            adilger Andreas Dilger added a comment - It makes more sense to add a mount option to enable the dirdata options in the ext4_data_in_dirent, and then set this mount option to osd_ldiskfs/osd_handler.c::osd_mount(). This will make the dirdata only available for Lustre, and will not require non-Lustre mounts to specify an option in order to work properly. Instead of passing a text mount option in osd_mount() (which adds complexity and is prone to errors if ldiskfs is packaged separately and wasn't patched for this option) it is also possible to set this option directly in the superblock: #define EXT4_MOUNT_ERRORS_MASK 0x00070 #define EXT4_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ #define EXT4_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ +#define EXT4_MOUNT_DIRDATA 0x00200 /* Data in directory entries */ #define EXT4_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ #define EXT4_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ #define EXT4_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ static int osd_mount(...) { if (lmd_flags & LMD_FLG_NOSCRUB) o->od_noscrub = 1; +#ifdef EXT4_MOUNT_OPT_DIRDATA + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_DIRDATA)) + set_opt(o->od_mnt->mnt_sb, DIRDATA); +#endif out: if (__page) OBD_PAGE_FREE(__page); This value for EXT4_MOUNT_DIRDATA appears to be unused for all of the relevant kernels. In get_dtype() it can just check for this mount option instead of checking the feature flag each time: if (!test_opt(sb, DIRDATA)) return ext4_filetype_table[fl_index]; return (ext4_filetype_table[fl_index]) | (filetype & EXT4_DIRENT_LUFID);

            ldiskfs just does not return the file type bits but also the dirdata info bits (get_dtype()).
            The osd-ldiskfs layer calls ldiskfs internally and it needs this dirdata bit information.
            From osd-ldiskfs call_filldir() (its used for htree indexing directories) calls get_dtype().
            So simply masking the dirdata bits would break the osd-ldiskfs functionality.

            Other way to fix the issue could be , provide a mount option "nodirdata" for mounting ldiskfs. If this option is set we will not return dirdata bits information.

            manisha Manisha salve (Inactive) added a comment - ldiskfs just does not return the file type bits but also the dirdata info bits (get_dtype()). The osd-ldiskfs layer calls ldiskfs internally and it needs this dirdata bit information. From osd-ldiskfs call_filldir() (its used for htree indexing directories) calls get_dtype(). So simply masking the dirdata bits would break the osd-ldiskfs functionality. Other way to fix the issue could be , provide a mount option "nodirdata" for mounting ldiskfs. If this option is set we will not return dirdata bits information.

            People

              bogl Bob Glossman (Inactive)
              jhammond John Hammond
              Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: