aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2017-04-26 11:30:39 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2017-04-28 11:11:08 -0400
commit756baca27fff3ecaeab9dbc7a5ee35a1d7bc0c7f (patch)
tree75e7bd77fba23d4d0ab39659d3fe6b723d46717c
parent8f720d9f892e0e223dab8400f03130bc208c72e7 (diff)
xfs: support ability to wait on new inodes
Inodes that are inserted into the perag tree but still under construction are flagged with the XFS_INEW bit. Most contexts either skip such inodes when they are encountered or have the ability to handle them. The runtime quotaoff sequence introduces a context that must wait for construction of such inodes to correctly ensure that all dquots in the fs are released. In anticipation of this, support the ability to wait on new inodes. Wake the appropriate bit when XFS_INEW is cleared. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/xfs_icache.c5
-rw-r--r--fs/xfs/xfs_inode.h4
2 files changed, 7 insertions, 2 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 3531f8f72fa5..25f4f4595821 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -366,14 +366,17 @@ xfs_iget_cache_hit(
366 366
367 error = xfs_reinit_inode(mp, inode); 367 error = xfs_reinit_inode(mp, inode);
368 if (error) { 368 if (error) {
369 bool wake;
369 /* 370 /*
370 * Re-initializing the inode failed, and we are in deep 371 * Re-initializing the inode failed, and we are in deep
371 * trouble. Try to re-add it to the reclaim list. 372 * trouble. Try to re-add it to the reclaim list.
372 */ 373 */
373 rcu_read_lock(); 374 rcu_read_lock();
374 spin_lock(&ip->i_flags_lock); 375 spin_lock(&ip->i_flags_lock);
375 376 wake = !!__xfs_iflags_test(ip, XFS_INEW);
376 ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM); 377 ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM);
378 if (wake)
379 wake_up_bit(&ip->i_flags, __XFS_INEW_BIT);
377 ASSERT(ip->i_flags & XFS_IRECLAIMABLE); 380 ASSERT(ip->i_flags & XFS_IRECLAIMABLE);
378 trace_xfs_iget_reclaim_fail(ip); 381 trace_xfs_iget_reclaim_fail(ip);
379 goto out_error; 382 goto out_error;
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 10dcf27b4c85..10e89fcb49d7 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -216,7 +216,8 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
216#define XFS_IRECLAIM (1 << 0) /* started reclaiming this inode */ 216#define XFS_IRECLAIM (1 << 0) /* started reclaiming this inode */
217#define XFS_ISTALE (1 << 1) /* inode has been staled */ 217#define XFS_ISTALE (1 << 1) /* inode has been staled */
218#define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */ 218#define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */
219#define XFS_INEW (1 << 3) /* inode has just been allocated */ 219#define __XFS_INEW_BIT 3 /* inode has just been allocated */
220#define XFS_INEW (1 << __XFS_INEW_BIT)
220#define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */ 221#define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */
221#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ 222#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */
222#define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */ 223#define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */
@@ -464,6 +465,7 @@ static inline void xfs_finish_inode_setup(struct xfs_inode *ip)
464 xfs_iflags_clear(ip, XFS_INEW); 465 xfs_iflags_clear(ip, XFS_INEW);
465 barrier(); 466 barrier();
466 unlock_new_inode(VFS_I(ip)); 467 unlock_new_inode(VFS_I(ip));
468 wake_up_bit(&ip->i_flags, __XFS_INEW_BIT);
467} 469}
468 470
469static inline void xfs_setup_existing_inode(struct xfs_inode *ip) 471static inline void xfs_setup_existing_inode(struct xfs_inode *ip)