From: Nathan Scott Date: Thu, 29 Sep 2005 03:27:13 +0000 (+0000) Subject: Merge back further kernel changes into libxfs, esp. attr2 related, and extend xfs_db... X-Git-Tag: v2.8.0~90 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6239071d5ef1f761ac7c2ec7d4b7903350d11762;p=thirdparty%2Fxfsprogs-dev.git Merge back further kernel changes into libxfs, esp. attr2 related, and extend xfs_db attrset code to allow noattr2 debugging also. --- diff --git a/db/attrset.c b/db/attrset.c index aec51cfbe..65ff58325 100644 --- a/db/attrset.c +++ b/db/attrset.c @@ -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; diff --git a/include/libxfs.h b/include/libxfs.h index 6a3e589f0..2a1acdeb2 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -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 *); diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 9fc699d96..a48b96b59 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -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 */ diff --git a/libxfs/init.c b/libxfs/init.c index 9759e165a..f4e7b7875 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -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); diff --git a/libxfs/xfs.h b/libxfs/xfs.h index d2815a00b..cdcd512ae 100644 --- a/libxfs/xfs.h +++ b/libxfs/xfs.h @@ -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) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index c99dd1d47..303fa7833 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -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; diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index 5c5efefba..8fe5e7d49 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -43,17 +43,23 @@ *========================================================================*/ /* - * 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); } diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 284abc005..bf84807eb 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -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]; diff --git a/libxfs/xfs_dir.c b/libxfs/xfs_dir.c index dd446d038..9b0db7b8c 100644 --- a/libxfs/xfs_dir.c +++ b/libxfs/xfs_dir.c @@ -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); diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index 0038b3d5a..83ec9437d 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -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. diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index 6d3633344..220494756 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/libxfs/xfs_dir2_sf.c @@ -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 */ } diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c index 774346e41..42b201d34 100644 --- a/libxlog/xfs_log_recover.c +++ b/libxlog/xfs_log_recover.c @@ -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;