diff options
-rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 56 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 37 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 1 |
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 | */ | ||
3574 | uint | ||
3575 | xfs_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 | ||
341 | uint | ||
342 | xfs_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 */ |