ceph: eliminate ceph_async_iput()
Now that we don't need to hold session->s_mutex or the snap_rwsem when calling ceph_check_caps, we can eliminate ceph_async_iput and just use normal iput calls. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
7732fe168e
commit
23c2c76ead
@ -3142,8 +3142,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
|
||||
if (complete_capsnap)
|
||||
wake_up_all(&ci->i_cap_wq);
|
||||
while (put-- > 0) {
|
||||
/* avoid calling iput_final() in osd dispatch threads */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4131,8 +4130,7 @@ done:
|
||||
mutex_unlock(&session->s_mutex);
|
||||
done_unlocked:
|
||||
ceph_put_string(extra_info.pool_ns);
|
||||
/* avoid calling iput_final() in mds dispatch threads */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
return;
|
||||
|
||||
flush_cap_releases:
|
||||
@ -4174,8 +4172,7 @@ void ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
|
||||
spin_unlock(&mdsc->cap_delay_lock);
|
||||
dout("check_delayed_caps on %p\n", inode);
|
||||
ceph_check_caps(ci, 0, NULL);
|
||||
/* avoid calling iput_final() in tick thread */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
spin_lock(&mdsc->cap_delay_lock);
|
||||
}
|
||||
}
|
||||
|
@ -1566,8 +1566,7 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
|
||||
unlock_new_inode(in);
|
||||
}
|
||||
|
||||
/* avoid calling iput_final() in mds dispatch threads */
|
||||
ceph_async_iput(in);
|
||||
iput(in);
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -1764,13 +1763,11 @@ retry_lookup:
|
||||
if (ret < 0) {
|
||||
pr_err("ceph_fill_inode badness on %p\n", in);
|
||||
if (d_really_is_negative(dn)) {
|
||||
/* avoid calling iput_final() in mds
|
||||
* dispatch threads */
|
||||
if (in->i_state & I_NEW) {
|
||||
ihold(in);
|
||||
discard_new_inode(in);
|
||||
}
|
||||
ceph_async_iput(in);
|
||||
iput(in);
|
||||
}
|
||||
d_drop(dn);
|
||||
err = ret;
|
||||
@ -1783,7 +1780,7 @@ retry_lookup:
|
||||
if (ceph_security_xattr_deadlock(in)) {
|
||||
dout(" skip splicing dn %p to inode %p"
|
||||
" (security xattr deadlock)\n", dn, in);
|
||||
ceph_async_iput(in);
|
||||
iput(in);
|
||||
skipped++;
|
||||
goto next_item;
|
||||
}
|
||||
@ -1834,25 +1831,6 @@ bool ceph_inode_set_size(struct inode *inode, loff_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put reference to inode, but avoid calling iput_final() in current thread.
|
||||
* iput_final() may wait for reahahead pages. The wait can cause deadlock in
|
||||
* some contexts.
|
||||
*/
|
||||
void ceph_async_iput(struct inode *inode)
|
||||
{
|
||||
if (!inode)
|
||||
return;
|
||||
for (;;) {
|
||||
if (atomic_add_unless(&inode->i_count, -1, 1))
|
||||
break;
|
||||
if (queue_work(ceph_inode_to_client(inode)->inode_wq,
|
||||
&ceph_inode(inode)->i_work))
|
||||
break;
|
||||
/* queue work failed, i_count must be at least 2 */
|
||||
}
|
||||
}
|
||||
|
||||
void ceph_queue_inode_work(struct inode *inode, int work_bit)
|
||||
{
|
||||
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
|
||||
|
@ -824,14 +824,13 @@ void ceph_mdsc_release_request(struct kref *kref)
|
||||
ceph_msg_put(req->r_reply);
|
||||
if (req->r_inode) {
|
||||
ceph_put_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN);
|
||||
/* avoid calling iput_final() in mds dispatch threads */
|
||||
ceph_async_iput(req->r_inode);
|
||||
iput(req->r_inode);
|
||||
}
|
||||
if (req->r_parent) {
|
||||
ceph_put_cap_refs(ceph_inode(req->r_parent), CEPH_CAP_PIN);
|
||||
ceph_async_iput(req->r_parent);
|
||||
iput(req->r_parent);
|
||||
}
|
||||
ceph_async_iput(req->r_target_inode);
|
||||
iput(req->r_target_inode);
|
||||
if (req->r_dentry)
|
||||
dput(req->r_dentry);
|
||||
if (req->r_old_dentry)
|
||||
@ -845,7 +844,7 @@ void ceph_mdsc_release_request(struct kref *kref)
|
||||
*/
|
||||
ceph_put_cap_refs(ceph_inode(req->r_old_dentry_dir),
|
||||
CEPH_CAP_PIN);
|
||||
ceph_async_iput(req->r_old_dentry_dir);
|
||||
iput(req->r_old_dentry_dir);
|
||||
}
|
||||
kfree(req->r_path1);
|
||||
kfree(req->r_path2);
|
||||
@ -960,8 +959,7 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
|
||||
}
|
||||
|
||||
if (req->r_unsafe_dir) {
|
||||
/* avoid calling iput_final() in mds dispatch threads */
|
||||
ceph_async_iput(req->r_unsafe_dir);
|
||||
iput(req->r_unsafe_dir);
|
||||
req->r_unsafe_dir = NULL;
|
||||
}
|
||||
|
||||
@ -1132,7 +1130,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
|
||||
cap = rb_entry(rb_first(&ci->i_caps), struct ceph_cap, ci_node);
|
||||
if (!cap) {
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
goto random;
|
||||
}
|
||||
mds = cap->session->s_mds;
|
||||
@ -1141,9 +1139,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
|
||||
cap == ci->i_auth_cap ? "auth " : "", cap);
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
out:
|
||||
/* avoid calling iput_final() while holding mdsc->mutex or
|
||||
* in mds dispatch threads */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
return mds;
|
||||
|
||||
random:
|
||||
@ -1546,9 +1542,7 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
|
||||
spin_unlock(&session->s_cap_lock);
|
||||
|
||||
if (last_inode) {
|
||||
/* avoid calling iput_final() while holding
|
||||
* s_mutex or in mds dispatch threads */
|
||||
ceph_async_iput(last_inode);
|
||||
iput(last_inode);
|
||||
last_inode = NULL;
|
||||
}
|
||||
if (old_cap) {
|
||||
@ -1582,7 +1576,7 @@ out:
|
||||
session->s_cap_iterator = NULL;
|
||||
spin_unlock(&session->s_cap_lock);
|
||||
|
||||
ceph_async_iput(last_inode);
|
||||
iput(last_inode);
|
||||
if (old_cap)
|
||||
ceph_put_cap(session->s_mdsc, old_cap);
|
||||
|
||||
@ -1722,8 +1716,7 @@ static void remove_session_caps(struct ceph_mds_session *session)
|
||||
spin_unlock(&session->s_cap_lock);
|
||||
|
||||
inode = ceph_find_inode(sb, vino);
|
||||
/* avoid calling iput_final() while holding s_mutex */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
|
||||
spin_lock(&session->s_cap_lock);
|
||||
}
|
||||
@ -4369,8 +4362,7 @@ release:
|
||||
|
||||
out:
|
||||
mutex_unlock(&session->s_mutex);
|
||||
/* avoid calling iput_final() in mds dispatch threads */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
return;
|
||||
|
||||
bad:
|
||||
|
@ -74,8 +74,7 @@ void ceph_handle_quota(struct ceph_mds_client *mdsc,
|
||||
le64_to_cpu(h->max_files));
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
|
||||
/* avoid calling iput_final() in dispatch thread */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
}
|
||||
|
||||
static struct ceph_quotarealm_inode *
|
||||
@ -247,8 +246,7 @@ restart:
|
||||
|
||||
ci = ceph_inode(in);
|
||||
has_quota = __ceph_has_any_quota(ci);
|
||||
/* avoid calling iput_final() while holding mdsc->snap_rwsem */
|
||||
ceph_async_iput(in);
|
||||
iput(in);
|
||||
|
||||
next = realm->parent;
|
||||
if (has_quota || !next)
|
||||
@ -383,8 +381,7 @@ restart:
|
||||
pr_warn("Invalid quota check op (%d)\n", op);
|
||||
exceeded = true; /* Just break the loop */
|
||||
}
|
||||
/* avoid calling iput_final() while holding mdsc->snap_rwsem */
|
||||
ceph_async_iput(in);
|
||||
iput(in);
|
||||
|
||||
next = realm->parent;
|
||||
if (exceeded || !next)
|
||||
|
@ -677,15 +677,13 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
|
||||
if (!inode)
|
||||
continue;
|
||||
spin_unlock(&realm->inodes_with_caps_lock);
|
||||
/* avoid calling iput_final() while holding
|
||||
* mdsc->snap_rwsem or in mds dispatch threads */
|
||||
ceph_async_iput(lastinode);
|
||||
iput(lastinode);
|
||||
lastinode = inode;
|
||||
ceph_queue_cap_snap(ci);
|
||||
spin_lock(&realm->inodes_with_caps_lock);
|
||||
}
|
||||
spin_unlock(&realm->inodes_with_caps_lock);
|
||||
ceph_async_iput(lastinode);
|
||||
iput(lastinode);
|
||||
|
||||
dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino);
|
||||
}
|
||||
@ -839,9 +837,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc)
|
||||
ihold(inode);
|
||||
spin_unlock(&mdsc->snap_flush_lock);
|
||||
ceph_flush_snaps(ci, &session);
|
||||
/* avoid calling iput_final() while holding
|
||||
* session->s_mutex or in mds dispatch threads */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
spin_lock(&mdsc->snap_flush_lock);
|
||||
}
|
||||
spin_unlock(&mdsc->snap_flush_lock);
|
||||
@ -982,14 +978,12 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
|
||||
ceph_get_snap_realm(mdsc, realm);
|
||||
ceph_put_snap_realm(mdsc, oldrealm);
|
||||
|
||||
/* avoid calling iput_final() while holding
|
||||
* mdsc->snap_rwsem or mds in dispatch threads */
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
continue;
|
||||
|
||||
skip_inode:
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
ceph_async_iput(inode);
|
||||
iput(inode);
|
||||
}
|
||||
|
||||
/* we may have taken some of the old realm's children. */
|
||||
|
@ -988,8 +988,6 @@ extern int ceph_inode_holds_cap(struct inode *inode, int mask);
|
||||
extern bool ceph_inode_set_size(struct inode *inode, loff_t size);
|
||||
extern void __ceph_do_pending_vmtruncate(struct inode *inode);
|
||||
|
||||
extern void ceph_async_iput(struct inode *inode);
|
||||
|
||||
void ceph_queue_inode_work(struct inode *inode, int work_bit);
|
||||
|
||||
static inline void ceph_queue_vmtruncate(struct inode *inode)
|
||||
|
Loading…
Reference in New Issue
Block a user