* move the extent count and format into struct xfs_ifork @ 2020-05-10 7:23 Christoph Hellwig 2020-05-10 7:23 ` [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps Christoph Hellwig ` (5 more replies) 0 siblings, 6 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-10 7:23 UTC (permalink / raw) To: linux-xfs Hi all, this series moves the extent count and format fields into the xfs_ifork structure. It is based on the "dinode reading cleanups v2" series. Git tree: git://git.infradead.org/users/hch/xfs.git xfs-ifork-cleanup Gitweb: http://git.infradead.org/users/hch/xfs.git/shortlog/refs/heads/xfs-ifork-cleanup ^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-10 7:23 move the extent count and format into struct xfs_ifork Christoph Hellwig @ 2020-05-10 7:23 ` Christoph Hellwig 2020-05-11 11:40 ` Chandan Babu R 2020-05-16 18:42 ` [PATCH] xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q Darrick J. Wong 2020-05-10 7:24 ` [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro Christoph Hellwig ` (4 subsequent siblings) 5 siblings, 2 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-10 7:23 UTC (permalink / raw) To: linux-xfs XFS_IFORK_Q is to be used in boolean context, not for a size. This doesn't make a difference in practice as size is only checked for 0, but this keeps the logic sane. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/scrub/bmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index add8598eacd5d..283424d6d2bb6 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -591,7 +591,7 @@ xchk_bmap_check_rmaps( size = i_size_read(VFS_I(sc->ip)); break; case XFS_ATTR_FORK: - size = XFS_IFORK_Q(sc->ip); + size = XFS_IFORK_BOFF(sc->ip); break; default: size = 0; -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-10 7:23 ` [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps Christoph Hellwig @ 2020-05-11 11:40 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster 2020-05-16 18:42 ` [PATCH] xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q Darrick J. Wong 1 sibling, 1 reply; 41+ messages in thread From: Chandan Babu R @ 2020-05-11 11:40 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sunday 10 May 2020 12:53:59 PM IST Christoph Hellwig wrote: > XFS_IFORK_Q is to be used in boolean context, not for a size. This > doesn't make a difference in practice as size is only checked for > 0, but this keeps the logic sane. > Wouldn't XFS_IFORK_ASIZE() be a better fit since it gives the space used by the attr fork inside an inode's literal area? > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/scrub/bmap.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > index add8598eacd5d..283424d6d2bb6 100644 > --- a/fs/xfs/scrub/bmap.c > +++ b/fs/xfs/scrub/bmap.c > @@ -591,7 +591,7 @@ xchk_bmap_check_rmaps( > size = i_size_read(VFS_I(sc->ip)); > break; > case XFS_ATTR_FORK: > - size = XFS_IFORK_Q(sc->ip); > + size = XFS_IFORK_BOFF(sc->ip); > break; > default: > size = 0; > -- chandan ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-11 11:40 ` Chandan Babu R @ 2020-05-12 15:31 ` Brian Foster 2020-05-12 15:38 ` Darrick J. Wong 0 siblings, 1 reply; 41+ messages in thread From: Brian Foster @ 2020-05-12 15:31 UTC (permalink / raw) To: Chandan Babu R; +Cc: Christoph Hellwig, linux-xfs On Mon, May 11, 2020 at 05:10:04PM +0530, Chandan Babu R wrote: > On Sunday 10 May 2020 12:53:59 PM IST Christoph Hellwig wrote: > > XFS_IFORK_Q is to be used in boolean context, not for a size. This > > doesn't make a difference in practice as size is only checked for > > 0, but this keeps the logic sane. > > > > Wouldn't XFS_IFORK_ASIZE() be a better fit since it gives the space used by the > attr fork inside an inode's literal area? > I had the same thought. It's not clear to me what size is really supposed to be between the file size for a data fork and fork offset for the attr fork. I was also wondering if this should use XFS_IFORK_DSIZE(), but that won't be conditional based on population of the fork. At the same time, I don't think i_size != 0 necessarily correlates with the existence of blocks. The file could be completely sparse or could have any number of post-eof preallocated extents. Brian > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > --- > > fs/xfs/scrub/bmap.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > index add8598eacd5d..283424d6d2bb6 100644 > > --- a/fs/xfs/scrub/bmap.c > > +++ b/fs/xfs/scrub/bmap.c > > @@ -591,7 +591,7 @@ xchk_bmap_check_rmaps( > > size = i_size_read(VFS_I(sc->ip)); > > break; > > case XFS_ATTR_FORK: > > - size = XFS_IFORK_Q(sc->ip); > > + size = XFS_IFORK_BOFF(sc->ip); > > break; > > default: > > size = 0; > > > > > -- > chandan > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-12 15:31 ` Brian Foster @ 2020-05-12 15:38 ` Darrick J. Wong 2020-05-12 16:14 ` Brian Foster 0 siblings, 1 reply; 41+ messages in thread From: Darrick J. Wong @ 2020-05-12 15:38 UTC (permalink / raw) To: Brian Foster; +Cc: Chandan Babu R, Christoph Hellwig, linux-xfs On Tue, May 12, 2020 at 11:31:32AM -0400, Brian Foster wrote: > On Mon, May 11, 2020 at 05:10:04PM +0530, Chandan Babu R wrote: > > On Sunday 10 May 2020 12:53:59 PM IST Christoph Hellwig wrote: > > > XFS_IFORK_Q is to be used in boolean context, not for a size. This > > > doesn't make a difference in practice as size is only checked for > > > 0, but this keeps the logic sane. > > > > > > > Wouldn't XFS_IFORK_ASIZE() be a better fit since it gives the space used by the > > attr fork inside an inode's literal area? > > > > I had the same thought. It's not clear to me what size is really > supposed to be between the file size for a data fork and fork offset for > the attr fork. I was also wondering if this should use > XFS_IFORK_DSIZE(), but that won't be conditional based on population of > the fork. At the same time, I don't think i_size != 0 necessarily > correlates with the existence of blocks. The file could be completely > sparse or could have any number of post-eof preallocated extents. TBH I should have made that variable "bool empty" or something. case XFS_DATA_FORK: empty = i_size_read() == 0; case XFS_ATTR_FORK: empty = !XFS_IFORK_Q(); default: empty = true; if ((is not btree) && (empty || nextents > 0)) return 0; --D > Brian > > > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > > --- > > > fs/xfs/scrub/bmap.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > > index add8598eacd5d..283424d6d2bb6 100644 > > > --- a/fs/xfs/scrub/bmap.c > > > +++ b/fs/xfs/scrub/bmap.c > > > @@ -591,7 +591,7 @@ xchk_bmap_check_rmaps( > > > size = i_size_read(VFS_I(sc->ip)); > > > break; > > > case XFS_ATTR_FORK: > > > - size = XFS_IFORK_Q(sc->ip); > > > + size = XFS_IFORK_BOFF(sc->ip); > > > break; > > > default: > > > size = 0; > > > > > > > > > -- > > chandan > > > > > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-12 15:38 ` Darrick J. Wong @ 2020-05-12 16:14 ` Brian Foster 2020-05-12 19:16 ` Darrick J. Wong 0 siblings, 1 reply; 41+ messages in thread From: Brian Foster @ 2020-05-12 16:14 UTC (permalink / raw) To: Darrick J. Wong; +Cc: Chandan Babu R, Christoph Hellwig, linux-xfs On Tue, May 12, 2020 at 08:38:54AM -0700, Darrick J. Wong wrote: > On Tue, May 12, 2020 at 11:31:32AM -0400, Brian Foster wrote: > > On Mon, May 11, 2020 at 05:10:04PM +0530, Chandan Babu R wrote: > > > On Sunday 10 May 2020 12:53:59 PM IST Christoph Hellwig wrote: > > > > XFS_IFORK_Q is to be used in boolean context, not for a size. This > > > > doesn't make a difference in practice as size is only checked for > > > > 0, but this keeps the logic sane. > > > > > > > > > > Wouldn't XFS_IFORK_ASIZE() be a better fit since it gives the space used by the > > > attr fork inside an inode's literal area? > > > > > > > I had the same thought. It's not clear to me what size is really > > supposed to be between the file size for a data fork and fork offset for > > the attr fork. I was also wondering if this should use > > XFS_IFORK_DSIZE(), but that won't be conditional based on population of > > the fork. At the same time, I don't think i_size != 0 necessarily > > correlates with the existence of blocks. The file could be completely > > sparse or could have any number of post-eof preallocated extents. > > TBH I should have made that variable "bool empty" or something. > > case XFS_DATA_FORK: > empty = i_size_read() == 0; > Even that is somewhat unclear because it's tied to i_size. What about size == 0 && <post-eof extents>? Brian > case XFS_ATTR_FORK: > empty = !XFS_IFORK_Q(); > > default: > empty = true; > > if ((is not btree) && (empty || nextents > 0)) > return 0; > > --D > > > Brian > > > > > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > > > --- > > > > fs/xfs/scrub/bmap.c | 2 +- > > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > > > index add8598eacd5d..283424d6d2bb6 100644 > > > > --- a/fs/xfs/scrub/bmap.c > > > > +++ b/fs/xfs/scrub/bmap.c > > > > @@ -591,7 +591,7 @@ xchk_bmap_check_rmaps( > > > > size = i_size_read(VFS_I(sc->ip)); > > > > break; > > > > case XFS_ATTR_FORK: > > > > - size = XFS_IFORK_Q(sc->ip); > > > > + size = XFS_IFORK_BOFF(sc->ip); > > > > break; > > > > default: > > > > size = 0; > > > > > > > > > > > > > -- > > > chandan > > > > > > > > > > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-12 16:14 ` Brian Foster @ 2020-05-12 19:16 ` Darrick J. Wong 2020-05-13 13:19 ` Brian Foster 0 siblings, 1 reply; 41+ messages in thread From: Darrick J. Wong @ 2020-05-12 19:16 UTC (permalink / raw) To: Brian Foster; +Cc: Chandan Babu R, Christoph Hellwig, linux-xfs On Tue, May 12, 2020 at 12:14:10PM -0400, Brian Foster wrote: > On Tue, May 12, 2020 at 08:38:54AM -0700, Darrick J. Wong wrote: > > On Tue, May 12, 2020 at 11:31:32AM -0400, Brian Foster wrote: > > > On Mon, May 11, 2020 at 05:10:04PM +0530, Chandan Babu R wrote: > > > > On Sunday 10 May 2020 12:53:59 PM IST Christoph Hellwig wrote: > > > > > XFS_IFORK_Q is to be used in boolean context, not for a size. This > > > > > doesn't make a difference in practice as size is only checked for > > > > > 0, but this keeps the logic sane. > > > > > > > > > > > > > Wouldn't XFS_IFORK_ASIZE() be a better fit since it gives the space used by the > > > > attr fork inside an inode's literal area? > > > > > > > > > > I had the same thought. It's not clear to me what size is really > > > supposed to be between the file size for a data fork and fork offset for > > > the attr fork. I was also wondering if this should use > > > XFS_IFORK_DSIZE(), but that won't be conditional based on population of > > > the fork. At the same time, I don't think i_size != 0 necessarily > > > correlates with the existence of blocks. The file could be completely > > > sparse or could have any number of post-eof preallocated extents. > > > > TBH I should have made that variable "bool empty" or something. > > > > case XFS_DATA_FORK: > > empty = i_size_read() == 0; > > > > Even that is somewhat unclear because it's tied to i_size. What about > size == 0 && <post-eof extents>? /me stumbles around trying to remember under what circumstances do we actually scan all the rmaps to make sure there's a corresponding bmap. I think we're trying to avoid doing it for every file in the filesystem because it's very slow... Oh right -- we do that for btree format forks because there are a lot of extent records and therefore a high(er) chance of something getting lost; or We scan all the rmaps for files that have nonzero size but zero extents, because the (forthcoming) inode fork repair will reset damaged forks back to extents format with zero extents, and this is how we will trigger the bmap repair to get the extents mapped back into the file. --D > > Brian > > > case XFS_ATTR_FORK: > > empty = !XFS_IFORK_Q(); > > > > default: > > empty = true; > > > > if ((is not btree) && (empty || nextents > 0)) > > return 0; > > > > --D > > > > > Brian > > > > > > > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > > > > --- > > > > > fs/xfs/scrub/bmap.c | 2 +- > > > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > > > > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > > > > index add8598eacd5d..283424d6d2bb6 100644 > > > > > --- a/fs/xfs/scrub/bmap.c > > > > > +++ b/fs/xfs/scrub/bmap.c > > > > > @@ -591,7 +591,7 @@ xchk_bmap_check_rmaps( > > > > > size = i_size_read(VFS_I(sc->ip)); > > > > > break; > > > > > case XFS_ATTR_FORK: > > > > > - size = XFS_IFORK_Q(sc->ip); > > > > > + size = XFS_IFORK_BOFF(sc->ip); > > > > > break; > > > > > default: > > > > > size = 0; > > > > > > > > > > > > > > > > > -- > > > > chandan > > > > > > > > > > > > > > > > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-12 19:16 ` Darrick J. Wong @ 2020-05-13 13:19 ` Brian Foster 2020-05-13 13:21 ` Christoph Hellwig 0 siblings, 1 reply; 41+ messages in thread From: Brian Foster @ 2020-05-13 13:19 UTC (permalink / raw) To: Darrick J. Wong; +Cc: Chandan Babu R, Christoph Hellwig, linux-xfs On Tue, May 12, 2020 at 12:16:15PM -0700, Darrick J. Wong wrote: > On Tue, May 12, 2020 at 12:14:10PM -0400, Brian Foster wrote: > > On Tue, May 12, 2020 at 08:38:54AM -0700, Darrick J. Wong wrote: > > > On Tue, May 12, 2020 at 11:31:32AM -0400, Brian Foster wrote: > > > > On Mon, May 11, 2020 at 05:10:04PM +0530, Chandan Babu R wrote: > > > > > On Sunday 10 May 2020 12:53:59 PM IST Christoph Hellwig wrote: > > > > > > XFS_IFORK_Q is to be used in boolean context, not for a size. This > > > > > > doesn't make a difference in practice as size is only checked for > > > > > > 0, but this keeps the logic sane. > > > > > > > > > > > > > > > > Wouldn't XFS_IFORK_ASIZE() be a better fit since it gives the space used by the > > > > > attr fork inside an inode's literal area? > > > > > > > > > > > > > I had the same thought. It's not clear to me what size is really > > > > supposed to be between the file size for a data fork and fork offset for > > > > the attr fork. I was also wondering if this should use > > > > XFS_IFORK_DSIZE(), but that won't be conditional based on population of > > > > the fork. At the same time, I don't think i_size != 0 necessarily > > > > correlates with the existence of blocks. The file could be completely > > > > sparse or could have any number of post-eof preallocated extents. > > > > > > TBH I should have made that variable "bool empty" or something. > > > > > > case XFS_DATA_FORK: > > > empty = i_size_read() == 0; > > > > > > > Even that is somewhat unclear because it's tied to i_size. What about > > size == 0 && <post-eof extents>? > > /me stumbles around trying to remember under what circumstances do we > actually scan all the rmaps to make sure there's a corresponding bmap. > I think we're trying to avoid doing it for every file in the filesystem > because it's very slow... > > Oh right -- we do that for btree format forks because there are a lot of > extent records and therefore a high(er) chance of something getting > lost; or > > We scan all the rmaps for files that have nonzero size but zero extents, > because the (forthcoming) inode fork repair will reset damaged forks > back to extents format with zero extents, and this is how we will > trigger the bmap repair to get the extents mapped back into the file. > Not sure I follow. Does this mean we're basically looking at sparse files as "suspect" because we'd expect them to have extents? Why are we looking at i_size here instead of fork size like for the attr fork, for example? Either way it sounds like we're getting into some twisty repair logic so perhaps this is beyond the scope of Christoph's patches.. Brian > --D > > > > > Brian > > > > > case XFS_ATTR_FORK: > > > empty = !XFS_IFORK_Q(); > > > > > > default: > > > empty = true; > > > > > > if ((is not btree) && (empty || nextents > 0)) > > > return 0; > > > > > > --D > > > > > > > Brian > > > > > > > > > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > > > > > --- > > > > > > fs/xfs/scrub/bmap.c | 2 +- > > > > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > > > > > > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > > > > > index add8598eacd5d..283424d6d2bb6 100644 > > > > > > --- a/fs/xfs/scrub/bmap.c > > > > > > +++ b/fs/xfs/scrub/bmap.c > > > > > > @@ -591,7 +591,7 @@ xchk_bmap_check_rmaps( > > > > > > size = i_size_read(VFS_I(sc->ip)); > > > > > > break; > > > > > > case XFS_ATTR_FORK: > > > > > > - size = XFS_IFORK_Q(sc->ip); > > > > > > + size = XFS_IFORK_BOFF(sc->ip); > > > > > > break; > > > > > > default: > > > > > > size = 0; > > > > > > > > > > > > > > > > > > > > > -- > > > > > chandan > > > > > > > > > > > > > > > > > > > > > > > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps 2020-05-13 13:19 ` Brian Foster @ 2020-05-13 13:21 ` Christoph Hellwig 0 siblings, 0 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-13 13:21 UTC (permalink / raw) To: Brian Foster Cc: Darrick J. Wong, Chandan Babu R, Christoph Hellwig, linux-xfs On Wed, May 13, 2020 at 09:19:50AM -0400, Brian Foster wrote: > > We scan all the rmaps for files that have nonzero size but zero extents, > > because the (forthcoming) inode fork repair will reset damaged forks > > back to extents format with zero extents, and this is how we will > > trigger the bmap repair to get the extents mapped back into the file. > > > > Not sure I follow. Does this mean we're basically looking at sparse > files as "suspect" because we'd expect them to have extents? Why are we > looking at i_size here instead of fork size like for the attr fork, for > example? Either way it sounds like we're getting into some twisty repair > logic so perhaps this is beyond the scope of Christoph's patches.. The patch can be easily dropped from the series. I just noticed something fishy while looking over the code and though the fix would be easy enough.. ^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH] xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q 2020-05-10 7:23 ` [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps Christoph Hellwig 2020-05-11 11:40 ` Chandan Babu R @ 2020-05-16 18:42 ` Darrick J. Wong 2020-05-16 20:01 ` Christoph Hellwig 1 sibling, 1 reply; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 18:42 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs From: Darrick J. Wong <darrick.wong@oracle.com> XFS_IFORK_Q is supposed to be a predicate, not a function returning a value. Its usage is in xchk_bmap_check_rmaps is incorrect, but that function only cares about whether or not the "size" of the data is zero or not. Convert that logic to use a proper boolean, and teach the caller to skip the call entirely if the end result would be that we'd do nothing anyway. This avoids a crash later in this series. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> --- fs/xfs/scrub/bmap.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index add8598eacd5..002f10944de7 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -566,8 +566,8 @@ xchk_bmap_check_rmaps( struct xfs_scrub *sc, int whichfork) { - loff_t size; xfs_agnumber_t agno; + bool zero_size; int error; if (!xfs_sb_version_hasrmapbt(&sc->mp->m_sb) || @@ -579,6 +579,8 @@ xchk_bmap_check_rmaps( if (XFS_IS_REALTIME_INODE(sc->ip) && whichfork == XFS_DATA_FORK) return 0; + ASSERT(XFS_IFORK_PTR(sc->ip, whichfork) != NULL); + /* * Only do this for complex maps that are in btree format, or for * situations where we would seem to have a size but zero extents. @@ -586,19 +588,13 @@ xchk_bmap_check_rmaps( * to flag this bmap as corrupt if there are rmaps that need to be * reattached. */ - switch (whichfork) { - case XFS_DATA_FORK: - size = i_size_read(VFS_I(sc->ip)); - break; - case XFS_ATTR_FORK: - size = XFS_IFORK_Q(sc->ip); - break; - default: - size = 0; - break; - } + if (whichfork == XFS_DATA_FORK) + zero_size = i_size_read(VFS_I(sc->ip)) == 0; + else + zero_size = false; + if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && - (size == 0 || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) + (zero_size || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) return 0; for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { @@ -651,8 +647,9 @@ xchk_bmap( } break; case XFS_ATTR_FORK: + /* No fork means no attr data at all. */ if (!ifp) - goto out_check_rmap; + goto out; if (!xfs_sb_version_hasattr(&mp->m_sb) && !xfs_sb_version_hasattr2(&mp->m_sb)) xchk_ino_set_corrupt(sc, sc->ip->i_ino); @@ -717,7 +714,6 @@ xchk_bmap( goto out; } -out_check_rmap: error = xchk_bmap_check_rmaps(sc, whichfork); if (!xchk_fblock_xref_process_error(sc, whichfork, 0, &error)) goto out; ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH] xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q 2020-05-16 18:42 ` [PATCH] xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q Darrick J. Wong @ 2020-05-16 20:01 ` Christoph Hellwig 2020-05-17 8:05 ` Christoph Hellwig 0 siblings, 1 reply; 41+ messages in thread From: Christoph Hellwig @ 2020-05-16 20:01 UTC (permalink / raw) To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs > for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { > @@ -651,8 +647,9 @@ xchk_bmap( > } > break; > case XFS_ATTR_FORK: > + /* No fork means no attr data at all. */ > if (!ifp) > - goto out_check_rmap; > + goto out; Maybe lift the !ifp to before the switch statement, or even to just after assigning the value to ifp? For the data fork it obviously won't be true, but it still looks simple than duplicating it for the attr and cow fork. Otherwise looks fine: Reviewed-by: Christoph Hellwig <hch@lst.de> ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH] xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q 2020-05-16 20:01 ` Christoph Hellwig @ 2020-05-17 8:05 ` Christoph Hellwig 0 siblings, 0 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-17 8:05 UTC (permalink / raw) To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs On Sat, May 16, 2020 at 10:01:06PM +0200, Christoph Hellwig wrote: > > for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { > > @@ -651,8 +647,9 @@ xchk_bmap( > > } > > break; > > case XFS_ATTR_FORK: > > + /* No fork means no attr data at all. */ > > if (!ifp) > > - goto out_check_rmap; > > + goto out; > > Maybe lift the !ifp to before the switch statement, or even to just after > assigning the value to ifp? For the data fork it obviously won't be > true, but it still looks simple than duplicating it for the attr and > cow fork. > > Otherwise looks fine: > > Reviewed-by: Christoph Hellwig <hch@lst.de> This is what I ended up with for my tree: --- From a98ef6f4bbfe186a83d3384cbd0a0727c0e1ddee Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" <darrick.wong@oracle.com> Date: Sat, 16 May 2020 11:42:59 -0700 Subject: xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q XFS_IFORK_Q is supposed to be a predicate, not a function returning a value. Its usage is in xchk_bmap_check_rmaps is incorrect, but that function only cares about whether or not the "size" of the data is zero or not. Convert that logic to use a proper boolean, and teach the caller to skip the call entirely if the end result would be that we'd do nothing anyway. This avoids a crash later in this series. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> [hch: generalized the NULL ifor check] Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/scrub/bmap.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index add8598eacd5d..93d5b8a9d7f74 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -566,8 +566,8 @@ xchk_bmap_check_rmaps( struct xfs_scrub *sc, int whichfork) { - loff_t size; xfs_agnumber_t agno; + bool zero_size; int error; if (!xfs_sb_version_hasrmapbt(&sc->mp->m_sb) || @@ -579,6 +579,8 @@ xchk_bmap_check_rmaps( if (XFS_IS_REALTIME_INODE(sc->ip) && whichfork == XFS_DATA_FORK) return 0; + ASSERT(XFS_IFORK_PTR(sc->ip, whichfork) != NULL); + /* * Only do this for complex maps that are in btree format, or for * situations where we would seem to have a size but zero extents. @@ -586,19 +588,13 @@ xchk_bmap_check_rmaps( * to flag this bmap as corrupt if there are rmaps that need to be * reattached. */ - switch (whichfork) { - case XFS_DATA_FORK: - size = i_size_read(VFS_I(sc->ip)); - break; - case XFS_ATTR_FORK: - size = XFS_IFORK_Q(sc->ip); - break; - default: - size = 0; - break; - } + if (whichfork == XFS_DATA_FORK) + zero_size = i_size_read(VFS_I(sc->ip)) == 0; + else + zero_size = false; + if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && - (size == 0 || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) + (zero_size || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) return 0; for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { @@ -627,12 +623,14 @@ xchk_bmap( struct xchk_bmap_info info = { NULL }; struct xfs_mount *mp = sc->mp; struct xfs_inode *ip = sc->ip; - struct xfs_ifork *ifp; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); xfs_fileoff_t endoff; struct xfs_iext_cursor icur; int error = 0; - ifp = XFS_IFORK_PTR(ip, whichfork); + /* Non-existent forks can be ignored. */ + if (!ifp) + goto out; info.is_rt = whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip); info.whichfork = whichfork; @@ -641,9 +639,6 @@ xchk_bmap( switch (whichfork) { case XFS_COW_FORK: - /* Non-existent CoW forks are ignorable. */ - if (!ifp) - goto out; /* No CoW forks on non-reflink inodes/filesystems. */ if (!xfs_is_reflink_inode(ip)) { xchk_ino_set_corrupt(sc, sc->ip->i_ino); @@ -651,8 +646,6 @@ xchk_bmap( } break; case XFS_ATTR_FORK: - if (!ifp) - goto out_check_rmap; if (!xfs_sb_version_hasattr(&mp->m_sb) && !xfs_sb_version_hasattr2(&mp->m_sb)) xchk_ino_set_corrupt(sc, sc->ip->i_ino); @@ -717,7 +710,6 @@ xchk_bmap( goto out; } -out_check_rmap: error = xchk_bmap_check_rmaps(sc, whichfork); if (!xchk_fblock_xref_process_error(sc, whichfork, 0, &error)) goto out; -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro 2020-05-10 7:23 move the extent count and format into struct xfs_ifork Christoph Hellwig 2020-05-10 7:23 ` [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps Christoph Hellwig @ 2020-05-10 7:24 ` Christoph Hellwig 2020-05-11 12:39 ` Chandan Babu R ` (2 more replies) 2020-05-10 7:24 ` [PATCH 3/6] xfs: remove xfs_ifree_local_data Christoph Hellwig ` (3 subsequent siblings) 5 siblings, 3 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-10 7:24 UTC (permalink / raw) To: linux-xfs Just checking di_forkoff directly is a little easier to follow. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/libxfs/xfs_format.h | 5 ++--- fs/xfs/libxfs/xfs_inode_buf.c | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 045556e78ee2c..3cc352000b8a1 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -964,13 +964,12 @@ enum xfs_dinode_fmt { /* * Inode data & attribute fork sizes, per inode. */ -#define XFS_DFORK_Q(dip) ((dip)->di_forkoff != 0) #define XFS_DFORK_BOFF(dip) ((int)((dip)->di_forkoff << 3)) #define XFS_DFORK_DSIZE(dip,mp) \ - (XFS_DFORK_Q(dip) ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) + ((dip)->di_forkoff ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) #define XFS_DFORK_ASIZE(dip,mp) \ - (XFS_DFORK_Q(dip) ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) + ((dip)->di_forkoff ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) #define XFS_DFORK_SIZE(dip,mp,w) \ ((w) == XFS_DATA_FORK ? \ XFS_DFORK_DSIZE(dip, mp) : \ diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 05f939adea944..5547bbb3cf945 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -265,7 +265,7 @@ xfs_inode_from_disk( error = xfs_iformat_data_fork(ip, from); if (error) return error; - if (XFS_DFORK_Q(from)) { + if (from->di_forkoff) { error = xfs_iformat_attr_fork(ip, from); if (error) goto out_destroy_data_fork; @@ -435,7 +435,7 @@ xfs_dinode_verify_forkoff( struct xfs_dinode *dip, struct xfs_mount *mp) { - if (!XFS_DFORK_Q(dip)) + if (!dip->di_forkoff) return NULL; switch (dip->di_format) { @@ -538,7 +538,7 @@ xfs_dinode_verify( return __this_address; } - if (XFS_DFORK_Q(dip)) { + if (dip->di_forkoff) { fa = xfs_dinode_verify_fork(dip, mp, XFS_ATTR_FORK); if (fa) return fa; -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro 2020-05-10 7:24 ` [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro Christoph Hellwig @ 2020-05-11 12:39 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster 2020-05-16 18:02 ` Darrick J. Wong 2 siblings, 0 replies; 41+ messages in thread From: Chandan Babu R @ 2020-05-11 12:39 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sunday 10 May 2020 12:54:00 PM IST Christoph Hellwig wrote: > Just checking di_forkoff directly is a little easier to follow. > Looks good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/libxfs/xfs_format.h | 5 ++--- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +++--- > 2 files changed, 5 insertions(+), 6 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h > index 045556e78ee2c..3cc352000b8a1 100644 > --- a/fs/xfs/libxfs/xfs_format.h > +++ b/fs/xfs/libxfs/xfs_format.h > @@ -964,13 +964,12 @@ enum xfs_dinode_fmt { > /* > * Inode data & attribute fork sizes, per inode. > */ > -#define XFS_DFORK_Q(dip) ((dip)->di_forkoff != 0) > #define XFS_DFORK_BOFF(dip) ((int)((dip)->di_forkoff << 3)) > > #define XFS_DFORK_DSIZE(dip,mp) \ > - (XFS_DFORK_Q(dip) ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) > + ((dip)->di_forkoff ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) > #define XFS_DFORK_ASIZE(dip,mp) \ > - (XFS_DFORK_Q(dip) ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) > + ((dip)->di_forkoff ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) > #define XFS_DFORK_SIZE(dip,mp,w) \ > ((w) == XFS_DATA_FORK ? \ > XFS_DFORK_DSIZE(dip, mp) : \ > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index 05f939adea944..5547bbb3cf945 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -265,7 +265,7 @@ xfs_inode_from_disk( > error = xfs_iformat_data_fork(ip, from); > if (error) > return error; > - if (XFS_DFORK_Q(from)) { > + if (from->di_forkoff) { > error = xfs_iformat_attr_fork(ip, from); > if (error) > goto out_destroy_data_fork; > @@ -435,7 +435,7 @@ xfs_dinode_verify_forkoff( > struct xfs_dinode *dip, > struct xfs_mount *mp) > { > - if (!XFS_DFORK_Q(dip)) > + if (!dip->di_forkoff) > return NULL; > > switch (dip->di_format) { > @@ -538,7 +538,7 @@ xfs_dinode_verify( > return __this_address; > } > > - if (XFS_DFORK_Q(dip)) { > + if (dip->di_forkoff) { > fa = xfs_dinode_verify_fork(dip, mp, XFS_ATTR_FORK); > if (fa) > return fa; > -- chandan ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro 2020-05-10 7:24 ` [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro Christoph Hellwig 2020-05-11 12:39 ` Chandan Babu R @ 2020-05-12 15:31 ` Brian Foster 2020-05-16 18:02 ` Darrick J. Wong 2 siblings, 0 replies; 41+ messages in thread From: Brian Foster @ 2020-05-12 15:31 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:00AM +0200, Christoph Hellwig wrote: > Just checking di_forkoff directly is a little easier to follow. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- Reviewed-by: Brian Foster <bfoster@redhat.com> > fs/xfs/libxfs/xfs_format.h | 5 ++--- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +++--- > 2 files changed, 5 insertions(+), 6 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h > index 045556e78ee2c..3cc352000b8a1 100644 > --- a/fs/xfs/libxfs/xfs_format.h > +++ b/fs/xfs/libxfs/xfs_format.h > @@ -964,13 +964,12 @@ enum xfs_dinode_fmt { > /* > * Inode data & attribute fork sizes, per inode. > */ > -#define XFS_DFORK_Q(dip) ((dip)->di_forkoff != 0) > #define XFS_DFORK_BOFF(dip) ((int)((dip)->di_forkoff << 3)) > > #define XFS_DFORK_DSIZE(dip,mp) \ > - (XFS_DFORK_Q(dip) ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) > + ((dip)->di_forkoff ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) > #define XFS_DFORK_ASIZE(dip,mp) \ > - (XFS_DFORK_Q(dip) ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) > + ((dip)->di_forkoff ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) > #define XFS_DFORK_SIZE(dip,mp,w) \ > ((w) == XFS_DATA_FORK ? \ > XFS_DFORK_DSIZE(dip, mp) : \ > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index 05f939adea944..5547bbb3cf945 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -265,7 +265,7 @@ xfs_inode_from_disk( > error = xfs_iformat_data_fork(ip, from); > if (error) > return error; > - if (XFS_DFORK_Q(from)) { > + if (from->di_forkoff) { > error = xfs_iformat_attr_fork(ip, from); > if (error) > goto out_destroy_data_fork; > @@ -435,7 +435,7 @@ xfs_dinode_verify_forkoff( > struct xfs_dinode *dip, > struct xfs_mount *mp) > { > - if (!XFS_DFORK_Q(dip)) > + if (!dip->di_forkoff) > return NULL; > > switch (dip->di_format) { > @@ -538,7 +538,7 @@ xfs_dinode_verify( > return __this_address; > } > > - if (XFS_DFORK_Q(dip)) { > + if (dip->di_forkoff) { > fa = xfs_dinode_verify_fork(dip, mp, XFS_ATTR_FORK); > if (fa) > return fa; > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro 2020-05-10 7:24 ` [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro Christoph Hellwig 2020-05-11 12:39 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster @ 2020-05-16 18:02 ` Darrick J. Wong 2 siblings, 0 replies; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 18:02 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:00AM +0200, Christoph Hellwig wrote: > Just checking di_forkoff directly is a little easier to follow. > > Signed-off-by: Christoph Hellwig <hch@lst.de> /me hates macros Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> --D > --- > fs/xfs/libxfs/xfs_format.h | 5 ++--- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +++--- > 2 files changed, 5 insertions(+), 6 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h > index 045556e78ee2c..3cc352000b8a1 100644 > --- a/fs/xfs/libxfs/xfs_format.h > +++ b/fs/xfs/libxfs/xfs_format.h > @@ -964,13 +964,12 @@ enum xfs_dinode_fmt { > /* > * Inode data & attribute fork sizes, per inode. > */ > -#define XFS_DFORK_Q(dip) ((dip)->di_forkoff != 0) > #define XFS_DFORK_BOFF(dip) ((int)((dip)->di_forkoff << 3)) > > #define XFS_DFORK_DSIZE(dip,mp) \ > - (XFS_DFORK_Q(dip) ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) > + ((dip)->di_forkoff ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp)) > #define XFS_DFORK_ASIZE(dip,mp) \ > - (XFS_DFORK_Q(dip) ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) > + ((dip)->di_forkoff ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0) > #define XFS_DFORK_SIZE(dip,mp,w) \ > ((w) == XFS_DATA_FORK ? \ > XFS_DFORK_DSIZE(dip, mp) : \ > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index 05f939adea944..5547bbb3cf945 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -265,7 +265,7 @@ xfs_inode_from_disk( > error = xfs_iformat_data_fork(ip, from); > if (error) > return error; > - if (XFS_DFORK_Q(from)) { > + if (from->di_forkoff) { > error = xfs_iformat_attr_fork(ip, from); > if (error) > goto out_destroy_data_fork; > @@ -435,7 +435,7 @@ xfs_dinode_verify_forkoff( > struct xfs_dinode *dip, > struct xfs_mount *mp) > { > - if (!XFS_DFORK_Q(dip)) > + if (!dip->di_forkoff) > return NULL; > > switch (dip->di_format) { > @@ -538,7 +538,7 @@ xfs_dinode_verify( > return __this_address; > } > > - if (XFS_DFORK_Q(dip)) { > + if (dip->di_forkoff) { > fa = xfs_dinode_verify_fork(dip, mp, XFS_ATTR_FORK); > if (fa) > return fa; > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 3/6] xfs: remove xfs_ifree_local_data 2020-05-10 7:23 move the extent count and format into struct xfs_ifork Christoph Hellwig 2020-05-10 7:23 ` [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps Christoph Hellwig 2020-05-10 7:24 ` [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro Christoph Hellwig @ 2020-05-10 7:24 ` Christoph Hellwig 2020-05-11 16:32 ` Chandan Babu R ` (2 more replies) 2020-05-10 7:24 ` [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork Christoph Hellwig ` (2 subsequent siblings) 5 siblings, 3 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-10 7:24 UTC (permalink / raw) To: linux-xfs xfs_ifree only need to free inline data in the data fork, as we've already taken care of the attr fork before (and in fact freed the fork structure). Just open code the freeing of the inline data. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/xfs_inode.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 549ff468b7b60..7d3144dc99b72 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2711,24 +2711,6 @@ xfs_ifree_cluster( return 0; } -/* - * Free any local-format buffers sitting around before we reset to - * extents format. - */ -static inline void -xfs_ifree_local_data( - struct xfs_inode *ip, - int whichfork) -{ - struct xfs_ifork *ifp; - - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) - return; - - ifp = XFS_IFORK_PTR(ip, whichfork); - xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); -} - /* * This is called to return an inode to the inode free list. * The inode should already be truncated to 0 length and have @@ -2765,8 +2747,16 @@ xfs_ifree( if (error) return error; - xfs_ifree_local_data(ip, XFS_DATA_FORK); - xfs_ifree_local_data(ip, XFS_ATTR_FORK); + /* + * Free any local-format data sitting around before we reset the + * data fork to extents format. Note that the attr fork data has + * already been freed by xfs_attr_inactive. + */ + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { + kmem_free(ip->i_df.if_u1.if_data); + ip->i_df.if_u1.if_data = NULL; + ip->i_df.if_bytes = 0; + } VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ ip->i_d.di_flags = 0; -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 3/6] xfs: remove xfs_ifree_local_data 2020-05-10 7:24 ` [PATCH 3/6] xfs: remove xfs_ifree_local_data Christoph Hellwig @ 2020-05-11 16:32 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster 2020-05-16 18:07 ` Darrick J. Wong 2 siblings, 0 replies; 41+ messages in thread From: Chandan Babu R @ 2020-05-11 16:32 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sunday 10 May 2020 12:54:01 PM IST Christoph Hellwig wrote: > xfs_ifree only need to free inline data in the data fork, as we've > already taken care of the attr fork before (and in fact freed the > fork structure). Just open code the freeing of the inline data. > xfs_inactive() => xfs_attr_inactive() would have freed the attr fork. Hence the changes made in this patch are correct. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/xfs_inode.c | 30 ++++++++++-------------------- > 1 file changed, 10 insertions(+), 20 deletions(-) > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 549ff468b7b60..7d3144dc99b72 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -2711,24 +2711,6 @@ xfs_ifree_cluster( > return 0; > } > > -/* > - * Free any local-format buffers sitting around before we reset to > - * extents format. > - */ > -static inline void > -xfs_ifree_local_data( > - struct xfs_inode *ip, > - int whichfork) > -{ > - struct xfs_ifork *ifp; > - > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) > - return; > - > - ifp = XFS_IFORK_PTR(ip, whichfork); > - xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); > -} > - > /* > * This is called to return an inode to the inode free list. > * The inode should already be truncated to 0 length and have > @@ -2765,8 +2747,16 @@ xfs_ifree( > if (error) > return error; > > - xfs_ifree_local_data(ip, XFS_DATA_FORK); > - xfs_ifree_local_data(ip, XFS_ATTR_FORK); > + /* > + * Free any local-format data sitting around before we reset the > + * data fork to extents format. Note that the attr fork data has > + * already been freed by xfs_attr_inactive. > + */ > + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + kmem_free(ip->i_df.if_u1.if_data); > + ip->i_df.if_u1.if_data = NULL; > + ip->i_df.if_bytes = 0; > + } > > VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ > ip->i_d.di_flags = 0; > -- chandan ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 3/6] xfs: remove xfs_ifree_local_data 2020-05-10 7:24 ` [PATCH 3/6] xfs: remove xfs_ifree_local_data Christoph Hellwig 2020-05-11 16:32 ` Chandan Babu R @ 2020-05-12 15:31 ` Brian Foster 2020-05-16 18:07 ` Darrick J. Wong 2 siblings, 0 replies; 41+ messages in thread From: Brian Foster @ 2020-05-12 15:31 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:01AM +0200, Christoph Hellwig wrote: > xfs_ifree only need to free inline data in the data fork, as we've > already taken care of the attr fork before (and in fact freed the > fork structure). Just open code the freeing of the inline data. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- Reviewed-by: Brian Foster <bfoster@redhat.com> > fs/xfs/xfs_inode.c | 30 ++++++++++-------------------- > 1 file changed, 10 insertions(+), 20 deletions(-) > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 549ff468b7b60..7d3144dc99b72 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -2711,24 +2711,6 @@ xfs_ifree_cluster( > return 0; > } > > -/* > - * Free any local-format buffers sitting around before we reset to > - * extents format. > - */ > -static inline void > -xfs_ifree_local_data( > - struct xfs_inode *ip, > - int whichfork) > -{ > - struct xfs_ifork *ifp; > - > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) > - return; > - > - ifp = XFS_IFORK_PTR(ip, whichfork); > - xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); > -} > - > /* > * This is called to return an inode to the inode free list. > * The inode should already be truncated to 0 length and have > @@ -2765,8 +2747,16 @@ xfs_ifree( > if (error) > return error; > > - xfs_ifree_local_data(ip, XFS_DATA_FORK); > - xfs_ifree_local_data(ip, XFS_ATTR_FORK); > + /* > + * Free any local-format data sitting around before we reset the > + * data fork to extents format. Note that the attr fork data has > + * already been freed by xfs_attr_inactive. > + */ > + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + kmem_free(ip->i_df.if_u1.if_data); > + ip->i_df.if_u1.if_data = NULL; > + ip->i_df.if_bytes = 0; > + } > > VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ > ip->i_d.di_flags = 0; > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 3/6] xfs: remove xfs_ifree_local_data 2020-05-10 7:24 ` [PATCH 3/6] xfs: remove xfs_ifree_local_data Christoph Hellwig 2020-05-11 16:32 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster @ 2020-05-16 18:07 ` Darrick J. Wong 2022-07-24 12:14 ` Alex Lyakas 2 siblings, 1 reply; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 18:07 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:01AM +0200, Christoph Hellwig wrote: > xfs_ifree only need to free inline data in the data fork, as we've > already taken care of the attr fork before (and in fact freed the > fork structure). Just open code the freeing of the inline data. > > Signed-off-by: Christoph Hellwig <hch@lst.de> Looks ok, Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> --D > --- > fs/xfs/xfs_inode.c | 30 ++++++++++-------------------- > 1 file changed, 10 insertions(+), 20 deletions(-) > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 549ff468b7b60..7d3144dc99b72 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -2711,24 +2711,6 @@ xfs_ifree_cluster( > return 0; > } > > -/* > - * Free any local-format buffers sitting around before we reset to > - * extents format. > - */ > -static inline void > -xfs_ifree_local_data( > - struct xfs_inode *ip, > - int whichfork) > -{ > - struct xfs_ifork *ifp; > - > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) > - return; > - > - ifp = XFS_IFORK_PTR(ip, whichfork); > - xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); > -} > - > /* > * This is called to return an inode to the inode free list. > * The inode should already be truncated to 0 length and have > @@ -2765,8 +2747,16 @@ xfs_ifree( > if (error) > return error; > > - xfs_ifree_local_data(ip, XFS_DATA_FORK); > - xfs_ifree_local_data(ip, XFS_ATTR_FORK); > + /* > + * Free any local-format data sitting around before we reset the > + * data fork to extents format. Note that the attr fork data has > + * already been freed by xfs_attr_inactive. > + */ > + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + kmem_free(ip->i_df.if_u1.if_data); > + ip->i_df.if_u1.if_data = NULL; > + ip->i_df.if_bytes = 0; > + } > > VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ > ip->i_d.di_flags = 0; > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 3/6] xfs: remove xfs_ifree_local_data 2020-05-16 18:07 ` Darrick J. Wong @ 2022-07-24 12:14 ` Alex Lyakas 0 siblings, 0 replies; 41+ messages in thread From: Alex Lyakas @ 2022-07-24 12:14 UTC (permalink / raw) To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs Hi Christoph, On Sat, May 16, 2020 at 9:07 PM Darrick J. Wong <darrick.wong@oracle.com> wrote: > > On Sun, May 10, 2020 at 09:24:01AM +0200, Christoph Hellwig wrote: > > xfs_ifree only need to free inline data in the data fork, as we've > > already taken care of the attr fork before (and in fact freed the > > fork structure). Just open code the freeing of the inline data. > > > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > Looks ok, > Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> > > --D > > > --- > > fs/xfs/xfs_inode.c | 30 ++++++++++-------------------- > > 1 file changed, 10 insertions(+), 20 deletions(-) > > > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > > index 549ff468b7b60..7d3144dc99b72 100644 > > --- a/fs/xfs/xfs_inode.c > > +++ b/fs/xfs/xfs_inode.c > > @@ -2711,24 +2711,6 @@ xfs_ifree_cluster( > > return 0; > > } > > > > -/* > > - * Free any local-format buffers sitting around before we reset to > > - * extents format. > > - */ > > -static inline void > > -xfs_ifree_local_data( > > - struct xfs_inode *ip, > > - int whichfork) > > -{ > > - struct xfs_ifork *ifp; > > - > > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) > > - return; > > - > > - ifp = XFS_IFORK_PTR(ip, whichfork); > > - xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); > > -} > > - > > /* > > * This is called to return an inode to the inode free list. > > * The inode should already be truncated to 0 length and have > > @@ -2765,8 +2747,16 @@ xfs_ifree( > > if (error) > > return error; > > > > - xfs_ifree_local_data(ip, XFS_DATA_FORK); > > - xfs_ifree_local_data(ip, XFS_ATTR_FORK); > > + /* > > + * Free any local-format data sitting around before we reset the > > + * data fork to extents format. Note that the attr fork data has > > + * already been freed by xfs_attr_inactive. > > + */ > > + if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > > + kmem_free(ip->i_df.if_u1.if_data); > > + ip->i_df.if_u1.if_data = NULL; > > + ip->i_df.if_bytes = 0; > > + } > > > > VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ > > ip->i_d.di_flags = 0; > > -- > > 2.26.2 > > I stumbled upon this patch, by analyzing a kernel panic we had [1]. Looking at the call trace, the panic happened in xfs_ifree_local_data() being called with XFS_ATTR_FORK. It looks like ifp = XFS_IFORK_PTR(ip, whichfork); returned NULL. Based on your patch, do I understand correctly that it fixes the panic? What happened seems to be that inode had an attribute fork and xfs_attr_fork_remove() was called on it. This function set: ip->i_afp = NULL ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS. As a result, xfs_ifree_local_data() [2] checked XFS_IFORK_FORMAT() and got XFS_DINODE_FMT_EXTENTS. So it performed: ifp = XFS_IFORK_PTR(ip, whichfork); xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); which caused NULL pointer exception. Is this analysis correct, that any time we have an inode with an attribute fork, we will crash deleting it? Thanks, Alex. [1] BUG: unable to handle kernel NULL pointer dereference at (null) IP: xfs_ifree+0x12c/0x150 [xfs] PGD 800000066eea0067 P4D 800000066eea0067 PUD 3066ce067 PMD 0 Oops: 0000 [#1] PREEMPT SMP PTI Modules linked in: binfmt_misc xt_nat xfs(OE) sd_mod sg bonding xt_CHECKSUM i libiscsi_tcp(OE) sunrpc libiscsi(OE) scsi_transport_iscsi(OE) i6300esb ip_ta CPU: 3 PID: 19176 Comm: swift-object-re Tainted: G W OE 4.14.99-zad Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 0 task: ffffa009b0d45640 task.stack: ffffb0a85dddc000 RIP: 0010:xfs_ifree+0x12c/0x150 [xfs] RSP: 0018:ffffb0a85dddfdb8 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffa00999610f00 RCX: 000000168215a803 RDX: 0000000000000000 RSI: ffffd0a83f9b3ed0 RDI: ffffa00999610f00 RBP: ffffa00edbe1af30 R08: 00003091b4833ed0 R09: ffffffffc0a39de4 R10: 0000000000000000 R11: 0000000000000040 R12: ffffb0a85dddfe10 R13: ffffb0a85dddfe08 R14: ffffa00d7f147780 R15: 0000000000000000 FS: 00007f012ffff700(0000) GS:ffffa0168b180000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000749f26006 CR4: 00000000003606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: xfs_inactive_ifree+0xbb/0x220 [xfs] xfs_inactive+0x74/0x100 [xfs] xfs_fs_destroy_inode+0xb4/0x240 [xfs] do_unlinkat+0x1b3/0x310 do_syscall_64+0x6e/0x120 entry_SYSCALL_64_after_hwframe+0x3d/0xa2 [2] static inline void xfs_ifree_local_data( struct xfs_inode *ip, int whichfork) { struct xfs_ifork *ifp; if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) return; ifp = XFS_IFORK_PTR(ip, whichfork); xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); } ^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork 2020-05-10 7:23 move the extent count and format into struct xfs_ifork Christoph Hellwig ` (2 preceding siblings ...) 2020-05-10 7:24 ` [PATCH 3/6] xfs: remove xfs_ifree_local_data Christoph Hellwig @ 2020-05-10 7:24 ` Christoph Hellwig 2020-05-12 5:26 ` Chandan Babu R 2020-05-12 16:10 ` Brian Foster 2020-05-10 7:24 ` [PATCH 5/6] xfs: move the fork format " Christoph Hellwig 2020-05-10 7:24 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig 5 siblings, 2 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-10 7:24 UTC (permalink / raw) To: linux-xfs There are thee number of extents counters, one for each of the forks, Two are in the legacy icdinode and one is directly in struct xfs_inode. Switch to a single counter in the xfs_ifork structure where it uses up padding at the end of the structure. This simplifies various bits of code that just wants the number of extents counter and can now directly dereference it. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/libxfs/xfs_attr.c | 4 +- fs/xfs/libxfs/xfs_attr_leaf.c | 1 - fs/xfs/libxfs/xfs_bmap.c | 126 ++++++++++++++------------------- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_inode_buf.c | 6 +- fs/xfs/libxfs/xfs_inode_buf.h | 2 - fs/xfs/libxfs/xfs_inode_fork.c | 12 ++-- fs/xfs/libxfs/xfs_inode_fork.h | 20 +++--- fs/xfs/scrub/bmap.c | 3 +- fs/xfs/scrub/parent.c | 2 +- fs/xfs/xfs_bmap_util.c | 28 ++++---- fs/xfs/xfs_file.c | 2 +- fs/xfs/xfs_icache.c | 1 - fs/xfs/xfs_inode.c | 19 +++-- fs/xfs/xfs_inode.h | 1 - fs/xfs/xfs_inode_item.c | 14 ++-- fs/xfs/xfs_ioctl.c | 25 +++---- fs/xfs/xfs_iomap.c | 2 +- fs/xfs/xfs_iops.c | 2 +- fs/xfs/xfs_itable.c | 4 +- fs/xfs/xfs_qm_syscalls.c | 2 +- fs/xfs/xfs_quotaops.c | 2 +- fs/xfs/xfs_symlink.c | 2 +- fs/xfs/xfs_trace.h | 2 +- 24 files changed, 122 insertions(+), 162 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index e4fe3dca9883b..1b01675e9c80b 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -62,7 +62,7 @@ xfs_inode_hasattr( { if (!XFS_IFORK_Q(ip) || (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && - ip->i_d.di_anextents == 0)) + ip->i_afp->if_nextents == 0)) return 0; return 1; } @@ -214,7 +214,7 @@ xfs_attr_set_args( */ if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL || (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && - dp->i_d.di_anextents == 0)) { + dp->i_afp->if_nextents == 0)) { /* * Build initial attribute list (if required). diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 863444e2dda7e..64b172180c42c 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -723,7 +723,6 @@ xfs_attr_fork_remove( ip->i_d.di_forkoff = 0; ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; - ASSERT(ip->i_d.di_anextents == 0); ASSERT(ip->i_afp == NULL); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 34518a6dc7376..c1136be49abeb 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -61,10 +61,10 @@ xfs_bmap_compute_maxlevels( int sz; /* root block size */ /* - * The maximum number of extents in a file, hence the maximum - * number of leaf entries, is controlled by the type of di_nextents - * (a signed 32-bit number, xfs_extnum_t), or by di_anextents - * (a signed 16-bit number, xfs_aextnum_t). + * The maximum number of extents in a file, hence the maximum number of + * leaf entries, is controlled by the size of the on-disk extent count, + * either a signed 32-bit number for the data fork, or a signed 16-bit + * number for the attr fork. * * Note that we can no longer assume that if we are in ATTR1 that * the fork offset of all the inodes will be @@ -120,10 +120,11 @@ xfs_bmbt_lookup_first( */ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) { + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + return whichfork != XFS_COW_FORK && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(ip, whichfork) > - XFS_IFORK_MAXEXT(ip, whichfork); + ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork); } /* @@ -131,10 +132,11 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) */ static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) { + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + return whichfork != XFS_COW_FORK && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && - XFS_IFORK_NEXTENTS(ip, whichfork) <= - XFS_IFORK_MAXEXT(ip, whichfork); + ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork); } /* @@ -334,7 +336,7 @@ xfs_bmap_check_leaf_extents( } /* skip large extent count inodes */ - if (ip->i_d.di_nextents > 10000) + if (ip->i_df.if_nextents > 10000) return; bno = NULLFSBLOCK; @@ -750,7 +752,7 @@ xfs_bmap_extents_to_btree( xfs_bmbt_disk_set_all(arp, &rec); cnt++; } - ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork)); + ASSERT(cnt == ifp->if_nextents); xfs_btree_set_numrecs(ablock, cnt); /* @@ -802,7 +804,7 @@ xfs_bmap_local_to_extents_empty( ASSERT(whichfork != XFS_COW_FORK); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); ASSERT(ifp->if_bytes == 0); - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); + ASSERT(ifp->if_nextents == 0); xfs_bmap_forkoff_reset(ip, whichfork); ifp->if_flags &= ~XFS_IFINLINE; @@ -907,7 +909,7 @@ xfs_bmap_local_to_extents( xfs_iext_first(ifp, &icur); xfs_iext_insert(ip, &icur, &rec, 0); - XFS_IFORK_NEXT_SET(ip, whichfork, 1); + ifp->if_nextents = 1; ip->i_d.di_nblocks = 1; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); @@ -972,7 +974,8 @@ xfs_bmap_add_attrfork_extents( xfs_btree_cur_t *cur; /* bmap btree cursor */ int error; /* error return value */ - if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) + if (ip->i_df.if_nextents * sizeof(struct xfs_bmbt_rec) <= + XFS_IFORK_DSIZE(ip)) return 0; cur = NULL; error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags, @@ -1091,10 +1094,6 @@ xfs_bmap_add_attrfork( goto trans_cancel; if (XFS_IFORK_Q(ip)) goto trans_cancel; - if (XFS_IS_CORRUPT(mp, ip->i_d.di_anextents != 0)) { - error = -EFSCORRUPTED; - goto trans_cancel; - } if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { /* * For inodes coming from pre-6.2 filesystems. @@ -1183,13 +1182,13 @@ xfs_iread_bmbt_block( xfs_extnum_t num_recs; xfs_extnum_t j; int whichfork = cur->bc_ino.whichfork; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); block = xfs_btree_get_block(cur, level, &bp); /* Abort if we find more records than nextents. */ num_recs = xfs_btree_get_numrecs(block); - if (unlikely(ir->loaded + num_recs > - XFS_IFORK_NEXTENTS(ip, whichfork))) { + if (unlikely(ir->loaded + num_recs > ifp->if_nextents)) { xfs_warn(ip->i_mount, "corrupt dinode %llu, (btree extents).", (unsigned long long)ip->i_ino); xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block, @@ -1215,7 +1214,7 @@ xfs_iread_bmbt_block( xfs_bmap_fork_to_state(whichfork)); trace_xfs_read_extent(ip, &ir->icur, xfs_bmap_fork_to_state(whichfork), _THIS_IP_); - xfs_iext_next(XFS_IFORK_PTR(ip, whichfork), &ir->icur); + xfs_iext_next(ifp, &ir->icur); } return 0; @@ -1254,8 +1253,7 @@ xfs_iread_extents( if (error) goto out; - if (XFS_IS_CORRUPT(mp, - ir.loaded != XFS_IFORK_NEXTENTS(ip, whichfork))) { + if (XFS_IS_CORRUPT(mp, ir.loaded != ifp->if_nextents)) { error = -EFSCORRUPTED; goto out; } @@ -1463,23 +1461,22 @@ xfs_bmap_last_offset( */ int /* 1=>1 block, 0=>otherwise */ xfs_bmap_one_block( - xfs_inode_t *ip, /* incore inode */ - int whichfork) /* data or attr fork */ + struct xfs_inode *ip, /* incore inode */ + int whichfork) /* data or attr fork */ { - struct xfs_ifork *ifp; /* inode fork pointer */ - int rval; /* return value */ - xfs_bmbt_irec_t s; /* internal version of extent */ + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + int rval; /* return value */ + struct xfs_bmbt_irec s; /* internal version of extent */ struct xfs_iext_cursor icur; #ifndef DEBUG if (whichfork == XFS_DATA_FORK) return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize; #endif /* !DEBUG */ - if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) + if (ifp->if_nextents != 1) return 0; if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) return 0; - ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(ifp->if_flags & XFS_IFEXTENTS); xfs_iext_first(ifp, &icur); xfs_iext_get_extent(ifp, &icur, &s); @@ -1501,10 +1498,11 @@ xfs_bmap_add_extent_delay_real( struct xfs_bmalloca *bma, int whichfork) { + struct xfs_mount *mp = bma->ip->i_mount; + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); struct xfs_bmbt_irec *new = &bma->got; int error; /* error return value */ int i; /* temp state */ - struct xfs_ifork *ifp; /* inode fork pointer */ xfs_fileoff_t new_endoff; /* end offset of new entry */ xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ /* left is 0, right is 1, prev is 2 */ @@ -1514,16 +1512,9 @@ xfs_bmap_add_extent_delay_real( xfs_filblks_t da_old; /* old count del alloc blocks used */ xfs_filblks_t temp=0; /* value for da_new calculations */ int tmp_rval; /* partial logging flags */ - struct xfs_mount *mp; - xfs_extnum_t *nextents; struct xfs_bmbt_irec old; - mp = bma->ip->i_mount; - ifp = XFS_IFORK_PTR(bma->ip, whichfork); ASSERT(whichfork != XFS_ATTR_FORK); - nextents = (whichfork == XFS_COW_FORK ? &bma->ip->i_cnextents : - &bma->ip->i_d.di_nextents); - ASSERT(!isnullstartblock(new->br_startblock)); ASSERT(!bma->cur || (bma->cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL)); @@ -1614,7 +1605,7 @@ xfs_bmap_add_extent_delay_real( xfs_iext_remove(bma->ip, &bma->icur, state); xfs_iext_prev(ifp, &bma->icur); xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); - (*nextents)--; + ifp->if_nextents--; if (bma->cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; @@ -1718,8 +1709,8 @@ xfs_bmap_add_extent_delay_real( PREV.br_startblock = new->br_startblock; PREV.br_state = new->br_state; xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); + ifp->if_nextents++; - (*nextents)++; if (bma->cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -1784,7 +1775,8 @@ xfs_bmap_add_extent_delay_real( * The left neighbor is not contiguous. */ xfs_iext_update_extent(bma->ip, state, &bma->icur, new); - (*nextents)++; + ifp->if_nextents++; + if (bma->cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -1870,7 +1862,8 @@ xfs_bmap_add_extent_delay_real( * The right neighbor is not contiguous. */ xfs_iext_update_extent(bma->ip, state, &bma->icur, new); - (*nextents)++; + ifp->if_nextents++; + if (bma->cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -1955,7 +1948,7 @@ xfs_bmap_add_extent_delay_real( xfs_iext_next(ifp, &bma->icur); xfs_iext_insert(bma->ip, &bma->icur, &RIGHT, state); xfs_iext_insert(bma->ip, &bma->icur, &LEFT, state); - (*nextents)++; + ifp->if_nextents++; if (bma->cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; @@ -2159,8 +2152,7 @@ xfs_bmap_add_extent_unwritten_real( xfs_iext_remove(ip, icur, state); xfs_iext_prev(ifp, icur); xfs_iext_update_extent(ip, state, icur, &LEFT); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 2); + ifp->if_nextents -= 2; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -2212,8 +2204,7 @@ xfs_bmap_add_extent_unwritten_real( xfs_iext_remove(ip, icur, state); xfs_iext_prev(ifp, icur); xfs_iext_update_extent(ip, state, icur, &LEFT); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); + ifp->if_nextents--; if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -2255,9 +2246,8 @@ xfs_bmap_add_extent_unwritten_real( xfs_iext_remove(ip, icur, state); xfs_iext_prev(ifp, icur); xfs_iext_update_extent(ip, state, icur, &PREV); + ifp->if_nextents--; - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -2364,8 +2354,8 @@ xfs_bmap_add_extent_unwritten_real( xfs_iext_update_extent(ip, state, icur, &PREV); xfs_iext_insert(ip, icur, new, state); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); + ifp->if_nextents++; + if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -2440,9 +2430,8 @@ xfs_bmap_add_extent_unwritten_real( xfs_iext_update_extent(ip, state, icur, &PREV); xfs_iext_next(ifp, icur); xfs_iext_insert(ip, icur, new, state); + ifp->if_nextents++; - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -2493,9 +2482,8 @@ xfs_bmap_add_extent_unwritten_real( xfs_iext_next(ifp, icur); xfs_iext_insert(ip, icur, &r[1], state); xfs_iext_insert(ip, icur, &r[0], state); + ifp->if_nextents += 2; - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 2); if (cur == NULL) rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; else { @@ -2810,9 +2798,8 @@ xfs_bmap_add_extent_hole_real( xfs_iext_remove(ip, icur, state); xfs_iext_prev(ifp, icur); xfs_iext_update_extent(ip, state, icur, &left); + ifp->if_nextents--; - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); if (cur == NULL) { rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else { @@ -2910,8 +2897,8 @@ xfs_bmap_add_extent_hole_real( * Insert a new entry. */ xfs_iext_insert(ip, icur, new, state); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); + ifp->if_nextents++; + if (cur == NULL) { rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else { @@ -4512,8 +4499,7 @@ xfs_bmapi_write( goto error0; ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || - XFS_IFORK_NEXTENTS(ip, whichfork) > - XFS_IFORK_MAXEXT(ip, whichfork)); + ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork)); xfs_bmapi_finish(&bma, whichfork, 0); xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, orig_nmap, *nmap); @@ -5056,8 +5042,7 @@ xfs_bmap_del_extent_real( */ if (tp->t_blk_res == 0 && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(ip, whichfork) >= - XFS_IFORK_MAXEXT(ip, whichfork) && + ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) && del->br_startoff > got.br_startoff && del_endoff < got_endoff) return -ENOSPC; @@ -5109,8 +5094,8 @@ xfs_bmap_del_extent_real( */ xfs_iext_remove(ip, icur, state); xfs_iext_prev(ifp, icur); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); + ifp->if_nextents--; + flags |= XFS_ILOG_CORE; if (!cur) { flags |= xfs_ilog_fext(whichfork); @@ -5218,8 +5203,8 @@ xfs_bmap_del_extent_real( } } else flags |= xfs_ilog_fext(whichfork); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); + + ifp->if_nextents++; xfs_iext_next(ifp, icur); xfs_iext_insert(ip, icur, &new, state); break; @@ -5667,6 +5652,7 @@ xfs_bmse_merge( struct xfs_btree_cur *cur, int *logflags) /* output */ { + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_bmbt_irec new; xfs_filblks_t blockcount; int error, i; @@ -5685,8 +5671,7 @@ xfs_bmse_merge( * Update the on-disk extent count, the btree if necessary and log the * inode. */ - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); + ifp->if_nextents--; *logflags |= XFS_ILOG_CORE; if (!cur) { *logflags |= XFS_ILOG_DEXT; @@ -5724,7 +5709,7 @@ xfs_bmse_merge( done: xfs_iext_remove(ip, icur, 0); - xfs_iext_prev(XFS_IFORK_PTR(ip, whichfork), icur); + xfs_iext_prev(ifp, icur); xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur, &new); @@ -6074,8 +6059,7 @@ xfs_bmap_split_extent( /* Add new extent */ xfs_iext_next(ifp, &icur); xfs_iext_insert(ip, &icur, &new, 0); - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); + ifp->if_nextents++; if (cur) { error = xfs_bmbt_lookup_eq(cur, &new, &i); diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 1dbf2f980a26a..5b59d3f7746b3 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1104,7 +1104,7 @@ xfs_dir2_sf_to_block( ASSERT(ifp->if_bytes == dp->i_d.di_size); ASSERT(ifp->if_u1.if_data != NULL); ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count)); - ASSERT(dp->i_d.di_nextents == 0); + ASSERT(dp->i_df.if_nextents == 0); /* * Copy the directory into a temporary buffer. diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 5547bbb3cf945..a374e2a81e764 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -245,8 +245,6 @@ xfs_inode_from_disk( to->di_size = be64_to_cpu(from->di_size); to->di_nblocks = be64_to_cpu(from->di_nblocks); to->di_extsize = be32_to_cpu(from->di_extsize); - to->di_nextents = be32_to_cpu(from->di_nextents); - to->di_anextents = be16_to_cpu(from->di_anextents); to->di_forkoff = from->di_forkoff; to->di_aformat = from->di_aformat; to->di_dmevmask = be32_to_cpu(from->di_dmevmask); @@ -311,8 +309,8 @@ xfs_inode_to_disk( to->di_size = cpu_to_be64(from->di_size); to->di_nblocks = cpu_to_be64(from->di_nblocks); to->di_extsize = cpu_to_be32(from->di_extsize); - to->di_nextents = cpu_to_be32(from->di_nextents); - to->di_anextents = cpu_to_be16(from->di_anextents); + to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df)); + to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp)); to->di_forkoff = from->di_forkoff; to->di_aformat = from->di_aformat; to->di_dmevmask = cpu_to_be32(from->di_dmevmask); diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index e4cbcaf62a32b..fecccfb26463c 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -22,8 +22,6 @@ struct xfs_icdinode { xfs_fsize_t di_size; /* number of bytes in file */ xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ - xfs_extnum_t di_nextents; /* number of extents in data fork */ - xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ int8_t di_aformat; /* format of attr fork's data */ uint32_t di_dmevmask; /* DMIG event mask */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 2fe325e38fd88..195da3552c5b5 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -188,12 +188,11 @@ xfs_iformat_btree( * or the number of extents is greater than the number of * blocks. */ - if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= - XFS_IFORK_MAXEXT(ip, whichfork) || + if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) || nrecs == 0 || XFS_BMDR_SPACE_CALC(nrecs) > XFS_DFORK_SIZE(dip, mp, whichfork) || - XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) || + ifp->if_nextents > ip->i_d.di_nblocks) || level == 0 || level > XFS_BTREE_MAXLEVELS) { xfs_warn(mp, "corrupt inode %Lu (btree).", (unsigned long long) ip->i_ino); @@ -229,6 +228,8 @@ xfs_iformat_data_fork( struct inode *inode = VFS_I(ip); int error; + ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); + switch (inode->i_mode & S_IFMT) { case S_IFIFO: case S_IFCHR: @@ -282,6 +283,8 @@ xfs_iformat_attr_fork( int error = 0; ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); + ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); + switch (dip->di_aformat) { case XFS_DINODE_FMT_LOCAL: error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, @@ -617,7 +620,7 @@ xfs_iflush_fork( !(iip->ili_fields & extflag[whichfork])); if ((iip->ili_fields & extflag[whichfork]) && (ifp->if_bytes > 0)) { - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); + ASSERT(ifp->if_nextents > 0); (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, whichfork); } @@ -676,7 +679,6 @@ xfs_ifork_init_cow( KM_NOFS); ip->i_cowfp->if_flags = XFS_IFEXTENTS; ip->i_cformat = XFS_DINODE_FMT_EXTENTS; - ip->i_cnextents = 0; } /* Verify the inline contents of the data fork of an inode. */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index f46a8c1db5964..a69d425fe68df 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -23,6 +23,7 @@ struct xfs_ifork { } if_u1; short if_broot_bytes; /* bytes allocated for root */ unsigned char if_flags; /* per-fork flags */ + xfs_extnum_t if_nextents; /* # of extents in this fork */ }; /* @@ -67,18 +68,6 @@ struct xfs_ifork { ((w) == XFS_ATTR_FORK ? \ ((ip)->i_d.di_aformat = (n)) : \ ((ip)->i_cformat = (n)))) -#define XFS_IFORK_NEXTENTS(ip,w) \ - ((w) == XFS_DATA_FORK ? \ - (ip)->i_d.di_nextents : \ - ((w) == XFS_ATTR_FORK ? \ - (ip)->i_d.di_anextents : \ - (ip)->i_cnextents)) -#define XFS_IFORK_NEXT_SET(ip,w,n) \ - ((w) == XFS_DATA_FORK ? \ - ((ip)->i_d.di_nextents = (n)) : \ - ((w) == XFS_ATTR_FORK ? \ - ((ip)->i_d.di_anextents = (n)) : \ - ((ip)->i_cnextents = (n)))) #define XFS_IFORK_MAXEXT(ip, w) \ (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) @@ -86,6 +75,13 @@ struct xfs_ifork { (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) +static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) +{ + if (!ifp) + return 0; + return ifp->if_nextents; +} + struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 283424d6d2bb6..157f72efec5e9 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -566,6 +566,7 @@ xchk_bmap_check_rmaps( struct xfs_scrub *sc, int whichfork) { + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, whichfork); loff_t size; xfs_agnumber_t agno; int error; @@ -598,7 +599,7 @@ xchk_bmap_check_rmaps( break; } if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && - (size == 0 || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) + (size == 0 || ifp->if_nextents > 0)) return 0; for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c index 5705adc43a75f..855aa8bcab64b 100644 --- a/fs/xfs/scrub/parent.c +++ b/fs/xfs/scrub/parent.c @@ -90,7 +90,7 @@ xchk_parent_count_parent_dentries( * if there is one. */ lock_mode = xfs_ilock_data_map_shared(parent); - if (parent->i_d.di_nextents > 0) + if (parent->i_df.if_nextents > 0) error = xfs_dir3_data_readahead(parent, 0, 0); xfs_iunlock(parent, lock_mode); if (error) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index cc23a3e23e2d1..4f277a6253b8d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1220,7 +1220,7 @@ xfs_swap_extents_check_format( * if the target inode has less extents that then temporary inode then * why did userspace call us? */ - if (ip->i_d.di_nextents < tip->i_d.di_nextents) + if (ip->i_df.if_nextents < tip->i_df.if_nextents) return -EINVAL; /* @@ -1241,14 +1241,12 @@ xfs_swap_extents_check_format( /* Check temp in extent form to max in target */ if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) > - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) + tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) return -EINVAL; /* Check target in extent form to max in temp */ if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) return -EINVAL; /* @@ -1264,7 +1262,7 @@ xfs_swap_extents_check_format( if (XFS_IFORK_Q(ip) && XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) return -EINVAL; - if (XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= + if (tip->i_df.if_nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) return -EINVAL; } @@ -1274,7 +1272,7 @@ xfs_swap_extents_check_format( if (XFS_IFORK_Q(tip) && XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) return -EINVAL; - if (XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= + if (ip->i_df.if_nextents <= XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) return -EINVAL; } @@ -1427,15 +1425,15 @@ xfs_swap_extent_forks( /* * Count the number of extended attribute blocks */ - if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && - (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { + if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && + ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, &aforkblks); if (error) return error; } - if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && - (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { + if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && + tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, &taforkblks); if (error) @@ -1468,7 +1466,6 @@ xfs_swap_extent_forks( ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; - swap(ip->i_d.di_nextents, tip->i_d.di_nextents); swap(ip->i_d.di_format, tip->i_d.di_format); /* @@ -1615,9 +1612,9 @@ xfs_swap_extents( * performed with log redo items! */ if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { - int w = XFS_DATA_FORK; - uint32_t ipnext = XFS_IFORK_NEXTENTS(ip, w); - uint32_t tipnext = XFS_IFORK_NEXTENTS(tip, w); + int w = XFS_DATA_FORK; + uint32_t ipnext = ip->i_df.if_nextents; + uint32_t tipnext = tip->i_df.if_nextents; /* * Conceptually this shouldn't affect the shape of either bmbt, @@ -1720,7 +1717,6 @@ xfs_swap_extents( ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); - swap(ip->i_cnextents, tip->i_cnextents); swap(ip->i_cowfp, tip->i_cowfp); if (ip->i_cowfp && ip->i_cowfp->if_bytes) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 4b8bdecc38635..403c90309a8ff 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1102,7 +1102,7 @@ xfs_dir_open( * certain to have the next operation be a read there. */ mode = xfs_ilock_data_map_shared(ip); - if (ip->i_d.di_nextents > 0) + if (ip->i_df.if_nextents > 0) error = xfs_dir3_data_readahead(ip, 0, 0); xfs_iunlock(ip, mode); return error; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 5a3a520b95288..791d5d5e318cf 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -63,7 +63,6 @@ xfs_inode_alloc( memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); ip->i_afp = NULL; ip->i_cowfp = NULL; - ip->i_cnextents = 0; ip->i_cformat = XFS_DINODE_FMT_EXTENTS; memset(&ip->i_df, 0, sizeof(ip->i_df)); ip->i_flags = 0; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7d3144dc99b72..1677c4e7207ed 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -825,7 +825,7 @@ xfs_ialloc( inode->i_mode &= ~S_ISGID; ip->i_d.di_size = 0; - ip->i_d.di_nextents = 0; + ip->i_df.if_nextents = 0; ASSERT(ip->i_d.di_nblocks == 0); tv = current_time(inode); @@ -919,7 +919,6 @@ xfs_ialloc( * Attribute fork settings for new inode. */ ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; - ip->i_d.di_anextents = 0; /* * Log the new values stuffed into the inode. @@ -1686,7 +1685,7 @@ xfs_inactive_truncate( if (error) goto error_trans_cancel; - ASSERT(ip->i_d.di_nextents == 0); + ASSERT(ip->i_df.if_nextents == 0); error = xfs_trans_commit(tp); if (error) @@ -1836,7 +1835,7 @@ xfs_inactive( if (S_ISREG(VFS_I(ip)->i_mode) && (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || - ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) + ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) truncate = 1; error = xfs_qm_dqattach(ip); @@ -1862,7 +1861,6 @@ xfs_inactive( } ASSERT(!ip->i_afp); - ASSERT(ip->i_d.di_anextents == 0); ASSERT(ip->i_d.di_forkoff == 0); /* @@ -2731,8 +2729,7 @@ xfs_ifree( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(VFS_I(ip)->i_nlink == 0); - ASSERT(ip->i_d.di_nextents == 0); - ASSERT(ip->i_d.di_anextents == 0); + ASSERT(ip->i_df.if_nextents == 0); ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode)); ASSERT(ip->i_d.di_nblocks == 0); @@ -3628,7 +3625,7 @@ xfs_iflush( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(xfs_isiflocked(ip)); ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); *bpp = NULL; @@ -3710,7 +3707,7 @@ xfs_iflush_int( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(xfs_isiflocked(ip)); ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); ASSERT(iip != NULL && iip->ili_fields != 0); dip = xfs_buf_offset(bp, ip->i_imap.im_boffset); @@ -3751,13 +3748,13 @@ xfs_iflush_int( goto flush_out; } } - if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents > + if (XFS_TEST_ERROR(ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp) > ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, "%s: detected corrupt incore inode %Lu, " "total extents = %d, nblocks = %Ld, ptr "PTR_FMT, __func__, ip->i_ino, - ip->i_d.di_nextents + ip->i_d.di_anextents, + ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp), ip->i_d.di_nblocks, ip); goto flush_out; } diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ff846197941e4..24dae63ba16c0 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -57,7 +57,6 @@ typedef struct xfs_inode { struct xfs_icdinode i_d; /* most of ondisk inode */ - xfs_extnum_t i_cnextents; /* # of extents in cow fork */ unsigned int i_cformat; /* format of cow fork */ /* VFS inode */ diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index cefa2484f0dbf..401ba26aeed7b 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -39,7 +39,7 @@ xfs_inode_item_data_fork_size( switch (ip->i_d.di_format) { case XFS_DINODE_FMT_EXTENTS: if ((iip->ili_fields & XFS_ILOG_DEXT) && - ip->i_d.di_nextents > 0 && + ip->i_df.if_nextents > 0 && ip->i_df.if_bytes > 0) { /* worst case, doesn't subtract delalloc extents */ *nbytes += XFS_IFORK_DSIZE(ip); @@ -80,7 +80,7 @@ xfs_inode_item_attr_fork_size( switch (ip->i_d.di_aformat) { case XFS_DINODE_FMT_EXTENTS: if ((iip->ili_fields & XFS_ILOG_AEXT) && - ip->i_d.di_anextents > 0 && + ip->i_afp->if_nextents > 0 && ip->i_afp->if_bytes > 0) { /* worst case, doesn't subtract unused space */ *nbytes += XFS_IFORK_ASIZE(ip); @@ -148,7 +148,7 @@ xfs_inode_item_format_data_fork( ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); if ((iip->ili_fields & XFS_ILOG_DEXT) && - ip->i_d.di_nextents > 0 && + ip->i_df.if_nextents > 0 && ip->i_df.if_bytes > 0) { struct xfs_bmbt_rec *p; @@ -233,12 +233,12 @@ xfs_inode_item_format_attr_fork( ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); if ((iip->ili_fields & XFS_ILOG_AEXT) && - ip->i_d.di_anextents > 0 && + ip->i_afp->if_nextents > 0 && ip->i_afp->if_bytes > 0) { struct xfs_bmbt_rec *p; ASSERT(xfs_iext_count(ip->i_afp) == - ip->i_d.di_anextents); + ip->i_afp->if_nextents); p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT); data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK); @@ -326,8 +326,8 @@ xfs_inode_to_log_dinode( to->di_size = from->di_size; to->di_nblocks = from->di_nblocks; to->di_extsize = from->di_extsize; - to->di_nextents = from->di_nextents; - to->di_anextents = from->di_anextents; + to->di_nextents = xfs_ifork_nextents(&ip->i_df); + to->di_anextents = xfs_ifork_nextents(ip->i_afp); to->di_forkoff = from->di_forkoff; to->di_aformat = from->di_aformat; to->di_dmevmask = from->di_dmevmask; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 4ee0d13232f3f..7a71c03e9022b 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1104,26 +1104,17 @@ xfs_fill_fsxattr( bool attr, struct fsxattr *fa) { + struct xfs_ifork *ifp = attr ? ip->i_afp : &ip->i_df; + simple_fill_fsxattr(fa, xfs_ip2xflags(ip)); fa->fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; fa->fsx_cowextsize = ip->i_d.di_cowextsize << ip->i_mount->m_sb.sb_blocklog; fa->fsx_projid = ip->i_d.di_projid; - - if (attr) { - if (ip->i_afp) { - if (ip->i_afp->if_flags & XFS_IFEXTENTS) - fa->fsx_nextents = xfs_iext_count(ip->i_afp); - else - fa->fsx_nextents = ip->i_d.di_anextents; - } else - fa->fsx_nextents = 0; - } else { - if (ip->i_df.if_flags & XFS_IFEXTENTS) - fa->fsx_nextents = xfs_iext_count(&ip->i_df); - else - fa->fsx_nextents = ip->i_d.di_nextents; - } + if (ifp && (ifp->if_flags & XFS_IFEXTENTS)) + fa->fsx_nextents = xfs_iext_count(ifp); + else + fa->fsx_nextents = xfs_ifork_nextents(ifp); } STATIC int @@ -1211,7 +1202,7 @@ xfs_ioctl_setattr_xflags( uint64_t di_flags2; /* Can't change realtime flag if any extents are allocated. */ - if ((ip->i_d.di_nextents || ip->i_delayed_blks) && + if ((ip->i_df.if_nextents || ip->i_delayed_blks) && XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME)) return -EINVAL; @@ -1389,7 +1380,7 @@ xfs_ioctl_setattr_check_extsize( xfs_extlen_t size; xfs_fsblock_t extsize_fsb; - if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents && + if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents && ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) return -EINVAL; diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index bb590a267a7f9..b4fd918749e5f 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -1258,7 +1258,7 @@ xfs_xattr_iomap_begin( lockmode = xfs_ilock_attr_map_shared(ip); /* if there are no attribute fork or extents, return ENOENT */ - if (!XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { + if (!XFS_IFORK_Q(ip) || !ip->i_afp->if_nextents) { error = -ENOENT; goto out_unlock; } diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 26a71237d70f6..d66528fa36570 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -872,7 +872,7 @@ xfs_setattr_size( /* * Short circuit the truncate case for zero length files. */ - if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { + if (newsize == 0 && oldsize == 0 && ip->i_df.if_nextents == 0) { if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME))) return 0; diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index ff2da28fed90e..80da86c5703fb 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -104,9 +104,9 @@ xfs_bulkstat_one_int( buf->bs_xflags = xfs_ip2xflags(ip); buf->bs_extsize_blks = dic->di_extsize; - buf->bs_extents = dic->di_nextents; + buf->bs_extents = xfs_ifork_nextents(&ip->i_df); xfs_bulkstat_health(ip, buf); - buf->bs_aextents = dic->di_anextents; + buf->bs_aextents = xfs_ifork_nextents(ip->i_afp); buf->bs_forkoff = XFS_IFORK_BOFF(ip); buf->bs_version = XFS_BULKSTAT_VERSION_V5; diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 944486f2b2874..9edf761eec739 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -302,7 +302,7 @@ xfs_qm_scall_trunc_qfile( goto out_unlock; } - ASSERT(ip->i_d.di_nextents == 0); + ASSERT(ip->i_df.if_nextents == 0); xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); error = xfs_trans_commit(tp); diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 38669e8272060..b5d10ecb54743 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -36,7 +36,7 @@ xfs_qm_fill_state( } tstate->flags |= QCI_SYSFILE; tstate->blocks = ip->i_d.di_nblocks; - tstate->nextents = ip->i_d.di_nextents; + tstate->nextents = ip->i_df.if_nextents; tstate->spc_timelimit = (u32)q->qi_btimelimit; tstate->ino_timelimit = (u32)q->qi_itimelimit; tstate->rt_spc_timelimit = (u32)q->qi_rtbtimelimit; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 973441992b084..8cf2fcb509c12 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -384,7 +384,7 @@ xfs_inactive_symlink_rmt( * either 1 or 2 extents and that we can * free them all in one bunmapi call. */ - ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); + ASSERT(ip->i_df.if_nextents > 0 && ip->i_df.if_nextents <= 2); error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); if (error) diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index a4323a63438d8..ba2ab69e1fc7d 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1898,7 +1898,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, __entry->which = which; __entry->ino = ip->i_ino; __entry->format = ip->i_d.di_format; - __entry->nex = ip->i_d.di_nextents; + __entry->nex = ip->i_df.if_nextents; __entry->broot_size = ip->i_df.if_broot_bytes; __entry->fork_off = XFS_IFORK_BOFF(ip); ), -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork 2020-05-10 7:24 ` [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork Christoph Hellwig @ 2020-05-12 5:26 ` Chandan Babu R 2020-05-12 16:10 ` Brian Foster 1 sibling, 0 replies; 41+ messages in thread From: Chandan Babu R @ 2020-05-12 5:26 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sunday 10 May 2020 12:54:02 PM IST Christoph Hellwig wrote: > There are thee number of extents counters, one for each of the forks, ... three number of .... The patch itself looks good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Two are in the legacy icdinode and one is directly in struct xfs_inode. > Switch to a single counter in the xfs_ifork structure where it uses up > padding at the end of the structure. This simplifies various bits of > code that just wants the number of extents counter and can now directly > dereference it. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/libxfs/xfs_attr.c | 4 +- > fs/xfs/libxfs/xfs_attr_leaf.c | 1 - > fs/xfs/libxfs/xfs_bmap.c | 126 ++++++++++++++------------------- > fs/xfs/libxfs/xfs_dir2_block.c | 2 +- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +- > fs/xfs/libxfs/xfs_inode_buf.h | 2 - > fs/xfs/libxfs/xfs_inode_fork.c | 12 ++-- > fs/xfs/libxfs/xfs_inode_fork.h | 20 +++--- > fs/xfs/scrub/bmap.c | 3 +- > fs/xfs/scrub/parent.c | 2 +- > fs/xfs/xfs_bmap_util.c | 28 ++++---- > fs/xfs/xfs_file.c | 2 +- > fs/xfs/xfs_icache.c | 1 - > fs/xfs/xfs_inode.c | 19 +++-- > fs/xfs/xfs_inode.h | 1 - > fs/xfs/xfs_inode_item.c | 14 ++-- > fs/xfs/xfs_ioctl.c | 25 +++---- > fs/xfs/xfs_iomap.c | 2 +- > fs/xfs/xfs_iops.c | 2 +- > fs/xfs/xfs_itable.c | 4 +- > fs/xfs/xfs_qm_syscalls.c | 2 +- > fs/xfs/xfs_quotaops.c | 2 +- > fs/xfs/xfs_symlink.c | 2 +- > fs/xfs/xfs_trace.h | 2 +- > 24 files changed, 122 insertions(+), 162 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c > index e4fe3dca9883b..1b01675e9c80b 100644 > --- a/fs/xfs/libxfs/xfs_attr.c > +++ b/fs/xfs/libxfs/xfs_attr.c > @@ -62,7 +62,7 @@ xfs_inode_hasattr( > { > if (!XFS_IFORK_Q(ip) || > (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > - ip->i_d.di_anextents == 0)) > + ip->i_afp->if_nextents == 0)) > return 0; > return 1; > } > @@ -214,7 +214,7 @@ xfs_attr_set_args( > */ > if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL || > (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > - dp->i_d.di_anextents == 0)) { > + dp->i_afp->if_nextents == 0)) { > > /* > * Build initial attribute list (if required). > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index 863444e2dda7e..64b172180c42c 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -723,7 +723,6 @@ xfs_attr_fork_remove( > ip->i_d.di_forkoff = 0; > ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > - ASSERT(ip->i_d.di_anextents == 0); > ASSERT(ip->i_afp == NULL); > > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index 34518a6dc7376..c1136be49abeb 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -61,10 +61,10 @@ xfs_bmap_compute_maxlevels( > int sz; /* root block size */ > > /* > - * The maximum number of extents in a file, hence the maximum > - * number of leaf entries, is controlled by the type of di_nextents > - * (a signed 32-bit number, xfs_extnum_t), or by di_anextents > - * (a signed 16-bit number, xfs_aextnum_t). > + * The maximum number of extents in a file, hence the maximum number of > + * leaf entries, is controlled by the size of the on-disk extent count, > + * either a signed 32-bit number for the data fork, or a signed 16-bit > + * number for the attr fork. > * > * Note that we can no longer assume that if we are in ATTR1 that > * the fork offset of all the inodes will be > @@ -120,10 +120,11 @@ xfs_bmbt_lookup_first( > */ > static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > + > return whichfork != XFS_COW_FORK && > XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > - XFS_IFORK_NEXTENTS(ip, whichfork) > > - XFS_IFORK_MAXEXT(ip, whichfork); > + ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork); > } > > /* > @@ -131,10 +132,11 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) > */ > static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > + > return whichfork != XFS_COW_FORK && > XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && > - XFS_IFORK_NEXTENTS(ip, whichfork) <= > - XFS_IFORK_MAXEXT(ip, whichfork); > + ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork); > } > > /* > @@ -334,7 +336,7 @@ xfs_bmap_check_leaf_extents( > } > > /* skip large extent count inodes */ > - if (ip->i_d.di_nextents > 10000) > + if (ip->i_df.if_nextents > 10000) > return; > > bno = NULLFSBLOCK; > @@ -750,7 +752,7 @@ xfs_bmap_extents_to_btree( > xfs_bmbt_disk_set_all(arp, &rec); > cnt++; > } > - ASSERT(cnt == XFS_IFORK_NEXTENTS(ip, whichfork)); > + ASSERT(cnt == ifp->if_nextents); > xfs_btree_set_numrecs(ablock, cnt); > > /* > @@ -802,7 +804,7 @@ xfs_bmap_local_to_extents_empty( > ASSERT(whichfork != XFS_COW_FORK); > ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > ASSERT(ifp->if_bytes == 0); > - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); > + ASSERT(ifp->if_nextents == 0); > > xfs_bmap_forkoff_reset(ip, whichfork); > ifp->if_flags &= ~XFS_IFINLINE; > @@ -907,7 +909,7 @@ xfs_bmap_local_to_extents( > xfs_iext_first(ifp, &icur); > xfs_iext_insert(ip, &icur, &rec, 0); > > - XFS_IFORK_NEXT_SET(ip, whichfork, 1); > + ifp->if_nextents = 1; > ip->i_d.di_nblocks = 1; > xfs_trans_mod_dquot_byino(tp, ip, > XFS_TRANS_DQ_BCOUNT, 1L); > @@ -972,7 +974,8 @@ xfs_bmap_add_attrfork_extents( > xfs_btree_cur_t *cur; /* bmap btree cursor */ > int error; /* error return value */ > > - if (ip->i_d.di_nextents * sizeof(xfs_bmbt_rec_t) <= XFS_IFORK_DSIZE(ip)) > + if (ip->i_df.if_nextents * sizeof(struct xfs_bmbt_rec) <= > + XFS_IFORK_DSIZE(ip)) > return 0; > cur = NULL; > error = xfs_bmap_extents_to_btree(tp, ip, &cur, 0, flags, > @@ -1091,10 +1094,6 @@ xfs_bmap_add_attrfork( > goto trans_cancel; > if (XFS_IFORK_Q(ip)) > goto trans_cancel; > - if (XFS_IS_CORRUPT(mp, ip->i_d.di_anextents != 0)) { > - error = -EFSCORRUPTED; > - goto trans_cancel; > - } > if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { > /* > * For inodes coming from pre-6.2 filesystems. > @@ -1183,13 +1182,13 @@ xfs_iread_bmbt_block( > xfs_extnum_t num_recs; > xfs_extnum_t j; > int whichfork = cur->bc_ino.whichfork; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > block = xfs_btree_get_block(cur, level, &bp); > > /* Abort if we find more records than nextents. */ > num_recs = xfs_btree_get_numrecs(block); > - if (unlikely(ir->loaded + num_recs > > - XFS_IFORK_NEXTENTS(ip, whichfork))) { > + if (unlikely(ir->loaded + num_recs > ifp->if_nextents)) { > xfs_warn(ip->i_mount, "corrupt dinode %llu, (btree extents).", > (unsigned long long)ip->i_ino); > xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block, > @@ -1215,7 +1214,7 @@ xfs_iread_bmbt_block( > xfs_bmap_fork_to_state(whichfork)); > trace_xfs_read_extent(ip, &ir->icur, > xfs_bmap_fork_to_state(whichfork), _THIS_IP_); > - xfs_iext_next(XFS_IFORK_PTR(ip, whichfork), &ir->icur); > + xfs_iext_next(ifp, &ir->icur); > } > > return 0; > @@ -1254,8 +1253,7 @@ xfs_iread_extents( > if (error) > goto out; > > - if (XFS_IS_CORRUPT(mp, > - ir.loaded != XFS_IFORK_NEXTENTS(ip, whichfork))) { > + if (XFS_IS_CORRUPT(mp, ir.loaded != ifp->if_nextents)) { > error = -EFSCORRUPTED; > goto out; > } > @@ -1463,23 +1461,22 @@ xfs_bmap_last_offset( > */ > int /* 1=>1 block, 0=>otherwise */ > xfs_bmap_one_block( > - xfs_inode_t *ip, /* incore inode */ > - int whichfork) /* data or attr fork */ > + struct xfs_inode *ip, /* incore inode */ > + int whichfork) /* data or attr fork */ > { > - struct xfs_ifork *ifp; /* inode fork pointer */ > - int rval; /* return value */ > - xfs_bmbt_irec_t s; /* internal version of extent */ > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > + int rval; /* return value */ > + struct xfs_bmbt_irec s; /* internal version of extent */ > struct xfs_iext_cursor icur; > > #ifndef DEBUG > if (whichfork == XFS_DATA_FORK) > return XFS_ISIZE(ip) == ip->i_mount->m_sb.sb_blocksize; > #endif /* !DEBUG */ > - if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1) > + if (ifp->if_nextents != 1) > return 0; > if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > return 0; > - ifp = XFS_IFORK_PTR(ip, whichfork); > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > xfs_iext_first(ifp, &icur); > xfs_iext_get_extent(ifp, &icur, &s); > @@ -1501,10 +1498,11 @@ xfs_bmap_add_extent_delay_real( > struct xfs_bmalloca *bma, > int whichfork) > { > + struct xfs_mount *mp = bma->ip->i_mount; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); > struct xfs_bmbt_irec *new = &bma->got; > int error; /* error return value */ > int i; /* temp state */ > - struct xfs_ifork *ifp; /* inode fork pointer */ > xfs_fileoff_t new_endoff; /* end offset of new entry */ > xfs_bmbt_irec_t r[3]; /* neighbor extent entries */ > /* left is 0, right is 1, prev is 2 */ > @@ -1514,16 +1512,9 @@ xfs_bmap_add_extent_delay_real( > xfs_filblks_t da_old; /* old count del alloc blocks used */ > xfs_filblks_t temp=0; /* value for da_new calculations */ > int tmp_rval; /* partial logging flags */ > - struct xfs_mount *mp; > - xfs_extnum_t *nextents; > struct xfs_bmbt_irec old; > > - mp = bma->ip->i_mount; > - ifp = XFS_IFORK_PTR(bma->ip, whichfork); > ASSERT(whichfork != XFS_ATTR_FORK); > - nextents = (whichfork == XFS_COW_FORK ? &bma->ip->i_cnextents : > - &bma->ip->i_d.di_nextents); > - > ASSERT(!isnullstartblock(new->br_startblock)); > ASSERT(!bma->cur || > (bma->cur->bc_ino.flags & XFS_BTCUR_BMBT_WASDEL)); > @@ -1614,7 +1605,7 @@ xfs_bmap_add_extent_delay_real( > xfs_iext_remove(bma->ip, &bma->icur, state); > xfs_iext_prev(ifp, &bma->icur); > xfs_iext_update_extent(bma->ip, state, &bma->icur, &LEFT); > - (*nextents)--; > + ifp->if_nextents--; > > if (bma->cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > @@ -1718,8 +1709,8 @@ xfs_bmap_add_extent_delay_real( > PREV.br_startblock = new->br_startblock; > PREV.br_state = new->br_state; > xfs_iext_update_extent(bma->ip, state, &bma->icur, &PREV); > + ifp->if_nextents++; > > - (*nextents)++; > if (bma->cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -1784,7 +1775,8 @@ xfs_bmap_add_extent_delay_real( > * The left neighbor is not contiguous. > */ > xfs_iext_update_extent(bma->ip, state, &bma->icur, new); > - (*nextents)++; > + ifp->if_nextents++; > + > if (bma->cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -1870,7 +1862,8 @@ xfs_bmap_add_extent_delay_real( > * The right neighbor is not contiguous. > */ > xfs_iext_update_extent(bma->ip, state, &bma->icur, new); > - (*nextents)++; > + ifp->if_nextents++; > + > if (bma->cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -1955,7 +1948,7 @@ xfs_bmap_add_extent_delay_real( > xfs_iext_next(ifp, &bma->icur); > xfs_iext_insert(bma->ip, &bma->icur, &RIGHT, state); > xfs_iext_insert(bma->ip, &bma->icur, &LEFT, state); > - (*nextents)++; > + ifp->if_nextents++; > > if (bma->cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > @@ -2159,8 +2152,7 @@ xfs_bmap_add_extent_unwritten_real( > xfs_iext_remove(ip, icur, state); > xfs_iext_prev(ifp, icur); > xfs_iext_update_extent(ip, state, icur, &LEFT); > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) - 2); > + ifp->if_nextents -= 2; > if (cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -2212,8 +2204,7 @@ xfs_bmap_add_extent_unwritten_real( > xfs_iext_remove(ip, icur, state); > xfs_iext_prev(ifp, icur); > xfs_iext_update_extent(ip, state, icur, &LEFT); > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > + ifp->if_nextents--; > if (cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -2255,9 +2246,8 @@ xfs_bmap_add_extent_unwritten_real( > xfs_iext_remove(ip, icur, state); > xfs_iext_prev(ifp, icur); > xfs_iext_update_extent(ip, state, icur, &PREV); > + ifp->if_nextents--; > > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > if (cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -2364,8 +2354,8 @@ xfs_bmap_add_extent_unwritten_real( > > xfs_iext_update_extent(ip, state, icur, &PREV); > xfs_iext_insert(ip, icur, new, state); > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > + ifp->if_nextents++; > + > if (cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -2440,9 +2430,8 @@ xfs_bmap_add_extent_unwritten_real( > xfs_iext_update_extent(ip, state, icur, &PREV); > xfs_iext_next(ifp, icur); > xfs_iext_insert(ip, icur, new, state); > + ifp->if_nextents++; > > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > if (cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -2493,9 +2482,8 @@ xfs_bmap_add_extent_unwritten_real( > xfs_iext_next(ifp, icur); > xfs_iext_insert(ip, icur, &r[1], state); > xfs_iext_insert(ip, icur, &r[0], state); > + ifp->if_nextents += 2; > > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) + 2); > if (cur == NULL) > rval = XFS_ILOG_CORE | XFS_ILOG_DEXT; > else { > @@ -2810,9 +2798,8 @@ xfs_bmap_add_extent_hole_real( > xfs_iext_remove(ip, icur, state); > xfs_iext_prev(ifp, icur); > xfs_iext_update_extent(ip, state, icur, &left); > + ifp->if_nextents--; > > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > if (cur == NULL) { > rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); > } else { > @@ -2910,8 +2897,8 @@ xfs_bmap_add_extent_hole_real( > * Insert a new entry. > */ > xfs_iext_insert(ip, icur, new, state); > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > + ifp->if_nextents++; > + > if (cur == NULL) { > rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); > } else { > @@ -4512,8 +4499,7 @@ xfs_bmapi_write( > goto error0; > > ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || > - XFS_IFORK_NEXTENTS(ip, whichfork) > > - XFS_IFORK_MAXEXT(ip, whichfork)); > + ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork)); > xfs_bmapi_finish(&bma, whichfork, 0); > xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, > orig_nmap, *nmap); > @@ -5056,8 +5042,7 @@ xfs_bmap_del_extent_real( > */ > if (tp->t_blk_res == 0 && > XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > - XFS_IFORK_NEXTENTS(ip, whichfork) >= > - XFS_IFORK_MAXEXT(ip, whichfork) && > + ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) && > del->br_startoff > got.br_startoff && del_endoff < got_endoff) > return -ENOSPC; > > @@ -5109,8 +5094,8 @@ xfs_bmap_del_extent_real( > */ > xfs_iext_remove(ip, icur, state); > xfs_iext_prev(ifp, icur); > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > + ifp->if_nextents--; > + > flags |= XFS_ILOG_CORE; > if (!cur) { > flags |= xfs_ilog_fext(whichfork); > @@ -5218,8 +5203,8 @@ xfs_bmap_del_extent_real( > } > } else > flags |= xfs_ilog_fext(whichfork); > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > + > + ifp->if_nextents++; > xfs_iext_next(ifp, icur); > xfs_iext_insert(ip, icur, &new, state); > break; > @@ -5667,6 +5652,7 @@ xfs_bmse_merge( > struct xfs_btree_cur *cur, > int *logflags) /* output */ > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_bmbt_irec new; > xfs_filblks_t blockcount; > int error, i; > @@ -5685,8 +5671,7 @@ xfs_bmse_merge( > * Update the on-disk extent count, the btree if necessary and log the > * inode. > */ > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > + ifp->if_nextents--; > *logflags |= XFS_ILOG_CORE; > if (!cur) { > *logflags |= XFS_ILOG_DEXT; > @@ -5724,7 +5709,7 @@ xfs_bmse_merge( > > done: > xfs_iext_remove(ip, icur, 0); > - xfs_iext_prev(XFS_IFORK_PTR(ip, whichfork), icur); > + xfs_iext_prev(ifp, icur); > xfs_iext_update_extent(ip, xfs_bmap_fork_to_state(whichfork), icur, > &new); > > @@ -6074,8 +6059,7 @@ xfs_bmap_split_extent( > /* Add new extent */ > xfs_iext_next(ifp, &icur); > xfs_iext_insert(ip, &icur, &new, 0); > - XFS_IFORK_NEXT_SET(ip, whichfork, > - XFS_IFORK_NEXTENTS(ip, whichfork) + 1); > + ifp->if_nextents++; > > if (cur) { > error = xfs_bmbt_lookup_eq(cur, &new, &i); > diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c > index 1dbf2f980a26a..5b59d3f7746b3 100644 > --- a/fs/xfs/libxfs/xfs_dir2_block.c > +++ b/fs/xfs/libxfs/xfs_dir2_block.c > @@ -1104,7 +1104,7 @@ xfs_dir2_sf_to_block( > ASSERT(ifp->if_bytes == dp->i_d.di_size); > ASSERT(ifp->if_u1.if_data != NULL); > ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count)); > - ASSERT(dp->i_d.di_nextents == 0); > + ASSERT(dp->i_df.if_nextents == 0); > > /* > * Copy the directory into a temporary buffer. > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index 5547bbb3cf945..a374e2a81e764 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -245,8 +245,6 @@ xfs_inode_from_disk( > to->di_size = be64_to_cpu(from->di_size); > to->di_nblocks = be64_to_cpu(from->di_nblocks); > to->di_extsize = be32_to_cpu(from->di_extsize); > - to->di_nextents = be32_to_cpu(from->di_nextents); > - to->di_anextents = be16_to_cpu(from->di_anextents); > to->di_forkoff = from->di_forkoff; > to->di_aformat = from->di_aformat; > to->di_dmevmask = be32_to_cpu(from->di_dmevmask); > @@ -311,8 +309,8 @@ xfs_inode_to_disk( > to->di_size = cpu_to_be64(from->di_size); > to->di_nblocks = cpu_to_be64(from->di_nblocks); > to->di_extsize = cpu_to_be32(from->di_extsize); > - to->di_nextents = cpu_to_be32(from->di_nextents); > - to->di_anextents = cpu_to_be16(from->di_anextents); > + to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df)); > + to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp)); > to->di_forkoff = from->di_forkoff; > to->di_aformat = from->di_aformat; > to->di_dmevmask = cpu_to_be32(from->di_dmevmask); > diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h > index e4cbcaf62a32b..fecccfb26463c 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.h > +++ b/fs/xfs/libxfs/xfs_inode_buf.h > @@ -22,8 +22,6 @@ struct xfs_icdinode { > xfs_fsize_t di_size; /* number of bytes in file */ > xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ > xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ > - xfs_extnum_t di_nextents; /* number of extents in data fork */ > - xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ > uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ > int8_t di_aformat; /* format of attr fork's data */ > uint32_t di_dmevmask; /* DMIG event mask */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 2fe325e38fd88..195da3552c5b5 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -188,12 +188,11 @@ xfs_iformat_btree( > * or the number of extents is greater than the number of > * blocks. > */ > - if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= > - XFS_IFORK_MAXEXT(ip, whichfork) || > + if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) || > nrecs == 0 || > XFS_BMDR_SPACE_CALC(nrecs) > > XFS_DFORK_SIZE(dip, mp, whichfork) || > - XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) || > + ifp->if_nextents > ip->i_d.di_nblocks) || > level == 0 || level > XFS_BTREE_MAXLEVELS) { > xfs_warn(mp, "corrupt inode %Lu (btree).", > (unsigned long long) ip->i_ino); > @@ -229,6 +228,8 @@ xfs_iformat_data_fork( > struct inode *inode = VFS_I(ip); > int error; > > + ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); > + > switch (inode->i_mode & S_IFMT) { > case S_IFIFO: > case S_IFCHR: > @@ -282,6 +283,8 @@ xfs_iformat_attr_fork( > int error = 0; > > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); > + ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); > + > switch (dip->di_aformat) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, > @@ -617,7 +620,7 @@ xfs_iflush_fork( > !(iip->ili_fields & extflag[whichfork])); > if ((iip->ili_fields & extflag[whichfork]) && > (ifp->if_bytes > 0)) { > - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); > + ASSERT(ifp->if_nextents > 0); > (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, > whichfork); > } > @@ -676,7 +679,6 @@ xfs_ifork_init_cow( > KM_NOFS); > ip->i_cowfp->if_flags = XFS_IFEXTENTS; > ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > - ip->i_cnextents = 0; > } > > /* Verify the inline contents of the data fork of an inode. */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index f46a8c1db5964..a69d425fe68df 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -23,6 +23,7 @@ struct xfs_ifork { > } if_u1; > short if_broot_bytes; /* bytes allocated for root */ > unsigned char if_flags; /* per-fork flags */ > + xfs_extnum_t if_nextents; /* # of extents in this fork */ > }; > > /* > @@ -67,18 +68,6 @@ struct xfs_ifork { > ((w) == XFS_ATTR_FORK ? \ > ((ip)->i_d.di_aformat = (n)) : \ > ((ip)->i_cformat = (n)))) > -#define XFS_IFORK_NEXTENTS(ip,w) \ > - ((w) == XFS_DATA_FORK ? \ > - (ip)->i_d.di_nextents : \ > - ((w) == XFS_ATTR_FORK ? \ > - (ip)->i_d.di_anextents : \ > - (ip)->i_cnextents)) > -#define XFS_IFORK_NEXT_SET(ip,w,n) \ > - ((w) == XFS_DATA_FORK ? \ > - ((ip)->i_d.di_nextents = (n)) : \ > - ((w) == XFS_ATTR_FORK ? \ > - ((ip)->i_d.di_anextents = (n)) : \ > - ((ip)->i_cnextents = (n)))) > #define XFS_IFORK_MAXEXT(ip, w) \ > (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) > > @@ -86,6 +75,13 @@ struct xfs_ifork { > (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ > XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) > > +static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > +{ > + if (!ifp) > + return 0; > + return ifp->if_nextents; > +} > + > struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); > > int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > index 283424d6d2bb6..157f72efec5e9 100644 > --- a/fs/xfs/scrub/bmap.c > +++ b/fs/xfs/scrub/bmap.c > @@ -566,6 +566,7 @@ xchk_bmap_check_rmaps( > struct xfs_scrub *sc, > int whichfork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, whichfork); > loff_t size; > xfs_agnumber_t agno; > int error; > @@ -598,7 +599,7 @@ xchk_bmap_check_rmaps( > break; > } > if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > - (size == 0 || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) > + (size == 0 || ifp->if_nextents > 0)) > return 0; > > for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { > diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c > index 5705adc43a75f..855aa8bcab64b 100644 > --- a/fs/xfs/scrub/parent.c > +++ b/fs/xfs/scrub/parent.c > @@ -90,7 +90,7 @@ xchk_parent_count_parent_dentries( > * if there is one. > */ > lock_mode = xfs_ilock_data_map_shared(parent); > - if (parent->i_d.di_nextents > 0) > + if (parent->i_df.if_nextents > 0) > error = xfs_dir3_data_readahead(parent, 0, 0); > xfs_iunlock(parent, lock_mode); > if (error) > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index cc23a3e23e2d1..4f277a6253b8d 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -1220,7 +1220,7 @@ xfs_swap_extents_check_format( > * if the target inode has less extents that then temporary inode then > * why did userspace call us? > */ > - if (ip->i_d.di_nextents < tip->i_d.di_nextents) > + if (ip->i_df.if_nextents < tip->i_df.if_nextents) > return -EINVAL; > > /* > @@ -1241,14 +1241,12 @@ xfs_swap_extents_check_format( > > /* Check temp in extent form to max in target */ > if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) > > - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > > /* Check target in extent form to max in temp */ > if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > > - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > > /* > @@ -1264,7 +1262,7 @@ xfs_swap_extents_check_format( > if (XFS_IFORK_Q(ip) && > XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) > return -EINVAL; > - if (XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= > + if (tip->i_df.if_nextents <= > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > } > @@ -1274,7 +1272,7 @@ xfs_swap_extents_check_format( > if (XFS_IFORK_Q(tip) && > XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) > return -EINVAL; > - if (XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= > + if (ip->i_df.if_nextents <= > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > } > @@ -1427,15 +1425,15 @@ xfs_swap_extent_forks( > /* > * Count the number of extended attribute blocks > */ > - if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && > - (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { > + if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && > + ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, > &aforkblks); > if (error) > return error; > } > - if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && > - (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { > + if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && > + tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, > &taforkblks); > if (error) > @@ -1468,7 +1466,6 @@ xfs_swap_extent_forks( > ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; > tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; > > - swap(ip->i_d.di_nextents, tip->i_d.di_nextents); > swap(ip->i_d.di_format, tip->i_d.di_format); > > /* > @@ -1615,9 +1612,9 @@ xfs_swap_extents( > * performed with log redo items! > */ > if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { > - int w = XFS_DATA_FORK; > - uint32_t ipnext = XFS_IFORK_NEXTENTS(ip, w); > - uint32_t tipnext = XFS_IFORK_NEXTENTS(tip, w); > + int w = XFS_DATA_FORK; > + uint32_t ipnext = ip->i_df.if_nextents; > + uint32_t tipnext = tip->i_df.if_nextents; > > /* > * Conceptually this shouldn't affect the shape of either bmbt, > @@ -1720,7 +1717,6 @@ xfs_swap_extents( > ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); > ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); > > - swap(ip->i_cnextents, tip->i_cnextents); > swap(ip->i_cowfp, tip->i_cowfp); > > if (ip->i_cowfp && ip->i_cowfp->if_bytes) > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 4b8bdecc38635..403c90309a8ff 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1102,7 +1102,7 @@ xfs_dir_open( > * certain to have the next operation be a read there. > */ > mode = xfs_ilock_data_map_shared(ip); > - if (ip->i_d.di_nextents > 0) > + if (ip->i_df.if_nextents > 0) > error = xfs_dir3_data_readahead(ip, 0, 0); > xfs_iunlock(ip, mode); > return error; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index 5a3a520b95288..791d5d5e318cf 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -63,7 +63,6 @@ xfs_inode_alloc( > memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); > ip->i_afp = NULL; > ip->i_cowfp = NULL; > - ip->i_cnextents = 0; > ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > memset(&ip->i_df, 0, sizeof(ip->i_df)); > ip->i_flags = 0; > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 7d3144dc99b72..1677c4e7207ed 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -825,7 +825,7 @@ xfs_ialloc( > inode->i_mode &= ~S_ISGID; > > ip->i_d.di_size = 0; > - ip->i_d.di_nextents = 0; > + ip->i_df.if_nextents = 0; > ASSERT(ip->i_d.di_nblocks == 0); > > tv = current_time(inode); > @@ -919,7 +919,6 @@ xfs_ialloc( > * Attribute fork settings for new inode. > */ > ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > - ip->i_d.di_anextents = 0; > > /* > * Log the new values stuffed into the inode. > @@ -1686,7 +1685,7 @@ xfs_inactive_truncate( > if (error) > goto error_trans_cancel; > > - ASSERT(ip->i_d.di_nextents == 0); > + ASSERT(ip->i_df.if_nextents == 0); > > error = xfs_trans_commit(tp); > if (error) > @@ -1836,7 +1835,7 @@ xfs_inactive( > > if (S_ISREG(VFS_I(ip)->i_mode) && > (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || > - ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) > + ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) > truncate = 1; > > error = xfs_qm_dqattach(ip); > @@ -1862,7 +1861,6 @@ xfs_inactive( > } > > ASSERT(!ip->i_afp); > - ASSERT(ip->i_d.di_anextents == 0); > ASSERT(ip->i_d.di_forkoff == 0); > > /* > @@ -2731,8 +2729,7 @@ xfs_ifree( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > ASSERT(VFS_I(ip)->i_nlink == 0); > - ASSERT(ip->i_d.di_nextents == 0); > - ASSERT(ip->i_d.di_anextents == 0); > + ASSERT(ip->i_df.if_nextents == 0); > ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode)); > ASSERT(ip->i_d.di_nblocks == 0); > > @@ -3628,7 +3625,7 @@ xfs_iflush( > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > *bpp = NULL; > > @@ -3710,7 +3707,7 @@ xfs_iflush_int( > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > ASSERT(iip != NULL && iip->ili_fields != 0); > > dip = xfs_buf_offset(bp, ip->i_imap.im_boffset); > @@ -3751,13 +3748,13 @@ xfs_iflush_int( > goto flush_out; > } > } > - if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents > > + if (XFS_TEST_ERROR(ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp) > > ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: detected corrupt incore inode %Lu, " > "total extents = %d, nblocks = %Ld, ptr "PTR_FMT, > __func__, ip->i_ino, > - ip->i_d.di_nextents + ip->i_d.di_anextents, > + ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp), > ip->i_d.di_nblocks, ip); > goto flush_out; > } > diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h > index ff846197941e4..24dae63ba16c0 100644 > --- a/fs/xfs/xfs_inode.h > +++ b/fs/xfs/xfs_inode.h > @@ -57,7 +57,6 @@ typedef struct xfs_inode { > > struct xfs_icdinode i_d; /* most of ondisk inode */ > > - xfs_extnum_t i_cnextents; /* # of extents in cow fork */ > unsigned int i_cformat; /* format of cow fork */ > > /* VFS inode */ > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > index cefa2484f0dbf..401ba26aeed7b 100644 > --- a/fs/xfs/xfs_inode_item.c > +++ b/fs/xfs/xfs_inode_item.c > @@ -39,7 +39,7 @@ xfs_inode_item_data_fork_size( > switch (ip->i_d.di_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_DEXT) && > - ip->i_d.di_nextents > 0 && > + ip->i_df.if_nextents > 0 && > ip->i_df.if_bytes > 0) { > /* worst case, doesn't subtract delalloc extents */ > *nbytes += XFS_IFORK_DSIZE(ip); > @@ -80,7 +80,7 @@ xfs_inode_item_attr_fork_size( > switch (ip->i_d.di_aformat) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_AEXT) && > - ip->i_d.di_anextents > 0 && > + ip->i_afp->if_nextents > 0 && > ip->i_afp->if_bytes > 0) { > /* worst case, doesn't subtract unused space */ > *nbytes += XFS_IFORK_ASIZE(ip); > @@ -148,7 +148,7 @@ xfs_inode_item_format_data_fork( > ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); > > if ((iip->ili_fields & XFS_ILOG_DEXT) && > - ip->i_d.di_nextents > 0 && > + ip->i_df.if_nextents > 0 && > ip->i_df.if_bytes > 0) { > struct xfs_bmbt_rec *p; > > @@ -233,12 +233,12 @@ xfs_inode_item_format_attr_fork( > ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); > > if ((iip->ili_fields & XFS_ILOG_AEXT) && > - ip->i_d.di_anextents > 0 && > + ip->i_afp->if_nextents > 0 && > ip->i_afp->if_bytes > 0) { > struct xfs_bmbt_rec *p; > > ASSERT(xfs_iext_count(ip->i_afp) == > - ip->i_d.di_anextents); > + ip->i_afp->if_nextents); > > p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT); > data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK); > @@ -326,8 +326,8 @@ xfs_inode_to_log_dinode( > to->di_size = from->di_size; > to->di_nblocks = from->di_nblocks; > to->di_extsize = from->di_extsize; > - to->di_nextents = from->di_nextents; > - to->di_anextents = from->di_anextents; > + to->di_nextents = xfs_ifork_nextents(&ip->i_df); > + to->di_anextents = xfs_ifork_nextents(ip->i_afp); > to->di_forkoff = from->di_forkoff; > to->di_aformat = from->di_aformat; > to->di_dmevmask = from->di_dmevmask; > diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c > index 4ee0d13232f3f..7a71c03e9022b 100644 > --- a/fs/xfs/xfs_ioctl.c > +++ b/fs/xfs/xfs_ioctl.c > @@ -1104,26 +1104,17 @@ xfs_fill_fsxattr( > bool attr, > struct fsxattr *fa) > { > + struct xfs_ifork *ifp = attr ? ip->i_afp : &ip->i_df; > + > simple_fill_fsxattr(fa, xfs_ip2xflags(ip)); > fa->fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; > fa->fsx_cowextsize = ip->i_d.di_cowextsize << > ip->i_mount->m_sb.sb_blocklog; > fa->fsx_projid = ip->i_d.di_projid; > - > - if (attr) { > - if (ip->i_afp) { > - if (ip->i_afp->if_flags & XFS_IFEXTENTS) > - fa->fsx_nextents = xfs_iext_count(ip->i_afp); > - else > - fa->fsx_nextents = ip->i_d.di_anextents; > - } else > - fa->fsx_nextents = 0; > - } else { > - if (ip->i_df.if_flags & XFS_IFEXTENTS) > - fa->fsx_nextents = xfs_iext_count(&ip->i_df); > - else > - fa->fsx_nextents = ip->i_d.di_nextents; > - } > + if (ifp && (ifp->if_flags & XFS_IFEXTENTS)) > + fa->fsx_nextents = xfs_iext_count(ifp); > + else > + fa->fsx_nextents = xfs_ifork_nextents(ifp); > } > > STATIC int > @@ -1211,7 +1202,7 @@ xfs_ioctl_setattr_xflags( > uint64_t di_flags2; > > /* Can't change realtime flag if any extents are allocated. */ > - if ((ip->i_d.di_nextents || ip->i_delayed_blks) && > + if ((ip->i_df.if_nextents || ip->i_delayed_blks) && > XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME)) > return -EINVAL; > > @@ -1389,7 +1380,7 @@ xfs_ioctl_setattr_check_extsize( > xfs_extlen_t size; > xfs_fsblock_t extsize_fsb; > > - if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents && > + if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents && > ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) > return -EINVAL; > > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index bb590a267a7f9..b4fd918749e5f 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -1258,7 +1258,7 @@ xfs_xattr_iomap_begin( > lockmode = xfs_ilock_attr_map_shared(ip); > > /* if there are no attribute fork or extents, return ENOENT */ > - if (!XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { > + if (!XFS_IFORK_Q(ip) || !ip->i_afp->if_nextents) { > error = -ENOENT; > goto out_unlock; > } > diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c > index 26a71237d70f6..d66528fa36570 100644 > --- a/fs/xfs/xfs_iops.c > +++ b/fs/xfs/xfs_iops.c > @@ -872,7 +872,7 @@ xfs_setattr_size( > /* > * Short circuit the truncate case for zero length files. > */ > - if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { > + if (newsize == 0 && oldsize == 0 && ip->i_df.if_nextents == 0) { > if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME))) > return 0; > > diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c > index ff2da28fed90e..80da86c5703fb 100644 > --- a/fs/xfs/xfs_itable.c > +++ b/fs/xfs/xfs_itable.c > @@ -104,9 +104,9 @@ xfs_bulkstat_one_int( > > buf->bs_xflags = xfs_ip2xflags(ip); > buf->bs_extsize_blks = dic->di_extsize; > - buf->bs_extents = dic->di_nextents; > + buf->bs_extents = xfs_ifork_nextents(&ip->i_df); > xfs_bulkstat_health(ip, buf); > - buf->bs_aextents = dic->di_anextents; > + buf->bs_aextents = xfs_ifork_nextents(ip->i_afp); > buf->bs_forkoff = XFS_IFORK_BOFF(ip); > buf->bs_version = XFS_BULKSTAT_VERSION_V5; > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 944486f2b2874..9edf761eec739 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -302,7 +302,7 @@ xfs_qm_scall_trunc_qfile( > goto out_unlock; > } > > - ASSERT(ip->i_d.di_nextents == 0); > + ASSERT(ip->i_df.if_nextents == 0); > > xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); > error = xfs_trans_commit(tp); > diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c > index 38669e8272060..b5d10ecb54743 100644 > --- a/fs/xfs/xfs_quotaops.c > +++ b/fs/xfs/xfs_quotaops.c > @@ -36,7 +36,7 @@ xfs_qm_fill_state( > } > tstate->flags |= QCI_SYSFILE; > tstate->blocks = ip->i_d.di_nblocks; > - tstate->nextents = ip->i_d.di_nextents; > + tstate->nextents = ip->i_df.if_nextents; > tstate->spc_timelimit = (u32)q->qi_btimelimit; > tstate->ino_timelimit = (u32)q->qi_itimelimit; > tstate->rt_spc_timelimit = (u32)q->qi_rtbtimelimit; > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > index 973441992b084..8cf2fcb509c12 100644 > --- a/fs/xfs/xfs_symlink.c > +++ b/fs/xfs/xfs_symlink.c > @@ -384,7 +384,7 @@ xfs_inactive_symlink_rmt( > * either 1 or 2 extents and that we can > * free them all in one bunmapi call. > */ > - ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); > + ASSERT(ip->i_df.if_nextents > 0 && ip->i_df.if_nextents <= 2); > > error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); > if (error) > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index a4323a63438d8..ba2ab69e1fc7d 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -1898,7 +1898,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, > __entry->which = which; > __entry->ino = ip->i_ino; > __entry->format = ip->i_d.di_format; > - __entry->nex = ip->i_d.di_nextents; > + __entry->nex = ip->i_df.if_nextents; > __entry->broot_size = ip->i_df.if_broot_bytes; > __entry->fork_off = XFS_IFORK_BOFF(ip); > ), > -- chandan ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork 2020-05-10 7:24 ` [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork Christoph Hellwig 2020-05-12 5:26 ` Chandan Babu R @ 2020-05-12 16:10 ` Brian Foster 2020-05-16 18:09 ` Darrick J. Wong 2020-05-17 8:12 ` Christoph Hellwig 1 sibling, 2 replies; 41+ messages in thread From: Brian Foster @ 2020-05-12 16:10 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:02AM +0200, Christoph Hellwig wrote: > There are thee number of extents counters, one for each of the forks, > Two are in the legacy icdinode and one is directly in struct xfs_inode. > Switch to a single counter in the xfs_ifork structure where it uses up > padding at the end of the structure. This simplifies various bits of > code that just wants the number of extents counter and can now directly > dereference it. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/libxfs/xfs_attr.c | 4 +- > fs/xfs/libxfs/xfs_attr_leaf.c | 1 - > fs/xfs/libxfs/xfs_bmap.c | 126 ++++++++++++++------------------- > fs/xfs/libxfs/xfs_dir2_block.c | 2 +- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +- > fs/xfs/libxfs/xfs_inode_buf.h | 2 - > fs/xfs/libxfs/xfs_inode_fork.c | 12 ++-- > fs/xfs/libxfs/xfs_inode_fork.h | 20 +++--- > fs/xfs/scrub/bmap.c | 3 +- > fs/xfs/scrub/parent.c | 2 +- > fs/xfs/xfs_bmap_util.c | 28 ++++---- > fs/xfs/xfs_file.c | 2 +- > fs/xfs/xfs_icache.c | 1 - > fs/xfs/xfs_inode.c | 19 +++-- > fs/xfs/xfs_inode.h | 1 - > fs/xfs/xfs_inode_item.c | 14 ++-- > fs/xfs/xfs_ioctl.c | 25 +++---- > fs/xfs/xfs_iomap.c | 2 +- > fs/xfs/xfs_iops.c | 2 +- > fs/xfs/xfs_itable.c | 4 +- > fs/xfs/xfs_qm_syscalls.c | 2 +- > fs/xfs/xfs_quotaops.c | 2 +- > fs/xfs/xfs_symlink.c | 2 +- > fs/xfs/xfs_trace.h | 2 +- > 24 files changed, 122 insertions(+), 162 deletions(-) > ... > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index 863444e2dda7e..64b172180c42c 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -723,7 +723,6 @@ xfs_attr_fork_remove( > ip->i_d.di_forkoff = 0; > ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > - ASSERT(ip->i_d.di_anextents == 0); Perhaps we could create an analogous assert in xfs_idestroy_fork()? > ASSERT(ip->i_afp == NULL); > > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); ... > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 2fe325e38fd88..195da3552c5b5 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -188,12 +188,11 @@ xfs_iformat_btree( > * or the number of extents is greater than the number of > * blocks. > */ > - if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= > - XFS_IFORK_MAXEXT(ip, whichfork) || > + if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) || > nrecs == 0 || > XFS_BMDR_SPACE_CALC(nrecs) > > XFS_DFORK_SIZE(dip, mp, whichfork) || > - XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) || > + ifp->if_nextents > ip->i_d.di_nblocks) || > level == 0 || level > XFS_BTREE_MAXLEVELS) { > xfs_warn(mp, "corrupt inode %Lu (btree).", > (unsigned long long) ip->i_ino); > @@ -229,6 +228,8 @@ xfs_iformat_data_fork( > struct inode *inode = VFS_I(ip); > int error; > > + ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); > + Could use a comment here that the format calls below might depend on this being set (i.e. xfs_iformat_btree() just above). > switch (inode->i_mode & S_IFMT) { > case S_IFIFO: > case S_IFCHR: > @@ -282,6 +283,8 @@ xfs_iformat_attr_fork( > int error = 0; > > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); > + ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); > + Same here. Otherwise LGTM: Reviewed-by: Brian Foster <bfoster@redhat.com> > switch (dip->di_aformat) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, > @@ -617,7 +620,7 @@ xfs_iflush_fork( > !(iip->ili_fields & extflag[whichfork])); > if ((iip->ili_fields & extflag[whichfork]) && > (ifp->if_bytes > 0)) { > - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); > + ASSERT(ifp->if_nextents > 0); > (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, > whichfork); > } > @@ -676,7 +679,6 @@ xfs_ifork_init_cow( > KM_NOFS); > ip->i_cowfp->if_flags = XFS_IFEXTENTS; > ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > - ip->i_cnextents = 0; > } > > /* Verify the inline contents of the data fork of an inode. */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index f46a8c1db5964..a69d425fe68df 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -23,6 +23,7 @@ struct xfs_ifork { > } if_u1; > short if_broot_bytes; /* bytes allocated for root */ > unsigned char if_flags; /* per-fork flags */ > + xfs_extnum_t if_nextents; /* # of extents in this fork */ > }; > > /* > @@ -67,18 +68,6 @@ struct xfs_ifork { > ((w) == XFS_ATTR_FORK ? \ > ((ip)->i_d.di_aformat = (n)) : \ > ((ip)->i_cformat = (n)))) > -#define XFS_IFORK_NEXTENTS(ip,w) \ > - ((w) == XFS_DATA_FORK ? \ > - (ip)->i_d.di_nextents : \ > - ((w) == XFS_ATTR_FORK ? \ > - (ip)->i_d.di_anextents : \ > - (ip)->i_cnextents)) > -#define XFS_IFORK_NEXT_SET(ip,w,n) \ > - ((w) == XFS_DATA_FORK ? \ > - ((ip)->i_d.di_nextents = (n)) : \ > - ((w) == XFS_ATTR_FORK ? \ > - ((ip)->i_d.di_anextents = (n)) : \ > - ((ip)->i_cnextents = (n)))) > #define XFS_IFORK_MAXEXT(ip, w) \ > (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) > > @@ -86,6 +75,13 @@ struct xfs_ifork { > (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ > XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) > > +static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > +{ > + if (!ifp) > + return 0; > + return ifp->if_nextents; > +} > + > struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); > > int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > index 283424d6d2bb6..157f72efec5e9 100644 > --- a/fs/xfs/scrub/bmap.c > +++ b/fs/xfs/scrub/bmap.c > @@ -566,6 +566,7 @@ xchk_bmap_check_rmaps( > struct xfs_scrub *sc, > int whichfork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, whichfork); > loff_t size; > xfs_agnumber_t agno; > int error; > @@ -598,7 +599,7 @@ xchk_bmap_check_rmaps( > break; > } > if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > - (size == 0 || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) > + (size == 0 || ifp->if_nextents > 0)) > return 0; > > for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { > diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c > index 5705adc43a75f..855aa8bcab64b 100644 > --- a/fs/xfs/scrub/parent.c > +++ b/fs/xfs/scrub/parent.c > @@ -90,7 +90,7 @@ xchk_parent_count_parent_dentries( > * if there is one. > */ > lock_mode = xfs_ilock_data_map_shared(parent); > - if (parent->i_d.di_nextents > 0) > + if (parent->i_df.if_nextents > 0) > error = xfs_dir3_data_readahead(parent, 0, 0); > xfs_iunlock(parent, lock_mode); > if (error) > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index cc23a3e23e2d1..4f277a6253b8d 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -1220,7 +1220,7 @@ xfs_swap_extents_check_format( > * if the target inode has less extents that then temporary inode then > * why did userspace call us? > */ > - if (ip->i_d.di_nextents < tip->i_d.di_nextents) > + if (ip->i_df.if_nextents < tip->i_df.if_nextents) > return -EINVAL; > > /* > @@ -1241,14 +1241,12 @@ xfs_swap_extents_check_format( > > /* Check temp in extent form to max in target */ > if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) > > - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > > /* Check target in extent form to max in temp */ > if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > > - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > > /* > @@ -1264,7 +1262,7 @@ xfs_swap_extents_check_format( > if (XFS_IFORK_Q(ip) && > XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) > return -EINVAL; > - if (XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= > + if (tip->i_df.if_nextents <= > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > } > @@ -1274,7 +1272,7 @@ xfs_swap_extents_check_format( > if (XFS_IFORK_Q(tip) && > XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) > return -EINVAL; > - if (XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= > + if (ip->i_df.if_nextents <= > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > } > @@ -1427,15 +1425,15 @@ xfs_swap_extent_forks( > /* > * Count the number of extended attribute blocks > */ > - if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && > - (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { > + if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && > + ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, > &aforkblks); > if (error) > return error; > } > - if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && > - (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { > + if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && > + tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, > &taforkblks); > if (error) > @@ -1468,7 +1466,6 @@ xfs_swap_extent_forks( > ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; > tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; > > - swap(ip->i_d.di_nextents, tip->i_d.di_nextents); > swap(ip->i_d.di_format, tip->i_d.di_format); > > /* > @@ -1615,9 +1612,9 @@ xfs_swap_extents( > * performed with log redo items! > */ > if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { > - int w = XFS_DATA_FORK; > - uint32_t ipnext = XFS_IFORK_NEXTENTS(ip, w); > - uint32_t tipnext = XFS_IFORK_NEXTENTS(tip, w); > + int w = XFS_DATA_FORK; > + uint32_t ipnext = ip->i_df.if_nextents; > + uint32_t tipnext = tip->i_df.if_nextents; > > /* > * Conceptually this shouldn't affect the shape of either bmbt, > @@ -1720,7 +1717,6 @@ xfs_swap_extents( > ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); > ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); > > - swap(ip->i_cnextents, tip->i_cnextents); > swap(ip->i_cowfp, tip->i_cowfp); > > if (ip->i_cowfp && ip->i_cowfp->if_bytes) > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 4b8bdecc38635..403c90309a8ff 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1102,7 +1102,7 @@ xfs_dir_open( > * certain to have the next operation be a read there. > */ > mode = xfs_ilock_data_map_shared(ip); > - if (ip->i_d.di_nextents > 0) > + if (ip->i_df.if_nextents > 0) > error = xfs_dir3_data_readahead(ip, 0, 0); > xfs_iunlock(ip, mode); > return error; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index 5a3a520b95288..791d5d5e318cf 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -63,7 +63,6 @@ xfs_inode_alloc( > memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); > ip->i_afp = NULL; > ip->i_cowfp = NULL; > - ip->i_cnextents = 0; > ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > memset(&ip->i_df, 0, sizeof(ip->i_df)); > ip->i_flags = 0; > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 7d3144dc99b72..1677c4e7207ed 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -825,7 +825,7 @@ xfs_ialloc( > inode->i_mode &= ~S_ISGID; > > ip->i_d.di_size = 0; > - ip->i_d.di_nextents = 0; > + ip->i_df.if_nextents = 0; > ASSERT(ip->i_d.di_nblocks == 0); > > tv = current_time(inode); > @@ -919,7 +919,6 @@ xfs_ialloc( > * Attribute fork settings for new inode. > */ > ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > - ip->i_d.di_anextents = 0; > > /* > * Log the new values stuffed into the inode. > @@ -1686,7 +1685,7 @@ xfs_inactive_truncate( > if (error) > goto error_trans_cancel; > > - ASSERT(ip->i_d.di_nextents == 0); > + ASSERT(ip->i_df.if_nextents == 0); > > error = xfs_trans_commit(tp); > if (error) > @@ -1836,7 +1835,7 @@ xfs_inactive( > > if (S_ISREG(VFS_I(ip)->i_mode) && > (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || > - ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) > + ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) > truncate = 1; > > error = xfs_qm_dqattach(ip); > @@ -1862,7 +1861,6 @@ xfs_inactive( > } > > ASSERT(!ip->i_afp); > - ASSERT(ip->i_d.di_anextents == 0); > ASSERT(ip->i_d.di_forkoff == 0); > > /* > @@ -2731,8 +2729,7 @@ xfs_ifree( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > ASSERT(VFS_I(ip)->i_nlink == 0); > - ASSERT(ip->i_d.di_nextents == 0); > - ASSERT(ip->i_d.di_anextents == 0); > + ASSERT(ip->i_df.if_nextents == 0); > ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode)); > ASSERT(ip->i_d.di_nblocks == 0); > > @@ -3628,7 +3625,7 @@ xfs_iflush( > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > *bpp = NULL; > > @@ -3710,7 +3707,7 @@ xfs_iflush_int( > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > ASSERT(iip != NULL && iip->ili_fields != 0); > > dip = xfs_buf_offset(bp, ip->i_imap.im_boffset); > @@ -3751,13 +3748,13 @@ xfs_iflush_int( > goto flush_out; > } > } > - if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents > > + if (XFS_TEST_ERROR(ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp) > > ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: detected corrupt incore inode %Lu, " > "total extents = %d, nblocks = %Ld, ptr "PTR_FMT, > __func__, ip->i_ino, > - ip->i_d.di_nextents + ip->i_d.di_anextents, > + ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp), > ip->i_d.di_nblocks, ip); > goto flush_out; > } > diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h > index ff846197941e4..24dae63ba16c0 100644 > --- a/fs/xfs/xfs_inode.h > +++ b/fs/xfs/xfs_inode.h > @@ -57,7 +57,6 @@ typedef struct xfs_inode { > > struct xfs_icdinode i_d; /* most of ondisk inode */ > > - xfs_extnum_t i_cnextents; /* # of extents in cow fork */ > unsigned int i_cformat; /* format of cow fork */ > > /* VFS inode */ > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > index cefa2484f0dbf..401ba26aeed7b 100644 > --- a/fs/xfs/xfs_inode_item.c > +++ b/fs/xfs/xfs_inode_item.c > @@ -39,7 +39,7 @@ xfs_inode_item_data_fork_size( > switch (ip->i_d.di_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_DEXT) && > - ip->i_d.di_nextents > 0 && > + ip->i_df.if_nextents > 0 && > ip->i_df.if_bytes > 0) { > /* worst case, doesn't subtract delalloc extents */ > *nbytes += XFS_IFORK_DSIZE(ip); > @@ -80,7 +80,7 @@ xfs_inode_item_attr_fork_size( > switch (ip->i_d.di_aformat) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_AEXT) && > - ip->i_d.di_anextents > 0 && > + ip->i_afp->if_nextents > 0 && > ip->i_afp->if_bytes > 0) { > /* worst case, doesn't subtract unused space */ > *nbytes += XFS_IFORK_ASIZE(ip); > @@ -148,7 +148,7 @@ xfs_inode_item_format_data_fork( > ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); > > if ((iip->ili_fields & XFS_ILOG_DEXT) && > - ip->i_d.di_nextents > 0 && > + ip->i_df.if_nextents > 0 && > ip->i_df.if_bytes > 0) { > struct xfs_bmbt_rec *p; > > @@ -233,12 +233,12 @@ xfs_inode_item_format_attr_fork( > ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); > > if ((iip->ili_fields & XFS_ILOG_AEXT) && > - ip->i_d.di_anextents > 0 && > + ip->i_afp->if_nextents > 0 && > ip->i_afp->if_bytes > 0) { > struct xfs_bmbt_rec *p; > > ASSERT(xfs_iext_count(ip->i_afp) == > - ip->i_d.di_anextents); > + ip->i_afp->if_nextents); > > p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT); > data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK); > @@ -326,8 +326,8 @@ xfs_inode_to_log_dinode( > to->di_size = from->di_size; > to->di_nblocks = from->di_nblocks; > to->di_extsize = from->di_extsize; > - to->di_nextents = from->di_nextents; > - to->di_anextents = from->di_anextents; > + to->di_nextents = xfs_ifork_nextents(&ip->i_df); > + to->di_anextents = xfs_ifork_nextents(ip->i_afp); > to->di_forkoff = from->di_forkoff; > to->di_aformat = from->di_aformat; > to->di_dmevmask = from->di_dmevmask; > diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c > index 4ee0d13232f3f..7a71c03e9022b 100644 > --- a/fs/xfs/xfs_ioctl.c > +++ b/fs/xfs/xfs_ioctl.c > @@ -1104,26 +1104,17 @@ xfs_fill_fsxattr( > bool attr, > struct fsxattr *fa) > { > + struct xfs_ifork *ifp = attr ? ip->i_afp : &ip->i_df; > + > simple_fill_fsxattr(fa, xfs_ip2xflags(ip)); > fa->fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; > fa->fsx_cowextsize = ip->i_d.di_cowextsize << > ip->i_mount->m_sb.sb_blocklog; > fa->fsx_projid = ip->i_d.di_projid; > - > - if (attr) { > - if (ip->i_afp) { > - if (ip->i_afp->if_flags & XFS_IFEXTENTS) > - fa->fsx_nextents = xfs_iext_count(ip->i_afp); > - else > - fa->fsx_nextents = ip->i_d.di_anextents; > - } else > - fa->fsx_nextents = 0; > - } else { > - if (ip->i_df.if_flags & XFS_IFEXTENTS) > - fa->fsx_nextents = xfs_iext_count(&ip->i_df); > - else > - fa->fsx_nextents = ip->i_d.di_nextents; > - } > + if (ifp && (ifp->if_flags & XFS_IFEXTENTS)) > + fa->fsx_nextents = xfs_iext_count(ifp); > + else > + fa->fsx_nextents = xfs_ifork_nextents(ifp); > } > > STATIC int > @@ -1211,7 +1202,7 @@ xfs_ioctl_setattr_xflags( > uint64_t di_flags2; > > /* Can't change realtime flag if any extents are allocated. */ > - if ((ip->i_d.di_nextents || ip->i_delayed_blks) && > + if ((ip->i_df.if_nextents || ip->i_delayed_blks) && > XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME)) > return -EINVAL; > > @@ -1389,7 +1380,7 @@ xfs_ioctl_setattr_check_extsize( > xfs_extlen_t size; > xfs_fsblock_t extsize_fsb; > > - if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents && > + if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents && > ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) > return -EINVAL; > > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index bb590a267a7f9..b4fd918749e5f 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -1258,7 +1258,7 @@ xfs_xattr_iomap_begin( > lockmode = xfs_ilock_attr_map_shared(ip); > > /* if there are no attribute fork or extents, return ENOENT */ > - if (!XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { > + if (!XFS_IFORK_Q(ip) || !ip->i_afp->if_nextents) { > error = -ENOENT; > goto out_unlock; > } > diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c > index 26a71237d70f6..d66528fa36570 100644 > --- a/fs/xfs/xfs_iops.c > +++ b/fs/xfs/xfs_iops.c > @@ -872,7 +872,7 @@ xfs_setattr_size( > /* > * Short circuit the truncate case for zero length files. > */ > - if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { > + if (newsize == 0 && oldsize == 0 && ip->i_df.if_nextents == 0) { > if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME))) > return 0; > > diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c > index ff2da28fed90e..80da86c5703fb 100644 > --- a/fs/xfs/xfs_itable.c > +++ b/fs/xfs/xfs_itable.c > @@ -104,9 +104,9 @@ xfs_bulkstat_one_int( > > buf->bs_xflags = xfs_ip2xflags(ip); > buf->bs_extsize_blks = dic->di_extsize; > - buf->bs_extents = dic->di_nextents; > + buf->bs_extents = xfs_ifork_nextents(&ip->i_df); > xfs_bulkstat_health(ip, buf); > - buf->bs_aextents = dic->di_anextents; > + buf->bs_aextents = xfs_ifork_nextents(ip->i_afp); > buf->bs_forkoff = XFS_IFORK_BOFF(ip); > buf->bs_version = XFS_BULKSTAT_VERSION_V5; > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 944486f2b2874..9edf761eec739 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -302,7 +302,7 @@ xfs_qm_scall_trunc_qfile( > goto out_unlock; > } > > - ASSERT(ip->i_d.di_nextents == 0); > + ASSERT(ip->i_df.if_nextents == 0); > > xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); > error = xfs_trans_commit(tp); > diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c > index 38669e8272060..b5d10ecb54743 100644 > --- a/fs/xfs/xfs_quotaops.c > +++ b/fs/xfs/xfs_quotaops.c > @@ -36,7 +36,7 @@ xfs_qm_fill_state( > } > tstate->flags |= QCI_SYSFILE; > tstate->blocks = ip->i_d.di_nblocks; > - tstate->nextents = ip->i_d.di_nextents; > + tstate->nextents = ip->i_df.if_nextents; > tstate->spc_timelimit = (u32)q->qi_btimelimit; > tstate->ino_timelimit = (u32)q->qi_itimelimit; > tstate->rt_spc_timelimit = (u32)q->qi_rtbtimelimit; > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > index 973441992b084..8cf2fcb509c12 100644 > --- a/fs/xfs/xfs_symlink.c > +++ b/fs/xfs/xfs_symlink.c > @@ -384,7 +384,7 @@ xfs_inactive_symlink_rmt( > * either 1 or 2 extents and that we can > * free them all in one bunmapi call. > */ > - ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); > + ASSERT(ip->i_df.if_nextents > 0 && ip->i_df.if_nextents <= 2); > > error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); > if (error) > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index a4323a63438d8..ba2ab69e1fc7d 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -1898,7 +1898,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, > __entry->which = which; > __entry->ino = ip->i_ino; > __entry->format = ip->i_d.di_format; > - __entry->nex = ip->i_d.di_nextents; > + __entry->nex = ip->i_df.if_nextents; > __entry->broot_size = ip->i_df.if_broot_bytes; > __entry->fork_off = XFS_IFORK_BOFF(ip); > ), > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork 2020-05-12 16:10 ` Brian Foster @ 2020-05-16 18:09 ` Darrick J. Wong 2020-05-17 8:12 ` Christoph Hellwig 1 sibling, 0 replies; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 18:09 UTC (permalink / raw) To: Brian Foster; +Cc: Christoph Hellwig, linux-xfs On Tue, May 12, 2020 at 12:10:53PM -0400, Brian Foster wrote: > On Sun, May 10, 2020 at 09:24:02AM +0200, Christoph Hellwig wrote: > > There are thee number of extents counters, one for each of the forks, > > Two are in the legacy icdinode and one is directly in struct xfs_inode. > > Switch to a single counter in the xfs_ifork structure where it uses up > > padding at the end of the structure. This simplifies various bits of > > code that just wants the number of extents counter and can now directly > > dereference it. > > > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > --- > > fs/xfs/libxfs/xfs_attr.c | 4 +- > > fs/xfs/libxfs/xfs_attr_leaf.c | 1 - > > fs/xfs/libxfs/xfs_bmap.c | 126 ++++++++++++++------------------- > > fs/xfs/libxfs/xfs_dir2_block.c | 2 +- > > fs/xfs/libxfs/xfs_inode_buf.c | 6 +- > > fs/xfs/libxfs/xfs_inode_buf.h | 2 - > > fs/xfs/libxfs/xfs_inode_fork.c | 12 ++-- > > fs/xfs/libxfs/xfs_inode_fork.h | 20 +++--- > > fs/xfs/scrub/bmap.c | 3 +- > > fs/xfs/scrub/parent.c | 2 +- > > fs/xfs/xfs_bmap_util.c | 28 ++++---- > > fs/xfs/xfs_file.c | 2 +- > > fs/xfs/xfs_icache.c | 1 - > > fs/xfs/xfs_inode.c | 19 +++-- > > fs/xfs/xfs_inode.h | 1 - > > fs/xfs/xfs_inode_item.c | 14 ++-- > > fs/xfs/xfs_ioctl.c | 25 +++---- > > fs/xfs/xfs_iomap.c | 2 +- > > fs/xfs/xfs_iops.c | 2 +- > > fs/xfs/xfs_itable.c | 4 +- > > fs/xfs/xfs_qm_syscalls.c | 2 +- > > fs/xfs/xfs_quotaops.c | 2 +- > > fs/xfs/xfs_symlink.c | 2 +- > > fs/xfs/xfs_trace.h | 2 +- > > 24 files changed, 122 insertions(+), 162 deletions(-) > > > ... > > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > > index 863444e2dda7e..64b172180c42c 100644 > > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > > @@ -723,7 +723,6 @@ xfs_attr_fork_remove( > > ip->i_d.di_forkoff = 0; > > ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > > > - ASSERT(ip->i_d.di_anextents == 0); > > Perhaps we could create an analogous assert in xfs_idestroy_fork()? > > > ASSERT(ip->i_afp == NULL); > > > > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > ... > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > > index 2fe325e38fd88..195da3552c5b5 100644 > > --- a/fs/xfs/libxfs/xfs_inode_fork.c > > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > > @@ -188,12 +188,11 @@ xfs_iformat_btree( > > * or the number of extents is greater than the number of > > * blocks. > > */ > > - if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= > > - XFS_IFORK_MAXEXT(ip, whichfork) || > > + if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) || > > nrecs == 0 || > > XFS_BMDR_SPACE_CALC(nrecs) > > > XFS_DFORK_SIZE(dip, mp, whichfork) || > > - XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) || > > + ifp->if_nextents > ip->i_d.di_nblocks) || > > level == 0 || level > XFS_BTREE_MAXLEVELS) { > > xfs_warn(mp, "corrupt inode %Lu (btree).", > > (unsigned long long) ip->i_ino); > > @@ -229,6 +228,8 @@ xfs_iformat_data_fork( > > struct inode *inode = VFS_I(ip); > > int error; > > > > + ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); > > + > > Could use a comment here that the format calls below might depend on > this being set (i.e. xfs_iformat_btree() just above). > > > switch (inode->i_mode & S_IFMT) { > > case S_IFIFO: > > case S_IFCHR: > > @@ -282,6 +283,8 @@ xfs_iformat_attr_fork( > > int error = 0; > > > > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); > > + ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); > > + > > Same here. Otherwise LGTM: > Looks fine to me, and I can add those things on merge... Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> --D > Reviewed-by: Brian Foster <bfoster@redhat.com> > > > switch (dip->di_aformat) { > > case XFS_DINODE_FMT_LOCAL: > > error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, > > @@ -617,7 +620,7 @@ xfs_iflush_fork( > > !(iip->ili_fields & extflag[whichfork])); > > if ((iip->ili_fields & extflag[whichfork]) && > > (ifp->if_bytes > 0)) { > > - ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); > > + ASSERT(ifp->if_nextents > 0); > > (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, > > whichfork); > > } > > @@ -676,7 +679,6 @@ xfs_ifork_init_cow( > > KM_NOFS); > > ip->i_cowfp->if_flags = XFS_IFEXTENTS; > > ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > > - ip->i_cnextents = 0; > > } > > > > /* Verify the inline contents of the data fork of an inode. */ > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > > index f46a8c1db5964..a69d425fe68df 100644 > > --- a/fs/xfs/libxfs/xfs_inode_fork.h > > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > > @@ -23,6 +23,7 @@ struct xfs_ifork { > > } if_u1; > > short if_broot_bytes; /* bytes allocated for root */ > > unsigned char if_flags; /* per-fork flags */ > > + xfs_extnum_t if_nextents; /* # of extents in this fork */ > > }; > > > > /* > > @@ -67,18 +68,6 @@ struct xfs_ifork { > > ((w) == XFS_ATTR_FORK ? \ > > ((ip)->i_d.di_aformat = (n)) : \ > > ((ip)->i_cformat = (n)))) > > -#define XFS_IFORK_NEXTENTS(ip,w) \ > > - ((w) == XFS_DATA_FORK ? \ > > - (ip)->i_d.di_nextents : \ > > - ((w) == XFS_ATTR_FORK ? \ > > - (ip)->i_d.di_anextents : \ > > - (ip)->i_cnextents)) > > -#define XFS_IFORK_NEXT_SET(ip,w,n) \ > > - ((w) == XFS_DATA_FORK ? \ > > - ((ip)->i_d.di_nextents = (n)) : \ > > - ((w) == XFS_ATTR_FORK ? \ > > - ((ip)->i_d.di_anextents = (n)) : \ > > - ((ip)->i_cnextents = (n)))) > > #define XFS_IFORK_MAXEXT(ip, w) \ > > (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) > > > > @@ -86,6 +75,13 @@ struct xfs_ifork { > > (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ > > XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) > > > > +static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > > +{ > > + if (!ifp) > > + return 0; > > + return ifp->if_nextents; > > +} > > + > > struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); > > > > int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > index 283424d6d2bb6..157f72efec5e9 100644 > > --- a/fs/xfs/scrub/bmap.c > > +++ b/fs/xfs/scrub/bmap.c > > @@ -566,6 +566,7 @@ xchk_bmap_check_rmaps( > > struct xfs_scrub *sc, > > int whichfork) > > { > > + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, whichfork); > > loff_t size; > > xfs_agnumber_t agno; > > int error; > > @@ -598,7 +599,7 @@ xchk_bmap_check_rmaps( > > break; > > } > > if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > > - (size == 0 || XFS_IFORK_NEXTENTS(sc->ip, whichfork) > 0)) > > + (size == 0 || ifp->if_nextents > 0)) > > return 0; > > > > for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) { > > diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c > > index 5705adc43a75f..855aa8bcab64b 100644 > > --- a/fs/xfs/scrub/parent.c > > +++ b/fs/xfs/scrub/parent.c > > @@ -90,7 +90,7 @@ xchk_parent_count_parent_dentries( > > * if there is one. > > */ > > lock_mode = xfs_ilock_data_map_shared(parent); > > - if (parent->i_d.di_nextents > 0) > > + if (parent->i_df.if_nextents > 0) > > error = xfs_dir3_data_readahead(parent, 0, 0); > > xfs_iunlock(parent, lock_mode); > > if (error) > > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > > index cc23a3e23e2d1..4f277a6253b8d 100644 > > --- a/fs/xfs/xfs_bmap_util.c > > +++ b/fs/xfs/xfs_bmap_util.c > > @@ -1220,7 +1220,7 @@ xfs_swap_extents_check_format( > > * if the target inode has less extents that then temporary inode then > > * why did userspace call us? > > */ > > - if (ip->i_d.di_nextents < tip->i_d.di_nextents) > > + if (ip->i_df.if_nextents < tip->i_df.if_nextents) > > return -EINVAL; > > > > /* > > @@ -1241,14 +1241,12 @@ xfs_swap_extents_check_format( > > > > /* Check temp in extent form to max in target */ > > if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > > - XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) > > > - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > > + tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > > return -EINVAL; > > > > /* Check target in extent form to max in temp */ > > if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > > - XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > > > - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > > return -EINVAL; > > > > /* > > @@ -1264,7 +1262,7 @@ xfs_swap_extents_check_format( > > if (XFS_IFORK_Q(ip) && > > XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) > > return -EINVAL; > > - if (XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= > > + if (tip->i_df.if_nextents <= > > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > > return -EINVAL; > > } > > @@ -1274,7 +1272,7 @@ xfs_swap_extents_check_format( > > if (XFS_IFORK_Q(tip) && > > XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) > > return -EINVAL; > > - if (XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= > > + if (ip->i_df.if_nextents <= > > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > > return -EINVAL; > > } > > @@ -1427,15 +1425,15 @@ xfs_swap_extent_forks( > > /* > > * Count the number of extended attribute blocks > > */ > > - if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) && > > - (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { > > + if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && > > + ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > > error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, > > &aforkblks); > > if (error) > > return error; > > } > > - if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) && > > - (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) { > > + if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && > > + tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > > error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, > > &taforkblks); > > if (error) > > @@ -1468,7 +1466,6 @@ xfs_swap_extent_forks( > > ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; > > tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; > > > > - swap(ip->i_d.di_nextents, tip->i_d.di_nextents); > > swap(ip->i_d.di_format, tip->i_d.di_format); > > > > /* > > @@ -1615,9 +1612,9 @@ xfs_swap_extents( > > * performed with log redo items! > > */ > > if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { > > - int w = XFS_DATA_FORK; > > - uint32_t ipnext = XFS_IFORK_NEXTENTS(ip, w); > > - uint32_t tipnext = XFS_IFORK_NEXTENTS(tip, w); > > + int w = XFS_DATA_FORK; > > + uint32_t ipnext = ip->i_df.if_nextents; > > + uint32_t tipnext = tip->i_df.if_nextents; > > > > /* > > * Conceptually this shouldn't affect the shape of either bmbt, > > @@ -1720,7 +1717,6 @@ xfs_swap_extents( > > ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); > > ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); > > > > - swap(ip->i_cnextents, tip->i_cnextents); > > swap(ip->i_cowfp, tip->i_cowfp); > > > > if (ip->i_cowfp && ip->i_cowfp->if_bytes) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > > index 4b8bdecc38635..403c90309a8ff 100644 > > --- a/fs/xfs/xfs_file.c > > +++ b/fs/xfs/xfs_file.c > > @@ -1102,7 +1102,7 @@ xfs_dir_open( > > * certain to have the next operation be a read there. > > */ > > mode = xfs_ilock_data_map_shared(ip); > > - if (ip->i_d.di_nextents > 0) > > + if (ip->i_df.if_nextents > 0) > > error = xfs_dir3_data_readahead(ip, 0, 0); > > xfs_iunlock(ip, mode); > > return error; > > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > > index 5a3a520b95288..791d5d5e318cf 100644 > > --- a/fs/xfs/xfs_icache.c > > +++ b/fs/xfs/xfs_icache.c > > @@ -63,7 +63,6 @@ xfs_inode_alloc( > > memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); > > ip->i_afp = NULL; > > ip->i_cowfp = NULL; > > - ip->i_cnextents = 0; > > ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > > memset(&ip->i_df, 0, sizeof(ip->i_df)); > > ip->i_flags = 0; > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > > index 7d3144dc99b72..1677c4e7207ed 100644 > > --- a/fs/xfs/xfs_inode.c > > +++ b/fs/xfs/xfs_inode.c > > @@ -825,7 +825,7 @@ xfs_ialloc( > > inode->i_mode &= ~S_ISGID; > > > > ip->i_d.di_size = 0; > > - ip->i_d.di_nextents = 0; > > + ip->i_df.if_nextents = 0; > > ASSERT(ip->i_d.di_nblocks == 0); > > > > tv = current_time(inode); > > @@ -919,7 +919,6 @@ xfs_ialloc( > > * Attribute fork settings for new inode. > > */ > > ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > - ip->i_d.di_anextents = 0; > > > > /* > > * Log the new values stuffed into the inode. > > @@ -1686,7 +1685,7 @@ xfs_inactive_truncate( > > if (error) > > goto error_trans_cancel; > > > > - ASSERT(ip->i_d.di_nextents == 0); > > + ASSERT(ip->i_df.if_nextents == 0); > > > > error = xfs_trans_commit(tp); > > if (error) > > @@ -1836,7 +1835,7 @@ xfs_inactive( > > > > if (S_ISREG(VFS_I(ip)->i_mode) && > > (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || > > - ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) > > + ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) > > truncate = 1; > > > > error = xfs_qm_dqattach(ip); > > @@ -1862,7 +1861,6 @@ xfs_inactive( > > } > > > > ASSERT(!ip->i_afp); > > - ASSERT(ip->i_d.di_anextents == 0); > > ASSERT(ip->i_d.di_forkoff == 0); > > > > /* > > @@ -2731,8 +2729,7 @@ xfs_ifree( > > > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > ASSERT(VFS_I(ip)->i_nlink == 0); > > - ASSERT(ip->i_d.di_nextents == 0); > > - ASSERT(ip->i_d.di_anextents == 0); > > + ASSERT(ip->i_df.if_nextents == 0); > > ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode)); > > ASSERT(ip->i_d.di_nblocks == 0); > > > > @@ -3628,7 +3625,7 @@ xfs_iflush( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > > ASSERT(xfs_isiflocked(ip)); > > ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > > - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > > > *bpp = NULL; > > > > @@ -3710,7 +3707,7 @@ xfs_iflush_int( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > > ASSERT(xfs_isiflocked(ip)); > > ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > > - ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > + ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > ASSERT(iip != NULL && iip->ili_fields != 0); > > > > dip = xfs_buf_offset(bp, ip->i_imap.im_boffset); > > @@ -3751,13 +3748,13 @@ xfs_iflush_int( > > goto flush_out; > > } > > } > > - if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents > > > + if (XFS_TEST_ERROR(ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp) > > > ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) { > > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > > "%s: detected corrupt incore inode %Lu, " > > "total extents = %d, nblocks = %Ld, ptr "PTR_FMT, > > __func__, ip->i_ino, > > - ip->i_d.di_nextents + ip->i_d.di_anextents, > > + ip->i_df.if_nextents + xfs_ifork_nextents(ip->i_afp), > > ip->i_d.di_nblocks, ip); > > goto flush_out; > > } > > diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h > > index ff846197941e4..24dae63ba16c0 100644 > > --- a/fs/xfs/xfs_inode.h > > +++ b/fs/xfs/xfs_inode.h > > @@ -57,7 +57,6 @@ typedef struct xfs_inode { > > > > struct xfs_icdinode i_d; /* most of ondisk inode */ > > > > - xfs_extnum_t i_cnextents; /* # of extents in cow fork */ > > unsigned int i_cformat; /* format of cow fork */ > > > > /* VFS inode */ > > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > > index cefa2484f0dbf..401ba26aeed7b 100644 > > --- a/fs/xfs/xfs_inode_item.c > > +++ b/fs/xfs/xfs_inode_item.c > > @@ -39,7 +39,7 @@ xfs_inode_item_data_fork_size( > > switch (ip->i_d.di_format) { > > case XFS_DINODE_FMT_EXTENTS: > > if ((iip->ili_fields & XFS_ILOG_DEXT) && > > - ip->i_d.di_nextents > 0 && > > + ip->i_df.if_nextents > 0 && > > ip->i_df.if_bytes > 0) { > > /* worst case, doesn't subtract delalloc extents */ > > *nbytes += XFS_IFORK_DSIZE(ip); > > @@ -80,7 +80,7 @@ xfs_inode_item_attr_fork_size( > > switch (ip->i_d.di_aformat) { > > case XFS_DINODE_FMT_EXTENTS: > > if ((iip->ili_fields & XFS_ILOG_AEXT) && > > - ip->i_d.di_anextents > 0 && > > + ip->i_afp->if_nextents > 0 && > > ip->i_afp->if_bytes > 0) { > > /* worst case, doesn't subtract unused space */ > > *nbytes += XFS_IFORK_ASIZE(ip); > > @@ -148,7 +148,7 @@ xfs_inode_item_format_data_fork( > > ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); > > > > if ((iip->ili_fields & XFS_ILOG_DEXT) && > > - ip->i_d.di_nextents > 0 && > > + ip->i_df.if_nextents > 0 && > > ip->i_df.if_bytes > 0) { > > struct xfs_bmbt_rec *p; > > > > @@ -233,12 +233,12 @@ xfs_inode_item_format_attr_fork( > > ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); > > > > if ((iip->ili_fields & XFS_ILOG_AEXT) && > > - ip->i_d.di_anextents > 0 && > > + ip->i_afp->if_nextents > 0 && > > ip->i_afp->if_bytes > 0) { > > struct xfs_bmbt_rec *p; > > > > ASSERT(xfs_iext_count(ip->i_afp) == > > - ip->i_d.di_anextents); > > + ip->i_afp->if_nextents); > > > > p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT); > > data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK); > > @@ -326,8 +326,8 @@ xfs_inode_to_log_dinode( > > to->di_size = from->di_size; > > to->di_nblocks = from->di_nblocks; > > to->di_extsize = from->di_extsize; > > - to->di_nextents = from->di_nextents; > > - to->di_anextents = from->di_anextents; > > + to->di_nextents = xfs_ifork_nextents(&ip->i_df); > > + to->di_anextents = xfs_ifork_nextents(ip->i_afp); > > to->di_forkoff = from->di_forkoff; > > to->di_aformat = from->di_aformat; > > to->di_dmevmask = from->di_dmevmask; > > diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c > > index 4ee0d13232f3f..7a71c03e9022b 100644 > > --- a/fs/xfs/xfs_ioctl.c > > +++ b/fs/xfs/xfs_ioctl.c > > @@ -1104,26 +1104,17 @@ xfs_fill_fsxattr( > > bool attr, > > struct fsxattr *fa) > > { > > + struct xfs_ifork *ifp = attr ? ip->i_afp : &ip->i_df; > > + > > simple_fill_fsxattr(fa, xfs_ip2xflags(ip)); > > fa->fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; > > fa->fsx_cowextsize = ip->i_d.di_cowextsize << > > ip->i_mount->m_sb.sb_blocklog; > > fa->fsx_projid = ip->i_d.di_projid; > > - > > - if (attr) { > > - if (ip->i_afp) { > > - if (ip->i_afp->if_flags & XFS_IFEXTENTS) > > - fa->fsx_nextents = xfs_iext_count(ip->i_afp); > > - else > > - fa->fsx_nextents = ip->i_d.di_anextents; > > - } else > > - fa->fsx_nextents = 0; > > - } else { > > - if (ip->i_df.if_flags & XFS_IFEXTENTS) > > - fa->fsx_nextents = xfs_iext_count(&ip->i_df); > > - else > > - fa->fsx_nextents = ip->i_d.di_nextents; > > - } > > + if (ifp && (ifp->if_flags & XFS_IFEXTENTS)) > > + fa->fsx_nextents = xfs_iext_count(ifp); > > + else > > + fa->fsx_nextents = xfs_ifork_nextents(ifp); > > } > > > > STATIC int > > @@ -1211,7 +1202,7 @@ xfs_ioctl_setattr_xflags( > > uint64_t di_flags2; > > > > /* Can't change realtime flag if any extents are allocated. */ > > - if ((ip->i_d.di_nextents || ip->i_delayed_blks) && > > + if ((ip->i_df.if_nextents || ip->i_delayed_blks) && > > XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME)) > > return -EINVAL; > > > > @@ -1389,7 +1380,7 @@ xfs_ioctl_setattr_check_extsize( > > xfs_extlen_t size; > > xfs_fsblock_t extsize_fsb; > > > > - if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents && > > + if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents && > > ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) > > return -EINVAL; > > > > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > > index bb590a267a7f9..b4fd918749e5f 100644 > > --- a/fs/xfs/xfs_iomap.c > > +++ b/fs/xfs/xfs_iomap.c > > @@ -1258,7 +1258,7 @@ xfs_xattr_iomap_begin( > > lockmode = xfs_ilock_attr_map_shared(ip); > > > > /* if there are no attribute fork or extents, return ENOENT */ > > - if (!XFS_IFORK_Q(ip) || !ip->i_d.di_anextents) { > > + if (!XFS_IFORK_Q(ip) || !ip->i_afp->if_nextents) { > > error = -ENOENT; > > goto out_unlock; > > } > > diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c > > index 26a71237d70f6..d66528fa36570 100644 > > --- a/fs/xfs/xfs_iops.c > > +++ b/fs/xfs/xfs_iops.c > > @@ -872,7 +872,7 @@ xfs_setattr_size( > > /* > > * Short circuit the truncate case for zero length files. > > */ > > - if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) { > > + if (newsize == 0 && oldsize == 0 && ip->i_df.if_nextents == 0) { > > if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME))) > > return 0; > > > > diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c > > index ff2da28fed90e..80da86c5703fb 100644 > > --- a/fs/xfs/xfs_itable.c > > +++ b/fs/xfs/xfs_itable.c > > @@ -104,9 +104,9 @@ xfs_bulkstat_one_int( > > > > buf->bs_xflags = xfs_ip2xflags(ip); > > buf->bs_extsize_blks = dic->di_extsize; > > - buf->bs_extents = dic->di_nextents; > > + buf->bs_extents = xfs_ifork_nextents(&ip->i_df); > > xfs_bulkstat_health(ip, buf); > > - buf->bs_aextents = dic->di_anextents; > > + buf->bs_aextents = xfs_ifork_nextents(ip->i_afp); > > buf->bs_forkoff = XFS_IFORK_BOFF(ip); > > buf->bs_version = XFS_BULKSTAT_VERSION_V5; > > > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > > index 944486f2b2874..9edf761eec739 100644 > > --- a/fs/xfs/xfs_qm_syscalls.c > > +++ b/fs/xfs/xfs_qm_syscalls.c > > @@ -302,7 +302,7 @@ xfs_qm_scall_trunc_qfile( > > goto out_unlock; > > } > > > > - ASSERT(ip->i_d.di_nextents == 0); > > + ASSERT(ip->i_df.if_nextents == 0); > > > > xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); > > error = xfs_trans_commit(tp); > > diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c > > index 38669e8272060..b5d10ecb54743 100644 > > --- a/fs/xfs/xfs_quotaops.c > > +++ b/fs/xfs/xfs_quotaops.c > > @@ -36,7 +36,7 @@ xfs_qm_fill_state( > > } > > tstate->flags |= QCI_SYSFILE; > > tstate->blocks = ip->i_d.di_nblocks; > > - tstate->nextents = ip->i_d.di_nextents; > > + tstate->nextents = ip->i_df.if_nextents; > > tstate->spc_timelimit = (u32)q->qi_btimelimit; > > tstate->ino_timelimit = (u32)q->qi_itimelimit; > > tstate->rt_spc_timelimit = (u32)q->qi_rtbtimelimit; > > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > > index 973441992b084..8cf2fcb509c12 100644 > > --- a/fs/xfs/xfs_symlink.c > > +++ b/fs/xfs/xfs_symlink.c > > @@ -384,7 +384,7 @@ xfs_inactive_symlink_rmt( > > * either 1 or 2 extents and that we can > > * free them all in one bunmapi call. > > */ > > - ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); > > + ASSERT(ip->i_df.if_nextents > 0 && ip->i_df.if_nextents <= 2); > > > > error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); > > if (error) > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > > index a4323a63438d8..ba2ab69e1fc7d 100644 > > --- a/fs/xfs/xfs_trace.h > > +++ b/fs/xfs/xfs_trace.h > > @@ -1898,7 +1898,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, > > __entry->which = which; > > __entry->ino = ip->i_ino; > > __entry->format = ip->i_d.di_format; > > - __entry->nex = ip->i_d.di_nextents; > > + __entry->nex = ip->i_df.if_nextents; > > __entry->broot_size = ip->i_df.if_broot_bytes; > > __entry->fork_off = XFS_IFORK_BOFF(ip); > > ), > > -- > > 2.26.2 > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork 2020-05-12 16:10 ` Brian Foster 2020-05-16 18:09 ` Darrick J. Wong @ 2020-05-17 8:12 ` Christoph Hellwig 1 sibling, 0 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-17 8:12 UTC (permalink / raw) To: Brian Foster; +Cc: Christoph Hellwig, linux-xfs On Tue, May 12, 2020 at 12:10:53PM -0400, Brian Foster wrote: > > ip->i_d.di_forkoff = 0; > > ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > > > - ASSERT(ip->i_d.di_anextents == 0); > > Perhaps we could create an analogous assert in xfs_idestroy_fork()? Added for the next version. > > @@ -229,6 +228,8 @@ xfs_iformat_data_fork( > > struct inode *inode = VFS_I(ip); > > int error; > > > > + ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); > > + > > Could use a comment here that the format calls below might depend on > this being set (i.e. xfs_iformat_btree() just above). > > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); > > + ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); > > + > > Same here. Otherwise LGTM: Sure. ^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-10 7:23 move the extent count and format into struct xfs_ifork Christoph Hellwig ` (3 preceding siblings ...) 2020-05-10 7:24 ` [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork Christoph Hellwig @ 2020-05-10 7:24 ` Christoph Hellwig 2020-05-12 9:37 ` Chandan Babu R ` (2 more replies) 2020-05-10 7:24 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig 5 siblings, 3 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-10 7:24 UTC (permalink / raw) To: linux-xfs Both the data and attr fork have a format that is stored in the legacy idinode. Move it into the xfs_ifork structure instead, where it uses up padding. Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/libxfs/xfs_attr.c | 12 +-- fs/xfs/libxfs/xfs_attr_leaf.c | 32 ++++---- fs/xfs/libxfs/xfs_bmap.c | 120 +++++++++++++---------------- fs/xfs/libxfs/xfs_bmap_btree.c | 5 +- fs/xfs/libxfs/xfs_dir2.c | 8 +- fs/xfs/libxfs/xfs_dir2_sf.c | 13 ++-- fs/xfs/libxfs/xfs_inode_buf.c | 6 +- fs/xfs/libxfs/xfs_inode_buf.h | 2 - fs/xfs/libxfs/xfs_inode_fork.c | 14 ++-- fs/xfs/libxfs/xfs_inode_fork.h | 28 ++++--- fs/xfs/libxfs/xfs_symlink_remote.c | 16 ++-- fs/xfs/scrub/bmap.c | 4 +- fs/xfs/scrub/dabtree.c | 2 +- fs/xfs/scrub/dir.c | 7 +- fs/xfs/xfs_aops.c | 2 +- fs/xfs/xfs_attr_inactive.c | 2 +- fs/xfs/xfs_attr_list.c | 4 +- fs/xfs/xfs_bmap_util.c | 56 +++++++------- fs/xfs/xfs_dir2_readdir.c | 2 +- fs/xfs/xfs_icache.c | 1 - fs/xfs/xfs_inode.c | 36 ++++----- fs/xfs/xfs_inode.h | 2 - fs/xfs/xfs_inode_item.c | 12 +-- fs/xfs/xfs_iomap.c | 4 +- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_symlink.c | 2 +- fs/xfs/xfs_trace.h | 2 +- 27 files changed, 181 insertions(+), 215 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 1b01675e9c80b..3b1bd6e112f89 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -61,7 +61,7 @@ xfs_inode_hasattr( struct xfs_inode *ip) { if (!XFS_IFORK_Q(ip) || - (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && + (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && ip->i_afp->if_nextents == 0)) return 0; return 1; @@ -84,7 +84,7 @@ xfs_attr_get_ilocked( if (!xfs_inode_hasattr(args->dp)) return -ENOATTR; - if (args->dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) + if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) return xfs_attr_shortform_getvalue(args); if (xfs_bmap_one_block(args->dp, XFS_ATTR_FORK)) return xfs_attr_leaf_get(args); @@ -212,14 +212,14 @@ xfs_attr_set_args( * If the attribute list is non-existent or a shortform list, * upgrade it to a single-leaf-block attribute list. */ - if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL || - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL || + (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && dp->i_afp->if_nextents == 0)) { /* * Build initial attribute list (if required). */ - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) + if (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS) xfs_attr_shortform_create(args); /* @@ -272,7 +272,7 @@ xfs_attr_remove_args( if (!xfs_inode_hasattr(dp)) { error = -ENOATTR; - } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { + } else if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) { ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); error = xfs_attr_shortform_remove(args); } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 64b172180c42c..d7f3173ce3c31 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -539,7 +539,7 @@ xfs_attr_shortform_bytesfit( /* rounded down */ offset = (XFS_LITINO(mp) - bytes) >> 3; - if (dp->i_d.di_format == XFS_DINODE_FMT_DEV) { + if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) { minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; return (offset >= minforkoff) ? minforkoff : 0; } @@ -567,7 +567,7 @@ xfs_attr_shortform_bytesfit( dsize = dp->i_df.if_bytes; - switch (dp->i_d.di_format) { + switch (dp->i_df.if_format) { case XFS_DINODE_FMT_EXTENTS: /* * If there is no attr fork and the data fork is extents, @@ -636,22 +636,19 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) * Create the initial contents of a shortform attribute list. */ void -xfs_attr_shortform_create(xfs_da_args_t *args) +xfs_attr_shortform_create( + struct xfs_da_args *args) { - xfs_attr_sf_hdr_t *hdr; - xfs_inode_t *dp; - struct xfs_ifork *ifp; + struct xfs_inode *dp = args->dp; + struct xfs_ifork *ifp = dp->i_afp; + struct xfs_attr_sf_hdr *hdr; trace_xfs_attr_sf_create(args); - dp = args->dp; - ASSERT(dp != NULL); - ifp = dp->i_afp; - ASSERT(ifp != NULL); ASSERT(ifp->if_bytes == 0); - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) { + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS) { ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */ - dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL; + ifp->if_format = XFS_DINODE_FMT_LOCAL; ifp->if_flags |= XFS_IFINLINE; } else { ASSERT(ifp->if_flags & XFS_IFINLINE); @@ -721,7 +718,6 @@ xfs_attr_fork_remove( { xfs_idestroy_fork(ip, XFS_ATTR_FORK); ip->i_d.di_forkoff = 0; - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; ASSERT(ip->i_afp == NULL); @@ -774,7 +770,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) totsize -= size; if (totsize == sizeof(xfs_attr_sf_hdr_t) && (mp->m_flags & XFS_MOUNT_ATTR2) && - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && !(args->op_flags & XFS_DA_OP_ADDNAME)) { xfs_attr_fork_remove(dp, args->trans); } else { @@ -784,7 +780,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || (args->op_flags & XFS_DA_OP_ADDNAME) || !(mp->m_flags & XFS_MOUNT_ATTR2) || - dp->i_d.di_format == XFS_DINODE_FMT_BTREE); + dp->i_df.if_format == XFS_DINODE_FMT_BTREE); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); } @@ -961,7 +957,7 @@ xfs_attr_shortform_allfit( + be16_to_cpu(name_loc->valuelen); } if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && (bytes == sizeof(struct xfs_attr_sf_hdr))) return -1; return xfs_attr_shortform_bytesfit(dp, bytes); @@ -980,7 +976,7 @@ xfs_attr_shortform_verify( int i; int64_t size; - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL); + ASSERT(ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL); ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK); sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data; size = ifp->if_bytes; @@ -1084,7 +1080,7 @@ xfs_attr3_leaf_to_shortform( if (forkoff == -1) { ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); - ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); + ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE); xfs_attr_fork_remove(dp, args->trans); goto out; } diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index c1136be49abeb..edc63dba007f4 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -123,7 +123,7 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); return whichfork != XFS_COW_FORK && - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && + ifp->if_format == XFS_DINODE_FMT_EXTENTS && ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork); } @@ -135,7 +135,7 @@ static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); return whichfork != XFS_COW_FORK && - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && + ifp->if_format == XFS_DINODE_FMT_BTREE && ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork); } @@ -215,8 +215,8 @@ xfs_bmap_forkoff_reset( int whichfork) { if (whichfork == XFS_ATTR_FORK && - ip->i_d.di_format != XFS_DINODE_FMT_DEV && - ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { + ip->i_df.if_format != XFS_DINODE_FMT_DEV && + ip->i_df.if_format != XFS_DINODE_FMT_BTREE) { uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; if (dfl_forkoff > ip->i_d.di_forkoff) @@ -317,31 +317,28 @@ xfs_bmap_check_leaf_extents( xfs_inode_t *ip, /* incore inode pointer */ int whichfork) /* data or attr fork */ { + struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_btree_block *block; /* current btree block */ xfs_fsblock_t bno; /* block # of "block" */ xfs_buf_t *bp; /* buffer for "block" */ int error; /* error return value */ xfs_extnum_t i=0, j; /* index into the extents list */ - struct xfs_ifork *ifp; /* fork structure */ int level; /* btree level, for checking */ - xfs_mount_t *mp; /* file system mount structure */ __be64 *pp; /* pointer to block address */ xfs_bmbt_rec_t *ep; /* pointer to current extent */ xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */ xfs_bmbt_rec_t *nextp; /* pointer to next extent */ int bp_release = 0; - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { + if (ifp->if_format != XFS_DINODE_FMT_BTREE) return; - } /* skip large extent count inodes */ if (ip->i_df.if_nextents > 10000) return; bno = NULLFSBLOCK; - mp = ip->i_mount; - ifp = XFS_IFORK_PTR(ip, whichfork); block = ifp->if_broot; /* * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. @@ -606,7 +603,7 @@ xfs_bmap_btree_to_extents( ASSERT(cur); ASSERT(whichfork != XFS_COW_FORK); ASSERT(ifp->if_flags & XFS_IFEXTENTS); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); ASSERT(be16_to_cpu(rblock->bb_level) == 1); ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); @@ -634,7 +631,7 @@ xfs_bmap_btree_to_extents( xfs_iroot_realloc(ip, -1, whichfork); ASSERT(ifp->if_broot == NULL); ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); + ifp->if_format = XFS_DINODE_FMT_EXTENTS; *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork); return 0; } @@ -670,7 +667,7 @@ xfs_bmap_extents_to_btree( mp = ip->i_mount; ASSERT(whichfork != XFS_COW_FORK); ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); + ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS); /* * Make space in the inode incore. This needs to be undone if we fail @@ -694,7 +691,7 @@ xfs_bmap_extents_to_btree( /* * Convert to a btree with two levels, one record in root. */ - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); + ifp->if_format = XFS_DINODE_FMT_BTREE; memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; @@ -780,7 +777,7 @@ xfs_bmap_extents_to_btree( xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); out_root_realloc: xfs_iroot_realloc(ip, -1, whichfork); - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); + ifp->if_format = XFS_DINODE_FMT_EXTENTS; ASSERT(ifp->if_broot == NULL); xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); @@ -802,7 +799,7 @@ xfs_bmap_local_to_extents_empty( struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT(whichfork != XFS_COW_FORK); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); ASSERT(ifp->if_bytes == 0); ASSERT(ifp->if_nextents == 0); @@ -811,7 +808,7 @@ xfs_bmap_local_to_extents_empty( ifp->if_flags |= XFS_IFEXTENTS; ifp->if_u1.if_root = NULL; ifp->if_height = 0; - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); + ifp->if_format = XFS_DINODE_FMT_EXTENTS; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } @@ -842,7 +839,7 @@ xfs_bmap_local_to_extents( */ ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK)); ifp = XFS_IFORK_PTR(ip, whichfork); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); if (!ifp->if_bytes) { xfs_bmap_local_to_extents_empty(tp, ip, whichfork); @@ -1036,7 +1033,7 @@ xfs_bmap_set_attrforkoff( int size, int *version) { - switch (ip->i_d.di_format) { + switch (ip->i_df.if_format) { case XFS_DINODE_FMT_DEV: ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; break; @@ -1094,13 +1091,6 @@ xfs_bmap_add_attrfork( goto trans_cancel; if (XFS_IFORK_Q(ip)) goto trans_cancel; - if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { - /* - * For inodes coming from pre-6.2 filesystems. - */ - ASSERT(ip->i_d.di_aformat == 0); - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; - } xfs_trans_ijoin(tp, ip, 0); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); @@ -1109,9 +1099,10 @@ xfs_bmap_add_attrfork( goto trans_cancel; ASSERT(ip->i_afp == NULL); ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, 0); + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; ip->i_afp->if_flags = XFS_IFEXTENTS; logflags = 0; - switch (ip->i_d.di_format) { + switch (ip->i_df.if_format) { case XFS_DINODE_FMT_LOCAL: error = xfs_bmap_add_attrfork_local(tp, ip, &logflags); break; @@ -1237,9 +1228,7 @@ xfs_iread_extents( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - if (XFS_IS_CORRUPT(mp, - XFS_IFORK_FORMAT(ip, whichfork) != - XFS_DINODE_FMT_BTREE)) { + if (XFS_IS_CORRUPT(mp, ifp->if_format != XFS_DINODE_FMT_BTREE)) { error = -EFSCORRUPTED; goto out; } @@ -1287,14 +1276,13 @@ xfs_bmap_first_unused( xfs_fileoff_t lowest, max; int error; - ASSERT(xfs_ifork_has_extents(ip, whichfork) || - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); - - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { *first_unused = 0; return 0; } + ASSERT(xfs_ifork_has_extents(ifp)); + if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(tp, ip, whichfork); if (error) @@ -1335,7 +1323,7 @@ xfs_bmap_last_before( struct xfs_iext_cursor icur; int error; - switch (XFS_IFORK_FORMAT(ip, whichfork)) { + switch (ifp->if_format) { case XFS_DINODE_FMT_LOCAL: *last_block = 0; return 0; @@ -1434,16 +1422,17 @@ xfs_bmap_last_offset( xfs_fileoff_t *last_block, int whichfork) { + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_bmbt_irec rec; int is_empty; int error; *last_block = 0; - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) return 0; - if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ip, whichfork))) + if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp))) return -EFSCORRUPTED; error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); @@ -1475,7 +1464,7 @@ xfs_bmap_one_block( #endif /* !DEBUG */ if (ifp->if_nextents != 1) return 0; - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS) return 0; ASSERT(ifp->if_flags & XFS_IFEXTENTS); xfs_iext_first(ifp, &icur); @@ -3895,10 +3884,9 @@ xfs_bmapi_read( if (WARN_ON_ONCE(!ifp)) return -EFSCORRUPTED; - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || - XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) return -EFSCORRUPTED; - } if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; @@ -4281,11 +4269,13 @@ xfs_bmapi_minleft( struct xfs_inode *ip, int fork) { + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, fork); + if (tp && tp->t_firstblock != NULLFSBLOCK) return 0; - if (XFS_IFORK_FORMAT(ip, fork) != XFS_DINODE_FMT_BTREE) + if (ifp->if_format != XFS_DINODE_FMT_BTREE) return 1; - return be16_to_cpu(XFS_IFORK_PTR(ip, fork)->if_broot->bb_level) + 1; + return be16_to_cpu(ifp->if_broot->bb_level) + 1; } /* @@ -4300,11 +4290,13 @@ xfs_bmapi_finish( int whichfork, int error) { + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); + if ((bma->logflags & xfs_ilog_fext(whichfork)) && - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_EXTENTS) + ifp->if_format != XFS_DINODE_FMT_EXTENTS) bma->logflags &= ~xfs_ilog_fext(whichfork); else if ((bma->logflags & xfs_ilog_fbroot(whichfork)) && - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_BTREE) + ifp->if_format != XFS_DINODE_FMT_BTREE) bma->logflags &= ~xfs_ilog_fbroot(whichfork); if (bma->logflags) @@ -4336,13 +4328,13 @@ xfs_bmapi_write( .total = total, }; struct xfs_mount *mp = ip->i_mount; - struct xfs_ifork *ifp; + int whichfork = xfs_bmapi_whichfork(flags); + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); xfs_fileoff_t end; /* end of mapped file region */ bool eof = false; /* after the end of extents */ int error; /* error return */ int n; /* current extent index */ xfs_fileoff_t obno; /* old block number (offset) */ - int whichfork; /* data or attr fork */ #ifdef DEBUG xfs_fileoff_t orig_bno; /* original block number value */ @@ -4357,13 +4349,12 @@ xfs_bmapi_write( orig_mval = mval; orig_nmap = *nmap; #endif - whichfork = xfs_bmapi_whichfork(flags); ASSERT(*nmap >= 1); ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); ASSERT(tp != NULL); ASSERT(len > 0); - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); + ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(!(flags & XFS_BMAPI_REMAP)); @@ -4379,7 +4370,7 @@ xfs_bmapi_write( ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -4387,8 +4378,6 @@ xfs_bmapi_write( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - ifp = XFS_IFORK_PTR(ip, whichfork); - XFS_STATS_INC(mp, xs_blk_mapw); if (!(ifp->if_flags & XFS_IFEXTENTS)) { @@ -4498,7 +4487,7 @@ xfs_bmapi_write( if (error) goto error0; - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || + ASSERT(ifp->if_format != XFS_DINODE_FMT_BTREE || ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork)); xfs_bmapi_finish(&bma, whichfork, 0); xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, @@ -4645,7 +4634,7 @@ xfs_bmapi_remap( ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) != (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)); - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -4689,9 +4678,9 @@ xfs_bmapi_remap( error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, whichfork); error0: - if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) + if (ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS) logflags &= ~XFS_ILOG_DEXT; - else if (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) + else if (ip->i_df.if_format != XFS_DINODE_FMT_BTREE) logflags &= ~XFS_ILOG_DBROOT; if (logflags) @@ -5041,7 +5030,7 @@ xfs_bmap_del_extent_real( * conversion to btree format, since the transaction will be dirty then. */ if (tp->t_blk_res == 0 && - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && + ifp->if_format == XFS_DINODE_FMT_EXTENTS && ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) && del->br_startoff > got.br_startoff && del_endoff < got_endoff) return -ENOSPC; @@ -5284,7 +5273,7 @@ __xfs_bunmapi( whichfork = xfs_bmapi_whichfork(flags); ASSERT(whichfork != XFS_COW_FORK); ifp = XFS_IFORK_PTR(ip, whichfork); - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork))) + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp))) return -EFSCORRUPTED; if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; @@ -5322,7 +5311,7 @@ __xfs_bunmapi( logflags = 0; if (ifp->if_flags & XFS_IFBROOT) { - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_ino.flags = 0; } else @@ -5567,10 +5556,10 @@ __xfs_bunmapi( * logging the extent records if we've converted to btree format. */ if ((logflags & xfs_ilog_fext(whichfork)) && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) + ifp->if_format != XFS_DINODE_FMT_EXTENTS) logflags &= ~xfs_ilog_fext(whichfork); else if ((logflags & xfs_ilog_fbroot(whichfork)) && - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) + ifp->if_format != XFS_DINODE_FMT_BTREE) logflags &= ~xfs_ilog_fbroot(whichfork); /* * Log inode even in the error case, if the transaction @@ -5781,7 +5770,7 @@ xfs_bmap_collapse_extents( int error = 0; int logflags = 0; - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -5898,7 +5887,7 @@ xfs_bmap_insert_extents( int error = 0; int logflags = 0; - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -5992,18 +5981,18 @@ xfs_bmap_split_extent( xfs_fileoff_t split_fsb) { int whichfork = XFS_DATA_FORK; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); struct xfs_btree_cur *cur = NULL; struct xfs_bmbt_irec got; struct xfs_bmbt_irec new; /* split extent */ struct xfs_mount *mp = ip->i_mount; - struct xfs_ifork *ifp; xfs_fsblock_t gotblkcnt; /* new block count for got */ struct xfs_iext_cursor icur; int error = 0; int logflags = 0; int i = 0; - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { return -EFSCORRUPTED; } @@ -6011,7 +6000,6 @@ xfs_bmap_split_extent( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS)) { /* Read in all the extents */ error = xfs_iread_extents(tp, ip, whichfork); diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 295a59cf88407..d9c63f17d2dec 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -636,10 +636,7 @@ xfs_bmbt_change_owner( ASSERT(tp || buffer_list); ASSERT(!(tp && buffer_list)); - if (whichfork == XFS_DATA_FORK) - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_BTREE); - else - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE); + ASSERT(XFS_IFORK_PTR(ip, whichfork)->if_format == XFS_DINODE_FMT_BTREE); cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork); if (!cur) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index dd6fcaaea318a..612a9c5e41b1c 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -278,7 +278,7 @@ xfs_dir_createname( if (!inum) args->op_flags |= XFS_DA_OP_JUSTCHECK; - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_addname(args); goto out_free; } @@ -373,7 +373,7 @@ xfs_dir_lookup( args->op_flags |= XFS_DA_OP_CILOOKUP; lock_mode = xfs_ilock_data_map_shared(dp); - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_lookup(args); goto out_check_rval; } @@ -443,7 +443,7 @@ xfs_dir_removename( args->whichfork = XFS_DATA_FORK; args->trans = tp; - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_removename(args); goto out_free; } @@ -504,7 +504,7 @@ xfs_dir_replace( args->whichfork = XFS_DATA_FORK; args->trans = tp; - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_replace(args); goto out_free; } diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index 7b7f6fb2ea3b2..2463b5d734472 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -343,7 +343,7 @@ xfs_dir2_block_to_sf( */ ASSERT(dp->i_df.if_bytes == 0); xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size); - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; dp->i_d.di_size = size; logflags |= XFS_ILOG_DDATA; @@ -710,11 +710,11 @@ xfs_dir2_sf_verify( struct xfs_inode *ip) { struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); struct xfs_dir2_sf_hdr *sfp; struct xfs_dir2_sf_entry *sfep; struct xfs_dir2_sf_entry *next_sfep; char *endp; - struct xfs_ifork *ifp; xfs_ino_t ino; int i; int i8count; @@ -723,9 +723,8 @@ xfs_dir2_sf_verify( int error; uint8_t filetype; - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; size = ifp->if_bytes; @@ -827,9 +826,9 @@ xfs_dir2_sf_create( * If it's currently a zero-length extent file, * convert it to local format. */ - if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { + if (dp->i_df.if_format == XFS_DINODE_FMT_EXTENTS) { dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); dp->i_df.if_flags |= XFS_IFINLINE; } @@ -1027,7 +1026,7 @@ xfs_dir2_sf_replace_needblock( int newsize; struct xfs_dir2_sf_hdr *sfp; - if (dp->i_d.di_format != XFS_DINODE_FMT_LOCAL) + if (dp->i_df.if_format != XFS_DINODE_FMT_LOCAL) return false; sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data; diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index a374e2a81e764..ab555671e1543 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -225,7 +225,6 @@ xfs_inode_from_disk( be16_to_cpu(from->di_projid_lo); } - to->di_format = from->di_format; i_uid_write(inode, be32_to_cpu(from->di_uid)); i_gid_write(inode, be32_to_cpu(from->di_gid)); @@ -246,7 +245,6 @@ xfs_inode_from_disk( to->di_nblocks = be64_to_cpu(from->di_nblocks); to->di_extsize = be32_to_cpu(from->di_extsize); to->di_forkoff = from->di_forkoff; - to->di_aformat = from->di_aformat; to->di_dmevmask = be32_to_cpu(from->di_dmevmask); to->di_dmstate = be16_to_cpu(from->di_dmstate); to->di_flags = be16_to_cpu(from->di_flags); @@ -289,7 +287,7 @@ xfs_inode_to_disk( to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); to->di_onlink = 0; - to->di_format = from->di_format; + to->di_format = xfs_ifork_format(&ip->i_df); to->di_uid = cpu_to_be32(i_uid_read(inode)); to->di_gid = cpu_to_be32(i_gid_read(inode)); to->di_projid_lo = cpu_to_be16(from->di_projid & 0xffff); @@ -312,7 +310,7 @@ xfs_inode_to_disk( to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df)); to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp)); to->di_forkoff = from->di_forkoff; - to->di_aformat = from->di_aformat; + to->di_aformat = xfs_ifork_format(ip->i_afp); to->di_dmevmask = cpu_to_be32(from->di_dmevmask); to->di_dmstate = cpu_to_be16(from->di_dmstate); to->di_flags = cpu_to_be16(from->di_flags); diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h index fecccfb26463c..865ac493c72a2 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.h +++ b/fs/xfs/libxfs/xfs_inode_buf.h @@ -16,14 +16,12 @@ struct xfs_dinode; * format specific structures at the appropriate time. */ struct xfs_icdinode { - int8_t di_format; /* format of di_c data */ uint16_t di_flushiter; /* incremented on flush */ uint32_t di_projid; /* owner's project id */ xfs_fsize_t di_size; /* number of bytes in file */ xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ - int8_t di_aformat; /* format of attr fork's data */ uint32_t di_dmevmask; /* DMIG event mask */ uint16_t di_dmstate; /* DMIG state info */ uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 195da3552c5b5..6562f2bcd15cc 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -228,6 +228,7 @@ xfs_iformat_data_fork( struct inode *inode = VFS_I(ip); int error; + ip->i_df.if_format = dip->di_format; ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); switch (inode->i_mode & S_IFMT) { @@ -241,7 +242,7 @@ xfs_iformat_data_fork( case S_IFREG: case S_IFLNK: case S_IFDIR: - switch (dip->di_format) { + switch (ip->i_df.if_format) { case XFS_DINODE_FMT_LOCAL: error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, be64_to_cpu(dip->di_size)); @@ -283,9 +284,12 @@ xfs_iformat_attr_fork( int error = 0; ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); + ip->i_afp->if_format = dip->di_aformat; + if (unlikely(ip->i_afp->if_format == 0)) /* pre IRIX 6.2 file system */ + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); - switch (dip->di_aformat) { + switch (ip->i_afp->if_format) { case XFS_DINODE_FMT_LOCAL: error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, xfs_dfork_attr_shortform_size(dip)); @@ -508,7 +512,7 @@ xfs_idestroy_fork( * not local then we may or may not have an extents list, * so check and free it up if we do. */ - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { if (ifp->if_u1.if_data != NULL) { kmem_free(ifp->if_u1.if_data); ifp->if_u1.if_data = NULL; @@ -605,7 +609,7 @@ xfs_iflush_fork( } cp = XFS_DFORK_PTR(dip, whichfork); mp = ip->i_mount; - switch (XFS_IFORK_FORMAT(ip, whichfork)) { + switch (ifp->if_format) { case XFS_DINODE_FMT_LOCAL: if ((iip->ili_fields & dataflag[whichfork]) && (ifp->if_bytes > 0)) { @@ -678,7 +682,7 @@ xfs_ifork_init_cow( ip->i_cowfp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); ip->i_cowfp->if_flags = XFS_IFEXTENTS; - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; + ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS; } /* Verify the inline contents of the data fork of an inode. */ diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index a69d425fe68df..d849cca103edd 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -23,6 +23,7 @@ struct xfs_ifork { } if_u1; short if_broot_bytes; /* bytes allocated for root */ unsigned char if_flags; /* per-fork flags */ + int8_t if_format; /* format of this fork */ xfs_extnum_t if_nextents; /* # of extents in this fork */ }; @@ -56,24 +57,14 @@ struct xfs_ifork { ((w) == XFS_ATTR_FORK ? \ XFS_IFORK_ASIZE(ip) : \ 0)) -#define XFS_IFORK_FORMAT(ip,w) \ - ((w) == XFS_DATA_FORK ? \ - (ip)->i_d.di_format : \ - ((w) == XFS_ATTR_FORK ? \ - (ip)->i_d.di_aformat : \ - (ip)->i_cformat)) -#define XFS_IFORK_FMT_SET(ip,w,n) \ - ((w) == XFS_DATA_FORK ? \ - ((ip)->i_d.di_format = (n)) : \ - ((w) == XFS_ATTR_FORK ? \ - ((ip)->i_d.di_aformat = (n)) : \ - ((ip)->i_cformat = (n)))) #define XFS_IFORK_MAXEXT(ip, w) \ (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) -#define xfs_ifork_has_extents(ip, w) \ - (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ - XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) +static inline bool xfs_ifork_has_extents(struct xfs_ifork *ifp) +{ + return ifp->if_format == XFS_DINODE_FMT_EXTENTS || + ifp->if_format == XFS_DINODE_FMT_BTREE; +} static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) { @@ -82,6 +73,13 @@ static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) return ifp->if_nextents; } +static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp) +{ + if (!ifp) + return XFS_DINODE_FMT_EXTENTS; + return ifp->if_format; +} + struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c index 3b8260ca7d1b8..594bc447a7dd2 100644 --- a/fs/xfs/libxfs/xfs_symlink_remote.c +++ b/fs/xfs/libxfs/xfs_symlink_remote.c @@ -204,16 +204,12 @@ xfs_failaddr_t xfs_symlink_shortform_verify( struct xfs_inode *ip) { - char *sfp; - char *endp; - struct xfs_ifork *ifp; - int size; - - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); - sfp = (char *)ifp->if_u1.if_data; - size = ifp->if_bytes; - endp = sfp + size; + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); + char *sfp = (char *)ifp->if_u1.if_data; + int size = ifp->if_bytes; + char *endp = sfp + size; + + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); /* * Zero length symlinks should never occur in memory as they are diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 157f72efec5e9..dfa1533b4edfc 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -598,7 +598,7 @@ xchk_bmap_check_rmaps( size = 0; break; } - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && + if (ifp->if_format != XFS_DINODE_FMT_BTREE && (size == 0 || ifp->if_nextents > 0)) return 0; @@ -664,7 +664,7 @@ xchk_bmap( } /* Check the fork values */ - switch (XFS_IFORK_FORMAT(ip, whichfork)) { + switch (ifp->if_format) { case XFS_DINODE_FMT_UUID: case XFS_DINODE_FMT_DEV: case XFS_DINODE_FMT_LOCAL: diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c index 9a2e27ac13003..44b15015021f3 100644 --- a/fs/xfs/scrub/dabtree.c +++ b/fs/xfs/scrub/dabtree.c @@ -468,7 +468,7 @@ xchk_da_btree( int error; /* Skip short format data structures; no btree to scan. */ - if (!xfs_ifork_has_extents(sc->ip, whichfork)) + if (!xfs_ifork_has_extents(XFS_IFORK_PTR(sc->ip, whichfork))) return 0; /* Set up initial da state. */ diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index fe2a6e030c8a0..7c432997edade 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -635,7 +635,7 @@ xchk_directory_blocks( { struct xfs_bmbt_irec got; struct xfs_da_args args; - struct xfs_ifork *ifp; + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); struct xfs_mount *mp = sc->mp; xfs_fileoff_t leaf_lblk; xfs_fileoff_t free_lblk; @@ -647,11 +647,10 @@ xchk_directory_blocks( int error; /* Ignore local format directories. */ - if (sc->ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && - sc->ip->i_d.di_format != XFS_DINODE_FMT_BTREE) + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS && + ifp->if_format != XFS_DINODE_FMT_BTREE) return 0; - ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); lblk = XFS_B_TO_FSB(mp, XFS_DIR2_DATA_OFFSET); leaf_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_LEAF_OFFSET); free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET); diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 9d9cebf187268..2834cbf1212e5 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -382,7 +382,7 @@ xfs_map_blocks( */ retry: xfs_ilock(ip, XFS_ILOCK_SHARED); - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || (ip->i_df.if_flags & XFS_IFEXTENTS)); /* diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index c42f90e16b4fa..00ffc46c0bf71 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -367,7 +367,7 @@ xfs_attr_inactive( * removal below. */ if (xfs_inode_hasattr(dp) && - dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { + dp->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { error = xfs_attr3_root_inactive(&trans, dp); if (error) goto out_cancel; diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 5ff1d929d3b5f..e380bd1a9bfc9 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -512,9 +512,9 @@ xfs_attr_list_ilocked( */ if (!xfs_inode_hasattr(dp)) return 0; - else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) return xfs_attr_shortform_list(context); - else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) + if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) return xfs_attr_leaf_list(context); return xfs_attr_node_list(context); } diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 4f277a6253b8d..5e32c3cf8e8c1 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -223,7 +223,7 @@ xfs_bmap_count_blocks( if (!ifp) return 0; - switch (XFS_IFORK_FORMAT(ip, whichfork)) { + switch (ifp->if_format) { case XFS_DINODE_FMT_BTREE: if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(tp, ip, whichfork); @@ -449,7 +449,7 @@ xfs_getbmap( break; } - switch (XFS_IFORK_FORMAT(ip, whichfork)) { + switch (ifp->if_format) { case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_BTREE: break; @@ -1210,17 +1210,19 @@ xfs_swap_extents_check_format( struct xfs_inode *ip, /* target inode */ struct xfs_inode *tip) /* tmp inode */ { + struct xfs_ifork *ifp = &ip->i_df; + struct xfs_ifork *tifp = &tip->i_df; /* Should never get a local format */ - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || - tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) + if (ifp->if_format == XFS_DINODE_FMT_LOCAL || + tifp->if_format == XFS_DINODE_FMT_LOCAL) return -EINVAL; /* * if the target inode has less extents that then temporary inode then * why did userspace call us? */ - if (ip->i_df.if_nextents < tip->i_df.if_nextents) + if (ifp->if_nextents < tifp->if_nextents) return -EINVAL; /* @@ -1235,18 +1237,18 @@ xfs_swap_extents_check_format( * form then we will end up with the target inode in the wrong format * as we already know there are less extents in the temp inode. */ - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - tip->i_d.di_format == XFS_DINODE_FMT_BTREE) + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && + tifp->if_format == XFS_DINODE_FMT_BTREE) return -EINVAL; /* Check temp in extent form to max in target */ - if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) + if (tifp->if_format == XFS_DINODE_FMT_EXTENTS && + tifp->if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) return -EINVAL; /* Check target in extent form to max in temp */ - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && - ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && + ifp->if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) return -EINVAL; /* @@ -1258,22 +1260,20 @@ xfs_swap_extents_check_format( * (a common defrag case) which will occur when the temp inode is in * extent format... */ - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) { + if (tifp->if_format == XFS_DINODE_FMT_BTREE) { if (XFS_IFORK_Q(ip) && - XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) + XFS_BMAP_BMDR_SPACE(tifp->if_broot) > XFS_IFORK_BOFF(ip)) return -EINVAL; - if (tip->i_df.if_nextents <= - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) + if (tifp->if_nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) return -EINVAL; } /* Reciprocal target->temp btree format checks */ - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { + if (ifp->if_format == XFS_DINODE_FMT_BTREE) { if (XFS_IFORK_Q(tip) && XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) return -EINVAL; - if (ip->i_df.if_nextents <= - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) + if (ifp->if_nextents <= XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) return -EINVAL; } @@ -1426,14 +1426,14 @@ xfs_swap_extent_forks( * Count the number of extended attribute blocks */ if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && - ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { + ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, &aforkblks); if (error) return error; } if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && - tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { + tip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, &taforkblks); if (error) @@ -1448,9 +1448,9 @@ xfs_swap_extent_forks( * bmbt scan as the last step. */ if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) { - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) (*target_log_flags) |= XFS_ILOG_DOWNER; - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) + if (tip->i_df.if_format == XFS_DINODE_FMT_BTREE) (*src_log_flags) |= XFS_ILOG_DOWNER; } @@ -1466,8 +1466,6 @@ xfs_swap_extent_forks( ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; - swap(ip->i_d.di_format, tip->i_d.di_format); - /* * The extents in the source inode could still contain speculative * preallocation beyond EOF (e.g. the file is open but not modified @@ -1481,7 +1479,7 @@ xfs_swap_extent_forks( tip->i_delayed_blks = ip->i_delayed_blks; ip->i_delayed_blks = 0; - switch (ip->i_d.di_format) { + switch (ip->i_df.if_format) { case XFS_DINODE_FMT_EXTENTS: (*src_log_flags) |= XFS_ILOG_DEXT; break; @@ -1492,7 +1490,7 @@ xfs_swap_extent_forks( break; } - switch (tip->i_d.di_format) { + switch (tip->i_df.if_format) { case XFS_DINODE_FMT_EXTENTS: (*target_log_flags) |= XFS_ILOG_DEXT; break; @@ -1714,8 +1712,10 @@ xfs_swap_extents( /* Swap the cow forks. */ if (xfs_sb_version_hasreflink(&mp->m_sb)) { - ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); - ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); + ASSERT(!ip->i_cowfp || + ip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); + ASSERT(!tip->i_cowfp || + tip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); swap(ip->i_cowfp, tip->i_cowfp); diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 871ec22c9aee9..66deddd5e2969 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -524,7 +524,7 @@ xfs_readdir( args.geo = dp->i_mount->m_dir_geo; args.trans = tp; - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_getdents(&args, ctx); else if ((rval = xfs_dir2_isblock(&args, &v))) ; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 791d5d5e318cf..c09b3e9eab1da 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -63,7 +63,6 @@ xfs_inode_alloc( memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); ip->i_afp = NULL; ip->i_cowfp = NULL; - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; memset(&ip->i_df, 0, sizeof(ip->i_df)); ip->i_flags = 0; ip->i_delayed_blks = 0; diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1677c4e7207ed..64f5f9a440aed 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -112,7 +112,7 @@ xfs_ilock_data_map_shared( { uint lock_mode = XFS_ILOCK_SHARED; - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE && (ip->i_df.if_flags & XFS_IFEXTENTS) == 0) lock_mode = XFS_ILOCK_EXCL; xfs_ilock(ip, lock_mode); @@ -125,7 +125,8 @@ xfs_ilock_attr_map_shared( { uint lock_mode = XFS_ILOCK_SHARED; - if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE && + if (ip->i_afp && + ip->i_afp->if_format == XFS_DINODE_FMT_BTREE && (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0) lock_mode = XFS_ILOCK_EXCL; xfs_ilock(ip, lock_mode); @@ -851,7 +852,7 @@ xfs_ialloc( case S_IFCHR: case S_IFBLK: case S_IFSOCK: - ip->i_d.di_format = XFS_DINODE_FMT_DEV; + ip->i_df.if_format = XFS_DINODE_FMT_DEV; ip->i_df.if_flags = 0; flags |= XFS_ILOG_DEV; break; @@ -907,7 +908,7 @@ xfs_ialloc( } /* FALLTHROUGH */ case S_IFLNK: - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; ip->i_df.if_flags = XFS_IFEXTENTS; ip->i_df.if_bytes = 0; ip->i_df.if_u1.if_root = NULL; @@ -915,10 +916,6 @@ xfs_ialloc( default: ASSERT(0); } - /* - * Attribute fork settings for new inode. - */ - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; /* * Log the new values stuffed into the inode. @@ -2749,7 +2746,7 @@ xfs_ifree( * data fork to extents format. Note that the attr fork data has * already been freed by xfs_attr_inactive. */ - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) { kmem_free(ip->i_df.if_u1.if_data); ip->i_df.if_u1.if_data = NULL; ip->i_df.if_bytes = 0; @@ -2760,8 +2757,7 @@ xfs_ifree( ip->i_d.di_flags2 = 0; ip->i_d.di_dmevmask = 0; ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; /* Don't attempt to replay owner changes for a deleted inode */ ip->i_itemp->ili_fields &= ~(XFS_ILOG_AOWNER|XFS_ILOG_DOWNER); @@ -3624,7 +3620,7 @@ xfs_iflush( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(xfs_isiflocked(ip)); - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); *bpp = NULL; @@ -3706,7 +3702,7 @@ xfs_iflush_int( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(xfs_isiflocked(ip)); - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); ASSERT(iip != NULL && iip->ili_fields != 0); @@ -3728,8 +3724,8 @@ xfs_iflush_int( } if (S_ISREG(VFS_I(ip)->i_mode)) { if (XFS_TEST_ERROR( - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && + ip->i_df.if_format != XFS_DINODE_FMT_BTREE, mp, XFS_ERRTAG_IFLUSH_3)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, "%s: Bad regular inode %Lu, ptr "PTR_FMT, @@ -3738,9 +3734,9 @@ xfs_iflush_int( } } else if (S_ISDIR(VFS_I(ip)->i_mode)) { if (XFS_TEST_ERROR( - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && - (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL), + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && + ip->i_df.if_format != XFS_DINODE_FMT_BTREE && + ip->i_df.if_format != XFS_DINODE_FMT_LOCAL, mp, XFS_ERRTAG_IFLUSH_4)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, "%s: Bad directory inode %Lu, ptr "PTR_FMT, @@ -3782,10 +3778,10 @@ xfs_iflush_int( * If there are inline format data / attr forks attached to this inode, * make sure they are not corrupt. */ - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL && xfs_ifork_verify_local_data(ip)) goto flush_out; - if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL && + if (ip->i_afp && ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL && xfs_ifork_verify_local_attr(ip)) goto flush_out; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 24dae63ba16c0..dadcf19458960 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -57,8 +57,6 @@ typedef struct xfs_inode { struct xfs_icdinode i_d; /* most of ondisk inode */ - unsigned int i_cformat; /* format of cow fork */ - /* VFS inode */ struct inode i_vnode; /* embedded VFS inode */ diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 401ba26aeed7b..ba47bf65b772b 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -36,7 +36,7 @@ xfs_inode_item_data_fork_size( { struct xfs_inode *ip = iip->ili_inode; - switch (ip->i_d.di_format) { + switch (ip->i_df.if_format) { case XFS_DINODE_FMT_EXTENTS: if ((iip->ili_fields & XFS_ILOG_DEXT) && ip->i_df.if_nextents > 0 && @@ -77,7 +77,7 @@ xfs_inode_item_attr_fork_size( { struct xfs_inode *ip = iip->ili_inode; - switch (ip->i_d.di_aformat) { + switch (ip->i_afp->if_format) { case XFS_DINODE_FMT_EXTENTS: if ((iip->ili_fields & XFS_ILOG_AEXT) && ip->i_afp->if_nextents > 0 && @@ -142,7 +142,7 @@ xfs_inode_item_format_data_fork( struct xfs_inode *ip = iip->ili_inode; size_t data_bytes; - switch (ip->i_d.di_format) { + switch (ip->i_df.if_format) { case XFS_DINODE_FMT_EXTENTS: iip->ili_fields &= ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); @@ -227,7 +227,7 @@ xfs_inode_item_format_attr_fork( struct xfs_inode *ip = iip->ili_inode; size_t data_bytes; - switch (ip->i_d.di_aformat) { + switch (ip->i_afp->if_format) { case XFS_DINODE_FMT_EXTENTS: iip->ili_fields &= ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); @@ -305,7 +305,7 @@ xfs_inode_to_log_dinode( struct inode *inode = VFS_I(ip); to->di_magic = XFS_DINODE_MAGIC; - to->di_format = from->di_format; + to->di_format = xfs_ifork_format(&ip->i_df); to->di_uid = i_uid_read(inode); to->di_gid = i_gid_read(inode); to->di_projid_lo = from->di_projid & 0xffff; @@ -329,7 +329,7 @@ xfs_inode_to_log_dinode( to->di_nextents = xfs_ifork_nextents(&ip->i_df); to->di_anextents = xfs_ifork_nextents(ip->i_afp); to->di_forkoff = from->di_forkoff; - to->di_aformat = from->di_aformat; + to->di_aformat = xfs_ifork_format(ip->i_afp); to->di_dmevmask = from->di_dmevmask; to->di_dmstate = from->di_dmstate; to->di_flags = from->di_flags; diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index b4fd918749e5f..6ae3a2457777a 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -856,7 +856,7 @@ xfs_buffered_write_iomap_begin( xfs_ilock(ip, XFS_ILOCK_EXCL); - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, XFS_DATA_FORK)) || + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(&ip->i_df)) || XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { error = -EFSCORRUPTED; goto out_unlock; @@ -1263,7 +1263,7 @@ xfs_xattr_iomap_begin( goto out_unlock; } - ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); + ASSERT(ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL); error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, &nimaps, XFS_BMAPI_ATTRFORK); out_unlock: diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 80da86c5703fb..16ca97a7ff00f 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -115,7 +115,7 @@ xfs_bulkstat_one_int( buf->bs_cowextsize_blks = dic->di_cowextsize; } - switch (dic->di_format) { + switch (ip->i_df.if_format) { case XFS_DINODE_FMT_DEV: buf->bs_rdev = sysv_encode_dev(inode->i_rdev); buf->bs_blksize = BLKDEV_IOSIZE; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 8cf2fcb509c12..8e88a7ca387ea 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -251,7 +251,7 @@ xfs_symlink( xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen); ip->i_d.di_size = pathlen; - ip->i_d.di_format = XFS_DINODE_FMT_LOCAL; + ip->i_df.if_format = XFS_DINODE_FMT_LOCAL; xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE); } else { int offset; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index ba2ab69e1fc7d..460136628a795 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1897,7 +1897,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, __entry->dev = VFS_I(ip)->i_sb->s_dev; __entry->which = which; __entry->ino = ip->i_ino; - __entry->format = ip->i_d.di_format; + __entry->format = ip->i_df.if_format; __entry->nex = ip->i_df.if_nextents; __entry->broot_size = ip->i_df.if_broot_bytes; __entry->fork_off = XFS_IFORK_BOFF(ip); -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-10 7:24 ` [PATCH 5/6] xfs: move the fork format " Christoph Hellwig @ 2020-05-12 9:37 ` Chandan Babu R 2020-05-12 18:53 ` Brian Foster 2020-05-14 21:25 ` Darrick J. Wong 2 siblings, 0 replies; 41+ messages in thread From: Chandan Babu R @ 2020-05-12 9:37 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sunday 10 May 2020 12:54:03 PM IST Christoph Hellwig wrote: > Both the data and attr fork have a format that is stored in the legacy > idinode. Move it into the xfs_ifork structure instead, where it uses > up padding. > The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/libxfs/xfs_attr.c | 12 +-- > fs/xfs/libxfs/xfs_attr_leaf.c | 32 ++++---- > fs/xfs/libxfs/xfs_bmap.c | 120 +++++++++++++---------------- > fs/xfs/libxfs/xfs_bmap_btree.c | 5 +- > fs/xfs/libxfs/xfs_dir2.c | 8 +- > fs/xfs/libxfs/xfs_dir2_sf.c | 13 ++-- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +- > fs/xfs/libxfs/xfs_inode_buf.h | 2 - > fs/xfs/libxfs/xfs_inode_fork.c | 14 ++-- > fs/xfs/libxfs/xfs_inode_fork.h | 28 ++++--- > fs/xfs/libxfs/xfs_symlink_remote.c | 16 ++-- > fs/xfs/scrub/bmap.c | 4 +- > fs/xfs/scrub/dabtree.c | 2 +- > fs/xfs/scrub/dir.c | 7 +- > fs/xfs/xfs_aops.c | 2 +- > fs/xfs/xfs_attr_inactive.c | 2 +- > fs/xfs/xfs_attr_list.c | 4 +- > fs/xfs/xfs_bmap_util.c | 56 +++++++------- > fs/xfs/xfs_dir2_readdir.c | 2 +- > fs/xfs/xfs_icache.c | 1 - > fs/xfs/xfs_inode.c | 36 ++++----- > fs/xfs/xfs_inode.h | 2 - > fs/xfs/xfs_inode_item.c | 12 +-- > fs/xfs/xfs_iomap.c | 4 +- > fs/xfs/xfs_itable.c | 2 +- > fs/xfs/xfs_symlink.c | 2 +- > fs/xfs/xfs_trace.h | 2 +- > 27 files changed, 181 insertions(+), 215 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c > index 1b01675e9c80b..3b1bd6e112f89 100644 > --- a/fs/xfs/libxfs/xfs_attr.c > +++ b/fs/xfs/libxfs/xfs_attr.c > @@ -61,7 +61,7 @@ xfs_inode_hasattr( > struct xfs_inode *ip) > { > if (!XFS_IFORK_Q(ip) || > - (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > + (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && > ip->i_afp->if_nextents == 0)) > return 0; > return 1; > @@ -84,7 +84,7 @@ xfs_attr_get_ilocked( > if (!xfs_inode_hasattr(args->dp)) > return -ENOATTR; > > - if (args->dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) > + if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) > return xfs_attr_shortform_getvalue(args); > if (xfs_bmap_one_block(args->dp, XFS_ATTR_FORK)) > return xfs_attr_leaf_get(args); > @@ -212,14 +212,14 @@ xfs_attr_set_args( > * If the attribute list is non-existent or a shortform list, > * upgrade it to a single-leaf-block attribute list. > */ > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL || > - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL || > + (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && > dp->i_afp->if_nextents == 0)) { > > /* > * Build initial attribute list (if required). > */ > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) > + if (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS) > xfs_attr_shortform_create(args); > > /* > @@ -272,7 +272,7 @@ xfs_attr_remove_args( > > if (!xfs_inode_hasattr(dp)) { > error = -ENOATTR; > - } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { > + } else if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) { > ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); > error = xfs_attr_shortform_remove(args); > } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index 64b172180c42c..d7f3173ce3c31 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -539,7 +539,7 @@ xfs_attr_shortform_bytesfit( > /* rounded down */ > offset = (XFS_LITINO(mp) - bytes) >> 3; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_DEV) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) { > minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; > return (offset >= minforkoff) ? minforkoff : 0; > } > @@ -567,7 +567,7 @@ xfs_attr_shortform_bytesfit( > > dsize = dp->i_df.if_bytes; > > - switch (dp->i_d.di_format) { > + switch (dp->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > /* > * If there is no attr fork and the data fork is extents, > @@ -636,22 +636,19 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) > * Create the initial contents of a shortform attribute list. > */ > void > -xfs_attr_shortform_create(xfs_da_args_t *args) > +xfs_attr_shortform_create( > + struct xfs_da_args *args) > { > - xfs_attr_sf_hdr_t *hdr; > - xfs_inode_t *dp; > - struct xfs_ifork *ifp; > + struct xfs_inode *dp = args->dp; > + struct xfs_ifork *ifp = dp->i_afp; > + struct xfs_attr_sf_hdr *hdr; > > trace_xfs_attr_sf_create(args); > > - dp = args->dp; > - ASSERT(dp != NULL); > - ifp = dp->i_afp; > - ASSERT(ifp != NULL); > ASSERT(ifp->if_bytes == 0); > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) { > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS) { > ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */ > - dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL; > + ifp->if_format = XFS_DINODE_FMT_LOCAL; > ifp->if_flags |= XFS_IFINLINE; > } else { > ASSERT(ifp->if_flags & XFS_IFINLINE); > @@ -721,7 +718,6 @@ xfs_attr_fork_remove( > { > xfs_idestroy_fork(ip, XFS_ATTR_FORK); > ip->i_d.di_forkoff = 0; > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > ASSERT(ip->i_afp == NULL); > > @@ -774,7 +770,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) > totsize -= size; > if (totsize == sizeof(xfs_attr_sf_hdr_t) && > (mp->m_flags & XFS_MOUNT_ATTR2) && > - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && > + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && > !(args->op_flags & XFS_DA_OP_ADDNAME)) { > xfs_attr_fork_remove(dp, args->trans); > } else { > @@ -784,7 +780,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) > ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || > (args->op_flags & XFS_DA_OP_ADDNAME) || > !(mp->m_flags & XFS_MOUNT_ATTR2) || > - dp->i_d.di_format == XFS_DINODE_FMT_BTREE); > + dp->i_df.if_format == XFS_DINODE_FMT_BTREE); > xfs_trans_log_inode(args->trans, dp, > XFS_ILOG_CORE | XFS_ILOG_ADATA); > } > @@ -961,7 +957,7 @@ xfs_attr_shortform_allfit( > + be16_to_cpu(name_loc->valuelen); > } > if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && > - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && > + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && > (bytes == sizeof(struct xfs_attr_sf_hdr))) > return -1; > return xfs_attr_shortform_bytesfit(dp, bytes); > @@ -980,7 +976,7 @@ xfs_attr_shortform_verify( > int i; > int64_t size; > > - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL); > + ASSERT(ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL); > ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK); > sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data; > size = ifp->if_bytes; > @@ -1084,7 +1080,7 @@ xfs_attr3_leaf_to_shortform( > > if (forkoff == -1) { > ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); > - ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); > + ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE); > xfs_attr_fork_remove(dp, args->trans); > goto out; > } > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index c1136be49abeb..edc63dba007f4 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -123,7 +123,7 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > return whichfork != XFS_COW_FORK && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > + ifp->if_format == XFS_DINODE_FMT_EXTENTS && > ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork); > } > > @@ -135,7 +135,7 @@ static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > return whichfork != XFS_COW_FORK && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && > + ifp->if_format == XFS_DINODE_FMT_BTREE && > ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork); > } > > @@ -215,8 +215,8 @@ xfs_bmap_forkoff_reset( > int whichfork) > { > if (whichfork == XFS_ATTR_FORK && > - ip->i_d.di_format != XFS_DINODE_FMT_DEV && > - ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { > + ip->i_df.if_format != XFS_DINODE_FMT_DEV && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE) { > uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; > > if (dfl_forkoff > ip->i_d.di_forkoff) > @@ -317,31 +317,28 @@ xfs_bmap_check_leaf_extents( > xfs_inode_t *ip, /* incore inode pointer */ > int whichfork) /* data or attr fork */ > { > + struct xfs_mount *mp = ip->i_mount; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_block *block; /* current btree block */ > xfs_fsblock_t bno; /* block # of "block" */ > xfs_buf_t *bp; /* buffer for "block" */ > int error; /* error return value */ > xfs_extnum_t i=0, j; /* index into the extents list */ > - struct xfs_ifork *ifp; /* fork structure */ > int level; /* btree level, for checking */ > - xfs_mount_t *mp; /* file system mount structure */ > __be64 *pp; /* pointer to block address */ > xfs_bmbt_rec_t *ep; /* pointer to current extent */ > xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */ > xfs_bmbt_rec_t *nextp; /* pointer to next extent */ > int bp_release = 0; > > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { > + if (ifp->if_format != XFS_DINODE_FMT_BTREE) > return; > - } > > /* skip large extent count inodes */ > if (ip->i_df.if_nextents > 10000) > return; > > bno = NULLFSBLOCK; > - mp = ip->i_mount; > - ifp = XFS_IFORK_PTR(ip, whichfork); > block = ifp->if_broot; > /* > * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. > @@ -606,7 +603,7 @@ xfs_bmap_btree_to_extents( > ASSERT(cur); > ASSERT(whichfork != XFS_COW_FORK); > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); > ASSERT(be16_to_cpu(rblock->bb_level) == 1); > ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); > ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); > @@ -634,7 +631,7 @@ xfs_bmap_btree_to_extents( > xfs_iroot_realloc(ip, -1, whichfork); > ASSERT(ifp->if_broot == NULL); > ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork); > return 0; > } > @@ -670,7 +667,7 @@ xfs_bmap_extents_to_btree( > mp = ip->i_mount; > ASSERT(whichfork != XFS_COW_FORK); > ifp = XFS_IFORK_PTR(ip, whichfork); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS); > > /* > * Make space in the inode incore. This needs to be undone if we fail > @@ -694,7 +691,7 @@ xfs_bmap_extents_to_btree( > /* > * Convert to a btree with two levels, one record in root. > */ > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); > + ifp->if_format = XFS_DINODE_FMT_BTREE; > memset(&args, 0, sizeof(args)); > args.tp = tp; > args.mp = mp; > @@ -780,7 +777,7 @@ xfs_bmap_extents_to_btree( > xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); > out_root_realloc: > xfs_iroot_realloc(ip, -1, whichfork); > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > ASSERT(ifp->if_broot == NULL); > xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); > > @@ -802,7 +799,7 @@ xfs_bmap_local_to_extents_empty( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > ASSERT(whichfork != XFS_COW_FORK); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > ASSERT(ifp->if_bytes == 0); > ASSERT(ifp->if_nextents == 0); > > @@ -811,7 +808,7 @@ xfs_bmap_local_to_extents_empty( > ifp->if_flags |= XFS_IFEXTENTS; > ifp->if_u1.if_root = NULL; > ifp->if_height = 0; > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > } > > @@ -842,7 +839,7 @@ xfs_bmap_local_to_extents( > */ > ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK)); > ifp = XFS_IFORK_PTR(ip, whichfork); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > if (!ifp->if_bytes) { > xfs_bmap_local_to_extents_empty(tp, ip, whichfork); > @@ -1036,7 +1033,7 @@ xfs_bmap_set_attrforkoff( > int size, > int *version) > { > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_DEV: > ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; > break; > @@ -1094,13 +1091,6 @@ xfs_bmap_add_attrfork( > goto trans_cancel; > if (XFS_IFORK_Q(ip)) > goto trans_cancel; > - if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { > - /* > - * For inodes coming from pre-6.2 filesystems. > - */ > - ASSERT(ip->i_d.di_aformat == 0); > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > - } > > xfs_trans_ijoin(tp, ip, 0); > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > @@ -1109,9 +1099,10 @@ xfs_bmap_add_attrfork( > goto trans_cancel; > ASSERT(ip->i_afp == NULL); > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, 0); > + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_afp->if_flags = XFS_IFEXTENTS; > logflags = 0; > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_bmap_add_attrfork_local(tp, ip, &logflags); > break; > @@ -1237,9 +1228,7 @@ xfs_iread_extents( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > - if (XFS_IS_CORRUPT(mp, > - XFS_IFORK_FORMAT(ip, whichfork) != > - XFS_DINODE_FMT_BTREE)) { > + if (XFS_IS_CORRUPT(mp, ifp->if_format != XFS_DINODE_FMT_BTREE)) { > error = -EFSCORRUPTED; > goto out; > } > @@ -1287,14 +1276,13 @@ xfs_bmap_first_unused( > xfs_fileoff_t lowest, max; > int error; > > - ASSERT(xfs_ifork_has_extents(ip, whichfork) || > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > - > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > *first_unused = 0; > return 0; > } > > + ASSERT(xfs_ifork_has_extents(ifp)); > + > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > error = xfs_iread_extents(tp, ip, whichfork); > if (error) > @@ -1335,7 +1323,7 @@ xfs_bmap_last_before( > struct xfs_iext_cursor icur; > int error; > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_LOCAL: > *last_block = 0; > return 0; > @@ -1434,16 +1422,17 @@ xfs_bmap_last_offset( > xfs_fileoff_t *last_block, > int whichfork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_bmbt_irec rec; > int is_empty; > int error; > > *last_block = 0; > > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) > return 0; > > - if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ip, whichfork))) > + if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp))) > return -EFSCORRUPTED; > > error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); > @@ -1475,7 +1464,7 @@ xfs_bmap_one_block( > #endif /* !DEBUG */ > if (ifp->if_nextents != 1) > return 0; > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS) > return 0; > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > xfs_iext_first(ifp, &icur); > @@ -3895,10 +3884,9 @@ xfs_bmapi_read( > if (WARN_ON_ONCE(!ifp)) > return -EFSCORRUPTED; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > - XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) > return -EFSCORRUPTED; > - } > > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > @@ -4281,11 +4269,13 @@ xfs_bmapi_minleft( > struct xfs_inode *ip, > int fork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, fork); > + > if (tp && tp->t_firstblock != NULLFSBLOCK) > return 0; > - if (XFS_IFORK_FORMAT(ip, fork) != XFS_DINODE_FMT_BTREE) > + if (ifp->if_format != XFS_DINODE_FMT_BTREE) > return 1; > - return be16_to_cpu(XFS_IFORK_PTR(ip, fork)->if_broot->bb_level) + 1; > + return be16_to_cpu(ifp->if_broot->bb_level) + 1; > } > > /* > @@ -4300,11 +4290,13 @@ xfs_bmapi_finish( > int whichfork, > int error) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); > + > if ((bma->logflags & xfs_ilog_fext(whichfork)) && > - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + ifp->if_format != XFS_DINODE_FMT_EXTENTS) > bma->logflags &= ~xfs_ilog_fext(whichfork); > else if ((bma->logflags & xfs_ilog_fbroot(whichfork)) && > - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_BTREE) > + ifp->if_format != XFS_DINODE_FMT_BTREE) > bma->logflags &= ~xfs_ilog_fbroot(whichfork); > > if (bma->logflags) > @@ -4336,13 +4328,13 @@ xfs_bmapi_write( > .total = total, > }; > struct xfs_mount *mp = ip->i_mount; > - struct xfs_ifork *ifp; > + int whichfork = xfs_bmapi_whichfork(flags); > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > xfs_fileoff_t end; /* end of mapped file region */ > bool eof = false; /* after the end of extents */ > int error; /* error return */ > int n; /* current extent index */ > xfs_fileoff_t obno; /* old block number (offset) */ > - int whichfork; /* data or attr fork */ > > #ifdef DEBUG > xfs_fileoff_t orig_bno; /* original block number value */ > @@ -4357,13 +4349,12 @@ xfs_bmapi_write( > orig_mval = mval; > orig_nmap = *nmap; > #endif > - whichfork = xfs_bmapi_whichfork(flags); > > ASSERT(*nmap >= 1); > ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); > ASSERT(tp != NULL); > ASSERT(len > 0); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL); > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > ASSERT(!(flags & XFS_BMAPI_REMAP)); > > @@ -4379,7 +4370,7 @@ xfs_bmapi_write( > ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != > (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -4387,8 +4378,6 @@ xfs_bmapi_write( > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > > - ifp = XFS_IFORK_PTR(ip, whichfork); > - > XFS_STATS_INC(mp, xs_blk_mapw); > > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > @@ -4498,7 +4487,7 @@ xfs_bmapi_write( > if (error) > goto error0; > > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || > + ASSERT(ifp->if_format != XFS_DINODE_FMT_BTREE || > ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork)); > xfs_bmapi_finish(&bma, whichfork, 0); > xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, > @@ -4645,7 +4634,7 @@ xfs_bmapi_remap( > ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) != > (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -4689,9 +4678,9 @@ xfs_bmapi_remap( > error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, whichfork); > > error0: > - if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) > + if (ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS) > logflags &= ~XFS_ILOG_DEXT; > - else if (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) > + else if (ip->i_df.if_format != XFS_DINODE_FMT_BTREE) > logflags &= ~XFS_ILOG_DBROOT; > > if (logflags) > @@ -5041,7 +5030,7 @@ xfs_bmap_del_extent_real( > * conversion to btree format, since the transaction will be dirty then. > */ > if (tp->t_blk_res == 0 && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > + ifp->if_format == XFS_DINODE_FMT_EXTENTS && > ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) && > del->br_startoff > got.br_startoff && del_endoff < got_endoff) > return -ENOSPC; > @@ -5284,7 +5273,7 @@ __xfs_bunmapi( > whichfork = xfs_bmapi_whichfork(flags); > ASSERT(whichfork != XFS_COW_FORK); > ifp = XFS_IFORK_PTR(ip, whichfork); > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork))) > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp))) > return -EFSCORRUPTED; > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > @@ -5322,7 +5311,7 @@ __xfs_bunmapi( > > logflags = 0; > if (ifp->if_flags & XFS_IFBROOT) { > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); > cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); > cur->bc_ino.flags = 0; > } else > @@ -5567,10 +5556,10 @@ __xfs_bunmapi( > * logging the extent records if we've converted to btree format. > */ > if ((logflags & xfs_ilog_fext(whichfork)) && > - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + ifp->if_format != XFS_DINODE_FMT_EXTENTS) > logflags &= ~xfs_ilog_fext(whichfork); > else if ((logflags & xfs_ilog_fbroot(whichfork)) && > - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) > + ifp->if_format != XFS_DINODE_FMT_BTREE) > logflags &= ~xfs_ilog_fbroot(whichfork); > /* > * Log inode even in the error case, if the transaction > @@ -5781,7 +5770,7 @@ xfs_bmap_collapse_extents( > int error = 0; > int logflags = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -5898,7 +5887,7 @@ xfs_bmap_insert_extents( > int error = 0; > int logflags = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -5992,18 +5981,18 @@ xfs_bmap_split_extent( > xfs_fileoff_t split_fsb) > { > int whichfork = XFS_DATA_FORK; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_cur *cur = NULL; > struct xfs_bmbt_irec got; > struct xfs_bmbt_irec new; /* split extent */ > struct xfs_mount *mp = ip->i_mount; > - struct xfs_ifork *ifp; > xfs_fsblock_t gotblkcnt; /* new block count for got */ > struct xfs_iext_cursor icur; > int error = 0; > int logflags = 0; > int i = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -6011,7 +6000,6 @@ xfs_bmap_split_extent( > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > > - ifp = XFS_IFORK_PTR(ip, whichfork); > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > /* Read in all the extents */ > error = xfs_iread_extents(tp, ip, whichfork); > diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c > index 295a59cf88407..d9c63f17d2dec 100644 > --- a/fs/xfs/libxfs/xfs_bmap_btree.c > +++ b/fs/xfs/libxfs/xfs_bmap_btree.c > @@ -636,10 +636,7 @@ xfs_bmbt_change_owner( > > ASSERT(tp || buffer_list); > ASSERT(!(tp && buffer_list)); > - if (whichfork == XFS_DATA_FORK) > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_BTREE); > - else > - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE); > + ASSERT(XFS_IFORK_PTR(ip, whichfork)->if_format == XFS_DINODE_FMT_BTREE); > > cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork); > if (!cur) > diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c > index dd6fcaaea318a..612a9c5e41b1c 100644 > --- a/fs/xfs/libxfs/xfs_dir2.c > +++ b/fs/xfs/libxfs/xfs_dir2.c > @@ -278,7 +278,7 @@ xfs_dir_createname( > if (!inum) > args->op_flags |= XFS_DA_OP_JUSTCHECK; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_addname(args); > goto out_free; > } > @@ -373,7 +373,7 @@ xfs_dir_lookup( > args->op_flags |= XFS_DA_OP_CILOOKUP; > > lock_mode = xfs_ilock_data_map_shared(dp); > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_lookup(args); > goto out_check_rval; > } > @@ -443,7 +443,7 @@ xfs_dir_removename( > args->whichfork = XFS_DATA_FORK; > args->trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_removename(args); > goto out_free; > } > @@ -504,7 +504,7 @@ xfs_dir_replace( > args->whichfork = XFS_DATA_FORK; > args->trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_replace(args); > goto out_free; > } > diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c > index 7b7f6fb2ea3b2..2463b5d734472 100644 > --- a/fs/xfs/libxfs/xfs_dir2_sf.c > +++ b/fs/xfs/libxfs/xfs_dir2_sf.c > @@ -343,7 +343,7 @@ xfs_dir2_block_to_sf( > */ > ASSERT(dp->i_df.if_bytes == 0); > xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size); > - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; > dp->i_d.di_size = size; > > logflags |= XFS_ILOG_DDATA; > @@ -710,11 +710,11 @@ xfs_dir2_sf_verify( > struct xfs_inode *ip) > { > struct xfs_mount *mp = ip->i_mount; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > struct xfs_dir2_sf_hdr *sfp; > struct xfs_dir2_sf_entry *sfep; > struct xfs_dir2_sf_entry *next_sfep; > char *endp; > - struct xfs_ifork *ifp; > xfs_ino_t ino; > int i; > int i8count; > @@ -723,9 +723,8 @@ xfs_dir2_sf_verify( > int error; > uint8_t filetype; > > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; > size = ifp->if_bytes; > > @@ -827,9 +826,9 @@ xfs_dir2_sf_create( > * If it's currently a zero-length extent file, > * convert it to local format. > */ > - if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_EXTENTS) { > dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ > - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; > xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); > dp->i_df.if_flags |= XFS_IFINLINE; > } > @@ -1027,7 +1026,7 @@ xfs_dir2_sf_replace_needblock( > int newsize; > struct xfs_dir2_sf_hdr *sfp; > > - if (dp->i_d.di_format != XFS_DINODE_FMT_LOCAL) > + if (dp->i_df.if_format != XFS_DINODE_FMT_LOCAL) > return false; > > sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data; > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index a374e2a81e764..ab555671e1543 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -225,7 +225,6 @@ xfs_inode_from_disk( > be16_to_cpu(from->di_projid_lo); > } > > - to->di_format = from->di_format; > i_uid_write(inode, be32_to_cpu(from->di_uid)); > i_gid_write(inode, be32_to_cpu(from->di_gid)); > > @@ -246,7 +245,6 @@ xfs_inode_from_disk( > to->di_nblocks = be64_to_cpu(from->di_nblocks); > to->di_extsize = be32_to_cpu(from->di_extsize); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > to->di_dmevmask = be32_to_cpu(from->di_dmevmask); > to->di_dmstate = be16_to_cpu(from->di_dmstate); > to->di_flags = be16_to_cpu(from->di_flags); > @@ -289,7 +287,7 @@ xfs_inode_to_disk( > to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); > to->di_onlink = 0; > > - to->di_format = from->di_format; > + to->di_format = xfs_ifork_format(&ip->i_df); > to->di_uid = cpu_to_be32(i_uid_read(inode)); > to->di_gid = cpu_to_be32(i_gid_read(inode)); > to->di_projid_lo = cpu_to_be16(from->di_projid & 0xffff); > @@ -312,7 +310,7 @@ xfs_inode_to_disk( > to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df)); > to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp)); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > + to->di_aformat = xfs_ifork_format(ip->i_afp); > to->di_dmevmask = cpu_to_be32(from->di_dmevmask); > to->di_dmstate = cpu_to_be16(from->di_dmstate); > to->di_flags = cpu_to_be16(from->di_flags); > diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h > index fecccfb26463c..865ac493c72a2 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.h > +++ b/fs/xfs/libxfs/xfs_inode_buf.h > @@ -16,14 +16,12 @@ struct xfs_dinode; > * format specific structures at the appropriate time. > */ > struct xfs_icdinode { > - int8_t di_format; /* format of di_c data */ > uint16_t di_flushiter; /* incremented on flush */ > uint32_t di_projid; /* owner's project id */ > xfs_fsize_t di_size; /* number of bytes in file */ > xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ > xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ > uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ > - int8_t di_aformat; /* format of attr fork's data */ > uint32_t di_dmevmask; /* DMIG event mask */ > uint16_t di_dmstate; /* DMIG state info */ > uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 195da3552c5b5..6562f2bcd15cc 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -228,6 +228,7 @@ xfs_iformat_data_fork( > struct inode *inode = VFS_I(ip); > int error; > > + ip->i_df.if_format = dip->di_format; > ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); > > switch (inode->i_mode & S_IFMT) { > @@ -241,7 +242,7 @@ xfs_iformat_data_fork( > case S_IFREG: > case S_IFLNK: > case S_IFDIR: > - switch (dip->di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, > be64_to_cpu(dip->di_size)); > @@ -283,9 +284,12 @@ xfs_iformat_attr_fork( > int error = 0; > > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); > + ip->i_afp->if_format = dip->di_aformat; > + if (unlikely(ip->i_afp->if_format == 0)) /* pre IRIX 6.2 file system */ > + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); > > - switch (dip->di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, > xfs_dfork_attr_shortform_size(dip)); > @@ -508,7 +512,7 @@ xfs_idestroy_fork( > * not local then we may or may not have an extents list, > * so check and free it up if we do. > */ > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > if (ifp->if_u1.if_data != NULL) { > kmem_free(ifp->if_u1.if_data); > ifp->if_u1.if_data = NULL; > @@ -605,7 +609,7 @@ xfs_iflush_fork( > } > cp = XFS_DFORK_PTR(dip, whichfork); > mp = ip->i_mount; > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_LOCAL: > if ((iip->ili_fields & dataflag[whichfork]) && > (ifp->if_bytes > 0)) { > @@ -678,7 +682,7 @@ xfs_ifork_init_cow( > ip->i_cowfp = kmem_zone_zalloc(xfs_ifork_zone, > KM_NOFS); > ip->i_cowfp->if_flags = XFS_IFEXTENTS; > - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > + ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS; > } > > /* Verify the inline contents of the data fork of an inode. */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index a69d425fe68df..d849cca103edd 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -23,6 +23,7 @@ struct xfs_ifork { > } if_u1; > short if_broot_bytes; /* bytes allocated for root */ > unsigned char if_flags; /* per-fork flags */ > + int8_t if_format; /* format of this fork */ > xfs_extnum_t if_nextents; /* # of extents in this fork */ > }; > > @@ -56,24 +57,14 @@ struct xfs_ifork { > ((w) == XFS_ATTR_FORK ? \ > XFS_IFORK_ASIZE(ip) : \ > 0)) > -#define XFS_IFORK_FORMAT(ip,w) \ > - ((w) == XFS_DATA_FORK ? \ > - (ip)->i_d.di_format : \ > - ((w) == XFS_ATTR_FORK ? \ > - (ip)->i_d.di_aformat : \ > - (ip)->i_cformat)) > -#define XFS_IFORK_FMT_SET(ip,w,n) \ > - ((w) == XFS_DATA_FORK ? \ > - ((ip)->i_d.di_format = (n)) : \ > - ((w) == XFS_ATTR_FORK ? \ > - ((ip)->i_d.di_aformat = (n)) : \ > - ((ip)->i_cformat = (n)))) > #define XFS_IFORK_MAXEXT(ip, w) \ > (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) > > -#define xfs_ifork_has_extents(ip, w) \ > - (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ > - XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) > +static inline bool xfs_ifork_has_extents(struct xfs_ifork *ifp) > +{ > + return ifp->if_format == XFS_DINODE_FMT_EXTENTS || > + ifp->if_format == XFS_DINODE_FMT_BTREE; > +} > > static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > { > @@ -82,6 +73,13 @@ static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > return ifp->if_nextents; > } > > +static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp) > +{ > + if (!ifp) > + return XFS_DINODE_FMT_EXTENTS; > + return ifp->if_format; > +} > + > struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); > > int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c > index 3b8260ca7d1b8..594bc447a7dd2 100644 > --- a/fs/xfs/libxfs/xfs_symlink_remote.c > +++ b/fs/xfs/libxfs/xfs_symlink_remote.c > @@ -204,16 +204,12 @@ xfs_failaddr_t > xfs_symlink_shortform_verify( > struct xfs_inode *ip) > { > - char *sfp; > - char *endp; > - struct xfs_ifork *ifp; > - int size; > - > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); > - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > - sfp = (char *)ifp->if_u1.if_data; > - size = ifp->if_bytes; > - endp = sfp + size; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > + char *sfp = (char *)ifp->if_u1.if_data; > + int size = ifp->if_bytes; > + char *endp = sfp + size; > + > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > /* > * Zero length symlinks should never occur in memory as they are > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > index 157f72efec5e9..dfa1533b4edfc 100644 > --- a/fs/xfs/scrub/bmap.c > +++ b/fs/xfs/scrub/bmap.c > @@ -598,7 +598,7 @@ xchk_bmap_check_rmaps( > size = 0; > break; > } > - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > + if (ifp->if_format != XFS_DINODE_FMT_BTREE && > (size == 0 || ifp->if_nextents > 0)) > return 0; > > @@ -664,7 +664,7 @@ xchk_bmap( > } > > /* Check the fork values */ > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_UUID: > case XFS_DINODE_FMT_DEV: > case XFS_DINODE_FMT_LOCAL: > diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c > index 9a2e27ac13003..44b15015021f3 100644 > --- a/fs/xfs/scrub/dabtree.c > +++ b/fs/xfs/scrub/dabtree.c > @@ -468,7 +468,7 @@ xchk_da_btree( > int error; > > /* Skip short format data structures; no btree to scan. */ > - if (!xfs_ifork_has_extents(sc->ip, whichfork)) > + if (!xfs_ifork_has_extents(XFS_IFORK_PTR(sc->ip, whichfork))) > return 0; > > /* Set up initial da state. */ > diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c > index fe2a6e030c8a0..7c432997edade 100644 > --- a/fs/xfs/scrub/dir.c > +++ b/fs/xfs/scrub/dir.c > @@ -635,7 +635,7 @@ xchk_directory_blocks( > { > struct xfs_bmbt_irec got; > struct xfs_da_args args; > - struct xfs_ifork *ifp; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); > struct xfs_mount *mp = sc->mp; > xfs_fileoff_t leaf_lblk; > xfs_fileoff_t free_lblk; > @@ -647,11 +647,10 @@ xchk_directory_blocks( > int error; > > /* Ignore local format directories. */ > - if (sc->ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && > - sc->ip->i_d.di_format != XFS_DINODE_FMT_BTREE) > + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS && > + ifp->if_format != XFS_DINODE_FMT_BTREE) > return 0; > > - ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); > lblk = XFS_B_TO_FSB(mp, XFS_DIR2_DATA_OFFSET); > leaf_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_LEAF_OFFSET); > free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET); > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > index 9d9cebf187268..2834cbf1212e5 100644 > --- a/fs/xfs/xfs_aops.c > +++ b/fs/xfs/xfs_aops.c > @@ -382,7 +382,7 @@ xfs_map_blocks( > */ > retry: > xfs_ilock(ip, XFS_ILOCK_SHARED); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > (ip->i_df.if_flags & XFS_IFEXTENTS)); > > /* > diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c > index c42f90e16b4fa..00ffc46c0bf71 100644 > --- a/fs/xfs/xfs_attr_inactive.c > +++ b/fs/xfs/xfs_attr_inactive.c > @@ -367,7 +367,7 @@ xfs_attr_inactive( > * removal below. > */ > if (xfs_inode_hasattr(dp) && > - dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + dp->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_attr3_root_inactive(&trans, dp); > if (error) > goto out_cancel; > diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c > index 5ff1d929d3b5f..e380bd1a9bfc9 100644 > --- a/fs/xfs/xfs_attr_list.c > +++ b/fs/xfs/xfs_attr_list.c > @@ -512,9 +512,9 @@ xfs_attr_list_ilocked( > */ > if (!xfs_inode_hasattr(dp)) > return 0; > - else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) > + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) > return xfs_attr_shortform_list(context); > - else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) > + if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) > return xfs_attr_leaf_list(context); > return xfs_attr_node_list(context); > } > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index 4f277a6253b8d..5e32c3cf8e8c1 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -223,7 +223,7 @@ xfs_bmap_count_blocks( > if (!ifp) > return 0; > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_BTREE: > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > error = xfs_iread_extents(tp, ip, whichfork); > @@ -449,7 +449,7 @@ xfs_getbmap( > break; > } > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > case XFS_DINODE_FMT_BTREE: > break; > @@ -1210,17 +1210,19 @@ xfs_swap_extents_check_format( > struct xfs_inode *ip, /* target inode */ > struct xfs_inode *tip) /* tmp inode */ > { > + struct xfs_ifork *ifp = &ip->i_df; > + struct xfs_ifork *tifp = &tip->i_df; > > /* Should never get a local format */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || > - tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL || > + tifp->if_format == XFS_DINODE_FMT_LOCAL) > return -EINVAL; > > /* > * if the target inode has less extents that then temporary inode then > * why did userspace call us? > */ > - if (ip->i_df.if_nextents < tip->i_df.if_nextents) > + if (ifp->if_nextents < tifp->if_nextents) > return -EINVAL; > > /* > @@ -1235,18 +1237,18 @@ xfs_swap_extents_check_format( > * form then we will end up with the target inode in the wrong format > * as we already know there are less extents in the temp inode. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - tip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && > + tifp->if_format == XFS_DINODE_FMT_BTREE) > return -EINVAL; > > /* Check temp in extent form to max in target */ > - if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + if (tifp->if_format == XFS_DINODE_FMT_EXTENTS && > + tifp->if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > > /* Check target in extent form to max in temp */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && > + ifp->if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > > /* > @@ -1258,22 +1260,20 @@ xfs_swap_extents_check_format( > * (a common defrag case) which will occur when the temp inode is in > * extent format... > */ > - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) { > + if (tifp->if_format == XFS_DINODE_FMT_BTREE) { > if (XFS_IFORK_Q(ip) && > - XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) > + XFS_BMAP_BMDR_SPACE(tifp->if_broot) > XFS_IFORK_BOFF(ip)) > return -EINVAL; > - if (tip->i_df.if_nextents <= > - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + if (tifp->if_nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > } > > /* Reciprocal target->temp btree format checks */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { > + if (ifp->if_format == XFS_DINODE_FMT_BTREE) { > if (XFS_IFORK_Q(tip) && > XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) > return -EINVAL; > - if (ip->i_df.if_nextents <= > - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + if (ifp->if_nextents <= XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > } > > @@ -1426,14 +1426,14 @@ xfs_swap_extent_forks( > * Count the number of extended attribute blocks > */ > if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && > - ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, > &aforkblks); > if (error) > return error; > } > if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && > - tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + tip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, > &taforkblks); > if (error) > @@ -1448,9 +1448,9 @@ xfs_swap_extent_forks( > * bmbt scan as the last step. > */ > if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) { > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) > (*target_log_flags) |= XFS_ILOG_DOWNER; > - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (tip->i_df.if_format == XFS_DINODE_FMT_BTREE) > (*src_log_flags) |= XFS_ILOG_DOWNER; > } > > @@ -1466,8 +1466,6 @@ xfs_swap_extent_forks( > ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; > tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; > > - swap(ip->i_d.di_format, tip->i_d.di_format); > - > /* > * The extents in the source inode could still contain speculative > * preallocation beyond EOF (e.g. the file is open but not modified > @@ -1481,7 +1479,7 @@ xfs_swap_extent_forks( > tip->i_delayed_blks = ip->i_delayed_blks; > ip->i_delayed_blks = 0; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > (*src_log_flags) |= XFS_ILOG_DEXT; > break; > @@ -1492,7 +1490,7 @@ xfs_swap_extent_forks( > break; > } > > - switch (tip->i_d.di_format) { > + switch (tip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > (*target_log_flags) |= XFS_ILOG_DEXT; > break; > @@ -1714,8 +1712,10 @@ xfs_swap_extents( > > /* Swap the cow forks. */ > if (xfs_sb_version_hasreflink(&mp->m_sb)) { > - ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); > - ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); > + ASSERT(!ip->i_cowfp || > + ip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); > + ASSERT(!tip->i_cowfp || > + tip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); > > swap(ip->i_cowfp, tip->i_cowfp); > > diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c > index 871ec22c9aee9..66deddd5e2969 100644 > --- a/fs/xfs/xfs_dir2_readdir.c > +++ b/fs/xfs/xfs_dir2_readdir.c > @@ -524,7 +524,7 @@ xfs_readdir( > args.geo = dp->i_mount->m_dir_geo; > args.trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) > rval = xfs_dir2_sf_getdents(&args, ctx); > else if ((rval = xfs_dir2_isblock(&args, &v))) > ; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index 791d5d5e318cf..c09b3e9eab1da 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -63,7 +63,6 @@ xfs_inode_alloc( > memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); > ip->i_afp = NULL; > ip->i_cowfp = NULL; > - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > memset(&ip->i_df, 0, sizeof(ip->i_df)); > ip->i_flags = 0; > ip->i_delayed_blks = 0; > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 1677c4e7207ed..64f5f9a440aed 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -112,7 +112,7 @@ xfs_ilock_data_map_shared( > { > uint lock_mode = XFS_ILOCK_SHARED; > > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && > + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE && > (ip->i_df.if_flags & XFS_IFEXTENTS) == 0) > lock_mode = XFS_ILOCK_EXCL; > xfs_ilock(ip, lock_mode); > @@ -125,7 +125,8 @@ xfs_ilock_attr_map_shared( > { > uint lock_mode = XFS_ILOCK_SHARED; > > - if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE && > + if (ip->i_afp && > + ip->i_afp->if_format == XFS_DINODE_FMT_BTREE && > (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0) > lock_mode = XFS_ILOCK_EXCL; > xfs_ilock(ip, lock_mode); > @@ -851,7 +852,7 @@ xfs_ialloc( > case S_IFCHR: > case S_IFBLK: > case S_IFSOCK: > - ip->i_d.di_format = XFS_DINODE_FMT_DEV; > + ip->i_df.if_format = XFS_DINODE_FMT_DEV; > ip->i_df.if_flags = 0; > flags |= XFS_ILOG_DEV; > break; > @@ -907,7 +908,7 @@ xfs_ialloc( > } > /* FALLTHROUGH */ > case S_IFLNK: > - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; > + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_df.if_flags = XFS_IFEXTENTS; > ip->i_df.if_bytes = 0; > ip->i_df.if_u1.if_root = NULL; > @@ -915,10 +916,6 @@ xfs_ialloc( > default: > ASSERT(0); > } > - /* > - * Attribute fork settings for new inode. > - */ > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > /* > * Log the new values stuffed into the inode. > @@ -2749,7 +2746,7 @@ xfs_ifree( > * data fork to extents format. Note that the attr fork data has > * already been freed by xfs_attr_inactive. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > kmem_free(ip->i_df.if_u1.if_data); > ip->i_df.if_u1.if_data = NULL; > ip->i_df.if_bytes = 0; > @@ -2760,8 +2757,7 @@ xfs_ifree( > ip->i_d.di_flags2 = 0; > ip->i_d.di_dmevmask = 0; > ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ > - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; > > /* Don't attempt to replay owner changes for a deleted inode */ > ip->i_itemp->ili_fields &= ~(XFS_ILOG_AOWNER|XFS_ILOG_DOWNER); > @@ -3624,7 +3620,7 @@ xfs_iflush( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > *bpp = NULL; > @@ -3706,7 +3702,7 @@ xfs_iflush_int( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > ASSERT(iip != NULL && iip->ili_fields != 0); > > @@ -3728,8 +3724,8 @@ xfs_iflush_int( > } > if (S_ISREG(VFS_I(ip)->i_mode)) { > if (XFS_TEST_ERROR( > - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && > - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), > + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE, > mp, XFS_ERRTAG_IFLUSH_3)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: Bad regular inode %Lu, ptr "PTR_FMT, > @@ -3738,9 +3734,9 @@ xfs_iflush_int( > } > } else if (S_ISDIR(VFS_I(ip)->i_mode)) { > if (XFS_TEST_ERROR( > - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && > - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && > - (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL), > + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE && > + ip->i_df.if_format != XFS_DINODE_FMT_LOCAL, > mp, XFS_ERRTAG_IFLUSH_4)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: Bad directory inode %Lu, ptr "PTR_FMT, > @@ -3782,10 +3778,10 @@ xfs_iflush_int( > * If there are inline format data / attr forks attached to this inode, > * make sure they are not corrupt. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && > + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL && > xfs_ifork_verify_local_data(ip)) > goto flush_out; > - if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL && > + if (ip->i_afp && ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL && > xfs_ifork_verify_local_attr(ip)) > goto flush_out; > > diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h > index 24dae63ba16c0..dadcf19458960 100644 > --- a/fs/xfs/xfs_inode.h > +++ b/fs/xfs/xfs_inode.h > @@ -57,8 +57,6 @@ typedef struct xfs_inode { > > struct xfs_icdinode i_d; /* most of ondisk inode */ > > - unsigned int i_cformat; /* format of cow fork */ > - > /* VFS inode */ > struct inode i_vnode; /* embedded VFS inode */ > > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > index 401ba26aeed7b..ba47bf65b772b 100644 > --- a/fs/xfs/xfs_inode_item.c > +++ b/fs/xfs/xfs_inode_item.c > @@ -36,7 +36,7 @@ xfs_inode_item_data_fork_size( > { > struct xfs_inode *ip = iip->ili_inode; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_DEXT) && > ip->i_df.if_nextents > 0 && > @@ -77,7 +77,7 @@ xfs_inode_item_attr_fork_size( > { > struct xfs_inode *ip = iip->ili_inode; > > - switch (ip->i_d.di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_AEXT) && > ip->i_afp->if_nextents > 0 && > @@ -142,7 +142,7 @@ xfs_inode_item_format_data_fork( > struct xfs_inode *ip = iip->ili_inode; > size_t data_bytes; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > iip->ili_fields &= > ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); > @@ -227,7 +227,7 @@ xfs_inode_item_format_attr_fork( > struct xfs_inode *ip = iip->ili_inode; > size_t data_bytes; > > - switch (ip->i_d.di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > iip->ili_fields &= > ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); > @@ -305,7 +305,7 @@ xfs_inode_to_log_dinode( > struct inode *inode = VFS_I(ip); > > to->di_magic = XFS_DINODE_MAGIC; > - to->di_format = from->di_format; > + to->di_format = xfs_ifork_format(&ip->i_df); > to->di_uid = i_uid_read(inode); > to->di_gid = i_gid_read(inode); > to->di_projid_lo = from->di_projid & 0xffff; > @@ -329,7 +329,7 @@ xfs_inode_to_log_dinode( > to->di_nextents = xfs_ifork_nextents(&ip->i_df); > to->di_anextents = xfs_ifork_nextents(ip->i_afp); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > + to->di_aformat = xfs_ifork_format(ip->i_afp); > to->di_dmevmask = from->di_dmevmask; > to->di_dmstate = from->di_dmstate; > to->di_flags = from->di_flags; > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index b4fd918749e5f..6ae3a2457777a 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -856,7 +856,7 @@ xfs_buffered_write_iomap_begin( > > xfs_ilock(ip, XFS_ILOCK_EXCL); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, XFS_DATA_FORK)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(&ip->i_df)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > error = -EFSCORRUPTED; > goto out_unlock; > @@ -1263,7 +1263,7 @@ xfs_xattr_iomap_begin( > goto out_unlock; > } > > - ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); > + ASSERT(ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL); > error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, > &nimaps, XFS_BMAPI_ATTRFORK); > out_unlock: > diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c > index 80da86c5703fb..16ca97a7ff00f 100644 > --- a/fs/xfs/xfs_itable.c > +++ b/fs/xfs/xfs_itable.c > @@ -115,7 +115,7 @@ xfs_bulkstat_one_int( > buf->bs_cowextsize_blks = dic->di_cowextsize; > } > > - switch (dic->di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_DEV: > buf->bs_rdev = sysv_encode_dev(inode->i_rdev); > buf->bs_blksize = BLKDEV_IOSIZE; > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > index 8cf2fcb509c12..8e88a7ca387ea 100644 > --- a/fs/xfs/xfs_symlink.c > +++ b/fs/xfs/xfs_symlink.c > @@ -251,7 +251,7 @@ xfs_symlink( > xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen); > > ip->i_d.di_size = pathlen; > - ip->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + ip->i_df.if_format = XFS_DINODE_FMT_LOCAL; > xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE); > } else { > int offset; > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index ba2ab69e1fc7d..460136628a795 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -1897,7 +1897,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, > __entry->dev = VFS_I(ip)->i_sb->s_dev; > __entry->which = which; > __entry->ino = ip->i_ino; > - __entry->format = ip->i_d.di_format; > + __entry->format = ip->i_df.if_format; > __entry->nex = ip->i_df.if_nextents; > __entry->broot_size = ip->i_df.if_broot_bytes; > __entry->fork_off = XFS_IFORK_BOFF(ip); > -- chandan ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-10 7:24 ` [PATCH 5/6] xfs: move the fork format " Christoph Hellwig 2020-05-12 9:37 ` Chandan Babu R @ 2020-05-12 18:53 ` Brian Foster 2020-05-14 21:25 ` Darrick J. Wong 2 siblings, 0 replies; 41+ messages in thread From: Brian Foster @ 2020-05-12 18:53 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:03AM +0200, Christoph Hellwig wrote: > Both the data and attr fork have a format that is stored in the legacy > idinode. Move it into the xfs_ifork structure instead, where it uses > up padding. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- Reviewed-by: Brian Foster <bfoster@redhat.com> > fs/xfs/libxfs/xfs_attr.c | 12 +-- > fs/xfs/libxfs/xfs_attr_leaf.c | 32 ++++---- > fs/xfs/libxfs/xfs_bmap.c | 120 +++++++++++++---------------- > fs/xfs/libxfs/xfs_bmap_btree.c | 5 +- > fs/xfs/libxfs/xfs_dir2.c | 8 +- > fs/xfs/libxfs/xfs_dir2_sf.c | 13 ++-- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +- > fs/xfs/libxfs/xfs_inode_buf.h | 2 - > fs/xfs/libxfs/xfs_inode_fork.c | 14 ++-- > fs/xfs/libxfs/xfs_inode_fork.h | 28 ++++--- > fs/xfs/libxfs/xfs_symlink_remote.c | 16 ++-- > fs/xfs/scrub/bmap.c | 4 +- > fs/xfs/scrub/dabtree.c | 2 +- > fs/xfs/scrub/dir.c | 7 +- > fs/xfs/xfs_aops.c | 2 +- > fs/xfs/xfs_attr_inactive.c | 2 +- > fs/xfs/xfs_attr_list.c | 4 +- > fs/xfs/xfs_bmap_util.c | 56 +++++++------- > fs/xfs/xfs_dir2_readdir.c | 2 +- > fs/xfs/xfs_icache.c | 1 - > fs/xfs/xfs_inode.c | 36 ++++----- > fs/xfs/xfs_inode.h | 2 - > fs/xfs/xfs_inode_item.c | 12 +-- > fs/xfs/xfs_iomap.c | 4 +- > fs/xfs/xfs_itable.c | 2 +- > fs/xfs/xfs_symlink.c | 2 +- > fs/xfs/xfs_trace.h | 2 +- > 27 files changed, 181 insertions(+), 215 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c > index 1b01675e9c80b..3b1bd6e112f89 100644 > --- a/fs/xfs/libxfs/xfs_attr.c > +++ b/fs/xfs/libxfs/xfs_attr.c > @@ -61,7 +61,7 @@ xfs_inode_hasattr( > struct xfs_inode *ip) > { > if (!XFS_IFORK_Q(ip) || > - (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > + (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && > ip->i_afp->if_nextents == 0)) > return 0; > return 1; > @@ -84,7 +84,7 @@ xfs_attr_get_ilocked( > if (!xfs_inode_hasattr(args->dp)) > return -ENOATTR; > > - if (args->dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) > + if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) > return xfs_attr_shortform_getvalue(args); > if (xfs_bmap_one_block(args->dp, XFS_ATTR_FORK)) > return xfs_attr_leaf_get(args); > @@ -212,14 +212,14 @@ xfs_attr_set_args( > * If the attribute list is non-existent or a shortform list, > * upgrade it to a single-leaf-block attribute list. > */ > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL || > - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL || > + (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && > dp->i_afp->if_nextents == 0)) { > > /* > * Build initial attribute list (if required). > */ > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) > + if (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS) > xfs_attr_shortform_create(args); > > /* > @@ -272,7 +272,7 @@ xfs_attr_remove_args( > > if (!xfs_inode_hasattr(dp)) { > error = -ENOATTR; > - } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { > + } else if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) { > ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); > error = xfs_attr_shortform_remove(args); > } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index 64b172180c42c..d7f3173ce3c31 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -539,7 +539,7 @@ xfs_attr_shortform_bytesfit( > /* rounded down */ > offset = (XFS_LITINO(mp) - bytes) >> 3; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_DEV) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) { > minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; > return (offset >= minforkoff) ? minforkoff : 0; > } > @@ -567,7 +567,7 @@ xfs_attr_shortform_bytesfit( > > dsize = dp->i_df.if_bytes; > > - switch (dp->i_d.di_format) { > + switch (dp->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > /* > * If there is no attr fork and the data fork is extents, > @@ -636,22 +636,19 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) > * Create the initial contents of a shortform attribute list. > */ > void > -xfs_attr_shortform_create(xfs_da_args_t *args) > +xfs_attr_shortform_create( > + struct xfs_da_args *args) > { > - xfs_attr_sf_hdr_t *hdr; > - xfs_inode_t *dp; > - struct xfs_ifork *ifp; > + struct xfs_inode *dp = args->dp; > + struct xfs_ifork *ifp = dp->i_afp; > + struct xfs_attr_sf_hdr *hdr; > > trace_xfs_attr_sf_create(args); > > - dp = args->dp; > - ASSERT(dp != NULL); > - ifp = dp->i_afp; > - ASSERT(ifp != NULL); > ASSERT(ifp->if_bytes == 0); > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) { > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS) { > ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */ > - dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL; > + ifp->if_format = XFS_DINODE_FMT_LOCAL; > ifp->if_flags |= XFS_IFINLINE; > } else { > ASSERT(ifp->if_flags & XFS_IFINLINE); > @@ -721,7 +718,6 @@ xfs_attr_fork_remove( > { > xfs_idestroy_fork(ip, XFS_ATTR_FORK); > ip->i_d.di_forkoff = 0; > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > ASSERT(ip->i_afp == NULL); > > @@ -774,7 +770,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) > totsize -= size; > if (totsize == sizeof(xfs_attr_sf_hdr_t) && > (mp->m_flags & XFS_MOUNT_ATTR2) && > - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && > + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && > !(args->op_flags & XFS_DA_OP_ADDNAME)) { > xfs_attr_fork_remove(dp, args->trans); > } else { > @@ -784,7 +780,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) > ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || > (args->op_flags & XFS_DA_OP_ADDNAME) || > !(mp->m_flags & XFS_MOUNT_ATTR2) || > - dp->i_d.di_format == XFS_DINODE_FMT_BTREE); > + dp->i_df.if_format == XFS_DINODE_FMT_BTREE); > xfs_trans_log_inode(args->trans, dp, > XFS_ILOG_CORE | XFS_ILOG_ADATA); > } > @@ -961,7 +957,7 @@ xfs_attr_shortform_allfit( > + be16_to_cpu(name_loc->valuelen); > } > if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && > - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && > + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && > (bytes == sizeof(struct xfs_attr_sf_hdr))) > return -1; > return xfs_attr_shortform_bytesfit(dp, bytes); > @@ -980,7 +976,7 @@ xfs_attr_shortform_verify( > int i; > int64_t size; > > - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL); > + ASSERT(ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL); > ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK); > sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data; > size = ifp->if_bytes; > @@ -1084,7 +1080,7 @@ xfs_attr3_leaf_to_shortform( > > if (forkoff == -1) { > ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); > - ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); > + ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE); > xfs_attr_fork_remove(dp, args->trans); > goto out; > } > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index c1136be49abeb..edc63dba007f4 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -123,7 +123,7 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > return whichfork != XFS_COW_FORK && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > + ifp->if_format == XFS_DINODE_FMT_EXTENTS && > ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork); > } > > @@ -135,7 +135,7 @@ static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > return whichfork != XFS_COW_FORK && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && > + ifp->if_format == XFS_DINODE_FMT_BTREE && > ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork); > } > > @@ -215,8 +215,8 @@ xfs_bmap_forkoff_reset( > int whichfork) > { > if (whichfork == XFS_ATTR_FORK && > - ip->i_d.di_format != XFS_DINODE_FMT_DEV && > - ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { > + ip->i_df.if_format != XFS_DINODE_FMT_DEV && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE) { > uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; > > if (dfl_forkoff > ip->i_d.di_forkoff) > @@ -317,31 +317,28 @@ xfs_bmap_check_leaf_extents( > xfs_inode_t *ip, /* incore inode pointer */ > int whichfork) /* data or attr fork */ > { > + struct xfs_mount *mp = ip->i_mount; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_block *block; /* current btree block */ > xfs_fsblock_t bno; /* block # of "block" */ > xfs_buf_t *bp; /* buffer for "block" */ > int error; /* error return value */ > xfs_extnum_t i=0, j; /* index into the extents list */ > - struct xfs_ifork *ifp; /* fork structure */ > int level; /* btree level, for checking */ > - xfs_mount_t *mp; /* file system mount structure */ > __be64 *pp; /* pointer to block address */ > xfs_bmbt_rec_t *ep; /* pointer to current extent */ > xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */ > xfs_bmbt_rec_t *nextp; /* pointer to next extent */ > int bp_release = 0; > > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { > + if (ifp->if_format != XFS_DINODE_FMT_BTREE) > return; > - } > > /* skip large extent count inodes */ > if (ip->i_df.if_nextents > 10000) > return; > > bno = NULLFSBLOCK; > - mp = ip->i_mount; > - ifp = XFS_IFORK_PTR(ip, whichfork); > block = ifp->if_broot; > /* > * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. > @@ -606,7 +603,7 @@ xfs_bmap_btree_to_extents( > ASSERT(cur); > ASSERT(whichfork != XFS_COW_FORK); > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); > ASSERT(be16_to_cpu(rblock->bb_level) == 1); > ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); > ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); > @@ -634,7 +631,7 @@ xfs_bmap_btree_to_extents( > xfs_iroot_realloc(ip, -1, whichfork); > ASSERT(ifp->if_broot == NULL); > ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork); > return 0; > } > @@ -670,7 +667,7 @@ xfs_bmap_extents_to_btree( > mp = ip->i_mount; > ASSERT(whichfork != XFS_COW_FORK); > ifp = XFS_IFORK_PTR(ip, whichfork); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS); > > /* > * Make space in the inode incore. This needs to be undone if we fail > @@ -694,7 +691,7 @@ xfs_bmap_extents_to_btree( > /* > * Convert to a btree with two levels, one record in root. > */ > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); > + ifp->if_format = XFS_DINODE_FMT_BTREE; > memset(&args, 0, sizeof(args)); > args.tp = tp; > args.mp = mp; > @@ -780,7 +777,7 @@ xfs_bmap_extents_to_btree( > xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); > out_root_realloc: > xfs_iroot_realloc(ip, -1, whichfork); > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > ASSERT(ifp->if_broot == NULL); > xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); > > @@ -802,7 +799,7 @@ xfs_bmap_local_to_extents_empty( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > ASSERT(whichfork != XFS_COW_FORK); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > ASSERT(ifp->if_bytes == 0); > ASSERT(ifp->if_nextents == 0); > > @@ -811,7 +808,7 @@ xfs_bmap_local_to_extents_empty( > ifp->if_flags |= XFS_IFEXTENTS; > ifp->if_u1.if_root = NULL; > ifp->if_height = 0; > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > } > > @@ -842,7 +839,7 @@ xfs_bmap_local_to_extents( > */ > ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK)); > ifp = XFS_IFORK_PTR(ip, whichfork); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > if (!ifp->if_bytes) { > xfs_bmap_local_to_extents_empty(tp, ip, whichfork); > @@ -1036,7 +1033,7 @@ xfs_bmap_set_attrforkoff( > int size, > int *version) > { > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_DEV: > ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; > break; > @@ -1094,13 +1091,6 @@ xfs_bmap_add_attrfork( > goto trans_cancel; > if (XFS_IFORK_Q(ip)) > goto trans_cancel; > - if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { > - /* > - * For inodes coming from pre-6.2 filesystems. > - */ > - ASSERT(ip->i_d.di_aformat == 0); > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > - } > > xfs_trans_ijoin(tp, ip, 0); > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > @@ -1109,9 +1099,10 @@ xfs_bmap_add_attrfork( > goto trans_cancel; > ASSERT(ip->i_afp == NULL); > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, 0); > + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_afp->if_flags = XFS_IFEXTENTS; > logflags = 0; > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_bmap_add_attrfork_local(tp, ip, &logflags); > break; > @@ -1237,9 +1228,7 @@ xfs_iread_extents( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > - if (XFS_IS_CORRUPT(mp, > - XFS_IFORK_FORMAT(ip, whichfork) != > - XFS_DINODE_FMT_BTREE)) { > + if (XFS_IS_CORRUPT(mp, ifp->if_format != XFS_DINODE_FMT_BTREE)) { > error = -EFSCORRUPTED; > goto out; > } > @@ -1287,14 +1276,13 @@ xfs_bmap_first_unused( > xfs_fileoff_t lowest, max; > int error; > > - ASSERT(xfs_ifork_has_extents(ip, whichfork) || > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > - > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > *first_unused = 0; > return 0; > } > > + ASSERT(xfs_ifork_has_extents(ifp)); > + > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > error = xfs_iread_extents(tp, ip, whichfork); > if (error) > @@ -1335,7 +1323,7 @@ xfs_bmap_last_before( > struct xfs_iext_cursor icur; > int error; > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_LOCAL: > *last_block = 0; > return 0; > @@ -1434,16 +1422,17 @@ xfs_bmap_last_offset( > xfs_fileoff_t *last_block, > int whichfork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_bmbt_irec rec; > int is_empty; > int error; > > *last_block = 0; > > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) > return 0; > > - if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ip, whichfork))) > + if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp))) > return -EFSCORRUPTED; > > error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); > @@ -1475,7 +1464,7 @@ xfs_bmap_one_block( > #endif /* !DEBUG */ > if (ifp->if_nextents != 1) > return 0; > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS) > return 0; > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > xfs_iext_first(ifp, &icur); > @@ -3895,10 +3884,9 @@ xfs_bmapi_read( > if (WARN_ON_ONCE(!ifp)) > return -EFSCORRUPTED; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > - XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) > return -EFSCORRUPTED; > - } > > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > @@ -4281,11 +4269,13 @@ xfs_bmapi_minleft( > struct xfs_inode *ip, > int fork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, fork); > + > if (tp && tp->t_firstblock != NULLFSBLOCK) > return 0; > - if (XFS_IFORK_FORMAT(ip, fork) != XFS_DINODE_FMT_BTREE) > + if (ifp->if_format != XFS_DINODE_FMT_BTREE) > return 1; > - return be16_to_cpu(XFS_IFORK_PTR(ip, fork)->if_broot->bb_level) + 1; > + return be16_to_cpu(ifp->if_broot->bb_level) + 1; > } > > /* > @@ -4300,11 +4290,13 @@ xfs_bmapi_finish( > int whichfork, > int error) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); > + > if ((bma->logflags & xfs_ilog_fext(whichfork)) && > - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + ifp->if_format != XFS_DINODE_FMT_EXTENTS) > bma->logflags &= ~xfs_ilog_fext(whichfork); > else if ((bma->logflags & xfs_ilog_fbroot(whichfork)) && > - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_BTREE) > + ifp->if_format != XFS_DINODE_FMT_BTREE) > bma->logflags &= ~xfs_ilog_fbroot(whichfork); > > if (bma->logflags) > @@ -4336,13 +4328,13 @@ xfs_bmapi_write( > .total = total, > }; > struct xfs_mount *mp = ip->i_mount; > - struct xfs_ifork *ifp; > + int whichfork = xfs_bmapi_whichfork(flags); > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > xfs_fileoff_t end; /* end of mapped file region */ > bool eof = false; /* after the end of extents */ > int error; /* error return */ > int n; /* current extent index */ > xfs_fileoff_t obno; /* old block number (offset) */ > - int whichfork; /* data or attr fork */ > > #ifdef DEBUG > xfs_fileoff_t orig_bno; /* original block number value */ > @@ -4357,13 +4349,12 @@ xfs_bmapi_write( > orig_mval = mval; > orig_nmap = *nmap; > #endif > - whichfork = xfs_bmapi_whichfork(flags); > > ASSERT(*nmap >= 1); > ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); > ASSERT(tp != NULL); > ASSERT(len > 0); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL); > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > ASSERT(!(flags & XFS_BMAPI_REMAP)); > > @@ -4379,7 +4370,7 @@ xfs_bmapi_write( > ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != > (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -4387,8 +4378,6 @@ xfs_bmapi_write( > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > > - ifp = XFS_IFORK_PTR(ip, whichfork); > - > XFS_STATS_INC(mp, xs_blk_mapw); > > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > @@ -4498,7 +4487,7 @@ xfs_bmapi_write( > if (error) > goto error0; > > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || > + ASSERT(ifp->if_format != XFS_DINODE_FMT_BTREE || > ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork)); > xfs_bmapi_finish(&bma, whichfork, 0); > xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, > @@ -4645,7 +4634,7 @@ xfs_bmapi_remap( > ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) != > (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -4689,9 +4678,9 @@ xfs_bmapi_remap( > error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, whichfork); > > error0: > - if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) > + if (ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS) > logflags &= ~XFS_ILOG_DEXT; > - else if (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) > + else if (ip->i_df.if_format != XFS_DINODE_FMT_BTREE) > logflags &= ~XFS_ILOG_DBROOT; > > if (logflags) > @@ -5041,7 +5030,7 @@ xfs_bmap_del_extent_real( > * conversion to btree format, since the transaction will be dirty then. > */ > if (tp->t_blk_res == 0 && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > + ifp->if_format == XFS_DINODE_FMT_EXTENTS && > ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) && > del->br_startoff > got.br_startoff && del_endoff < got_endoff) > return -ENOSPC; > @@ -5284,7 +5273,7 @@ __xfs_bunmapi( > whichfork = xfs_bmapi_whichfork(flags); > ASSERT(whichfork != XFS_COW_FORK); > ifp = XFS_IFORK_PTR(ip, whichfork); > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork))) > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp))) > return -EFSCORRUPTED; > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > @@ -5322,7 +5311,7 @@ __xfs_bunmapi( > > logflags = 0; > if (ifp->if_flags & XFS_IFBROOT) { > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); > cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); > cur->bc_ino.flags = 0; > } else > @@ -5567,10 +5556,10 @@ __xfs_bunmapi( > * logging the extent records if we've converted to btree format. > */ > if ((logflags & xfs_ilog_fext(whichfork)) && > - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + ifp->if_format != XFS_DINODE_FMT_EXTENTS) > logflags &= ~xfs_ilog_fext(whichfork); > else if ((logflags & xfs_ilog_fbroot(whichfork)) && > - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) > + ifp->if_format != XFS_DINODE_FMT_BTREE) > logflags &= ~xfs_ilog_fbroot(whichfork); > /* > * Log inode even in the error case, if the transaction > @@ -5781,7 +5770,7 @@ xfs_bmap_collapse_extents( > int error = 0; > int logflags = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -5898,7 +5887,7 @@ xfs_bmap_insert_extents( > int error = 0; > int logflags = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -5992,18 +5981,18 @@ xfs_bmap_split_extent( > xfs_fileoff_t split_fsb) > { > int whichfork = XFS_DATA_FORK; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_cur *cur = NULL; > struct xfs_bmbt_irec got; > struct xfs_bmbt_irec new; /* split extent */ > struct xfs_mount *mp = ip->i_mount; > - struct xfs_ifork *ifp; > xfs_fsblock_t gotblkcnt; /* new block count for got */ > struct xfs_iext_cursor icur; > int error = 0; > int logflags = 0; > int i = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -6011,7 +6000,6 @@ xfs_bmap_split_extent( > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > > - ifp = XFS_IFORK_PTR(ip, whichfork); > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > /* Read in all the extents */ > error = xfs_iread_extents(tp, ip, whichfork); > diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c > index 295a59cf88407..d9c63f17d2dec 100644 > --- a/fs/xfs/libxfs/xfs_bmap_btree.c > +++ b/fs/xfs/libxfs/xfs_bmap_btree.c > @@ -636,10 +636,7 @@ xfs_bmbt_change_owner( > > ASSERT(tp || buffer_list); > ASSERT(!(tp && buffer_list)); > - if (whichfork == XFS_DATA_FORK) > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_BTREE); > - else > - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE); > + ASSERT(XFS_IFORK_PTR(ip, whichfork)->if_format == XFS_DINODE_FMT_BTREE); > > cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork); > if (!cur) > diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c > index dd6fcaaea318a..612a9c5e41b1c 100644 > --- a/fs/xfs/libxfs/xfs_dir2.c > +++ b/fs/xfs/libxfs/xfs_dir2.c > @@ -278,7 +278,7 @@ xfs_dir_createname( > if (!inum) > args->op_flags |= XFS_DA_OP_JUSTCHECK; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_addname(args); > goto out_free; > } > @@ -373,7 +373,7 @@ xfs_dir_lookup( > args->op_flags |= XFS_DA_OP_CILOOKUP; > > lock_mode = xfs_ilock_data_map_shared(dp); > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_lookup(args); > goto out_check_rval; > } > @@ -443,7 +443,7 @@ xfs_dir_removename( > args->whichfork = XFS_DATA_FORK; > args->trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_removename(args); > goto out_free; > } > @@ -504,7 +504,7 @@ xfs_dir_replace( > args->whichfork = XFS_DATA_FORK; > args->trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_replace(args); > goto out_free; > } > diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c > index 7b7f6fb2ea3b2..2463b5d734472 100644 > --- a/fs/xfs/libxfs/xfs_dir2_sf.c > +++ b/fs/xfs/libxfs/xfs_dir2_sf.c > @@ -343,7 +343,7 @@ xfs_dir2_block_to_sf( > */ > ASSERT(dp->i_df.if_bytes == 0); > xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size); > - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; > dp->i_d.di_size = size; > > logflags |= XFS_ILOG_DDATA; > @@ -710,11 +710,11 @@ xfs_dir2_sf_verify( > struct xfs_inode *ip) > { > struct xfs_mount *mp = ip->i_mount; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > struct xfs_dir2_sf_hdr *sfp; > struct xfs_dir2_sf_entry *sfep; > struct xfs_dir2_sf_entry *next_sfep; > char *endp; > - struct xfs_ifork *ifp; > xfs_ino_t ino; > int i; > int i8count; > @@ -723,9 +723,8 @@ xfs_dir2_sf_verify( > int error; > uint8_t filetype; > > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; > size = ifp->if_bytes; > > @@ -827,9 +826,9 @@ xfs_dir2_sf_create( > * If it's currently a zero-length extent file, > * convert it to local format. > */ > - if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_EXTENTS) { > dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ > - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; > xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); > dp->i_df.if_flags |= XFS_IFINLINE; > } > @@ -1027,7 +1026,7 @@ xfs_dir2_sf_replace_needblock( > int newsize; > struct xfs_dir2_sf_hdr *sfp; > > - if (dp->i_d.di_format != XFS_DINODE_FMT_LOCAL) > + if (dp->i_df.if_format != XFS_DINODE_FMT_LOCAL) > return false; > > sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data; > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index a374e2a81e764..ab555671e1543 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -225,7 +225,6 @@ xfs_inode_from_disk( > be16_to_cpu(from->di_projid_lo); > } > > - to->di_format = from->di_format; > i_uid_write(inode, be32_to_cpu(from->di_uid)); > i_gid_write(inode, be32_to_cpu(from->di_gid)); > > @@ -246,7 +245,6 @@ xfs_inode_from_disk( > to->di_nblocks = be64_to_cpu(from->di_nblocks); > to->di_extsize = be32_to_cpu(from->di_extsize); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > to->di_dmevmask = be32_to_cpu(from->di_dmevmask); > to->di_dmstate = be16_to_cpu(from->di_dmstate); > to->di_flags = be16_to_cpu(from->di_flags); > @@ -289,7 +287,7 @@ xfs_inode_to_disk( > to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); > to->di_onlink = 0; > > - to->di_format = from->di_format; > + to->di_format = xfs_ifork_format(&ip->i_df); > to->di_uid = cpu_to_be32(i_uid_read(inode)); > to->di_gid = cpu_to_be32(i_gid_read(inode)); > to->di_projid_lo = cpu_to_be16(from->di_projid & 0xffff); > @@ -312,7 +310,7 @@ xfs_inode_to_disk( > to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df)); > to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp)); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > + to->di_aformat = xfs_ifork_format(ip->i_afp); > to->di_dmevmask = cpu_to_be32(from->di_dmevmask); > to->di_dmstate = cpu_to_be16(from->di_dmstate); > to->di_flags = cpu_to_be16(from->di_flags); > diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h > index fecccfb26463c..865ac493c72a2 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.h > +++ b/fs/xfs/libxfs/xfs_inode_buf.h > @@ -16,14 +16,12 @@ struct xfs_dinode; > * format specific structures at the appropriate time. > */ > struct xfs_icdinode { > - int8_t di_format; /* format of di_c data */ > uint16_t di_flushiter; /* incremented on flush */ > uint32_t di_projid; /* owner's project id */ > xfs_fsize_t di_size; /* number of bytes in file */ > xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ > xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ > uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ > - int8_t di_aformat; /* format of attr fork's data */ > uint32_t di_dmevmask; /* DMIG event mask */ > uint16_t di_dmstate; /* DMIG state info */ > uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 195da3552c5b5..6562f2bcd15cc 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -228,6 +228,7 @@ xfs_iformat_data_fork( > struct inode *inode = VFS_I(ip); > int error; > > + ip->i_df.if_format = dip->di_format; > ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); > > switch (inode->i_mode & S_IFMT) { > @@ -241,7 +242,7 @@ xfs_iformat_data_fork( > case S_IFREG: > case S_IFLNK: > case S_IFDIR: > - switch (dip->di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, > be64_to_cpu(dip->di_size)); > @@ -283,9 +284,12 @@ xfs_iformat_attr_fork( > int error = 0; > > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); > + ip->i_afp->if_format = dip->di_aformat; > + if (unlikely(ip->i_afp->if_format == 0)) /* pre IRIX 6.2 file system */ > + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); > > - switch (dip->di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, > xfs_dfork_attr_shortform_size(dip)); > @@ -508,7 +512,7 @@ xfs_idestroy_fork( > * not local then we may or may not have an extents list, > * so check and free it up if we do. > */ > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > if (ifp->if_u1.if_data != NULL) { > kmem_free(ifp->if_u1.if_data); > ifp->if_u1.if_data = NULL; > @@ -605,7 +609,7 @@ xfs_iflush_fork( > } > cp = XFS_DFORK_PTR(dip, whichfork); > mp = ip->i_mount; > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_LOCAL: > if ((iip->ili_fields & dataflag[whichfork]) && > (ifp->if_bytes > 0)) { > @@ -678,7 +682,7 @@ xfs_ifork_init_cow( > ip->i_cowfp = kmem_zone_zalloc(xfs_ifork_zone, > KM_NOFS); > ip->i_cowfp->if_flags = XFS_IFEXTENTS; > - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > + ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS; > } > > /* Verify the inline contents of the data fork of an inode. */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index a69d425fe68df..d849cca103edd 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -23,6 +23,7 @@ struct xfs_ifork { > } if_u1; > short if_broot_bytes; /* bytes allocated for root */ > unsigned char if_flags; /* per-fork flags */ > + int8_t if_format; /* format of this fork */ > xfs_extnum_t if_nextents; /* # of extents in this fork */ > }; > > @@ -56,24 +57,14 @@ struct xfs_ifork { > ((w) == XFS_ATTR_FORK ? \ > XFS_IFORK_ASIZE(ip) : \ > 0)) > -#define XFS_IFORK_FORMAT(ip,w) \ > - ((w) == XFS_DATA_FORK ? \ > - (ip)->i_d.di_format : \ > - ((w) == XFS_ATTR_FORK ? \ > - (ip)->i_d.di_aformat : \ > - (ip)->i_cformat)) > -#define XFS_IFORK_FMT_SET(ip,w,n) \ > - ((w) == XFS_DATA_FORK ? \ > - ((ip)->i_d.di_format = (n)) : \ > - ((w) == XFS_ATTR_FORK ? \ > - ((ip)->i_d.di_aformat = (n)) : \ > - ((ip)->i_cformat = (n)))) > #define XFS_IFORK_MAXEXT(ip, w) \ > (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) > > -#define xfs_ifork_has_extents(ip, w) \ > - (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ > - XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) > +static inline bool xfs_ifork_has_extents(struct xfs_ifork *ifp) > +{ > + return ifp->if_format == XFS_DINODE_FMT_EXTENTS || > + ifp->if_format == XFS_DINODE_FMT_BTREE; > +} > > static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > { > @@ -82,6 +73,13 @@ static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > return ifp->if_nextents; > } > > +static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp) > +{ > + if (!ifp) > + return XFS_DINODE_FMT_EXTENTS; > + return ifp->if_format; > +} > + > struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); > > int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c > index 3b8260ca7d1b8..594bc447a7dd2 100644 > --- a/fs/xfs/libxfs/xfs_symlink_remote.c > +++ b/fs/xfs/libxfs/xfs_symlink_remote.c > @@ -204,16 +204,12 @@ xfs_failaddr_t > xfs_symlink_shortform_verify( > struct xfs_inode *ip) > { > - char *sfp; > - char *endp; > - struct xfs_ifork *ifp; > - int size; > - > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); > - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > - sfp = (char *)ifp->if_u1.if_data; > - size = ifp->if_bytes; > - endp = sfp + size; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > + char *sfp = (char *)ifp->if_u1.if_data; > + int size = ifp->if_bytes; > + char *endp = sfp + size; > + > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > /* > * Zero length symlinks should never occur in memory as they are > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > index 157f72efec5e9..dfa1533b4edfc 100644 > --- a/fs/xfs/scrub/bmap.c > +++ b/fs/xfs/scrub/bmap.c > @@ -598,7 +598,7 @@ xchk_bmap_check_rmaps( > size = 0; > break; > } > - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > + if (ifp->if_format != XFS_DINODE_FMT_BTREE && > (size == 0 || ifp->if_nextents > 0)) > return 0; > > @@ -664,7 +664,7 @@ xchk_bmap( > } > > /* Check the fork values */ > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_UUID: > case XFS_DINODE_FMT_DEV: > case XFS_DINODE_FMT_LOCAL: > diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c > index 9a2e27ac13003..44b15015021f3 100644 > --- a/fs/xfs/scrub/dabtree.c > +++ b/fs/xfs/scrub/dabtree.c > @@ -468,7 +468,7 @@ xchk_da_btree( > int error; > > /* Skip short format data structures; no btree to scan. */ > - if (!xfs_ifork_has_extents(sc->ip, whichfork)) > + if (!xfs_ifork_has_extents(XFS_IFORK_PTR(sc->ip, whichfork))) > return 0; > > /* Set up initial da state. */ > diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c > index fe2a6e030c8a0..7c432997edade 100644 > --- a/fs/xfs/scrub/dir.c > +++ b/fs/xfs/scrub/dir.c > @@ -635,7 +635,7 @@ xchk_directory_blocks( > { > struct xfs_bmbt_irec got; > struct xfs_da_args args; > - struct xfs_ifork *ifp; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); > struct xfs_mount *mp = sc->mp; > xfs_fileoff_t leaf_lblk; > xfs_fileoff_t free_lblk; > @@ -647,11 +647,10 @@ xchk_directory_blocks( > int error; > > /* Ignore local format directories. */ > - if (sc->ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && > - sc->ip->i_d.di_format != XFS_DINODE_FMT_BTREE) > + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS && > + ifp->if_format != XFS_DINODE_FMT_BTREE) > return 0; > > - ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); > lblk = XFS_B_TO_FSB(mp, XFS_DIR2_DATA_OFFSET); > leaf_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_LEAF_OFFSET); > free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET); > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > index 9d9cebf187268..2834cbf1212e5 100644 > --- a/fs/xfs/xfs_aops.c > +++ b/fs/xfs/xfs_aops.c > @@ -382,7 +382,7 @@ xfs_map_blocks( > */ > retry: > xfs_ilock(ip, XFS_ILOCK_SHARED); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > (ip->i_df.if_flags & XFS_IFEXTENTS)); > > /* > diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c > index c42f90e16b4fa..00ffc46c0bf71 100644 > --- a/fs/xfs/xfs_attr_inactive.c > +++ b/fs/xfs/xfs_attr_inactive.c > @@ -367,7 +367,7 @@ xfs_attr_inactive( > * removal below. > */ > if (xfs_inode_hasattr(dp) && > - dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + dp->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_attr3_root_inactive(&trans, dp); > if (error) > goto out_cancel; > diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c > index 5ff1d929d3b5f..e380bd1a9bfc9 100644 > --- a/fs/xfs/xfs_attr_list.c > +++ b/fs/xfs/xfs_attr_list.c > @@ -512,9 +512,9 @@ xfs_attr_list_ilocked( > */ > if (!xfs_inode_hasattr(dp)) > return 0; > - else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) > + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) > return xfs_attr_shortform_list(context); > - else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) > + if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) > return xfs_attr_leaf_list(context); > return xfs_attr_node_list(context); > } > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index 4f277a6253b8d..5e32c3cf8e8c1 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -223,7 +223,7 @@ xfs_bmap_count_blocks( > if (!ifp) > return 0; > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_BTREE: > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > error = xfs_iread_extents(tp, ip, whichfork); > @@ -449,7 +449,7 @@ xfs_getbmap( > break; > } > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > case XFS_DINODE_FMT_BTREE: > break; > @@ -1210,17 +1210,19 @@ xfs_swap_extents_check_format( > struct xfs_inode *ip, /* target inode */ > struct xfs_inode *tip) /* tmp inode */ > { > + struct xfs_ifork *ifp = &ip->i_df; > + struct xfs_ifork *tifp = &tip->i_df; > > /* Should never get a local format */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || > - tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL || > + tifp->if_format == XFS_DINODE_FMT_LOCAL) > return -EINVAL; > > /* > * if the target inode has less extents that then temporary inode then > * why did userspace call us? > */ > - if (ip->i_df.if_nextents < tip->i_df.if_nextents) > + if (ifp->if_nextents < tifp->if_nextents) > return -EINVAL; > > /* > @@ -1235,18 +1237,18 @@ xfs_swap_extents_check_format( > * form then we will end up with the target inode in the wrong format > * as we already know there are less extents in the temp inode. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - tip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && > + tifp->if_format == XFS_DINODE_FMT_BTREE) > return -EINVAL; > > /* Check temp in extent form to max in target */ > - if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + if (tifp->if_format == XFS_DINODE_FMT_EXTENTS && > + tifp->if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > > /* Check target in extent form to max in temp */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && > + ifp->if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > > /* > @@ -1258,22 +1260,20 @@ xfs_swap_extents_check_format( > * (a common defrag case) which will occur when the temp inode is in > * extent format... > */ > - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) { > + if (tifp->if_format == XFS_DINODE_FMT_BTREE) { > if (XFS_IFORK_Q(ip) && > - XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) > + XFS_BMAP_BMDR_SPACE(tifp->if_broot) > XFS_IFORK_BOFF(ip)) > return -EINVAL; > - if (tip->i_df.if_nextents <= > - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + if (tifp->if_nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > } > > /* Reciprocal target->temp btree format checks */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { > + if (ifp->if_format == XFS_DINODE_FMT_BTREE) { > if (XFS_IFORK_Q(tip) && > XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) > return -EINVAL; > - if (ip->i_df.if_nextents <= > - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + if (ifp->if_nextents <= XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > } > > @@ -1426,14 +1426,14 @@ xfs_swap_extent_forks( > * Count the number of extended attribute blocks > */ > if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && > - ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, > &aforkblks); > if (error) > return error; > } > if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && > - tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + tip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, > &taforkblks); > if (error) > @@ -1448,9 +1448,9 @@ xfs_swap_extent_forks( > * bmbt scan as the last step. > */ > if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) { > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) > (*target_log_flags) |= XFS_ILOG_DOWNER; > - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (tip->i_df.if_format == XFS_DINODE_FMT_BTREE) > (*src_log_flags) |= XFS_ILOG_DOWNER; > } > > @@ -1466,8 +1466,6 @@ xfs_swap_extent_forks( > ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; > tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; > > - swap(ip->i_d.di_format, tip->i_d.di_format); > - > /* > * The extents in the source inode could still contain speculative > * preallocation beyond EOF (e.g. the file is open but not modified > @@ -1481,7 +1479,7 @@ xfs_swap_extent_forks( > tip->i_delayed_blks = ip->i_delayed_blks; > ip->i_delayed_blks = 0; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > (*src_log_flags) |= XFS_ILOG_DEXT; > break; > @@ -1492,7 +1490,7 @@ xfs_swap_extent_forks( > break; > } > > - switch (tip->i_d.di_format) { > + switch (tip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > (*target_log_flags) |= XFS_ILOG_DEXT; > break; > @@ -1714,8 +1712,10 @@ xfs_swap_extents( > > /* Swap the cow forks. */ > if (xfs_sb_version_hasreflink(&mp->m_sb)) { > - ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); > - ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); > + ASSERT(!ip->i_cowfp || > + ip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); > + ASSERT(!tip->i_cowfp || > + tip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); > > swap(ip->i_cowfp, tip->i_cowfp); > > diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c > index 871ec22c9aee9..66deddd5e2969 100644 > --- a/fs/xfs/xfs_dir2_readdir.c > +++ b/fs/xfs/xfs_dir2_readdir.c > @@ -524,7 +524,7 @@ xfs_readdir( > args.geo = dp->i_mount->m_dir_geo; > args.trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) > rval = xfs_dir2_sf_getdents(&args, ctx); > else if ((rval = xfs_dir2_isblock(&args, &v))) > ; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index 791d5d5e318cf..c09b3e9eab1da 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -63,7 +63,6 @@ xfs_inode_alloc( > memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); > ip->i_afp = NULL; > ip->i_cowfp = NULL; > - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > memset(&ip->i_df, 0, sizeof(ip->i_df)); > ip->i_flags = 0; > ip->i_delayed_blks = 0; > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 1677c4e7207ed..64f5f9a440aed 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -112,7 +112,7 @@ xfs_ilock_data_map_shared( > { > uint lock_mode = XFS_ILOCK_SHARED; > > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && > + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE && > (ip->i_df.if_flags & XFS_IFEXTENTS) == 0) > lock_mode = XFS_ILOCK_EXCL; > xfs_ilock(ip, lock_mode); > @@ -125,7 +125,8 @@ xfs_ilock_attr_map_shared( > { > uint lock_mode = XFS_ILOCK_SHARED; > > - if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE && > + if (ip->i_afp && > + ip->i_afp->if_format == XFS_DINODE_FMT_BTREE && > (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0) > lock_mode = XFS_ILOCK_EXCL; > xfs_ilock(ip, lock_mode); > @@ -851,7 +852,7 @@ xfs_ialloc( > case S_IFCHR: > case S_IFBLK: > case S_IFSOCK: > - ip->i_d.di_format = XFS_DINODE_FMT_DEV; > + ip->i_df.if_format = XFS_DINODE_FMT_DEV; > ip->i_df.if_flags = 0; > flags |= XFS_ILOG_DEV; > break; > @@ -907,7 +908,7 @@ xfs_ialloc( > } > /* FALLTHROUGH */ > case S_IFLNK: > - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; > + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_df.if_flags = XFS_IFEXTENTS; > ip->i_df.if_bytes = 0; > ip->i_df.if_u1.if_root = NULL; > @@ -915,10 +916,6 @@ xfs_ialloc( > default: > ASSERT(0); > } > - /* > - * Attribute fork settings for new inode. > - */ > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > /* > * Log the new values stuffed into the inode. > @@ -2749,7 +2746,7 @@ xfs_ifree( > * data fork to extents format. Note that the attr fork data has > * already been freed by xfs_attr_inactive. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > kmem_free(ip->i_df.if_u1.if_data); > ip->i_df.if_u1.if_data = NULL; > ip->i_df.if_bytes = 0; > @@ -2760,8 +2757,7 @@ xfs_ifree( > ip->i_d.di_flags2 = 0; > ip->i_d.di_dmevmask = 0; > ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ > - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; > > /* Don't attempt to replay owner changes for a deleted inode */ > ip->i_itemp->ili_fields &= ~(XFS_ILOG_AOWNER|XFS_ILOG_DOWNER); > @@ -3624,7 +3620,7 @@ xfs_iflush( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > *bpp = NULL; > @@ -3706,7 +3702,7 @@ xfs_iflush_int( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > ASSERT(iip != NULL && iip->ili_fields != 0); > > @@ -3728,8 +3724,8 @@ xfs_iflush_int( > } > if (S_ISREG(VFS_I(ip)->i_mode)) { > if (XFS_TEST_ERROR( > - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && > - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), > + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE, > mp, XFS_ERRTAG_IFLUSH_3)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: Bad regular inode %Lu, ptr "PTR_FMT, > @@ -3738,9 +3734,9 @@ xfs_iflush_int( > } > } else if (S_ISDIR(VFS_I(ip)->i_mode)) { > if (XFS_TEST_ERROR( > - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && > - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && > - (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL), > + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE && > + ip->i_df.if_format != XFS_DINODE_FMT_LOCAL, > mp, XFS_ERRTAG_IFLUSH_4)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: Bad directory inode %Lu, ptr "PTR_FMT, > @@ -3782,10 +3778,10 @@ xfs_iflush_int( > * If there are inline format data / attr forks attached to this inode, > * make sure they are not corrupt. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && > + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL && > xfs_ifork_verify_local_data(ip)) > goto flush_out; > - if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL && > + if (ip->i_afp && ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL && > xfs_ifork_verify_local_attr(ip)) > goto flush_out; > > diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h > index 24dae63ba16c0..dadcf19458960 100644 > --- a/fs/xfs/xfs_inode.h > +++ b/fs/xfs/xfs_inode.h > @@ -57,8 +57,6 @@ typedef struct xfs_inode { > > struct xfs_icdinode i_d; /* most of ondisk inode */ > > - unsigned int i_cformat; /* format of cow fork */ > - > /* VFS inode */ > struct inode i_vnode; /* embedded VFS inode */ > > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > index 401ba26aeed7b..ba47bf65b772b 100644 > --- a/fs/xfs/xfs_inode_item.c > +++ b/fs/xfs/xfs_inode_item.c > @@ -36,7 +36,7 @@ xfs_inode_item_data_fork_size( > { > struct xfs_inode *ip = iip->ili_inode; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_DEXT) && > ip->i_df.if_nextents > 0 && > @@ -77,7 +77,7 @@ xfs_inode_item_attr_fork_size( > { > struct xfs_inode *ip = iip->ili_inode; > > - switch (ip->i_d.di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_AEXT) && > ip->i_afp->if_nextents > 0 && > @@ -142,7 +142,7 @@ xfs_inode_item_format_data_fork( > struct xfs_inode *ip = iip->ili_inode; > size_t data_bytes; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > iip->ili_fields &= > ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); > @@ -227,7 +227,7 @@ xfs_inode_item_format_attr_fork( > struct xfs_inode *ip = iip->ili_inode; > size_t data_bytes; > > - switch (ip->i_d.di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > iip->ili_fields &= > ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); > @@ -305,7 +305,7 @@ xfs_inode_to_log_dinode( > struct inode *inode = VFS_I(ip); > > to->di_magic = XFS_DINODE_MAGIC; > - to->di_format = from->di_format; > + to->di_format = xfs_ifork_format(&ip->i_df); > to->di_uid = i_uid_read(inode); > to->di_gid = i_gid_read(inode); > to->di_projid_lo = from->di_projid & 0xffff; > @@ -329,7 +329,7 @@ xfs_inode_to_log_dinode( > to->di_nextents = xfs_ifork_nextents(&ip->i_df); > to->di_anextents = xfs_ifork_nextents(ip->i_afp); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > + to->di_aformat = xfs_ifork_format(ip->i_afp); > to->di_dmevmask = from->di_dmevmask; > to->di_dmstate = from->di_dmstate; > to->di_flags = from->di_flags; > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index b4fd918749e5f..6ae3a2457777a 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -856,7 +856,7 @@ xfs_buffered_write_iomap_begin( > > xfs_ilock(ip, XFS_ILOCK_EXCL); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, XFS_DATA_FORK)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(&ip->i_df)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > error = -EFSCORRUPTED; > goto out_unlock; > @@ -1263,7 +1263,7 @@ xfs_xattr_iomap_begin( > goto out_unlock; > } > > - ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); > + ASSERT(ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL); > error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, > &nimaps, XFS_BMAPI_ATTRFORK); > out_unlock: > diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c > index 80da86c5703fb..16ca97a7ff00f 100644 > --- a/fs/xfs/xfs_itable.c > +++ b/fs/xfs/xfs_itable.c > @@ -115,7 +115,7 @@ xfs_bulkstat_one_int( > buf->bs_cowextsize_blks = dic->di_cowextsize; > } > > - switch (dic->di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_DEV: > buf->bs_rdev = sysv_encode_dev(inode->i_rdev); > buf->bs_blksize = BLKDEV_IOSIZE; > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > index 8cf2fcb509c12..8e88a7ca387ea 100644 > --- a/fs/xfs/xfs_symlink.c > +++ b/fs/xfs/xfs_symlink.c > @@ -251,7 +251,7 @@ xfs_symlink( > xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen); > > ip->i_d.di_size = pathlen; > - ip->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + ip->i_df.if_format = XFS_DINODE_FMT_LOCAL; > xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE); > } else { > int offset; > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index ba2ab69e1fc7d..460136628a795 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -1897,7 +1897,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, > __entry->dev = VFS_I(ip)->i_sb->s_dev; > __entry->which = which; > __entry->ino = ip->i_ino; > - __entry->format = ip->i_d.di_format; > + __entry->format = ip->i_df.if_format; > __entry->nex = ip->i_df.if_nextents; > __entry->broot_size = ip->i_df.if_broot_bytes; > __entry->fork_off = XFS_IFORK_BOFF(ip); > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-10 7:24 ` [PATCH 5/6] xfs: move the fork format " Christoph Hellwig 2020-05-12 9:37 ` Chandan Babu R 2020-05-12 18:53 ` Brian Foster @ 2020-05-14 21:25 ` Darrick J. Wong 2020-05-16 13:58 ` Christoph Hellwig 2 siblings, 1 reply; 41+ messages in thread From: Darrick J. Wong @ 2020-05-14 21:25 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:03AM +0200, Christoph Hellwig wrote: > Both the data and attr fork have a format that is stored in the legacy > idinode. Move it into the xfs_ifork structure instead, where it uses > up padding. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/libxfs/xfs_attr.c | 12 +-- > fs/xfs/libxfs/xfs_attr_leaf.c | 32 ++++---- > fs/xfs/libxfs/xfs_bmap.c | 120 +++++++++++++---------------- > fs/xfs/libxfs/xfs_bmap_btree.c | 5 +- > fs/xfs/libxfs/xfs_dir2.c | 8 +- > fs/xfs/libxfs/xfs_dir2_sf.c | 13 ++-- > fs/xfs/libxfs/xfs_inode_buf.c | 6 +- > fs/xfs/libxfs/xfs_inode_buf.h | 2 - > fs/xfs/libxfs/xfs_inode_fork.c | 14 ++-- > fs/xfs/libxfs/xfs_inode_fork.h | 28 ++++--- > fs/xfs/libxfs/xfs_symlink_remote.c | 16 ++-- > fs/xfs/scrub/bmap.c | 4 +- > fs/xfs/scrub/dabtree.c | 2 +- > fs/xfs/scrub/dir.c | 7 +- > fs/xfs/xfs_aops.c | 2 +- > fs/xfs/xfs_attr_inactive.c | 2 +- > fs/xfs/xfs_attr_list.c | 4 +- > fs/xfs/xfs_bmap_util.c | 56 +++++++------- > fs/xfs/xfs_dir2_readdir.c | 2 +- > fs/xfs/xfs_icache.c | 1 - > fs/xfs/xfs_inode.c | 36 ++++----- > fs/xfs/xfs_inode.h | 2 - > fs/xfs/xfs_inode_item.c | 12 +-- > fs/xfs/xfs_iomap.c | 4 +- > fs/xfs/xfs_itable.c | 2 +- > fs/xfs/xfs_symlink.c | 2 +- > fs/xfs/xfs_trace.h | 2 +- > 27 files changed, 181 insertions(+), 215 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c > index 1b01675e9c80b..3b1bd6e112f89 100644 > --- a/fs/xfs/libxfs/xfs_attr.c > +++ b/fs/xfs/libxfs/xfs_attr.c > @@ -61,7 +61,7 @@ xfs_inode_hasattr( > struct xfs_inode *ip) > { > if (!XFS_IFORK_Q(ip) || > - (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > + (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && > ip->i_afp->if_nextents == 0)) > return 0; > return 1; > @@ -84,7 +84,7 @@ xfs_attr_get_ilocked( > if (!xfs_inode_hasattr(args->dp)) > return -ENOATTR; > > - if (args->dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) > + if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) > return xfs_attr_shortform_getvalue(args); > if (xfs_bmap_one_block(args->dp, XFS_ATTR_FORK)) > return xfs_attr_leaf_get(args); > @@ -212,14 +212,14 @@ xfs_attr_set_args( > * If the attribute list is non-existent or a shortform list, > * upgrade it to a single-leaf-block attribute list. > */ > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL || > - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && > + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL || > + (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && > dp->i_afp->if_nextents == 0)) { > > /* > * Build initial attribute list (if required). > */ > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) > + if (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS) > xfs_attr_shortform_create(args); > > /* > @@ -272,7 +272,7 @@ xfs_attr_remove_args( > > if (!xfs_inode_hasattr(dp)) { > error = -ENOATTR; > - } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { > + } else if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) { > ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); > error = xfs_attr_shortform_remove(args); > } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index 64b172180c42c..d7f3173ce3c31 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -539,7 +539,7 @@ xfs_attr_shortform_bytesfit( > /* rounded down */ > offset = (XFS_LITINO(mp) - bytes) >> 3; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_DEV) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) { > minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; > return (offset >= minforkoff) ? minforkoff : 0; > } > @@ -567,7 +567,7 @@ xfs_attr_shortform_bytesfit( > > dsize = dp->i_df.if_bytes; > > - switch (dp->i_d.di_format) { > + switch (dp->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > /* > * If there is no attr fork and the data fork is extents, > @@ -636,22 +636,19 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) > * Create the initial contents of a shortform attribute list. > */ > void > -xfs_attr_shortform_create(xfs_da_args_t *args) > +xfs_attr_shortform_create( > + struct xfs_da_args *args) > { > - xfs_attr_sf_hdr_t *hdr; > - xfs_inode_t *dp; > - struct xfs_ifork *ifp; > + struct xfs_inode *dp = args->dp; > + struct xfs_ifork *ifp = dp->i_afp; > + struct xfs_attr_sf_hdr *hdr; > > trace_xfs_attr_sf_create(args); > > - dp = args->dp; > - ASSERT(dp != NULL); > - ifp = dp->i_afp; > - ASSERT(ifp != NULL); > ASSERT(ifp->if_bytes == 0); > - if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) { > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS) { > ifp->if_flags &= ~XFS_IFEXTENTS; /* just in case */ > - dp->i_d.di_aformat = XFS_DINODE_FMT_LOCAL; > + ifp->if_format = XFS_DINODE_FMT_LOCAL; > ifp->if_flags |= XFS_IFINLINE; > } else { > ASSERT(ifp->if_flags & XFS_IFINLINE); > @@ -721,7 +718,6 @@ xfs_attr_fork_remove( > { > xfs_idestroy_fork(ip, XFS_ATTR_FORK); > ip->i_d.di_forkoff = 0; > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > ASSERT(ip->i_afp == NULL); > > @@ -774,7 +770,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) > totsize -= size; > if (totsize == sizeof(xfs_attr_sf_hdr_t) && > (mp->m_flags & XFS_MOUNT_ATTR2) && > - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && > + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && > !(args->op_flags & XFS_DA_OP_ADDNAME)) { > xfs_attr_fork_remove(dp, args->trans); > } else { > @@ -784,7 +780,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) > ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || > (args->op_flags & XFS_DA_OP_ADDNAME) || > !(mp->m_flags & XFS_MOUNT_ATTR2) || > - dp->i_d.di_format == XFS_DINODE_FMT_BTREE); > + dp->i_df.if_format == XFS_DINODE_FMT_BTREE); > xfs_trans_log_inode(args->trans, dp, > XFS_ILOG_CORE | XFS_ILOG_ADATA); > } > @@ -961,7 +957,7 @@ xfs_attr_shortform_allfit( > + be16_to_cpu(name_loc->valuelen); > } > if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) && > - (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) && > + (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) && > (bytes == sizeof(struct xfs_attr_sf_hdr))) > return -1; > return xfs_attr_shortform_bytesfit(dp, bytes); > @@ -980,7 +976,7 @@ xfs_attr_shortform_verify( > int i; > int64_t size; > > - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL); > + ASSERT(ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL); > ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK); > sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data; > size = ifp->if_bytes; > @@ -1084,7 +1080,7 @@ xfs_attr3_leaf_to_shortform( > > if (forkoff == -1) { > ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2); > - ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE); > + ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE); > xfs_attr_fork_remove(dp, args->trans); > goto out; > } > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index c1136be49abeb..edc63dba007f4 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -123,7 +123,7 @@ static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork) > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > return whichfork != XFS_COW_FORK && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > + ifp->if_format == XFS_DINODE_FMT_EXTENTS && > ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork); > } > > @@ -135,7 +135,7 @@ static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork) > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > return whichfork != XFS_COW_FORK && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && > + ifp->if_format == XFS_DINODE_FMT_BTREE && > ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork); > } > > @@ -215,8 +215,8 @@ xfs_bmap_forkoff_reset( > int whichfork) > { > if (whichfork == XFS_ATTR_FORK && > - ip->i_d.di_format != XFS_DINODE_FMT_DEV && > - ip->i_d.di_format != XFS_DINODE_FMT_BTREE) { > + ip->i_df.if_format != XFS_DINODE_FMT_DEV && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE) { > uint dfl_forkoff = xfs_default_attroffset(ip) >> 3; > > if (dfl_forkoff > ip->i_d.di_forkoff) > @@ -317,31 +317,28 @@ xfs_bmap_check_leaf_extents( > xfs_inode_t *ip, /* incore inode pointer */ > int whichfork) /* data or attr fork */ > { > + struct xfs_mount *mp = ip->i_mount; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_block *block; /* current btree block */ > xfs_fsblock_t bno; /* block # of "block" */ > xfs_buf_t *bp; /* buffer for "block" */ > int error; /* error return value */ > xfs_extnum_t i=0, j; /* index into the extents list */ > - struct xfs_ifork *ifp; /* fork structure */ > int level; /* btree level, for checking */ > - xfs_mount_t *mp; /* file system mount structure */ > __be64 *pp; /* pointer to block address */ > xfs_bmbt_rec_t *ep; /* pointer to current extent */ > xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */ > xfs_bmbt_rec_t *nextp; /* pointer to next extent */ > int bp_release = 0; > > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) { > + if (ifp->if_format != XFS_DINODE_FMT_BTREE) > return; > - } > > /* skip large extent count inodes */ > if (ip->i_df.if_nextents > 10000) > return; > > bno = NULLFSBLOCK; > - mp = ip->i_mount; > - ifp = XFS_IFORK_PTR(ip, whichfork); > block = ifp->if_broot; > /* > * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. > @@ -606,7 +603,7 @@ xfs_bmap_btree_to_extents( > ASSERT(cur); > ASSERT(whichfork != XFS_COW_FORK); > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); > ASSERT(be16_to_cpu(rblock->bb_level) == 1); > ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); > ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); > @@ -634,7 +631,7 @@ xfs_bmap_btree_to_extents( > xfs_iroot_realloc(ip, -1, whichfork); > ASSERT(ifp->if_broot == NULL); > ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > *logflagsp |= XFS_ILOG_CORE | xfs_ilog_fext(whichfork); > return 0; > } > @@ -670,7 +667,7 @@ xfs_bmap_extents_to_btree( > mp = ip->i_mount; > ASSERT(whichfork != XFS_COW_FORK); > ifp = XFS_IFORK_PTR(ip, whichfork); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_EXTENTS); > > /* > * Make space in the inode incore. This needs to be undone if we fail > @@ -694,7 +691,7 @@ xfs_bmap_extents_to_btree( > /* > * Convert to a btree with two levels, one record in root. > */ > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); > + ifp->if_format = XFS_DINODE_FMT_BTREE; > memset(&args, 0, sizeof(args)); > args.tp = tp; > args.mp = mp; > @@ -780,7 +777,7 @@ xfs_bmap_extents_to_btree( > xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); > out_root_realloc: > xfs_iroot_realloc(ip, -1, whichfork); > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > ASSERT(ifp->if_broot == NULL); > xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); > > @@ -802,7 +799,7 @@ xfs_bmap_local_to_extents_empty( > struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > > ASSERT(whichfork != XFS_COW_FORK); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > ASSERT(ifp->if_bytes == 0); > ASSERT(ifp->if_nextents == 0); > > @@ -811,7 +808,7 @@ xfs_bmap_local_to_extents_empty( > ifp->if_flags |= XFS_IFEXTENTS; > ifp->if_u1.if_root = NULL; > ifp->if_height = 0; > - XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); > + ifp->if_format = XFS_DINODE_FMT_EXTENTS; > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > } > > @@ -842,7 +839,7 @@ xfs_bmap_local_to_extents( > */ > ASSERT(!(S_ISREG(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK)); > ifp = XFS_IFORK_PTR(ip, whichfork); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > if (!ifp->if_bytes) { > xfs_bmap_local_to_extents_empty(tp, ip, whichfork); > @@ -1036,7 +1033,7 @@ xfs_bmap_set_attrforkoff( > int size, > int *version) > { > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_DEV: > ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; > break; > @@ -1094,13 +1091,6 @@ xfs_bmap_add_attrfork( > goto trans_cancel; > if (XFS_IFORK_Q(ip)) > goto trans_cancel; > - if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) { > - /* > - * For inodes coming from pre-6.2 filesystems. > - */ > - ASSERT(ip->i_d.di_aformat == 0); > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > - } > > xfs_trans_ijoin(tp, ip, 0); > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > @@ -1109,9 +1099,10 @@ xfs_bmap_add_attrfork( > goto trans_cancel; > ASSERT(ip->i_afp == NULL); > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, 0); > + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_afp->if_flags = XFS_IFEXTENTS; > logflags = 0; > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_bmap_add_attrfork_local(tp, ip, &logflags); > break; > @@ -1237,9 +1228,7 @@ xfs_iread_extents( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > - if (XFS_IS_CORRUPT(mp, > - XFS_IFORK_FORMAT(ip, whichfork) != > - XFS_DINODE_FMT_BTREE)) { > + if (XFS_IS_CORRUPT(mp, ifp->if_format != XFS_DINODE_FMT_BTREE)) { > error = -EFSCORRUPTED; > goto out; > } > @@ -1287,14 +1276,13 @@ xfs_bmap_first_unused( > xfs_fileoff_t lowest, max; > int error; > > - ASSERT(xfs_ifork_has_extents(ip, whichfork) || > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); > - > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > *first_unused = 0; > return 0; > } > > + ASSERT(xfs_ifork_has_extents(ifp)); > + > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > error = xfs_iread_extents(tp, ip, whichfork); > if (error) > @@ -1335,7 +1323,7 @@ xfs_bmap_last_before( > struct xfs_iext_cursor icur; > int error; > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_LOCAL: > *last_block = 0; > return 0; > @@ -1434,16 +1422,17 @@ xfs_bmap_last_offset( > xfs_fileoff_t *last_block, > int whichfork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_bmbt_irec rec; > int is_empty; > int error; > > *last_block = 0; > > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) > return 0; > > - if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ip, whichfork))) > + if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp))) > return -EFSCORRUPTED; > > error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); > @@ -1475,7 +1464,7 @@ xfs_bmap_one_block( > #endif /* !DEBUG */ > if (ifp->if_nextents != 1) > return 0; > - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS) > return 0; > ASSERT(ifp->if_flags & XFS_IFEXTENTS); > xfs_iext_first(ifp, &icur); > @@ -3895,10 +3884,9 @@ xfs_bmapi_read( > if (WARN_ON_ONCE(!ifp)) > return -EFSCORRUPTED; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > - XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) > return -EFSCORRUPTED; > - } > > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > @@ -4281,11 +4269,13 @@ xfs_bmapi_minleft( > struct xfs_inode *ip, > int fork) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, fork); > + > if (tp && tp->t_firstblock != NULLFSBLOCK) > return 0; > - if (XFS_IFORK_FORMAT(ip, fork) != XFS_DINODE_FMT_BTREE) > + if (ifp->if_format != XFS_DINODE_FMT_BTREE) > return 1; > - return be16_to_cpu(XFS_IFORK_PTR(ip, fork)->if_broot->bb_level) + 1; > + return be16_to_cpu(ifp->if_broot->bb_level) + 1; > } > > /* > @@ -4300,11 +4290,13 @@ xfs_bmapi_finish( > int whichfork, > int error) > { > + struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); > + > if ((bma->logflags & xfs_ilog_fext(whichfork)) && > - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + ifp->if_format != XFS_DINODE_FMT_EXTENTS) > bma->logflags &= ~xfs_ilog_fext(whichfork); > else if ((bma->logflags & xfs_ilog_fbroot(whichfork)) && > - XFS_IFORK_FORMAT(bma->ip, whichfork) != XFS_DINODE_FMT_BTREE) > + ifp->if_format != XFS_DINODE_FMT_BTREE) > bma->logflags &= ~xfs_ilog_fbroot(whichfork); > > if (bma->logflags) > @@ -4336,13 +4328,13 @@ xfs_bmapi_write( > .total = total, > }; > struct xfs_mount *mp = ip->i_mount; > - struct xfs_ifork *ifp; > + int whichfork = xfs_bmapi_whichfork(flags); > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > xfs_fileoff_t end; /* end of mapped file region */ > bool eof = false; /* after the end of extents */ > int error; /* error return */ > int n; /* current extent index */ > xfs_fileoff_t obno; /* old block number (offset) */ > - int whichfork; /* data or attr fork */ > > #ifdef DEBUG > xfs_fileoff_t orig_bno; /* original block number value */ > @@ -4357,13 +4349,12 @@ xfs_bmapi_write( > orig_mval = mval; > orig_nmap = *nmap; > #endif > - whichfork = xfs_bmapi_whichfork(flags); > > ASSERT(*nmap >= 1); > ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); > ASSERT(tp != NULL); > ASSERT(len > 0); > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format != XFS_DINODE_FMT_LOCAL); > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > ASSERT(!(flags & XFS_BMAPI_REMAP)); > > @@ -4379,7 +4370,7 @@ xfs_bmapi_write( > ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != > (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -4387,8 +4378,6 @@ xfs_bmapi_write( > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > > - ifp = XFS_IFORK_PTR(ip, whichfork); > - > XFS_STATS_INC(mp, xs_blk_mapw); > > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > @@ -4498,7 +4487,7 @@ xfs_bmapi_write( > if (error) > goto error0; > > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || > + ASSERT(ifp->if_format != XFS_DINODE_FMT_BTREE || > ifp->if_nextents > XFS_IFORK_MAXEXT(ip, whichfork)); > xfs_bmapi_finish(&bma, whichfork, 0); > xfs_bmap_validate_ret(orig_bno, orig_len, orig_flags, orig_mval, > @@ -4645,7 +4634,7 @@ xfs_bmapi_remap( > ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) != > (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -4689,9 +4678,9 @@ xfs_bmapi_remap( > error = xfs_bmap_btree_to_extents(tp, ip, cur, &logflags, whichfork); > > error0: > - if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) > + if (ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS) > logflags &= ~XFS_ILOG_DEXT; > - else if (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) > + else if (ip->i_df.if_format != XFS_DINODE_FMT_BTREE) > logflags &= ~XFS_ILOG_DBROOT; > > if (logflags) > @@ -5041,7 +5030,7 @@ xfs_bmap_del_extent_real( > * conversion to btree format, since the transaction will be dirty then. > */ > if (tp->t_blk_res == 0 && > - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > + ifp->if_format == XFS_DINODE_FMT_EXTENTS && > ifp->if_nextents >= XFS_IFORK_MAXEXT(ip, whichfork) && > del->br_startoff > got.br_startoff && del_endoff < got_endoff) > return -ENOSPC; > @@ -5284,7 +5273,7 @@ __xfs_bunmapi( > whichfork = xfs_bmapi_whichfork(flags); > ASSERT(whichfork != XFS_COW_FORK); > ifp = XFS_IFORK_PTR(ip, whichfork); > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork))) > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp))) > return -EFSCORRUPTED; > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > @@ -5322,7 +5311,7 @@ __xfs_bunmapi( > > logflags = 0; > if (ifp->if_flags & XFS_IFBROOT) { > - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); > cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); > cur->bc_ino.flags = 0; > } else > @@ -5567,10 +5556,10 @@ __xfs_bunmapi( > * logging the extent records if we've converted to btree format. > */ > if ((logflags & xfs_ilog_fext(whichfork)) && > - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) > + ifp->if_format != XFS_DINODE_FMT_EXTENTS) > logflags &= ~xfs_ilog_fext(whichfork); > else if ((logflags & xfs_ilog_fbroot(whichfork)) && > - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) > + ifp->if_format != XFS_DINODE_FMT_BTREE) > logflags &= ~xfs_ilog_fbroot(whichfork); > /* > * Log inode even in the error case, if the transaction > @@ -5781,7 +5770,7 @@ xfs_bmap_collapse_extents( > int error = 0; > int logflags = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -5898,7 +5887,7 @@ xfs_bmap_insert_extents( > int error = 0; > int logflags = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -5992,18 +5981,18 @@ xfs_bmap_split_extent( > xfs_fileoff_t split_fsb) > { > int whichfork = XFS_DATA_FORK; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); > struct xfs_btree_cur *cur = NULL; > struct xfs_bmbt_irec got; > struct xfs_bmbt_irec new; /* split extent */ > struct xfs_mount *mp = ip->i_mount; > - struct xfs_ifork *ifp; > xfs_fsblock_t gotblkcnt; /* new block count for got */ > struct xfs_iext_cursor icur; > int error = 0; > int logflags = 0; > int i = 0; > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > return -EFSCORRUPTED; > } > @@ -6011,7 +6000,6 @@ xfs_bmap_split_extent( > if (XFS_FORCED_SHUTDOWN(mp)) > return -EIO; > > - ifp = XFS_IFORK_PTR(ip, whichfork); > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > /* Read in all the extents */ > error = xfs_iread_extents(tp, ip, whichfork); > diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c > index 295a59cf88407..d9c63f17d2dec 100644 > --- a/fs/xfs/libxfs/xfs_bmap_btree.c > +++ b/fs/xfs/libxfs/xfs_bmap_btree.c > @@ -636,10 +636,7 @@ xfs_bmbt_change_owner( > > ASSERT(tp || buffer_list); > ASSERT(!(tp && buffer_list)); > - if (whichfork == XFS_DATA_FORK) > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_BTREE); > - else > - ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE); > + ASSERT(XFS_IFORK_PTR(ip, whichfork)->if_format == XFS_DINODE_FMT_BTREE); > > cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork); > if (!cur) > diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c > index dd6fcaaea318a..612a9c5e41b1c 100644 > --- a/fs/xfs/libxfs/xfs_dir2.c > +++ b/fs/xfs/libxfs/xfs_dir2.c > @@ -278,7 +278,7 @@ xfs_dir_createname( > if (!inum) > args->op_flags |= XFS_DA_OP_JUSTCHECK; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_addname(args); > goto out_free; > } > @@ -373,7 +373,7 @@ xfs_dir_lookup( > args->op_flags |= XFS_DA_OP_CILOOKUP; > > lock_mode = xfs_ilock_data_map_shared(dp); > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_lookup(args); > goto out_check_rval; > } > @@ -443,7 +443,7 @@ xfs_dir_removename( > args->whichfork = XFS_DATA_FORK; > args->trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_removename(args); > goto out_free; > } > @@ -504,7 +504,7 @@ xfs_dir_replace( > args->whichfork = XFS_DATA_FORK; > args->trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > rval = xfs_dir2_sf_replace(args); > goto out_free; > } > diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c > index 7b7f6fb2ea3b2..2463b5d734472 100644 > --- a/fs/xfs/libxfs/xfs_dir2_sf.c > +++ b/fs/xfs/libxfs/xfs_dir2_sf.c > @@ -343,7 +343,7 @@ xfs_dir2_block_to_sf( > */ > ASSERT(dp->i_df.if_bytes == 0); > xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size); > - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; > dp->i_d.di_size = size; > > logflags |= XFS_ILOG_DDATA; > @@ -710,11 +710,11 @@ xfs_dir2_sf_verify( > struct xfs_inode *ip) > { > struct xfs_mount *mp = ip->i_mount; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > struct xfs_dir2_sf_hdr *sfp; > struct xfs_dir2_sf_entry *sfep; > struct xfs_dir2_sf_entry *next_sfep; > char *endp; > - struct xfs_ifork *ifp; > xfs_ino_t ino; > int i; > int i8count; > @@ -723,9 +723,8 @@ xfs_dir2_sf_verify( > int error; > uint8_t filetype; > > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; > size = ifp->if_bytes; > > @@ -827,9 +826,9 @@ xfs_dir2_sf_create( > * If it's currently a zero-length extent file, > * convert it to local format. > */ > - if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { > + if (dp->i_df.if_format == XFS_DINODE_FMT_EXTENTS) { > dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ > - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; > xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); > dp->i_df.if_flags |= XFS_IFINLINE; > } > @@ -1027,7 +1026,7 @@ xfs_dir2_sf_replace_needblock( > int newsize; > struct xfs_dir2_sf_hdr *sfp; > > - if (dp->i_d.di_format != XFS_DINODE_FMT_LOCAL) > + if (dp->i_df.if_format != XFS_DINODE_FMT_LOCAL) > return false; > > sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data; > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index a374e2a81e764..ab555671e1543 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -225,7 +225,6 @@ xfs_inode_from_disk( > be16_to_cpu(from->di_projid_lo); > } > > - to->di_format = from->di_format; > i_uid_write(inode, be32_to_cpu(from->di_uid)); > i_gid_write(inode, be32_to_cpu(from->di_gid)); > > @@ -246,7 +245,6 @@ xfs_inode_from_disk( > to->di_nblocks = be64_to_cpu(from->di_nblocks); > to->di_extsize = be32_to_cpu(from->di_extsize); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > to->di_dmevmask = be32_to_cpu(from->di_dmevmask); > to->di_dmstate = be16_to_cpu(from->di_dmstate); > to->di_flags = be16_to_cpu(from->di_flags); > @@ -289,7 +287,7 @@ xfs_inode_to_disk( > to->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); > to->di_onlink = 0; > > - to->di_format = from->di_format; > + to->di_format = xfs_ifork_format(&ip->i_df); > to->di_uid = cpu_to_be32(i_uid_read(inode)); > to->di_gid = cpu_to_be32(i_gid_read(inode)); > to->di_projid_lo = cpu_to_be16(from->di_projid & 0xffff); > @@ -312,7 +310,7 @@ xfs_inode_to_disk( > to->di_nextents = cpu_to_be32(xfs_ifork_nextents(&ip->i_df)); > to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp)); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > + to->di_aformat = xfs_ifork_format(ip->i_afp); > to->di_dmevmask = cpu_to_be32(from->di_dmevmask); > to->di_dmstate = cpu_to_be16(from->di_dmstate); > to->di_flags = cpu_to_be16(from->di_flags); > diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h > index fecccfb26463c..865ac493c72a2 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.h > +++ b/fs/xfs/libxfs/xfs_inode_buf.h > @@ -16,14 +16,12 @@ struct xfs_dinode; > * format specific structures at the appropriate time. > */ > struct xfs_icdinode { > - int8_t di_format; /* format of di_c data */ > uint16_t di_flushiter; /* incremented on flush */ > uint32_t di_projid; /* owner's project id */ > xfs_fsize_t di_size; /* number of bytes in file */ > xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ > xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ > uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ > - int8_t di_aformat; /* format of attr fork's data */ > uint32_t di_dmevmask; /* DMIG event mask */ > uint16_t di_dmstate; /* DMIG state info */ > uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 195da3552c5b5..6562f2bcd15cc 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -228,6 +228,7 @@ xfs_iformat_data_fork( > struct inode *inode = VFS_I(ip); > int error; > > + ip->i_df.if_format = dip->di_format; > ip->i_df.if_nextents = be32_to_cpu(dip->di_nextents); > > switch (inode->i_mode & S_IFMT) { > @@ -241,7 +242,7 @@ xfs_iformat_data_fork( > case S_IFREG: > case S_IFLNK: > case S_IFDIR: > - switch (dip->di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, > be64_to_cpu(dip->di_size)); > @@ -283,9 +284,12 @@ xfs_iformat_attr_fork( > int error = 0; > > ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_NOFS); > + ip->i_afp->if_format = dip->di_aformat; > + if (unlikely(ip->i_afp->if_format == 0)) /* pre IRIX 6.2 file system */ > + ip->i_afp->if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_afp->if_nextents = be16_to_cpu(dip->di_anextents); > > - switch (dip->di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_LOCAL: > error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, > xfs_dfork_attr_shortform_size(dip)); > @@ -508,7 +512,7 @@ xfs_idestroy_fork( > * not local then we may or may not have an extents list, > * so check and free it up if we do. > */ > - if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > if (ifp->if_u1.if_data != NULL) { > kmem_free(ifp->if_u1.if_data); > ifp->if_u1.if_data = NULL; > @@ -605,7 +609,7 @@ xfs_iflush_fork( > } > cp = XFS_DFORK_PTR(dip, whichfork); > mp = ip->i_mount; > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_LOCAL: > if ((iip->ili_fields & dataflag[whichfork]) && > (ifp->if_bytes > 0)) { > @@ -678,7 +682,7 @@ xfs_ifork_init_cow( > ip->i_cowfp = kmem_zone_zalloc(xfs_ifork_zone, > KM_NOFS); > ip->i_cowfp->if_flags = XFS_IFEXTENTS; > - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > + ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS; > } > > /* Verify the inline contents of the data fork of an inode. */ > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index a69d425fe68df..d849cca103edd 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -23,6 +23,7 @@ struct xfs_ifork { > } if_u1; > short if_broot_bytes; /* bytes allocated for root */ > unsigned char if_flags; /* per-fork flags */ > + int8_t if_format; /* format of this fork */ > xfs_extnum_t if_nextents; /* # of extents in this fork */ > }; > > @@ -56,24 +57,14 @@ struct xfs_ifork { > ((w) == XFS_ATTR_FORK ? \ > XFS_IFORK_ASIZE(ip) : \ > 0)) > -#define XFS_IFORK_FORMAT(ip,w) \ > - ((w) == XFS_DATA_FORK ? \ > - (ip)->i_d.di_format : \ > - ((w) == XFS_ATTR_FORK ? \ > - (ip)->i_d.di_aformat : \ > - (ip)->i_cformat)) > -#define XFS_IFORK_FMT_SET(ip,w,n) \ > - ((w) == XFS_DATA_FORK ? \ > - ((ip)->i_d.di_format = (n)) : \ > - ((w) == XFS_ATTR_FORK ? \ > - ((ip)->i_d.di_aformat = (n)) : \ > - ((ip)->i_cformat = (n)))) > #define XFS_IFORK_MAXEXT(ip, w) \ > (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) > > -#define xfs_ifork_has_extents(ip, w) \ > - (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ > - XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) > +static inline bool xfs_ifork_has_extents(struct xfs_ifork *ifp) > +{ > + return ifp->if_format == XFS_DINODE_FMT_EXTENTS || > + ifp->if_format == XFS_DINODE_FMT_BTREE; > +} > > static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > { > @@ -82,6 +73,13 @@ static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) > return ifp->if_nextents; > } > > +static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp) > +{ > + if (!ifp) > + return XFS_DINODE_FMT_EXTENTS; > + return ifp->if_format; > +} > + > struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); > > int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c > index 3b8260ca7d1b8..594bc447a7dd2 100644 > --- a/fs/xfs/libxfs/xfs_symlink_remote.c > +++ b/fs/xfs/libxfs/xfs_symlink_remote.c > @@ -204,16 +204,12 @@ xfs_failaddr_t > xfs_symlink_shortform_verify( > struct xfs_inode *ip) > { > - char *sfp; > - char *endp; > - struct xfs_ifork *ifp; > - int size; > - > - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); > - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > - sfp = (char *)ifp->if_u1.if_data; > - size = ifp->if_bytes; > - endp = sfp + size; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); > + char *sfp = (char *)ifp->if_u1.if_data; > + int size = ifp->if_bytes; > + char *endp = sfp + size; > + > + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); > > /* > * Zero length symlinks should never occur in memory as they are > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > index 157f72efec5e9..dfa1533b4edfc 100644 > --- a/fs/xfs/scrub/bmap.c > +++ b/fs/xfs/scrub/bmap.c > @@ -598,7 +598,7 @@ xchk_bmap_check_rmaps( > size = 0; > break; > } > - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > + if (ifp->if_format != XFS_DINODE_FMT_BTREE && ifp can be null here if bmapbt scrub is called on a file that has no xattrs; this crashed my test vm immediately... --D > (size == 0 || ifp->if_nextents > 0)) > return 0; > > @@ -664,7 +664,7 @@ xchk_bmap( > } > > /* Check the fork values */ > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_UUID: > case XFS_DINODE_FMT_DEV: > case XFS_DINODE_FMT_LOCAL: > diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c > index 9a2e27ac13003..44b15015021f3 100644 > --- a/fs/xfs/scrub/dabtree.c > +++ b/fs/xfs/scrub/dabtree.c > @@ -468,7 +468,7 @@ xchk_da_btree( > int error; > > /* Skip short format data structures; no btree to scan. */ > - if (!xfs_ifork_has_extents(sc->ip, whichfork)) > + if (!xfs_ifork_has_extents(XFS_IFORK_PTR(sc->ip, whichfork))) > return 0; > > /* Set up initial da state. */ > diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c > index fe2a6e030c8a0..7c432997edade 100644 > --- a/fs/xfs/scrub/dir.c > +++ b/fs/xfs/scrub/dir.c > @@ -635,7 +635,7 @@ xchk_directory_blocks( > { > struct xfs_bmbt_irec got; > struct xfs_da_args args; > - struct xfs_ifork *ifp; > + struct xfs_ifork *ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); > struct xfs_mount *mp = sc->mp; > xfs_fileoff_t leaf_lblk; > xfs_fileoff_t free_lblk; > @@ -647,11 +647,10 @@ xchk_directory_blocks( > int error; > > /* Ignore local format directories. */ > - if (sc->ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && > - sc->ip->i_d.di_format != XFS_DINODE_FMT_BTREE) > + if (ifp->if_format != XFS_DINODE_FMT_EXTENTS && > + ifp->if_format != XFS_DINODE_FMT_BTREE) > return 0; > > - ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); > lblk = XFS_B_TO_FSB(mp, XFS_DIR2_DATA_OFFSET); > leaf_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_LEAF_OFFSET); > free_lblk = XFS_B_TO_FSB(mp, XFS_DIR2_FREE_OFFSET); > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > index 9d9cebf187268..2834cbf1212e5 100644 > --- a/fs/xfs/xfs_aops.c > +++ b/fs/xfs/xfs_aops.c > @@ -382,7 +382,7 @@ xfs_map_blocks( > */ > retry: > xfs_ilock(ip, XFS_ILOCK_SHARED); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > (ip->i_df.if_flags & XFS_IFEXTENTS)); > > /* > diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c > index c42f90e16b4fa..00ffc46c0bf71 100644 > --- a/fs/xfs/xfs_attr_inactive.c > +++ b/fs/xfs/xfs_attr_inactive.c > @@ -367,7 +367,7 @@ xfs_attr_inactive( > * removal below. > */ > if (xfs_inode_hasattr(dp) && > - dp->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + dp->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_attr3_root_inactive(&trans, dp); > if (error) > goto out_cancel; > diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c > index 5ff1d929d3b5f..e380bd1a9bfc9 100644 > --- a/fs/xfs/xfs_attr_list.c > +++ b/fs/xfs/xfs_attr_list.c > @@ -512,9 +512,9 @@ xfs_attr_list_ilocked( > */ > if (!xfs_inode_hasattr(dp)) > return 0; > - else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) > + if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) > return xfs_attr_shortform_list(context); > - else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) > + if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) > return xfs_attr_leaf_list(context); > return xfs_attr_node_list(context); > } > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index 4f277a6253b8d..5e32c3cf8e8c1 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -223,7 +223,7 @@ xfs_bmap_count_blocks( > if (!ifp) > return 0; > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_BTREE: > if (!(ifp->if_flags & XFS_IFEXTENTS)) { > error = xfs_iread_extents(tp, ip, whichfork); > @@ -449,7 +449,7 @@ xfs_getbmap( > break; > } > > - switch (XFS_IFORK_FORMAT(ip, whichfork)) { > + switch (ifp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > case XFS_DINODE_FMT_BTREE: > break; > @@ -1210,17 +1210,19 @@ xfs_swap_extents_check_format( > struct xfs_inode *ip, /* target inode */ > struct xfs_inode *tip) /* tmp inode */ > { > + struct xfs_ifork *ifp = &ip->i_df; > + struct xfs_ifork *tifp = &tip->i_df; > > /* Should never get a local format */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL || > - tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) > + if (ifp->if_format == XFS_DINODE_FMT_LOCAL || > + tifp->if_format == XFS_DINODE_FMT_LOCAL) > return -EINVAL; > > /* > * if the target inode has less extents that then temporary inode then > * why did userspace call us? > */ > - if (ip->i_df.if_nextents < tip->i_df.if_nextents) > + if (ifp->if_nextents < tifp->if_nextents) > return -EINVAL; > > /* > @@ -1235,18 +1237,18 @@ xfs_swap_extents_check_format( > * form then we will end up with the target inode in the wrong format > * as we already know there are less extents in the temp inode. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - tip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && > + tifp->if_format == XFS_DINODE_FMT_BTREE) > return -EINVAL; > > /* Check temp in extent form to max in target */ > - if (tip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - tip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + if (tifp->if_format == XFS_DINODE_FMT_EXTENTS && > + tifp->if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > > /* Check target in extent form to max in temp */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && > - ip->i_df.if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + if (ifp->if_format == XFS_DINODE_FMT_EXTENTS && > + ifp->if_nextents > XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > > /* > @@ -1258,22 +1260,20 @@ xfs_swap_extents_check_format( > * (a common defrag case) which will occur when the temp inode is in > * extent format... > */ > - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) { > + if (tifp->if_format == XFS_DINODE_FMT_BTREE) { > if (XFS_IFORK_Q(ip) && > - XFS_BMAP_BMDR_SPACE(tip->i_df.if_broot) > XFS_IFORK_BOFF(ip)) > + XFS_BMAP_BMDR_SPACE(tifp->if_broot) > XFS_IFORK_BOFF(ip)) > return -EINVAL; > - if (tip->i_df.if_nextents <= > - XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > + if (tifp->if_nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) > return -EINVAL; > } > > /* Reciprocal target->temp btree format checks */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { > + if (ifp->if_format == XFS_DINODE_FMT_BTREE) { > if (XFS_IFORK_Q(tip) && > XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > XFS_IFORK_BOFF(tip)) > return -EINVAL; > - if (ip->i_df.if_nextents <= > - XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > + if (ifp->if_nextents <= XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) > return -EINVAL; > } > > @@ -1426,14 +1426,14 @@ xfs_swap_extent_forks( > * Count the number of extended attribute blocks > */ > if (XFS_IFORK_Q(ip) && ip->i_afp->if_nextents > 0 && > - ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk, > &aforkblks); > if (error) > return error; > } > if (XFS_IFORK_Q(tip) && tip->i_afp->if_nextents > 0 && > - tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL) { > + tip->i_afp->if_format != XFS_DINODE_FMT_LOCAL) { > error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk, > &taforkblks); > if (error) > @@ -1448,9 +1448,9 @@ xfs_swap_extent_forks( > * bmbt scan as the last step. > */ > if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) { > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE) > (*target_log_flags) |= XFS_ILOG_DOWNER; > - if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE) > + if (tip->i_df.if_format == XFS_DINODE_FMT_BTREE) > (*src_log_flags) |= XFS_ILOG_DOWNER; > } > > @@ -1466,8 +1466,6 @@ xfs_swap_extent_forks( > ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks; > tip->i_d.di_nblocks = tmp + taforkblks - aforkblks; > > - swap(ip->i_d.di_format, tip->i_d.di_format); > - > /* > * The extents in the source inode could still contain speculative > * preallocation beyond EOF (e.g. the file is open but not modified > @@ -1481,7 +1479,7 @@ xfs_swap_extent_forks( > tip->i_delayed_blks = ip->i_delayed_blks; > ip->i_delayed_blks = 0; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > (*src_log_flags) |= XFS_ILOG_DEXT; > break; > @@ -1492,7 +1490,7 @@ xfs_swap_extent_forks( > break; > } > > - switch (tip->i_d.di_format) { > + switch (tip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > (*target_log_flags) |= XFS_ILOG_DEXT; > break; > @@ -1714,8 +1712,10 @@ xfs_swap_extents( > > /* Swap the cow forks. */ > if (xfs_sb_version_hasreflink(&mp->m_sb)) { > - ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); > - ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); > + ASSERT(!ip->i_cowfp || > + ip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); > + ASSERT(!tip->i_cowfp || > + tip->i_cowfp->if_format == XFS_DINODE_FMT_EXTENTS); > > swap(ip->i_cowfp, tip->i_cowfp); > > diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c > index 871ec22c9aee9..66deddd5e2969 100644 > --- a/fs/xfs/xfs_dir2_readdir.c > +++ b/fs/xfs/xfs_dir2_readdir.c > @@ -524,7 +524,7 @@ xfs_readdir( > args.geo = dp->i_mount->m_dir_geo; > args.trans = tp; > > - if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) > + if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) > rval = xfs_dir2_sf_getdents(&args, ctx); > else if ((rval = xfs_dir2_isblock(&args, &v))) > ; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index 791d5d5e318cf..c09b3e9eab1da 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -63,7 +63,6 @@ xfs_inode_alloc( > memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); > ip->i_afp = NULL; > ip->i_cowfp = NULL; > - ip->i_cformat = XFS_DINODE_FMT_EXTENTS; > memset(&ip->i_df, 0, sizeof(ip->i_df)); > ip->i_flags = 0; > ip->i_delayed_blks = 0; > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 1677c4e7207ed..64f5f9a440aed 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -112,7 +112,7 @@ xfs_ilock_data_map_shared( > { > uint lock_mode = XFS_ILOCK_SHARED; > > - if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && > + if (ip->i_df.if_format == XFS_DINODE_FMT_BTREE && > (ip->i_df.if_flags & XFS_IFEXTENTS) == 0) > lock_mode = XFS_ILOCK_EXCL; > xfs_ilock(ip, lock_mode); > @@ -125,7 +125,8 @@ xfs_ilock_attr_map_shared( > { > uint lock_mode = XFS_ILOCK_SHARED; > > - if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE && > + if (ip->i_afp && > + ip->i_afp->if_format == XFS_DINODE_FMT_BTREE && > (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0) > lock_mode = XFS_ILOCK_EXCL; > xfs_ilock(ip, lock_mode); > @@ -851,7 +852,7 @@ xfs_ialloc( > case S_IFCHR: > case S_IFBLK: > case S_IFSOCK: > - ip->i_d.di_format = XFS_DINODE_FMT_DEV; > + ip->i_df.if_format = XFS_DINODE_FMT_DEV; > ip->i_df.if_flags = 0; > flags |= XFS_ILOG_DEV; > break; > @@ -907,7 +908,7 @@ xfs_ialloc( > } > /* FALLTHROUGH */ > case S_IFLNK: > - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; > + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; > ip->i_df.if_flags = XFS_IFEXTENTS; > ip->i_df.if_bytes = 0; > ip->i_df.if_u1.if_root = NULL; > @@ -915,10 +916,6 @@ xfs_ialloc( > default: > ASSERT(0); > } > - /* > - * Attribute fork settings for new inode. > - */ > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > > /* > * Log the new values stuffed into the inode. > @@ -2749,7 +2746,7 @@ xfs_ifree( > * data fork to extents format. Note that the attr fork data has > * already been freed by xfs_attr_inactive. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL) { > + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) { > kmem_free(ip->i_df.if_u1.if_data); > ip->i_df.if_u1.if_data = NULL; > ip->i_df.if_bytes = 0; > @@ -2760,8 +2757,7 @@ xfs_ifree( > ip->i_d.di_flags2 = 0; > ip->i_d.di_dmevmask = 0; > ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ > - ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; > - ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; > + ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS; > > /* Don't attempt to replay owner changes for a deleted inode */ > ip->i_itemp->ili_fields &= ~(XFS_ILOG_AOWNER|XFS_ILOG_DOWNER); > @@ -3624,7 +3620,7 @@ xfs_iflush( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > > *bpp = NULL; > @@ -3706,7 +3702,7 @@ xfs_iflush_int( > > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); > ASSERT(xfs_isiflocked(ip)); > - ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || > + ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_BTREE || > ip->i_df.if_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); > ASSERT(iip != NULL && iip->ili_fields != 0); > > @@ -3728,8 +3724,8 @@ xfs_iflush_int( > } > if (S_ISREG(VFS_I(ip)->i_mode)) { > if (XFS_TEST_ERROR( > - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && > - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), > + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE, > mp, XFS_ERRTAG_IFLUSH_3)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: Bad regular inode %Lu, ptr "PTR_FMT, > @@ -3738,9 +3734,9 @@ xfs_iflush_int( > } > } else if (S_ISDIR(VFS_I(ip)->i_mode)) { > if (XFS_TEST_ERROR( > - (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && > - (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && > - (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL), > + ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && > + ip->i_df.if_format != XFS_DINODE_FMT_BTREE && > + ip->i_df.if_format != XFS_DINODE_FMT_LOCAL, > mp, XFS_ERRTAG_IFLUSH_4)) { > xfs_alert_tag(mp, XFS_PTAG_IFLUSH, > "%s: Bad directory inode %Lu, ptr "PTR_FMT, > @@ -3782,10 +3778,10 @@ xfs_iflush_int( > * If there are inline format data / attr forks attached to this inode, > * make sure they are not corrupt. > */ > - if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL && > + if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL && > xfs_ifork_verify_local_data(ip)) > goto flush_out; > - if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL && > + if (ip->i_afp && ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL && > xfs_ifork_verify_local_attr(ip)) > goto flush_out; > > diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h > index 24dae63ba16c0..dadcf19458960 100644 > --- a/fs/xfs/xfs_inode.h > +++ b/fs/xfs/xfs_inode.h > @@ -57,8 +57,6 @@ typedef struct xfs_inode { > > struct xfs_icdinode i_d; /* most of ondisk inode */ > > - unsigned int i_cformat; /* format of cow fork */ > - > /* VFS inode */ > struct inode i_vnode; /* embedded VFS inode */ > > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > index 401ba26aeed7b..ba47bf65b772b 100644 > --- a/fs/xfs/xfs_inode_item.c > +++ b/fs/xfs/xfs_inode_item.c > @@ -36,7 +36,7 @@ xfs_inode_item_data_fork_size( > { > struct xfs_inode *ip = iip->ili_inode; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_DEXT) && > ip->i_df.if_nextents > 0 && > @@ -77,7 +77,7 @@ xfs_inode_item_attr_fork_size( > { > struct xfs_inode *ip = iip->ili_inode; > > - switch (ip->i_d.di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > if ((iip->ili_fields & XFS_ILOG_AEXT) && > ip->i_afp->if_nextents > 0 && > @@ -142,7 +142,7 @@ xfs_inode_item_format_data_fork( > struct xfs_inode *ip = iip->ili_inode; > size_t data_bytes; > > - switch (ip->i_d.di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_EXTENTS: > iip->ili_fields &= > ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV); > @@ -227,7 +227,7 @@ xfs_inode_item_format_attr_fork( > struct xfs_inode *ip = iip->ili_inode; > size_t data_bytes; > > - switch (ip->i_d.di_aformat) { > + switch (ip->i_afp->if_format) { > case XFS_DINODE_FMT_EXTENTS: > iip->ili_fields &= > ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); > @@ -305,7 +305,7 @@ xfs_inode_to_log_dinode( > struct inode *inode = VFS_I(ip); > > to->di_magic = XFS_DINODE_MAGIC; > - to->di_format = from->di_format; > + to->di_format = xfs_ifork_format(&ip->i_df); > to->di_uid = i_uid_read(inode); > to->di_gid = i_gid_read(inode); > to->di_projid_lo = from->di_projid & 0xffff; > @@ -329,7 +329,7 @@ xfs_inode_to_log_dinode( > to->di_nextents = xfs_ifork_nextents(&ip->i_df); > to->di_anextents = xfs_ifork_nextents(ip->i_afp); > to->di_forkoff = from->di_forkoff; > - to->di_aformat = from->di_aformat; > + to->di_aformat = xfs_ifork_format(ip->i_afp); > to->di_dmevmask = from->di_dmevmask; > to->di_dmstate = from->di_dmstate; > to->di_flags = from->di_flags; > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index b4fd918749e5f..6ae3a2457777a 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -856,7 +856,7 @@ xfs_buffered_write_iomap_begin( > > xfs_ilock(ip, XFS_ILOCK_EXCL); > > - if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, XFS_DATA_FORK)) || > + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(&ip->i_df)) || > XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { > error = -EFSCORRUPTED; > goto out_unlock; > @@ -1263,7 +1263,7 @@ xfs_xattr_iomap_begin( > goto out_unlock; > } > > - ASSERT(ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL); > + ASSERT(ip->i_afp->if_format != XFS_DINODE_FMT_LOCAL); > error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, > &nimaps, XFS_BMAPI_ATTRFORK); > out_unlock: > diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c > index 80da86c5703fb..16ca97a7ff00f 100644 > --- a/fs/xfs/xfs_itable.c > +++ b/fs/xfs/xfs_itable.c > @@ -115,7 +115,7 @@ xfs_bulkstat_one_int( > buf->bs_cowextsize_blks = dic->di_cowextsize; > } > > - switch (dic->di_format) { > + switch (ip->i_df.if_format) { > case XFS_DINODE_FMT_DEV: > buf->bs_rdev = sysv_encode_dev(inode->i_rdev); > buf->bs_blksize = BLKDEV_IOSIZE; > diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c > index 8cf2fcb509c12..8e88a7ca387ea 100644 > --- a/fs/xfs/xfs_symlink.c > +++ b/fs/xfs/xfs_symlink.c > @@ -251,7 +251,7 @@ xfs_symlink( > xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen); > > ip->i_d.di_size = pathlen; > - ip->i_d.di_format = XFS_DINODE_FMT_LOCAL; > + ip->i_df.if_format = XFS_DINODE_FMT_LOCAL; > xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE); > } else { > int offset; > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index ba2ab69e1fc7d..460136628a795 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -1897,7 +1897,7 @@ DECLARE_EVENT_CLASS(xfs_swap_extent_class, > __entry->dev = VFS_I(ip)->i_sb->s_dev; > __entry->which = which; > __entry->ino = ip->i_ino; > - __entry->format = ip->i_d.di_format; > + __entry->format = ip->i_df.if_format; > __entry->nex = ip->i_df.if_nextents; > __entry->broot_size = ip->i_df.if_broot_bytes; > __entry->fork_off = XFS_IFORK_BOFF(ip); > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-14 21:25 ` Darrick J. Wong @ 2020-05-16 13:58 ` Christoph Hellwig 2020-05-16 17:01 ` Darrick J. Wong 0 siblings, 1 reply; 41+ messages in thread From: Christoph Hellwig @ 2020-05-16 13:58 UTC (permalink / raw) To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs On Thu, May 14, 2020 at 02:25:41PM -0700, Darrick J. Wong wrote: [~1000 lines of fullquote deleted until I hit the first comment, sigh..] > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > index 157f72efec5e9..dfa1533b4edfc 100644 > > --- a/fs/xfs/scrub/bmap.c > > +++ b/fs/xfs/scrub/bmap.c > > @@ -598,7 +598,7 @@ xchk_bmap_check_rmaps( > > size = 0; > > break; > > } > > - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > > + if (ifp->if_format != XFS_DINODE_FMT_BTREE && > > ifp can be null here if bmapbt scrub is called on a file that has no > xattrs; this crashed my test vm immediately... What tests is that? And xfstests auto run did not hit it, even if a NULL check here seems sensible. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-16 13:58 ` Christoph Hellwig @ 2020-05-16 17:01 ` Darrick J. Wong 2020-05-16 18:01 ` Darrick J. Wong 0 siblings, 1 reply; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 17:01 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sat, May 16, 2020 at 03:58:08PM +0200, Christoph Hellwig wrote: > On Thu, May 14, 2020 at 02:25:41PM -0700, Darrick J. Wong wrote: > > [~1000 lines of fullquote deleted until I hit the first comment, sigh..] > > > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > > index 157f72efec5e9..dfa1533b4edfc 100644 > > > --- a/fs/xfs/scrub/bmap.c > > > +++ b/fs/xfs/scrub/bmap.c > > > @@ -598,7 +598,7 @@ xchk_bmap_check_rmaps( > > > size = 0; > > > break; > > > } > > > - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > > > + if (ifp->if_format != XFS_DINODE_FMT_BTREE && > > > > ifp can be null here if bmapbt scrub is called on a file that has no > > xattrs; this crashed my test vm immediately... > > What tests is that? And xfstests auto run did not hit it, even if a > NULL check here seems sensible. In my case it was the xfs_scrub run after generic/001 that did it. I think we're covered against null *ifp in most cases because they're guarded by an if(XFS_IFORK_Q()); it's jut here where I went around shortcutting. Maybe I should just fix this function for you... :) --D ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-16 17:01 ` Darrick J. Wong @ 2020-05-16 18:01 ` Darrick J. Wong 2020-05-16 18:16 ` Christoph Hellwig 0 siblings, 1 reply; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 18:01 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sat, May 16, 2020 at 10:01:43AM -0700, Darrick J. Wong wrote: > On Sat, May 16, 2020 at 03:58:08PM +0200, Christoph Hellwig wrote: > > On Thu, May 14, 2020 at 02:25:41PM -0700, Darrick J. Wong wrote: > > > > [~1000 lines of fullquote deleted until I hit the first comment, sigh..] > > > > > > diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c > > > > index 157f72efec5e9..dfa1533b4edfc 100644 > > > > --- a/fs/xfs/scrub/bmap.c > > > > +++ b/fs/xfs/scrub/bmap.c > > > > @@ -598,7 +598,7 @@ xchk_bmap_check_rmaps( > > > > size = 0; > > > > break; > > > > } > > > > - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE && > > > > + if (ifp->if_format != XFS_DINODE_FMT_BTREE && > > > > > > ifp can be null here if bmapbt scrub is called on a file that has no > > > xattrs; this crashed my test vm immediately... > > > > What tests is that? And xfstests auto run did not hit it, even if a > > NULL check here seems sensible. > > In my case it was the xfs_scrub run after generic/001 that did it. > > I think we're covered against null *ifp in most cases because they're > guarded by an if(XFS_IFORK_Q()); it's jut here where I went around > shortcutting. Maybe I should just fix this function for you... :) Hmm, that sounded meaner than I intended it to be. :/ Also, it turns out that it's pretty easy to fix this as part of fixing the contorted logic in patch 1 (aka xchk_bmap_check_rmaps) so I'll do that there. > --D ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-16 18:01 ` Darrick J. Wong @ 2020-05-16 18:16 ` Christoph Hellwig 2020-05-16 18:29 ` Darrick J. Wong 0 siblings, 1 reply; 41+ messages in thread From: Christoph Hellwig @ 2020-05-16 18:16 UTC (permalink / raw) To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs On Sat, May 16, 2020 at 11:01:50AM -0700, Darrick J. Wong wrote: > > In my case it was the xfs_scrub run after generic/001 that did it. > > > > I think we're covered against null *ifp in most cases because they're > > guarded by an if(XFS_IFORK_Q()); it's jut here where I went around > > shortcutting. Maybe I should just fix this function for you... :) > > Hmm, that sounded meaner than I intended it to be. :/ > > Also, it turns out that it's pretty easy to fix this as part of fixing > the contorted logic in patch 1 (aka xchk_bmap_check_rmaps) so I'll do > that there. How about you send a patch to just fix up that function for now, and I'll rebase on top of that? ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 5/6] xfs: move the fork format fields into struct xfs_ifork 2020-05-16 18:16 ` Christoph Hellwig @ 2020-05-16 18:29 ` Darrick J. Wong 0 siblings, 0 replies; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 18:29 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sat, May 16, 2020 at 08:16:58PM +0200, Christoph Hellwig wrote: > On Sat, May 16, 2020 at 11:01:50AM -0700, Darrick J. Wong wrote: > > > In my case it was the xfs_scrub run after generic/001 that did it. > > > > > > I think we're covered against null *ifp in most cases because they're > > > guarded by an if(XFS_IFORK_Q()); it's jut here where I went around > > > shortcutting. Maybe I should just fix this function for you... :) > > > > Hmm, that sounded meaner than I intended it to be. :/ > > > > Also, it turns out that it's pretty easy to fix this as part of fixing > > the contorted logic in patch 1 (aka xchk_bmap_check_rmaps) so I'll do > > that there. > > How about you send a patch to just fix up that function for now, > and I'll rebase on top of that? Ok. --D ^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 6/6] xfs: cleanup xfs_idestroy_fork 2020-05-10 7:23 move the extent count and format into struct xfs_ifork Christoph Hellwig ` (4 preceding siblings ...) 2020-05-10 7:24 ` [PATCH 5/6] xfs: move the fork format " Christoph Hellwig @ 2020-05-10 7:24 ` Christoph Hellwig 2020-05-12 9:48 ` Chandan Babu R 2020-05-12 18:54 ` Brian Foster 5 siblings, 2 replies; 41+ messages in thread From: Christoph Hellwig @ 2020-05-10 7:24 UTC (permalink / raw) To: linux-xfs Move freeing the dynamically allocated attr and COW fork, as well as zeroing the pointers where actually needed into the callers, and just pass the xfs_ifork structure to xfs_idestroy_fork. Simplify the kmem_free calls by not checking for NULL first, and not zeroing the pointers in structure that are about to be freed (either the ifork or the containing inode in case of the data fork). Signed-off-by: Christoph Hellwig <hch@lst.de> --- fs/xfs/libxfs/xfs_attr_leaf.c | 7 +++---- fs/xfs/libxfs/xfs_inode_buf.c | 2 +- fs/xfs/libxfs/xfs_inode_fork.c | 36 +++++++++------------------------- fs/xfs/libxfs/xfs_inode_fork.h | 2 +- fs/xfs/xfs_attr_inactive.c | 7 +++++-- fs/xfs/xfs_icache.c | 15 ++++++++------ 6 files changed, 28 insertions(+), 41 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index d7f3173ce3c31..8d775942f1c6c 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -716,11 +716,10 @@ xfs_attr_fork_remove( struct xfs_inode *ip, struct xfs_trans *tp) { - xfs_idestroy_fork(ip, XFS_ATTR_FORK); + xfs_idestroy_fork(ip->i_afp); + kmem_cache_free(xfs_ifork_zone, ip->i_afp); + ip->i_afp = NULL; ip->i_d.di_forkoff = 0; - - ASSERT(ip->i_afp == NULL); - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index ab555671e1543..6f84ea85fdd83 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -271,7 +271,7 @@ xfs_inode_from_disk( return 0; out_destroy_data_fork: - xfs_idestroy_fork(ip, XFS_DATA_FORK); + xfs_idestroy_fork(&ip->i_df); return error; } diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 6562f2bcd15cc..577cc20e03170 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -495,38 +495,20 @@ xfs_idata_realloc( void xfs_idestroy_fork( - xfs_inode_t *ip, - int whichfork) + struct xfs_ifork *ifp) { - struct xfs_ifork *ifp; - - ifp = XFS_IFORK_PTR(ip, whichfork); - if (ifp->if_broot != NULL) { - kmem_free(ifp->if_broot); - ifp->if_broot = NULL; - } + kmem_free(ifp->if_broot); /* - * If the format is local, then we can't have an extents - * array so just look for an inline data array. If we're - * not local then we may or may not have an extents list, - * so check and free it up if we do. + * If the format is local, then we can't have an extents array so just + * look for an inline data array. If we're not local then we may or may + * not have an extents list, so check and free it up if we do. */ if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { - if (ifp->if_u1.if_data != NULL) { - kmem_free(ifp->if_u1.if_data); - ifp->if_u1.if_data = NULL; - } - } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) { - xfs_iext_destroy(ifp); - } - - if (whichfork == XFS_ATTR_FORK) { - kmem_cache_free(xfs_ifork_zone, ip->i_afp); - ip->i_afp = NULL; - } else if (whichfork == XFS_COW_FORK) { - kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); - ip->i_cowfp = NULL; + kmem_free(ifp->if_u1.if_data); + } else if (ifp->if_flags & XFS_IFEXTENTS) { + if (ifp->if_height) + xfs_iext_destroy(ifp); } } diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index d849cca103edd..a4953e95c4f3f 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -86,7 +86,7 @@ int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); int xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *); void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, struct xfs_inode_log_item *, int); -void xfs_idestroy_fork(struct xfs_inode *, int); +void xfs_idestroy_fork(struct xfs_ifork *ifp); void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, int whichfork); void xfs_iroot_realloc(struct xfs_inode *, int, int); diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index 00ffc46c0bf71..bfad669e6b2f8 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -388,8 +388,11 @@ xfs_attr_inactive( xfs_trans_cancel(trans); out_destroy_fork: /* kill the in-core attr fork before we drop the inode lock */ - if (dp->i_afp) - xfs_idestroy_fork(dp, XFS_ATTR_FORK); + if (dp->i_afp) { + xfs_idestroy_fork(dp->i_afp); + kmem_cache_free(xfs_ifork_zone, dp->i_afp); + dp->i_afp = NULL; + } if (lock_mode) xfs_iunlock(dp, lock_mode); return error; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index c09b3e9eab1da..d806d3bfa8936 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -87,15 +87,18 @@ xfs_inode_free_callback( case S_IFREG: case S_IFDIR: case S_IFLNK: - xfs_idestroy_fork(ip, XFS_DATA_FORK); + xfs_idestroy_fork(&ip->i_df); break; } - if (ip->i_afp) - xfs_idestroy_fork(ip, XFS_ATTR_FORK); - if (ip->i_cowfp) - xfs_idestroy_fork(ip, XFS_COW_FORK); - + if (ip->i_afp) { + xfs_idestroy_fork(ip->i_afp); + kmem_cache_free(xfs_ifork_zone, ip->i_afp); + } + if (ip->i_cowfp) { + xfs_idestroy_fork(ip->i_cowfp); + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); + } if (ip->i_itemp) { ASSERT(!test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)); -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 6/6] xfs: cleanup xfs_idestroy_fork 2020-05-10 7:24 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig @ 2020-05-12 9:48 ` Chandan Babu R 2020-05-12 18:54 ` Brian Foster 1 sibling, 0 replies; 41+ messages in thread From: Chandan Babu R @ 2020-05-12 9:48 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sunday 10 May 2020 12:54:04 PM IST Christoph Hellwig wrote: > Move freeing the dynamically allocated attr and COW fork, as well > as zeroing the pointers where actually needed into the callers, and > just pass the xfs_ifork structure to xfs_idestroy_fork. Simplify > the kmem_free calls by not checking for NULL first, and not zeroing > the pointers in structure that are about to be freed (either the > ifork or the containing inode in case of the data fork). > The changes look good to me. Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/libxfs/xfs_attr_leaf.c | 7 +++---- > fs/xfs/libxfs/xfs_inode_buf.c | 2 +- > fs/xfs/libxfs/xfs_inode_fork.c | 36 +++++++++------------------------- > fs/xfs/libxfs/xfs_inode_fork.h | 2 +- > fs/xfs/xfs_attr_inactive.c | 7 +++++-- > fs/xfs/xfs_icache.c | 15 ++++++++------ > 6 files changed, 28 insertions(+), 41 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index d7f3173ce3c31..8d775942f1c6c 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -716,11 +716,10 @@ xfs_attr_fork_remove( > struct xfs_inode *ip, > struct xfs_trans *tp) > { > - xfs_idestroy_fork(ip, XFS_ATTR_FORK); > + xfs_idestroy_fork(ip->i_afp); > + kmem_cache_free(xfs_ifork_zone, ip->i_afp); > + ip->i_afp = NULL; > ip->i_d.di_forkoff = 0; > - > - ASSERT(ip->i_afp == NULL); > - > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > } > > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index ab555671e1543..6f84ea85fdd83 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -271,7 +271,7 @@ xfs_inode_from_disk( > return 0; > > out_destroy_data_fork: > - xfs_idestroy_fork(ip, XFS_DATA_FORK); > + xfs_idestroy_fork(&ip->i_df); > return error; > } > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 6562f2bcd15cc..577cc20e03170 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -495,38 +495,20 @@ xfs_idata_realloc( > > void > xfs_idestroy_fork( > - xfs_inode_t *ip, > - int whichfork) > + struct xfs_ifork *ifp) > { > - struct xfs_ifork *ifp; > - > - ifp = XFS_IFORK_PTR(ip, whichfork); > - if (ifp->if_broot != NULL) { > - kmem_free(ifp->if_broot); > - ifp->if_broot = NULL; > - } > + kmem_free(ifp->if_broot); > > /* > - * If the format is local, then we can't have an extents > - * array so just look for an inline data array. If we're > - * not local then we may or may not have an extents list, > - * so check and free it up if we do. > + * If the format is local, then we can't have an extents array so just > + * look for an inline data array. If we're not local then we may or may > + * not have an extents list, so check and free it up if we do. > */ > if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > - if (ifp->if_u1.if_data != NULL) { > - kmem_free(ifp->if_u1.if_data); > - ifp->if_u1.if_data = NULL; > - } > - } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) { > - xfs_iext_destroy(ifp); > - } > - > - if (whichfork == XFS_ATTR_FORK) { > - kmem_cache_free(xfs_ifork_zone, ip->i_afp); > - ip->i_afp = NULL; > - } else if (whichfork == XFS_COW_FORK) { > - kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > - ip->i_cowfp = NULL; > + kmem_free(ifp->if_u1.if_data); > + } else if (ifp->if_flags & XFS_IFEXTENTS) { > + if (ifp->if_height) > + xfs_iext_destroy(ifp); > } > } > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index d849cca103edd..a4953e95c4f3f 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -86,7 +86,7 @@ int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > int xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *); > void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, > struct xfs_inode_log_item *, int); > -void xfs_idestroy_fork(struct xfs_inode *, int); > +void xfs_idestroy_fork(struct xfs_ifork *ifp); > void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, > int whichfork); > void xfs_iroot_realloc(struct xfs_inode *, int, int); > diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c > index 00ffc46c0bf71..bfad669e6b2f8 100644 > --- a/fs/xfs/xfs_attr_inactive.c > +++ b/fs/xfs/xfs_attr_inactive.c > @@ -388,8 +388,11 @@ xfs_attr_inactive( > xfs_trans_cancel(trans); > out_destroy_fork: > /* kill the in-core attr fork before we drop the inode lock */ > - if (dp->i_afp) > - xfs_idestroy_fork(dp, XFS_ATTR_FORK); > + if (dp->i_afp) { > + xfs_idestroy_fork(dp->i_afp); > + kmem_cache_free(xfs_ifork_zone, dp->i_afp); > + dp->i_afp = NULL; > + } > if (lock_mode) > xfs_iunlock(dp, lock_mode); > return error; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index c09b3e9eab1da..d806d3bfa8936 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -87,15 +87,18 @@ xfs_inode_free_callback( > case S_IFREG: > case S_IFDIR: > case S_IFLNK: > - xfs_idestroy_fork(ip, XFS_DATA_FORK); > + xfs_idestroy_fork(&ip->i_df); > break; > } > > - if (ip->i_afp) > - xfs_idestroy_fork(ip, XFS_ATTR_FORK); > - if (ip->i_cowfp) > - xfs_idestroy_fork(ip, XFS_COW_FORK); > - > + if (ip->i_afp) { > + xfs_idestroy_fork(ip->i_afp); > + kmem_cache_free(xfs_ifork_zone, ip->i_afp); > + } > + if (ip->i_cowfp) { > + xfs_idestroy_fork(ip->i_cowfp); > + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > + } > if (ip->i_itemp) { > ASSERT(!test_bit(XFS_LI_IN_AIL, > &ip->i_itemp->ili_item.li_flags)); > -- chandan ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 6/6] xfs: cleanup xfs_idestroy_fork 2020-05-10 7:24 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig 2020-05-12 9:48 ` Chandan Babu R @ 2020-05-12 18:54 ` Brian Foster 2020-05-16 18:10 ` Darrick J. Wong 1 sibling, 1 reply; 41+ messages in thread From: Brian Foster @ 2020-05-12 18:54 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs On Sun, May 10, 2020 at 09:24:04AM +0200, Christoph Hellwig wrote: > Move freeing the dynamically allocated attr and COW fork, as well > as zeroing the pointers where actually needed into the callers, and > just pass the xfs_ifork structure to xfs_idestroy_fork. Simplify > the kmem_free calls by not checking for NULL first, and not zeroing > the pointers in structure that are about to be freed (either the > ifork or the containing inode in case of the data fork). > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > fs/xfs/libxfs/xfs_attr_leaf.c | 7 +++---- > fs/xfs/libxfs/xfs_inode_buf.c | 2 +- > fs/xfs/libxfs/xfs_inode_fork.c | 36 +++++++++------------------------- > fs/xfs/libxfs/xfs_inode_fork.h | 2 +- > fs/xfs/xfs_attr_inactive.c | 7 +++++-- > fs/xfs/xfs_icache.c | 15 ++++++++------ > 6 files changed, 28 insertions(+), 41 deletions(-) > ... > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index 6562f2bcd15cc..577cc20e03170 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -495,38 +495,20 @@ xfs_idata_realloc( > > void > xfs_idestroy_fork( > - xfs_inode_t *ip, > - int whichfork) > + struct xfs_ifork *ifp) > { > - struct xfs_ifork *ifp; > - > - ifp = XFS_IFORK_PTR(ip, whichfork); > - if (ifp->if_broot != NULL) { > - kmem_free(ifp->if_broot); > - ifp->if_broot = NULL; > - } > + kmem_free(ifp->if_broot); I think this function should still reset the pointers within the ifp that it frees (if_broot and if_data below), particularly as long as there are multiple callers that pass the data fork because it is not immediately/independently freed. IOW, it's not clear if something happens to reset i_mode between when xfs_inode_from_disk() might fail and destroy the data fork, and when the inode is ultimately freed and we look at i_mode to determine whether to destroy the data fork. Brian > > /* > - * If the format is local, then we can't have an extents > - * array so just look for an inline data array. If we're > - * not local then we may or may not have an extents list, > - * so check and free it up if we do. > + * If the format is local, then we can't have an extents array so just > + * look for an inline data array. If we're not local then we may or may > + * not have an extents list, so check and free it up if we do. > */ > if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > - if (ifp->if_u1.if_data != NULL) { > - kmem_free(ifp->if_u1.if_data); > - ifp->if_u1.if_data = NULL; > - } > - } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) { > - xfs_iext_destroy(ifp); > - } > - > - if (whichfork == XFS_ATTR_FORK) { > - kmem_cache_free(xfs_ifork_zone, ip->i_afp); > - ip->i_afp = NULL; > - } else if (whichfork == XFS_COW_FORK) { > - kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > - ip->i_cowfp = NULL; > + kmem_free(ifp->if_u1.if_data); > + } else if (ifp->if_flags & XFS_IFEXTENTS) { > + if (ifp->if_height) > + xfs_iext_destroy(ifp); > } > } > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index d849cca103edd..a4953e95c4f3f 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -86,7 +86,7 @@ int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > int xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *); > void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, > struct xfs_inode_log_item *, int); > -void xfs_idestroy_fork(struct xfs_inode *, int); > +void xfs_idestroy_fork(struct xfs_ifork *ifp); > void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, > int whichfork); > void xfs_iroot_realloc(struct xfs_inode *, int, int); > diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c > index 00ffc46c0bf71..bfad669e6b2f8 100644 > --- a/fs/xfs/xfs_attr_inactive.c > +++ b/fs/xfs/xfs_attr_inactive.c > @@ -388,8 +388,11 @@ xfs_attr_inactive( > xfs_trans_cancel(trans); > out_destroy_fork: > /* kill the in-core attr fork before we drop the inode lock */ > - if (dp->i_afp) > - xfs_idestroy_fork(dp, XFS_ATTR_FORK); > + if (dp->i_afp) { > + xfs_idestroy_fork(dp->i_afp); > + kmem_cache_free(xfs_ifork_zone, dp->i_afp); > + dp->i_afp = NULL; > + } > if (lock_mode) > xfs_iunlock(dp, lock_mode); > return error; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index c09b3e9eab1da..d806d3bfa8936 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -87,15 +87,18 @@ xfs_inode_free_callback( > case S_IFREG: > case S_IFDIR: > case S_IFLNK: > - xfs_idestroy_fork(ip, XFS_DATA_FORK); > + xfs_idestroy_fork(&ip->i_df); > break; > } > > - if (ip->i_afp) > - xfs_idestroy_fork(ip, XFS_ATTR_FORK); > - if (ip->i_cowfp) > - xfs_idestroy_fork(ip, XFS_COW_FORK); > - > + if (ip->i_afp) { > + xfs_idestroy_fork(ip->i_afp); > + kmem_cache_free(xfs_ifork_zone, ip->i_afp); > + } > + if (ip->i_cowfp) { > + xfs_idestroy_fork(ip->i_cowfp); > + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > + } > if (ip->i_itemp) { > ASSERT(!test_bit(XFS_LI_IN_AIL, > &ip->i_itemp->ili_item.li_flags)); > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 6/6] xfs: cleanup xfs_idestroy_fork 2020-05-12 18:54 ` Brian Foster @ 2020-05-16 18:10 ` Darrick J. Wong 0 siblings, 0 replies; 41+ messages in thread From: Darrick J. Wong @ 2020-05-16 18:10 UTC (permalink / raw) To: Brian Foster; +Cc: Christoph Hellwig, linux-xfs On Tue, May 12, 2020 at 02:54:35PM -0400, Brian Foster wrote: > On Sun, May 10, 2020 at 09:24:04AM +0200, Christoph Hellwig wrote: > > Move freeing the dynamically allocated attr and COW fork, as well > > as zeroing the pointers where actually needed into the callers, and > > just pass the xfs_ifork structure to xfs_idestroy_fork. Simplify > > the kmem_free calls by not checking for NULL first, and not zeroing > > the pointers in structure that are about to be freed (either the > > ifork or the containing inode in case of the data fork). > > > > Signed-off-by: Christoph Hellwig <hch@lst.de> > > --- > > fs/xfs/libxfs/xfs_attr_leaf.c | 7 +++---- > > fs/xfs/libxfs/xfs_inode_buf.c | 2 +- > > fs/xfs/libxfs/xfs_inode_fork.c | 36 +++++++++------------------------- > > fs/xfs/libxfs/xfs_inode_fork.h | 2 +- > > fs/xfs/xfs_attr_inactive.c | 7 +++++-- > > fs/xfs/xfs_icache.c | 15 ++++++++------ > > 6 files changed, 28 insertions(+), 41 deletions(-) > > > ... > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > > index 6562f2bcd15cc..577cc20e03170 100644 > > --- a/fs/xfs/libxfs/xfs_inode_fork.c > > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > > @@ -495,38 +495,20 @@ xfs_idata_realloc( > > > > void > > xfs_idestroy_fork( > > - xfs_inode_t *ip, > > - int whichfork) > > + struct xfs_ifork *ifp) > > { > > - struct xfs_ifork *ifp; > > - > > - ifp = XFS_IFORK_PTR(ip, whichfork); > > - if (ifp->if_broot != NULL) { > > - kmem_free(ifp->if_broot); > > - ifp->if_broot = NULL; > > - } > > + kmem_free(ifp->if_broot); > > I think this function should still reset the pointers within the ifp > that it frees (if_broot and if_data below), particularly as long as > there are multiple callers that pass the data fork because it is not > immediately/independently freed. IOW, it's not clear if something > happens to reset i_mode between when xfs_inode_from_disk() might fail > and destroy the data fork, and when the inode is ultimately freed and we > look at i_mode to determine whether to destroy the data fork. /me agrees, let's not leave a potential UAF landmine here. --D > Brian > > > > > /* > > - * If the format is local, then we can't have an extents > > - * array so just look for an inline data array. If we're > > - * not local then we may or may not have an extents list, > > - * so check and free it up if we do. > > + * If the format is local, then we can't have an extents array so just > > + * look for an inline data array. If we're not local then we may or may > > + * not have an extents list, so check and free it up if we do. > > */ > > if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > > - if (ifp->if_u1.if_data != NULL) { > > - kmem_free(ifp->if_u1.if_data); > > - ifp->if_u1.if_data = NULL; > > - } > > - } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) { > > - xfs_iext_destroy(ifp); > > - } > > - > > - if (whichfork == XFS_ATTR_FORK) { > > - kmem_cache_free(xfs_ifork_zone, ip->i_afp); > > - ip->i_afp = NULL; > > - } else if (whichfork == XFS_COW_FORK) { > > - kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > > - ip->i_cowfp = NULL; > > + kmem_free(ifp->if_u1.if_data); > > + } else if (ifp->if_flags & XFS_IFEXTENTS) { > > + if (ifp->if_height) > > + xfs_iext_destroy(ifp); > > } > > } > > > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > > index d849cca103edd..a4953e95c4f3f 100644 > > --- a/fs/xfs/libxfs/xfs_inode_fork.h > > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > > @@ -86,7 +86,7 @@ int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > > int xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *); > > void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, > > struct xfs_inode_log_item *, int); > > -void xfs_idestroy_fork(struct xfs_inode *, int); > > +void xfs_idestroy_fork(struct xfs_ifork *ifp); > > void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, > > int whichfork); > > void xfs_iroot_realloc(struct xfs_inode *, int, int); > > diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c > > index 00ffc46c0bf71..bfad669e6b2f8 100644 > > --- a/fs/xfs/xfs_attr_inactive.c > > +++ b/fs/xfs/xfs_attr_inactive.c > > @@ -388,8 +388,11 @@ xfs_attr_inactive( > > xfs_trans_cancel(trans); > > out_destroy_fork: > > /* kill the in-core attr fork before we drop the inode lock */ > > - if (dp->i_afp) > > - xfs_idestroy_fork(dp, XFS_ATTR_FORK); > > + if (dp->i_afp) { > > + xfs_idestroy_fork(dp->i_afp); > > + kmem_cache_free(xfs_ifork_zone, dp->i_afp); > > + dp->i_afp = NULL; > > + } > > if (lock_mode) > > xfs_iunlock(dp, lock_mode); > > return error; > > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > > index c09b3e9eab1da..d806d3bfa8936 100644 > > --- a/fs/xfs/xfs_icache.c > > +++ b/fs/xfs/xfs_icache.c > > @@ -87,15 +87,18 @@ xfs_inode_free_callback( > > case S_IFREG: > > case S_IFDIR: > > case S_IFLNK: > > - xfs_idestroy_fork(ip, XFS_DATA_FORK); > > + xfs_idestroy_fork(&ip->i_df); > > break; > > } > > > > - if (ip->i_afp) > > - xfs_idestroy_fork(ip, XFS_ATTR_FORK); > > - if (ip->i_cowfp) > > - xfs_idestroy_fork(ip, XFS_COW_FORK); > > - > > + if (ip->i_afp) { > > + xfs_idestroy_fork(ip->i_afp); > > + kmem_cache_free(xfs_ifork_zone, ip->i_afp); > > + } > > + if (ip->i_cowfp) { > > + xfs_idestroy_fork(ip->i_cowfp); > > + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > > + } > > if (ip->i_itemp) { > > ASSERT(!test_bit(XFS_LI_IN_AIL, > > &ip->i_itemp->ili_item.li_flags)); > > -- > > 2.26.2 > > > ^ permalink raw reply [flat|nested] 41+ messages in thread
* move the extent count and format into struct xfs_ifork v2 @ 2020-05-18 7:33 Christoph Hellwig 2020-05-18 7:33 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig 0 siblings, 1 reply; 41+ messages in thread From: Christoph Hellwig @ 2020-05-18 7:33 UTC (permalink / raw) To: linux-xfs Hi all, this series moves the extent count and format fields into the xfs_ifork structure. It is based on the "dinode reading cleanups v2" series. Git tree: git://git.infradead.org/users/hch/xfs.git xfs-ifork-cleanup.2 Gitweb: http://git.infradead.org/users/hch/xfs.git/shortlog/refs/heads/xfs-ifork-cleanup.2 Changes since v1: - pick up a different scrub prep patch from Darrick - keep the nextents == 0 assert in xfs_attr_fork_remove - keep clearing various ifork fields in xfs_ifork_destroy - add more comments ^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 6/6] xfs: cleanup xfs_idestroy_fork 2020-05-18 7:33 move the extent count and format into struct xfs_ifork v2 Christoph Hellwig @ 2020-05-18 7:33 ` Christoph Hellwig 2020-05-18 13:28 ` Brian Foster 0 siblings, 1 reply; 41+ messages in thread From: Christoph Hellwig @ 2020-05-18 7:33 UTC (permalink / raw) To: linux-xfs; +Cc: Chandan Babu R Move freeing the dynamically allocated attr and COW fork, as well as zeroing the pointers where actually needed into the callers, and just pass the xfs_ifork structure to xfs_idestroy_fork. Also simplify the kmem_free calls by not checking for NULL first. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> --- fs/xfs/libxfs/xfs_attr_leaf.c | 7 +++---- fs/xfs/libxfs/xfs_inode_buf.c | 2 +- fs/xfs/libxfs/xfs_inode_fork.c | 32 +++++++++----------------------- fs/xfs/libxfs/xfs_inode_fork.h | 2 +- fs/xfs/xfs_attr_inactive.c | 7 +++++-- fs/xfs/xfs_icache.c | 15 +++++++++------ 6 files changed, 28 insertions(+), 37 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b279200519777..394805abb4535 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -718,11 +718,10 @@ xfs_attr_fork_remove( { ASSERT(ip->i_afp->if_nextents == 0); - xfs_idestroy_fork(ip, XFS_ATTR_FORK); + xfs_idestroy_fork(ip->i_afp); + kmem_cache_free(xfs_ifork_zone, ip->i_afp); + ip->i_afp = NULL; ip->i_d.di_forkoff = 0; - - ASSERT(ip->i_afp == NULL); - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index ab555671e1543..6f84ea85fdd83 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -271,7 +271,7 @@ xfs_inode_from_disk( return 0; out_destroy_data_fork: - xfs_idestroy_fork(ip, XFS_DATA_FORK); + xfs_idestroy_fork(&ip->i_df); return error; } diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index ef43b4893766c..28b366275ae0e 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c @@ -503,38 +503,24 @@ xfs_idata_realloc( void xfs_idestroy_fork( - xfs_inode_t *ip, - int whichfork) + struct xfs_ifork *ifp) { - struct xfs_ifork *ifp; - - ifp = XFS_IFORK_PTR(ip, whichfork); if (ifp->if_broot != NULL) { kmem_free(ifp->if_broot); ifp->if_broot = NULL; } /* - * If the format is local, then we can't have an extents - * array so just look for an inline data array. If we're - * not local then we may or may not have an extents list, - * so check and free it up if we do. + * If the format is local, then we can't have an extents array so just + * look for an inline data array. If we're not local then we may or may + * not have an extents list, so check and free it up if we do. */ if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { - if (ifp->if_u1.if_data != NULL) { - kmem_free(ifp->if_u1.if_data); - ifp->if_u1.if_data = NULL; - } - } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) { - xfs_iext_destroy(ifp); - } - - if (whichfork == XFS_ATTR_FORK) { - kmem_cache_free(xfs_ifork_zone, ip->i_afp); - ip->i_afp = NULL; - } else if (whichfork == XFS_COW_FORK) { - kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); - ip->i_cowfp = NULL; + kmem_free(ifp->if_u1.if_data); + ifp->if_u1.if_data = NULL; + } else if (ifp->if_flags & XFS_IFEXTENTS) { + if (ifp->if_height) + xfs_iext_destroy(ifp); } } diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index d849cca103edd..a4953e95c4f3f 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h @@ -86,7 +86,7 @@ int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); int xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *); void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, struct xfs_inode_log_item *, int); -void xfs_idestroy_fork(struct xfs_inode *, int); +void xfs_idestroy_fork(struct xfs_ifork *ifp); void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, int whichfork); void xfs_iroot_realloc(struct xfs_inode *, int, int); diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c index 00ffc46c0bf71..bfad669e6b2f8 100644 --- a/fs/xfs/xfs_attr_inactive.c +++ b/fs/xfs/xfs_attr_inactive.c @@ -388,8 +388,11 @@ xfs_attr_inactive( xfs_trans_cancel(trans); out_destroy_fork: /* kill the in-core attr fork before we drop the inode lock */ - if (dp->i_afp) - xfs_idestroy_fork(dp, XFS_ATTR_FORK); + if (dp->i_afp) { + xfs_idestroy_fork(dp->i_afp); + kmem_cache_free(xfs_ifork_zone, dp->i_afp); + dp->i_afp = NULL; + } if (lock_mode) xfs_iunlock(dp, lock_mode); return error; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index c09b3e9eab1da..d806d3bfa8936 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -87,15 +87,18 @@ xfs_inode_free_callback( case S_IFREG: case S_IFDIR: case S_IFLNK: - xfs_idestroy_fork(ip, XFS_DATA_FORK); + xfs_idestroy_fork(&ip->i_df); break; } - if (ip->i_afp) - xfs_idestroy_fork(ip, XFS_ATTR_FORK); - if (ip->i_cowfp) - xfs_idestroy_fork(ip, XFS_COW_FORK); - + if (ip->i_afp) { + xfs_idestroy_fork(ip->i_afp); + kmem_cache_free(xfs_ifork_zone, ip->i_afp); + } + if (ip->i_cowfp) { + xfs_idestroy_fork(ip->i_cowfp); + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); + } if (ip->i_itemp) { ASSERT(!test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)); -- 2.26.2 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 6/6] xfs: cleanup xfs_idestroy_fork 2020-05-18 7:33 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig @ 2020-05-18 13:28 ` Brian Foster 0 siblings, 0 replies; 41+ messages in thread From: Brian Foster @ 2020-05-18 13:28 UTC (permalink / raw) To: Christoph Hellwig; +Cc: linux-xfs, Chandan Babu R On Mon, May 18, 2020 at 09:33:58AM +0200, Christoph Hellwig wrote: > Move freeing the dynamically allocated attr and COW fork, as well > as zeroing the pointers where actually needed into the callers, and > just pass the xfs_ifork structure to xfs_idestroy_fork. Also simplify > the kmem_free calls by not checking for NULL first. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> > --- Reviewed-by: Brian Foster <bfoster@redhat.com> > fs/xfs/libxfs/xfs_attr_leaf.c | 7 +++---- > fs/xfs/libxfs/xfs_inode_buf.c | 2 +- > fs/xfs/libxfs/xfs_inode_fork.c | 32 +++++++++----------------------- > fs/xfs/libxfs/xfs_inode_fork.h | 2 +- > fs/xfs/xfs_attr_inactive.c | 7 +++++-- > fs/xfs/xfs_icache.c | 15 +++++++++------ > 6 files changed, 28 insertions(+), 37 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index b279200519777..394805abb4535 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -718,11 +718,10 @@ xfs_attr_fork_remove( > { > ASSERT(ip->i_afp->if_nextents == 0); > > - xfs_idestroy_fork(ip, XFS_ATTR_FORK); > + xfs_idestroy_fork(ip->i_afp); > + kmem_cache_free(xfs_ifork_zone, ip->i_afp); > + ip->i_afp = NULL; > ip->i_d.di_forkoff = 0; > - > - ASSERT(ip->i_afp == NULL); > - > xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); > } > > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index ab555671e1543..6f84ea85fdd83 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -271,7 +271,7 @@ xfs_inode_from_disk( > return 0; > > out_destroy_data_fork: > - xfs_idestroy_fork(ip, XFS_DATA_FORK); > + xfs_idestroy_fork(&ip->i_df); > return error; > } > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c > index ef43b4893766c..28b366275ae0e 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.c > +++ b/fs/xfs/libxfs/xfs_inode_fork.c > @@ -503,38 +503,24 @@ xfs_idata_realloc( > > void > xfs_idestroy_fork( > - xfs_inode_t *ip, > - int whichfork) > + struct xfs_ifork *ifp) > { > - struct xfs_ifork *ifp; > - > - ifp = XFS_IFORK_PTR(ip, whichfork); > if (ifp->if_broot != NULL) { > kmem_free(ifp->if_broot); > ifp->if_broot = NULL; > } > > /* > - * If the format is local, then we can't have an extents > - * array so just look for an inline data array. If we're > - * not local then we may or may not have an extents list, > - * so check and free it up if we do. > + * If the format is local, then we can't have an extents array so just > + * look for an inline data array. If we're not local then we may or may > + * not have an extents list, so check and free it up if we do. > */ > if (ifp->if_format == XFS_DINODE_FMT_LOCAL) { > - if (ifp->if_u1.if_data != NULL) { > - kmem_free(ifp->if_u1.if_data); > - ifp->if_u1.if_data = NULL; > - } > - } else if ((ifp->if_flags & XFS_IFEXTENTS) && ifp->if_height) { > - xfs_iext_destroy(ifp); > - } > - > - if (whichfork == XFS_ATTR_FORK) { > - kmem_cache_free(xfs_ifork_zone, ip->i_afp); > - ip->i_afp = NULL; > - } else if (whichfork == XFS_COW_FORK) { > - kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > - ip->i_cowfp = NULL; > + kmem_free(ifp->if_u1.if_data); > + ifp->if_u1.if_data = NULL; > + } else if (ifp->if_flags & XFS_IFEXTENTS) { > + if (ifp->if_height) > + xfs_iext_destroy(ifp); > } > } > > diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h > index d849cca103edd..a4953e95c4f3f 100644 > --- a/fs/xfs/libxfs/xfs_inode_fork.h > +++ b/fs/xfs/libxfs/xfs_inode_fork.h > @@ -86,7 +86,7 @@ int xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); > int xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *); > void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, > struct xfs_inode_log_item *, int); > -void xfs_idestroy_fork(struct xfs_inode *, int); > +void xfs_idestroy_fork(struct xfs_ifork *ifp); > void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, > int whichfork); > void xfs_iroot_realloc(struct xfs_inode *, int, int); > diff --git a/fs/xfs/xfs_attr_inactive.c b/fs/xfs/xfs_attr_inactive.c > index 00ffc46c0bf71..bfad669e6b2f8 100644 > --- a/fs/xfs/xfs_attr_inactive.c > +++ b/fs/xfs/xfs_attr_inactive.c > @@ -388,8 +388,11 @@ xfs_attr_inactive( > xfs_trans_cancel(trans); > out_destroy_fork: > /* kill the in-core attr fork before we drop the inode lock */ > - if (dp->i_afp) > - xfs_idestroy_fork(dp, XFS_ATTR_FORK); > + if (dp->i_afp) { > + xfs_idestroy_fork(dp->i_afp); > + kmem_cache_free(xfs_ifork_zone, dp->i_afp); > + dp->i_afp = NULL; > + } > if (lock_mode) > xfs_iunlock(dp, lock_mode); > return error; > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c > index c09b3e9eab1da..d806d3bfa8936 100644 > --- a/fs/xfs/xfs_icache.c > +++ b/fs/xfs/xfs_icache.c > @@ -87,15 +87,18 @@ xfs_inode_free_callback( > case S_IFREG: > case S_IFDIR: > case S_IFLNK: > - xfs_idestroy_fork(ip, XFS_DATA_FORK); > + xfs_idestroy_fork(&ip->i_df); > break; > } > > - if (ip->i_afp) > - xfs_idestroy_fork(ip, XFS_ATTR_FORK); > - if (ip->i_cowfp) > - xfs_idestroy_fork(ip, XFS_COW_FORK); > - > + if (ip->i_afp) { > + xfs_idestroy_fork(ip->i_afp); > + kmem_cache_free(xfs_ifork_zone, ip->i_afp); > + } > + if (ip->i_cowfp) { > + xfs_idestroy_fork(ip->i_cowfp); > + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); > + } > if (ip->i_itemp) { > ASSERT(!test_bit(XFS_LI_IN_AIL, > &ip->i_itemp->ili_item.li_flags)); > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2022-07-24 12:14 UTC | newest] Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-05-10 7:23 move the extent count and format into struct xfs_ifork Christoph Hellwig 2020-05-10 7:23 ` [PATCH 1/6] xfs: use XFS_IFORK_BOFF xchk_bmap_check_rmaps Christoph Hellwig 2020-05-11 11:40 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster 2020-05-12 15:38 ` Darrick J. Wong 2020-05-12 16:14 ` Brian Foster 2020-05-12 19:16 ` Darrick J. Wong 2020-05-13 13:19 ` Brian Foster 2020-05-13 13:21 ` Christoph Hellwig 2020-05-16 18:42 ` [PATCH] xfs: clean up xchk_bmap_check_rmaps usage of XFS_IFORK_Q Darrick J. Wong 2020-05-16 20:01 ` Christoph Hellwig 2020-05-17 8:05 ` Christoph Hellwig 2020-05-10 7:24 ` [PATCH 2/6] xfs: remove the XFS_DFORK_Q macro Christoph Hellwig 2020-05-11 12:39 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster 2020-05-16 18:02 ` Darrick J. Wong 2020-05-10 7:24 ` [PATCH 3/6] xfs: remove xfs_ifree_local_data Christoph Hellwig 2020-05-11 16:32 ` Chandan Babu R 2020-05-12 15:31 ` Brian Foster 2020-05-16 18:07 ` Darrick J. Wong 2022-07-24 12:14 ` Alex Lyakas 2020-05-10 7:24 ` [PATCH 4/6] xfs: move the per-fork nextents fields into struct xfs_ifork Christoph Hellwig 2020-05-12 5:26 ` Chandan Babu R 2020-05-12 16:10 ` Brian Foster 2020-05-16 18:09 ` Darrick J. Wong 2020-05-17 8:12 ` Christoph Hellwig 2020-05-10 7:24 ` [PATCH 5/6] xfs: move the fork format " Christoph Hellwig 2020-05-12 9:37 ` Chandan Babu R 2020-05-12 18:53 ` Brian Foster 2020-05-14 21:25 ` Darrick J. Wong 2020-05-16 13:58 ` Christoph Hellwig 2020-05-16 17:01 ` Darrick J. Wong 2020-05-16 18:01 ` Darrick J. Wong 2020-05-16 18:16 ` Christoph Hellwig 2020-05-16 18:29 ` Darrick J. Wong 2020-05-10 7:24 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig 2020-05-12 9:48 ` Chandan Babu R 2020-05-12 18:54 ` Brian Foster 2020-05-16 18:10 ` Darrick J. Wong 2020-05-18 7:33 move the extent count and format into struct xfs_ifork v2 Christoph Hellwig 2020-05-18 7:33 ` [PATCH 6/6] xfs: cleanup xfs_idestroy_fork Christoph Hellwig 2020-05-18 13:28 ` Brian Foster
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.