Linux 2.4.0-test10pre4
[davej-history.git] / fs / coda / dir.c
blobe1ab9e89610bdbd7b9a943344fd497477ce57e85
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 <linux/string.h>
19 #include <linux/smp_lock.h>
21 #include <asm/uaccess.h>
23 #include <linux/coda.h>
24 #include <linux/coda_linux.h>
25 #include <linux/coda_psdev.h>
26 #include <linux/coda_fs_i.h>
27 #include <linux/coda_cache.h>
28 #include <linux/coda_proc.h>
30 /* dir inode-ops */
31 static int coda_create(struct inode *dir, struct dentry *new, int mode);
32 static int coda_mknod(struct inode *dir, struct dentry *new, int mode, int rdev);
33 static struct dentry *coda_lookup(struct inode *dir, struct dentry *target);
34 static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
35 struct dentry *entry);
36 static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
37 static int coda_symlink(struct inode *dir_inode, struct dentry *entry,
38 const char *symname);
39 static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode);
40 static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
41 static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
42 struct inode *new_inode, struct dentry *new_dentry);
44 /* dir file-ops */
45 static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
47 /* dentry ops */
48 static int coda_dentry_revalidate(struct dentry *de, int);
49 static int coda_dentry_delete(struct dentry *);
51 /* support routines */
52 static void coda_prepare_fakefile(struct inode *coda_inode,
53 struct file *coda_file,
54 struct inode *open_inode,
55 struct file *open_file,
56 struct dentry *open_dentry);
57 static int coda_venus_readdir(struct file *filp, void *dirent,
58 filldir_t filldir);
59 int coda_fsync(struct file *, struct dentry *dentry, int datasync);
61 int coda_hasmknod;
63 struct dentry_operations coda_dentry_operations =
65 d_revalidate: coda_dentry_revalidate,
66 d_delete: coda_dentry_delete,
69 struct inode_operations coda_dir_inode_operations =
71 create: coda_create,
72 lookup: coda_lookup,
73 link: coda_link,
74 unlink: coda_unlink,
75 symlink: coda_symlink,
76 mkdir: coda_mkdir,
77 rmdir: coda_rmdir,
78 mknod: coda_mknod,
79 rename: coda_rename,
80 permission: coda_permission,
81 revalidate: coda_revalidate_inode,
82 setattr: coda_notify_change,
85 struct file_operations coda_dir_operations = {
86 read: generic_read_dir,
87 readdir: coda_readdir,
88 open: coda_open,
89 release: coda_release,
90 fsync: coda_fsync,
94 /* inode operations for directories */
95 /* acces routines: lookup, readlink, permission */
96 static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
98 struct inode *res_inode = NULL;
99 struct ViceFid resfid = {0,0,0};
100 int dropme = 0; /* to indicate entry should not be cached */
101 int type = 0;
102 int error = 0;
103 const char *name = entry->d_name.name;
104 size_t length = entry->d_name.len;
106 ENTRY;
108 if ( length > CODA_MAXNAMLEN ) {
109 printk("name too long: lookup, %s (%*s)\n",
110 coda_i2s(dir), (int)length, name);
111 return ERR_PTR(-ENAMETOOLONG);
114 CDEBUG(D_INODE, "name %s, len %ld in ino %ld, fid %s\n",
115 name, (long)length, dir->i_ino, coda_i2s(dir));
117 /* control object, create inode on the fly */
118 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
119 error = coda_cnode_makectl(&res_inode, dir->i_sb);
120 CDEBUG(D_SPECIAL,
121 "Lookup on CTL object; dir ino %ld, count %d\n",
122 dir->i_ino, atomic_read(&dir->i_count));
123 dropme = 1;
124 goto exit;
127 error = venus_lookup(dir->i_sb, coda_i2f(dir),
128 (const char *)name, length, &type, &resfid);
130 res_inode = NULL;
131 if (!error) {
132 if (type & CODA_NOCACHE) {
133 type &= (~CODA_NOCACHE);
134 CDEBUG(D_INODE, "dropme set for %s\n",
135 coda_f2s(&resfid));
136 dropme = 1;
139 error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
140 if (error) return ERR_PTR(error);
142 /* make sure we drop unexpected weird fid's */
143 if (coda_f2i(&resfid) != res_inode->i_ino &&
144 !coda_fid_is_weird(&resfid))
145 dropme = 1;
146 } else if (error != -ENOENT) {
147 CDEBUG(D_INODE, "error for %s(%*s)%d\n",
148 coda_i2s(dir), (int)length, name, error);
149 return ERR_PTR(error);
151 CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n",
152 name, coda_f2s(&resfid), type, error, dropme);
154 exit:
155 entry->d_time = 0;
156 entry->d_op = &coda_dentry_operations;
157 d_add(entry, res_inode);
158 if ( dropme ) {
159 d_drop(entry);
160 coda_flag_inode(res_inode, C_VATTR);
162 EXIT;
163 return NULL;
167 int coda_permission(struct inode *inode, int mask)
169 int error;
171 ENTRY;
172 coda_vfs_stat.permission++;
174 if ( mask == 0 )
175 return 0;
177 if ( coda_access_cache ) {
178 coda_permission_stat.count++;
180 if ( coda_cache_check(inode, mask) ) {
181 coda_permission_stat.hit_count++;
182 return 0;
186 CDEBUG(D_INODE, "mask is %o\n", mask);
187 error = venus_access(inode->i_sb, coda_i2f(inode), mask);
189 CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %d\n",
190 coda_i2s(inode), inode->i_ino, mask, error);
192 if (!error)
193 coda_cache_enter(inode, mask);
195 return error;
199 static inline void coda_dir_changed(struct inode *dir, int link)
201 #ifdef REQUERY_VENUS_FOR_MTIME
202 /* invalidate the directory cnode's attributes so we refetch the
203 * attributes from venus next time the inode is referenced */
204 coda_flag_inode(dir, C_VATTR);
205 #else
206 /* optimistically we can also act as if our nose bleeds. The
207 * granularity of the mtime is coarse anyways so we might actually be
208 * right most of the time. Note: we only do this for directories. */
209 dir->i_mtime = CURRENT_TIME;
210 #endif
211 if (link)
212 dir->i_nlink += link;
215 /* creation routines: create, mknod, mkdir, link, symlink */
216 static int coda_create(struct inode *dir, struct dentry *de, int mode)
218 int error=0;
219 const char *name=de->d_name.name;
220 int length=de->d_name.len;
221 struct inode *result = NULL;
222 struct ViceFid newfid;
223 struct coda_vattr attrs;
225 ENTRY;
226 coda_vfs_stat.create++;
228 CDEBUG(D_INODE, "name: %s, length %d, mode %o\n", name, length, mode);
230 if (coda_isroot(dir) && coda_iscontrol(name, length))
231 return -EPERM;
233 error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
234 0, mode, 0, &newfid, &attrs);
236 if ( error ) {
237 CDEBUG(D_INODE, "create: %s, result %d\n",
238 coda_f2s(&newfid), error);
239 d_drop(de);
240 return error;
243 error = coda_cnode_make(&result, &newfid, dir->i_sb);
244 if ( error ) {
245 d_drop(de);
246 result = NULL;
247 return error;
250 /* invalidate the directory cnode's attributes */
251 coda_dir_changed(dir, 0);
252 d_instantiate(de, result);
253 return 0;
256 static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
258 int error=0;
259 const char *name=de->d_name.name;
260 int length=de->d_name.len;
261 struct inode *result = NULL;
262 struct ViceFid newfid;
263 struct coda_vattr attrs;
265 if ( coda_hasmknod == 0 )
266 return -EIO;
268 coda_vfs_stat.create++;
270 CDEBUG(D_INODE, "name: %s, length %d, mode %o, rdev %x\n",
271 name, length, mode, rdev);
273 if (coda_isroot(dir) && coda_iscontrol(name, length))
274 return -EPERM;
276 error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
277 0, mode, rdev, &newfid, &attrs);
279 if ( error ) {
280 CDEBUG(D_INODE, "mknod: %s, result %d\n",
281 coda_f2s(&newfid), error);
282 d_drop(de);
283 return error;
286 error = coda_cnode_make(&result, &newfid, dir->i_sb);
287 if ( error ) {
288 d_drop(de);
289 result = NULL;
290 return error;
293 /* invalidate the directory cnode's attributes */
294 coda_dir_changed(dir, 0);
295 d_instantiate(de, result);
296 return 0;
299 static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
301 struct inode *inode;
302 struct coda_vattr attr;
303 const char *name = de->d_name.name;
304 int len = de->d_name.len;
305 int error;
306 struct ViceFid newfid;
308 ENTRY;
309 coda_vfs_stat.mkdir++;
311 if (coda_isroot(dir) && coda_iscontrol(name, len))
312 return -EPERM;
314 CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n",
315 name, len, coda_i2s(dir), mode);
317 attr.va_mode = mode;
318 error = venus_mkdir(dir->i_sb, coda_i2f(dir),
319 name, len, &newfid, &attr);
321 if ( error ) {
322 CDEBUG(D_INODE, "mkdir error: %s result %d\n",
323 coda_f2s(&newfid), error);
324 d_drop(de);
325 return error;
328 CDEBUG(D_INODE, "mkdir: new dir has fid %s.\n",
329 coda_f2s(&newfid));
331 error = coda_cnode_make(&inode, &newfid, dir->i_sb);
332 if ( error ) {
333 d_drop(de);
334 return error;
337 /* invalidate the directory cnode's attributes */
338 coda_dir_changed(dir, 1);
339 d_instantiate(de, inode);
340 return 0;
343 /* try to make de an entry in dir_inodde linked to source_de */
344 static int coda_link(struct dentry *source_de, struct inode *dir_inode,
345 struct dentry *de)
347 struct inode *inode = source_de->d_inode;
348 const char * name = de->d_name.name;
349 int len = de->d_name.len;
350 int error;
352 ENTRY;
353 coda_vfs_stat.link++;
355 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
356 return -EPERM;
358 CDEBUG(D_INODE, "old: fid: %s\n", coda_i2s(inode));
359 CDEBUG(D_INODE, "directory: %s\n", coda_i2s(dir_inode));
361 error = venus_link(dir_inode->i_sb, coda_i2f(inode),
362 coda_i2f(dir_inode), (const char *)name, len);
364 if (error) {
365 d_drop(de);
366 goto out;
369 coda_dir_changed(dir_inode, 0);
370 atomic_inc(&inode->i_count);
371 d_instantiate(de, inode);
372 inode->i_nlink++;
374 out:
375 CDEBUG(D_INODE, "link result %d\n",error);
376 EXIT;
377 return(error);
381 static int coda_symlink(struct inode *dir_inode, struct dentry *de,
382 const char *symname)
384 const char *name = de->d_name.name;
385 int len = de->d_name.len;
386 int symlen;
387 int error=0;
389 ENTRY;
390 coda_vfs_stat.symlink++;
392 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
393 return -EPERM;
395 symlen = strlen(symname);
396 if ( symlen > CODA_MAXPATHLEN )
397 return -ENAMETOOLONG;
399 CDEBUG(D_INODE, "symname: %s, length: %d\n", symname, symlen);
402 * This entry is now negative. Since we do not create
403 * an inode for the entry we have to drop it.
405 d_drop(de);
406 error = venus_symlink(dir_inode->i_sb, coda_i2f(dir_inode), name, len,
407 symname, symlen);
409 /* mtime is no good anymore */
410 if ( !error )
411 coda_dir_changed(dir_inode, 0);
413 CDEBUG(D_INODE, "in symlink result %d\n",error);
414 EXIT;
415 return error;
418 /* destruction routines: unlink, rmdir */
419 int coda_unlink(struct inode *dir, struct dentry *de)
421 int error;
422 const char *name = de->d_name.name;
423 int len = de->d_name.len;
425 ENTRY;
426 coda_vfs_stat.unlink++;
428 CDEBUG(D_INODE, " %s in %s, dirino %ld\n", name ,
429 coda_i2s(dir), dir->i_ino);
431 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
432 if ( error ) {
433 CDEBUG(D_INODE, "upc returned error %d\n", error);
434 return error;
437 coda_dir_changed(dir, 0);
438 de->d_inode->i_nlink--;
440 return 0;
443 int coda_rmdir(struct inode *dir, struct dentry *de)
445 const char *name = de->d_name.name;
446 int len = de->d_name.len;
447 int error;
449 ENTRY;
450 coda_vfs_stat.rmdir++;
452 if (!d_unhashed(de))
453 return -EBUSY;
454 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
456 if ( error ) {
457 CDEBUG(D_INODE, "upc returned error %d\n", error);
458 return error;
461 coda_dir_changed(dir, -1);
462 de->d_inode->i_nlink--;
463 d_delete(de);
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 int link_adjust = 0;
477 int error;
479 ENTRY;
480 coda_vfs_stat.rename++;
482 CDEBUG(D_INODE, "old: %s, (%d length), new: %s"
483 "(%d length). old:d_count: %d, new:d_count: %d\n",
484 old_name, old_length, new_name, new_length,
485 atomic_read(&old_dentry->d_count), atomic_read(&new_dentry->d_count));
487 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
488 coda_i2f(new_dir), old_length, new_length,
489 (const char *) old_name, (const char *)new_name);
491 if ( !error ) {
492 if ( new_dentry->d_inode ) {
493 if ( S_ISDIR(new_dentry->d_inode->i_mode) )
494 link_adjust = 1;
496 coda_dir_changed(old_dir, -link_adjust);
497 coda_dir_changed(new_dir, link_adjust);
498 coda_flag_inode(new_dentry->d_inode, C_VATTR);
499 } else {
500 coda_flag_inode(old_dir, C_VATTR);
501 coda_flag_inode(new_dir, C_VATTR);
505 CDEBUG(D_INODE, "result %d\n", error);
507 EXIT;
508 return error;
512 /* file operations for directories */
513 int coda_readdir(struct file *file, void *dirent, filldir_t filldir)
515 int result = 0;
516 struct file open_file;
517 struct dentry open_dentry;
518 struct inode *inode=file->f_dentry->d_inode, *container;
520 ENTRY;
521 coda_vfs_stat.readdir++;
523 if ( inode->i_mapping == &inode->i_data ) {
524 CDEBUG(D_FILE, "no container inode.\n");
525 return -EIO;
528 container = (struct inode *)inode->i_mapping->host;
530 coda_prepare_fakefile(inode, file, container, &open_file, &open_dentry);
532 if ( S_ISREG(container->i_mode) ) {
533 /* Venus: we must read Venus dirents from the file */
534 result = coda_venus_readdir(&open_file, dirent, filldir);
535 } else {
536 /* potemkin case: we are handed a directory inode */
537 result = vfs_readdir(&open_file, filldir, dirent);
540 /* we only have to restore the file position (and f_version?) */
541 file->f_pos = open_file.f_pos;
542 file->f_version = open_file.f_version;
544 EXIT;
545 return result;
548 /* grab the ext2 inode of the container file */
549 static int coda_inode_grab(dev_t dev, ino_t ino, struct inode **ind)
551 struct super_block *sbptr;
553 sbptr = get_super(dev);
555 if ( !sbptr ) {
556 printk("coda_inode_grab: coda_find_super returns NULL.\n");
557 return -ENXIO;
560 *ind = NULL;
561 *ind = iget(sbptr, ino);
563 if ( *ind == NULL ) {
564 printk("coda_inode_grab: iget(dev: %d, ino: %ld) "
565 "returns NULL.\n", dev, (long)ino);
566 return -ENOENT;
568 CDEBUG(D_FILE, "ino: %ld, ops at %p\n", (long)ino, (*ind)->i_op);
569 return 0;
572 /* ask venus to cache the file and return the inode of the container file,
573 put this inode pointer in the cnode for future read/writes */
574 int coda_open(struct inode *i, struct file *f)
576 ino_t ino;
577 dev_t dev;
578 int error = 0;
579 struct inode *cont_inode = NULL, *old_container;
580 unsigned short flags = f->f_flags & (~O_EXCL);
581 unsigned short coda_flags = coda_flags_to_cflags(flags);
582 struct coda_cred *cred;
583 struct coda_inode_info *cii;
585 lock_kernel();
586 ENTRY;
587 coda_vfs_stat.open++;
589 CDEBUG(D_SPECIAL, "OPEN inode number: %ld, count %d, flags %o.\n",
590 f->f_dentry->d_inode->i_ino, atomic_read(&f->f_dentry->d_count), flags);
592 error = venus_open(i->i_sb, coda_i2f(i), coda_flags, &ino, &dev);
593 if (error) {
594 CDEBUG(D_FILE, "venus: dev %d, inode %ld, out->result %d\n",
595 dev, (long)ino, error);
596 unlock_kernel();
597 return error;
600 /* coda_upcall returns ino number of cached object, get inode */
601 CDEBUG(D_FILE, "cache file dev %d, ino %ld\n", dev, (long)ino);
602 error = coda_inode_grab(dev, ino, &cont_inode);
604 if ( error || !cont_inode ){
605 printk("coda_open: coda_inode_grab error %d.", error);
606 if (cont_inode)
607 iput(cont_inode);
608 unlock_kernel();
609 return error;
612 CODA_ALLOC(cred, struct coda_cred *, sizeof(*cred));
613 coda_load_creds(cred);
614 f->private_data = cred;
616 if ( i->i_mapping != &i->i_data ) {
617 old_container = (struct inode *)i->i_mapping->host;
618 i->i_mapping = &i->i_data;
619 iput(old_container);
621 i->i_mapping = cont_inode->i_mapping;
623 cii = ITOC(i);
624 cii->c_contcount++;
626 CDEBUG(D_FILE, "result %d, coda i->i_count is %d, cii->contcount is %d for ino %ld\n",
627 error, atomic_read(&i->i_count), cii->c_contcount, i->i_ino);
628 CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %p\n",
629 cont_inode->i_ino, atomic_read(&cont_inode->i_count),
630 cont_inode->i_op);
631 EXIT;
632 unlock_kernel();
633 return 0;
636 int coda_release(struct inode *i, struct file *f)
638 struct inode *container = NULL;
639 int error = 0;
640 unsigned short flags = (f->f_flags) & (~O_EXCL);
641 unsigned short cflags = coda_flags_to_cflags(flags);
642 struct coda_cred *cred;
643 struct coda_inode_info *cii;
645 lock_kernel();
646 ENTRY;
647 coda_vfs_stat.release++;
649 cred = (struct coda_cred *)f->private_data;
651 if (i->i_mapping != &i->i_data)
652 container = (struct inode *)i->i_mapping->host;
654 cii = ITOC(i);
655 CDEBUG(D_FILE, "RELEASE coda (ino %ld, ct %d, cc %d) cache (ino %ld, ct %d)\n",
656 i->i_ino, atomic_read(&i->i_count), cii->c_contcount,
657 (container ? container->i_ino : 0),
658 (container ? atomic_read(&container->i_count) : -99));
660 if (--cii->c_contcount == 0 && container) {
661 i->i_mapping = &i->i_data;
662 iput(container);
665 error = venus_release(i->i_sb, coda_i2f(i), cflags, cred);
667 f->private_data = NULL;
668 if (cred)
669 CODA_FREE(cred, sizeof(*cred));
671 CDEBUG(D_FILE, "coda_release: result: %d\n", error);
672 unlock_kernel();
673 return error;
676 /* support routines */
678 /* instantiate a fake file and dentry to pass to coda_venus_readdir */
679 static void coda_prepare_fakefile(struct inode *i, struct file *coda_file,
680 struct inode *cont_inode,
681 struct file *cont_file,
682 struct dentry *cont_dentry)
684 cont_file->f_dentry = cont_dentry;
685 cont_file->f_dentry->d_inode = cont_inode;
686 cont_file->f_pos = coda_file->f_pos;
687 cont_file->f_version = coda_file->f_version;
688 cont_file->f_op = cont_inode->i_fop;
689 return ;
693 * this structure is manipulated by filldir in vfs layer.
694 * the count holds the remaining amount of space in the getdents buffer,
695 * beyond the current_dir pointer.
697 * What structure is this comment referring to?? -JH
700 /* should be big enough to hold any single directory entry */
701 #define DIR_BUFSIZE 2048
703 static int coda_venus_readdir(struct file *filp, void *getdent,
704 filldir_t filldir)
706 int bufsize;
707 int offset = filp->f_pos; /* offset in the directory file */
708 int count = 0;
709 int pos = 0; /* offset in the block we read */
710 int result = 0; /* either an error or # of entries returned */
711 int errfill;
712 char *buff = NULL;
713 struct venus_dirent *vdirent;
714 int string_offset = (int) (&((struct venus_dirent *)(0))->d_name);
715 int i;
717 ENTRY;
719 CODA_ALLOC(buff, char *, DIR_BUFSIZE);
720 if ( !buff ) {
721 printk("coda_venus_readdir: out of memory.\n");
722 return -ENOMEM;
725 /* we use this routine to read the file into our buffer */
726 bufsize = kernel_read(filp, filp->f_pos, buff, DIR_BUFSIZE);
727 if ( bufsize < 0) {
728 printk("coda_venus_readdir: cannot read directory %d.\n",
729 bufsize);
730 result = bufsize;
731 goto exit;
733 if ( bufsize == 0) {
734 result = 0;
735 goto exit;
738 /* Parse and write into user space. Filldir tells us when done! */
739 CDEBUG(D_FILE, "buffsize: %d offset %d, count %d.\n",
740 bufsize, offset, count);
742 i = 0;
743 result = 0;
744 while ( pos + string_offset < bufsize && i < 1024) {
745 vdirent = (struct venus_dirent *) (buff + pos);
747 /* test if the name is fully in the buffer */
748 if ( pos + string_offset + (int) vdirent->d_namlen >= bufsize ){
749 if ( result == 0 )
750 printk("CODA: Invalid directory cfino: %ld\n",
751 filp->f_dentry->d_inode->i_ino);
752 break;
754 /* now we are certain that we can read the entry from buff */
756 /* if we don't have a null entry, copy it */
757 if ( vdirent->d_fileno && vdirent->d_reclen ) {
758 int namlen = vdirent->d_namlen;
759 off_t offs = filp->f_pos;
760 ino_t ino = vdirent->d_fileno;
761 char *name = vdirent->d_name;
763 errfill = filldir(getdent, name, namlen,
764 offs, ino, DT_UNKNOWN);
765 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);
766 /* errfill means no space for filling in this round */
767 if ( errfill < 0 ) {
768 result = 0;
769 break;
771 /* adjust count */
772 result++;
774 /* next one */
775 filp->f_pos += vdirent->d_reclen;
776 if ( filp->f_pos > filp->f_dentry->d_inode->i_size )
777 break;
778 if ( !vdirent->d_reclen ) {
779 printk("CODA: Invalid directory, cfino: %ld\n",
780 filp->f_dentry->d_inode->i_ino);
781 result = -EINVAL;
782 break;
784 pos += (unsigned int) vdirent->d_reclen;
785 i++;
788 if ( i >= 1024 ) {
789 printk("Repeating too much in readdir %ld\n",
790 filp->f_dentry->d_inode->i_ino);
791 result = -EINVAL;
794 exit:
795 CODA_FREE(buff, DIR_BUFSIZE);
796 return result;
799 /* called when a cache lookup succeeds */
800 static int coda_dentry_revalidate(struct dentry *de, int flags)
802 struct inode *inode = de->d_inode;
803 struct coda_inode_info *cii;
804 ENTRY;
806 if (!inode)
807 return 1;
808 lock_kernel();
809 if (coda_isroot(inode))
810 goto out;
811 if (is_bad_inode(inode))
812 goto bad;
814 cii = ITOC(de->d_inode);
815 if (! (cii->c_flags & (C_PURGE | C_FLUSH)) )
816 goto out;
818 shrink_dcache_parent(de);
820 /* propagate for a flush */
821 if (cii->c_flags & C_FLUSH)
822 coda_flag_inode_children(inode, C_FLUSH);
824 if (atomic_read(&de->d_count) > 1) {
825 /* pretend it's valid, but don't change the flags */
826 CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %s\n",
827 de->d_inode->i_ino, coda_f2s(&cii->c_fid));
828 goto out;
831 /* clear the flags. */
832 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
834 bad:
835 unlock_kernel();
836 return 0;
837 out:
838 unlock_kernel();
839 return 1;
843 * This is the callback from dput() when d_count is going to 0.
844 * We use this to unhash dentries with bad inodes.
846 static int coda_dentry_delete(struct dentry * dentry)
848 int flags;
850 if (!dentry->d_inode)
851 return 0;
853 flags = (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
854 if (is_bad_inode(dentry->d_inode) || flags) {
855 CDEBUG(D_DOWNCALL, "bad inode, unhashing %s/%s, %ld\n",
856 dentry->d_parent->d_name.name, dentry->d_name.name,
857 dentry->d_inode->i_ino);
858 return 1;
860 return 0;
866 * This is called when we want to check if the inode has
867 * changed on the server. Coda makes this easy since the
868 * cache manager Venus issues a downcall to the kernel when this
869 * happens
871 int coda_revalidate_inode(struct dentry *dentry)
873 struct coda_vattr attr;
874 int error = 0;
875 int old_mode;
876 ino_t old_ino;
877 struct inode *inode = dentry->d_inode, *container;
878 struct coda_inode_info *cii = ITOC(inode);
880 ENTRY;
881 CDEBUG(D_INODE, "revalidating: %*s/%*s\n",
882 dentry->d_name.len, dentry->d_name.name,
883 dentry->d_parent->d_name.len, dentry->d_parent->d_name.name);
885 lock_kernel();
886 if ( cii->c_flags == 0 )
887 goto ok;
889 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
890 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
891 if ( error )
892 goto return_bad_inode;
894 /* this inode may be lost if:
895 - it's ino changed
896 - type changes must be permitted for repair and
897 missing mount points.
899 old_mode = inode->i_mode;
900 old_ino = inode->i_ino;
901 coda_vattr_to_iattr(inode, &attr);
903 if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
904 printk("Coda: inode %ld, fid %s changed type!\n",
905 inode->i_ino, coda_f2s(&(cii->c_fid)));
908 /* the following can happen when a local fid is replaced
909 with a global one, here we lose and declare the inode bad */
910 if (inode->i_ino != old_ino)
911 goto return_bad_inode;
913 if ( cii->c_flags )
914 coda_flag_inode_children(inode, C_FLUSH);
916 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
920 unlock_kernel();
921 return 0;
923 return_bad_inode:
924 if ( inode->i_mapping != &inode->i_data ) {
925 container = (struct inode *)inode->i_mapping->host;
926 inode->i_mapping = &inode->i_data;
927 iput(container);
929 make_bad_inode(inode);
930 unlock_kernel();
931 return -EIO;