aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_attr.c')
-rw-r--r--fs/xfs/xfs_attr.c61
1 files changed, 31 insertions, 30 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index ce9f673f2b4c..c2939b8f8d24 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -200,7 +200,7 @@ xfs_attr_get(bhv_desc_t *bdp, char *name, char *value, int *valuelenp,
200 return(error); 200 return(error);
201} 201}
202 202
203int 203STATIC int
204xfs_attr_set_int(xfs_inode_t *dp, char *name, int namelen, 204xfs_attr_set_int(xfs_inode_t *dp, char *name, int namelen,
205 char *value, int valuelen, int flags) 205 char *value, int valuelen, int flags)
206{ 206{
@@ -220,12 +220,18 @@ xfs_attr_set_int(xfs_inode_t *dp, char *name, int namelen,
220 return (error); 220 return (error);
221 221
222 /* 222 /*
223 * Determine space new attribute will use, and if it would be
224 * "local" or "remote" (note: local != inline).
225 */
226 size = xfs_attr_leaf_newentsize(namelen, valuelen,
227 mp->m_sb.sb_blocksize, &local);
228
229 /*
223 * If the inode doesn't have an attribute fork, add one. 230 * If the inode doesn't have an attribute fork, add one.
224 * (inode must not be locked when we call this routine) 231 * (inode must not be locked when we call this routine)
225 */ 232 */
226 if (XFS_IFORK_Q(dp) == 0) { 233 if (XFS_IFORK_Q(dp) == 0) {
227 error = xfs_bmap_add_attrfork(dp, rsvd); 234 if ((error = xfs_bmap_add_attrfork(dp, size, rsvd)))
228 if (error)
229 return(error); 235 return(error);
230 } 236 }
231 237
@@ -243,14 +249,9 @@ xfs_attr_set_int(xfs_inode_t *dp, char *name, int namelen,
243 args.firstblock = &firstblock; 249 args.firstblock = &firstblock;
244 args.flist = &flist; 250 args.flist = &flist;
245 args.whichfork = XFS_ATTR_FORK; 251 args.whichfork = XFS_ATTR_FORK;
252 args.addname = 1;
246 args.oknoent = 1; 253 args.oknoent = 1;
247 254
248 /* Determine space new attribute will use, and if it will be inline
249 * or out of line.
250 */
251 size = xfs_attr_leaf_newentsize(namelen, valuelen,
252 mp->m_sb.sb_blocksize, &local);
253
254 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); 255 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
255 if (local) { 256 if (local) {
256 if (size > (mp->m_sb.sb_blocksize >> 1)) { 257 if (size > (mp->m_sb.sb_blocksize >> 1)) {
@@ -322,7 +323,7 @@ xfs_attr_set_int(xfs_inode_t *dp, char *name, int namelen,
322 * Build initial attribute list (if required). 323 * Build initial attribute list (if required).
323 */ 324 */
324 if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) 325 if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
325 (void)xfs_attr_shortform_create(&args); 326 xfs_attr_shortform_create(&args);
326 327
327 /* 328 /*
328 * Try to add the attr to the attribute list in 329 * Try to add the attr to the attribute list in
@@ -467,7 +468,7 @@ xfs_attr_set(bhv_desc_t *bdp, char *name, char *value, int valuelen, int flags,
467 * Generic handler routine to remove a name from an attribute list. 468 * Generic handler routine to remove a name from an attribute list.
468 * Transitions attribute list from Btree to shortform as necessary. 469 * Transitions attribute list from Btree to shortform as necessary.
469 */ 470 */
470int 471STATIC int
471xfs_attr_remove_int(xfs_inode_t *dp, char *name, int namelen, int flags) 472xfs_attr_remove_int(xfs_inode_t *dp, char *name, int namelen, int flags)
472{ 473{
473 xfs_da_args_t args; 474 xfs_da_args_t args;
@@ -523,7 +524,6 @@ xfs_attr_remove_int(xfs_inode_t *dp, char *name, int namelen, int flags)
523 XFS_ATTRRM_LOG_COUNT))) { 524 XFS_ATTRRM_LOG_COUNT))) {
524 xfs_trans_cancel(args.trans, 0); 525 xfs_trans_cancel(args.trans, 0);
525 return(error); 526 return(error);
526
527 } 527 }
528 528
529 xfs_ilock(dp, XFS_ILOCK_EXCL); 529 xfs_ilock(dp, XFS_ILOCK_EXCL);
@@ -822,7 +822,7 @@ out:
822STATIC int 822STATIC int
823xfs_attr_shortform_addname(xfs_da_args_t *args) 823xfs_attr_shortform_addname(xfs_da_args_t *args)
824{ 824{
825 int newsize, retval; 825 int newsize, forkoff, retval;
826 826
827 retval = xfs_attr_shortform_lookup(args); 827 retval = xfs_attr_shortform_lookup(args);
828 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) { 828 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
@@ -834,16 +834,18 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
834 ASSERT(retval == 0); 834 ASSERT(retval == 0);
835 } 835 }
836 836
837 if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
838 args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
839 return(XFS_ERROR(ENOSPC));
840
837 newsize = XFS_ATTR_SF_TOTSIZE(args->dp); 841 newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
838 newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); 842 newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
839 if ((newsize <= XFS_IFORK_ASIZE(args->dp)) && 843
840 (args->namelen < XFS_ATTR_SF_ENTSIZE_MAX) && 844 forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
841 (args->valuelen < XFS_ATTR_SF_ENTSIZE_MAX)) { 845 if (!forkoff)
842 retval = xfs_attr_shortform_add(args);
843 ASSERT(retval == 0);
844 } else {
845 return(XFS_ERROR(ENOSPC)); 846 return(XFS_ERROR(ENOSPC));
846 } 847
848 xfs_attr_shortform_add(args, forkoff);
847 return(0); 849 return(0);
848} 850}
849 851
@@ -863,7 +865,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
863{ 865{
864 xfs_inode_t *dp; 866 xfs_inode_t *dp;
865 xfs_dabuf_t *bp; 867 xfs_dabuf_t *bp;
866 int retval, error, committed; 868 int retval, error, committed, forkoff;
867 869
868 /* 870 /*
869 * Read the (only) block in the attribute list in. 871 * Read the (only) block in the attribute list in.
@@ -1006,9 +1008,9 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
1006 /* 1008 /*
1007 * If the result is small enough, shrink it all into the inode. 1009 * If the result is small enough, shrink it all into the inode.
1008 */ 1010 */
1009 if (xfs_attr_shortform_allfit(bp, dp)) { 1011 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1010 XFS_BMAP_INIT(args->flist, args->firstblock); 1012 XFS_BMAP_INIT(args->flist, args->firstblock);
1011 error = xfs_attr_leaf_to_shortform(bp, args); 1013 error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
1012 /* bp is gone due to xfs_da_shrink_inode */ 1014 /* bp is gone due to xfs_da_shrink_inode */
1013 if (!error) { 1015 if (!error) {
1014 error = xfs_bmap_finish(&args->trans, 1016 error = xfs_bmap_finish(&args->trans,
@@ -1060,8 +1062,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1060{ 1062{
1061 xfs_inode_t *dp; 1063 xfs_inode_t *dp;
1062 xfs_dabuf_t *bp; 1064 xfs_dabuf_t *bp;
1063 int committed; 1065 int error, committed, forkoff;
1064 int error;
1065 1066
1066 /* 1067 /*
1067 * Remove the attribute. 1068 * Remove the attribute.
@@ -1086,9 +1087,9 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1086 /* 1087 /*
1087 * If the result is small enough, shrink it all into the inode. 1088 * If the result is small enough, shrink it all into the inode.
1088 */ 1089 */
1089 if (xfs_attr_shortform_allfit(bp, dp)) { 1090 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1090 XFS_BMAP_INIT(args->flist, args->firstblock); 1091 XFS_BMAP_INIT(args->flist, args->firstblock);
1091 error = xfs_attr_leaf_to_shortform(bp, args); 1092 error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
1092 /* bp is gone due to xfs_da_shrink_inode */ 1093 /* bp is gone due to xfs_da_shrink_inode */
1093 if (!error) { 1094 if (!error) {
1094 error = xfs_bmap_finish(&args->trans, args->flist, 1095 error = xfs_bmap_finish(&args->trans, args->flist,
@@ -1459,7 +1460,7 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1459 xfs_da_state_blk_t *blk; 1460 xfs_da_state_blk_t *blk;
1460 xfs_inode_t *dp; 1461 xfs_inode_t *dp;
1461 xfs_dabuf_t *bp; 1462 xfs_dabuf_t *bp;
1462 int retval, error, committed; 1463 int retval, error, committed, forkoff;
1463 1464
1464 /* 1465 /*
1465 * Tie a string around our finger to remind us where we are. 1466 * Tie a string around our finger to remind us where we are.
@@ -1580,9 +1581,9 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1580 bp->data)->hdr.info.magic, ARCH_CONVERT) 1581 bp->data)->hdr.info.magic, ARCH_CONVERT)
1581 == XFS_ATTR_LEAF_MAGIC); 1582 == XFS_ATTR_LEAF_MAGIC);
1582 1583
1583 if (xfs_attr_shortform_allfit(bp, dp)) { 1584 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1584 XFS_BMAP_INIT(args->flist, args->firstblock); 1585 XFS_BMAP_INIT(args->flist, args->firstblock);
1585 error = xfs_attr_leaf_to_shortform(bp, args); 1586 error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
1586 /* bp is gone due to xfs_da_shrink_inode */ 1587 /* bp is gone due to xfs_da_shrink_inode */
1587 if (!error) { 1588 if (!error) {
1588 error = xfs_bmap_finish(&args->trans, 1589 error = xfs_bmap_finish(&args->trans,