aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/dir.c')
-rw-r--r--fs/coda/dir.c184
1 files changed, 65 insertions, 119 deletions
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index ccd98b0f2b0b..2b8dae4d121e 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -17,15 +17,15 @@
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> 20#include <linux/spinlock.h>
21#include <linux/namei.h>
21 22
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23 24
24#include <linux/coda.h> 25#include <linux/coda.h>
25#include <linux/coda_linux.h>
26#include <linux/coda_psdev.h> 26#include <linux/coda_psdev.h>
27#include <linux/coda_fs_i.h> 27#include "coda_linux.h"
28#include <linux/coda_cache.h> 28#include "coda_cache.h"
29 29
30#include "coda_int.h" 30#include "coda_int.h"
31 31
@@ -47,7 +47,7 @@ static int coda_readdir(struct file *file, void *buf, filldir_t filldir);
47 47
48/* dentry ops */ 48/* dentry ops */
49static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd); 49static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd);
50static int coda_dentry_delete(struct dentry *); 50static int coda_dentry_delete(const struct dentry *);
51 51
52/* support routines */ 52/* support routines */
53static int coda_venus_readdir(struct file *coda_file, void *buf, 53static int coda_venus_readdir(struct file *coda_file, void *buf,
@@ -60,7 +60,7 @@ static int coda_return_EIO(void)
60} 60}
61#define CODA_EIO_ERROR ((void *) (coda_return_EIO)) 61#define CODA_EIO_ERROR ((void *) (coda_return_EIO))
62 62
63static const struct dentry_operations coda_dentry_operations = 63const struct dentry_operations coda_dentry_operations =
64{ 64{
65 .d_revalidate = coda_dentry_revalidate, 65 .d_revalidate = coda_dentry_revalidate,
66 .d_delete = coda_dentry_delete, 66 .d_delete = coda_dentry_delete,
@@ -116,21 +116,15 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struc
116 goto exit; 116 goto exit;
117 } 117 }
118 118
119 lock_kernel();
120
121 error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length, 119 error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
122 &type, &resfid); 120 &type, &resfid);
123 if (!error) 121 if (!error)
124 error = coda_cnode_make(&inode, &resfid, dir->i_sb); 122 error = coda_cnode_make(&inode, &resfid, dir->i_sb);
125 123
126 unlock_kernel();
127
128 if (error && error != -ENOENT) 124 if (error && error != -ENOENT)
129 return ERR_PTR(error); 125 return ERR_PTR(error);
130 126
131exit: 127exit:
132 entry->d_op = &coda_dentry_operations;
133
134 if (inode && (type & CODA_NOCACHE)) 128 if (inode && (type & CODA_NOCACHE))
135 coda_flag_inode(inode, C_VATTR | C_PURGE); 129 coda_flag_inode(inode, C_VATTR | C_PURGE);
136 130
@@ -138,30 +132,29 @@ exit:
138} 132}
139 133
140 134
141int coda_permission(struct inode *inode, int mask) 135int coda_permission(struct inode *inode, int mask, unsigned int flags)
142{ 136{
143 int error = 0; 137 int error;
138
139 if (flags & IPERM_FLAG_RCU)
140 return -ECHILD;
144 141
145 mask &= MAY_READ | MAY_WRITE | MAY_EXEC; 142 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
146 143
147 if (!mask) 144 if (!mask)
148 return 0; 145 return 0;
149 146
150 if ((mask & MAY_EXEC) && !execute_ok(inode)) 147 if ((mask & MAY_EXEC) && !execute_ok(inode))
151 return -EACCES; 148 return -EACCES;
152 149
153 lock_kernel();
154
155 if (coda_cache_check(inode, mask)) 150 if (coda_cache_check(inode, mask))
156 goto out; 151 return 0;
157 152
158 error = venus_access(inode->i_sb, coda_i2f(inode), mask); 153 error = venus_access(inode->i_sb, coda_i2f(inode), mask);
159 154
160 if (!error) 155 if (!error)
161 coda_cache_enter(inode, mask); 156 coda_cache_enter(inode, mask);
162 157
163 out:
164 unlock_kernel();
165 return error; 158 return error;
166} 159}
167 160
@@ -200,41 +193,34 @@ static inline void coda_dir_drop_nlink(struct inode *dir)
200/* creation routines: create, mknod, mkdir, link, symlink */ 193/* creation routines: create, mknod, mkdir, link, symlink */
201static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd) 194static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd)
202{ 195{
203 int error=0; 196 int error;
204 const char *name=de->d_name.name; 197 const char *name=de->d_name.name;
205 int length=de->d_name.len; 198 int length=de->d_name.len;
206 struct inode *inode; 199 struct inode *inode;
207 struct CodaFid newfid; 200 struct CodaFid newfid;
208 struct coda_vattr attrs; 201 struct coda_vattr attrs;
209 202
210 lock_kernel(); 203 if (coda_isroot(dir) && coda_iscontrol(name, length))
211
212 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
213 unlock_kernel();
214 return -EPERM; 204 return -EPERM;
215 }
216 205
217 error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 206 error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
218 0, mode, &newfid, &attrs); 207 0, mode, &newfid, &attrs);
219 208 if (error)
220 if ( error ) { 209 goto err_out;
221 unlock_kernel();
222 d_drop(de);
223 return error;
224 }
225 210
226 inode = coda_iget(dir->i_sb, &newfid, &attrs); 211 inode = coda_iget(dir->i_sb, &newfid, &attrs);
227 if ( IS_ERR(inode) ) { 212 if (IS_ERR(inode)) {
228 unlock_kernel(); 213 error = PTR_ERR(inode);
229 d_drop(de); 214 goto err_out;
230 return PTR_ERR(inode);
231 } 215 }
232 216
233 /* invalidate the directory cnode's attributes */ 217 /* invalidate the directory cnode's attributes */
234 coda_dir_update_mtime(dir); 218 coda_dir_update_mtime(dir);
235 unlock_kernel();
236 d_instantiate(de, inode); 219 d_instantiate(de, inode);
237 return 0; 220 return 0;
221err_out:
222 d_drop(de);
223 return error;
238} 224}
239 225
240static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) 226static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
@@ -246,36 +232,29 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
246 int error; 232 int error;
247 struct CodaFid newfid; 233 struct CodaFid newfid;
248 234
249 lock_kernel(); 235 if (coda_isroot(dir) && coda_iscontrol(name, len))
250
251 if (coda_isroot(dir) && coda_iscontrol(name, len)) {
252 unlock_kernel();
253 return -EPERM; 236 return -EPERM;
254 }
255 237
256 attrs.va_mode = mode; 238 attrs.va_mode = mode;
257 error = venus_mkdir(dir->i_sb, coda_i2f(dir), 239 error = venus_mkdir(dir->i_sb, coda_i2f(dir),
258 name, len, &newfid, &attrs); 240 name, len, &newfid, &attrs);
259 241 if (error)
260 if ( error ) { 242 goto err_out;
261 unlock_kernel();
262 d_drop(de);
263 return error;
264 }
265 243
266 inode = coda_iget(dir->i_sb, &newfid, &attrs); 244 inode = coda_iget(dir->i_sb, &newfid, &attrs);
267 if ( IS_ERR(inode) ) { 245 if (IS_ERR(inode)) {
268 unlock_kernel(); 246 error = PTR_ERR(inode);
269 d_drop(de); 247 goto err_out;
270 return PTR_ERR(inode);
271 } 248 }
272 249
273 /* invalidate the directory cnode's attributes */ 250 /* invalidate the directory cnode's attributes */
274 coda_dir_inc_nlink(dir); 251 coda_dir_inc_nlink(dir);
275 coda_dir_update_mtime(dir); 252 coda_dir_update_mtime(dir);
276 unlock_kernel();
277 d_instantiate(de, inode); 253 d_instantiate(de, inode);
278 return 0; 254 return 0;
255err_out:
256 d_drop(de);
257 return error;
279} 258}
280 259
281/* try to make de an entry in dir_inodde linked to source_de */ 260/* try to make de an entry in dir_inodde linked to source_de */
@@ -287,52 +266,38 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
287 int len = de->d_name.len; 266 int len = de->d_name.len;
288 int error; 267 int error;
289 268
290 lock_kernel(); 269 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
291
292 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
293 unlock_kernel();
294 return -EPERM; 270 return -EPERM;
295 }
296 271
297 error = venus_link(dir_inode->i_sb, coda_i2f(inode), 272 error = venus_link(dir_inode->i_sb, coda_i2f(inode),
298 coda_i2f(dir_inode), (const char *)name, len); 273 coda_i2f(dir_inode), (const char *)name, len);
299
300 if (error) { 274 if (error) {
301 d_drop(de); 275 d_drop(de);
302 goto out; 276 return error;
303 } 277 }
304 278
305 coda_dir_update_mtime(dir_inode); 279 coda_dir_update_mtime(dir_inode);
306 atomic_inc(&inode->i_count); 280 ihold(inode);
307 d_instantiate(de, inode); 281 d_instantiate(de, inode);
308 inc_nlink(inode); 282 inc_nlink(inode);
309 283 return 0;
310out:
311 unlock_kernel();
312 return(error);
313} 284}
314 285
315 286
316static int coda_symlink(struct inode *dir_inode, struct dentry *de, 287static int coda_symlink(struct inode *dir_inode, struct dentry *de,
317 const char *symname) 288 const char *symname)
318{ 289{
319 const char *name = de->d_name.name; 290 const char *name = de->d_name.name;
320 int len = de->d_name.len; 291 int len = de->d_name.len;
321 int symlen; 292 int symlen;
322 int error = 0; 293 int error;
323
324 lock_kernel();
325 294
326 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) { 295 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
327 unlock_kernel();
328 return -EPERM; 296 return -EPERM;
329 }
330 297
331 symlen = strlen(symname); 298 symlen = strlen(symname);
332 if ( symlen > CODA_MAXPATHLEN ) { 299 if (symlen > CODA_MAXPATHLEN)
333 unlock_kernel();
334 return -ENAMETOOLONG; 300 return -ENAMETOOLONG;
335 }
336 301
337 /* 302 /*
338 * This entry is now negative. Since we do not create 303 * This entry is now negative. Since we do not create
@@ -343,10 +308,9 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
343 symname, symlen); 308 symname, symlen);
344 309
345 /* mtime is no good anymore */ 310 /* mtime is no good anymore */
346 if ( !error ) 311 if (!error)
347 coda_dir_update_mtime(dir_inode); 312 coda_dir_update_mtime(dir_inode);
348 313
349 unlock_kernel();
350 return error; 314 return error;
351} 315}
352 316
@@ -357,17 +321,12 @@ static int coda_unlink(struct inode *dir, struct dentry *de)
357 const char *name = de->d_name.name; 321 const char *name = de->d_name.name;
358 int len = de->d_name.len; 322 int len = de->d_name.len;
359 323
360 lock_kernel();
361
362 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len); 324 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
363 if ( error ) { 325 if (error)
364 unlock_kernel();
365 return error; 326 return error;
366 }
367 327
368 coda_dir_update_mtime(dir); 328 coda_dir_update_mtime(dir);
369 drop_nlink(de->d_inode); 329 drop_nlink(de->d_inode);
370 unlock_kernel();
371 return 0; 330 return 0;
372} 331}
373 332
@@ -377,8 +336,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
377 int len = de->d_name.len; 336 int len = de->d_name.len;
378 int error; 337 int error;
379 338
380 lock_kernel();
381
382 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); 339 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
383 if (!error) { 340 if (!error) {
384 /* VFS may delete the child */ 341 /* VFS may delete the child */
@@ -389,7 +346,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
389 coda_dir_drop_nlink(dir); 346 coda_dir_drop_nlink(dir);
390 coda_dir_update_mtime(dir); 347 coda_dir_update_mtime(dir);
391 } 348 }
392 unlock_kernel();
393 return error; 349 return error;
394} 350}
395 351
@@ -403,15 +359,12 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
403 int new_length = new_dentry->d_name.len; 359 int new_length = new_dentry->d_name.len;
404 int error; 360 int error;
405 361
406 lock_kernel();
407
408 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), 362 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
409 coda_i2f(new_dir), old_length, new_length, 363 coda_i2f(new_dir), old_length, new_length,
410 (const char *) old_name, (const char *)new_name); 364 (const char *) old_name, (const char *)new_name);
411 365 if (!error) {
412 if ( !error ) { 366 if (new_dentry->d_inode) {
413 if ( new_dentry->d_inode ) { 367 if (S_ISDIR(new_dentry->d_inode->i_mode)) {
414 if ( S_ISDIR(new_dentry->d_inode->i_mode) ) {
415 coda_dir_drop_nlink(old_dir); 368 coda_dir_drop_nlink(old_dir);
416 coda_dir_inc_nlink(new_dir); 369 coda_dir_inc_nlink(new_dir);
417 } 370 }
@@ -423,8 +376,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
423 coda_flag_inode(new_dir, C_VATTR); 376 coda_flag_inode(new_dir, C_VATTR);
424 } 377 }
425 } 378 }
426 unlock_kernel();
427
428 return error; 379 return error;
429} 380}
430 381
@@ -591,13 +542,14 @@ out:
591/* called when a cache lookup succeeds */ 542/* called when a cache lookup succeeds */
592static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd) 543static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
593{ 544{
594 struct inode *inode = de->d_inode; 545 struct inode *inode;
595 struct coda_inode_info *cii; 546 struct coda_inode_info *cii;
596 547
597 if (!inode) 548 if (nd->flags & LOOKUP_RCU)
598 return 1; 549 return -ECHILD;
599 lock_kernel(); 550
600 if (coda_isroot(inode)) 551 inode = de->d_inode;
552 if (!inode || coda_isroot(inode))
601 goto out; 553 goto out;
602 if (is_bad_inode(inode)) 554 if (is_bad_inode(inode))
603 goto bad; 555 goto bad;
@@ -612,18 +564,17 @@ static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
612 if (cii->c_flags & C_FLUSH) 564 if (cii->c_flags & C_FLUSH)
613 coda_flag_inode_children(inode, C_FLUSH); 565 coda_flag_inode_children(inode, C_FLUSH);
614 566
615 if (atomic_read(&de->d_count) > 1) 567 if (de->d_count > 1)
616 /* pretend it's valid, but don't change the flags */ 568 /* pretend it's valid, but don't change the flags */
617 goto out; 569 goto out;
618 570
619 /* clear the flags. */ 571 /* clear the flags. */
572 spin_lock(&cii->c_lock);
620 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 573 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
621 574 spin_unlock(&cii->c_lock);
622bad: 575bad:
623 unlock_kernel();
624 return 0; 576 return 0;
625out: 577out:
626 unlock_kernel();
627 return 1; 578 return 1;
628} 579}
629 580
@@ -631,7 +582,7 @@ out:
631 * This is the callback from dput() when d_count is going to 0. 582 * This is the callback from dput() when d_count is going to 0.
632 * We use this to unhash dentries with bad inodes. 583 * We use this to unhash dentries with bad inodes.
633 */ 584 */
634static int coda_dentry_delete(struct dentry * dentry) 585static int coda_dentry_delete(const struct dentry * dentry)
635{ 586{
636 int flags; 587 int flags;
637 588
@@ -656,20 +607,19 @@ static int coda_dentry_delete(struct dentry * dentry)
656int coda_revalidate_inode(struct dentry *dentry) 607int coda_revalidate_inode(struct dentry *dentry)
657{ 608{
658 struct coda_vattr attr; 609 struct coda_vattr attr;
659 int error = 0; 610 int error;
660 int old_mode; 611 int old_mode;
661 ino_t old_ino; 612 ino_t old_ino;
662 struct inode *inode = dentry->d_inode; 613 struct inode *inode = dentry->d_inode;
663 struct coda_inode_info *cii = ITOC(inode); 614 struct coda_inode_info *cii = ITOC(inode);
664 615
665 lock_kernel(); 616 if (!cii->c_flags)
666 if ( !cii->c_flags ) 617 return 0;
667 goto ok;
668 618
669 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) { 619 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
670 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr); 620 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
671 if ( error ) 621 if (error)
672 goto return_bad; 622 return -EIO;
673 623
674 /* this inode may be lost if: 624 /* this inode may be lost if:
675 - it's ino changed 625 - it's ino changed
@@ -688,17 +638,13 @@ int coda_revalidate_inode(struct dentry *dentry)
688 /* the following can happen when a local fid is replaced 638 /* the following can happen when a local fid is replaced
689 with a global one, here we lose and declare the inode bad */ 639 with a global one, here we lose and declare the inode bad */
690 if (inode->i_ino != old_ino) 640 if (inode->i_ino != old_ino)
691 goto return_bad; 641 return -EIO;
692 642
693 coda_flag_inode_children(inode, C_FLUSH); 643 coda_flag_inode_children(inode, C_FLUSH);
644
645 spin_lock(&cii->c_lock);
694 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 646 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
647 spin_unlock(&cii->c_lock);
695 } 648 }
696
697ok:
698 unlock_kernel();
699 return 0; 649 return 0;
700
701return_bad:
702 unlock_kernel();
703 return -EIO;
704} 650}