Import 2.1.118
[davej-history.git] / fs / coda / dir.c
blobb555415328a8c5b690049f5e2a215cac147b1ee3
1 /*
2 * Directory operations for Coda filesystem
3 * Original version: (C) 1996 P. Braam and M. Callahan
4 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University
5 *
6 * Carnegie Mellon encourages users to contribute improvements to
7 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu).
8 */
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/fs.h>
14 #include <linux/stat.h>
15 #include <linux/errno.h>
16 #include <linux/locks.h>
17 #include <asm/segment.h>
18 #include <asm/uaccess.h>
19 #include <linux/string.h>
21 #include <linux/coda.h>
22 #include <linux/coda_linux.h>
23 #include <linux/coda_psdev.h>
24 #include <linux/coda_fs_i.h>
25 #include <linux/coda_cache.h>
26 #include <linux/coda_proc.h>
28 /* dir inode-ops */
29 static int coda_create(struct inode *dir, struct dentry *new, int mode);
30 static int coda_mknod(struct inode *dir, struct dentry *new, int mode, int rdev);
31 static int coda_lookup(struct inode *dir, struct dentry *target);
32 static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
33 struct dentry *entry);
34 static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
35 static int coda_symlink(struct inode *dir_inode, struct dentry *entry,
36 const char *symname);
37 static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode);
38 static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
39 static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
40 struct inode *new_inode, struct dentry *new_dentry);
42 /* dir file-ops */
43 static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
45 /* dentry ops */
46 static int coda_dentry_revalidate(struct dentry *de);
47 static void coda_dentry_delete(struct dentry *);
48 /* support routines */
49 static int coda_venus_readdir(struct file *filp, void *dirent,
50 filldir_t filldir);
51 int coda_fsync(struct file *, struct dentry *dentry);
52 static int coda_refresh_inode(struct dentry *dentry);
54 int coda_crossvol_rename = 0;
55 int coda_hasmknod = 0;
58 struct dentry_operations coda_dentry_operations =
60 coda_dentry_revalidate, /* revalidate */
61 NULL, /* hash */
62 NULL, /* compare */
63 coda_dentry_delete /* delete */
66 struct inode_operations coda_dir_inode_operations =
68 &coda_dir_operations,
69 coda_create, /* create */
70 coda_lookup, /* lookup */
71 coda_link, /* link */
72 coda_unlink, /* unlink */
73 coda_symlink, /* symlink */
74 coda_mkdir, /* mkdir */
75 coda_rmdir, /* rmdir */
76 coda_mknod, /* mknod */
77 coda_rename, /* rename */
78 NULL, /* readlink */
79 NULL, /* follow_link */
80 NULL, /* readpage */
81 NULL, /* writepage */
82 NULL, /* bmap */
83 NULL, /* truncate */
84 coda_permission, /* permission */
85 NULL, /* smap */
86 NULL, /* update page */
87 coda_revalidate_inode /* revalidate */
90 struct file_operations coda_dir_operations = {
91 NULL, /* lseek */
92 NULL, /* read -- bad */
93 NULL, /* write */
94 coda_readdir, /* readdir */
95 NULL, /* select */
96 NULL, /* ioctl */
97 NULL, /* mmap */
98 coda_open, /* open */
99 NULL, /* flush */
100 coda_release, /* release */
101 coda_fsync, /* fsync */
102 NULL,
103 NULL,
104 NULL
108 /* inode operations for directories */
109 /* acces routines: lookup, readlink, permission */
110 static int coda_lookup(struct inode *dir, struct dentry *entry)
112 struct coda_inode_info *dircnp;
113 struct inode *res_inode = NULL;
114 struct ViceFid resfid;
115 int dropme = 0; /* to indicate entry should not be cached */
116 int type;
117 int error = 0;
118 const char *name = entry->d_name.name;
119 size_t length = entry->d_name.len;
121 ENTRY;
122 CDEBUG(D_INODE, "name %s, len %d in ino %ld\n",
123 name, length, dir->i_ino);
125 if (!dir || !S_ISDIR(dir->i_mode)) {
126 printk("coda_lookup: inode is NULL or not a directory\n");
127 return -ENOTDIR;
130 dircnp = ITOC(dir);
132 if ( length > CFS_MAXNAMLEN ) {
133 printk("name too long: lookup, %s (%*s)\n",
134 coda_f2s(&dircnp->c_fid), length, name);
135 return -ENAMETOOLONG;
138 CDEBUG(D_INODE, "lookup: %*s in %s\n", length, name,
139 coda_f2s(&dircnp->c_fid));
141 /* control object, create inode on the fly */
142 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
143 error = coda_cnode_makectl(&res_inode, dir->i_sb);
144 CDEBUG(D_SPECIAL,
145 "Lookup on CTL object; dir ino %ld, count %d\n",
146 dir->i_ino, dir->i_count);
147 goto exit;
150 error = venus_lookup(dir->i_sb, &(dircnp->c_fid),
151 (const char *)name, length, &type, &resfid);
153 res_inode = NULL;
154 if (!error) {
155 if (type & CFS_NOCACHE) {
156 type &= (~CFS_NOCACHE);
157 CDEBUG(D_INODE, "dropme set for %s\n",
158 coda_f2s(&resfid));
159 dropme = 1;
161 error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
162 if (error)
163 return error;
164 } else if (error != -ENOENT) {
165 CDEBUG(D_INODE, "error for %s(%*s)%d\n",
166 coda_f2s(&dircnp->c_fid), length, name, error);
167 return error;
169 CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n",
170 name, coda_f2s(&resfid), type, error, dropme);
172 exit:
173 entry->d_time = 0;
174 entry->d_op = &coda_dentry_operations;
175 d_add(entry, res_inode);
176 if ( dropme ) {
177 d_drop(entry);
178 ITOC(res_inode)->c_flags |= C_VATTR;
180 EXIT;
181 return 0;
185 int coda_permission(struct inode *inode, int mask)
187 struct coda_inode_info *cp;
188 int error;
190 ENTRY;
191 coda_vfs_stat.permission++;
192 coda_permission_stat.count++;
194 if ( mask == 0 ) {
195 EXIT;
196 return 0;
199 if ( coda_access_cache == 1 ) {
200 if ( coda_cache_check(inode, mask) ) {
201 coda_permission_stat.hit_count++;
202 return 0;
206 cp = ITOC(inode);
207 CHECK_CNODE(cp);
209 CDEBUG(D_INODE, "mask is %o\n", mask);
210 error = venus_access(inode->i_sb, &(cp->c_fid), mask);
212 CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %d\n",
213 coda_f2s(&(cp->c_fid)), inode->i_ino, mask, error);
215 if ( error == 0 ) {
216 coda_cache_enter(inode, mask);
219 return error;
224 /* creation routines: create, mknod, mkdir, link, symlink */
226 static int coda_create(struct inode *dir, struct dentry *de, int mode)
228 int error=0;
229 struct coda_inode_info *dircnp;
230 const char *name=de->d_name.name;
231 int length=de->d_name.len;
232 struct inode *result = NULL;
233 struct ViceFid newfid;
234 struct coda_vattr attrs;
236 ENTRY;
237 coda_vfs_stat.create++;
239 CDEBUG(D_INODE, "name: %s, length %d, mode %o\n",name, length, mode);
241 if (!dir || !S_ISDIR(dir->i_mode)) {
242 printk("coda_create: inode is null or not a directory\n");
243 return -ENOENT;
246 if (coda_isroot(dir) && coda_iscontrol(name, length))
247 return -EPERM;
249 dircnp = ITOC(dir);
250 CHECK_CNODE(dircnp);
252 if ( length > CFS_MAXNAMLEN ) {
253 printk("name too long: create, %s(%s)\n",
254 coda_f2s(&dircnp->c_fid), name);
255 return -ENAMETOOLONG;
258 error = venus_create(dir->i_sb, &(dircnp->c_fid), name, length,
259 0, mode, 0, &newfid, &attrs);
261 if ( error ) {
262 CDEBUG(D_INODE, "create: %s, result %d\n",
263 coda_f2s(&newfid), error);
264 d_drop(de);
265 return error;
268 error = coda_cnode_make(&result, &newfid, dir->i_sb);
269 if ( error ) {
270 d_drop(de);
271 result = NULL;
272 return error;
275 /* invalidate the directory cnode's attributes */
276 dircnp->c_flags |= C_VATTR;
277 d_instantiate(de, result);
278 return 0;
281 static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
283 int error=0;
284 struct coda_inode_info *dircnp;
285 const char *name=de->d_name.name;
286 int length=de->d_name.len;
287 struct inode *result = NULL;
288 struct ViceFid newfid;
289 struct coda_vattr attrs;
291 if ( coda_hasmknod == 0 )
292 return -EIO;
294 coda_vfs_stat.create++;
296 CDEBUG(D_INODE, "name: %s, length %d, mode %o, rdev %x\n",name, length, mode, rdev);
298 if (!dir || !S_ISDIR(dir->i_mode)) {
299 printk("coda_mknod: inode is null or not a directory\n");
300 return -ENOENT;
303 if (coda_isroot(dir) && coda_iscontrol(name, length))
304 return -EPERM;
306 dircnp = ITOC(dir);
307 CHECK_CNODE(dircnp);
309 if ( length > CFS_MAXNAMLEN ) {
310 printk("name too long: mknod, %s(%s)\n",
311 coda_f2s(&dircnp->c_fid), name);
312 return -ENAMETOOLONG;
315 error = venus_create(dir->i_sb, &(dircnp->c_fid), name, length,
316 0, mode, rdev, &newfid, &attrs);
318 if ( error ) {
319 CDEBUG(D_INODE, "mknod: %s, result %d\n",
320 coda_f2s(&newfid), error);
321 d_drop(de);
322 return error;
325 error = coda_cnode_make(&result, &newfid, dir->i_sb);
326 if ( error ) {
327 d_drop(de);
328 result = NULL;
329 return error;
332 /* invalidate the directory cnode's attributes */
333 dircnp->c_flags |= C_VATTR;
334 d_instantiate(de, result);
335 return 0;
338 static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
340 struct coda_inode_info *dircnp;
341 struct inode *inode;
342 struct coda_vattr attr;
343 const char *name = de->d_name.name;
344 int len = de->d_name.len;
345 int error;
346 struct ViceFid newfid;
348 ENTRY;
349 coda_vfs_stat.mkdir++;
351 if (!dir || !S_ISDIR(dir->i_mode)) {
352 printk("coda_mkdir: inode is NULL or not a directory\n");
353 return -ENOENT;
356 if ( len > CFS_MAXNAMLEN )
357 return -ENAMETOOLONG;
359 if (coda_isroot(dir) && coda_iscontrol(name, len))
360 return -EPERM;
362 dircnp = ITOC(dir);
363 CHECK_CNODE(dircnp);
365 CDEBUG(D_INODE, "mkdir %s (len %d) in %s, mode %o.\n",
366 name, len, coda_f2s(&(dircnp->c_fid)), mode);
368 attr.va_mode = mode;
369 error = venus_mkdir(dir->i_sb, &(dircnp->c_fid),
370 name, len, &newfid, &attr);
372 if ( error ) {
373 CDEBUG(D_INODE, "mkdir error: %s result %d\n",
374 coda_f2s(&newfid), error);
375 d_drop(de);
376 return error;
379 CDEBUG(D_INODE, "mkdir: new dir has fid %s.\n",
380 coda_f2s(&newfid));
382 error = coda_cnode_make(&inode, &newfid, dir->i_sb);
383 if ( error ) {
384 d_drop(de);
385 return error;
388 /* invalidate the directory cnode's attributes */
389 dircnp->c_flags |= C_VATTR;
390 dir->i_nlink++;
391 d_instantiate(de, inode);
392 return 0;
395 /* try to make de an entry in dir_inodde linked to source_de */
396 static int coda_link(struct dentry *source_de, struct inode *dir_inode,
397 struct dentry *de)
399 struct inode *inode = source_de->d_inode;
400 const char * name = de->d_name.name;
401 int len = de->d_name.len;
402 struct coda_inode_info *dir_cnp, *cnp;
403 int error;
405 ENTRY;
406 coda_vfs_stat.link++;
408 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
409 return -EPERM;
411 dir_cnp = ITOC(dir_inode);
412 cnp = ITOC(inode);
413 CHECK_CNODE(cnp);
415 CDEBUG(D_INODE, "old: fid: %s\n", coda_f2s(&(cnp->c_fid)));
416 CDEBUG(D_INODE, "directory: %s\n", coda_f2s(&(dir_cnp->c_fid)));
418 if ( len > CFS_MAXNAMLEN ) {
419 printk("coda_link: name too long. \n");
420 return -ENAMETOOLONG;
423 error = venus_link(dir_inode->i_sb,&(cnp->c_fid), &(dir_cnp->c_fid),
424 (const char *)name, len);
426 if ( ! error ) {
427 dir_cnp->c_flags |= C_VATTR;
428 ++inode->i_count;
429 d_instantiate(de, inode);
430 inode->i_nlink++;
431 } else {
432 d_drop(de);
435 CDEBUG(D_INODE, "link result %d\n",error);
436 EXIT;
437 return(error);
441 static int coda_symlink(struct inode *dir_inode, struct dentry *de,
442 const char *symname)
444 const char *name = de->d_name.name;
445 int len = de->d_name.len;
446 struct coda_inode_info *dir_cnp = ITOC(dir_inode);
447 int symlen;
448 int error=0;
450 ENTRY;
451 coda_vfs_stat.symlink++;
453 if (coda_isroot(dir_inode) && coda_iscontrol(name, len))
454 return -EPERM;
456 if ( len > CFS_MAXNAMLEN )
457 return -ENAMETOOLONG;
459 symlen = strlen(symname);
460 if ( symlen > CFS_MAXPATHLEN )
461 return -ENAMETOOLONG;
463 CDEBUG(D_INODE, "symname: %s, length: %d\n", symname, symlen);
466 * This entry is now negative. Since we do not create
467 * an inode for the entry we have to drop it.
469 d_drop(de);
471 error = venus_symlink(dir_inode->i_sb, &(dir_cnp->c_fid), name, len,
472 symname, symlen);
474 if ( !error ) {
475 dir_cnp->c_flags |= C_VATTR;
478 CDEBUG(D_INODE, "in symlink result %d\n",error);
479 EXIT;
480 return error;
483 /* destruction routines: unlink, rmdir */
484 int coda_unlink(struct inode *dir, struct dentry *de)
486 struct coda_inode_info *dircnp;
487 int error;
488 const char *name = de->d_name.name;
489 int len = de->d_name.len;
491 ENTRY;
492 coda_vfs_stat.unlink++;
494 dircnp = ITOC(dir);
495 CHECK_CNODE(dircnp);
497 CDEBUG(D_INODE, " %s in %s, ino %ld\n", name ,
498 coda_f2s(&(dircnp->c_fid)), dir->i_ino);
500 /* this file should no longer be in the namecache! */
502 error = venus_remove(dir->i_sb, &(dircnp->c_fid), name, len);
504 if ( error ) {
505 CDEBUG(D_INODE, "upc returned error %d\n", error);
506 return error;
509 /* cache management */
510 dircnp->c_flags |= C_VATTR;
511 de->d_inode->i_nlink--;
513 d_delete(de);
515 return 0;
518 int coda_rmdir(struct inode *dir, struct dentry *de)
520 struct coda_inode_info *dircnp;
521 const char *name = de->d_name.name;
522 int len = de->d_name.len;
523 int error, rehash = 0;
525 ENTRY;
526 coda_vfs_stat.rmdir++;
528 if (!dir || !S_ISDIR(dir->i_mode)) {
529 printk("coda_rmdir: inode is NULL or not a directory\n");
530 return -ENOENT;
532 dircnp = ITOC(dir);
533 CHECK_CNODE(dircnp);
535 if (len > CFS_MAXNAMLEN)
536 return -ENAMETOOLONG;
538 error = -EBUSY;
539 if (de->d_count > 1) {
540 /* Attempt to shrink child dentries ... */
541 shrink_dcache_parent(de);
542 if (de->d_count > 1)
543 return error;
545 /* Drop the dentry to force a new lookup */
546 if (!list_empty(&de->d_hash)) {
547 d_drop(de);
548 rehash = 1;
551 /* update i_nlink and free the inode before unlinking;
552 if rmdir fails a new lookup set i_nlink right.*/
553 if (de->d_inode->i_nlink)
554 de->d_inode->i_nlink --;
555 d_delete(de);
557 error = venus_rmdir(dir->i_sb, &(dircnp->c_fid), name, len);
559 if ( error ) {
560 CDEBUG(D_INODE, "upc returned error %d\n", error);
561 return error;
564 if (rehash)
565 d_add(de, NULL);
566 /* XXX how can mtime be set? */
568 return 0;
571 /* rename */
572 static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
573 struct inode *new_dir, struct dentry *new_dentry)
575 const char *old_name = old_dentry->d_name.name;
576 const char *new_name = new_dentry->d_name.name;
577 int old_length = old_dentry->d_name.len;
578 int new_length = new_dentry->d_name.len;
579 struct inode *old_inode = old_dentry->d_inode;
580 struct inode *new_inode = new_dentry->d_inode;
581 struct coda_inode_info *new_cnp, *old_cnp;
582 int error;
584 ENTRY;
585 coda_vfs_stat.rename++;
587 if ( (old_length > CFS_MAXNAMLEN) || new_length > CFS_MAXNAMLEN ) {
588 return -ENAMETOOLONG;
591 old_cnp = ITOC(old_dir);
592 new_cnp = ITOC(new_dir);
594 CDEBUG(D_INODE, "old: %s, (%d length, %d strlen), new: %s"
595 "(%d length, %d strlen).old:d_count: %d, new:d_count: %d\n",
596 old_name, old_length, strlen(old_name), new_name, new_length,
597 strlen(new_name),old_dentry->d_count, new_dentry->d_count);
599 if (new_inode == old_inode)
600 return 0;
602 /* make sure target is not in use */
603 if (new_inode && S_ISDIR(new_inode->i_mode)) {
605 * Prune any children before testing for busy.
607 if (new_dentry->d_count > 1)
608 shrink_dcache_parent(new_dentry);
610 if (new_dentry->d_count > 1)
611 return -EBUSY;
614 /* the C library will do unlink/create etc */
615 if ( coda_crossvol_rename == 0 &&
616 old_cnp->c_fid.Volume != new_cnp->c_fid.Volume )
617 return -EXDEV;
619 error = venus_rename(old_dir->i_sb, &(old_cnp->c_fid),
620 &(new_cnp->c_fid), old_length, new_length,
621 (const char *) old_name, (const char *)new_name);
623 if ( error ) {
624 CDEBUG(D_INODE, "returned error %d\n", error);
625 return error;
628 coda_flag_inode(new_inode, C_VATTR);
629 coda_flag_inode(old_dir, C_VATTR);
630 coda_flag_inode(new_dir, C_VATTR);
632 CDEBUG(D_INODE, "result %d\n", error);
633 d_move(old_dentry, new_dentry);
635 EXIT;
636 return 0;
641 /* file operations for directories */
642 int coda_readdir(struct file *file, void *dirent, filldir_t filldir)
644 int result = 0;
645 struct coda_inode_info *cnp;
646 struct file open_file;
647 struct dentry open_dentry;
648 struct inode *inode=file->f_dentry->d_inode;
650 ENTRY;
651 coda_vfs_stat.readdir++;
653 if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode)) {
654 printk("coda_readdir: inode is NULL or not a directory\n");
655 return -EBADF;
658 cnp = ITOC(inode);
659 CHECK_CNODE(cnp);
661 if ( !cnp->c_ovp ) {
662 CDEBUG(D_FILE, "open inode pointer = NULL.\n");
663 return -EIO;
666 coda_prepare_openfile(inode, file, cnp->c_ovp, &open_file,
667 &open_dentry);
668 if ( S_ISREG(cnp->c_ovp->i_mode) ) {
669 /* Venus: we must read Venus dirents from the file */
670 result = coda_venus_readdir(&open_file, dirent, filldir);
671 } else {
672 /* potemkin case: we are handed a directory inode */
673 result = open_file.f_op->readdir(&open_file, dirent, filldir);
675 coda_restore_codafile(inode, file, cnp->c_ovp, &open_file);
676 return result;
677 EXIT;
680 /* ask venus to cache the file and return the inode of the container file,
681 put this inode pointer in the cnode for future read/writes */
682 int coda_open(struct inode *i, struct file *f)
684 ino_t ino;
685 dev_t dev;
686 struct coda_inode_info *cnp;
687 int error = 0;
688 struct inode *cont_inode = NULL;
689 unsigned short flags = f->f_flags & (~O_EXCL);
690 unsigned short coda_flags = coda_flags_to_cflags(flags);
692 ENTRY;
693 coda_vfs_stat.open++;
695 CDEBUG(D_SPECIAL, "OPEN inode number: %ld, count %d, flags %o.\n",
696 f->f_dentry->d_inode->i_ino, f->f_dentry->d_count, flags);
698 cnp = ITOC(i);
700 error = venus_open(i->i_sb, &(cnp->c_fid), coda_flags, &ino, &dev);
701 if (error) {
702 CDEBUG(D_FILE, "venus: dev %d, inode %ld, out->result %d\n",
703 dev, ino, error);
704 return error;
707 /* coda_upcall returns ino number of cached object, get inode */
708 CDEBUG(D_FILE, "cache file dev %d, ino %ld\n", dev, ino);
709 error = coda_inode_grab(dev, ino, &cont_inode);
711 if ( error || !cont_inode ){
712 printk("coda_open: coda_inode_grab error %d.", error);
713 if (cont_inode)
714 iput(cont_inode);
715 return error;
718 if ( cnp->c_ovp ) {
719 iput(cnp->c_ovp);
720 cnp->c_ovp = NULL;
722 cnp->c_ovp = cont_inode;
723 cnp->c_ocount++;
725 CDEBUG(D_FILE, "result %d, coda i->i_count is %d for ino %ld\n",
726 error, i->i_count, i->i_ino);
727 CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %x\n",
728 cnp->c_ovp->i_ino, cnp->c_ovp->i_count,
729 (int)(cnp->c_ovp->i_op));
730 EXIT;
731 return 0;
734 int coda_release(struct inode *i, struct file *f)
736 struct coda_inode_info *cnp;
737 int error;
738 unsigned short flags = (f->f_flags) & (~O_EXCL);
739 unsigned short cflags = coda_flags_to_cflags(flags);
741 ENTRY;
742 coda_vfs_stat.release++;
744 cnp =ITOC(i);
745 CHECK_CNODE(cnp);
746 CDEBUG(D_FILE,
747 "RELEASE coda (ino %ld, ct %d) cache (ino %ld, ct %d)\n",
748 i->i_ino, i->i_count, (cnp->c_ovp ? cnp->c_ovp->i_ino : 0),
749 (cnp->c_ovp ? cnp->c_ovp->i_count : -99));
752 /* even when c_ocount=0 we cannot put c_ovp to
753 * NULL since the file may be mmapped.
754 * See code in inode.c (coda_put_inode) for
755 * further handling of close.
758 --cnp->c_ocount;
760 if (flags & (O_WRONLY | O_RDWR)) {
761 --cnp->c_owrite;
764 error = venus_release(i->i_sb, &(cnp->c_fid), cflags);
766 CDEBUG(D_FILE, "coda_release: result: %d\n", error);
767 return error;
770 /* support routines */
772 * this structure is manipulated by filldir in vfs layer.
773 * the count holds the remaining amount of space in the getdents buffer,
774 * beyond the current_dir pointer.
777 struct getdents_callback {
778 struct linux_dirent * current_dir;
779 struct linux_dirent * previous;
780 int count;
781 int error;
784 static int coda_venus_readdir(struct file *filp, void *getdent,
785 filldir_t filldir)
787 int result = 0, offset, count, pos, error = 0;
788 int errfill;
789 caddr_t buff = NULL;
790 struct venus_dirent *vdirent;
791 struct getdents_callback *dents_callback;
792 int string_offset;
793 int size;
794 char debug[255];
796 ENTRY;
798 /* we also need the ofset of the string in the dirent struct */
799 string_offset = sizeof ( char )* 2 + sizeof(unsigned int) +
800 sizeof(unsigned short);
802 dents_callback = (struct getdents_callback *) getdent;
804 size = count = dents_callback->count;
805 CODA_ALLOC(buff, void *, size);
806 if ( ! buff ) {
807 printk("coda_venus_readdir: out of memory.\n");
808 return -ENOMEM;
811 /* we use this routine to read the file into our buffer */
812 result = read_exec(filp->f_dentry, filp->f_pos, buff, count, 1);
813 if ( result < 0) {
814 printk("coda_venus_readdir: cannot read directory %d.\n",
815 result);
816 error = result;
817 goto exit;
819 if ( result == 0) {
820 error = result;
821 goto exit;
824 /* Parse and write into user space. Filldir tells us when done! */
825 offset = filp->f_pos;
826 pos = 0;
827 CDEBUG(D_FILE, "offset %d, count %d.\n", offset, count);
829 while ( pos + string_offset < result ) {
830 vdirent = (struct venus_dirent *) (buff + pos);
832 /* test if the name is fully in the buffer */
833 if ( pos + string_offset + (int) vdirent->d_namlen >= result ){
834 break;
837 /* now we are certain that we can read the entry from buff */
839 /* for debugging, get the string out */
840 memcpy(debug, vdirent->d_name, vdirent->d_namlen);
841 *(debug + vdirent->d_namlen) = '\0';
843 /* if we don't have a null entry, copy it */
844 if ( vdirent->d_fileno ) {
845 int namlen = vdirent->d_namlen;
846 off_t offs = filp->f_pos;
847 ino_t ino = vdirent->d_fileno;
848 char *name = vdirent->d_name;
849 /* adjust count */
850 count = dents_callback->count;
852 errfill = filldir(dents_callback, name, namlen,
853 offs, ino);
854 CDEBUG(D_FILE, "ino %ld, namlen %d, reclen %d, type %d, pos %d, string_offs %d, name %s, offset %d, count %d.\n", vdirent->d_fileno, vdirent->d_namlen, vdirent->d_reclen, vdirent->d_type, pos, string_offset, debug, (u_int) offs, dents_callback->count);
856 /* errfill means no space for filling in this round */
857 if ( errfill < 0 ) break;
859 /* next one */
860 filp->f_pos += (unsigned int) vdirent->d_reclen;
861 pos += (unsigned int) vdirent->d_reclen;
864 exit:
865 CODA_FREE(buff, size);
866 return error;
869 /* called when a cache lookup succeeds */
870 static int coda_dentry_revalidate(struct dentry *de)
872 int valid = 1;
873 struct inode *inode = de->d_inode;
874 struct coda_inode_info *cii;
875 ENTRY;
877 if (inode) {
878 if (is_bad_inode(inode))
879 return 0;
880 cii = ITOC(de->d_inode);
881 if (cii->c_flags & C_PURGE)
882 valid = 0;
884 return valid || coda_isroot(de->d_inode);
888 * This is the callback from dput() when d_count is going to 0.
889 * We use this to unhash dentries with bad inodes.
891 static void coda_dentry_delete(struct dentry * dentry)
893 int flags;
895 if (!dentry->d_inode)
896 return ;
898 flags = (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
899 if (is_bad_inode(dentry->d_inode) || flags) {
900 CDEBUG(D_DOWNCALL, "bad inode, unhashing %s/%s, %ld\n",
901 dentry->d_parent->d_name.name, dentry->d_name.name,
902 dentry->d_inode->i_ino);
903 d_drop(dentry);
908 static int coda_refresh_inode(struct dentry *dentry)
910 struct coda_vattr attr;
911 int error;
912 int old_mode;
913 ino_t old_ino;
914 struct inode *inode = dentry->d_inode;
915 struct coda_inode_info *cii = ITOC(inode);
917 ENTRY;
919 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
920 if ( error ) {
921 make_bad_inode(inode);
922 return -EIO;
925 /* this inode may be lost if:
926 - it's type changed
927 - it's ino changed
929 old_mode = inode->i_mode;
930 old_ino = inode->i_ino;
931 coda_vattr_to_iattr(inode, &attr);
933 if ((inode->i_ino != old_ino) ||
934 ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT))) {
935 make_bad_inode(inode);
936 inode->i_mode = old_mode;
937 return -EIO;
940 cii->c_flags &= ~C_VATTR;
941 return 0;
946 * This is called when we want to check if the inode has
947 * changed on the server. Coda makes this easy since the
948 * cache manager Venus issues a downcall to the kernel when this
949 * happens
952 int coda_revalidate_inode(struct dentry *dentry)
954 int error = 0;
955 struct coda_inode_info *cii = ITOC(dentry->d_inode);
957 ENTRY;
958 CDEBUG(D_INODE, "revalidating: %*s/%*s\n",
959 dentry->d_name.len, dentry->d_name.name,
960 dentry->d_parent->d_name.len, dentry->d_parent->d_name.name);
962 if (cii->c_flags & (C_VATTR | C_PURGE)) {
963 error = coda_refresh_inode(dentry);
966 return error;