Import 2.4.0-test2pre6
[davej-history.git] / fs / coda / dir.c
blob2031b4f6e0399fdd268060a4a886a068d404c7c0
2 /*
3 * Directory operations for Coda filesystem
4 * Original version: (C) 1996 P. Braam and M. Callahan
5 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
6 *
7 * Carnegie Mellon encourages users to contribute improvements to
8 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
9 */
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/fs.h>
15 #include <linux/stat.h>
16 #include <linux/errno.h>
17 #include <linux/locks.h>
18 #include <asm/segment.h>
19 #include <asm/uaccess.h>
20 #include <linux/string.h>
22 #include <linux/coda.h>
23 #include <linux/coda_linux.h>
24 #include <linux/coda_psdev.h>
25 #include <linux/coda_fs_i.h>
26 #include <linux/coda_cache.h>
27 #include <linux/coda_proc.h>
29 /* dir inode-ops */
30 static int coda_create(struct inode *dir, struct dentry *new, int mode);
31 static int coda_mknod(struct inode *dir, struct dentry *new, int mode, int rdev);
32 static struct dentry *coda_lookup(struct inode *dir, struct dentry *target);
33 static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
34 struct dentry *entry);
35 static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
36 static int coda_symlink(struct inode *dir_inode, struct dentry *entry,
37 const char *symname);
38 static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode);
39 static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
40 static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
41 struct inode *new_inode, struct dentry *new_dentry);
43 /* dir file-ops */
44 static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
46 /* dentry ops */
47 static int coda_dentry_revalidate(struct dentry *de, int);
48 static int coda_dentry_delete(struct dentry *);
50 /* support routines */
51 static int coda_venus_readdir(struct file *filp, void *dirent,
52 filldir_t filldir);
53 int coda_fsync(struct file *, struct dentry *dentry);
55 int coda_crossvol_rename = 0;
56 int coda_hasmknod = 0;
58 struct dentry_operations coda_dentry_operations =
60 d_revalidate: coda_dentry_revalidate,
61 d_delete: coda_dentry_delete,
64 struct inode_operations coda_dir_inode_operations =
66 create: coda_create,
67 lookup: coda_lookup,
68 link: coda_link,
69 unlink: coda_unlink,
70 symlink: coda_symlink,
71 mkdir: coda_mkdir,
72 rmdir: coda_rmdir,
73 mknod: coda_mknod,
74 rename: coda_rename,
75 permission: coda_permission,
76 revalidate: coda_revalidate_inode,
77 setattr: coda_notify_change,
80 struct file_operations coda_dir_operations = {
81 read: generic_read_dir,
82 readdir: coda_readdir,
83 open: coda_open,
84 release: coda_release,
85 fsync: coda_fsync,
89 /* inode operations for directories */
90 /* acces routines: lookup, readlink, permission */
91 static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
93 struct coda_inode_info *dircnp;
94 struct inode *res_inode = NULL;
95 struct ViceFid resfid;
96 int dropme = 0; /* to indicate entry should not be cached */
97 int type;
98 int error = 0;
99 const char *name = entry->d_name.name;
100 size_t length = entry->d_name.len;
102 ENTRY;
104 dircnp = ITOC(dir);
106 if ( length > CODA_MAXNAMLEN ) {
107 printk("name too long: lookup, %s (%*s)\n",
108 coda_f2s(&dircnp->c_fid), (int)length, name);
109 return ERR_PTR(-ENAMETOOLONG);
112 CDEBUG(D_INODE, "name %s, len %ld in ino %ld, fid %s\n",
113 name, (long)length, dir->i_ino, coda_f2s(&dircnp->c_fid));
115 /* control object, create inode on the fly */
116 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
117 error = coda_cnode_makectl(&res_inode, dir->i_sb);
118 CDEBUG(D_SPECIAL,
119 "Lookup on CTL object; dir ino %ld, count %d\n",
120 dir->i_ino, atomic_read(&dir->i_count));
121 goto exit;
124 error = venus_lookup(dir->i_sb, &(dircnp->c_fid),
125 (const char *)name, length, &type, &resfid);
127 res_inode = NULL;
128 if (!error) {
129 if (type & CODA_NOCACHE) {
130 type &= (~CODA_NOCACHE);
131 CDEBUG(D_INODE, "dropme set for %s\n",
132 coda_f2s(&resfid));
133 dropme = 1;
135 error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
136 if (error)
137 return ERR_PTR(error);
138 } else if (error != -ENOENT) {
139 CDEBUG(D_INODE, "error for %s(%*s)%d\n",
140 coda_f2s(&dircnp->c_fid), (int)length, name, error);
141 return ERR_PTR(error);
143 CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n",
144 name, coda_f2s(&resfid), type, error, dropme);
146 exit:
147 entry->d_time = 0;
148 entry->d_op = &coda_dentry_operations;
149 d_add(entry, res_inode);
150 if ( dropme ) {
151 d_drop(entry);
152 ITOC(res_inode)->c_flags |= C_VATTR;
154 EXIT;
155 return NULL;
159 int coda_permission(struct inode *inode, int mask)
161 struct coda_inode_info *cp = ITOC(inode);
162 int error;
164 ENTRY;
165 coda_vfs_stat.permission++;
166 coda_permission_stat.count++;
168 if ( mask == 0 ) {
169 return 0;
172 if ( coda_access_cache == 1 ) {
173 if ( coda_cache_check(inode, mask) ) {
174 coda_permission_stat.hit_count++;
175 return 0;
179 cp = ITOC(inode);
181 CDEBUG(D_INODE, "mask is %o\n", mask);
182 error = venus_access(inode->i_sb, &(cp->c_fid), mask);
184 CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %d\n",
185 coda_f2s(&(cp->c_fid)), inode->i_ino, mask, error);
187 if ( error == 0 ) {
188 coda_cache_enter(inode, mask);
191 return error;
195 /* creation routines: create, mknod, mkdir, link, symlink */
197 static int coda_create(struct inode *dir, struct dentry *de, int mode)
199 int error=0;
200 struct coda_inode_info *dircnp;
201 const char *name=de->d_name.name;
202 int length=de->d_name.len;
203 struct inode *result = NULL;
204 struct ViceFid newfid;
205 struct coda_vattr attrs;
207 ENTRY;
208 coda_vfs_stat.create++;
210 CDEBUG(D_INODE, "name: %s, length %d, mode %o\n",name, length, mode);
212 if (coda_isroot(dir) && coda_iscontrol(name, length))
213 return -EPERM;
215 dircnp = ITOC(dir);
217 error = venus_create(dir->i_sb, &(dircnp->c_fid), name, length,
218 0, mode, 0, &newfid, &attrs);
220 if ( error ) {
221 CDEBUG(D_INODE, "create: %s, result %d\n",
222 coda_f2s(&newfid), error);
223 d_drop(de);
224 return error;
227 error = coda_cnode_make(&result, &newfid, dir->i_sb);
228 if ( error ) {
229 d_drop(de);
230 result = NULL;
231 return error;
234 /* invalidate the directory cnode's attributes */
235 dircnp->c_flags |= C_VATTR;
236 d_instantiate(de, result);
237 return 0;
240 static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
242 int error=0;
243 struct coda_inode_info *dircnp;
244 const char *name=de->d_name.name;
245 int length=de->d_name.len;
246 struct inode *result = NULL;
247 struct ViceFid newfid;
248 struct coda_vattr attrs;
250 if ( coda_hasmknod == 0 )
251 return -EIO;
253 coda_vfs_stat.create++;
255 CDEBUG(D_INODE, "name: %s, length %d, mode %o, rdev %x\n",
256 name, length, mode, rdev);
258 if (coda_isroot(dir) && coda_iscontrol(name, length))
259 return -EPERM;
261 dircnp = ITOC(dir);
263 error = venus_create(dir->i_sb, &(dircnp->c_fid), name, length,
264 0, mode, rdev, &newfid, &attrs);
266 if ( error ) {
267 CDEBUG(D_INODE, "mknod: %s, result %d\n",
268 coda_f2s(&newfid), error);
269 d_drop(de);
270 return error;
273 error = coda_cnode_make(&result, &newfid, dir->i_sb);
274 if ( error ) {
275 d_drop(de);
276 result = NULL;
277 return error;
280 /* invalidate the directory cnode's attributes */
281 dircnp->c_flags |= C_VATTR;
282 d_instantiate(de, result);
283 return 0;
286 static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
288 struct coda_inode_info *dircnp;
289 struct inode *inode;
290 struct coda_vattr attr;
291 const char *name = de->d_name.name;
292 int len = de->d_name.len;
293 int error;
294 struct ViceFid newfid;
296 ENTRY;
297 coda_vfs_stat.mkdir++;
299 if (coda_isroot(dir) && coda_iscontrol(name, len))
300 return -EPERM;
302 dircnp = ITOC(dir);
304 CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n",
305 name, len, coda_f2s(&(dircnp->c_fid)), mode);
307 attr.va_mode = mode;
308 error = venus_mkdir(dir->i_sb, &(dircnp->c_fid),
309 name, len, &newfid, &attr);
311 if ( error ) {
312 CDEBUG(D_INODE, "mkdir error: %s result %d\n",
313 coda_f2s(&newfid), error);
314 d_drop(de);
315 return error;
318 CDEBUG(D_INODE, "mkdir: new dir has fid %s.\n",
319 coda_f2s(&newfid));
321 error = coda_cnode_make(&inode, &newfid, dir->i_sb);
322 if ( error ) {
323 d_drop(de);
324 return error;
327 /* invalidate the directory cnode's attributes */
328 dircnp->c_flags |= C_VATTR;
329 dir->i_nlink++;
330 d_instantiate(de, inode);
331 return 0;
334 /* try to make de an entry in dir_inodde linked to source_de */
335 static int coda_link(struct dentry *source_de, struct inode *dir_inode,
336 struct dentry *de)
338 struct inode *inode = source_de->d_inode;
339 const char * name = de->d_name.name;
340 int len = de->d_name.len;
341 struct coda_inode_info *dir_cnp, *cnp;
342 int error;
344 ENTRY;
345 coda_vfs_stat.link++;
347 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
348 return -EPERM;
350 dir_cnp = ITOC(dir_inode);
351 cnp = ITOC(inode);
353 CDEBUG(D_INODE, "old: fid: %s\n", coda_f2s(&(cnp->c_fid)));
354 CDEBUG(D_INODE, "directory: %s\n", coda_f2s(&(dir_cnp->c_fid)));
356 error = venus_link(dir_inode->i_sb,&(cnp->c_fid), &(dir_cnp->c_fid),
357 (const char *)name, len);
359 if ( ! error ) {
360 dir_cnp->c_flags |= C_VATTR;
361 atomic_inc(&inode->i_count);
362 d_instantiate(de, inode);
363 inode->i_nlink++;
364 } else {
365 d_drop(de);
366 return error;
369 CDEBUG(D_INODE, "link result %d\n",error);
370 EXIT;
371 return(error);
375 static int coda_symlink(struct inode *dir_inode, struct dentry *de,
376 const char *symname)
378 const char *name = de->d_name.name;
379 int len = de->d_name.len;
380 struct coda_inode_info *dir_cnp = ITOC(dir_inode);
381 int symlen;
382 int error=0;
384 ENTRY;
385 coda_vfs_stat.symlink++;
387 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
388 return -EPERM;
390 symlen = strlen(symname);
391 if ( symlen > CODA_MAXPATHLEN )
392 return -ENAMETOOLONG;
394 CDEBUG(D_INODE, "symname: %s, length: %d\n", symname, symlen);
397 * This entry is now negative. Since we do not create
398 * an inode for the entry we have to drop it.
400 d_drop(de);
401 error = venus_symlink(dir_inode->i_sb, &(dir_cnp->c_fid), name, len,
402 symname, symlen);
404 /* mtime is no good anymore */
405 if ( !error ) {
406 dir_cnp->c_flags |= C_VATTR;
409 CDEBUG(D_INODE, "in symlink result %d\n",error);
410 EXIT;
411 return error;
414 /* destruction routines: unlink, rmdir */
415 int coda_unlink(struct inode *dir, struct dentry *de)
417 struct coda_inode_info *dircnp = ITOC(dir);
418 int error;
419 const char *name = de->d_name.name;
420 int len = de->d_name.len;
422 ENTRY;
423 coda_vfs_stat.unlink++;
425 CDEBUG(D_INODE, " %s in %s, dirino %ld\n", name ,
426 coda_f2s(&(dircnp->c_fid)), dir->i_ino);
428 error = venus_remove(dir->i_sb, &(dircnp->c_fid), name, len);
429 if ( error ) {
430 CDEBUG(D_INODE, "upc returned error %d\n", error);
431 return error;
434 /* cache management: mtime has changed, ask Venus */
435 dircnp->c_flags |= C_VATTR;
436 de->d_inode->i_nlink--;
438 return 0;
441 int coda_rmdir(struct inode *dir, struct dentry *de)
443 struct coda_inode_info *dircnp;
444 const char *name = de->d_name.name;
445 int len = de->d_name.len;
446 int error;
448 ENTRY;
449 coda_vfs_stat.rmdir++;
451 dircnp = ITOC(dir);
453 if (!d_unhashed(de))
454 return -EBUSY;
455 error = venus_rmdir(dir->i_sb, &(dircnp->c_fid), name, len);
457 if ( error ) {
458 CDEBUG(D_INODE, "upc returned error %d\n", error);
459 return error;
462 if (de->d_inode->i_nlink)
463 de->d_inode->i_nlink --;
465 return 0;
468 /* rename */
469 static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
470 struct inode *new_dir, struct dentry *new_dentry)
472 const char *old_name = old_dentry->d_name.name;
473 const char *new_name = new_dentry->d_name.name;
474 int old_length = old_dentry->d_name.len;
475 int new_length = new_dentry->d_name.len;
476 struct inode *new_inode = new_dentry->d_inode;
477 struct coda_inode_info *new_cnp, *old_cnp;
478 int error;
480 ENTRY;
481 coda_vfs_stat.rename++;
483 old_cnp = ITOC(old_dir);
484 new_cnp = ITOC(new_dir);
486 CDEBUG(D_INODE, "old: %s, (%d length, %ld strlen), new: %s"
487 "(%d length, %ld strlen).old:d_count: %d, new:d_count: %d\n",
488 old_name, old_length, (long)strlen(old_name), new_name, new_length,
489 (long)strlen(new_name),old_dentry->d_count, new_dentry->d_count);
491 /* the C library will do unlink/create etc */
492 if ( coda_crossvol_rename == 0 &&
493 old_cnp->c_fid.Volume != new_cnp->c_fid.Volume )
494 return -EXDEV;
496 error = venus_rename(old_dir->i_sb, &(old_cnp->c_fid),
497 &(new_cnp->c_fid), old_length, new_length,
498 (const char *) old_name, (const char *)new_name);
500 if ( error ) {
501 CDEBUG(D_INODE, "returned error %d\n", error);
502 return error;
505 coda_flag_inode(new_inode, C_VATTR);
506 coda_flag_inode(old_dir, C_VATTR);
507 coda_flag_inode(new_dir, C_VATTR);
509 CDEBUG(D_INODE, "result %d\n", error);
511 EXIT;
512 return 0;
516 /* file operations for directories */
517 int coda_readdir(struct file *file, void *dirent, filldir_t filldir)
519 int result = 0;
520 struct coda_inode_info *cnp;
521 struct file open_file;
522 struct dentry open_dentry;
523 struct inode *inode=file->f_dentry->d_inode;
525 ENTRY;
526 coda_vfs_stat.readdir++;
528 cnp = ITOC(inode);
529 if ( !cnp->c_ovp ) {
530 CDEBUG(D_FILE, "open inode pointer = NULL.\n");
531 return -EIO;
534 coda_prepare_openfile(inode, file, cnp->c_ovp, &open_file,
535 &open_dentry);
536 if ( S_ISREG(cnp->c_ovp->i_mode) ) {
537 /* Venus: we must read Venus dirents from the file */
538 result = coda_venus_readdir(&open_file, dirent, filldir);
539 } else {
540 /* potemkin case: we are handed a directory inode */
541 result = vfs_readdir(&open_file, filldir, dirent);
543 coda_restore_codafile(inode, file, cnp->c_ovp, &open_file);
544 EXIT;
545 return result;
548 /* ask venus to cache the file and return the inode of the container file,
549 put this inode pointer in the cnode for future read/writes */
550 int coda_open(struct inode *i, struct file *f)
552 ino_t ino;
553 dev_t dev;
554 struct coda_inode_info *cnp;
555 int error = 0;
556 struct inode *cont_inode = NULL;
557 unsigned short flags = f->f_flags & (~O_EXCL);
558 unsigned short coda_flags = coda_flags_to_cflags(flags);
559 struct coda_cred *cred;
561 ENTRY;
562 coda_vfs_stat.open++;
564 CDEBUG(D_SPECIAL, "OPEN inode number: %ld, count %d, flags %o.\n",
565 f->f_dentry->d_inode->i_ino, f->f_dentry->d_count, flags);
567 cnp = ITOC(i);
570 error = venus_open(i->i_sb, &(cnp->c_fid), coda_flags, &ino, &dev);
571 if (error) {
572 CDEBUG(D_FILE, "venus: dev %d, inode %ld, out->result %d\n",
573 dev, (long)ino, error);
574 return error;
577 /* coda_upcall returns ino number of cached object, get inode */
578 CDEBUG(D_FILE, "cache file dev %d, ino %ld\n", dev, (long)ino);
579 error = coda_inode_grab(dev, ino, &cont_inode);
581 if ( error || !cont_inode ){
582 printk("coda_open: coda_inode_grab error %d.", error);
583 if (cont_inode)
584 iput(cont_inode);
585 return error;
588 CODA_ALLOC(cred, struct coda_cred *, sizeof(*cred));
589 coda_load_creds(cred);
590 f->private_data = cred;
592 if ( cnp->c_ovp )
593 iput(cnp->c_ovp);
595 cnp->c_ovp = cont_inode;
596 i->i_mapping = cont_inode->i_mapping;
597 cnp->c_ocount++;
599 CDEBUG(D_FILE, "result %d, coda i->i_count is %d for ino %ld\n",
600 error, atomic_read(&i->i_count), i->i_ino);
601 CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %p\n",
602 cnp->c_ovp->i_ino, atomic_read(&cnp->c_ovp->i_count),
603 (cnp->c_ovp->i_op));
604 EXIT;
605 return 0;
608 int coda_release(struct inode *i, struct file *f)
610 struct coda_inode_info *cnp;
611 int error = 0;
612 unsigned short flags = (f->f_flags) & (~O_EXCL);
613 unsigned short cflags = coda_flags_to_cflags(flags);
614 struct coda_cred *cred;
616 ENTRY;
617 coda_vfs_stat.release++;
619 cred = (struct coda_cred *)f->private_data;
621 cnp =ITOC(i);
622 CHECK_CNODE(cnp);
623 CDEBUG(D_FILE,
624 "RELEASE coda (ino %ld, ct %d) cache (ino %ld, ct %d)\n",
625 i->i_ino, atomic_read(&i->i_count),
626 (cnp->c_ovp ? cnp->c_ovp->i_ino : 0),
627 (cnp->c_ovp ? atomic_read(&cnp->c_ovp->i_count) : -99));
630 /* even when c_ocount=0 we cannot put c_ovp to
631 * NULL since the file may be mmapped.
632 * See code in inode.c (coda_put_inode) for
633 * further handling of close.
636 --cnp->c_ocount;
638 if ( flags & (O_WRONLY | O_RDWR) )
639 --cnp->c_owrite;
641 /* Venus closing a container file? don't bother making the upcall. */
642 if ( current->pid != coda_upc_comm.vc_pid ) {
643 error = venus_release(i->i_sb, &(cnp->c_fid), cflags, cred);
646 f->private_data = NULL;
647 if (cred)
648 CODA_FREE(cred, sizeof(*cred));
650 CDEBUG(D_FILE, "coda_release: result: %d\n", error);
651 return error;
654 /* support routines */
656 * this structure is manipulated by filldir in vfs layer.
657 * the count holds the remaining amount of space in the getdents buffer,
658 * beyond the current_dir pointer.
662 /* should be big enough to hold any single directory entry */
663 #define DIR_BUFSIZE 2048
665 static int coda_venus_readdir(struct file *filp, void *getdent,
666 filldir_t filldir)
668 int bufsize;
669 int offset = filp->f_pos; /* offset in the directory file */
670 int count = 0;
671 int pos = 0; /* offset in the block we read */
672 int result = 0; /* either an error or # of entries returned */
673 int errfill;
674 char *buff = NULL;
675 struct venus_dirent *vdirent;
676 int string_offset = (int) (&((struct venus_dirent *)(0))->d_name);
677 int i;
679 ENTRY;
681 CODA_ALLOC(buff, char *, DIR_BUFSIZE);
682 if ( !buff ) {
683 printk("coda_venus_readdir: out of memory.\n");
684 return -ENOMEM;
687 /* we use this routine to read the file into our buffer */
688 bufsize = kernel_read(filp, filp->f_pos, buff, DIR_BUFSIZE);
689 if ( bufsize < 0) {
690 printk("coda_venus_readdir: cannot read directory %d.\n",
691 bufsize);
692 result = bufsize;
693 goto exit;
695 if ( bufsize == 0) {
696 result = 0;
697 goto exit;
700 /* Parse and write into user space. Filldir tells us when done! */
701 CDEBUG(D_FILE, "buffsize: %d offset %d, count %d.\n",
702 bufsize, offset, count);
704 i = 0;
705 result = 0;
706 while ( pos + string_offset < bufsize && i < 1024) {
707 vdirent = (struct venus_dirent *) (buff + pos);
709 /* test if the name is fully in the buffer */
710 if ( pos + string_offset + (int) vdirent->d_namlen >= bufsize ){
711 if ( result == 0 )
712 printk("CODA: Invalid directory cfino: %ld\n",
713 filp->f_dentry->d_inode->i_ino);
714 break;
716 /* now we are certain that we can read the entry from buff */
718 /* if we don't have a null entry, copy it */
719 if ( vdirent->d_fileno && vdirent->d_reclen ) {
720 int namlen = vdirent->d_namlen;
721 off_t offs = filp->f_pos;
722 ino_t ino = vdirent->d_fileno;
723 char *name = vdirent->d_name;
725 errfill = filldir(getdent, name, namlen,
726 offs, ino);
727 CDEBUG(D_FILE, "entry %d: ino %ld, namlen %d, reclen %d, type %d, pos %d, string_offs %d, name %*s, offset %d, result: %d, errfill: %d.\n", i,vdirent->d_fileno, vdirent->d_namlen, vdirent->d_reclen, vdirent->d_type, pos, string_offset, vdirent->d_namlen, vdirent->d_name, (u_int) offs, result, errfill);
728 /* errfill means no space for filling in this round */
729 if ( errfill < 0 ) {
730 result = 0;
731 break;
733 /* adjust count */
734 result++;
736 /* next one */
737 filp->f_pos += vdirent->d_reclen;
738 if ( filp->f_pos > filp->f_dentry->d_inode->i_size )
739 break;
740 if ( !vdirent->d_reclen ) {
741 printk("CODA: Invalid directory, cfino: %ld\n",
742 filp->f_dentry->d_inode->i_ino);
743 result = -EINVAL;
744 break;
746 pos += (unsigned int) vdirent->d_reclen;
747 i++;
750 if ( i >= 1024 ) {
751 printk("Repeating too much in readdir %ld\n",
752 filp->f_dentry->d_inode->i_ino);
753 result = -EINVAL;
756 exit:
757 CODA_FREE(buff, DIR_BUFSIZE);
758 return result;
761 /* called when a cache lookup succeeds */
762 static int coda_dentry_revalidate(struct dentry *de, int flags)
764 int valid = 1;
765 struct inode *inode = de->d_inode;
766 struct coda_inode_info *cii;
767 ENTRY;
769 if (!inode)
770 return 1;
772 cii = ITOC(de->d_inode);
773 if (coda_isroot(inode))
774 return 1;
775 if (is_bad_inode(inode))
776 return 0;
778 if (! (cii->c_flags & (C_PURGE | C_FLUSH)) )
779 return valid;
781 shrink_dcache_parent(de);
783 /* propagate for a flush */
784 if (cii->c_flags & C_FLUSH)
785 coda_flag_inode_children(inode, C_FLUSH);
787 if (de->d_count > 1) {
788 /* pretend it's valid, but don't change the flags */
789 CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %s\n",
790 de->d_inode->i_ino, coda_f2s(&cii->c_fid));
791 return 1;
794 /* clear the flags. */
795 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
797 return 0;
801 * This is the callback from dput() when d_count is going to 0.
802 * We use this to unhash dentries with bad inodes.
804 static int coda_dentry_delete(struct dentry * dentry)
806 int flags;
808 if (!dentry->d_inode)
809 return 0;
811 flags = (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
812 if (is_bad_inode(dentry->d_inode) || flags) {
813 CDEBUG(D_DOWNCALL, "bad inode, unhashing %s/%s, %ld\n",
814 dentry->d_parent->d_name.name, dentry->d_name.name,
815 dentry->d_inode->i_ino);
816 return 1;
818 return 0;
824 * This is called when we want to check if the inode has
825 * changed on the server. Coda makes this easy since the
826 * cache manager Venus issues a downcall to the kernel when this
827 * happens
830 int coda_revalidate_inode(struct dentry *dentry)
832 struct coda_vattr attr;
833 int error = 0;
834 int old_mode;
835 ino_t old_ino;
836 struct inode *inode = dentry->d_inode;
837 struct coda_inode_info *cii = ITOC(inode);
839 ENTRY;
840 CDEBUG(D_INODE, "revalidating: %*s/%*s\n",
841 dentry->d_name.len, dentry->d_name.name,
842 dentry->d_parent->d_name.len, dentry->d_parent->d_name.name);
844 if ( cii->c_flags == 0 )
845 return 0;
847 /* Venus accessing a container file, don't try to revalidate */
848 if ( current->pid == coda_upc_comm.vc_pid )
849 return 0;
851 /* Venus closed the device .... */
852 if ( cii->c_flags & C_DYING )
853 goto return_bad_inode;
855 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
856 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
857 if ( error )
858 goto return_bad_inode;
860 /* this inode may be lost if:
861 - it's ino changed
862 - type changes must be permitted for repair and
863 missing mount points.
865 old_mode = inode->i_mode;
866 old_ino = inode->i_ino;
867 coda_vattr_to_iattr(inode, &attr);
870 if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
871 printk("Coda: inode %ld, fid %s changed type!\n",
872 inode->i_ino, coda_f2s(&(cii->c_fid)));
875 /* the following can happen when a local fid is replaced
876 with a global one, here we lose and declare the inode bad */
877 if (inode->i_ino != old_ino)
878 goto return_bad_inode;
880 if ( cii->c_flags )
881 coda_flag_inode_children(inode, C_FLUSH);
883 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
886 return 0;
888 return_bad_inode:
889 if ( cii->c_ovp ) {
890 iput(cii->c_ovp);
891 inode->i_mapping = &inode->i_data;
892 cii->c_ovp = NULL;
894 make_bad_inode(inode);
895 return -EIO;