ceph: eliminate ceph_async_iput()
authorJeff Layton <jlayton@kernel.org>
Fri, 4 Jun 2021 16:03:09 +0000 (12:03 -0400)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 28 Jun 2021 22:15:52 +0000 (00:15 +0200)
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>
fs/ceph/caps.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/quota.c
fs/ceph/snap.c
fs/ceph/super.h

index 3fe9ea3..7bdefd0 100644 (file)
@@ -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);
                }
        }
index 6034821..1bd2cc0 100644 (file)
@@ -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);
index 87d3be1..f8a7fbf 100644 (file)
@@ -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:
index 4e32c96..620c691 100644 (file)
@@ -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)
index 8ca95d1..4ac0606 100644 (file)
@@ -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. */
index 31f0be9..6b6332a 100644 (file)
@@ -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)