aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_attr.c61
-rw-r--r--fs/xfs/xfs_attr_leaf.c177
-rw-r--r--fs/xfs/xfs_attr_leaf.h14
-rw-r--r--fs/xfs/xfs_bmap.c84
-rw-r--r--fs/xfs/xfs_bmap.h5
-rw-r--r--fs/xfs/xfs_dir.c24
-rw-r--r--fs/xfs/xfs_fs.h3
-rw-r--r--fs/xfs/xfs_fsops.c6
-rw-r--r--fs/xfs/xfs_macros.c17
-rw-r--r--fs/xfs/xfs_mount.c7
-rw-r--r--fs/xfs/xfs_sb.h44
-rw-r--r--fs/xfs/xfs_types.h8
-rw-r--r--fs/xfs/xfs_vfsops.c18
13 files changed, 354 insertions, 114 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,
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index e13eaa521436..50598b121683 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -118,13 +118,82 @@ STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
118 118
119 119
120/*======================================================================== 120/*========================================================================
121 * External routines when dirsize < XFS_LITINO(mp). 121 * External routines when attribute fork size < XFS_LITINO(mp).
122 *========================================================================*/ 122 *========================================================================*/
123 123
124/* 124/*
125 * Create the initial contents of a shortform attribute list. 125 * Query whether the requested number of additional bytes of extended
126 * attribute space will be able to fit inline.
127 * Returns zero if not, else the di_forkoff fork offset to be used in the
128 * literal area for attribute data once the new bytes have been added.
129 *
130 * di_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
131 * special case for dev/uuid inodes, they have fixed size data forks.
126 */ 132 */
127int 133int
134xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
135{
136 int offset;
137 int minforkoff; /* lower limit on valid forkoff locations */
138 int maxforkoff; /* upper limit on valid forkoff locations */
139 xfs_mount_t *mp = dp->i_mount;
140
141 if (unlikely(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
142 if (bytes <= XFS_IFORK_ASIZE(dp))
143 return mp->m_attroffset >> 3;
144 return 0;
145 }
146
147 offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */
148
149 switch (dp->i_d.di_format) {
150 case XFS_DINODE_FMT_DEV:
151 minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
152 return (offset >= minforkoff) ? minforkoff : 0;
153 case XFS_DINODE_FMT_UUID:
154 minforkoff = roundup(sizeof(uuid_t), 8) >> 3;
155 return (offset >= minforkoff) ? minforkoff : 0;
156 }
157
158 /* data fork btree root can have at least this many key/ptr pairs */
159 minforkoff = MAX(dp->i_df.if_bytes, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
160 minforkoff = roundup(minforkoff, 8) >> 3;
161
162 /* attr fork btree root can have at least this many key/ptr pairs */
163 maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
164 maxforkoff = maxforkoff >> 3; /* rounded down */
165
166 if (offset >= minforkoff && offset < maxforkoff)
167 return offset;
168 if (offset >= maxforkoff)
169 return maxforkoff;
170 return 0;
171}
172
173/*
174 * Switch on the ATTR2 superblock bit (implies also FEATURES2)
175 */
176STATIC void
177xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
178{
179 unsigned long s;
180
181 if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
182 !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
183 s = XFS_SB_LOCK(mp);
184 if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
185 XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
186 XFS_SB_UNLOCK(mp, s);
187 xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
188 } else
189 XFS_SB_UNLOCK(mp, s);
190 }
191}
192
193/*
194 * Create the initial contents of a shortform attribute list.
195 */
196void
128xfs_attr_shortform_create(xfs_da_args_t *args) 197xfs_attr_shortform_create(xfs_da_args_t *args)
129{ 198{
130 xfs_attr_sf_hdr_t *hdr; 199 xfs_attr_sf_hdr_t *hdr;
@@ -148,29 +217,37 @@ xfs_attr_shortform_create(xfs_da_args_t *args)
148 hdr->count = 0; 217 hdr->count = 0;
149 INT_SET(hdr->totsize, ARCH_CONVERT, sizeof(*hdr)); 218 INT_SET(hdr->totsize, ARCH_CONVERT, sizeof(*hdr));
150 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 219 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
151 return(0);
152} 220}
153 221
154/* 222/*
155 * Add a name/value pair to the shortform attribute list. 223 * Add a name/value pair to the shortform attribute list.
156 * Overflow from the inode has already been checked for. 224 * Overflow from the inode has already been checked for.
157 */ 225 */
158int 226void
159xfs_attr_shortform_add(xfs_da_args_t *args) 227xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
160{ 228{
161 xfs_attr_shortform_t *sf; 229 xfs_attr_shortform_t *sf;
162 xfs_attr_sf_entry_t *sfe; 230 xfs_attr_sf_entry_t *sfe;
163 int i, offset, size; 231 int i, offset, size;
232 xfs_mount_t *mp;
164 xfs_inode_t *dp; 233 xfs_inode_t *dp;
165 xfs_ifork_t *ifp; 234 xfs_ifork_t *ifp;
166 235
167 dp = args->dp; 236 dp = args->dp;
237 mp = dp->i_mount;
238 dp->i_d.di_forkoff = forkoff;
239 dp->i_df.if_ext_max =
240 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
241 dp->i_afp->if_ext_max =
242 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
243
168 ifp = dp->i_afp; 244 ifp = dp->i_afp;
169 ASSERT(ifp->if_flags & XFS_IFINLINE); 245 ASSERT(ifp->if_flags & XFS_IFINLINE);
170 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; 246 sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
171 sfe = &sf->list[0]; 247 sfe = &sf->list[0];
172 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); 248 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT);
173 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) { 249 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
250#ifdef DEBUG
174 if (sfe->namelen != args->namelen) 251 if (sfe->namelen != args->namelen)
175 continue; 252 continue;
176 if (memcmp(args->name, sfe->nameval, args->namelen) != 0) 253 if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
@@ -181,7 +258,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
181 if (((args->flags & ATTR_ROOT) != 0) != 258 if (((args->flags & ATTR_ROOT) != 0) !=
182 ((sfe->flags & XFS_ATTR_ROOT) != 0)) 259 ((sfe->flags & XFS_ATTR_ROOT) != 0))
183 continue; 260 continue;
184 return(XFS_ERROR(EEXIST)); 261 ASSERT(0);
262#endif
185 } 263 }
186 264
187 offset = (char *)sfe - (char *)sf; 265 offset = (char *)sfe - (char *)sf;
@@ -200,11 +278,11 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
200 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size); 278 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, size);
201 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 279 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
202 280
203 return(0); 281 xfs_sbversion_add_attr2(mp, args->trans);
204} 282}
205 283
206/* 284/*
207 * Remove a name from the shortform attribute list structure. 285 * Remove an attribute from the shortform attribute list structure.
208 */ 286 */
209int 287int
210xfs_attr_shortform_remove(xfs_da_args_t *args) 288xfs_attr_shortform_remove(xfs_da_args_t *args)
@@ -212,17 +290,16 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
212 xfs_attr_shortform_t *sf; 290 xfs_attr_shortform_t *sf;
213 xfs_attr_sf_entry_t *sfe; 291 xfs_attr_sf_entry_t *sfe;
214 int base, size=0, end, totsize, i; 292 int base, size=0, end, totsize, i;
293 xfs_mount_t *mp;
215 xfs_inode_t *dp; 294 xfs_inode_t *dp;
216 295
217 /*
218 * Remove the attribute.
219 */
220 dp = args->dp; 296 dp = args->dp;
297 mp = dp->i_mount;
221 base = sizeof(xfs_attr_sf_hdr_t); 298 base = sizeof(xfs_attr_sf_hdr_t);
222 sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; 299 sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
223 sfe = &sf->list[0]; 300 sfe = &sf->list[0];
224 for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); 301 end = INT_GET(sf->hdr.count, ARCH_CONVERT);
225 sfe = XFS_ATTR_SF_NEXTENTRY(sfe), 302 for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
226 base += size, i++) { 303 base += size, i++) {
227 size = XFS_ATTR_SF_ENTSIZE(sfe); 304 size = XFS_ATTR_SF_ENTSIZE(sfe);
228 if (sfe->namelen != args->namelen) 305 if (sfe->namelen != args->namelen)
@@ -237,19 +314,51 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
237 continue; 314 continue;
238 break; 315 break;
239 } 316 }
240 if (i == INT_GET(sf->hdr.count, ARCH_CONVERT)) 317 if (i == end)
241 return(XFS_ERROR(ENOATTR)); 318 return(XFS_ERROR(ENOATTR));
242 319
320 /*
321 * Fix up the attribute fork data, covering the hole
322 */
243 end = base + size; 323 end = base + size;
244 totsize = INT_GET(sf->hdr.totsize, ARCH_CONVERT); 324 totsize = INT_GET(sf->hdr.totsize, ARCH_CONVERT);
245 if (end != totsize) { 325 if (end != totsize)
246 memmove(&((char *)sf)[base], &((char *)sf)[end], 326 memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
247 totsize - end);
248 }
249 INT_MOD(sf->hdr.count, ARCH_CONVERT, -1); 327 INT_MOD(sf->hdr.count, ARCH_CONVERT, -1);
250 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, -size); 328 INT_MOD(sf->hdr.totsize, ARCH_CONVERT, -size);
251 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); 329
252 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); 330 /*
331 * Fix up the start offset of the attribute fork
332 */
333 totsize -= size;
334 if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname) {
335 /*
336 * Last attribute now removed, revert to original
337 * inode format making all literal area available
338 * to the data fork once more.
339 */
340 xfs_idestroy_fork(dp, XFS_ATTR_FORK);
341 dp->i_d.di_forkoff = 0;
342 dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
343 ASSERT(dp->i_d.di_anextents == 0);
344 ASSERT(dp->i_afp == NULL);
345 dp->i_df.if_ext_max =
346 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
347 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
348 } else {
349 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
350 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
351 ASSERT(dp->i_d.di_forkoff);
352 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname);
353 dp->i_afp->if_ext_max =
354 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
355 dp->i_df.if_ext_max =
356 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
357 xfs_trans_log_inode(args->trans, dp,
358 XFS_ILOG_CORE | XFS_ILOG_ADATA);
359 }
360
361 xfs_sbversion_add_attr2(mp, args->trans);
253 362
254 return(0); 363 return(0);
255} 364}
@@ -649,14 +758,16 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
649 + name_loc->namelen 758 + name_loc->namelen
650 + INT_GET(name_loc->valuelen, ARCH_CONVERT); 759 + INT_GET(name_loc->valuelen, ARCH_CONVERT);
651 } 760 }
652 return( bytes < XFS_IFORK_ASIZE(dp) ); 761 if (bytes == sizeof(struct xfs_attr_sf_hdr))
762 return(-1);
763 return(xfs_attr_shortform_bytesfit(dp, bytes));
653} 764}
654 765
655/* 766/*
656 * Convert a leaf attribute list to shortform attribute list 767 * Convert a leaf attribute list to shortform attribute list
657 */ 768 */
658int 769int
659xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args) 770xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
660{ 771{
661 xfs_attr_leafblock_t *leaf; 772 xfs_attr_leafblock_t *leaf;
662 xfs_attr_leaf_entry_t *entry; 773 xfs_attr_leaf_entry_t *entry;
@@ -683,9 +794,25 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
683 error = xfs_da_shrink_inode(args, 0, bp); 794 error = xfs_da_shrink_inode(args, 0, bp);
684 if (error) 795 if (error)
685 goto out; 796 goto out;
686 error = xfs_attr_shortform_create(args); 797
687 if (error) 798 if (forkoff == -1) {
799 /*
800 * Last attribute was removed, revert to original
801 * inode format making all literal area available
802 * to the data fork once more.
803 */
804 xfs_idestroy_fork(dp, XFS_ATTR_FORK);
805 dp->i_d.di_forkoff = 0;
806 dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
807 ASSERT(dp->i_d.di_anextents == 0);
808 ASSERT(dp->i_afp == NULL);
809 dp->i_df.if_ext_max =
810 XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
811 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
688 goto out; 812 goto out;
813 }
814
815 xfs_attr_shortform_create(args);
689 816
690 /* 817 /*
691 * Copy the attributes 818 * Copy the attributes
@@ -713,7 +840,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
713 nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT); 840 nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
714 nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : 841 nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
715 ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); 842 ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
716 xfs_attr_shortform_add(&nargs); 843 xfs_attr_shortform_add(&nargs, forkoff);
717 } 844 }
718 error = 0; 845 error = 0;
719 846
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index b99f0491061c..326802f80d54 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -238,23 +238,25 @@ typedef struct xfs_attr_inactive_list {
238 *========================================================================*/ 238 *========================================================================*/
239 239
240/* 240/*
241 * Internal routines when dirsize < XFS_LITINO(mp). 241 * Internal routines when attribute fork size < XFS_LITINO(mp).
242 */ 242 */
243int xfs_attr_shortform_create(struct xfs_da_args *args); 243void xfs_attr_shortform_create(struct xfs_da_args *args);
244int xfs_attr_shortform_add(struct xfs_da_args *add); 244void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff);
245int xfs_attr_shortform_lookup(struct xfs_da_args *args); 245int xfs_attr_shortform_lookup(struct xfs_da_args *args);
246int xfs_attr_shortform_getvalue(struct xfs_da_args *args); 246int xfs_attr_shortform_getvalue(struct xfs_da_args *args);
247int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); 247int xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
248int xfs_attr_shortform_remove(struct xfs_da_args *remove); 248int xfs_attr_shortform_remove(struct xfs_da_args *args);
249int xfs_attr_shortform_list(struct xfs_attr_list_context *context); 249int xfs_attr_shortform_list(struct xfs_attr_list_context *context);
250int xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp); 250int xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp);
251int xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes);
252
251 253
252/* 254/*
253 * Internal routines when dirsize == XFS_LBSIZE(mp). 255 * Internal routines when attribute fork size == XFS_LBSIZE(mp).
254 */ 256 */
255int xfs_attr_leaf_to_node(struct xfs_da_args *args); 257int xfs_attr_leaf_to_node(struct xfs_da_args *args);
256int xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp, 258int xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp,
257 struct xfs_da_args *args); 259 struct xfs_da_args *args, int forkoff);
258int xfs_attr_leaf_clearflag(struct xfs_da_args *args); 260int xfs_attr_leaf_clearflag(struct xfs_da_args *args);
259int xfs_attr_leaf_setflag(struct xfs_da_args *args); 261int xfs_attr_leaf_setflag(struct xfs_da_args *args);
260int xfs_attr_leaf_flipflags(xfs_da_args_t *args); 262int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 26645d267f1b..3e013530d00d 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -62,6 +62,7 @@
62#include "xfs_error.h" 62#include "xfs_error.h"
63#include "xfs_da_btree.h" 63#include "xfs_da_btree.h"
64#include "xfs_dir_leaf.h" 64#include "xfs_dir_leaf.h"
65#include "xfs_attr_leaf.h"
65#include "xfs_bit.h" 66#include "xfs_bit.h"
66#include "xfs_rw.h" 67#include "xfs_rw.h"
67#include "xfs_quota.h" 68#include "xfs_quota.h"
@@ -3337,6 +3338,29 @@ xfs_bmap_insert_exlist(
3337} 3338}
3338 3339
3339/* 3340/*
3341 * Helper routine to reset inode di_forkoff field when switching
3342 * attribute fork from local to extent format - we reset it where
3343 * possible to make space available for inline data fork extents.
3344 */
3345STATIC void
3346xfs_bmap_forkoff_reset(
3347 xfs_mount_t *mp,
3348 xfs_inode_t *ip,
3349 int whichfork)
3350{
3351 if (whichfork == XFS_ATTR_FORK &&
3352 (ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
3353 (ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
3354 ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
3355 ip->i_d.di_forkoff = mp->m_attroffset >> 3;
3356 ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
3357 (uint)sizeof(xfs_bmbt_rec_t);
3358 ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
3359 (uint)sizeof(xfs_bmbt_rec_t);
3360 }
3361}
3362
3363/*
3340 * Convert a local file to an extents file. 3364 * Convert a local file to an extents file.
3341 * This code is out of bounds for data forks of regular files, 3365 * This code is out of bounds for data forks of regular files,
3342 * since the file data needs to get logged so things will stay consistent. 3366 * since the file data needs to get logged so things will stay consistent.
@@ -3403,6 +3427,7 @@ xfs_bmap_local_to_extents(
3403 memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data, 3427 memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data,
3404 ifp->if_bytes); 3428 ifp->if_bytes);
3405 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 3429 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
3430 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
3406 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); 3431 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
3407 xfs_iext_realloc(ip, 1, whichfork); 3432 xfs_iext_realloc(ip, 1, whichfork);
3408 ep = ifp->if_u1.if_extents; 3433 ep = ifp->if_u1.if_extents;
@@ -3413,8 +3438,10 @@ xfs_bmap_local_to_extents(
3413 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, 3438 XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip,
3414 XFS_TRANS_DQ_BCOUNT, 1L); 3439 XFS_TRANS_DQ_BCOUNT, 1L);
3415 flags |= XFS_ILOG_FEXT(whichfork); 3440 flags |= XFS_ILOG_FEXT(whichfork);
3416 } else 3441 } else {
3417 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); 3442 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
3443 xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork);
3444 }
3418 ifp->if_flags &= ~XFS_IFINLINE; 3445 ifp->if_flags &= ~XFS_IFINLINE;
3419 ifp->if_flags |= XFS_IFEXTENTS; 3446 ifp->if_flags |= XFS_IFEXTENTS;
3420 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); 3447 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
@@ -3796,22 +3823,24 @@ xfs_bunmap_trace(
3796int /* error code */ 3823int /* error code */
3797xfs_bmap_add_attrfork( 3824xfs_bmap_add_attrfork(
3798 xfs_inode_t *ip, /* incore inode pointer */ 3825 xfs_inode_t *ip, /* incore inode pointer */
3799 int rsvd) /* OK to allocated reserved blocks in trans */ 3826 int size, /* space new attribute needs */
3827 int rsvd) /* xact may use reserved blks */
3800{ 3828{
3801 int blks; /* space reservation */
3802 int committed; /* xaction was committed */
3803 int error; /* error return value */
3804 xfs_fsblock_t firstblock; /* 1st block/ag allocated */ 3829 xfs_fsblock_t firstblock; /* 1st block/ag allocated */
3805 xfs_bmap_free_t flist; /* freed extent list */ 3830 xfs_bmap_free_t flist; /* freed extent list */
3806 int logflags; /* logging flags */
3807 xfs_mount_t *mp; /* mount structure */ 3831 xfs_mount_t *mp; /* mount structure */
3808 unsigned long s; /* spinlock spl value */
3809 xfs_trans_t *tp; /* transaction pointer */ 3832 xfs_trans_t *tp; /* transaction pointer */
3833 unsigned long s; /* spinlock spl value */
3834 int blks; /* space reservation */
3835 int version = 1; /* superblock attr version */
3836 int committed; /* xaction was committed */
3837 int logflags; /* logging flags */
3838 int error; /* error return value */
3810 3839
3840 ASSERT(XFS_IFORK_Q(ip) == 0);
3811 ASSERT(ip->i_df.if_ext_max == 3841 ASSERT(ip->i_df.if_ext_max ==
3812 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t)); 3842 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
3813 if (XFS_IFORK_Q(ip)) 3843
3814 return 0;
3815 mp = ip->i_mount; 3844 mp = ip->i_mount;
3816 ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); 3845 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
3817 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK); 3846 tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
@@ -3853,7 +3882,11 @@ xfs_bmap_add_attrfork(
3853 case XFS_DINODE_FMT_LOCAL: 3882 case XFS_DINODE_FMT_LOCAL:
3854 case XFS_DINODE_FMT_EXTENTS: 3883 case XFS_DINODE_FMT_EXTENTS:
3855 case XFS_DINODE_FMT_BTREE: 3884 case XFS_DINODE_FMT_BTREE:
3856 ip->i_d.di_forkoff = mp->m_attroffset >> 3; 3885 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
3886 if (!ip->i_d.di_forkoff)
3887 ip->i_d.di_forkoff = mp->m_attroffset >> 3;
3888 else if (!(mp->m_flags & XFS_MOUNT_COMPAT_ATTR))
3889 version = 2;
3857 break; 3890 break;
3858 default: 3891 default:
3859 ASSERT(0); 3892 ASSERT(0);
@@ -3890,12 +3923,21 @@ xfs_bmap_add_attrfork(
3890 xfs_trans_log_inode(tp, ip, logflags); 3923 xfs_trans_log_inode(tp, ip, logflags);
3891 if (error) 3924 if (error)
3892 goto error2; 3925 goto error2;
3893 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { 3926 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) ||
3927 (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) {
3928 logflags = 0;
3894 s = XFS_SB_LOCK(mp); 3929 s = XFS_SB_LOCK(mp);
3895 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { 3930 if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
3896 XFS_SB_VERSION_ADDATTR(&mp->m_sb); 3931 XFS_SB_VERSION_ADDATTR(&mp->m_sb);
3932 logflags |= XFS_SB_VERSIONNUM;
3933 }
3934 if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) {
3935 XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
3936 logflags |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
3937 }
3938 if (logflags) {
3897 XFS_SB_UNLOCK(mp, s); 3939 XFS_SB_UNLOCK(mp, s);
3898 xfs_mod_sb(tp, XFS_SB_VERSIONNUM); 3940 xfs_mod_sb(tp, logflags);
3899 } else 3941 } else
3900 XFS_SB_UNLOCK(mp, s); 3942 XFS_SB_UNLOCK(mp, s);
3901 } 3943 }
@@ -3988,13 +4030,19 @@ xfs_bmap_compute_maxlevels(
3988 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents 4030 * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
3989 * (a signed 16-bit number, xfs_aextnum_t). 4031 * (a signed 16-bit number, xfs_aextnum_t).
3990 */ 4032 */
3991 maxleafents = (whichfork == XFS_DATA_FORK) ? MAXEXTNUM : MAXAEXTNUM; 4033 if (whichfork == XFS_DATA_FORK) {
4034 maxleafents = MAXEXTNUM;
4035 sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
4036 mp->m_attroffset : XFS_BMDR_SPACE_CALC(MINDBTPTRS);
4037 } else {
4038 maxleafents = MAXAEXTNUM;
4039 sz = (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) ?
4040 mp->m_sb.sb_inodesize - mp->m_attroffset :
4041 XFS_BMDR_SPACE_CALC(MINABTPTRS);
4042 }
4043 maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
3992 minleafrecs = mp->m_bmap_dmnr[0]; 4044 minleafrecs = mp->m_bmap_dmnr[0];
3993 minnoderecs = mp->m_bmap_dmnr[1]; 4045 minnoderecs = mp->m_bmap_dmnr[1];
3994 sz = (whichfork == XFS_DATA_FORK) ?
3995 mp->m_attroffset :
3996 mp->m_sb.sb_inodesize - mp->m_attroffset;
3997 maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
3998 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; 4046 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
3999 for (level = 1; maxblocks > 1; level++) { 4047 for (level = 1; maxblocks > 1; level++) {
4000 if (maxblocks <= maxrootrecs) 4048 if (maxblocks <= maxrootrecs)
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index e6d22ec9b2e4..e42d1b7777e1 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -156,7 +156,8 @@ xfs_bmap_trace_exlist(
156int /* error code */ 156int /* error code */
157xfs_bmap_add_attrfork( 157xfs_bmap_add_attrfork(
158 struct xfs_inode *ip, /* incore inode pointer */ 158 struct xfs_inode *ip, /* incore inode pointer */
159 int rsvd); /* flag for reserved block allocation */ 159 int size, /* space needed for new attribute */
160 int rsvd); /* flag for reserved block allocation */
160 161
161/* 162/*
162 * Add the extent to the list of extents to be free at transaction end. 163 * Add the extent to the list of extents to be free at transaction end.
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
index ba30bc7682f2..53787f35338b 100644
--- a/fs/xfs/xfs_dir.c
+++ b/fs/xfs/xfs_dir.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -192,11 +192,23 @@ xfs_dir_mount(xfs_mount_t *mp)
192 uint shortcount, leafcount, count; 192 uint shortcount, leafcount, count;
193 193
194 mp->m_dirversion = 1; 194 mp->m_dirversion = 1;
195 shortcount = (mp->m_attroffset - (uint)sizeof(xfs_dir_sf_hdr_t)) / 195 if (mp->m_flags & XFS_MOUNT_COMPAT_ATTR) {
196 (uint)sizeof(xfs_dir_sf_entry_t); 196 shortcount = (mp->m_attroffset -
197 leafcount = (XFS_LBSIZE(mp) - (uint)sizeof(xfs_dir_leaf_hdr_t)) / 197 (uint)sizeof(xfs_dir_sf_hdr_t)) /
198 ((uint)sizeof(xfs_dir_leaf_entry_t) + 198 (uint)sizeof(xfs_dir_sf_entry_t);
199 (uint)sizeof(xfs_dir_leaf_name_t)); 199 leafcount = (XFS_LBSIZE(mp) -
200 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
201 ((uint)sizeof(xfs_dir_leaf_entry_t) +
202 (uint)sizeof(xfs_dir_leaf_name_t));
203 } else {
204 shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
205 (uint)sizeof(xfs_dir_sf_hdr_t)) /
206 (uint)sizeof(xfs_dir_sf_entry_t);
207 leafcount = (XFS_LBSIZE(mp) -
208 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
209 ((uint)sizeof(xfs_dir_leaf_entry_t) +
210 (uint)sizeof(xfs_dir_leaf_name_t));
211 }
200 count = shortcount > leafcount ? shortcount : leafcount; 212 count = shortcount > leafcount ? shortcount : leafcount;
201 mp->m_dircook_elog = xfs_da_log2_roundup(count + 1); 213 mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
202 ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog); 214 ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 095af0a5cff3..7bf2e92b8c0b 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 1995-2003 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 1995-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2.1 of the GNU Lesser General Public License 5 * under the terms of version 2.1 of the GNU Lesser General Public License
@@ -251,6 +251,7 @@ typedef struct xfs_fsop_resblks {
251#define XFS_FSOP_GEOM_FLAGS_DIRV2 0x0080 /* directory version 2 */ 251#define XFS_FSOP_GEOM_FLAGS_DIRV2 0x0080 /* directory version 2 */
252#define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */ 252#define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */
253#define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */ 253#define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */
254#define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */
254 255
255 256
256/* 257/*
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index ca535d613190..67522f2bcee8 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -110,7 +110,9 @@ xfs_fs_geometry(
110 (XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ? 110 (XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
111 XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) | 111 XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) |
112 (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? 112 (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
113 XFS_FSOP_GEOM_FLAGS_SECTOR : 0); 113 XFS_FSOP_GEOM_FLAGS_SECTOR : 0) |
114 (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ?
115 XFS_FSOP_GEOM_FLAGS_ATTR2 : 0);
114 geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? 116 geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
115 mp->m_sb.sb_logsectsize : BBSIZE; 117 mp->m_sb.sb_logsectsize : BBSIZE;
116 geo->rtsectsize = mp->m_sb.sb_blocksize; 118 geo->rtsectsize = mp->m_sb.sb_blocksize;
diff --git a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c
index 698c2cd62858..c715da13b2fe 100644
--- a/fs/xfs/xfs_macros.c
+++ b/fs/xfs/xfs_macros.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -1995,6 +1995,14 @@ xfs_sb_version_addshared(xfs_sb_t *sbp)
1995} 1995}
1996#endif 1996#endif
1997 1997
1998#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_ADDATTR2)
1999void
2000xfs_sb_version_addattr2(xfs_sb_t *sbp)
2001{
2002 XFS_SB_VERSION_ADDATTR2(sbp);
2003}
2004#endif
2005
1998#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASALIGN) 2006#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASALIGN)
1999int 2007int
2000xfs_sb_version_hasalign(xfs_sb_t *sbp) 2008xfs_sb_version_hasalign(xfs_sb_t *sbp)
@@ -2139,3 +2147,10 @@ xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
2139} 2147}
2140#endif 2148#endif
2141 2149
2150#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_SB_VERSION_HASATTR2)
2151int
2152xfs_sb_version_hasattr2(xfs_sb_t *sbp)
2153{
2154 return XFS_SB_VERSION_HASATTR2(sbp);
2155}
2156#endif
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 12f10d5c3d99..a93ef802db6b 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -584,12 +584,13 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
584 ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048); 584 ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
585 switch (sbp->sb_inodesize) { 585 switch (sbp->sb_inodesize) {
586 case 256: 586 case 256:
587 mp->m_attroffset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(2); 587 mp->m_attroffset = XFS_LITINO(mp) -
588 XFS_BMDR_SPACE_CALC(MINABTPTRS);
588 break; 589 break;
589 case 512: 590 case 512:
590 case 1024: 591 case 1024:
591 case 2048: 592 case 2048:
592 mp->m_attroffset = XFS_BMDR_SPACE_CALC(12); 593 mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
593 break; 594 break;
594 default: 595 default:
595 ASSERT(0); 596 ASSERT(0);
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index ad090a834ced..01c5a5ff230e 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -72,7 +72,8 @@ struct xfs_mount;
72 XFS_SB_VERSION_DALIGNBIT | \ 72 XFS_SB_VERSION_DALIGNBIT | \
73 XFS_SB_VERSION_SHAREDBIT | \ 73 XFS_SB_VERSION_SHAREDBIT | \
74 XFS_SB_VERSION_LOGV2BIT | \ 74 XFS_SB_VERSION_LOGV2BIT | \
75 XFS_SB_VERSION_SECTORBIT) 75 XFS_SB_VERSION_SECTORBIT | \
76 XFS_SB_VERSION_MOREBITSBIT)
76#define XFS_SB_VERSION_OKSASHBITS \ 77#define XFS_SB_VERSION_OKSASHBITS \
77 (XFS_SB_VERSION_NUMBITS | \ 78 (XFS_SB_VERSION_NUMBITS | \
78 XFS_SB_VERSION_REALFBITS | \ 79 XFS_SB_VERSION_REALFBITS | \
@@ -103,12 +104,15 @@ struct xfs_mount;
103 */ 104 */
104#define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */ 105#define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */
105#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001 106#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001
107#define XFS_SB_VERSION2_RESERVED2BIT 0x00000002
108#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
109#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
106#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that 110#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that
107 require changing 111 require changing
108 PROM and SASH */ 112 PROM and SASH */
109 113
110#define XFS_SB_VERSION2_OKREALFBITS \ 114#define XFS_SB_VERSION2_OKREALFBITS \
111 (0) 115 (XFS_SB_VERSION2_ATTR2BIT)
112#define XFS_SB_VERSION2_OKSASHFBITS \ 116#define XFS_SB_VERSION2_OKSASHFBITS \
113 (0) 117 (0)
114#define XFS_SB_VERSION2_OKREALBITS \ 118#define XFS_SB_VERSION2_OKREALBITS \
@@ -118,8 +122,7 @@ struct xfs_mount;
118/* 122/*
119 * mkfs macro to set up sb_features2 word 123 * mkfs macro to set up sb_features2 word
120 */ 124 */
121#define XFS_SB_VERSION2_MKFS(xyz) \ 125#define XFS_SB_VERSION2_MKFS(resvd1, sbcntr) 0
122 ((xyz) ? 0 : 0)
123 126
124typedef struct xfs_sb 127typedef struct xfs_sb
125{ 128{
@@ -176,7 +179,7 @@ typedef struct xfs_sb
176 __uint8_t sb_logsectlog; /* log2 of the log sector size */ 179 __uint8_t sb_logsectlog; /* log2 of the log sector size */
177 __uint16_t sb_logsectsize; /* sector size for the log, bytes */ 180 __uint16_t sb_logsectsize; /* sector size for the log, bytes */
178 __uint32_t sb_logsunit; /* stripe unit size for the log */ 181 __uint32_t sb_logsunit; /* stripe unit size for the log */
179 __uint32_t sb_features2; /* additonal feature bits */ 182 __uint32_t sb_features2; /* additional feature bits */
180} xfs_sb_t; 183} xfs_sb_t;
181 184
182/* 185/*
@@ -216,12 +219,15 @@ typedef enum {
216#define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) 219#define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN)
217#define XFS_SB_UNIT XFS_SB_MVAL(UNIT) 220#define XFS_SB_UNIT XFS_SB_MVAL(UNIT)
218#define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) 221#define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH)
222#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2)
219#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) 223#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT)
220#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) 224#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1)
221#define XFS_SB_MOD_BITS \ 225#define XFS_SB_MOD_BITS \
222 (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ 226 (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \
223 XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ 227 XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
224 XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH) 228 XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
229 XFS_SB_FEATURES2)
230
225 231
226/* 232/*
227 * Misc. Flags - warning - these will be cleared by xfs_repair unless 233 * Misc. Flags - warning - these will be cleared by xfs_repair unless
@@ -500,13 +506,31 @@ int xfs_sb_version_hasmorebits(xfs_sb_t *sbp);
500/* 506/*
501 * sb_features2 bit version macros. 507 * sb_features2 bit version macros.
502 * 508 *
503 * For example, for a bit defined as XFS_SB_VERSION2_YBIT, has a macro: 509 * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro:
504 * 510 *
505 * SB_VERSION_HASYBIT(xfs_sb_t *sbp) 511 * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp)
506 * ((XFS_SB_VERSION_HASMOREBITS(sbp) && 512 * ((XFS_SB_VERSION_HASMOREBITS(sbp) &&
507 * ((sbp)->sb_versionnum & XFS_SB_VERSION2_YBIT) 513 * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT)
508 */ 514 */
515#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_HASATTR2)
516int xfs_sb_version_hasattr2(xfs_sb_t *sbp);
517#define XFS_SB_VERSION_HASATTR2(sbp) xfs_sb_version_hasattr2(sbp)
518#else
519#define XFS_SB_VERSION_HASATTR2(sbp) \
520 ((XFS_SB_VERSION_HASMOREBITS(sbp)) && \
521 ((sbp)->sb_features2 & XFS_SB_VERSION2_ATTR2BIT))
522#endif
509 523
524#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_SB_VERSION_ADDATTR2)
525void xfs_sb_version_addattr2(xfs_sb_t *sbp);
526#define XFS_SB_VERSION_ADDATTR2(sbp) xfs_sb_version_addattr2(sbp)
527#else
528#define XFS_SB_VERSION_ADDATTR2(sbp) \
529 ((sbp)->sb_versionnum = \
530 ((sbp)->sb_versionnum | XFS_SB_VERSION_MOREBITSBIT), \
531 ((sbp)->sb_features2 = \
532 ((sbp)->sb_features2 | XFS_SB_VERSION2_ATTR2BIT)))
533#endif
510/* 534/*
511 * end of superblock version macros 535 * end of superblock version macros
512 */ 536 */
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 16f5371ce102..33a888e6b3f2 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -154,6 +154,12 @@ typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */
154#define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */ 154#define MAXAEXTNUM ((xfs_aextnum_t)0x7fff) /* signed short */
155 155
156/* 156/*
157 * Min numbers of data/attr fork btree root pointers.
158 */
159#define MINDBTPTRS 3
160#define MINABTPTRS 2
161
162/*
157 * MAXNAMELEN is the length (including the terminating null) of 163 * MAXNAMELEN is the length (including the terminating null) of
158 * the longest permissible file (component) name. 164 * the longest permissible file (component) name.
159 */ 165 */
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 7227baee8994..07779c5ab42f 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -268,19 +268,14 @@ xfs_start_flags(
268#endif 268#endif
269 if (ap->flags & XFSMNT_NOATIME) 269 if (ap->flags & XFSMNT_NOATIME)
270 mp->m_flags |= XFS_MOUNT_NOATIME; 270 mp->m_flags |= XFS_MOUNT_NOATIME;
271
272 if (ap->flags & XFSMNT_RETERR) 271 if (ap->flags & XFSMNT_RETERR)
273 mp->m_flags |= XFS_MOUNT_RETERR; 272 mp->m_flags |= XFS_MOUNT_RETERR;
274
275 if (ap->flags & XFSMNT_NOALIGN) 273 if (ap->flags & XFSMNT_NOALIGN)
276 mp->m_flags |= XFS_MOUNT_NOALIGN; 274 mp->m_flags |= XFS_MOUNT_NOALIGN;
277
278 if (ap->flags & XFSMNT_SWALLOC) 275 if (ap->flags & XFSMNT_SWALLOC)
279 mp->m_flags |= XFS_MOUNT_SWALLOC; 276 mp->m_flags |= XFS_MOUNT_SWALLOC;
280
281 if (ap->flags & XFSMNT_OSYNCISOSYNC) 277 if (ap->flags & XFSMNT_OSYNCISOSYNC)
282 mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC; 278 mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
283
284 if (ap->flags & XFSMNT_32BITINODES) 279 if (ap->flags & XFSMNT_32BITINODES)
285 mp->m_flags |= (XFS_MOUNT_32BITINODES | XFS_MOUNT_32BITINOOPT); 280 mp->m_flags |= (XFS_MOUNT_32BITINODES | XFS_MOUNT_32BITINOOPT);
286 281
@@ -300,15 +295,14 @@ xfs_start_flags(
300 295
301 if (ap->flags & XFSMNT_IHASHSIZE) 296 if (ap->flags & XFSMNT_IHASHSIZE)
302 mp->m_flags |= XFS_MOUNT_IHASHSIZE; 297 mp->m_flags |= XFS_MOUNT_IHASHSIZE;
303
304 if (ap->flags & XFSMNT_IDELETE) 298 if (ap->flags & XFSMNT_IDELETE)
305 mp->m_flags |= XFS_MOUNT_IDELETE; 299 mp->m_flags |= XFS_MOUNT_IDELETE;
306
307 if (ap->flags & XFSMNT_DIRSYNC) 300 if (ap->flags & XFSMNT_DIRSYNC)
308 mp->m_flags |= XFS_MOUNT_DIRSYNC; 301 mp->m_flags |= XFS_MOUNT_DIRSYNC;
309
310 if (ap->flags & XFSMNT_COMPAT_IOSIZE) 302 if (ap->flags & XFSMNT_COMPAT_IOSIZE)
311 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; 303 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
304 if (ap->flags & XFSMNT_COMPAT_ATTR)
305 mp->m_flags |= XFS_MOUNT_COMPAT_ATTR;
312 306
313 /* 307 /*
314 * no recovery flag requires a read-only mount 308 * no recovery flag requires a read-only mount
@@ -1643,7 +1637,7 @@ xfs_vget(
1643#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ 1637#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
1644#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ 1638#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
1645#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and 1639#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
1646 unwritten extent conversion */ 1640 * unwritten extent conversion */
1647#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */ 1641#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
1648#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ 1642#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
1649#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ 1643#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
@@ -1651,6 +1645,8 @@ xfs_vget(
1651#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ 1645#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
1652#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes 1646#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes
1653 * in stat(). */ 1647 * in stat(). */
1648#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
1649#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1654 1650
1655STATIC unsigned long 1651STATIC unsigned long
1656suffix_strtoul(const char *cp, char **endp, unsigned int base) 1652suffix_strtoul(const char *cp, char **endp, unsigned int base)
@@ -1820,6 +1816,10 @@ xfs_parseargs(
1820 args->flags &= ~XFSMNT_COMPAT_IOSIZE; 1816 args->flags &= ~XFSMNT_COMPAT_IOSIZE;
1821 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { 1817 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
1822 args->flags |= XFSMNT_COMPAT_IOSIZE; 1818 args->flags |= XFSMNT_COMPAT_IOSIZE;
1819 } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
1820 args->flags &= ~XFSMNT_COMPAT_ATTR;
1821 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
1822 args->flags |= XFSMNT_COMPAT_ATTR;
1823 } else if (!strcmp(this_char, "osyncisdsync")) { 1823 } else if (!strcmp(this_char, "osyncisdsync")) {
1824 /* no-op, this is now the default */ 1824 /* no-op, this is now the default */
1825printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); 1825printk("XFS: osyncisdsync is now the default, option is deprecated.\n");