ecryptfs: don't reinvent the wheels, please - use struct completion
Al Viro [Mon, 25 Jun 2012 07:38:56 +0000 (11:38 +0400)]
... and keep the sodding requests on stack - they are small enough.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/kthread.c
fs/ecryptfs/main.c

index 867b64c..989e034 100644 (file)
@@ -550,20 +550,6 @@ extern struct kmem_cache *ecryptfs_key_record_cache;
 extern struct kmem_cache *ecryptfs_key_sig_cache;
 extern struct kmem_cache *ecryptfs_global_auth_tok_cache;
 extern struct kmem_cache *ecryptfs_key_tfm_cache;
-extern struct kmem_cache *ecryptfs_open_req_cache;
-
-struct ecryptfs_open_req {
-#define ECRYPTFS_REQ_PROCESSED 0x00000001
-#define ECRYPTFS_REQ_DROPPED   0x00000002
-#define ECRYPTFS_REQ_ZOMBIE    0x00000004
-       u32 flags;
-       struct file **lower_file;
-       struct dentry *lower_dentry;
-       struct vfsmount *lower_mnt;
-       wait_queue_head_t wait;
-       struct mutex mux;
-       struct list_head kthread_ctl_list;
-};
 
 struct inode *ecryptfs_get_inode(struct inode *lower_inode,
                                 struct super_block *sb);
index 0dbe58a..c7d199d 100644 (file)
 #include <linux/mount.h>
 #include "ecryptfs_kernel.h"
 
-struct kmem_cache *ecryptfs_open_req_cache;
+struct ecryptfs_open_req {
+       struct file **lower_file;
+       struct dentry *lower_dentry;
+       struct vfsmount *lower_mnt;
+       struct completion done;
+       struct list_head kthread_ctl_list;
+};
 
 static struct ecryptfs_kthread_ctl {
 #define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
@@ -67,18 +73,13 @@ static int ecryptfs_threadfn(void *ignored)
                        req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
                                               struct ecryptfs_open_req,
                                               kthread_ctl_list);
-                       mutex_lock(&req->mux);
                        list_del(&req->kthread_ctl_list);
-                       if (!(req->flags & ECRYPTFS_REQ_ZOMBIE)) {
-                               dget(req->lower_dentry);
-                               mntget(req->lower_mnt);
-                               (*req->lower_file) = dentry_open(
-                                       req->lower_dentry, req->lower_mnt,
-                                       (O_RDWR | O_LARGEFILE), current_cred());
-                               req->flags |= ECRYPTFS_REQ_PROCESSED;
-                       }
-                       wake_up(&req->wait);
-                       mutex_unlock(&req->mux);
+                       dget(req->lower_dentry);
+                       mntget(req->lower_mnt);
+                       (*req->lower_file) = dentry_open(
+                               req->lower_dentry, req->lower_mnt,
+                               (O_RDWR | O_LARGEFILE), current_cred());
+                       complete(&req->done);
                }
                mutex_unlock(&ecryptfs_kthread_ctl.mux);
        }
@@ -111,10 +112,9 @@ void ecryptfs_destroy_kthread(void)
        ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
        list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list,
                            kthread_ctl_list) {
-               mutex_lock(&req->mux);
-               req->flags |= ECRYPTFS_REQ_ZOMBIE;
-               wake_up(&req->wait);
-               mutex_unlock(&req->mux);
+               list_del(&req->kthread_ctl_list);
+               *req->lower_file = ERR_PTR(-EIO);
+               complete(&req->done);
        }
        mutex_unlock(&ecryptfs_kthread_ctl.mux);
        kthread_stop(ecryptfs_kthread);
@@ -136,7 +136,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
                             struct vfsmount *lower_mnt,
                             const struct cred *cred)
 {
-       struct ecryptfs_open_req *req;
+       struct ecryptfs_open_req req;
        int flags = O_LARGEFILE;
        int rc = 0;
 
@@ -153,17 +153,10 @@ int ecryptfs_privileged_open(struct file **lower_file,
                rc = PTR_ERR((*lower_file));
                goto out;
        }
-       req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
-       if (!req) {
-               rc = -ENOMEM;
-               goto out;
-       }
-       mutex_init(&req->mux);
-       req->lower_file = lower_file;
-       req->lower_dentry = lower_dentry;
-       req->lower_mnt = lower_mnt;
-       init_waitqueue_head(&req->wait);
-       req->flags = 0;
+       init_completion(&req.done);
+       req.lower_file = lower_file;
+       req.lower_dentry = lower_dentry;
+       req.lower_mnt = lower_mnt;
        mutex_lock(&ecryptfs_kthread_ctl.mux);
        if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
                rc = -EIO;
@@ -171,27 +164,14 @@ int ecryptfs_privileged_open(struct file **lower_file,
                printk(KERN_ERR "%s: We are in the middle of shutting down; "
                       "aborting privileged request to open lower file\n",
                        __func__);
-               goto out_free;
+               goto out;
        }
-       list_add_tail(&req->kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
+       list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
        mutex_unlock(&ecryptfs_kthread_ctl.mux);
        wake_up(&ecryptfs_kthread_ctl.wait);
-       wait_event(req->wait, (req->flags != 0));
-       mutex_lock(&req->mux);
-       BUG_ON(req->flags == 0);
-       if (req->flags & ECRYPTFS_REQ_DROPPED
-           || req->flags & ECRYPTFS_REQ_ZOMBIE) {
-               rc = -EIO;
-               printk(KERN_WARNING "%s: Privileged open request dropped\n",
-                      __func__);
-               goto out_unlock;
-       }
-       if (IS_ERR(*req->lower_file))
-               rc = PTR_ERR(*req->lower_file);
-out_unlock:
-       mutex_unlock(&req->mux);
-out_free:
-       kmem_cache_free(ecryptfs_open_req_cache, req);
+       wait_for_completion(&req.done);
+       if (IS_ERR(*lower_file))
+               rc = PTR_ERR(*lower_file);
 out:
        return rc;
 }
index 7edeb3d..1c0b3b6 100644 (file)
@@ -681,11 +681,6 @@ static struct ecryptfs_cache_info {
                .name = "ecryptfs_key_tfm_cache",
                .size = sizeof(struct ecryptfs_key_tfm),
        },
-       {
-               .cache = &ecryptfs_open_req_cache,
-               .name = "ecryptfs_open_req_cache",
-               .size = sizeof(struct ecryptfs_open_req),
-       },
 };
 
 static void ecryptfs_free_kmem_caches(void)