aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/coda/dir.c149
-rw-r--r--fs/coda/file.c19
-rw-r--r--fs/coda/inode.c46
-rw-r--r--fs/coda/pioctl.c22
-rw-r--r--fs/coda/psdev.c13
-rw-r--r--fs/coda/symlink.c3
-rw-r--r--fs/coda/upcall.c32
-rw-r--r--include/linux/coda_psdev.h2
8 files changed, 96 insertions, 190 deletions
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 69fbbea75f1b..96fbeab77f2f 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -17,7 +17,6 @@
17#include <linux/stat.h> 17#include <linux/stat.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/smp_lock.h>
21#include <linux/spinlock.h> 20#include <linux/spinlock.h>
22 21
23#include <asm/uaccess.h> 22#include <asm/uaccess.h>
@@ -117,15 +116,11 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc
117 goto exit; 116 goto exit;
118 } 117 }
119 118
120 lock_kernel();
121
122 error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length, 119 error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
123 &type, &resfid); 120 &type, &resfid);
124 if (!error) 121 if (!error)
125 error = coda_cnode_make(&inode, &resfid, dir->i_sb); 122 error = coda_cnode_make(&inode, &resfid, dir->i_sb);
126 123
127 unlock_kernel();
128
129 if (error && error != -ENOENT) 124 if (error && error != -ENOENT)
130 return ERR_PTR(error); 125 return ERR_PTR(error);
131 126
@@ -141,28 +136,24 @@ exit:
141 136
142int coda_permission(struct inode *inode, int mask) 137int coda_permission(struct inode *inode, int mask)
143{ 138{
144 int error = 0; 139 int error;
145 140
146 mask &= MAY_READ | MAY_WRITE | MAY_EXEC; 141 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
147 142
148 if (!mask) 143 if (!mask)
149 return 0; 144 return 0;
150 145
151 if ((mask & MAY_EXEC) && !execute_ok(inode)) 146 if ((mask & MAY_EXEC) && !execute_ok(inode))
152 return -EACCES; 147 return -EACCES;
153 148
154 lock_kernel();
155
156 if (coda_cache_check(inode, mask)) 149 if (coda_cache_check(inode, mask))
157 goto out; 150 return 0;
158 151
159 error = venus_access(inode->i_sb, coda_i2f(inode), mask); 152 error = venus_access(inode->i_sb, coda_i2f(inode), mask);
160 153
161 if (!error) 154 if (!error)
162 coda_cache_enter(inode, mask); 155 coda_cache_enter(inode, mask);
163 156
164 out:
165 unlock_kernel();
166 return error; 157 return error;
167} 158}
168 159
@@ -201,41 +192,34 @@ static inline void coda_dir_drop_nlink(struct inode *dir)
201/* creation routines: create, mknod, mkdir, link, symlink */ 192/* creation routines: create, mknod, mkdir, link, symlink */
202static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd) 193static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd)
203{ 194{
204 int error=0; 195 int error;
205 const char *name=de->d_name.name; 196 const char *name=de->d_name.name;
206 int length=de->d_name.len; 197 int length=de->d_name.len;
207 struct inode *inode; 198 struct inode *inode;
208 struct CodaFid newfid; 199 struct CodaFid newfid;
209 struct coda_vattr attrs; 200 struct coda_vattr attrs;
210 201
211 lock_kernel(); 202 if (coda_isroot(dir) && coda_iscontrol(name, length))
212
213 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
214 unlock_kernel();
215 return -EPERM; 203 return -EPERM;
216 }
217 204
218 error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 205 error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
219 0, mode, &newfid, &attrs); 206 0, mode, &newfid, &attrs);
220 207 if (error)
221 if ( error ) { 208 goto err_out;
222 unlock_kernel();
223 d_drop(de);
224 return error;
225 }
226 209
227 inode = coda_iget(dir->i_sb, &newfid, &attrs); 210 inode = coda_iget(dir->i_sb, &newfid, &attrs);
228 if ( IS_ERR(inode) ) { 211 if (IS_ERR(inode)) {
229 unlock_kernel(); 212 error = PTR_ERR(inode);
230 d_drop(de); 213 goto err_out;
231 return PTR_ERR(inode);
232 } 214 }
233 215
234 /* invalidate the directory cnode's attributes */ 216 /* invalidate the directory cnode's attributes */
235 coda_dir_update_mtime(dir); 217 coda_dir_update_mtime(dir);
236 unlock_kernel();
237 d_instantiate(de, inode); 218 d_instantiate(de, inode);
238 return 0; 219 return 0;
220err_out:
221 d_drop(de);
222 return error;
239} 223}
240 224
241static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) 225static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
@@ -247,36 +231,29 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
247 int error; 231 int error;
248 struct CodaFid newfid; 232 struct CodaFid newfid;
249 233
250 lock_kernel(); 234 if (coda_isroot(dir) && coda_iscontrol(name, len))
251
252 if (coda_isroot(dir) && coda_iscontrol(name, len)) {
253 unlock_kernel();
254 return -EPERM; 235 return -EPERM;
255 }
256 236
257 attrs.va_mode = mode; 237 attrs.va_mode = mode;
258 error = venus_mkdir(dir->i_sb, coda_i2f(dir), 238 error = venus_mkdir(dir->i_sb, coda_i2f(dir),
259 name, len, &newfid, &attrs); 239 name, len, &newfid, &attrs);
260 240 if (error)
261 if ( error ) { 241 goto err_out;
262 unlock_kernel();
263 d_drop(de);
264 return error;
265 }
266 242
267 inode = coda_iget(dir->i_sb, &newfid, &attrs); 243 inode = coda_iget(dir->i_sb, &newfid, &attrs);
268 if ( IS_ERR(inode) ) { 244 if (IS_ERR(inode)) {
269 unlock_kernel(); 245 error = PTR_ERR(inode);
270 d_drop(de); 246 goto err_out;
271 return PTR_ERR(inode);
272 } 247 }
273 248
274 /* invalidate the directory cnode's attributes */ 249 /* invalidate the directory cnode's attributes */
275 coda_dir_inc_nlink(dir); 250 coda_dir_inc_nlink(dir);
276 coda_dir_update_mtime(dir); 251 coda_dir_update_mtime(dir);
277 unlock_kernel();
278 d_instantiate(de, inode); 252 d_instantiate(de, inode);
279 return 0; 253 return 0;
254err_out:
255 d_drop(de);
256 return error;
280} 257}
281 258
282/* try to make de an entry in dir_inodde linked to source_de */ 259/* try to make de an entry in dir_inodde linked to source_de */
@@ -288,52 +265,38 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
288 int len = de->d_name.len; 265 int len = de->d_name.len;
289 int error; 266 int error;
290 267
291 lock_kernel(); 268 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
292
293 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
294 unlock_kernel();
295 return -EPERM; 269 return -EPERM;
296 }
297 270
298 error = venus_link(dir_inode->i_sb, coda_i2f(inode), 271 error = venus_link(dir_inode->i_sb, coda_i2f(inode),
299 coda_i2f(dir_inode), (const char *)name, len); 272 coda_i2f(dir_inode), (const char *)name, len);
300
301 if (error) { 273 if (error) {
302 d_drop(de); 274 d_drop(de);
303 goto out; 275 return error;
304 } 276 }
305 277
306 coda_dir_update_mtime(dir_inode); 278 coda_dir_update_mtime(dir_inode);
307 atomic_inc(&inode->i_count); 279 atomic_inc(&inode->i_count);
308 d_instantiate(de, inode); 280 d_instantiate(de, inode);
309 inc_nlink(inode); 281 inc_nlink(inode);
310 282 return 0;
311out:
312 unlock_kernel();
313 return(error);
314} 283}
315 284
316 285
317static int coda_symlink(struct inode *dir_inode, struct dentry *de, 286static int coda_symlink(struct inode *dir_inode, struct dentry *de,
318 const char *symname) 287 const char *symname)
319{ 288{
320 const char *name = de->d_name.name; 289 const char *name = de->d_name.name;
321 int len = de->d_name.len; 290 int len = de->d_name.len;
322 int symlen; 291 int symlen;
323 int error = 0; 292 int error;
324
325 lock_kernel();
326 293
327 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) { 294 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
328 unlock_kernel();
329 return -EPERM; 295 return -EPERM;
330 }
331 296
332 symlen = strlen(symname); 297 symlen = strlen(symname);
333 if ( symlen > CODA_MAXPATHLEN ) { 298 if (symlen > CODA_MAXPATHLEN)
334 unlock_kernel();
335 return -ENAMETOOLONG; 299 return -ENAMETOOLONG;
336 }
337 300
338 /* 301 /*
339 * This entry is now negative. Since we do not create 302 * This entry is now negative. Since we do not create
@@ -344,10 +307,9 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
344 symname, symlen); 307 symname, symlen);
345 308
346 /* mtime is no good anymore */ 309 /* mtime is no good anymore */
347 if ( !error ) 310 if (!error)
348 coda_dir_update_mtime(dir_inode); 311 coda_dir_update_mtime(dir_inode);
349 312
350 unlock_kernel();
351 return error; 313 return error;
352} 314}
353 315
@@ -358,17 +320,12 @@ static int coda_unlink(struct inode *dir, struct dentry *de)
358 const char *name = de->d_name.name; 320 const char *name = de->d_name.name;
359 int len = de->d_name.len; 321 int len = de->d_name.len;
360 322
361 lock_kernel();
362
363 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len); 323 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
364 if ( error ) { 324 if (error)
365 unlock_kernel();
366 return error; 325 return error;
367 }
368 326
369 coda_dir_update_mtime(dir); 327 coda_dir_update_mtime(dir);
370 drop_nlink(de->d_inode); 328 drop_nlink(de->d_inode);
371 unlock_kernel();
372 return 0; 329 return 0;
373} 330}
374 331
@@ -378,8 +335,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
378 int len = de->d_name.len; 335 int len = de->d_name.len;
379 int error; 336 int error;
380 337
381 lock_kernel();
382
383 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); 338 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
384 if (!error) { 339 if (!error) {
385 /* VFS may delete the child */ 340 /* VFS may delete the child */
@@ -390,7 +345,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
390 coda_dir_drop_nlink(dir); 345 coda_dir_drop_nlink(dir);
391 coda_dir_update_mtime(dir); 346 coda_dir_update_mtime(dir);
392 } 347 }
393 unlock_kernel();
394 return error; 348 return error;
395} 349}
396 350
@@ -404,15 +358,12 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
404 int new_length = new_dentry->d_name.len; 358 int new_length = new_dentry->d_name.len;
405 int error; 359 int error;
406 360
407 lock_kernel();
408
409 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), 361 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
410 coda_i2f(new_dir), old_length, new_length, 362 coda_i2f(new_dir), old_length, new_length,
411 (const char *) old_name, (const char *)new_name); 363 (const char *) old_name, (const char *)new_name);
412 364 if (!error) {
413 if ( !error ) { 365 if (new_dentry->d_inode) {
414 if ( new_dentry->d_inode ) { 366 if (S_ISDIR(new_dentry->d_inode->i_mode)) {
415 if ( S_ISDIR(new_dentry->d_inode->i_mode) ) {
416 coda_dir_drop_nlink(old_dir); 367 coda_dir_drop_nlink(old_dir);
417 coda_dir_inc_nlink(new_dir); 368 coda_dir_inc_nlink(new_dir);
418 } 369 }
@@ -424,8 +375,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
424 coda_flag_inode(new_dir, C_VATTR); 375 coda_flag_inode(new_dir, C_VATTR);
425 } 376 }
426 } 377 }
427 unlock_kernel();
428
429 return error; 378 return error;
430} 379}
431 380
@@ -595,10 +544,7 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
595 struct inode *inode = de->d_inode; 544 struct inode *inode = de->d_inode;
596 struct coda_inode_info *cii; 545 struct coda_inode_info *cii;
597 546
598 if (!inode) 547 if (!inode || coda_isroot(inode))
599 return 1;
600 lock_kernel();
601 if (coda_isroot(inode))
602 goto out; 548 goto out;
603 if (is_bad_inode(inode)) 549 if (is_bad_inode(inode))
604 goto bad; 550 goto bad;
@@ -621,12 +567,9 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
621 spin_lock(&cii->c_lock); 567 spin_lock(&cii->c_lock);
622 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 568 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
623 spin_unlock(&cii->c_lock); 569 spin_unlock(&cii->c_lock);
624
625bad: 570bad:
626 unlock_kernel();
627 return 0; 571 return 0;
628out: 572out:
629 unlock_kernel();
630 return 1; 573 return 1;
631} 574}
632 575
@@ -659,20 +602,19 @@ static int coda_dentry_delete(struct dentry * dentry)
659int coda_revalidate_inode(struct dentry *dentry) 602int coda_revalidate_inode(struct dentry *dentry)
660{ 603{
661 struct coda_vattr attr; 604 struct coda_vattr attr;
662 int error = 0; 605 int error;
663 int old_mode; 606 int old_mode;
664 ino_t old_ino; 607 ino_t old_ino;
665 struct inode *inode = dentry->d_inode; 608 struct inode *inode = dentry->d_inode;
666 struct coda_inode_info *cii = ITOC(inode); 609 struct coda_inode_info *cii = ITOC(inode);
667 610
668 lock_kernel(); 611 if (!cii->c_flags)
669 if ( !cii->c_flags ) 612 return 0;
670 goto ok;
671 613
672 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) { 614 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
673 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr); 615 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
674 if ( error ) 616 if (error)
675 goto return_bad; 617 return -EIO;
676 618
677 /* this inode may be lost if: 619 /* this inode may be lost if:
678 - it's ino changed 620 - it's ino changed
@@ -691,7 +633,7 @@ int coda_revalidate_inode(struct dentry *dentry)
691 /* the following can happen when a local fid is replaced 633 /* the following can happen when a local fid is replaced
692 with a global one, here we lose and declare the inode bad */ 634 with a global one, here we lose and declare the inode bad */
693 if (inode->i_ino != old_ino) 635 if (inode->i_ino != old_ino)
694 goto return_bad; 636 return -EIO;
695 637
696 coda_flag_inode_children(inode, C_FLUSH); 638 coda_flag_inode_children(inode, C_FLUSH);
697 639
@@ -699,12 +641,5 @@ int coda_revalidate_inode(struct dentry *dentry)
699 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 641 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
700 spin_unlock(&cii->c_lock); 642 spin_unlock(&cii->c_lock);
701 } 643 }
702
703ok:
704 unlock_kernel();
705 return 0; 644 return 0;
706
707return_bad:
708 unlock_kernel();
709 return -EIO;
710} 645}
diff --git a/fs/coda/file.c b/fs/coda/file.c
index c4e395781d41..c8b50ba4366a 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -15,7 +15,6 @@
15#include <linux/stat.h> 15#include <linux/stat.h>
16#include <linux/cred.h> 16#include <linux/cred.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/smp_lock.h>
19#include <linux/spinlock.h> 18#include <linux/spinlock.h>
20#include <linux/string.h> 19#include <linux/string.h>
21#include <linux/slab.h> 20#include <linux/slab.h>
@@ -144,8 +143,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
144 if (!cfi) 143 if (!cfi)
145 return -ENOMEM; 144 return -ENOMEM;
146 145
147 lock_kernel();
148
149 error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, 146 error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
150 &host_file); 147 &host_file);
151 if (!host_file) 148 if (!host_file)
@@ -153,7 +150,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
153 150
154 if (error) { 151 if (error) {
155 kfree(cfi); 152 kfree(cfi);
156 unlock_kernel();
157 return error; 153 return error;
158 } 154 }
159 155
@@ -165,8 +161,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
165 161
166 BUG_ON(coda_file->private_data != NULL); 162 BUG_ON(coda_file->private_data != NULL);
167 coda_file->private_data = cfi; 163 coda_file->private_data = cfi;
168
169 unlock_kernel();
170 return 0; 164 return 0;
171} 165}
172 166
@@ -177,9 +171,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
177 struct coda_file_info *cfi; 171 struct coda_file_info *cfi;
178 struct coda_inode_info *cii; 172 struct coda_inode_info *cii;
179 struct inode *host_inode; 173 struct inode *host_inode;
180 int err = 0; 174 int err;
181
182 lock_kernel();
183 175
184 cfi = CODA_FTOC(coda_file); 176 cfi = CODA_FTOC(coda_file);
185 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); 177 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
@@ -203,8 +195,6 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
203 kfree(coda_file->private_data); 195 kfree(coda_file->private_data);
204 coda_file->private_data = NULL; 196 coda_file->private_data = NULL;
205 197
206 unlock_kernel();
207
208 /* VFS fput ignores the return value from file_operations->release, so 198 /* VFS fput ignores the return value from file_operations->release, so
209 * there is no use returning an error here */ 199 * there is no use returning an error here */
210 return 0; 200 return 0;
@@ -215,7 +205,7 @@ int coda_fsync(struct file *coda_file, int datasync)
215 struct file *host_file; 205 struct file *host_file;
216 struct inode *coda_inode = coda_file->f_path.dentry->d_inode; 206 struct inode *coda_inode = coda_file->f_path.dentry->d_inode;
217 struct coda_file_info *cfi; 207 struct coda_file_info *cfi;
218 int err = 0; 208 int err;
219 209
220 if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) || 210 if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||
221 S_ISLNK(coda_inode->i_mode))) 211 S_ISLNK(coda_inode->i_mode)))
@@ -226,11 +216,8 @@ int coda_fsync(struct file *coda_file, int datasync)
226 host_file = cfi->cfi_container; 216 host_file = cfi->cfi_container;
227 217
228 err = vfs_fsync(host_file, datasync); 218 err = vfs_fsync(host_file, datasync);
229 if ( !err && !datasync ) { 219 if (!err && !datasync)
230 lock_kernel();
231 err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); 220 err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode));
232 unlock_kernel();
233 }
234 221
235 return err; 222 return err;
236} 223}
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 0553f3bd7b1b..b7fa3e3d772f 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -150,8 +150,6 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
150 int error; 150 int error;
151 int idx; 151 int idx;
152 152
153 lock_kernel();
154
155 idx = get_device_index((struct coda_mount_data *) data); 153 idx = get_device_index((struct coda_mount_data *) data);
156 154
157 /* Ignore errors in data, for backward compatibility */ 155 /* Ignore errors in data, for backward compatibility */
@@ -161,23 +159,26 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
161 printk(KERN_INFO "coda_read_super: device index: %i\n", idx); 159 printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
162 160
163 vc = &coda_comms[idx]; 161 vc = &coda_comms[idx];
162 lock_kernel();
163
164 if (!vc->vc_inuse) { 164 if (!vc->vc_inuse) {
165 printk("coda_read_super: No pseudo device\n"); 165 printk("coda_read_super: No pseudo device\n");
166 unlock_kernel(); 166 error = -EINVAL;
167 return -EINVAL; 167 goto unlock_out;
168 } 168 }
169 169
170 if ( vc->vc_sb ) { 170 if (vc->vc_sb) {
171 printk("coda_read_super: Device already mounted\n"); 171 printk("coda_read_super: Device already mounted\n");
172 unlock_kernel(); 172 error = -EBUSY;
173 return -EBUSY; 173 goto unlock_out;
174 } 174 }
175 175
176 error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); 176 error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY);
177 if (error) 177 if (error)
178 goto bdi_err; 178 goto unlock_out;
179 179
180 vc->vc_sb = sb; 180 vc->vc_sb = sb;
181 unlock_kernel();
181 182
182 sb->s_fs_info = vc; 183 sb->s_fs_info = vc;
183 sb->s_flags |= MS_NOATIME; 184 sb->s_flags |= MS_NOATIME;
@@ -206,21 +207,23 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
206 printk("coda_read_super: rootinode is %ld dev %s\n", 207 printk("coda_read_super: rootinode is %ld dev %s\n",
207 root->i_ino, root->i_sb->s_id); 208 root->i_ino, root->i_sb->s_id);
208 sb->s_root = d_alloc_root(root); 209 sb->s_root = d_alloc_root(root);
209 if (!sb->s_root) 210 if (!sb->s_root) {
211 error = -EINVAL;
210 goto error; 212 goto error;
211 unlock_kernel(); 213 }
212 return 0; 214 return 0;
213 215
214 error: 216error:
215 bdi_destroy(&vc->bdi);
216 bdi_err:
217 if (root) 217 if (root)
218 iput(root); 218 iput(root);
219 if (vc)
220 vc->vc_sb = NULL;
221 219
220 lock_kernel();
221 bdi_destroy(&vc->bdi);
222 vc->vc_sb = NULL;
223 sb->s_fs_info = NULL;
224unlock_out:
222 unlock_kernel(); 225 unlock_kernel();
223 return -EINVAL; 226 return error;
224} 227}
225 228
226static void coda_put_super(struct super_block *sb) 229static void coda_put_super(struct super_block *sb)
@@ -253,8 +256,6 @@ int coda_setattr(struct dentry *de, struct iattr *iattr)
253 struct coda_vattr vattr; 256 struct coda_vattr vattr;
254 int error; 257 int error;
255 258
256 lock_kernel();
257
258 memset(&vattr, 0, sizeof(vattr)); 259 memset(&vattr, 0, sizeof(vattr));
259 260
260 inode->i_ctime = CURRENT_TIME_SEC; 261 inode->i_ctime = CURRENT_TIME_SEC;
@@ -264,13 +265,10 @@ int coda_setattr(struct dentry *de, struct iattr *iattr)
264 /* Venus is responsible for truncating the container-file!!! */ 265 /* Venus is responsible for truncating the container-file!!! */
265 error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr); 266 error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr);
266 267
267 if ( !error ) { 268 if (!error) {
268 coda_vattr_to_iattr(inode, &vattr); 269 coda_vattr_to_iattr(inode, &vattr);
269 coda_cache_clear_inode(inode); 270 coda_cache_clear_inode(inode);
270 } 271 }
271
272 unlock_kernel();
273
274 return error; 272 return error;
275} 273}
276 274
@@ -284,12 +282,8 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
284{ 282{
285 int error; 283 int error;
286 284
287 lock_kernel();
288
289 error = venus_statfs(dentry, buf); 285 error = venus_statfs(dentry, buf);
290 286
291 unlock_kernel();
292
293 if (error) { 287 if (error) {
294 /* fake something like AFS does */ 288 /* fake something like AFS does */
295 buf->f_blocks = 9000000; 289 buf->f_blocks = 9000000;
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c
index 028a9a0f588b..2fd89b5c5c7b 100644
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -23,8 +23,6 @@
23#include <linux/coda_fs_i.h> 23#include <linux/coda_fs_i.h>
24#include <linux/coda_psdev.h> 24#include <linux/coda_psdev.h>
25 25
26#include <linux/smp_lock.h>
27
28/* pioctl ops */ 26/* pioctl ops */
29static int coda_ioctl_permission(struct inode *inode, int mask); 27static int coda_ioctl_permission(struct inode *inode, int mask);
30static long coda_pioctl(struct file *filp, unsigned int cmd, 28static long coda_pioctl(struct file *filp, unsigned int cmd,
@@ -58,13 +56,9 @@ static long coda_pioctl(struct file *filp, unsigned int cmd,
58 struct inode *target_inode = NULL; 56 struct inode *target_inode = NULL;
59 struct coda_inode_info *cnp; 57 struct coda_inode_info *cnp;
60 58
61 lock_kernel();
62
63 /* get the Pioctl data arguments from user space */ 59 /* get the Pioctl data arguments from user space */
64 if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) { 60 if (copy_from_user(&data, (void __user *)user_data, sizeof(data)))
65 error = -EINVAL; 61 return -EINVAL;
66 goto out;
67 }
68 62
69 /* 63 /*
70 * Look up the pathname. Note that the pathname is in 64 * Look up the pathname. Note that the pathname is in
@@ -76,13 +70,12 @@ static long coda_pioctl(struct file *filp, unsigned int cmd,
76 error = user_lpath(data.path, &path); 70 error = user_lpath(data.path, &path);
77 71
78 if (error) 72 if (error)
79 goto out; 73 return error;
80 else 74
81 target_inode = path.dentry->d_inode; 75 target_inode = path.dentry->d_inode;
82 76
83 /* return if it is not a Coda inode */ 77 /* return if it is not a Coda inode */
84 if (target_inode->i_sb != inode->i_sb) { 78 if (target_inode->i_sb != inode->i_sb) {
85 path_put(&path);
86 error = -EINVAL; 79 error = -EINVAL;
87 goto out; 80 goto out;
88 } 81 }
@@ -91,10 +84,7 @@ static long coda_pioctl(struct file *filp, unsigned int cmd,
91 cnp = ITOC(target_inode); 84 cnp = ITOC(target_inode);
92 85
93 error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); 86 error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);
94
95 path_put(&path);
96
97out: 87out:
98 unlock_kernel(); 88 path_put(&path);
99 return error; 89 return error;
100} 90}
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index fdc2f3ef7ecd..9a9248e632c6 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -108,16 +108,9 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
108 return -EFAULT; 108 return -EFAULT;
109 109
110 if (DOWNCALL(hdr.opcode)) { 110 if (DOWNCALL(hdr.opcode)) {
111 struct super_block *sb = NULL; 111 union outputArgs *dcbuf;
112 union outputArgs *dcbuf;
113 int size = sizeof(*dcbuf); 112 int size = sizeof(*dcbuf);
114 113
115 sb = vcp->vc_sb;
116 if ( !sb ) {
117 count = nbytes;
118 goto out;
119 }
120
121 if ( nbytes < sizeof(struct coda_out_hdr) ) { 114 if ( nbytes < sizeof(struct coda_out_hdr) ) {
122 printk("coda_downcall opc %d uniq %d, not enough!\n", 115 printk("coda_downcall opc %d uniq %d, not enough!\n",
123 hdr.opcode, hdr.unique); 116 hdr.opcode, hdr.unique);
@@ -137,9 +130,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
137 } 130 }
138 131
139 /* what downcall errors does Venus handle ? */ 132 /* what downcall errors does Venus handle ? */
140 lock_kernel(); 133 error = coda_downcall(vcp, hdr.opcode, dcbuf);
141 error = coda_downcall(hdr.opcode, dcbuf, sb);
142 unlock_kernel();
143 134
144 CODA_FREE(dcbuf, nbytes); 135 CODA_FREE(dcbuf, nbytes);
145 if (error) { 136 if (error) {
diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c
index 4513b7258458..af78f007a2b0 100644
--- a/fs/coda/symlink.c
+++ b/fs/coda/symlink.c
@@ -14,7 +14,6 @@
14#include <linux/stat.h> 14#include <linux/stat.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/pagemap.h> 16#include <linux/pagemap.h>
17#include <linux/smp_lock.h>
18 17
19#include <linux/coda.h> 18#include <linux/coda.h>
20#include <linux/coda_linux.h> 19#include <linux/coda_linux.h>
@@ -29,11 +28,9 @@ static int coda_symlink_filler(struct file *file, struct page *page)
29 unsigned int len = PAGE_SIZE; 28 unsigned int len = PAGE_SIZE;
30 char *p = kmap(page); 29 char *p = kmap(page);
31 30
32 lock_kernel();
33 cii = ITOC(inode); 31 cii = ITOC(inode);
34 32
35 error = venus_readlink(inode->i_sb, &cii->c_fid, p, &len); 33 error = venus_readlink(inode->i_sb, &cii->c_fid, p, &len);
36 unlock_kernel();
37 if (error) 34 if (error)
38 goto fail; 35 goto fail;
39 SetPageUptodate(page); 36 SetPageUptodate(page);
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index b8893ab6f9e6..4c258cb5266d 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -27,6 +27,7 @@
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/string.h> 28#include <linux/string.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/smp_lock.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
32#include <linux/vfs.h> 33#include <linux/vfs.h>
@@ -667,18 +668,23 @@ static int coda_upcall(struct venus_comm *vcp,
667{ 668{
668 union outputArgs *out; 669 union outputArgs *out;
669 union inputArgs *sig_inputArgs; 670 union inputArgs *sig_inputArgs;
670 struct upc_req *req, *sig_req; 671 struct upc_req *req = NULL, *sig_req;
671 int error = 0; 672 int error;
673
674 lock_kernel();
672 675
673 if (!vcp->vc_inuse) { 676 if (!vcp->vc_inuse) {
674 printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); 677 printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
675 return -ENXIO; 678 error = -ENXIO;
679 goto exit;
676 } 680 }
677 681
678 /* Format the request message. */ 682 /* Format the request message. */
679 req = kmalloc(sizeof(struct upc_req), GFP_KERNEL); 683 req = kmalloc(sizeof(struct upc_req), GFP_KERNEL);
680 if (!req) 684 if (!req) {
681 return -ENOMEM; 685 error = -ENOMEM;
686 goto exit;
687 }
682 688
683 req->uc_data = (void *)buffer; 689 req->uc_data = (void *)buffer;
684 req->uc_flags = 0; 690 req->uc_flags = 0;
@@ -759,6 +765,7 @@ static int coda_upcall(struct venus_comm *vcp,
759 765
760exit: 766exit:
761 kfree(req); 767 kfree(req);
768 unlock_kernel();
762 return error; 769 return error;
763} 770}
764 771
@@ -796,21 +803,24 @@ exit:
796 * 803 *
797 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */ 804 * CODA_REPLACE -- replace one CodaFid with another throughout the name cache */
798 805
799int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb) 806int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
800{ 807{
801 struct inode *inode = NULL; 808 struct inode *inode = NULL;
802 struct CodaFid *fid, *newfid; 809 struct CodaFid *fid, *newfid;
810 struct super_block *sb;
803 811
804 /* Handle invalidation requests. */ 812 /* Handle invalidation requests. */
805 if ( !sb || !sb->s_root) 813 lock_kernel();
806 return 0; 814 sb = vcp->vc_sb;
815 if (!sb || !sb->s_root)
816 goto unlock_out;
807 817
808 switch (opcode) { 818 switch (opcode) {
809 case CODA_FLUSH: 819 case CODA_FLUSH:
810 coda_cache_clear_all(sb); 820 coda_cache_clear_all(sb);
811 shrink_dcache_sb(sb); 821 shrink_dcache_sb(sb);
812 if (sb->s_root->d_inode) 822 if (sb->s_root->d_inode)
813 coda_flag_inode(sb->s_root->d_inode, C_FLUSH); 823 coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
814 break; 824 break;
815 825
816 case CODA_PURGEUSER: 826 case CODA_PURGEUSER:
@@ -855,9 +865,11 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
855 break; 865 break;
856 } 866 }
857 867
868unlock_out:
869 unlock_kernel();
870
858 if (inode) 871 if (inode)
859 iput(inode); 872 iput(inode);
860
861 return 0; 873 return 0;
862} 874}
863 875
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h
index 284b520934a0..1e60c5a41a5b 100644
--- a/include/linux/coda_psdev.h
+++ b/include/linux/coda_psdev.h
@@ -63,7 +63,7 @@ int venus_symlink(struct super_block *sb, struct CodaFid *fid,
63int venus_access(struct super_block *sb, struct CodaFid *fid, int mask); 63int venus_access(struct super_block *sb, struct CodaFid *fid, int mask);
64int venus_pioctl(struct super_block *sb, struct CodaFid *fid, 64int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
65 unsigned int cmd, struct PioctlData *data); 65 unsigned int cmd, struct PioctlData *data);
66int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb); 66int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out);
67int venus_fsync(struct super_block *sb, struct CodaFid *fid); 67int venus_fsync(struct super_block *sb, struct CodaFid *fid);
68int venus_statfs(struct dentry *dentry, struct kstatfs *sfs); 68int venus_statfs(struct dentry *dentry, struct kstatfs *sfs);
69 69