Commit aa82daa0 authored by Nathan Scott's avatar Nathan Scott
Browse files

[XFS] Move some code around to prepare for the upcoming extended


attributes format change (attr2).

SGI-PV: 941645
SGI-Modid: xfs-linux:xfs-kern:23833a

Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent e8c8b3a7
Loading
Loading
Loading
Loading
+64 −53
Original line number Diff line number Diff line
/*
 * 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
@@ -200,40 +200,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, 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.
@@ -270,7 +248,8 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
	/* Determine space new attribute will use, and if it will be inline
	 * or out of line.
	 */
	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) {
@@ -456,32 +435,21 @@ 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, 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;
	int             namelen, error;

	ASSERT(MAXNAMELEN-1<=0xff); /* length is stored in uint8 */
	namelen = strlen(name);
	if (namelen >= MAXNAMELEN)
		return EFAULT; /* match irix behaviour */
		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);
@@ -489,14 +457,25 @@ xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred)
	     (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, 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.
	 */
@@ -612,6 +591,38 @@ out:
	return(error);
}

int
xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred)
{
	xfs_inode_t         *dp;
	int                 namelen, error;

	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 (!(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_remove_int(dp, name, namelen, flags);
}

/*
 * Generate a list of extended attribute names and optionally
 * also value lengths.  Positive return value follows the XFS
+22 −17
Original line number Diff line number Diff line
/*
 * Copyright (c) 2000-2003 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
@@ -898,7 +898,7 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args)
	ASSERT((args->index >= 0)
		&& (args->index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
	hdr = &leaf->hdr;
	entsize = xfs_attr_leaf_newentsize(args,
	entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
			   args->trans->t_mountp->m_sb.sb_blocksize, NULL);

	/*
@@ -995,13 +995,14 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
	mp = args->trans->t_mountp;
	ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
	ASSERT((INT_GET(map->base, ARCH_CONVERT) & 0x3) == 0);
	ASSERT(INT_GET(map->size, ARCH_CONVERT)
				>= xfs_attr_leaf_newentsize(args,
	ASSERT(INT_GET(map->size, ARCH_CONVERT) >=
		xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
					 mp->m_sb.sb_blocksize, NULL));
	ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
	ASSERT((INT_GET(map->size, ARCH_CONVERT) & 0x3) == 0);
	INT_MOD(map->size, ARCH_CONVERT,
		-xfs_attr_leaf_newentsize(args, mp->m_sb.sb_blocksize, &tmp));
		-xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
					  mp->m_sb.sb_blocksize, &tmp));
	INT_SET(entry->nameidx, ARCH_CONVERT,
					INT_GET(map->base, ARCH_CONVERT)
				      + INT_GET(map->size, ARCH_CONVERT));
@@ -1357,7 +1358,9 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
	half  = (max+1) * sizeof(*entry);
	half += INT_GET(hdr1->usedbytes, ARCH_CONVERT)
				+ INT_GET(hdr2->usedbytes, ARCH_CONVERT)
				+ xfs_attr_leaf_newentsize(state->args,
				+ xfs_attr_leaf_newentsize(
						state->args->namelen,
						state->args->valuelen,
						state->blocksize, NULL);
	half /= 2;
	lastdelta = state->blocksize;
@@ -1370,9 +1373,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
		 */
		if (count == blk1->index) {
			tmp = totallen + sizeof(*entry) +
				xfs_attr_leaf_newentsize(state->args,
							 state->blocksize,
							 NULL);
				xfs_attr_leaf_newentsize(
						state->args->namelen,
						state->args->valuelen,
						state->blocksize, NULL);
			if (XFS_ATTR_ABS(half - tmp) > lastdelta)
				break;
			lastdelta = XFS_ATTR_ABS(half - tmp);
@@ -1408,9 +1412,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
	totallen -= count * sizeof(*entry);
	if (foundit) {
		totallen -= sizeof(*entry) +
				xfs_attr_leaf_newentsize(state->args,
							 state->blocksize,
							 NULL);
				xfs_attr_leaf_newentsize(
						state->args->namelen,
						state->args->valuelen,
						state->blocksize, NULL);
	}

	*countarg = count;
@@ -2253,17 +2258,17 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
 * a "local" or a "remote" attribute.
 */
int
xfs_attr_leaf_newentsize(xfs_da_args_t *args, int blocksize, int *local)
xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
{
	int size;

	size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(args->namelen, args->valuelen);
	size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(namelen, valuelen);
	if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) {
		if (local) {
			*local = 1;
		}
	} else {
		size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(args->namelen);
		size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(namelen);
		if (local) {
			*local = 0;
		}
+3 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2000, 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
 * Copyright (c) 2000, 2002-2003, 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
@@ -289,7 +290,7 @@ int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
xfs_dahash_t	xfs_attr_leaf_lasthash(struct xfs_dabuf *bp, int *count);
int	xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp,
				   struct xfs_dabuf *leaf2_bp);
int	xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize,
int	xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
					int *local);
int	xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);

+1 −27
Original line number Diff line number Diff line
/*
 * 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
@@ -190,9 +190,6 @@ xfs_da_split(xfs_da_state_t *state)
		 */
		switch (oldblk->magic) {
		case XFS_ATTR_LEAF_MAGIC:
#ifndef __KERNEL__
			return(ENOTTY);
#else
			error = xfs_attr_leaf_split(state, oldblk, newblk);
			if ((error != 0) && (error != ENOSPC)) {
				return(error);	/* GROT: attr is inconsistent */
@@ -218,7 +215,6 @@ xfs_da_split(xfs_da_state_t *state)
				return(error);	/* GROT: attr inconsistent */
			addblk = newblk;
			break;
#endif
		case XFS_DIR_LEAF_MAGIC:
			ASSERT(XFS_DIR_IS_V1(state->mp));
			error = xfs_dir_leaf_split(state, oldblk, newblk);
@@ -706,18 +702,12 @@ xfs_da_join(xfs_da_state_t *state)
		 */
		switch (drop_blk->magic) {
		case XFS_ATTR_LEAF_MAGIC:
#ifndef __KERNEL__
			error = ENOTTY;
#else
			error = xfs_attr_leaf_toosmall(state, &action);
#endif
			if (error)
				return(error);
			if (action == 0)
				return(0);
#ifdef __KERNEL__
			xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
#endif
			break;
		case XFS_DIR_LEAF_MAGIC:
			ASSERT(XFS_DIR_IS_V1(state->mp));
@@ -973,13 +963,11 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
	level = path->active-1;
	blk = &path->blk[ level ];
	switch (blk->magic) {
#ifdef __KERNEL__
	case XFS_ATTR_LEAF_MAGIC:
		lasthash = xfs_attr_leaf_lasthash(blk->bp, &count);
		if (count == 0)
			return;
		break;
#endif
	case XFS_DIR_LEAF_MAGIC:
		ASSERT(XFS_DIR_IS_V1(state->mp));
		lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
@@ -1220,12 +1208,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
				blkno = INT_GET(btree->before, ARCH_CONVERT);
			}
		}
#ifdef __KERNEL__
		else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC) {
			blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
			break;
		}
#endif
		else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) {
			blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
			break;
@@ -1252,13 +1238,11 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
			retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
							&blk->index, state);
		}
