Import 2.1.81
[davej-history.git] / fs / nfsd / nfsfh.c
blob2cd24e78ffb7c6b10a490c238758d60bcddc9d14
1 /*
2 * linux/fs/nfsd/nfsfh.c
4 * NFS server filehandle treatment.
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */
9 #include <linux/sched.h>
10 #include <linux/malloc.h>
11 #include <linux/fs.h>
12 #include <linux/unistd.h>
13 #include <linux/string.h>
14 #include <linux/stat.h>
15 #include <linux/dcache.h>
17 #include <linux/sunrpc/svc.h>
18 #include <linux/nfsd/nfsd.h>
20 #define NFSDDBG_FACILITY NFSDDBG_FH
21 #define NFSD_PARANOIA 1
22 /* #define NFSD_DEBUG_VERBOSE 1 */
24 extern unsigned long num_physpages;
26 #define NFSD_FILE_CACHE 0
27 #define NFSD_DIR_CACHE 1
28 struct fh_entry {
29 struct dentry * dentry;
30 unsigned long reftime;
31 ino_t ino;
32 dev_t dev;
35 #define NFSD_MAXFH PAGE_SIZE/sizeof(struct fh_entry)
36 static struct fh_entry filetable[NFSD_MAXFH];
37 static struct fh_entry dirstable[NFSD_MAXFH];
39 static int nfsd_nr_verified = 0;
40 static int nfsd_nr_put = 0;
41 static unsigned long nfsd_next_expire = 0;
43 static int add_to_fhcache(struct dentry *, int);
44 static int nfsd_d_validate(struct dentry *);
45 struct dentry * lookup_inode(dev_t, ino_t, ino_t);
47 static LIST_HEAD(fixup_head);
48 static LIST_HEAD(path_inuse);
49 static int nfsd_nr_fixups = 0;
50 static int nfsd_nr_paths = 0;
51 #define NFSD_MAX_PATHS 500
52 #define NFSD_MAX_FIXUPAGE 60*HZ
54 struct nfsd_fixup {
55 struct list_head lru;
56 ino_t dir;
57 ino_t ino;
58 dev_t dev;
59 struct dentry *dentry;
60 unsigned long reftime;
63 struct nfsd_path {
64 struct list_head lru;
65 unsigned long reftime;
66 int users;
67 ino_t ino;
68 dev_t dev;
69 char name[1];
72 static struct nfsd_fixup * find_cached_lookup(dev_t dev, ino_t dir, ino_t ino)
74 struct list_head *tmp = fixup_head.next;
76 for (; tmp != &fixup_head; tmp = tmp->next) {
77 struct nfsd_fixup *fp;
79 fp = list_entry(tmp, struct nfsd_fixup, lru);
80 if (fp->ino != ino)
81 continue;
82 if (fp->dir != dir)
83 continue;
84 if (fp->dev != dev)
85 continue;
86 list_del(tmp);
87 list_add(tmp, &fixup_head);
88 fp->reftime = jiffies;
89 return fp;
91 return NULL;
95 * Save the dentry pointer from a successful lookup.
97 static void add_to_lookup_cache(struct dentry *dentry, struct knfs_fh *fh)
99 struct nfsd_fixup *fp;
101 fp = find_cached_lookup(fh->fh_dev, fh->fh_dirino, fh->fh_ino);
102 if (fp) {
103 fp->dentry = dentry;
104 return;
108 * Add a new entry. The small race here is unimportant:
109 * if another task adds the same lookup, both entries
110 * will be consistent.
112 fp = kmalloc(sizeof(struct nfsd_fixup), GFP_KERNEL);
113 if (fp) {
114 fp->dir = fh->fh_dirino;
115 fp->ino = fh->fh_ino;
116 fp->dev = fh->fh_dev;
117 fp->dentry = dentry;
118 fp->reftime = jiffies;
119 list_add(&fp->lru, &fixup_head);
120 nfsd_nr_fixups++;
124 static void free_fixup_entry(struct nfsd_fixup *fp)
126 list_del(&fp->lru);
127 kfree(fp);
128 nfsd_nr_fixups--;
132 * Copy a dentry's path into the specified buffer.
134 static int copy_path(char *buffer, struct dentry *dentry, int namelen)
136 char *p, *b = buffer;
137 int result = 0, totlen = 0, len;
139 while (1) {
140 struct dentry *parent;
141 dentry = dentry->d_covers;
142 parent = dentry->d_parent;
143 len = dentry->d_name.len;
144 p = (char *) dentry->d_name.name + len;
145 totlen += len;
146 if (totlen > namelen)
147 goto out;
148 while (len--)
149 *b++ = *(--p);
150 if (dentry == parent)
151 break;
152 dentry = parent;
153 totlen++;
154 if (totlen > namelen)
155 goto out;
156 *b++ = '/';
158 *b = 0;
161 * Now reverse in place ...
163 p = buffer;
164 while (p < b) {
165 char c = *(--b);
166 *b = *p;
167 *p++ = c;
169 result = 1;
170 out:
171 return result;
175 * Add a dentry's path to the path cache.
177 static int add_to_path_cache(struct dentry *dentry)
179 struct inode *inode = dentry->d_inode;
180 struct dentry *this;
181 struct nfsd_path *new;
182 int len, result = 0;
184 #ifdef NFSD_DEBUG_VERBOSE
185 printk("add_to_path_cache: cacheing %s/%s\n",
186 dentry->d_parent->d_name.name, dentry->d_name.name);
187 #endif
189 * Get the length of the full pathname.
191 restart:
192 len = 0;
193 this = dentry;
194 while (1) {
195 struct dentry *parent;
196 this = this->d_covers;
197 parent = this->d_parent;
198 len += this->d_name.len;
199 if (this == parent)
200 break;
201 this = parent;
202 len++;
205 * Allocate a structure to hold the path.
207 new = kmalloc(sizeof(struct nfsd_path) + len, GFP_KERNEL);
208 if (new) {
209 new->users = 0;
210 new->reftime = jiffies;
211 new->ino = inode->i_ino;
212 new->dev = inode->i_dev;
213 result = copy_path(new->name, dentry, len);
214 if (!result)
215 goto retry;
216 list_add(&new->lru, &path_inuse);
217 nfsd_nr_paths++;
218 #ifdef NFSD_DEBUG_VERBOSE
219 printk("add_to_path_cache: added %s, paths=%d\n", new->name, nfsd_nr_paths);
220 #endif
222 return result;
225 * If the dentry's path length changed, just try again ...
227 retry:
228 kfree(new);
229 printk("add_to_path_cache: path length changed, retrying\n");
230 goto restart;
234 * Search for a path entry for the specified (dev, inode).
236 struct nfsd_path *get_path_entry(dev_t dev, ino_t ino)
238 struct nfsd_path *pe;
239 struct list_head *tmp;
241 for (tmp = path_inuse.next; tmp != &path_inuse; tmp = tmp->next) {
242 pe = list_entry(tmp, struct nfsd_path, lru);
243 if (pe->ino != ino)
244 continue;
245 if (pe->dev != dev)
246 continue;
247 list_del(tmp);
248 list_add(tmp, &path_inuse);
249 pe->users++;
250 pe->reftime = jiffies;
251 #ifdef NFSD_PARANOIA
252 printk("get_path_entry: found %s for %s/%ld\n", pe->name, kdevname(dev), ino);
253 #endif
254 return pe;
256 return NULL;
259 static void put_path(struct nfsd_path *pe)
261 pe->users--;
264 static void free_path_entry(struct nfsd_path *pe)
266 if (pe->users)
267 printk("free_path_entry: %s in use, users=%d\n",
268 pe->name, pe->users);
269 list_del(&pe->lru);
270 kfree(pe);
271 nfsd_nr_paths--;
274 struct nfsd_getdents_callback {
275 struct nfsd_dirent *dirent;
276 ino_t dirino; /* parent inode number */
277 int found; /* dirent inode matched? */
278 int sequence; /* sequence counter */
281 struct nfsd_dirent {
282 ino_t ino; /* preset to desired entry */
283 int len;
284 char name[256];
288 * A rather strange filldir function to capture the inode number
289 * for the second entry (the parent inode) and the name matching
290 * the specified inode number.
292 static int filldir_one(void * __buf, const char * name, int len,
293 off_t pos, ino_t ino)
295 struct nfsd_getdents_callback *buf = __buf;
296 struct nfsd_dirent *dirent = buf->dirent;
297 int result = 0;
299 buf->sequence++;
300 #ifdef NFSD_DEBUG_VERBOSE
301 printk("filldir_one: seq=%d, ino=%ld, name=%s\n", buf->sequence, ino, name);
302 #endif
303 if (buf->sequence == 2) {
304 buf->dirino = ino;
305 goto out;
307 if (dirent->ino == ino) {
308 dirent->len = len;
309 memcpy(dirent->name, name, len);
310 dirent->name[len] = 0;
311 buf->found = 1;
312 result = -1;
314 out:
315 return result;
319 * Read a directory and return the parent inode number and the name
320 * of the specified entry. The dirent must be initialized with the
321 * inode number of the desired entry.
323 static int get_parent_ino(struct dentry *dentry, struct nfsd_dirent *dirent)
325 struct inode *dir = dentry->d_inode;
326 int error;
327 struct file file;
328 struct nfsd_getdents_callback buffer;
330 error = -ENOTDIR;
331 if (!dir || !S_ISDIR(dir->i_mode))
332 goto out;
333 error = -EINVAL;
334 if (!dir->i_op || !dir->i_op->default_file_ops)
335 goto out;
337 * Open the directory ...
339 error = init_private_file(&file, dentry, FMODE_READ);
340 if (error)
341 goto out;
342 error = -EINVAL;
343 if (!file.f_op->readdir)
344 goto out_close;
346 buffer.dirent = dirent;
347 buffer.dirino = 0;
348 buffer.found = 0;
349 buffer.sequence = 0;
350 while (1) {
351 int old_seq = buffer.sequence;
352 down(&dir->i_sem);
353 error = file.f_op->readdir(&file, &buffer, filldir_one);
354 up(&dir->i_sem);
355 if (error < 0)
356 break;
358 error = 0;
359 if (buffer.found)
360 break;
361 error = -ENOENT;
362 if (old_seq == buffer.sequence)
363 break;
365 dirent->ino = buffer.dirino;
367 out_close:
368 if (file.f_op->release)
369 file.f_op->release(dir, &file);
370 out:
371 return error;
375 * Look up a dentry given inode and parent inode numbers.
377 * This relies on the ability of a unix-like filesystem to return
378 * the parent inode of a directory as the ".." (second) entry.
380 * This could be further optimized if we had an efficient way of
381 * searching for a dentry given the inode: as we walk up the tree,
382 * it's likely that a dentry exists before we reach the root.
384 struct dentry * lookup_inode(dev_t dev, ino_t dirino, ino_t ino)
386 struct super_block *sb;
387 struct dentry *root, *dentry, *result;
388 struct inode *dir;
389 char *name;
390 unsigned long page;
391 ino_t root_ino;
392 int error;
393 struct nfsd_dirent dirent;
395 result = ERR_PTR(-ENOMEM);
396 page = __get_free_page(GFP_KERNEL);
397 if (!page)
398 goto out;
401 * Get the root dentry for the device.
403 result = ERR_PTR(-ENOENT);
404 sb = get_super(dev);
405 if (!sb)
406 goto out_page;
407 root = dget(sb->s_root);
408 root_ino = root->d_inode->i_ino; /* usually 2 */
410 name = (char *) page + PAGE_SIZE;
411 *(--name) = 0;
414 * Walk up the tree to construct the name string.
415 * When we reach the root inode, look up the name
416 * relative to the root dentry.
418 while (1) {
419 if (ino == root_ino) {
420 if (*name == '/')
421 name++;
423 * Note: this dput()s the root dentry.
425 result = lookup_dentry(name, root, 0);
426 break;
429 result = ERR_PTR(-ENOENT);
430 dir = iget(sb, dirino);
431 if (!dir)
432 goto out_root;
433 dentry = d_alloc_root(dir, NULL);
434 if (!dentry)
435 goto out_iput;
438 * Get the name for this inode and the next parent inode.
440 dirent.ino = ino;
441 error = get_parent_ino(dentry, &dirent);
442 result = ERR_PTR(error);
443 dput(dentry);
444 if (error)
445 goto out_root;
447 * Prepend the name to the buffer.
449 result = ERR_PTR(-ENAMETOOLONG);
450 name -= (dirent.len + 1);
451 if ((unsigned long) name <= page)
452 goto out_root;
453 memcpy(name + 1, dirent.name, dirent.len);
454 *name = '/';
457 * Make sure we can't get caught in a loop ...
459 if (dirino == dirent.ino && dirino != root_ino) {
460 printk("lookup_inode: looping?? (ino=%ld, path=%s)\n",
461 dirino, name);
462 goto out_root;
464 ino = dirino;
465 dirino = dirent.ino;
468 out_page:
469 free_page(page);
470 out:
471 return result;
474 * Error exits ...
476 out_iput:
477 result = ERR_PTR(-ENOMEM);
478 iput(dir);
479 out_root:
480 dput(root);
481 goto out;
485 * Find an entry in the cache matching the given dentry pointer.
487 static struct fh_entry *find_fhe(struct dentry *dentry, int cache,
488 struct fh_entry **empty)
490 struct fh_entry *fhe;
491 int i, found = (empty == NULL) ? 1 : 0;
493 fhe = (cache == NFSD_FILE_CACHE) ? &filetable[0] : &dirstable[0];
494 for (i = 0; i < NFSD_MAXFH; i++, fhe++) {
495 if (fhe->dentry == dentry) {
496 fhe->reftime = jiffies;
497 return fhe;
499 if (!found && !fhe->dentry) {
500 found = 1;
501 *empty = fhe;
504 return NULL;
508 * Expire a cache entry.
510 static void expire_fhe(struct fh_entry *empty, int cache)
512 struct dentry *dentry = empty->dentry;
514 #ifdef NFSD_DEBUG_VERBOSE
515 printk("expire_fhe: expiring %s/%s, d_count=%d, ino=%ld\n",
516 dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count,empty->ino);
517 #endif
518 empty->dentry = NULL; /* no dentry */
520 * Add the parent to the dir cache before releasing the dentry,
521 * and check whether to save a copy of the dentry's path.
523 if (dentry != dentry->d_parent) {
524 struct dentry *parent = dget(dentry->d_parent);
525 if (add_to_fhcache(parent, NFSD_DIR_CACHE))
526 nfsd_nr_verified++;
527 else
528 dput(parent);
530 * If we're expiring a directory, copy its path.
532 if (cache == NFSD_DIR_CACHE) {
533 add_to_path_cache(dentry);
536 dput(dentry);
537 nfsd_nr_put++;
541 * Look for an empty slot, or select one to expire.
543 static void expire_slot(int cache)
545 struct fh_entry *fhe, *empty = NULL;
546 unsigned long oldest = -1;
547 int i;
549 fhe = (cache == NFSD_FILE_CACHE) ? &filetable[0] : &dirstable[0];
550 for (i = 0; i < NFSD_MAXFH; i++, fhe++) {
551 if (!fhe->dentry)
552 goto out;
553 if (fhe->reftime < oldest) {
554 oldest = fhe->reftime;
555 empty = fhe;
558 if (empty)
559 expire_fhe(empty, cache);
561 out:
562 return;
566 * Expire any cache entries older than a certain age.
568 static void expire_old(int cache, int age)
570 struct list_head *tmp;
571 struct fh_entry *fhe;
572 int i;
574 #ifdef NFSD_DEBUG_VERBOSE
575 printk("expire_old: expiring %s older than %d\n",
576 (cache == NFSD_FILE_CACHE) ? "file" : "dir", age);
577 #endif
578 fhe = (cache == NFSD_FILE_CACHE) ? &filetable[0] : &dirstable[0];
579 for (i = 0; i < NFSD_MAXFH; i++, fhe++) {
580 if (!fhe->dentry)
581 continue;
582 if ((jiffies - fhe->reftime) > age)
583 expire_fhe(fhe, cache);
587 * Remove old entries from the patch-up cache.
589 while ((tmp = fixup_head.prev) != &fixup_head) {
590 struct nfsd_fixup *fp;
591 fp = list_entry(tmp, struct nfsd_fixup, lru);
592 if ((jiffies - fp->reftime) < NFSD_MAX_FIXUPAGE)
593 break;
594 free_fixup_entry(fp);
598 * Trim the path cache ...
600 while (nfsd_nr_paths > NFSD_MAX_PATHS) {
601 struct nfsd_path *pe;
602 pe = list_entry(path_inuse.prev, struct nfsd_path, lru);
603 if (pe->users)
604 break;
605 free_path_entry(pe);
610 * Add a dentry to the file or dir cache.
612 * Note: As NFS filehandles must have an inode, we don't accept
613 * negative dentries.
615 static int add_to_fhcache(struct dentry *dentry, int cache)
617 struct fh_entry *fhe, *empty = NULL;
618 struct inode *inode = dentry->d_inode;
620 if (!inode) {
621 #ifdef NFSD_PARANOIA
622 printk("add_to_fhcache: %s/%s rejected, no inode!\n",
623 dentry->d_parent->d_name.name, dentry->d_name.name);
624 #endif
625 return 0;
628 repeat:
629 fhe = find_fhe(dentry, cache, &empty);
630 if (fhe) {
631 return 0;
635 * Not found ... make a new entry.
637 if (empty) {
638 empty->dentry = dentry;
639 empty->reftime = jiffies;
640 empty->ino = inode->i_ino;
641 empty->dev = inode->i_dev;
642 return 1;
645 expire_slot(cache);
646 goto repeat;
650 * Find an entry in the dir cache for the specified inode number.
652 static struct fh_entry *find_fhe_by_ino(dev_t dev, ino_t ino)
654 struct fh_entry * fhe = &dirstable[0];
655 int i;
657 for (i = 0; i < NFSD_MAXFH; i++, fhe++) {
658 if (fhe->ino == ino && fhe->dev == dev) {
659 fhe->reftime = jiffies;
660 return fhe;
663 return NULL;
667 * Find the (directory) dentry with the specified (dev, inode) number.
668 * Note: this leaves the dentry in the cache.
670 static struct dentry *find_dentry_by_ino(dev_t dev, ino_t ino)
672 struct fh_entry *fhe;
673 struct nfsd_path *pe;
674 struct dentry * dentry;
676 #ifdef NFSD_DEBUG_VERBOSE
677 printk("find_dentry_by_ino: looking for inode %ld\n", ino);
678 #endif
680 * Special case: inode number 2 is the root inode,
681 * so we can use the root dentry for the device.
683 if (ino == 2) {
684 struct super_block *sb = get_super(dev);
685 if (sb) {
686 #ifdef NFSD_PARANOIA
687 printk("find_dentry_by_ino: getting root dentry for %s\n", kdevname(dev));
688 #endif
689 if (sb->s_root) {
690 dentry = dget(sb->s_root);
691 goto out;
692 } else {
693 #ifdef NFSD_PARANOIA
694 printk("find_dentry_by_ino: %s has no root??\n",
695 kdevname(dev));
696 #endif
702 * Search the dentry cache ...
704 fhe = find_fhe_by_ino(dev, ino);
705 if (fhe) {
706 dentry = dget(fhe->dentry);
707 goto out;
711 * Search the path cache ...
713 dentry = NULL;
714 pe = get_path_entry(dev, ino);
715 if (pe) {
716 struct dentry *res;
717 res = lookup_dentry(pe->name, NULL, 0);
718 if (!IS_ERR(res)) {
719 struct inode *inode = res->d_inode;
720 if (inode && inode->i_ino == ino &&
721 inode->i_dev == dev) {
722 dentry = res;
723 #ifdef NFSD_PARANOIA
724 printk("find_dentry_by_ino: found %s/%s, ino=%ld\n",
725 dentry->d_parent->d_name.name, dentry->d_name.name, ino);
726 #endif
727 if (add_to_fhcache(dentry, NFSD_DIR_CACHE)) {
728 dget(dentry);
729 nfsd_nr_verified++;
731 } else {
732 dput(res);
734 } else {
735 #ifdef NFSD_PARANOIA
736 printk("find_dentry_by_ino: %s lookup failed\n", pe->name);
737 #endif
739 put_path(pe);
741 out:
742 return dentry;
746 * Look for an entry in the file cache matching the dentry pointer,
747 * and verify that the (dev, inode) numbers are correct. If found,
748 * the entry is removed from the cache.
750 static struct dentry *find_dentry_in_fhcache(struct knfs_fh *fh)
752 struct fh_entry * fhe;
754 fhe = find_fhe(fh->fh_dcookie, NFSD_FILE_CACHE, NULL);
755 if (fhe) {
756 struct dentry *parent, *dentry = fhe->dentry;
757 struct inode *inode = dentry->d_inode;
758 if (!inode) {
759 #ifdef NFSD_PARANOIA
760 printk("find_dentry_in_fhcache: %s/%s has no inode!\n",
761 dentry->d_parent->d_name.name, dentry->d_name.name);
762 #endif
763 goto out;
765 if (inode->i_ino != fh->fh_ino || inode->i_dev != fh->fh_dev)
766 goto out;
768 fhe->dentry = NULL;
769 fhe->ino = 0;
770 fhe->dev = 0;
771 nfsd_nr_put++;
773 * Make sure the parent is in the dir cache ...
775 parent = dget(dentry->d_parent);
776 if (add_to_fhcache(parent, NFSD_DIR_CACHE))
777 nfsd_nr_verified++;
778 else
779 dput(parent);
780 return dentry;
782 out:
783 return NULL;
787 * Look for an entry in the parent directory with the specified
788 * inode number.
790 static struct dentry *lookup_by_inode(struct dentry *parent, ino_t ino)
792 struct dentry *dentry;
793 int error;
794 struct nfsd_dirent dirent;
797 * Search the directory for the inode number.
799 dirent.ino = ino;
800 error = get_parent_ino(parent, &dirent);
801 if (error) {
802 #ifdef NFSD_PARANOIA
803 printk("lookup_by_inode: ino %ld not found in %s\n", ino, parent->d_name.name);
804 #endif
805 goto no_entry;
807 #ifdef NFSD_PARANOIA
808 printk("lookup_by_inode: found %s\n", dirent.name);
809 #endif
811 dentry = lookup_dentry(dirent.name, dget(parent), 0);
812 if (!IS_ERR(dentry)) {
813 if (dentry->d_inode && dentry->d_inode->i_ino == ino)
814 goto out;
815 #ifdef NFSD_PARANOIA
816 printk("lookup_by_inode: %s/%s inode mismatch??\n",
817 parent->d_name.name, dentry->d_name.name);
818 #endif
819 dput(dentry);
820 } else {
821 #ifdef NFSD_PARANOIA
822 printk("lookup_by_inode: %s lookup failed, error=%ld\n",
823 dirent.name, PTR_ERR(dentry));
824 #endif
827 no_entry:
828 dentry = NULL;
829 out:
830 return dentry;
835 * Search the fix-up list for a dentry from a prior lookup.
837 static struct dentry *nfsd_cached_lookup(struct knfs_fh *fh)
839 struct nfsd_fixup *fp;
841 fp = find_cached_lookup(fh->fh_dev, fh->fh_dirino, fh->fh_ino);
842 if (fp)
843 return fp->dentry;
844 return NULL;
848 * The is the basic lookup mechanism for turning an NFS filehandle
849 * into a dentry. There are several levels to the search:
850 * (1) Look for the dentry pointer the short-term fhcache,
851 * and verify that it has the correct inode number.
853 * (2) Try to validate the dentry pointer in the filehandle,
854 * and verify that it has the correct inode number. If this
855 * fails, check for a cached lookup in the fix-up list and
856 * repeat step (2) using the new dentry pointer.
858 * (3) Look up the dentry by using the inode and parent inode numbers
859 * to build the name string. This should succeed for any unix-like
860 * filesystem.
862 * (4) Search for the parent dentry in the dir cache, and then
863 * look for the name matching the inode number.
865 * (5) The most general case ... search the whole volume for the inode.
867 * If successful, we return a dentry with the use count incremented.
869 * Note: steps (4) and (5) above are probably unnecessary now that (3)
870 * is working. Remove the code once this is verified ...
872 static struct dentry *
873 find_fh_dentry(struct knfs_fh *fh)
875 struct dentry *dentry, *parent;
876 int looked_up = 0, retry = 0;
879 * Stage 1: Look for the dentry in the short-term fhcache.
881 dentry = find_dentry_in_fhcache(fh);
882 if (dentry) {
883 nfsdstats.fh_cached++;
884 goto out;
888 * Stage 2: Attempt to validate the dentry in the filehandle.
890 dentry = fh->fh_dcookie;
891 recheck:
892 if (nfsd_d_validate(dentry)) {
893 struct inode * dir = dentry->d_parent->d_inode;
895 if (dir->i_ino == fh->fh_dirino && dir->i_dev == fh->fh_dev) {
896 struct inode * inode = dentry->d_inode;
898 * NFS filehandles must always have an inode,
899 * so we won't accept a negative dentry.
901 if (inode && inode->i_ino == fh->fh_ino) {
902 dget(dentry);
903 #ifdef NFSD_DEBUG_VERBOSE
904 printk("find_fh_dentry: validated %s/%s, ino=%ld\n",
905 dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_ino);
906 #endif
907 if (!retry)
908 nfsdstats.fh_valid++;
909 else {
910 nfsdstats.fh_fixup++;
911 #ifdef NFSD_DEBUG_VERBOSE
912 printk("find_fh_dentry: retried validation successful\n");
913 #endif
915 goto out;
921 * Before proceeding to a lookup, check whether we cached a
922 * prior lookup. If so, try to validate that dentry ...
924 if (!retry && (dentry = nfsd_cached_lookup(fh)) != NULL) {
925 retry = 1;
926 goto recheck;
930 * Stage 3: Look up the dentry based on the inode and parent inode
931 * numbers. This should work for all unix-like filesystems ...
933 looked_up = 1;
934 dentry = lookup_inode(fh->fh_dev, fh->fh_dirino, fh->fh_ino);
935 if (!IS_ERR(dentry)) {
936 struct inode * inode = dentry->d_inode;
937 #ifdef NFSD_DEBUG_VERBOSE
938 printk("find_fh_dentry: looked up %s/%s\n",
939 dentry->d_parent->d_name.name, dentry->d_name.name);
940 #endif
941 if (inode && inode->i_ino == fh->fh_ino) {
942 nfsdstats.fh_lookup++;
943 goto out;
945 #ifdef NFSD_PARANOIA
946 printk("find_fh_dentry: %s/%s lookup mismatch!\n",
947 dentry->d_parent->d_name.name, dentry->d_name.name);
948 #endif
949 dput(dentry);
953 * Stage 4: Look for the parent dentry in the fhcache ...
955 parent = find_dentry_by_ino(fh->fh_dev, fh->fh_dirino);
956 if (parent) {
958 * ... then search for the inode in the parent directory.
960 dentry = lookup_by_inode(parent, fh->fh_ino);
961 dput(parent);
962 if (dentry)
963 goto out;
967 * Stage 5: Search the whole volume.
969 #ifdef NFSD_PARANOIA
970 printk("find_fh_dentry: %s, %ld/%ld not found -- need full search!\n",
971 kdevname(fh->fh_dev), fh->fh_dirino, fh->fh_ino);
972 #endif
973 dentry = NULL;
974 nfsdstats.fh_stale++;
976 out:
977 if (looked_up && dentry) {
978 add_to_lookup_cache(dentry, fh);
982 * Perform any needed housekeeping ...
983 * N.B. move this into one of the daemons ...
985 if (jiffies >= nfsd_next_expire) {
986 expire_old(NFSD_FILE_CACHE, 5*HZ);
987 expire_old(NFSD_DIR_CACHE , 60*HZ);
988 nfsd_next_expire = jiffies + 5*HZ;
990 return dentry;
994 * Perform sanity checks on the dentry in a client's file handle.
996 * Note that the filehandle dentry may need to be freed even after
997 * an error return.
1000 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
1002 struct knfs_fh *fh = &fhp->fh_handle;
1003 struct svc_export *exp;
1004 struct dentry *dentry;
1005 struct inode *inode;
1006 u32 error = 0;
1008 dprintk("nfsd: fh_verify(exp %x/%ld cookie %p)\n",
1009 fh->fh_xdev, fh->fh_xino, fh->fh_dcookie);
1011 if(fhp->fh_dverified)
1012 goto check_type;
1014 * Look up the export entry.
1016 error = nfserr_stale;
1017 exp = exp_get(rqstp->rq_client, fh->fh_xdev, fh->fh_xino);
1018 if (!exp) /* export entry revoked */
1019 goto out;
1021 /* Check if the request originated from a secure port. */
1022 error = nfserr_perm;
1023 if (!rqstp->rq_secure && EX_SECURE(exp)) {
1024 printk(KERN_WARNING
1025 "nfsd: request from insecure port (%08lx:%d)!\n",
1026 ntohl(rqstp->rq_addr.sin_addr.s_addr),
1027 ntohs(rqstp->rq_addr.sin_port));
1028 goto out;
1031 /* Set user creds if we haven't done so already. */
1032 nfsd_setuser(rqstp, exp);
1035 * Look up the dentry using the NFS fh.
1037 error = nfserr_stale;
1038 dentry = find_fh_dentry(fh);
1039 if (!dentry)
1040 goto out;
1042 * Note: it's possible that the returned dentry won't be the
1043 * one in the filehandle. We can correct the FH for our use,
1044 * but unfortunately the client will keep sending the broken
1045 * one. Hopefully the lookup will keep patching things up..
1047 fhp->fh_dentry = dentry;
1048 fhp->fh_export = exp;
1049 fhp->fh_dverified = 1;
1050 nfsd_nr_verified++;
1052 /* Type check. The correct error return for type mismatches
1053 * does not seem to be generally agreed upon. SunOS seems to
1054 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
1055 * spec says this is incorrect (implementation notes for the
1056 * write call).
1058 check_type:
1059 dentry = fhp->fh_dentry;
1060 inode = dentry->d_inode;
1061 if (type > 0 && (inode->i_mode & S_IFMT) != type) {
1062 error = (type == S_IFDIR)? nfserr_notdir : nfserr_isdir;
1063 goto out;
1065 if (type < 0 && (inode->i_mode & S_IFMT) == -type) {
1066 error = (type == -S_IFDIR)? nfserr_notdir : nfserr_isdir;
1067 goto out;
1070 /* Finally, check access permissions. */
1071 error = nfsd_permission(fhp->fh_export, dentry, access);
1072 #ifdef NFSD_PARANOIA
1073 if (error)
1074 printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n",
1075 dentry->d_parent->d_name.name, dentry->d_name.name, access, error);
1076 #endif
1078 out:
1079 return error;
1083 * Compose a filehandle for an NFS reply.
1085 * Note that when first composed, the dentry may not yet have
1086 * an inode. In this case a call to fh_update should be made
1087 * before the fh goes out on the wire ...
1089 void
1090 fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry)
1092 struct inode * inode = dentry->d_inode;
1094 dprintk("nfsd: fh_compose(exp %x/%ld %s/%s, ino=%ld)\n",
1095 exp->ex_dev, exp->ex_ino,
1096 dentry->d_parent->d_name.name, dentry->d_name.name,
1097 (inode ? inode->i_ino : 0));
1100 * N.B. We shouldn't need to init the fh -- the call to fh_compose
1101 * may not be done on error paths, but the cleanup must call fh_put.
1102 * Fix this soon!
1104 fh_init(fhp);
1105 fhp->fh_handle.fh_dcookie = dentry;
1106 if (inode) {
1107 fhp->fh_handle.fh_ino = inode->i_ino;
1109 fhp->fh_handle.fh_dirino = dentry->d_parent->d_inode->i_ino;
1110 fhp->fh_handle.fh_dev = dentry->d_parent->d_inode->i_dev;
1111 fhp->fh_handle.fh_xdev = exp->ex_dev;
1112 fhp->fh_handle.fh_xino = exp->ex_ino;
1114 fhp->fh_dentry = dentry; /* our internal copy */
1115 fhp->fh_export = exp;
1117 /* We stuck it there, we know it's good. */
1118 fhp->fh_dverified = 1;
1119 nfsd_nr_verified++;
1123 * Update filehandle information after changing a dentry.
1125 void
1126 fh_update(struct svc_fh *fhp)
1128 struct dentry *dentry;
1129 struct inode *inode;
1131 if (!fhp->fh_dverified) {
1132 printk("fh_update: fh not verified!\n");
1133 goto out;
1136 dentry = fhp->fh_dentry;
1137 inode = dentry->d_inode;
1138 if (!inode) {
1139 printk("fh_update: %s/%s still negative!\n",
1140 dentry->d_parent->d_name.name, dentry->d_name.name);
1141 goto out;
1143 fhp->fh_handle.fh_ino = inode->i_ino;
1144 out:
1145 return;
1149 * Release a filehandle. If the filehandle carries a dentry count,
1150 * we add the dentry to the short-term cache rather than release it.
1152 void
1153 fh_put(struct svc_fh *fhp)
1155 if (fhp->fh_dverified) {
1156 struct dentry * dentry = fhp->fh_dentry;
1157 fh_unlock(fhp);
1158 fhp->fh_dverified = 0;
1159 if (!dentry->d_count) {
1160 printk("fh_put: %s/%s has d_count 0!\n",
1161 dentry->d_parent->d_name.name, dentry->d_name.name);
1162 return;
1164 if (!dentry->d_inode || !add_to_fhcache(dentry, 0)) {
1165 dput(dentry);
1166 nfsd_nr_put++;
1172 * Verify that the FH dentry is still a valid dentry pointer.
1173 * After making some preliminary checks, we ask VFS to verify
1174 * that it is indeed a dentry.
1176 static int nfsd_d_validate(struct dentry *dentry)
1178 unsigned long dent_addr = (unsigned long) dentry;
1179 unsigned long min_addr = PAGE_OFFSET;
1180 unsigned long max_addr = min_addr + (num_physpages << PAGE_SHIFT);
1181 unsigned long align_mask = 0x0F;
1182 unsigned int len;
1183 int valid = 0;
1185 if (dent_addr < min_addr)
1186 goto bad_addr;
1187 if (dent_addr > max_addr - sizeof(struct dentry))
1188 goto bad_addr;
1189 if ((dent_addr & ~align_mask) != dent_addr)
1190 goto bad_align;
1192 * Looks safe enough to dereference ...
1194 len = dentry->d_name.len;
1195 if (len > NFS_MAXNAMLEN)
1196 goto out;
1198 * Note: d_validate doesn't dereference the parent pointer ...
1199 * just combines it with the name hash to find the hash chain.
1201 valid = d_validate(dentry, dentry->d_parent, dentry->d_name.hash, len);
1203 out:
1204 return valid;
1206 bad_addr:
1207 printk("nfsd_d_validate: invalid address %lx\n", dent_addr);
1208 goto out;
1209 bad_align:
1210 printk("nfsd_d_validate: unaligned address %lx\n", dent_addr);
1211 goto out;
1215 * Flush any cached dentries for the specified device
1216 * or for all devices.
1218 * This is called when revoking the last export for a
1219 * device, so that it can be unmounted cleanly.
1221 void nfsd_fh_flush(dev_t dev)
1223 struct fh_entry *fhe;
1224 int i, pass = 2;
1226 fhe = &filetable[0];
1227 while (pass--) {
1228 for (i = 0; i < NFSD_MAXFH; i++, fhe++) {
1229 struct dentry *dentry = fhe->dentry;
1230 if (!dentry)
1231 continue;
1232 if (dev && dentry->d_inode->i_dev != dev)
1233 continue;
1234 fhe->dentry = NULL;
1235 dput(dentry);
1236 nfsd_nr_put++;
1238 fhe = &dirstable[0];
1243 * Free the dentry and path caches.
1245 void nfsd_fh_free(void)
1247 struct list_head *tmp;
1248 int i;
1250 /* Flush dentries for all devices */
1251 nfsd_fh_flush(0);
1254 * N.B. write a destructor for these lists ...
1256 i = 0;
1257 while ((tmp = fixup_head.next) != &fixup_head) {
1258 struct nfsd_fixup *fp;
1259 fp = list_entry(tmp, struct nfsd_fixup, lru);
1260 free_fixup_entry(fp);
1261 i++;
1263 printk("nfsd_fh_free: %d fixups freed\n", i);
1265 i = 0;
1266 while ((tmp = path_inuse.next) != &path_inuse) {
1267 struct nfsd_path *pe;
1268 pe = list_entry(tmp, struct nfsd_path, lru);
1269 free_path_entry(pe);
1270 i++;
1272 printk("nfsd_fh_free: %d paths freed\n", i);
1274 printk("nfsd_fh_free: verified %d, put %d\n",
1275 nfsd_nr_verified, nfsd_nr_put);
1278 void nfsd_fh_init(void)
1280 memset(filetable, 0, NFSD_MAXFH*sizeof(struct fh_entry));
1281 memset(dirstable, 0, NFSD_MAXFH*sizeof(struct fh_entry));
1282 INIT_LIST_HEAD(&path_inuse);
1283 INIT_LIST_HEAD(&fixup_head);
1285 printk("nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH);