]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Merge back further kernel changes into libxfs, esp. attr2 related, and extend xfs_db...
authorNathan Scott <nathans@sgi.com>
Thu, 29 Sep 2005 03:27:13 +0000 (03:27 +0000)
committerNathan Scott <nathans@sgi.com>
Thu, 29 Sep 2005 03:27:13 +0000 (03:27 +0000)
12 files changed:
db/attrset.c
include/libxfs.h
include/xfs_da_btree.h
libxfs/init.c
libxfs/xfs.h
libxfs/xfs_attr.c
libxfs/xfs_attr_leaf.c
libxfs/xfs_bmap.c
libxfs/xfs_dir.c
libxfs/xfs_dir2_block.c
libxfs/xfs_dir2_sf.c
libxlog/xfs_log_recover.c

index aec51cfbe5ddce549871c9de10d38f9671eee349..65ff583251de4f0e5ffa7d9a0c81fb39c434d698 100644 (file)
@@ -49,11 +49,11 @@ static void         attrset_help(void);
 
 static const cmdinfo_t attr_set_cmd =
        { "attr_set", "aset", attr_set_f, 1, -1, 0,
-         "[-r|-s|-p|-u] [-R|-C] [-v n] name",
+         "[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name",
          "set the named attribute on the current inode", attrset_help };
 static const cmdinfo_t attr_remove_cmd =
        { "attr_remove", "aremove", attr_remove_f, 1, -1, 0,
-         "[-r|-s|-p|-u] name",
+         "[-r|-s|-p|-u] [-n] name",
          "remove the named attribute from the current inode", attrset_help };
 
 static void
@@ -70,9 +70,10 @@ attrset_help(void)
 "  -u -- 'user'                (default)\n"
 "  -s -- 'secure'\n"
 "\n"
-" For attr_set, these options further define the type of set:\n"
+" For attr_set, these options further define the type of set operation:\n"
 "  -C -- 'create'    - create attribute, fail if it already exists\n"
 "  -R -- 'replace'   - replace attribute, fail if it does not exist\n"
+" The backward compatibility mode 'noattr2' can be emulated (-n) also.\n"
 "\n");
 }
 
@@ -104,7 +105,7 @@ attr_set_f(
                return 0;
        }
 
-       while ((c = getopt(argc, argv, "rusCRv:")) != EOF) {
+       while ((c = getopt(argc, argv, "rusCRnv:")) != EOF) {
                switch (c) {
                /* namespaces */
                case 'r':
@@ -127,6 +128,10 @@ attr_set_f(
                        flags |= LIBXFS_ATTR_REPLACE;
                        break;
 
+               case 'n':
+                       mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR;
+                       break;
+
                /* value length */
                case 'v':
                        valuelen = (int)strtol(optarg, &sp, 0);
@@ -177,6 +182,7 @@ attr_set_f(
        set_cur_inode(iocur_top->ino);
 
 out:
+       mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR;
        if (ip)
                libxfs_iput(ip, 0);
        if (value)
@@ -202,7 +208,7 @@ attr_remove_f(
                return 0;
        }
 
-       while ((c = getopt(argc, argv, "rus")) != EOF) {
+       while ((c = getopt(argc, argv, "rusn")) != EOF) {
                switch (c) {
                /* namespaces */
                case 'r':
@@ -217,6 +223,10 @@ attr_remove_f(
                        flags &= ~LIBXFS_ATTR_ROOT;
                        break;
 
+               case 'n':
+                       mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR;
+                       break;
+
                default:
                        dbprintf("bad option for attr_remove command\n");
                        return 0;
@@ -247,6 +257,7 @@ attr_remove_f(
        set_cur_inode(iocur_top->ino);
 
 out:
+       mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR;
        if (ip)
                libxfs_iput(ip, 0);
        return 0;
index 6a3e589f017af4bf7f59724c509861f85f268e1d..2a1acdeb2e1d8edd86908ab0c243d55258bc17fe 100644 (file)
@@ -202,8 +202,11 @@ typedef struct xfs_mount {
 } xfs_mount_t;
 #define        XFS_DIR_IS_V1(mp)       ((mp)->m_dirversion == 1)
 
-#define LIBXFS_MOUNT_ROOTINOS  0x0001
-#define LIBXFS_MOUNT_DEBUGGER  0x0002
+#define LIBXFS_MOUNT_ROOTINOS          0x0001
+#define LIBXFS_MOUNT_DEBUGGER          0x0002
+#define LIBXFS_MOUNT_32BITINODES       0x0004
+#define LIBXFS_MOUNT_32BITINOOPT       0x0008
+#define LIBXFS_MOUNT_COMPAT_ATTR       0x0010
 
 extern xfs_mount_t     *libxfs_mount (xfs_mount_t *, xfs_sb_t *,
                                dev_t, dev_t, dev_t, int);
@@ -468,8 +471,9 @@ extern int  libxfs_alloc_file_space (xfs_inode_t *, xfs_off_t,
 
 extern xfs_dahash_t    libxfs_da_hashname (uchar_t *, int);
 extern int     libxfs_attr_leaf_newentsize (int, int, int, int *);
-extern int     libxfs_attr_set_int (xfs_inode_t*, char*, int, char*, int, int);
-extern int     libxfs_attr_remove_int (xfs_inode_t *, char *, int, int);
+extern int     libxfs_attr_set_int (xfs_inode_t*, const char *, int, char *,
+                               int, int);
+extern int     libxfs_attr_remove_int (xfs_inode_t *, const char *, int, int);
 
 
 extern void    libxfs_bmbt_get_all (xfs_bmbt_rec_t *, xfs_bmbt_irec_t *);
index 9fc699d9699575f8fc2ad69cb095b4ca3d5a6565..a48b96b59c78d575b59c81a53e25cc1b879c0ae2 100644 (file)
@@ -168,7 +168,7 @@ int xfs_da_cookie_entry(struct xfs_mount *mp, xfs_off_t cookie);
  * Structure to ease passing around component names.
  */
 typedef struct xfs_da_args {
-       uchar_t         *name;          /* string (maybe not NULL terminated) */
+       const uchar_t   *name;          /* string (maybe not NULL terminated) */
        int             namelen;        /* length of string (maybe no NULL) */
        uchar_t         *value;         /* set of bytes (maybe contain NULLs) */
        int             valuelen;       /* length of value */
index 9759e165a153cd70fec8619c40f9a0964107fb85..f4e7b78758d4e8c39d7926798bbefab8dd53183a 100644 (file)
@@ -544,8 +544,6 @@ rtmount_init(
        return 0;
 }
 
-#define XFS_MOUNT_32BITINODES  0x1
-#define XFS_MOUNT_32BITINOOPT  0x2
 /*
  * Mount structure initialization, provides a filled-in xfs_mount_t
  * such that the numerous XFS_* macros can be used.  If dev is zero,
@@ -569,7 +567,7 @@ libxfs_mount(
        mp->m_dev = dev;
        mp->m_rtdev = rtdev;
        mp->m_logdev = logdev;
-       mp->m_flags = (XFS_MOUNT_32BITINODES|XFS_MOUNT_32BITINOOPT);
+       mp->m_flags = (LIBXFS_MOUNT_32BITINODES|LIBXFS_MOUNT_32BITINOOPT);
        mp->m_sb = *sb;
        sbp = &(mp->m_sb);
        manage_zones(0);
index d2815a00b0cabd22c6e2e738d96d7eb3e4245e5e..cdcd512ae36a6d3548618e0123f1d85e1ca3ad04 100644 (file)
@@ -290,9 +290,11 @@ typedef struct { dev_t dev; } xfs_buftarg_t;
 #define XFS_STATS_ADD(count, x)                do { } while (0)
 #define XFS_MOUNT_WSYNC                        0       /* ignored in userspace */
 #define XFS_MOUNT_NOALIGN              0       /* ignored in userspace */
-#define XFS_MOUNT_32BITINODES          0x1     /* enforce in userspace */
-#define XFS_MOUNT_32BITINOOPT          0x2     /* enforce in userspace */
+#define XFS_MOUNT_32BITINODES          LIBXFS_MOUNT_32BITINODES
+#define XFS_MOUNT_32BITINOOPT          LIBXFS_MOUNT_32BITINOOPT
+#define XFS_MOUNT_COMPAT_ATTR          LIBXFS_MOUNT_COMPAT_ATTR
 #define XFS_ILOCK_EXCL                 0
+#define xfs_sort                       qsort
 #define down_read(a)                   ((void) 0)
 #define up_read(a)                     ((void) 0)
 #define mrlock(a,b,c)                  ((void) 0)
index c99dd1d47cfaf6331f07a849ed4d0d84b39a1cb6..303fa7833cc14674ddfcdf363834563483fe2efb 100644 (file)
@@ -79,7 +79,7 @@ STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
  *========================================================================*/
 
 int
-xfs_attr_set_int(xfs_inode_t *dp, char *name, int namelen,
+xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
                 char *value, int valuelen, int flags)
 {
        xfs_da_args_t   args;
@@ -315,7 +315,7 @@ out:
 }
 
 STATIC int
-xfs_attr_remove_int(xfs_inode_t *dp, char *name, int namelen, int flags)
+xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
 {
        xfs_da_args_t   args;
        xfs_fsblock_t   firstblock;
index 5c5efefba76737d896533eb244fe02659384f545..8fe5e7d49ec3d6d6b4f67c7315668c86937bed72 100644 (file)
  *========================================================================*/
 
 /*
- * Query whether additional requested number of bytes of extended attribute
- * space will be able to fit inline.
+ * Query whether the requested number of additional bytes of extended
+ * attribute space will be able to fit inline.
  * Returns zero if not, else the di_forkoff fork offset to be used in the
  * literal area for attribute data once the new bytes have been added.
+ *
+ * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
+ * special case for dev/uuid inodes, they have fixed size data forks.
  */
 int
 xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
 {
-       int offset, minforkoff, maxforkoff;
+       int offset;
+       int minforkoff; /* lower limit on valid forkoff locations */
+       int maxforkoff; /* upper limit on valid forkoff locations */
+       xfs_mount_t *mp = dp->i_mount;
 
-       offset = (XFS_LITINO(dp->i_mount) - bytes) >> 3; /* rounded down */
+       offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
 
        switch (dp->i_d.di_format) {
        case XFS_DINODE_FMT_DEV:
@@ -64,12 +70,18 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
                return (offset >= minforkoff) ? minforkoff : 0;
        }
 
+       if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
+               if (bytes <= XFS_IFORK_ASIZE(dp))
+                       return mp->m_attroffset >> 3;
+               return 0;
+       }
+
        /* data fork btree root can have at least this many key/ptr pairs */
        minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
        minforkoff = roundup(minforkoff, 8) >> 3;
 
        /* attr fork btree root can have at least this many key/ptr pairs */
-       maxforkoff = XFS_LITINO(dp->i_mount) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
+       maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
        maxforkoff = maxforkoff >> 3;   /* rounded down */
 
        if (offset >= minforkoff && offset < maxforkoff)
@@ -79,6 +91,26 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
        return 0;
 }
 
+/*
+ * Switch on the ATTR2 superblock bit (implies also FEATURES2)
+ */
+STATIC void
+xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
+{
+       unsigned long s;
+
+       if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
+           !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
+               s = XFS_SB_LOCK(mp);
+               if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
+                       XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
+                       XFS_SB_UNLOCK(mp, s);
+                       xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
+               } else
+                       XFS_SB_UNLOCK(mp, s);
+       }
+}
+
 /*
  * Create the initial contents of a shortform attribute list.
  */
@@ -118,7 +150,6 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
        xfs_attr_shortform_t *sf;
        xfs_attr_sf_entry_t *sfe;
        int i, offset, size;
-       unsigned long s;
        xfs_mount_t *mp;
        xfs_inode_t *dp;
        xfs_ifork_t *ifp;
@@ -168,16 +199,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
        INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size);
        xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
 
-       if (unlikely(!XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
-               s = XFS_SB_LOCK(mp);
-               if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
-                       XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
-                       XFS_SB_UNLOCK(mp, s);
-                       xfs_mod_sb(args->trans,
-                                  XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
-               } else
-                       XFS_SB_UNLOCK(mp, s);
-       }
+       xfs_sbversion_add_attr2(mp, args->trans);
 }
 
 /*
@@ -189,7 +211,6 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
        xfs_attr_shortform_t *sf;
        xfs_attr_sf_entry_t *sfe;
        int base, size=0, end, totsize, i;
-       unsigned long s;
        xfs_mount_t *mp;
        xfs_inode_t *dp;
 
@@ -258,16 +279,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
                                        XFS_ILOG_CORE | XFS_ILOG_ADATA);
        }
 
-       if (unlikely(!XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
-               s = XFS_SB_LOCK(mp);
-               if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
-                       XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
-                       XFS_SB_UNLOCK(mp, s);
-                       xfs_mod_sb(args->trans,
-                                  XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
-               } else
-                       XFS_SB_UNLOCK(mp, s);
-       }
+       xfs_sbversion_add_attr2(mp, args->trans);
 
        return(0);
 }
index 284abc005c9c351e8100a6bd1b6b74cbeb3d8b17..bf84807eb614a0ea1716484ccf6f3c37687ad10a 100644 (file)
@@ -3289,10 +3289,10 @@ xfs_bmap_add_attrfork(
        case XFS_DINODE_FMT_EXTENTS:
        case XFS_DINODE_FMT_BTREE:
                ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
-               if (ip->i_d.di_forkoff)
-                       version = 2;
-               else
+               if (!ip->i_d.di_forkoff)
                        ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+               else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
+                       version = 2;
                break;
        default:
                ASSERT(0);
@@ -3439,10 +3439,13 @@ xfs_bmap_compute_maxlevels(
         */
        if (whichfork == XFS_DATA_FORK) {
                maxleafents = MAXEXTNUM;
-               sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
+               sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
+                       mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS);
        } else {
                maxleafents = MAXAEXTNUM;
-               sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
+               sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
+                       mp->m_sb.sb_inodesize - mp->m_attroffset :
+                       XFS_BMDR_SPACE_CALC(MINABTPTRS);
        }
        maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
        minleafrecs = mp->m_bmap_dmnr[0];
index dd446d038f3d369d08308e0fdcce6c1658b27acc..9b0db7b8cb9ffb2b94e26993997b469dfb02a619 100644 (file)
@@ -61,12 +61,23 @@ xfs_dir_mount(xfs_mount_t *mp)
        uint shortcount, leafcount, count;
 
        mp->m_dirversion = 1;
-       shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
-                     (uint)sizeof(xfs_dir_sf_hdr_t)) /
-                      (uint)sizeof(xfs_dir_sf_entry_t);
-       leafcount = (XFS_LBSIZE(mp) - (uint)sizeof(xfs_dir_leaf_hdr_t)) /
-                   ((uint)sizeof(xfs_dir_leaf_entry_t) +
-                    (uint)sizeof(xfs_dir_leaf_name_t));
+       if (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) {
+               shortcount = (mp->m_attroffset -
+                               (uint)sizeof(xfs_dir_sf_hdr_t)) /
+                                (uint)sizeof(xfs_dir_sf_entry_t);
+               leafcount = (XFS_LBSIZE(mp) -
+                               (uint)sizeof(xfs_dir_leaf_hdr_t)) /
+                                ((uint)sizeof(xfs_dir_leaf_entry_t) +
+                                 (uint)sizeof(xfs_dir_leaf_name_t));
+       } else {
+               shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
+                             (uint)sizeof(xfs_dir_sf_hdr_t)) /
+                              (uint)sizeof(xfs_dir_sf_entry_t);
+               leafcount = (XFS_LBSIZE(mp) -
+                           (uint)sizeof(xfs_dir_leaf_hdr_t)) /
+                            ((uint)sizeof(xfs_dir_leaf_entry_t) +
+                             (uint)sizeof(xfs_dir_leaf_name_t));
+       }
        count = shortcount > leafcount ? shortcount : leafcount;
        mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
        ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
index 0038b3d5a00d2ce1099ffdbcb14afc7482c49881..83ec9437dbdaa96d1abfd01fc4b2520bab99a17a 100644 (file)
@@ -1074,7 +1074,7 @@ xfs_dir2_sf_to_block(
        /*
         * Sort the leaf entries by hash value.
         */
-       qsort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort);
+       xfs_sort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort);
        /*
         * Log the leaf entry area and tail.
         * Already logged the header in data_init, ignore needlog.
index 6d36333443e4ed471d9ce3aeb5705b2e94b519e5..220494756d653bf36469a23435ba24e2f8623355 100644 (file)
@@ -61,7 +61,6 @@ xfs_dir2_block_sfsize(
        int                     isdotdot;       /* entry is ".." */
        xfs_mount_t             *mp;            /* mount structure pointer */
        int                     namelen;        /* total name bytes */
-       int                     inode_size;     /* inode number bytes */
        xfs_ino_t               parent;         /* parent inode number */
        int                     size=0;         /* total computed size */
 
@@ -103,10 +102,13 @@ xfs_dir2_block_sfsize(
                /*
                 * Calculate the new size, see if we should give up yet.
                 */
-               inode_size = i8count ?  sizeof(xfs_dir2_ino8_t) :
-                                       sizeof(xfs_dir2_ino4_t);
-               size = XFS_DIR2_SF_HDR_SIZE(i8count) + namelen +
-                       count * (sizeof(xfs_dir2_sf_off_t) + 1 + inode_size);
+               size = XFS_DIR2_SF_HDR_SIZE(i8count) +          /* header */
+                      count +                                  /* namelen */
+                      count * (uint)sizeof(xfs_dir2_sf_off_t) + /* offset */
+                      namelen +                                /* name */
+                      (i8count ?                               /* inumber */
+                               (uint)sizeof(xfs_dir2_ino8_t) * count :
+                               (uint)sizeof(xfs_dir2_ino4_t) * count);
                if (size > XFS_IFORK_DSIZE(dp))
                        return size;            /* size value is a failure */
        }
index 774346e41ce298155ae55e302d2ee45e1200c85e..42b201d349b633061ead8a5cd9eb8aef4abaf71f 100644 (file)
@@ -1023,7 +1023,7 @@ xlog_recover_add_to_cont_trans(
        old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
        old_len = item->ri_buf[item->ri_cnt-1].i_len;
 
-       ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0);
+       ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u);
        memcpy(&ptr[old_len], dp, len); /* d, s, l */
        item->ri_buf[item->ri_cnt-1].i_len += len;
        item->ri_buf[item->ri_cnt-1].i_addr = ptr;