aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/inode.c')
-rw-r--r--fs/coda/inode.c82
1 files changed, 47 insertions, 35 deletions
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 6526e6f21ecf..871b27715465 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -15,7 +15,8 @@
15#include <linux/stat.h> 15#include <linux/stat.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/unistd.h> 17#include <linux/unistd.h>
18#include <linux/smp_lock.h> 18#include <linux/mutex.h>
19#include <linux/spinlock.h>
19#include <linux/file.h> 20#include <linux/file.h>
20#include <linux/vfs.h> 21#include <linux/vfs.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
@@ -27,10 +28,9 @@
27#include <linux/vmalloc.h> 28#include <linux/vmalloc.h>
28 29
29#include <linux/coda.h> 30#include <linux/coda.h>
30#include <linux/coda_linux.h>
31#include <linux/coda_psdev.h> 31#include <linux/coda_psdev.h>
32#include <linux/coda_fs_i.h> 32#include "coda_linux.h"
33#include <linux/coda_cache.h> 33#include "coda_cache.h"
34 34
35#include "coda_int.h" 35#include "coda_int.h"
36 36
@@ -44,21 +44,29 @@ static struct kmem_cache * coda_inode_cachep;
44static struct inode *coda_alloc_inode(struct super_block *sb) 44static struct inode *coda_alloc_inode(struct super_block *sb)
45{ 45{
46 struct coda_inode_info *ei; 46 struct coda_inode_info *ei;
47 ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); 47 ei = kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL);
48 if (!ei) 48 if (!ei)
49 return NULL; 49 return NULL;
50 memset(&ei->c_fid, 0, sizeof(struct CodaFid)); 50 memset(&ei->c_fid, 0, sizeof(struct CodaFid));
51 ei->c_flags = 0; 51 ei->c_flags = 0;
52 ei->c_uid = 0; 52 ei->c_uid = 0;
53 ei->c_cached_perm = 0; 53 ei->c_cached_perm = 0;
54 spin_lock_init(&ei->c_lock);
54 return &ei->vfs_inode; 55 return &ei->vfs_inode;
55} 56}
56 57
57static void coda_destroy_inode(struct inode *inode) 58static void coda_i_callback(struct rcu_head *head)
58{ 59{
60 struct inode *inode = container_of(head, struct inode, i_rcu);
61 INIT_LIST_HEAD(&inode->i_dentry);
59 kmem_cache_free(coda_inode_cachep, ITOC(inode)); 62 kmem_cache_free(coda_inode_cachep, ITOC(inode));
60} 63}
61 64
65static void coda_destroy_inode(struct inode *inode)
66{
67 call_rcu(&inode->i_rcu, coda_i_callback);
68}
69
62static void init_once(void *foo) 70static void init_once(void *foo)
63{ 71{
64 struct coda_inode_info *ei = (struct coda_inode_info *) foo; 72 struct coda_inode_info *ei = (struct coda_inode_info *) foo;
@@ -143,7 +151,7 @@ static int get_device_index(struct coda_mount_data *data)
143static int coda_fill_super(struct super_block *sb, void *data, int silent) 151static int coda_fill_super(struct super_block *sb, void *data, int silent)
144{ 152{
145 struct inode *root = NULL; 153 struct inode *root = NULL;
146 struct venus_comm *vc = NULL; 154 struct venus_comm *vc;
147 struct CodaFid fid; 155 struct CodaFid fid;
148 int error; 156 int error;
149 int idx; 157 int idx;
@@ -157,21 +165,26 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
157 printk(KERN_INFO "coda_read_super: device index: %i\n", idx); 165 printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
158 166
159 vc = &coda_comms[idx]; 167 vc = &coda_comms[idx];
168 mutex_lock(&vc->vc_mutex);
169
160 if (!vc->vc_inuse) { 170 if (!vc->vc_inuse) {
161 printk("coda_read_super: No pseudo device\n"); 171 printk("coda_read_super: No pseudo device\n");
162 return -EINVAL; 172 error = -EINVAL;
173 goto unlock_out;
163 } 174 }
164 175
165 if ( vc->vc_sb ) { 176 if (vc->vc_sb) {
166 printk("coda_read_super: Device already mounted\n"); 177 printk("coda_read_super: Device already mounted\n");
167 return -EBUSY; 178 error = -EBUSY;
179 goto unlock_out;
168 } 180 }
169 181
170 error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); 182 error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY);
171 if (error) 183 if (error)
172 goto bdi_err; 184 goto unlock_out;
173 185
174 vc->vc_sb = sb; 186 vc->vc_sb = sb;
187 mutex_unlock(&vc->vc_mutex);
175 188
176 sb->s_fs_info = vc; 189 sb->s_fs_info = vc;
177 sb->s_flags |= MS_NOATIME; 190 sb->s_flags |= MS_NOATIME;
@@ -179,6 +192,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
179 sb->s_blocksize_bits = 12; 192 sb->s_blocksize_bits = 12;
180 sb->s_magic = CODA_SUPER_MAGIC; 193 sb->s_magic = CODA_SUPER_MAGIC;
181 sb->s_op = &coda_super_operations; 194 sb->s_op = &coda_super_operations;
195 sb->s_d_op = &coda_dentry_operations;
182 sb->s_bdi = &vc->bdi; 196 sb->s_bdi = &vc->bdi;
183 197
184 /* get root fid from Venus: this needs the root inode */ 198 /* get root fid from Venus: this needs the root inode */
@@ -200,26 +214,33 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
200 printk("coda_read_super: rootinode is %ld dev %s\n", 214 printk("coda_read_super: rootinode is %ld dev %s\n",
201 root->i_ino, root->i_sb->s_id); 215 root->i_ino, root->i_sb->s_id);
202 sb->s_root = d_alloc_root(root); 216 sb->s_root = d_alloc_root(root);
203 if (!sb->s_root) 217 if (!sb->s_root) {
218 error = -EINVAL;
204 goto error; 219 goto error;
205 return 0; 220 }
221 return 0;
206 222
207 error: 223error:
208 bdi_destroy(&vc->bdi);
209 bdi_err:
210 if (root) 224 if (root)
211 iput(root); 225 iput(root);
212 if (vc)
213 vc->vc_sb = NULL;
214 226
215 return -EINVAL; 227 mutex_lock(&vc->vc_mutex);
228 bdi_destroy(&vc->bdi);
229 vc->vc_sb = NULL;
230 sb->s_fs_info = NULL;
231unlock_out:
232 mutex_unlock(&vc->vc_mutex);
233 return error;
216} 234}
217 235
218static void coda_put_super(struct super_block *sb) 236static void coda_put_super(struct super_block *sb)
219{ 237{
220 bdi_destroy(&coda_vcp(sb)->bdi); 238 struct venus_comm *vcp = coda_vcp(sb);
221 coda_vcp(sb)->vc_sb = NULL; 239 mutex_lock(&vcp->vc_mutex);
240 bdi_destroy(&vcp->bdi);
241 vcp->vc_sb = NULL;
222 sb->s_fs_info = NULL; 242 sb->s_fs_info = NULL;
243 mutex_unlock(&vcp->vc_mutex);
223 244
224 printk("Coda: Bye bye.\n"); 245 printk("Coda: Bye bye.\n");
225} 246}
@@ -245,8 +266,6 @@ int coda_setattr(struct dentry *de, struct iattr *iattr)
245 struct coda_vattr vattr; 266 struct coda_vattr vattr;
246 int error; 267 int error;
247 268
248 lock_kernel();
249
250 memset(&vattr, 0, sizeof(vattr)); 269 memset(&vattr, 0, sizeof(vattr));
251 270
252 inode->i_ctime = CURRENT_TIME_SEC; 271 inode->i_ctime = CURRENT_TIME_SEC;
@@ -256,13 +275,10 @@ int coda_setattr(struct dentry *de, struct iattr *iattr)
256 /* Venus is responsible for truncating the container-file!!! */ 275 /* Venus is responsible for truncating the container-file!!! */
257 error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr); 276 error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr);
258 277
259 if ( !error ) { 278 if (!error) {
260 coda_vattr_to_iattr(inode, &vattr); 279 coda_vattr_to_iattr(inode, &vattr);
261 coda_cache_clear_inode(inode); 280 coda_cache_clear_inode(inode);
262 } 281 }
263
264 unlock_kernel();
265
266 return error; 282 return error;
267} 283}
268 284
@@ -276,12 +292,8 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
276{ 292{
277 int error; 293 int error;
278 294
279 lock_kernel();
280
281 error = venus_statfs(dentry, buf); 295 error = venus_statfs(dentry, buf);
282 296
283 unlock_kernel();
284
285 if (error) { 297 if (error) {
286 /* fake something like AFS does */ 298 /* fake something like AFS does */
287 buf->f_blocks = 9000000; 299 buf->f_blocks = 9000000;
@@ -301,16 +313,16 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
301 313
302/* init_coda: used by filesystems.c to register coda */ 314/* init_coda: used by filesystems.c to register coda */
303 315
304static int coda_get_sb(struct file_system_type *fs_type, 316static struct dentry *coda_mount(struct file_system_type *fs_type,
305 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 317 int flags, const char *dev_name, void *data)
306{ 318{
307 return get_sb_nodev(fs_type, flags, data, coda_fill_super, mnt); 319 return mount_nodev(fs_type, flags, data, coda_fill_super);
308} 320}
309 321
310struct file_system_type coda_fs_type = { 322struct file_system_type coda_fs_type = {
311 .owner = THIS_MODULE, 323 .owner = THIS_MODULE,
312 .name = "coda", 324 .name = "coda",
313 .get_sb = coda_get_sb, 325 .mount = coda_mount,
314 .kill_sb = kill_anon_super, 326 .kill_sb = kill_anon_super,
315 .fs_flags = FS_BINARY_MOUNTDATA, 327 .fs_flags = FS_BINARY_MOUNTDATA,
316}; 328};