aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_attr_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_attr_leaf.c')
-rw-r--r--fs/xfs/xfs_attr_leaf.c273
1 files changed, 192 insertions, 81 deletions
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 1cdd574c63a9..35e557b00db2 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -1,46 +1,26 @@
1/* 1/*
2 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or
5 * under the terms of version 2 of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
7 * 8 *
8 * This program is distributed in the hope that it would be useful, but 9 * This program is distributed in the hope that it would be useful,
9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
11 * 13 *
12 * Further, this software is distributed without any warranty that it is 14 * You should have received a copy of the GNU General Public License
13 * free of the rightful claim of any third person regarding infringement 15 * along with this program; if not, write the Free Software Foundation,
14 * or the like. Any license provided herein, whether implied or 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */ 17 */
32/*
33 * xfs_attr_leaf.c
34 *
35 * GROT: figure out how to recover gracefully when bmap returns ENOSPC.
36 */
37
38#include "xfs.h" 18#include "xfs.h"
39 19#include "xfs_fs.h"
40#include "xfs_macros.h"
41#include "xfs_types.h" 20#include "xfs_types.h"
42#include "xfs_inum.h" 21#include "xfs_bit.h"
43#include "xfs_log.h" 22#include "xfs_log.h"
23#include "xfs_inum.h"
44#include "xfs_trans.h" 24#include "xfs_trans.h"
45#include "xfs_sb.h" 25#include "xfs_sb.h"
46#include "xfs_ag.h" 26#include "xfs_ag.h"
@@ -48,23 +28,22 @@
48#include "xfs_dir2.h" 28#include "xfs_dir2.h"
49#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
50#include "xfs_mount.h" 30#include "xfs_mount.h"
51#include "xfs_alloc_btree.h" 31#include "xfs_da_btree.h"
52#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h"
53#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
54#include "xfs_alloc.h" 35#include "xfs_alloc.h"
55#include "xfs_btree.h" 36#include "xfs_btree.h"
56#include "xfs_attr_sf.h"
57#include "xfs_dir_sf.h" 37#include "xfs_dir_sf.h"
58#include "xfs_dir2_sf.h" 38#include "xfs_dir2_sf.h"
39#include "xfs_attr_sf.h"
59#include "xfs_dinode.h" 40#include "xfs_dinode.h"
60#include "xfs_inode_item.h"
61#include "xfs_inode.h" 41#include "xfs_inode.h"
42#include "xfs_inode_item.h"
62#include "xfs_bmap.h" 43#include "xfs_bmap.h"
63#include "xfs_da_btree.h"
64#include "xfs_attr.h" 44#include "xfs_attr.h"
65#include "xfs_attr_leaf.h" 45#include "xfs_attr_leaf.h"
66#include "xfs_error.h" 46#include "xfs_error.h"
67#include "xfs_bit.h"
68 47
69/* 48/*
70 * xfs_attr_leaf.c 49 * xfs_attr_leaf.c
@@ -118,13 +97,82 @@ STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
118 97
119 98
120/*======================================================================== 99/*========================================================================
121 * External routines when dirsize < XFS_LITINO(mp). 100 * External routines when attribute fork size < XFS_LITINO(mp).
122 *========================================================================*/ 101 *========================================================================*/
123 102
124/* 103/*
125 * Create the initial contents of a shortform attribute list. 104 * Query whether the requested number of additional bytes of extended
105 * attribute space will be able to fit inline.
106 * Returns zero if not, else the di_forkoff fork offset to be used in the
107 * literal area for attribute data once the new bytes have been added.
108 *
109 * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
110 * special case for dev/uuid inodes, they have fixed size data forks.
126 */ 111 */
127int 112int
113xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
114{
115 int offset;
116 int minforkoff; /* lower limit on valid forkoff locations */
117 int maxforkoff; /* upper limit on valid forkoff locations */
118 xfs_mount_t *mp = dp->i_mount;
119
120 offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
121
122 switch (dp->i_d.di_format) {
123 case XFS_DINODE_FMT_DEV:
124 minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
125 return (offset >= minforkoff) ? minforkoff : 0;
126 case XFS_DINODE_FMT_UUID:
127 minforkoff = roundup(sizeof(uuid_t), 8) >> 3;
128 return (offset >= minforkoff) ? minforkoff : 0;
129 }
130
131 if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
132 if (bytes <= XFS_IFORK_ASIZE(dp))
133 return mp->m_attroffset >> 3;
134 return 0;
135 }
136
137 /* data fork btree root can have at least this many key/ptr pairs */
138 minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
139 minforkoff = roundup(minforkoff, 8) >> 3;
140
141 /* attr fork btree root can have at least this many key/ptr pairs */
142 maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
143 maxforkoff = maxforkoff >> 3; /* rounded down */
144
145 if (offset >= minforkoff && offset < maxforkoff)
146 return offset;
147 if (offset >= maxforkoff)
148 return maxforkoff;
149 return 0;
150}
151
152/*
153 * Switch on the ATTR2 superblock bit (implies also FEATURES2)
154 */
155STATIC void
156xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
157{
158 unsigned long s;
159
160 if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
161 !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
162 s = XFS_SB_LOCK(mp);
163 if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
164 XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
165 XFS_SB_UNLOCK(mp, s);
166 xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
167 } else
168 XFS_SB_UNLOCK(mp, s);
169 }
170}
171
172/*
173 * Create the initial contents of a shortform attribute list.
174 */
175void
128xfs_attr_shortform_create(xfs_da_args_t *args) 176xfs_attr_shortform_create(xfs_da_args_t *args)
129{ 177{
130 xfs_attr_sf_hdr_t *hdr; 178 xfs_attr_sf_hdr_t *hdr;
@@ -148,29 +196,37 @@ xfs_attr_shortform_create(xfs_da_args_t *args)
148 hdr->count = 0; 196 hdr->count = 0;
149 INT_SET(hdr->totsize, ARCH_CONVERT, sizeof(*hdr)); 197 INT_SET(hdr->totsize, ARCH_CONVERT, sizeof(*hdr));
150 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 198 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
151 return(0);
152} 199}
153 200
154/* 201/*
155 * Add a name/value pair to the shortform attribute list. 202 * Add a name/value pair to the shortform attribute list.
156 * Overflow from the inode has already been checked for. 203 * Overflow from the inode has already been checked for.
157 */ 204 */
158int 205void
159xfs_attr_shortform_add(xfs_da_args_t *args) 206xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
160{ 207{
161 xfs_attr_shortform_t *sf; 208 xfs_attr_shortform_t *sf;
162 xfs_attr_sf_entry_t *sfe; 209 xfs_attr_sf_entry_t *sfe;
163 int i, offset, size; 210 int i, offset, size;
211 xfs_mount_t *mp;
164 xfs_inode_t *dp; 212 xfs_inode_t *dp;
165 xfs_ifork_t *ifp; 213 xfs_ifork_t *ifp;
166 214
167 dp = args->dp; 215 dp = args->dp;
216 mp = dp->i_mount;
217 dp->i_d.di_forkoff = forkoff;
218 dp->i_df.if_ext_max =
219 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
220 dp->i_afp->if_ext_max =
221 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
222
168 ifp = dp->i_afp; 223 ifp = dp->i_afp;
169 ASSERT(ifp->if_flags & XFS_IFINLINE); 224 ASSERT(ifp->if_flags & XFS_IFINLINE);
170 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; 225 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
171 sfe = &sf->list[0]; 226 sfe = &sf->list[0];
172 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); 227 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT);
173 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { 228 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
229#ifdef DEBUG
174 if (sfe->namelen != args->namelen) 230 if (sfe->namelen != args->namelen)
175 continue; 231 continue;
176 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 232 if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
@@ -181,7 +237,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
181 if (((args->flags & ATTR_ROOT) != 0) != 237 if (((args->flags & ATTR_ROOT) != 0) !=
182 ((sfe->flags & XFS_ATTR_ROOT) != 0)) 238 ((sfe->flags & XFS_ATTR_ROOT) != 0))
183 continue; 239 continue;
184 return(XFS_ERROR(EEXIST)); 240 ASSERT(0);
241#endif
185 } 242 }
186 243
187 offset = (char *)sfe - (char *)sf; 244 offset = (char *)sfe - (char *)sf;
@@ -200,11 +257,11 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
200 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size); 257 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size);
201 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 258 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
202 259
203 return(0); 260 xfs_sbversion_add_attr2(mp, args->trans);
204} 261}
205 262
206/* 263/*
207 * Remove a name from the shortform attribute list structure. 264 * Remove an attribute from the shortform attribute list structure.
208 */ 265 */
209int 266int
210xfs_attr_shortform_remove(xfs_da_args_t *args) 267xfs_attr_shortform_remove(xfs_da_args_t *args)
@@ -212,17 +269,16 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
212 xfs_attr_shortform_t *sf; 269 xfs_attr_shortform_t *sf;
213 xfs_attr_sf_entry_t *sfe; 270 xfs_attr_sf_entry_t *sfe;
214 int base, size=0, end, totsize, i; 271 int base, size=0, end, totsize, i;
272 xfs_mount_t *mp;
215 xfs_inode_t *dp; 273 xfs_inode_t *dp;
216 274
217 /*
218 * Remove the attribute.
219 */
220 dp = args->dp; 275 dp = args->dp;
276 mp = dp->i_mount;
221 base = sizeof(xfs_attr_sf_hdr_t); 277 base = sizeof(xfs_attr_sf_hdr_t);
222 sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; 278 sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
223 sfe = &sf->list[0]; 279 sfe = &sf->list[0];
224 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); 280 end = INT_GET(sf->hdr.count, ARCH_CONVERT);
225 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), 281 for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
226 base += size, i++) { 282 base += size, i++) {
227 size = XFS_ATTR_SF_ENTSIZE(sfe); 283 size = XFS_ATTR_SF_ENTSIZE(sfe);
228 if (sfe->namelen != args->namelen) 284 if (sfe->namelen != args->namelen)
@@ -237,19 +293,51 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
237 continue; 293 continue;
238 break; 294 break;
239 } 295 }
240 if (i == INT_GET(sf->hdr.count, ARCH_CONVERT)) 296 if (i == end)
241 return(XFS_ERROR(ENOATTR)); 297 return(XFS_ERROR(ENOATTR));
242 298
299 /*
300 * Fix up the attribute fork data, covering the hole
301 */
243 end = base + size; 302 end = base + size;
244 totsize = INT_GET(sf->hdr.totsize, ARCH_CONVERT); 303 totsize = INT_GET(sf->hdr.totsize, ARCH_CONVERT);
245 if (end != totsize) { 304 if (end != totsize)
246 memmove(&((char *)sf)[base], &((char *)sf)[end], 305 memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
247 totsize - end);
248 }
249 INT_MOD(sf->hdr.count, ARCH_CONVERT, -1); 306 INT_MOD(sf->hdr.count, ARCH_CONVERT, -1);
250 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, -size); 307 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, -size);
251 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); 308
252 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 309 /*
310 * Fix up the start offset of the attribute fork
311 */
312 totsize -= size;
313 if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname) {
314 /*
315 * Last attribute now removed, revert to original
316 * inode format making all literal area available
317 * to the data fork once more.
318 */
319 xfs_idestroy_fork(dp, XFS_ATTR_FORK);
320 dp->i_d.di_forkoff = 0;
321 dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
322 ASSERT(dp->i_d.di_anextents == 0);
323 ASSERT(dp->i_afp == NULL);
324 dp->i_df.if_ext_max =
325 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
326 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
327 } else {
328 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
329 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
330 ASSERT(dp->i_d.di_forkoff);
331 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname);
332 dp->i_afp->if_ext_max =
333 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
334 dp->i_df.if_ext_max =
335 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
336 xfs_trans_log_inode(args->trans, dp,
337 XFS_ILOG_CORE | XFS_ILOG_ADATA);
338 }
339
340 xfs_sbversion_add_attr2(mp, args->trans);
253 341
254 return(0); 342 return(0);
255} 343}
@@ -561,7 +649,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
561 /* 649 /*
562 * Sort the entries on hash then entno. 650 * Sort the entries on hash then entno.
563 */ 651 */
564 qsort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare); 652 xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_attr_shortform_compare);
565 653
566 /* 654 /*
567 * Re-find our place IN THE SORTED LIST. 655 * Re-find our place IN THE SORTED LIST.
@@ -649,14 +737,16 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
649 + name_loc->namelen 737 + name_loc->namelen
650 + INT_GET(name_loc->valuelen, ARCH_CONVERT); 738 + INT_GET(name_loc->valuelen, ARCH_CONVERT);
651 } 739 }
652 return( bytes < XFS_IFORK_ASIZE(dp) ); 740 if (bytes == sizeof(struct xfs_attr_sf_hdr))
741 return(-1);
742 return(xfs_attr_shortform_bytesfit(dp, bytes));
653} 743}
654 744
655/* 745/*
656 * Convert a leaf attribute list to shortform attribute list 746 * Convert a leaf attribute list to shortform attribute list
657 */ 747 */
658int 748int
659xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args) 749xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
660{ 750{
661 xfs_attr_leafblock_t *leaf; 751 xfs_attr_leafblock_t *leaf;
662 xfs_attr_leaf_entry_t *entry; 752 xfs_attr_leaf_entry_t *entry;
@@ -683,9 +773,25 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
683 error = xfs_da_shrink_inode(args, 0, bp); 773 error = xfs_da_shrink_inode(args, 0, bp);
684 if (error) 774 if (error)
685 goto out; 775 goto out;
686 error = xfs_attr_shortform_create(args); 776
687 if (error) 777 if (forkoff == -1) {
778 /*
779 * Last attribute was removed, revert to original
780 * inode format making all literal area available
781 * to the data fork once more.
782 */
783 xfs_idestroy_fork(dp, XFS_ATTR_FORK);
784 dp->i_d.di_forkoff = 0;
785 dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
786 ASSERT(dp->i_d.di_anextents == 0);
787 ASSERT(dp->i_afp == NULL);
788 dp->i_df.if_ext_max =
789 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
790 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
688 goto out; 791 goto out;
792 }
793
794 xfs_attr_shortform_create(args);
689 795
690 /* 796 /*
691 * Copy the attributes 797 * Copy the attributes
@@ -713,7 +819,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
713 nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT); 819 nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
714 nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : 820 nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
715 ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); 821 ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
716 xfs_attr_shortform_add(&nargs); 822 xfs_attr_shortform_add(&nargs, forkoff);
717 } 823 }
718 error = 0; 824 error = 0;
719 825
@@ -898,7 +1004,7 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args)
898 ASSERT((args->index >= 0) 1004 ASSERT((args->index >= 0)
899 && (args->index <= INT_GET(leaf->hdr.count, ARCH_CONVERT))); 1005 && (args->index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
900 hdr = &leaf->hdr; 1006 hdr = &leaf->hdr;
901 entsize = xfs_attr_leaf_newentsize(args, 1007 entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
902 args->trans->t_mountp->m_sb.sb_blocksize, NULL); 1008 args->trans->t_mountp->m_sb.sb_blocksize, NULL);
903 1009
904 /* 1010 /*
@@ -995,13 +1101,14 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
995 mp = args->trans->t_mountp; 1101 mp = args->trans->t_mountp;
996 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); 1102 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
997 ASSERT((INT_GET(map->base, ARCH_CONVERT) & 0x3) == 0); 1103 ASSERT((INT_GET(map->base, ARCH_CONVERT) & 0x3) == 0);
998 ASSERT(INT_GET(map->size, ARCH_CONVERT) 1104 ASSERT(INT_GET(map->size, ARCH_CONVERT) >=
999 >= xfs_attr_leaf_newentsize(args, 1105 xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
1000 mp->m_sb.sb_blocksize, NULL)); 1106 mp->m_sb.sb_blocksize, NULL));
1001 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); 1107 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
1002 ASSERT((INT_GET(map->size, ARCH_CONVERT) & 0x3) == 0); 1108 ASSERT((INT_GET(map->size, ARCH_CONVERT) & 0x3) == 0);
1003 INT_MOD(map->size, ARCH_CONVERT, 1109 INT_MOD(map->size, ARCH_CONVERT,
1004 -xfs_attr_leaf_newentsize(args, mp->m_sb.sb_blocksize, &tmp)); 1110 -xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
1111 mp->m_sb.sb_blocksize, &tmp));
1005 INT_SET(entry->nameidx, ARCH_CONVERT, 1112 INT_SET(entry->nameidx, ARCH_CONVERT,
1006 INT_GET(map->base, ARCH_CONVERT) 1113 INT_GET(map->base, ARCH_CONVERT)
1007 + INT_GET(map->size, ARCH_CONVERT)); 1114 + INT_GET(map->size, ARCH_CONVERT));
@@ -1357,8 +1464,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
1357 half = (max+1) * sizeof(*entry); 1464 half = (max+1) * sizeof(*entry);
1358 half += INT_GET(hdr1->usedbytes, ARCH_CONVERT) 1465 half += INT_GET(hdr1->usedbytes, ARCH_CONVERT)
1359 + INT_GET(hdr2->usedbytes, ARCH_CONVERT) 1466 + INT_GET(hdr2->usedbytes, ARCH_CONVERT)
1360 + xfs_attr_leaf_newentsize(state->args, 1467 + xfs_attr_leaf_newentsize(
1361 state->blocksize, NULL); 1468 state->args->namelen,
1469 state->args->valuelen,
1470 state->blocksize, NULL);
1362 half /= 2; 1471 half /= 2;
1363 lastdelta = state->blocksize; 1472 lastdelta = state->blocksize;
1364 entry = &leaf1->entries[0]; 1473 entry = &leaf1->entries[0];
@@ -1370,9 +1479,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
1370 */ 1479 */
1371 if (count == blk1->index) { 1480 if (count == blk1->index) {
1372 tmp = totallen + sizeof(*entry) + 1481 tmp = totallen + sizeof(*entry) +
1373 xfs_attr_leaf_newentsize(state->args, 1482 xfs_attr_leaf_newentsize(
1374 state->blocksize, 1483 state->args->namelen,
1375 NULL); 1484 state->args->valuelen,
1485 state->blocksize, NULL);
1376 if (XFS_ATTR_ABS(half - tmp) > lastdelta) 1486 if (XFS_ATTR_ABS(half - tmp) > lastdelta)
1377 break; 1487 break;
1378 lastdelta = XFS_ATTR_ABS(half - tmp); 1488 lastdelta = XFS_ATTR_ABS(half - tmp);
@@ -1408,9 +1518,10 @@ xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
1408 totallen -= count * sizeof(*entry); 1518 totallen -= count * sizeof(*entry);
1409 if (foundit) { 1519 if (foundit) {
1410 totallen -= sizeof(*entry) + 1520 totallen -= sizeof(*entry) +
1411 xfs_attr_leaf_newentsize(state->args, 1521 xfs_attr_leaf_newentsize(
1412 state->blocksize, 1522 state->args->namelen,
1413 NULL); 1523 state->args->valuelen,
1524 state->blocksize, NULL);
1414 } 1525 }
1415 1526
1416 *countarg = count; 1527 *countarg = count;
@@ -2253,17 +2364,17 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2253 * a "local" or a "remote" attribute. 2364 * a "local" or a "remote" attribute.
2254 */ 2365 */
2255int 2366int
2256xfs_attr_leaf_newentsize(xfs_da_args_t *args, int blocksize, int *local) 2367xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local)
2257{ 2368{
2258 int size; 2369 int size;
2259 2370
2260 size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(args->namelen, args->valuelen); 2371 size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(namelen, valuelen);
2261 if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) { 2372 if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) {
2262 if (local) { 2373 if (local) {
2263 *local = 1; 2374 *local = 1;
2264 } 2375 }
2265 } else { 2376 } else {
2266 size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(args->namelen); 2377 size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(namelen);
2267 if (local) { 2378 if (local) {
2268 *local = 0; 2379 *local = 0;
2269 } 2380 }