#ifdef __KERNEL__
		else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
			retval = xfs_attr_leaf_lookup_int(blk->bp, args);
			blk->index = args->index;
			args->blkno = blk->blkno;
		}
#endif
		if (((retval == ENOENT) || (retval == ENOATTR)) &&
		    (blk->hashval == args->hashval)) {
			error = xfs_da_path_shift(state, &state->path, 1, 1,
@@ -1268,12 +1252,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
			if (retval == 0) {
				continue;
			}
#ifdef __KERNEL__
			else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
				/* path_shift() gives ENOENT */
				retval = XFS_ERROR(ENOATTR);
			}
#endif
		}
		break;
	}
@@ -1312,11 +1294,9 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
	ASSERT(old_blk->magic == new_blk->magic);

	switch (old_blk->magic) {
#ifdef __KERNEL__
	case XFS_ATTR_LEAF_MAGIC:
		before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
		break;
#endif
	case XFS_DIR_LEAF_MAGIC:
		ASSERT(XFS_DIR_IS_V1(state->mp));
		before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
@@ -1587,12 +1567,10 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
			ASSERT(level == path->active-1);
			blk->index = 0;
			switch(blk->magic) {
#ifdef __KERNEL__
			case XFS_ATTR_LEAF_MAGIC:
				blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
								      NULL);
				break;
#endif
			case XFS_DIR_LEAF_MAGIC:
				ASSERT(XFS_DIR_IS_V1(state->mp));
				blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
@@ -2200,20 +2178,16 @@ xfs_da_do_buf(
			error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO);
			break;
		case 1:
#ifndef __KERNEL__
		case 2:
#endif
			bp = NULL;
			error = xfs_trans_read_buf(mp, trans, mp->m_ddev_targp,
				mappedbno, nmapped, 0, &bp);
			break;
#ifdef __KERNEL__
		case 3:
			xfs_baread(mp->m_ddev_targp, mappedbno, nmapped);
			error = 0;
			bp = NULL;
			break;
#endif
		}
		if (error) {
			if (bp)