goto again;
}
+ ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE));
+
+ /*
+ * If lookup is racing with unlink, then we
+ * should return an error immediately so we
+ * don't remove it from the reclaim list and
+ * potentially leak the inode.
+ */
+ if ((ip->i_d.di_mode == 0) &&
+ !(flags & XFS_IGET_CREATE)) {
+ read_unlock(&ih->ih_lock);
+ return ENOENT;
+ }
+
+ /*
+ * There may be transactions sitting in the
+ * incore log buffers or being flushed to disk
+ * at this time. We can't clear the
+ * XFS_IRECLAIMABLE flag until these
+ * transactions have hit the disk, otherwise we
+ * will void the guarantee the flag provides
+ * xfs_iunpin()
+ */
+ if (xfs_ipincount(ip)) {
+ read_unlock(&ih->ih_lock);
+ xfs_log_force(mp, 0,
+ XFS_LOG_FORCE|XFS_LOG_SYNC);
+ XFS_STATS_INC(xs_ig_frecycle);
+ goto again;
+ }
vn_trace_exit(vp, "xfs_iget.alloc",
(inst_t *)__return_address);
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
+ ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
if (lock_flags & XFS_IOLOCK_EXCL) {
- mrupdate(&ip->i_iolock);
+ mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
} else if (lock_flags & XFS_IOLOCK_SHARED) {
- mraccess(&ip->i_iolock);
+ mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
}
if (lock_flags & XFS_ILOCK_EXCL) {
- mrupdate(&ip->i_lock);
+ mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
} else if (lock_flags & XFS_ILOCK_SHARED) {
- mraccess(&ip->i_lock);
+ mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
}
xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
}
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
+ ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
iolocked = 0;
if (lock_flags & XFS_IOLOCK_EXCL) {
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY)) == 0);
+ ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY |
+ XFS_LOCK_DEP_MASK)) == 0);
ASSERT(lock_flags != 0);
if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {