aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_inode.c27
-rw-r--r--fs/xfs/xfs_inode.h3
-rw-r--r--fs/xfs/xfs_inode_item.c2
-rw-r--r--fs/xfs/xfs_super.c1
4 files changed, 24 insertions, 9 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index eeb60d31b08..62603369b52 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2037,7 +2037,7 @@ xfs_idestroy_fork(
2037 * once someone is waiting for it to be unpinned. 2037 * once someone is waiting for it to be unpinned.
2038 */ 2038 */
2039static void 2039static void
2040xfs_iunpin_nowait( 2040xfs_iunpin(
2041 struct xfs_inode *ip) 2041 struct xfs_inode *ip)
2042{ 2042{
2043 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 2043 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
@@ -2049,14 +2049,29 @@ xfs_iunpin_nowait(
2049 2049
2050} 2050}
2051 2051
2052static void
2053__xfs_iunpin_wait(
2054 struct xfs_inode *ip)
2055{
2056 wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IPINNED_BIT);
2057 DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IPINNED_BIT);
2058
2059 xfs_iunpin(ip);
2060
2061 do {
2062 prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
2063 if (xfs_ipincount(ip))
2064 io_schedule();
2065 } while (xfs_ipincount(ip));
2066 finish_wait(wq, &wait.wait);
2067}
2068
2052void 2069void
2053xfs_iunpin_wait( 2070xfs_iunpin_wait(
2054 struct xfs_inode *ip) 2071 struct xfs_inode *ip)
2055{ 2072{
2056 if (xfs_ipincount(ip)) { 2073 if (xfs_ipincount(ip))
2057 xfs_iunpin_nowait(ip); 2074 __xfs_iunpin_wait(ip);
2058 wait_event(ip->i_ipin_wait, (xfs_ipincount(ip) == 0));
2059 }
2060} 2075}
2061 2076
2062/* 2077/*
@@ -2415,7 +2430,7 @@ xfs_iflush(
2415 * out for us if they occur after the log force completes. 2430 * out for us if they occur after the log force completes.
2416 */ 2431 */
2417 if (!(flags & SYNC_WAIT) && xfs_ipincount(ip)) { 2432 if (!(flags & SYNC_WAIT) && xfs_ipincount(ip)) {
2418 xfs_iunpin_nowait(ip); 2433 xfs_iunpin(ip);
2419 xfs_ifunlock(ip); 2434 xfs_ifunlock(ip);
2420 return EAGAIN; 2435 return EAGAIN;
2421 } 2436 }
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 960d2a89b3a..4acbe740be4 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -238,7 +238,6 @@ typedef struct xfs_inode {
238 mrlock_t i_lock; /* inode lock */ 238 mrlock_t i_lock; /* inode lock */
239 mrlock_t i_iolock; /* inode IO lock */ 239 mrlock_t i_iolock; /* inode IO lock */
240 atomic_t i_pincount; /* inode pin count */ 240 atomic_t i_pincount; /* inode pin count */
241 wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */
242 spinlock_t i_flags_lock; /* inode i_flags lock */ 241 spinlock_t i_flags_lock; /* inode i_flags lock */
243 /* Miscellaneous state. */ 242 /* Miscellaneous state. */
244 unsigned long i_flags; /* see defined flags below */ 243 unsigned long i_flags; /* see defined flags below */
@@ -367,6 +366,8 @@ xfs_set_projid(struct xfs_inode *ip,
367#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ 366#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */
368#define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */ 367#define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */
369#define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT) 368#define XFS_IFLOCK (1 << __XFS_IFLOCK_BIT)
369#define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */
370#define XFS_IPINNED (1 << __XFS_IPINNED_BIT)
370 371
371/* 372/*
372 * Per-lifetime flags need to be reset when re-using a reclaimable inode during 373 * Per-lifetime flags need to be reset when re-using a reclaimable inode during
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index c8d4ce0efd5..91d71dcd485 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -555,7 +555,7 @@ xfs_inode_item_unpin(
555 trace_xfs_inode_unpin(ip, _RET_IP_); 555 trace_xfs_inode_unpin(ip, _RET_IP_);
556 ASSERT(atomic_read(&ip->i_pincount) > 0); 556 ASSERT(atomic_read(&ip->i_pincount) > 0);
557 if (atomic_dec_and_test(&ip->i_pincount)) 557 if (atomic_dec_and_test(&ip->i_pincount))
558 wake_up(&ip->i_ipin_wait); 558 wake_up_bit(&ip->i_flags, __XFS_IPINNED_BIT);
559} 559}
560 560
561/* 561/*
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 6851fa7b1af..ee5b695c99a 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -828,7 +828,6 @@ xfs_fs_inode_init_once(
828 /* xfs inode */ 828 /* xfs inode */
829 atomic_set(&ip->i_pincount, 0); 829 atomic_set(&ip->i_pincount, 0);
830 spin_lock_init(&ip->i_flags_lock); 830 spin_lock_init(&ip->i_flags_lock);
831 init_waitqueue_head(&ip->i_ipin_wait);
832 831
833 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, 832 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
834 "xfsino", ip->i_ino); 833 "xfsino", ip->i_ino);