aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2009-03-29 13:26:46 -0400
committerChristoph Hellwig <hch@brick.lst.de>2009-03-29 13:26:46 -0400
commit1a5902c5d2ad4f3aa1ee747017622d5d4edfa20f (patch)
treecf93367c9b63f814095351c1eeb8d7cc1c2d3f9f /fs/xfs
parent9da096fd13e63031662566e5e868ec3dcc70824e (diff)
xfs: remove m_attroffset
With the upcoming v3 inodes the default attroffset needs to be calculated for each specific inode, so we can't cache it in the superblock anymore. Also replace the assert for wrong inode sizes with a proper error check also included in non-debug builds. Note that the ENOSYS return for that might seem odd, but that error is returned by xfs_mount_validate_sb for all theoretically valid but not supported filesystem geometries. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Diffstat (limited to 'fs/xfs')
-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 */