Skip to content

Commit bc7d684

Browse files
dgchinnercmaiolino
authored andcommitted
xfs: rearrange code in xfs_inode_item_precommit
There are similar extsize checks and updates done inside and outside the inode item lock, which could all be done under a single top level logic branch outside the ili_lock. The COW extsize fixup can potentially miss updating the XFS_ILOG_CORE in ili_fsync_fields, so moving this code up above the ili_fsync_fields update could also be considered a fix. Further, to make the next change a bit cleaner, move where we calculate the on-disk flag mask to after we attach the cluster buffer to the the inode log item. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent fc0d192 commit bc7d684

1 file changed

Lines changed: 29 additions & 36 deletions

File tree

fs/xfs/xfs_inode_item.c

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -131,46 +131,28 @@ xfs_inode_item_precommit(
131131
}
132132

133133
/*
134-
* Inode verifiers do not check that the extent size hint is an integer
135-
* multiple of the rt extent size on a directory with both rtinherit
136-
* and extszinherit flags set. If we're logging a directory that is
137-
* misconfigured in this way, clear the hint.
134+
* Inode verifiers do not check that the extent size hints are an
135+
* integer multiple of the rt extent size on a directory with
136+
* rtinherit flags set. If we're logging a directory that is
137+
* misconfigured in this way, clear the bad hints.
138138
*/
139-
if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
140-
(ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) &&
141-
xfs_extlen_to_rtxmod(ip->i_mount, ip->i_extsize) > 0) {
142-
ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
143-
XFS_DIFLAG_EXTSZINHERIT);
144-
ip->i_extsize = 0;
145-
flags |= XFS_ILOG_CORE;
139+
if (ip->i_diflags & XFS_DIFLAG_RTINHERIT) {
140+
if ((ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) &&
141+
xfs_extlen_to_rtxmod(ip->i_mount, ip->i_extsize) > 0) {
142+
ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
143+
XFS_DIFLAG_EXTSZINHERIT);
144+
ip->i_extsize = 0;
145+
flags |= XFS_ILOG_CORE;
146+
}
147+
if ((ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) &&
148+
xfs_extlen_to_rtxmod(ip->i_mount, ip->i_cowextsize) > 0) {
149+
ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
150+
ip->i_cowextsize = 0;
151+
flags |= XFS_ILOG_CORE;
152+
}
146153
}
147154

148-
/*
149-
* Record the specific change for fdatasync optimisation. This allows
150-
* fdatasync to skip log forces for inodes that are only timestamp
151-
* dirty. Once we've processed the XFS_ILOG_IVERSION flag, convert it
152-
* to XFS_ILOG_CORE so that the actual on-disk dirty tracking
153-
* (ili_fields) correctly tracks that the version has changed.
154-
*/
155155
spin_lock(&iip->ili_lock);
156-
iip->ili_fsync_fields |= (flags & ~XFS_ILOG_IVERSION);
157-
if (flags & XFS_ILOG_IVERSION)
158-
flags = ((flags & ~XFS_ILOG_IVERSION) | XFS_ILOG_CORE);
159-
160-
/*
161-
* Inode verifiers do not check that the CoW extent size hint is an
162-
* integer multiple of the rt extent size on a directory with both
163-
* rtinherit and cowextsize flags set. If we're logging a directory
164-
* that is misconfigured in this way, clear the hint.
165-
*/
166-
if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
167-
(ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) &&
168-
xfs_extlen_to_rtxmod(ip->i_mount, ip->i_cowextsize) > 0) {
169-
ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
170-
ip->i_cowextsize = 0;
171-
flags |= XFS_ILOG_CORE;
172-
}
173-
174156
if (!iip->ili_item.li_buf) {
175157
struct xfs_buf *bp;
176158
int error;
@@ -204,6 +186,17 @@ xfs_inode_item_precommit(
204186
xfs_trans_brelse(tp, bp);
205187
}
206188

189+
/*
190+
* Record the specific change for fdatasync optimisation. This allows
191+
* fdatasync to skip log forces for inodes that are only timestamp
192+
* dirty. Once we've processed the XFS_ILOG_IVERSION flag, convert it
193+
* to XFS_ILOG_CORE so that the actual on-disk dirty tracking
194+
* (ili_fields) correctly tracks that the version has changed.
195+
*/
196+
iip->ili_fsync_fields |= (flags & ~XFS_ILOG_IVERSION);
197+
if (flags & XFS_ILOG_IVERSION)
198+
flags = ((flags & ~XFS_ILOG_IVERSION) | XFS_ILOG_CORE);
199+
207200
/*
208201
* Always OR in the bits from the ili_last_fields field. This is to
209202
* coordinate with the xfs_iflush() and xfs_buf_inode_iodone() routines

0 commit comments

Comments
 (0)