[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: Nathan Scott <nathans@sgi.com>
This commit is contained in:
parent
e8c8b3a79d
commit
aa82daa061
4 changed files with 90 additions and 99 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
|
|||
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 @@ xfs_attr_remove(bhv_desc_t *bdp, char *name, int flags, struct cred *cred)
|
|||
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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* 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,5 +1,5 @@
|
|||
/*
|
||||
* 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)
|
||||
|
|
Loading…
Reference in a new issue