aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_attr_leaf.c3
-rw-r--r--fs/xfs/xfs_bmap.c56
-rw-r--r--fs/xfs/xfs_bmap.h4
-rw-r--r--fs/xfs/xfs_mount.c37
-rw-r--r--fs/xfs/xfs_mount.h1
5 files changed, 62 insertions, 39 deletions
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index aa001629b596..afdc8911637d 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -155,7 +155,8 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes)
155 * minimum offset only needs to be the space required for 155 * minimum offset only needs to be the space required for
156 * the btree root. 156 * the btree root.
157 */ 157 */
158 if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > mp->m_attroffset) 158 if (!dp->i_d.di_forkoff && dp->i_df.if_bytes >
159 xfs_default_attroffset(dp))
159 dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); 160 dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
160 break; 161 break;
161 162
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 47a87de35af5..3a6ed426327a 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -3569,6 +3569,27 @@ xfs_bmap_extents_to_btree(
3569} 3569}
3570 3570
3571/* 3571/*
3572 * Calculate the default attribute fork offset for newly created inodes.
3573 */
3574uint
3575xfs_default_attroffset(
3576 struct xfs_inode *ip)
3577{
3578 struct xfs_mount *mp = ip->i_mount;
3579 uint offset;
3580
3581 if (mp->m_sb.sb_inodesize == 256) {
3582 offset = XFS_LITINO(mp) -
3583 XFS_BMDR_SPACE_CALC(MINABTPTRS);
3584 } else {
3585 offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
3586 }
3587
3588 ASSERT(offset < XFS_LITINO(mp));
3589 return offset;
3590}
3591
3592/*
3572 * Helper routine to reset inode di_forkoff field when switching 3593 * Helper routine to reset inode di_forkoff field when switching
3573 * attribute fork from local to extent format - we reset it where 3594 * attribute fork from local to extent format - we reset it where
3574 * possible to make space available for inline data fork extents. 3595 * possible to make space available for inline data fork extents.
@@ -3580,15 +3601,18 @@ xfs_bmap_forkoff_reset(
3580 int whichfork) 3601 int whichfork)
3581{ 3602{
3582 if (whichfork == XFS_ATTR_FORK && 3603 if (whichfork == XFS_ATTR_FORK &&
3583 (ip->i_d.di_format != XFS_DINODE_FMT_DEV) && 3604 ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
3584 (ip->i_d.di_format != XFS_DINODE_FMT_UUID) && 3605 ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
3585 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && 3606 ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
3586 ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) { 3607 uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
3587 ip->i_d.di_forkoff = mp->m_attroffset >> 3; 3608
3588 ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / 3609 if (dfl_forkoff > ip->i_d.di_forkoff) {
3589 (uint)sizeof(xfs_bmbt_rec_t); 3610 ip->i_d.di_forkoff = dfl_forkoff;
3590 ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) / 3611 ip->i_df.if_ext_max =
3591 (uint)sizeof(xfs_bmbt_rec_t); 3612 XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
3613 ip->i_afp->if_ext_max =
3614 XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t);
3615 }
3592 } 3616 }
3593} 3617}
3594 3618
@@ -4057,7 +4081,7 @@ xfs_bmap_add_attrfork(
4057 case XFS_DINODE_FMT_BTREE: 4081 case XFS_DINODE_FMT_BTREE:
4058 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size); 4082 ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
4059 if (!ip->i_d.di_forkoff) 4083 if (!ip->i_d.di_forkoff)
4060 ip->i_d.di_forkoff = mp->m_attroffset >> 3; 4084 ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
4061 else if (mp->m_flags & XFS_MOUNT_ATTR2) 4085 else if (mp->m_flags & XFS_MOUNT_ATTR2)
4062 version = 2; 4086 version = 2;
4063 break; 4087 break;
@@ -4204,12 +4228,12 @@ xfs_bmap_compute_maxlevels(
4204 * (a signed 16-bit number, xfs_aextnum_t). 4228 * (a signed 16-bit number, xfs_aextnum_t).
4205 * 4229 *
4206 * Note that we can no longer assume that if we are in ATTR1 that 4230 * Note that we can no longer assume that if we are in ATTR1 that
4207 * the fork offset of all the inodes will be (m_attroffset >> 3) 4231 * the fork offset of all the inodes will be
4208 * because we could have mounted with ATTR2 and then mounted back 4232 * (xfs_default_attroffset(ip) >> 3) because we could have mounted
4209 * with ATTR1, keeping the di_forkoff's fixed but probably at 4233 * with ATTR2 and then mounted back with ATTR1, keeping the
4210 * various positions. Therefore, for both ATTR1 and ATTR2 4234 * di_forkoff's fixed but probably at various positions. Therefore,
4211 * we have to assume the worst case scenario of a minimum size 4235 * for both ATTR1 and ATTR2 we have to assume the worst case scenario
4212 * available. 4236 * of a minimum size available.
4213 */ 4237 */
4214 if (whichfork == XFS_DATA_FORK) { 4238 if (whichfork == XFS_DATA_FORK) {
4215 maxleafents = MAXEXTNUM; 4239 maxleafents = MAXEXTNUM;
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 589d3dabdd17..1b8ff9256bd0 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -338,6 +338,10 @@ xfs_check_nostate_extents(
338 xfs_extnum_t idx, 338 xfs_extnum_t idx,
339 xfs_extnum_t num); 339 xfs_extnum_t num);
340 340
341uint
342xfs_default_attroffset(
343 struct xfs_inode *ip);
344
341#ifdef __KERNEL__ 345#ifdef __KERNEL__
342 346
343/* 347/*
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 1c372f998c15..92fedfcc879a 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -256,6 +256,22 @@ xfs_mount_validate_sb(
256 return XFS_ERROR(ENOSYS); 256 return XFS_ERROR(ENOSYS);
257 } 257 }
258 258
259 /*
260 * Currently only very few inode sizes are supported.
261 */
262 switch (sbp->sb_inodesize) {
263 case 256:
264 case 512:
265 case 1024:
266 case 2048:
267 break;
268 default:
269 xfs_fs_mount_cmn_err(flags,
270 "inode size of %d bytes not supported",
271 sbp->sb_inodesize);
272 return XFS_ERROR(ENOSYS);
273 }
274
259 if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) || 275 if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) ||
260 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { 276 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
261 xfs_fs_mount_cmn_err(flags, 277 xfs_fs_mount_cmn_err(flags,
@@ -578,27 +594,6 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
578 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; 594 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
579 mp->m_blockwmask = mp->m_blockwsize - 1; 595 mp->m_blockwmask = mp->m_blockwsize - 1;
580 596
581 /*
582 * Setup for attributes, in case they get created.
583 * This value is for inodes getting attributes for the first time,
584 * the per-inode value is for old attribute values.
585 */
586 ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
587 switch (sbp->sb_inodesize) {
588 case 256:
589 mp->m_attroffset = XFS_LITINO(mp) -
590 XFS_BMDR_SPACE_CALC(MINABTPTRS);
591 break;
592 case 512:
593 case 1024:
594 case 2048:
595 mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
596 break;
597 default:
598 ASSERT(0);
599 }
600 ASSERT(mp->m_attroffset < XFS_LITINO(mp));
601
602 mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); 597 mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
603 mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); 598 mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
604 mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; 599 mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 5dbc6f72d988..7af44adffc8f 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -276,7 +276,6 @@ typedef struct xfs_mount {
276 int m_fixedfsid[2]; /* unchanged for life of FS */ 276 int m_fixedfsid[2]; /* unchanged for life of FS */
277 uint m_dmevmask; /* DMI events for this FS */ 277 uint m_dmevmask; /* DMI events for this FS */
278 __uint64_t m_flags; /* global mount flags */ 278 __uint64_t m_flags; /* global mount flags */
279 uint m_attroffset; /* inode attribute offset */
280 uint m_dir_node_ents; /* #entries in a dir danode */ 279 uint m_dir_node_ents; /* #entries in a dir danode */
281 uint m_attr_node_ents; /* #entries in attr danode */ 280 uint m_attr_node_ents; /* #entries in attr danode */
282 int m_ialloc_inos; /* inodes in inode allocation */ 281 int m_ialloc_inos; /* inodes in inode allocation */