Commit 23c2c76e authored by Jeff Layton's avatar Jeff Layton Committed by Ilya Dryomov
Browse files

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: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 7732fe16
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -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 @@ void ceph_handle_caps(struct ceph_mds_session *session,
	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);
		}
	}
+3 −25
Original line number Diff line number Diff line
@@ -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 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
		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 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
			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);
+11 −19
Original line number Diff line number Diff line
@@ -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 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
	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 @@ static void handle_lease(struct ceph_mds_client *mdsc,

out:
	mutex_unlock(&session->s_mutex);
	/* avoid calling iput_final() in mds dispatch threads */
	ceph_async_iput(inode);
	iput(inode);
	return;

bad:
+3 −6
Original line number Diff line number Diff line
@@ -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 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,

		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 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
			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)
+5 −11
Original line number Diff line number Diff line
@@ -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. */
Loading