fs: don't use igrab() while holding i_lock

Fix the incorrect use of igrab() inside the i_lock in NFS and Ceph‥

If we are already holding the i_lock, we have a reference to the
inode so we can safely use ihold() to gain an extra reference. This
avoids hangs due to lock recursion on the i_lock now that the
inode_lock is gone and igrab() uses the i_lock itself.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Cc: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Dave Chinner and committed by Linus Torvalds 0444d76a cb1817b3

+5 -4
+1 -1
fs/ceph/addr.c
··· 92 92 ci->i_head_snapc = ceph_get_snap_context(snapc); 93 93 ++ci->i_wrbuffer_ref_head; 94 94 if (ci->i_wrbuffer_ref == 0) 95 - igrab(inode); 95 + ihold(inode); 96 96 ++ci->i_wrbuffer_ref; 97 97 dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d " 98 98 "snapc %p seq %lld (%d snaps)\n",
+2 -2
fs/ceph/snap.c
··· 463 463 464 464 dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode, 465 465 capsnap, snapc); 466 - igrab(inode); 467 - 466 + ihold(inode); 467 + 468 468 atomic_set(&capsnap->nref, 1); 469 469 capsnap->ci = ci; 470 470 INIT_LIST_HEAD(&capsnap->ci_item);
+2 -1
fs/nfs/nfs4state.c
··· 590 590 state->owner = owner; 591 591 atomic_inc(&owner->so_count); 592 592 list_add(&state->inode_states, &nfsi->open_states); 593 - state->inode = igrab(inode); 593 + ihold(inode); 594 + state->inode = inode; 594 595 spin_unlock(&inode->i_lock); 595 596 /* Note: The reclaim code dictates that we add stateless 596 597 * and read-only stateids to the end of the list */