]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: Add write support for dirent filetype field
authorDave Chinner <dchinner@redhat.com>
Wed, 4 Sep 2013 22:05:52 +0000 (22:05 +0000)
committerRich Johnston <rjohnston@sgi.com>
Mon, 16 Sep 2013 20:15:46 +0000 (15:15 -0500)
Add support to propagate and add filetype values into the on-disk
directs. This involves passing the filetype into the xfs_da_args
structure along with the name and namelength for direct operations,
and encoding it into the dirent at the same time we write the inode
number into the dirent.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
include/xfs_sb.h
libxfs/xfs_dir2_block.c
libxfs/xfs_dir2_data.c
libxfs/xfs_dir2_leaf.c
libxfs/xfs_dir2_node.c
libxfs/xfs_dir2_sf.c

index 3c297a4516224bf36e6bac08494b94fda69f8db4..c8d88989bad68cdeb86f0f6972b946959eb7acd8 100644 (file)
@@ -594,7 +594,8 @@ xfs_sb_has_ro_compat_feature(
 }
 
 #define XFS_SB_FEAT_INCOMPAT_FTYPE     (1 << 0)        /* filetype in dirent */
-#define XFS_SB_FEAT_INCOMPAT_ALL 0
+#define XFS_SB_FEAT_INCOMPAT_ALL \
+               (XFS_SB_FEAT_INCOMPAT_FTYPE)
 
 #define XFS_SB_FEAT_INCOMPAT_UNKNOWN   ~XFS_SB_FEAT_INCOMPAT_ALL
 static inline bool
index 615eea911ea6b800e3e127fa7713644183e1c4f1..3e4bc53b751268b95d1d8533add0301277f90043 100644 (file)
@@ -530,6 +530,7 @@ xfs_dir2_block_addname(
        dep->inumber = cpu_to_be64(args->inumber);
        dep->namelen = args->namelen;
        memcpy(dep->name, args->name, args->namelen);
+       xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
        tagp = xfs_dir3_data_entry_tag_p(mp, dep);
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
        /*
@@ -622,6 +623,7 @@ xfs_dir2_block_lookup(
         * Fill in inode number, CI name if appropriate, release the block.
         */
        args->inumber = be64_to_cpu(dep->inumber);
+       args->filetype = xfs_dir3_dirent_get_ftype(mp, dep);
        error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
        xfs_trans_brelse(args->trans, bp);
        return XFS_ERROR(error);
@@ -854,6 +856,7 @@ xfs_dir2_block_replace(
         * Change the inode number to the new value.
         */
        dep->inumber = cpu_to_be64(args->inumber);
+       xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
        xfs_dir2_data_log_entry(args->trans, bp, dep);
        xfs_dir3_data_check(dp, bp);
        return 0;
@@ -1140,6 +1143,7 @@ xfs_dir2_sf_to_block(
        dep->inumber = cpu_to_be64(dp->i_ino);
        dep->namelen = 1;
        dep->name[0] = '.';
+       xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
        tagp = xfs_dir3_data_entry_tag_p(mp, dep);
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
        xfs_dir2_data_log_entry(tp, bp, dep);
@@ -1153,6 +1157,7 @@ xfs_dir2_sf_to_block(
        dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
        dep->namelen = 2;
        dep->name[0] = dep->name[1] = '.';
+       xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR);
        tagp = xfs_dir3_data_entry_tag_p(mp, dep);
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
        xfs_dir2_data_log_entry(tp, bp, dep);
@@ -1200,6 +1205,8 @@ xfs_dir2_sf_to_block(
                dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
                dep->inumber = cpu_to_be64(xfs_dir3_sfe_get_ino(mp, sfp, sfep));
                dep->namelen = sfep->namelen;
+               xfs_dir3_dirent_put_ftype(mp, dep,
+                                       xfs_dir3_sfe_get_ftype(mp, sfp, sfep));
                memcpy(dep->name, sfep->name, dep->namelen);
                tagp = xfs_dir3_data_entry_tag_p(mp, dep);
                *tagp = cpu_to_be16((char *)dep - (char *)hdr);
index ea9ba9131c7d8a23b532efa3a4a1eb41263c3f51..189699ff4003a25b89e078da277f994dde399415 100644 (file)
@@ -133,6 +133,8 @@ __xfs_dir3_data_check(
                XFS_WANT_CORRUPTED_RETURN(
                        be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) ==
                                               (char *)dep - (char *)hdr);
+               XFS_WANT_CORRUPTED_RETURN(
+                       xfs_dir3_dirent_get_ftype(mp, dep) < XFS_DIR3_FT_MAX);
                count++;
                lastfree = 0;
                if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
index 04ad083c4ff3a300873053b3e33d296ef697bf33..7ec2f1975d062e5e6056ef1c2a354c6fdfab1186 100644 (file)
@@ -878,6 +878,7 @@ xfs_dir2_leaf_addname(
        dep->inumber = cpu_to_be64(args->inumber);
        dep->namelen = args->namelen;
        memcpy(dep->name, args->name, dep->namelen);
+       xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
        tagp = xfs_dir3_data_entry_tag_p(mp, dep);
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
        /*
@@ -1207,6 +1208,7 @@ xfs_dir2_leaf_lookup(
         * Return the found inode number & CI name if appropriate
         */
        args->inumber = be64_to_cpu(dep->inumber);
+       args->filetype = xfs_dir3_dirent_get_ftype(dp->i_mount, dep);
        error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
        xfs_trans_brelse(tp, dbp);
        xfs_trans_brelse(tp, lbp);
@@ -1537,6 +1539,7 @@ xfs_dir2_leaf_replace(
         * Put the new inode number in, log it.
         */
        dep->inumber = cpu_to_be64(args->inumber);
+       xfs_dir3_dirent_put_ftype(dp->i_mount, dep, args->filetype);
        tp = args->trans;
        xfs_dir2_data_log_entry(tp, dbp, dep);
        xfs_dir3_leaf_check(dp->i_mount, lbp);
index 15b1eb61fe88993cfa5f3c43bd69a1512f140a40..6a245e5cf5d38acba79048b087650f32fdb17184 100644 (file)
@@ -798,6 +798,7 @@ xfs_dir2_leafn_lookup_for_entry(
                                xfs_trans_brelse(tp, state->extrablk.bp);
                        args->cmpresult = cmp;
                        args->inumber = be64_to_cpu(dep->inumber);
+                       args->filetype = xfs_dir3_dirent_get_ftype(mp, dep);
                        *indexp = index;
                        state->extravalid = 1;
                        state->extrablk.bp = curbp;
@@ -1989,6 +1990,7 @@ xfs_dir2_node_addname_int(
        dep->inumber = cpu_to_be64(args->inumber);
        dep->namelen = args->namelen;
        memcpy(dep->name, args->name, dep->namelen);
+       xfs_dir3_dirent_put_ftype(mp, dep, args->filetype);
        tagp = xfs_dir3_data_entry_tag_p(mp, dep);
        *tagp = cpu_to_be16((char *)dep - (char *)hdr);
        xfs_dir2_data_log_entry(tp, dbp, dep);
@@ -2209,6 +2211,7 @@ xfs_dir2_node_replace(
                 * Fill in the new inode number and log the entry.
                 */
                dep->inumber = cpu_to_be64(inum);
+               xfs_dir3_dirent_put_ftype(state->mp, dep, args->filetype);
                xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
                rval = 0;
        }
index 2791d997aac36e41bafd90f74b4b134a360c9bd9..740cab02c0d56e6d323c80b0dd21b574fccd2b47 100644 (file)
@@ -316,6 +316,8 @@ xfs_dir2_block_to_sf(
                        memcpy(sfep->name, dep->name, dep->namelen);
                        xfs_dir3_sfe_put_ino(mp, sfp, sfep,
                                             be64_to_cpu(dep->inumber));
+                       xfs_dir3_sfe_put_ftype(mp, sfp, sfep,
+                                       xfs_dir3_dirent_get_ftype(mp, dep));
 
                        sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep);
                }
@@ -479,6 +481,8 @@ xfs_dir2_sf_addname_easy(
        xfs_dir2_sf_put_offset(sfep, offset);
        memcpy(sfep->name, args->name, sfep->namelen);
        xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep, args->inumber);
+       xfs_dir3_sfe_put_ftype(dp->i_mount, sfp, sfep, args->filetype);
+
        /*
         * Update the header and inode.
         */
@@ -572,6 +576,7 @@ xfs_dir2_sf_addname_hard(
        xfs_dir2_sf_put_offset(sfep, offset);
        memcpy(sfep->name, args->name, sfep->namelen);
        xfs_dir3_sfe_put_ino(mp, sfp, sfep, args->inumber);
+       xfs_dir3_sfe_put_ftype(mp, sfp, sfep, args->filetype);
        sfp->count++;
 #if XFS_BIG_INUMS
        if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
@@ -808,6 +813,7 @@ xfs_dir2_sf_lookup(
        if (args->namelen == 1 && args->name[0] == '.') {
                args->inumber = dp->i_ino;
                args->cmpresult = XFS_CMP_EXACT;
+               args->filetype = XFS_DIR3_FT_DIR;
                return XFS_ERROR(EEXIST);
        }
        /*
@@ -817,6 +823,7 @@ xfs_dir2_sf_lookup(
            args->name[0] == '.' && args->name[1] == '.') {
                args->inumber = xfs_dir2_sf_get_parent_ino(sfp);
                args->cmpresult = XFS_CMP_EXACT;
+               args->filetype = XFS_DIR3_FT_DIR;
                return XFS_ERROR(EEXIST);
        }
        /*
@@ -836,6 +843,8 @@ xfs_dir2_sf_lookup(
                        args->cmpresult = cmp;
                        args->inumber = xfs_dir3_sfe_get_ino(dp->i_mount,
                                                             sfp, sfep);
+                       args->filetype = xfs_dir3_sfe_get_ftype(dp->i_mount,
+                                                               sfp, sfep);
                        if (cmp == XFS_CMP_EXACT)
                                return XFS_ERROR(EEXIST);
                        ci_sfep = sfep;
@@ -1035,6 +1044,8 @@ xfs_dir2_sf_replace(
 #endif
                                xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
                                                     args->inumber);
+                               xfs_dir3_sfe_put_ftype(dp->i_mount, sfp, sfep,
+                                                      args->filetype);
                                break;
                        }
                }
@@ -1101,10 +1112,12 @@ xfs_dir2_sf_toino4(
        int                     oldsize;        /* old inode size */
        xfs_dir2_sf_entry_t     *sfep;          /* new sf entry */
        xfs_dir2_sf_hdr_t       *sfp;           /* new sf directory */
+       struct xfs_mount        *mp;
 
        trace_xfs_dir2_sf_toino4(args);
 
        dp = args->dp;
+       mp = dp->i_mount;
 
        /*
         * Copy the old directory to the buffer.
@@ -1142,13 +1155,15 @@ xfs_dir2_sf_toino4(
        for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
                    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
             i < sfp->count;
-            i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep),
-                 oldsfep = xfs_dir3_sf_nextentry(dp->i_mount, oldsfp, oldsfep)) {
+            i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep),
+                 oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) {
                sfep->namelen = oldsfep->namelen;
                sfep->offset = oldsfep->offset;
                memcpy(sfep->name, oldsfep->name, sfep->namelen);
-               xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
-                       xfs_dir3_sfe_get_ino(dp->i_mount, oldsfp, oldsfep));
+               xfs_dir3_sfe_put_ino(mp, sfp, sfep,
+                       xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep));
+               xfs_dir3_sfe_put_ftype(mp, sfp, sfep,
+                       xfs_dir3_sfe_get_ftype(mp, oldsfp, oldsfep));
        }
        /*
         * Clean up the inode.
@@ -1176,10 +1191,12 @@ xfs_dir2_sf_toino8(
        int                     oldsize;        /* old inode size */
        xfs_dir2_sf_entry_t     *sfep;          /* new sf entry */
        xfs_dir2_sf_hdr_t       *sfp;           /* new sf directory */
+       struct xfs_mount        *mp;
 
        trace_xfs_dir2_sf_toino8(args);
 
        dp = args->dp;
+       mp = dp->i_mount;
 
        /*
         * Copy the old directory to the buffer.
@@ -1217,13 +1234,15 @@ xfs_dir2_sf_toino8(
        for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
                    oldsfep = xfs_dir2_sf_firstentry(oldsfp);
             i < sfp->count;
-            i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep),
-                 oldsfep = xfs_dir3_sf_nextentry(dp->i_mount, oldsfp, oldsfep)) {
+            i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep),
+                 oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) {
                sfep->namelen = oldsfep->namelen;
                sfep->offset = oldsfep->offset;
                memcpy(sfep->name, oldsfep->name, sfep->namelen);
-               xfs_dir3_sfe_put_ino(dp->i_mount, sfp, sfep,
-                       xfs_dir3_sfe_get_ino(dp->i_mount, oldsfp, oldsfep));
+               xfs_dir3_sfe_put_ino(mp, sfp, sfep,
+                       xfs_dir3_sfe_get_ino(mp, oldsfp, oldsfep));
+               xfs_dir3_sfe_put_ftype(mp, sfp, sfep,
+                       xfs_dir3_sfe_get_ftype(mp, oldsfp, oldsfep));
        }
        /*
         * Clean up the inode.