|
|
| version 1.484, 2007/10/19 04:06:50 | version 1.485, 2007/11/02 05:12:07 |
|---|---|
| Line 2812 xfs_iunpin( | Line 2812 xfs_iunpin( |
| { | { |
| ASSERT(atomic_read(&ip->i_pincount) > 0); | ASSERT(atomic_read(&ip->i_pincount) > 0); |
| if (atomic_dec_and_lock(&ip->i_pincount, &ip->i_flags_lock)) { | if (atomic_dec_and_test(&ip->i_pincount)) |
| /* | |
| * If the inode is currently being reclaimed, the link between | |
| * the bhv_vnode and the xfs_inode will be broken after the | |
| * XFS_IRECLAIM* flag is set. Hence, if these flags are not | |
| * set, then we can move forward and mark the linux inode dirty | |
| * knowing that it is still valid as it won't freed until after | |
| * the bhv_vnode<->xfs_inode link is broken in xfs_reclaim. The | |
| * i_flags_lock is used to synchronise the setting of the | |
| * XFS_IRECLAIM* flags and the breaking of the link, and so we | |
| * can execute atomically w.r.t to reclaim by holding this lock | |
| * here. | |
| * | |
| * However, we still need to issue the unpin wakeup call as the | |
| * inode reclaim may be blocked waiting for the inode to become | |
| * unpinned. | |
| */ | |
| if (!__xfs_iflags_test(ip, XFS_IRECLAIM|XFS_IRECLAIMABLE)) { | |
| bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | |
| struct inode *inode = NULL; | |
| BUG_ON(vp == NULL); | |
| inode = vn_to_inode(vp); | |
| BUG_ON(inode->i_state & I_CLEAR); | |
| /* make sync come back and flush this inode */ | |
| if (!(inode->i_state & (I_NEW|I_FREEING))) | |
| mark_inode_dirty_sync(inode); | |
| } | |
| spin_unlock(&ip->i_flags_lock); | |
| wake_up(&ip->i_ipin_wait); | wake_up(&ip->i_ipin_wait); |
| } | |
| } | } |
| /* | /* |