X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fxfs%2Fxfs_attr.c;h=ceab001c038d0b58522e2c4b22f95cc9dd8491a0;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=ee8b5904ec7ccd7e7fb0a15ec3470cd1336e2c45;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index ee8b5904e..ceab001c0 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -1,69 +1,54 @@ /* - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "xfs.h" +#include -#include "xfs_macros.h" +#include "xfs.h" +#include "xfs_fs.h" #include "xfs_types.h" -#include "xfs_inum.h" +#include "xfs_bit.h" #include "xfs_log.h" +#include "xfs_inum.h" #include "xfs_trans.h" #include "xfs_sb.h" #include "xfs_ag.h" -#include "xfs_dir.h" #include "xfs_dir2.h" #include "xfs_dmapi.h" #include "xfs_mount.h" -#include "xfs_alloc_btree.h" +#include "xfs_da_btree.h" #include "xfs_bmap_btree.h" +#include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" -#include "xfs_alloc.h" -#include "xfs_btree.h" -#include "xfs_attr_sf.h" -#include "xfs_dir_sf.h" #include "xfs_dir2_sf.h" +#include "xfs_attr_sf.h" #include "xfs_dinode.h" -#include "xfs_inode_item.h" #include "xfs_inode.h" +#include "xfs_alloc.h" +#include "xfs_btree.h" +#include "xfs_inode_item.h" #include "xfs_bmap.h" -#include "xfs_da_btree.h" #include "xfs_attr.h" #include "xfs_attr_leaf.h" #include "xfs_error.h" -#include "xfs_bit.h" #include "xfs_quota.h" -#include "xfs_rw.h" #include "xfs_trans_space.h" #include "xfs_acl.h" +#include "xfs_rw.h" /* * xfs_attr.c @@ -71,6 +56,11 @@ * Provide the external interfaces to manage attribute lists. */ +#define ATTR_SYSCOUNT 2 +STATIC struct attrnames posix_acl_access; +STATIC struct attrnames posix_acl_default; +STATIC struct attrnames *attr_system_names[ATTR_SYSCOUNT]; + /*======================================================================== * Function prototypes for the kernel. *========================================================================*/ @@ -83,6 +73,7 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); /* * Internal routines when attribute list is one block. */ +STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); @@ -90,6 +81,7 @@ STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); /* * Internal routines when attribute list is more than one block. */ +STATIC int xfs_attr_node_get(xfs_da_args_t *args); STATIC int xfs_attr_node_addname(xfs_da_args_t *args); STATIC int xfs_attr_node_removename(xfs_da_args_t *args); STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context); @@ -99,7 +91,6 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state); /* * Routines to manipulate out-of-line attribute values. */ -STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); @@ -115,7 +106,7 @@ ktrace_t *xfs_attr_trace_buf; *========================================================================*/ int -xfs_attr_fetch(xfs_inode_t *ip, char *name, int namelen, +xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen, char *value, int *valuelenp, int flags, struct cred *cred) { xfs_da_args_t args; @@ -126,11 +117,6 @@ xfs_attr_fetch(xfs_inode_t *ip, char *name, int namelen, ip->i_d.di_anextents == 0)) return(ENOATTR); - if (!(flags & (ATTR_KERNACCESS|ATTR_SECURE))) { - if ((error = xfs_iaccess(ip, S_IRUSR, cred))) - return(XFS_ERROR(error)); - } - /* * Fill in the arg structure for this request. */ @@ -170,7 +156,7 @@ xfs_attr_fetch(xfs_inode_t *ip, char *name, int namelen, } int -xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp, +xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp, int flags, struct cred *cred) { xfs_inode_t *ip = XFS_BHVTOI(bdp); @@ -193,40 +179,18 @@ xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp, return(error); } -/*ARGSUSED*/ -int /* error */ -xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags, - struct cred *cred) +int +xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, + char *value, int valuelen, int flags) { xfs_da_args_t args; - xfs_inode_t *dp; xfs_fsblock_t firstblock; xfs_bmap_free_t flist; int error, err2, committed; int local, size; uint nblks; - xfs_mount_t *mp; + xfs_mount_t *mp = dp->i_mount; int rsvd = (flags & ATTR_ROOT) != 0; - int namelen; - - namelen = strlen(name); - if (namelen >= MAXNAMELEN) - return EFAULT; /* match IRIX behaviour */ - - XFS_STATS_INC(xs_attr_set); - - dp = XFS_BHVTOI(bdp); - mp = dp->i_mount; - if (XFS_FORCED_SHUTDOWN(mp)) - return (EIO); - - xfs_ilock(dp, XFS_ILOCK_SHARED); - if (!(flags & ATTR_SECURE) && - (error = xfs_iaccess(dp, S_IWUSR, cred))) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return(XFS_ERROR(error)); - } - xfs_iunlock(dp, XFS_ILOCK_SHARED); /* * Attach the dquots to the inode. @@ -239,8 +203,10 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags, * (inode must not be locked when we call this routine) */ if (XFS_IFORK_Q(dp) == 0) { - error = xfs_bmap_add_attrfork(dp, rsvd); - if (error) + int sf_size = sizeof(xfs_attr_sf_hdr_t) + + XFS_ATTR_SF_ENTSIZE_BYNAME(namelen, valuelen); + + if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd))) return(error); } @@ -258,12 +224,15 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags, args.firstblock = &firstblock; args.flist = &flist; args.whichfork = XFS_ATTR_FORK; + args.addname = 1; args.oknoent = 1; - /* Determine space new attribute will use, and if it will be inline - * or out of line. + /* + * Determine space new attribute will use, and if it would be + * "local" or "remote" (note: local != inline). */ - size = xfs_attr_leaf_newentsize(&args, mp->m_sb.sb_blocksize, &local); + size = xfs_attr_leaf_newentsize(namelen, valuelen, + mp->m_sb.sb_blocksize, &local); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); if (local) { @@ -325,7 +294,7 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags, xfs_trans_ihold(args.trans, dp); /* - * If the attribute list is non-existant or a shortform list, + * If the attribute list is non-existent or a shortform list, * upgrade it to a single-leaf-block attribute list. */ if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) || @@ -336,7 +305,7 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags, * Build initial attribute list (if required). */ if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) - (void)xfs_attr_shortform_create(&args); + xfs_attr_shortform_create(&args); /* * Try to add the attr to the attribute list in @@ -449,46 +418,38 @@ out: return(error); } -/* - * Generic handler routine to remove a name from an attribute list. - * Transitions attribute list from Btree to shortform as necessary. - */ -/*ARGSUSED*/ -int /* error */ -xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred) +int +xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int flags, + struct cred *cred) { - xfs_da_args_t args; - xfs_inode_t *dp; - xfs_fsblock_t firstblock; - xfs_bmap_free_t flist; - int error; - xfs_mount_t *mp; - int namelen; + xfs_inode_t *dp; + int namelen; - ASSERT(MAXNAMELEN-1<=0xff); /* length is stored in uint8 */ namelen = strlen(name); - if (namelen>=MAXNAMELEN) - return EFAULT; /* match irix behaviour */ + if (namelen >= MAXNAMELEN) + return EFAULT; /* match IRIX behaviour */ - XFS_STATS_INC(xs_attr_remove); + XFS_STATS_INC(xs_attr_set); dp = XFS_BHVTOI(bdp); - mp = dp->i_mount; - if (XFS_FORCED_SHUTDOWN(mp)) + if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return (EIO); - xfs_ilock(dp, XFS_ILOCK_SHARED); - if (!(flags & ATTR_SECURE) && - (error = xfs_iaccess(dp, S_IWUSR, cred))) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return(XFS_ERROR(error)); - } else if (XFS_IFORK_Q(dp) == 0 || - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && - dp->i_d.di_anextents == 0)) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return(XFS_ERROR(ENOATTR)); - } - xfs_iunlock(dp, XFS_ILOCK_SHARED); + return xfs_attr_set_int(dp, name, namelen, value, valuelen, flags); +} + +/* + * Generic handler routine to remove a name from an attribute list. + * Transitions attribute list from Btree to shortform as necessary. + */ +int +xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) +{ + xfs_da_args_t args; + xfs_fsblock_t firstblock; + xfs_bmap_free_t flist; + int error; + xfs_mount_t *mp = dp->i_mount; /* * Fill in the arg structure for this request. @@ -537,7 +498,6 @@ xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred) XFS_ATTRRM_LOG_COUNT))) { xfs_trans_cancel(args.trans, 0); return(error); - } xfs_ilock(dp, XFS_ILOCK_EXCL); @@ -605,6 +565,138 @@ out: return(error); } +int +xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) +{ + xfs_inode_t *dp; + int namelen; + + namelen = strlen(name); + if (namelen >= MAXNAMELEN) + return EFAULT; /* match IRIX behaviour */ + + XFS_STATS_INC(xs_attr_remove); + + dp = XFS_BHVTOI(bdp); + if (XFS_FORCED_SHUTDOWN(dp->i_mount)) + return (EIO); + + xfs_ilock(dp, XFS_ILOCK_SHARED); + if (XFS_IFORK_Q(dp) == 0 || + (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && + dp->i_d.di_anextents == 0)) { + xfs_iunlock(dp, XFS_ILOCK_SHARED); + return(XFS_ERROR(ENOATTR)); + } + xfs_iunlock(dp, XFS_ILOCK_SHARED); + + return xfs_attr_remove_int(dp, name, namelen, flags); +} + +int /* error */ +xfs_attr_list_int(xfs_attr_list_context_t *context) +{ + int error; + xfs_inode_t *dp = context->dp; + + /* + * Decide on what work routines to call based on the inode size. + */ + if (XFS_IFORK_Q(dp) == 0 || + (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && + dp->i_d.di_anextents == 0)) { + error = 0; + } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { + error = xfs_attr_shortform_list(context); + } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { + error = xfs_attr_leaf_list(context); + } else { + error = xfs_attr_node_list(context); + } + return error; +} + +#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \ + (((struct attrlist_ent *) 0)->a_name - (char *) 0) +#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \ + ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \ + & ~(sizeof(u_int32_t)-1)) + +/* + * Format an attribute and copy it out to the user's buffer. + * Take care to check values and protect against them changing later, + * we may be reading them directly out of a user buffer. + */ +/*ARGSUSED*/ +STATIC int +xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp, + char *name, int namelen, + int valuelen, char *value) +{ + attrlist_ent_t *aep; + int arraytop; + + ASSERT(!(context->flags & ATTR_KERNOVAL)); + ASSERT(context->count >= 0); + ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); + ASSERT(context->firstu >= sizeof(*context->alist)); + ASSERT(context->firstu <= context->bufsize); + + arraytop = sizeof(*context->alist) + + context->count * sizeof(context->alist->al_offset[0]); + context->firstu -= ATTR_ENTSIZE(namelen); + if (context->firstu < arraytop) { + xfs_attr_trace_l_c("buffer full", context); + context->alist->al_more = 1; + context->seen_enough = 1; + return 1; + } + + aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]); + aep->a_valuelen = valuelen; + memcpy(aep->a_name, name, namelen); + aep->a_name[ namelen ] = 0; + context->alist->al_offset[ context->count++ ] = context->firstu; + context->alist->al_count = context->count; + xfs_attr_trace_l_c("add", context); + return 0; +} + +STATIC int +xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp, + char *name, int namelen, + int valuelen, char *value) +{ + char *offset; + int arraytop; + + ASSERT(context->count >= 0); + + arraytop = context->count + namesp->attr_namelen + namelen + 1; + if (arraytop > context->firstu) { + context->count = -1; /* insufficient space */ + return 1; + } + offset = (char *)context->alist + context->count; + strncpy(offset, namesp->attr_name, namesp->attr_namelen); + offset += namesp->attr_namelen; + strncpy(offset, name, namelen); /* real name */ + offset += namelen; + *offset = '\0'; + context->count += namesp->attr_namelen + namelen + 1; + return 0; +} + +/*ARGSUSED*/ +STATIC int +xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp, + char *name, int namelen, + int valuelen, char *value) +{ + context->count += namesp->attr_namelen + namelen + 1; + return 0; +} + /* * Generate a list of extended attribute names and optionally * also value lengths. Positive return value follows the XFS @@ -629,13 +721,13 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, return(XFS_ERROR(EINVAL)); if ((cursor->initted == 0) && (cursor->hashval || cursor->blkno || cursor->offset)) - return(XFS_ERROR(EINVAL)); + return XFS_ERROR(EINVAL); /* * Check for a properly aligned buffer. */ if (((long)buffer) & (sizeof(int)-1)) - return(XFS_ERROR(EFAULT)); + return XFS_ERROR(EFAULT); if (flags & ATTR_KERNOVAL) bufsize = 0; @@ -648,59 +740,47 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, context.dupcnt = 0; context.resynch = 1; context.flags = flags; - if (!(flags & ATTR_KERNAMELS)) { + context.seen_enough = 0; + context.alist = (attrlist_t *)buffer; + context.put_value = 0; + + if (flags & ATTR_KERNAMELS) { + context.bufsize = bufsize; + context.firstu = context.bufsize; + if (flags & ATTR_KERNOVAL) + context.put_listent = xfs_attr_kern_list_sizes; + else + context.put_listent = xfs_attr_kern_list; + } else { context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */ context.firstu = context.bufsize; - context.alist = (attrlist_t *)buffer; context.alist->al_count = 0; context.alist->al_more = 0; context.alist->al_offset[0] = context.bufsize; - } - else { - context.bufsize = bufsize; - context.firstu = context.bufsize; - context.alist = (attrlist_t *)buffer; + context.put_listent = xfs_attr_put_listent; } if (XFS_FORCED_SHUTDOWN(dp->i_mount)) - return (EIO); + return EIO; xfs_ilock(dp, XFS_ILOCK_SHARED); - if (!(flags & ATTR_SECURE) && - (error = xfs_iaccess(dp, S_IRUSR, cred))) { - xfs_iunlock(dp, XFS_ILOCK_SHARED); - return(XFS_ERROR(error)); - } - - /* - * Decide on what work routines to call based on the inode size. - */ xfs_attr_trace_l_c("syscall start", &context); - if (XFS_IFORK_Q(dp) == 0 || - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && - dp->i_d.di_anextents == 0)) { - error = 0; - } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { - error = xfs_attr_shortform_list(&context); - } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { - error = xfs_attr_leaf_list(&context); - } else { - error = xfs_attr_node_list(&context); - } + + error = xfs_attr_list_int(&context); + xfs_iunlock(dp, XFS_ILOCK_SHARED); xfs_attr_trace_l_c("syscall end", &context); - if (!(context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS))) { - ASSERT(error >= 0); - } - else { /* must return negated buffer size or the error */ + if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) { + /* must return negated buffer size or the error */ if (context.count < 0) error = XFS_ERROR(ERANGE); else error = -context.count; - } + } else + ASSERT(error >= 0); - return(error); + return error; } int /* error */ @@ -804,7 +884,7 @@ out: STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args) { - int newsize, retval; + int newsize, forkoff, retval; retval = xfs_attr_shortform_lookup(args); if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { @@ -816,16 +896,18 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) ASSERT(retval == 0); } + if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX || + args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX) + return(XFS_ERROR(ENOSPC)); + newsize = XFS_ATTR_SF_TOTSIZE(args->dp); newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); - if ((newsize <= XFS_IFORK_ASIZE(args->dp)) && - (args->namelen < XFS_ATTR_SF_ENTSIZE_MAX) && - (args->valuelen < XFS_ATTR_SF_ENTSIZE_MAX)) { - retval = xfs_attr_shortform_add(args); - ASSERT(retval == 0); - } else { + + forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize); + if (!forkoff) return(XFS_ERROR(ENOSPC)); - } + + xfs_attr_shortform_add(args, forkoff); return(0); } @@ -845,7 +927,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) { xfs_inode_t *dp; xfs_dabuf_t *bp; - int retval, error, committed; + int retval, error, committed, forkoff; /* * Read the (only) block in the attribute list in. @@ -988,9 +1070,9 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) /* * If the result is small enough, shrink it all into the inode. */ - if (xfs_attr_shortform_allfit(bp, dp)) { + if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { XFS_BMAP_INIT(args->flist, args->firstblock); - error = xfs_attr_leaf_to_shortform(bp, args); + error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, @@ -1042,8 +1124,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) { xfs_inode_t *dp; xfs_dabuf_t *bp; - int committed; - int error; + int error, committed, forkoff; /* * Remove the attribute. @@ -1068,9 +1149,9 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) /* * If the result is small enough, shrink it all into the inode. */ - if (xfs_attr_shortform_allfit(bp, dp)) { + if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { XFS_BMAP_INIT(args->flist, args->firstblock); - error = xfs_attr_leaf_to_shortform(bp, args); + error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, @@ -1102,7 +1183,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) * This leaf block cannot have a "remote" value, we only call this routine * if bmap_one_block() says there is only one block (ie: no remote blks). */ -int +STATIC int xfs_attr_leaf_get(xfs_da_args_t *args) { xfs_dabuf_t *bp; @@ -1141,20 +1222,19 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context) context->cursor->blkno = 0; error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK); if (error) - return(error); + return XFS_ERROR(error); ASSERT(bp != NULL); leaf = bp->data; - if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) - != XFS_ATTR_LEAF_MAGIC)) { + if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) { XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, context->dp->i_mount, leaf); xfs_da_brelse(NULL, bp); - return(XFS_ERROR(EFSCORRUPTED)); + return XFS_ERROR(EFSCORRUPTED); } - (void)xfs_attr_leaf_list_int(bp, context); + error = xfs_attr_leaf_list_int(bp, context); xfs_da_brelse(NULL, bp); - return(0); + return XFS_ERROR(error); } @@ -1441,7 +1521,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_da_state_blk_t *blk; xfs_inode_t *dp; xfs_dabuf_t *bp; - int retval, error, committed; + int retval, error, committed, forkoff; /* * Tie a string around our finger to remind us where we are. @@ -1558,13 +1638,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) XFS_ATTR_FORK); if (error) goto out; - ASSERT(INT_GET(((xfs_attr_leafblock_t *) - bp->data)->hdr.info.magic, ARCH_CONVERT) + ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *) + bp->data)->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); - if (xfs_attr_shortform_allfit(bp, dp)) { + if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { XFS_BMAP_INIT(args->flist, args->firstblock); - error = xfs_attr_leaf_to_shortform(bp, args); + error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { error = xfs_bmap_finish(&args->trans, @@ -1602,7 +1682,7 @@ out: * Fill in the disk block numbers in the state structure for the buffers * that are attached to the state structure. * This is done so that we can quickly reattach ourselves to those buffers - * after some set of transaction commit's has released these buffers. + * after some set of transaction commits have released these buffers. */ STATIC int xfs_attr_fillstate(xfs_da_state_t *state) @@ -1649,7 +1729,7 @@ xfs_attr_fillstate(xfs_da_state_t *state) /* * Reattach the buffers to the state structure based on the disk block * numbers stored in the state structure. - * This is done after some set of transaction commit's has released those + * This is done after some set of transaction commits have released those * buffers from our grip. */ STATIC int @@ -1707,7 +1787,7 @@ xfs_attr_refillstate(xfs_da_state_t *state) * block, ie: both true Btree attr lists and for single-leaf-blocks with * "remote" values taking up more blocks. */ -int +STATIC int xfs_attr_node_get(xfs_da_args_t *args) { xfs_da_state_t *state; @@ -1780,7 +1860,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) return(error); if (bp) { node = bp->data; - switch (INT_GET(node->hdr.info.magic, ARCH_CONVERT)) { + switch (be16_to_cpu(node->hdr.info.magic)) { case XFS_DA_NODE_MAGIC: xfs_attr_trace_l_cn("wrong blk", context, node); xfs_da_brelse(NULL, bp); @@ -1788,18 +1868,14 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) break; case XFS_ATTR_LEAF_MAGIC: leaf = bp->data; - if (cursor->hashval > - INT_GET(leaf->entries[ - INT_GET(leaf->hdr.count, - ARCH_CONVERT)-1].hashval, - ARCH_CONVERT)) { + if (cursor->hashval > be32_to_cpu(leaf->entries[ + be16_to_cpu(leaf->hdr.count)-1].hashval)) { xfs_attr_trace_l_cl("wrong blk", context, leaf); xfs_da_brelse(NULL, bp); bp = NULL; } else if (cursor->hashval <= - INT_GET(leaf->entries[0].hashval, - ARCH_CONVERT)) { + be32_to_cpu(leaf->entries[0].hashval)) { xfs_attr_trace_l_cl("maybe wrong blk", context, leaf); xfs_da_brelse(NULL, bp); @@ -1834,10 +1910,10 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) return(XFS_ERROR(EFSCORRUPTED)); } node = bp->data; - if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) + if (be16_to_cpu(node->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC) break; - if (unlikely(INT_GET(node->hdr.info.magic, ARCH_CONVERT) + if (unlikely(be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)) { XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)", XFS_ERRLEVEL_LOW, @@ -1847,19 +1923,17 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) return(XFS_ERROR(EFSCORRUPTED)); } btree = node->btree; - for (i = 0; - i < INT_GET(node->hdr.count, ARCH_CONVERT); + for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) { if (cursor->hashval - <= INT_GET(btree->hashval, - ARCH_CONVERT)) { - cursor->blkno = INT_GET(btree->before, ARCH_CONVERT); + <= be32_to_cpu(btree->hashval)) { + cursor->blkno = be32_to_cpu(btree->before); xfs_attr_trace_l_cb("descending", context, btree); break; } } - if (i == INT_GET(node->hdr.count, ARCH_CONVERT)) { + if (i == be16_to_cpu(node->hdr.count)) { xfs_da_brelse(NULL, bp); return(0); } @@ -1875,7 +1949,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) */ for (;;) { leaf = bp->data; - if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) + if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) { XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)", XFS_ERRLEVEL_LOW, @@ -1884,9 +1958,13 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) return(XFS_ERROR(EFSCORRUPTED)); } error = xfs_attr_leaf_list_int(bp, context); - if (error || !leaf->hdr.info.forw) - break; /* not really an error, buffer full or EOF */ - cursor->blkno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT); + if (error) { + xfs_da_brelse(NULL, bp); + return error; + } + if (context->seen_enough || leaf->hdr.info.forw == 0) + break; + cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); xfs_da_brelse(NULL, bp); error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, &bp, XFS_ATTR_FORK); @@ -1912,7 +1990,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) * Read the value associated with an attribute from the out-of-line buffer * that we stored it in. */ -STATIC int +int xfs_attr_rmtval_get(xfs_da_args_t *args) { xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; @@ -1934,7 +2012,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args) error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - NULL, 0, map, &nmap, NULL); + NULL, 0, map, &nmap, NULL, NULL); if (error) return(error); ASSERT(nmap >= 1); @@ -2012,7 +2090,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, args->firstblock, args->total, &map, &nmap, - args->flist); + args->flist, NULL); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, *args->firstblock, &committed); @@ -2063,7 +2141,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - args->firstblock, 0, &map, &nmap, NULL); + args->firstblock, 0, &map, &nmap, + NULL, NULL); if (error) { return(error); } @@ -2128,7 +2207,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) args->rmtblkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, args->firstblock, 0, &map, &nmap, - args->flist); + args->flist, NULL); if (error) { return(error); } @@ -2166,7 +2245,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) XFS_BMAP_INIT(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, - 1, args->firstblock, args->flist, &done); + 1, args->firstblock, args->flist, + NULL, &done); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, *args->firstblock, &committed); @@ -2249,9 +2329,10 @@ xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context, : 0, (__psunsigned_t)context->dupcnt, (__psunsigned_t)context->flags, - (__psunsigned_t)INT_GET(node->hdr.count, ARCH_CONVERT), - (__psunsigned_t)INT_GET(node->btree[0].hashval, ARCH_CONVERT), - (__psunsigned_t)INT_GET(node->btree[INT_GET(node->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT)); + (__psunsigned_t)be16_to_cpu(node->hdr.count), + (__psunsigned_t)be32_to_cpu(node->btree[0].hashval), + (__psunsigned_t)be32_to_cpu(node->btree[ + be16_to_cpu(node->hdr.count)-1].hashval)); } /* @@ -2278,8 +2359,8 @@ xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context, : 0, (__psunsigned_t)context->dupcnt, (__psunsigned_t)context->flags, - (__psunsigned_t)INT_GET(btree->hashval, ARCH_CONVERT), - (__psunsigned_t)INT_GET(btree->before, ARCH_CONVERT), + (__psunsigned_t)be32_to_cpu(btree->hashval), + (__psunsigned_t)be32_to_cpu(btree->before), (__psunsigned_t)NULL); } @@ -2307,9 +2388,10 @@ xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context, : 0, (__psunsigned_t)context->dupcnt, (__psunsigned_t)context->flags, - (__psunsigned_t)INT_GET(leaf->hdr.count, ARCH_CONVERT), - (__psunsigned_t)INT_GET(leaf->entries[0].hashval, ARCH_CONVERT), - (__psunsigned_t)INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT)); + (__psunsigned_t)be16_to_cpu(leaf->hdr.count), + (__psunsigned_t)be32_to_cpu(leaf->entries[0].hashval), + (__psunsigned_t)be32_to_cpu(leaf->entries[ + be16_to_cpu(leaf->hdr.count)-1].hashval)); } /* @@ -2344,61 +2426,61 @@ xfs_attr_trace_enter(int type, char *where, STATIC int posix_acl_access_set( - vnode_t *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS); } STATIC int posix_acl_access_remove( - struct vnode *vp, char *name, int xflags) + bhv_vnode_t *vp, char *name, int xflags) { return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); } STATIC int posix_acl_access_get( - vnode_t *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); } STATIC int posix_acl_access_exists( - vnode_t *vp) + bhv_vnode_t *vp) { return xfs_acl_vhasacl_access(vp); } STATIC int posix_acl_default_set( - vnode_t *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT); } STATIC int posix_acl_default_get( - vnode_t *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); } STATIC int posix_acl_default_remove( - struct vnode *vp, char *name, int xflags) + bhv_vnode_t *vp, char *name, int xflags) { return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); } STATIC int posix_acl_default_exists( - vnode_t *vp) + bhv_vnode_t *vp) { return xfs_acl_vhasacl_default(vp); } -struct attrnames posix_acl_access = { +STATIC struct attrnames posix_acl_access = { .attr_name = "posix_acl_access", .attr_namelen = sizeof("posix_acl_access") - 1, .attr_get = posix_acl_access_get, @@ -2407,7 +2489,7 @@ struct attrnames posix_acl_access = { .attr_exists = posix_acl_access_exists, }; -struct attrnames posix_acl_default = { +STATIC struct attrnames posix_acl_default = { .attr_name = "posix_acl_default", .attr_namelen = sizeof("posix_acl_default") - 1, .attr_get = posix_acl_default_get, @@ -2416,7 +2498,7 @@ struct attrnames posix_acl_default = { .attr_exists = posix_acl_default_exists, }; -struct attrnames *attr_system_names[] = +STATIC struct attrnames *attr_system_names[] = { &posix_acl_access, &posix_acl_default }; @@ -2426,21 +2508,18 @@ struct attrnames *attr_system_names[] = STATIC int attr_generic_set( - struct vnode *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { - int error; - - VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error); - return -error; + return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL); } STATIC int attr_generic_get( - struct vnode *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { int error, asize = size; - VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error); + error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL); if (!error) return asize; return -error; @@ -2448,12 +2527,9 @@ attr_generic_get( STATIC int attr_generic_remove( - struct vnode *vp, char *name, int xflags) + bhv_vnode_t *vp, char *name, int xflags) { - int error; - - VOP_ATTR_REMOVE(vp, name, xflags, NULL, error); - return -error; + return -bhv_vop_attr_remove(vp, name, xflags, NULL); } STATIC int @@ -2481,7 +2557,7 @@ attr_generic_listadd( STATIC int attr_system_list( - struct vnode *vp, + bhv_vnode_t *vp, void *data, size_t size, ssize_t *result) @@ -2503,12 +2579,12 @@ attr_system_list( int attr_generic_list( - struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result) + bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result) { attrlist_cursor_kern_t cursor = { 0 }; int error; - VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); + error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL); if (error > 0) return -error; *result = -error; @@ -2536,10 +2612,10 @@ attr_lookup_namespace( */ STATIC int attr_user_capable( - struct vnode *vp, + bhv_vnode_t *vp, cred_t *cred) { - struct inode *inode = LINVFS_GET_IP(vp); + struct inode *inode = vn_to_inode(vp); if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; @@ -2554,10 +2630,10 @@ attr_user_capable( STATIC int attr_trusted_capable( - struct vnode *vp, + bhv_vnode_t *vp, cred_t *cred) { - struct inode *inode = LINVFS_GET_IP(vp); + struct inode *inode = vn_to_inode(vp); if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; @@ -2568,7 +2644,7 @@ attr_trusted_capable( STATIC int attr_secure_capable( - struct vnode *vp, + bhv_vnode_t *vp, cred_t *cred) { return -ENOSECURITY; @@ -2576,7 +2652,7 @@ attr_secure_capable( STATIC int attr_system_set( - struct vnode *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { attrnames_t *namesp; int error; @@ -2595,7 +2671,7 @@ attr_system_set( STATIC int attr_system_get( - struct vnode *vp, char *name, void *data, size_t size, int xflags) + bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) { attrnames_t *namesp; @@ -2607,7 +2683,7 @@ attr_system_get( STATIC int attr_system_remove( - struct vnode *vp, char *name, int xflags) + bhv_vnode_t *vp, char *name, int xflags) { attrnames_t *namesp;