Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
kthread.c
Go to the documentation of this file.
1 
23 #include <linux/kthread.h>
24 #include <linux/freezer.h>
25 #include <linux/slab.h>
26 #include <linux/wait.h>
27 #include <linux/mount.h>
28 #include "ecryptfs_kernel.h"
29 
31  struct file **lower_file;
32  struct path path;
33  struct completion done;
35 };
36 
37 static struct ecryptfs_kthread_ctl {
38 #define ECRYPTFS_KTHREAD_ZOMBIE 0x00000001
39  u32 flags;
40  struct mutex mux;
41  struct list_head req_list;
43 } ecryptfs_kthread_ctl;
44 
45 static struct task_struct *ecryptfs_kthread;
46 
56 static int ecryptfs_threadfn(void *ignored)
57 {
58  set_freezable();
59  while (1) {
60  struct ecryptfs_open_req *req;
61 
63  ecryptfs_kthread_ctl.wait,
64  (!list_empty(&ecryptfs_kthread_ctl.req_list)
65  || kthread_should_stop()));
66  mutex_lock(&ecryptfs_kthread_ctl.mux);
67  if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
68  mutex_unlock(&ecryptfs_kthread_ctl.mux);
69  goto out;
70  }
71  while (!list_empty(&ecryptfs_kthread_ctl.req_list)) {
72  req = list_first_entry(&ecryptfs_kthread_ctl.req_list,
73  struct ecryptfs_open_req,
76  *req->lower_file = dentry_open(&req->path,
78  complete(&req->done);
79  }
80  mutex_unlock(&ecryptfs_kthread_ctl.mux);
81  }
82 out:
83  return 0;
84 }
85 
87 {
88  int rc = 0;
89 
90  mutex_init(&ecryptfs_kthread_ctl.mux);
91  init_waitqueue_head(&ecryptfs_kthread_ctl.wait);
92  INIT_LIST_HEAD(&ecryptfs_kthread_ctl.req_list);
93  ecryptfs_kthread = kthread_run(&ecryptfs_threadfn, NULL,
94  "ecryptfs-kthread");
95  if (IS_ERR(ecryptfs_kthread)) {
96  rc = PTR_ERR(ecryptfs_kthread);
97  printk(KERN_ERR "%s: Failed to create kernel thread; rc = [%d]"
98  "\n", __func__, rc);
99  }
100  return rc;
101 }
102 
104 {
105  struct ecryptfs_open_req *req;
106 
107  mutex_lock(&ecryptfs_kthread_ctl.mux);
108  ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE;
109  list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list,
111  list_del(&req->kthread_ctl_list);
112  *req->lower_file = ERR_PTR(-EIO);
113  complete(&req->done);
114  }
115  mutex_unlock(&ecryptfs_kthread_ctl.mux);
116  kthread_stop(ecryptfs_kthread);
117  wake_up(&ecryptfs_kthread_ctl.wait);
118 }
119 
131  struct dentry *lower_dentry,
132  struct vfsmount *lower_mnt,
133  const struct cred *cred)
134 {
135  struct ecryptfs_open_req req;
136  int flags = O_LARGEFILE;
137  int rc = 0;
138 
139  init_completion(&req.done);
140  req.lower_file = lower_file;
141  req.path.dentry = lower_dentry;
142  req.path.mnt = lower_mnt;
143 
144  /* Corresponding dput() and mntput() are done when the
145  * lower file is fput() when all eCryptfs files for the inode are
146  * released. */
147  flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
148  (*lower_file) = dentry_open(&req.path, flags, cred);
149  if (!IS_ERR(*lower_file))
150  goto out;
151  if ((flags & O_ACCMODE) == O_RDONLY) {
152  rc = PTR_ERR((*lower_file));
153  goto out;
154  }
155  mutex_lock(&ecryptfs_kthread_ctl.mux);
156  if (ecryptfs_kthread_ctl.flags & ECRYPTFS_KTHREAD_ZOMBIE) {
157  rc = -EIO;
158  mutex_unlock(&ecryptfs_kthread_ctl.mux);
159  printk(KERN_ERR "%s: We are in the middle of shutting down; "
160  "aborting privileged request to open lower file\n",
161  __func__);
162  goto out;
163  }
164  list_add_tail(&req.kthread_ctl_list, &ecryptfs_kthread_ctl.req_list);
165  mutex_unlock(&ecryptfs_kthread_ctl.mux);
166  wake_up(&ecryptfs_kthread_ctl.wait);
168  if (IS_ERR(*lower_file))
169  rc = PTR_ERR(*lower_file);
170 out:
171  return rc;
172 }