- if (flags & SYNC_BDFLUSH) {
- if ((flags & SYNC_ATTR) &&
- ((ip->i_update_core) ||
- ((ip->i_itemp != NULL) &&
- (ip->i_itemp->ili_format.ilf_fields != 0)))) {
-
- /* Insert marker and drop lock if not already
- * done.
- */
- if (mount_locked) {
- IPOINTER_INSERT(ip, mp);
- }
-
- /*
- * We don't want the periodic flushing of the
- * inodes by vfs_sync() to interfere with
- * I/O to the file, especially read I/O
- * where it is only the access time stamp
- * that is being flushed out. To prevent
- * long periods where we have both inode
- * locks held shared here while reading the
- * inode's buffer in from disk, we drop the
- * inode lock while reading in the inode
- * buffer. We have to release the buffer
- * and reacquire the inode lock so that they
- * are acquired in the proper order (inode
- * locks first). The buffer will go at the
- * end of the lru chain, though, so we can
- * expect it to still be there when we go
- * for it again in xfs_iflush().
- */
- if ((xfs_ipincount(ip) == 0) &&
- xfs_iflock_nowait(ip)) {
-
- xfs_ifunlock(ip);
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- error = xfs_itobp(mp, NULL, ip,
- &dip, &bp, 0, 0);
- if (!error) {
- xfs_buf_relse(bp);
- } else {
- /* Bailing out, remove the
- * marker and free it.
- */
- XFS_MOUNT_ILOCK(mp);
- IPOINTER_REMOVE(ip, mp);
- XFS_MOUNT_IUNLOCK(mp);
-
- ASSERT(!(lock_flags &
- XFS_IOLOCK_SHARED));
-
- kmem_free(ipointer,
- sizeof(xfs_iptr_t));
- return (0);
- }
-
- /*
- * Since we dropped the inode lock,
- * the inode may have been reclaimed.
- * Therefore, we reacquire the mount
- * lock and check to see if we were the
- * inode reclaimed. If this happened
- * then the ipointer marker will no
- * longer point back at us. In this
- * case, move ip along to the inode
- * after the marker, remove the marker
- * and continue.
- */
- XFS_MOUNT_ILOCK(mp);
- mount_locked = B_TRUE;
-
- if (ip != ipointer->ip_mprev) {
- IPOINTER_REMOVE(ip, mp);
-
- ASSERT(!vnode_refed);
- ASSERT(!(lock_flags &
- XFS_IOLOCK_SHARED));
- continue;
- }
-
- ASSERT(ip->i_mount == mp);
-
- if (xfs_ilock_nowait(ip,
- XFS_ILOCK_SHARED) == 0) {
- ASSERT(ip->i_mount == mp);
- /*
- * We failed to reacquire
- * the inode lock without
- * sleeping, so just skip
- * the inode for now. We
- * clear the ILOCK bit from
- * the lock_flags so that we
- * won't try to drop a lock
- * we don't hold below.
- */
- lock_flags &= ~XFS_ILOCK_SHARED;
- IPOINTER_REMOVE(ip_next, mp);
- } else if ((xfs_ipincount(ip) == 0) &&
- xfs_iflock_nowait(ip)) {
- ASSERT(ip->i_mount == mp);
- /*
- * Since this is vfs_sync()
- * calling we only flush the
- * inode out if we can lock
- * it without sleeping and
- * it is not pinned. Drop
- * the mount lock here so
- * that we don't hold it for
- * too long. We already have
- * a marker in the list here.
- */
- XFS_MOUNT_IUNLOCK(mp);
- mount_locked = B_FALSE;
- error = xfs_iflush(ip,
- XFS_IFLUSH_DELWRI);
- } else {
- ASSERT(ip->i_mount == mp);
- IPOINTER_REMOVE(ip_next, mp);
- }
- }
-
- }