1 diff -uprN linux/fs/Makefile linux-2.4.20/fs/Makefile
2 --- linux/fs/Makefile Sun Oct 5 21:52:51 2003
3 +++ linux-2.4.20/fs/Makefile Sun Oct 5 21:47:45 2003
8 -export-objs := filesystems.o open.o dcache.o buffer.o inode.o
9 +export-objs := filesystems.o open.o dcache.o buffer.o inode.o namei.o \
13 obj-y := open.o read_write.o devices.o file_table.o buffer.o \
14 diff -uprN linux/fs/file_table.c linux-2.4.20/fs/file_table.c
15 --- linux/fs/file_table.c Fri Nov 29 05:23:15 2002
16 +++ linux-2.4.20/fs/file_table.c Sun Oct 5 21:47:45 2003
17 @@ -82,7 +82,8 @@ struct file * get_empty_filp(void)
18 * and call the open function (if any). The caller must verify that
19 * inode->i_fop is not NULL.
21 -int init_private_file(struct file *filp, struct dentry *dentry, int mode)
22 +int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
23 + struct lookup_intent *it)
25 memset(filp, 0, sizeof(*filp));
27 @@ -90,12 +91,20 @@ int init_private_file(struct file *filp,
28 filp->f_dentry = dentry;
29 filp->f_uid = current->fsuid;
30 filp->f_gid = current->fsgid;
33 filp->f_op = dentry->d_inode->i_fop;
35 return filp->f_op->open(dentry->d_inode, filp);
39 +EXPORT_SYMBOL(init_private_file_it);
41 +int init_private_file(struct file *filp, struct dentry *dentry, int mode)
43 + return init_private_file_it(filp, dentry, mode, NULL);
46 void fput(struct file * file)
48 diff -uprN linux/fs/inode.c linux-2.4.20/fs/inode.c
49 --- linux/fs/inode.c Sun Oct 5 21:52:49 2003
50 +++ linux-2.4.20/fs/inode.c Sun Oct 5 21:47:45 2003
51 @@ -970,9 +970,10 @@ struct inode *igrab(struct inode *inode)
55 -struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
56 +static inline struct inode *ifind(struct super_block *sb, unsigned long ino,
57 + struct list_head *head,
58 + find_inode_t find_actor, void *opaque)
60 - struct list_head * head = inode_hashtable + hash(sb,ino);
63 spin_lock(&inode_lock);
64 @@ -985,6 +986,24 @@ struct inode *iget4(struct super_block *
66 spin_unlock(&inode_lock);
71 +struct inode *ilookup4(struct super_block *sb, unsigned long ino,
72 + find_inode_t find_actor, void *opaque)
74 + struct list_head * head = inode_hashtable + hash(sb,ino);
75 + return ifind(sb, ino, head, find_actor, opaque);
78 +struct inode *iget4(struct super_block *sb, unsigned long ino,
79 + find_inode_t find_actor, void *opaque)
81 + struct list_head * head = inode_hashtable + hash(sb,ino);
82 + struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
87 * get_new_inode() will do the right thing, re-trying the search
88 * in case it had to block at any point.
89 diff -uprN linux/fs/namei.c linux-2.4.20/fs/namei.c
90 --- linux/fs/namei.c Sun Oct 5 21:52:48 2003
91 +++ linux-2.4.20/fs/namei.c Sun Oct 5 21:47:45 2003
93 #include <linux/dnotify.h>
94 #include <linux/smp_lock.h>
95 #include <linux/personality.h>
96 +#include <linux/module.h>
98 #include <asm/namei.h>
99 #include <asm/uaccess.h>
100 @@ -100,6 +101,7 @@ void intent_release(struct lookup_intent
101 it->it_op_release(it);
104 +EXPORT_SYMBOL(intent_release);
106 /* In order to reduce some races, while at the same time doing additional
107 * checking and hopefully speeding things up, we copy filenames to the
108 @@ -900,7 +902,8 @@ struct dentry * lookup_hash(struct qstr
112 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
113 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
114 + int len, struct lookup_intent *it)
118 @@ -920,11 +923,16 @@ struct dentry * lookup_one_len(const cha
120 this.hash = end_name_hash(hash);
122 - return lookup_hash_it(&this, base, NULL, NULL);
123 + return lookup_hash_it(&this, base, NULL, it);
125 return ERR_PTR(-EACCES);
128 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
130 + return lookup_one_len_it(name, base, len, NULL);
136 diff -uprN linux/fs/nfsd/export.c linux-2.4.20/fs/nfsd/export.c
137 --- linux/fs/nfsd/export.c Fri Nov 29 05:23:15 2002
138 +++ linux-2.4.20/fs/nfsd/export.c Sun Oct 5 22:25:20 2003
139 @@ -222,6 +222,11 @@ exp_export(struct nfsctl_export *nxp)
140 inode = nd.dentry->d_inode;
143 + if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
144 + !(nxp->ex_flags & NFSEXP_FSID)) {
145 + nxp->ex_dev = inode->i_sb->s_dev;
146 + nxp->ex_flags |= NFSEXP_FSID;
150 exp = exp_get(clp, dev, ino);
151 diff -uprN linux/fs/nfsd/nfsfh.c linux-2.4.20/fs/nfsd/nfsfh.c
152 --- linux/fs/nfsd/nfsfh.c Fri Nov 29 05:23:15 2002
153 +++ linux-2.4.20/fs/nfsd/nfsfh.c Sun Oct 5 21:47:45 2003
154 @@ -36,6 +36,15 @@ struct nfsd_getdents_callback {
155 int sequence; /* sequence counter */
158 +static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
160 + if (inode->i_op->lookup_it)
161 + return inode->i_op->lookup_it(inode, dentry, NULL, NULL, 0);
163 + return inode->i_op->lookup(inode, dentry);
168 * A rather strange filldir function to capture
169 * the name matching the specified inode number.
170 @@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry *
173 struct nfsd_getdents_callback buffer;
174 + struct lookup_intent it;
175 + struct file *filp = NULL;
178 if (!dir || !S_ISDIR(dir->i_mode))
179 @@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry *
181 * Open the directory ...
183 - error = init_private_file(&file, dentry, FMODE_READ);
185 + if (dentry->d_op && dentry->d_op->d_revalidate_it) {
186 + if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
187 + (dentry->d_parent == dentry) ) {
188 + it.it_op_release = NULL;
190 + * XXX Temporary Hack: Simulating init_private_file without
191 + * f_op->open for disconnected dentry Since we don't have actual
192 + * dentry->d_name to revalidate in revalidate_it()
195 + memset(filp, 0, sizeof(*filp));
196 + filp->f_mode = FMODE_READ;
197 + atomic_set(&filp->f_count, 1);
198 + filp->f_dentry = dentry;
199 + filp->f_uid = current->fsuid;
200 + filp->f_gid = current->fsgid;
201 + filp->f_op = dentry->d_inode->i_fop;
204 + intent_init(&it, IT_OPEN, 0);
205 + error = revalidate_it(dentry, &it);
208 + error = init_private_file_it(&file, dentry, FMODE_READ, &it);
211 + error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
217 if (!file.f_op->readdir)
219 @@ -113,9 +152,13 @@ static int nfsd_get_name(struct dentry *
223 - if (file.f_op->release)
224 + if (file.f_op->release && !filp)
225 file.f_op->release(dir, &file);
227 + if (dentry->d_op &&
228 + dentry->d_op->d_revalidate_it &&
229 + it.it_op_release && !filp)
230 + intent_release(&it);
234 @@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de
235 * it is well connected. But nobody returns different dentrys do they?
237 down(&child->d_inode->i_sem);
238 - pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
239 + pdentry = lookup_it(child->d_inode, tdentry);
240 up(&child->d_inode->i_sem);
241 d_drop(tdentry); /* we never want ".." hashed */
242 if (!pdentry && tdentry->d_inode == NULL) {
243 @@ -306,6 +349,8 @@ struct dentry *nfsd_findparent(struct de
244 igrab(tdentry->d_inode);
245 pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
247 + if (child->d_op && child->d_op->d_revalidate_it)
248 + pdentry->d_op = child->d_op;
251 pdentry = ERR_PTR(-ENOMEM);
252 @@ -463,6 +508,8 @@ find_fh_dentry(struct super_block *sb, _
253 struct dentry *pdentry;
254 struct inode *parent;
256 + if (result->d_op && result->d_op->d_revalidate_it)
257 + dentry->d_op = result->d_op;
258 pdentry = nfsd_findparent(dentry);
259 err = PTR_ERR(pdentry);
261 @@ -662,6 +709,11 @@ fh_verify(struct svc_rqst *rqstp, struct
263 inode = dentry->d_inode;
265 + /* cache coherency for non-device filesystems */
266 + if (inode->i_op && inode->i_op->revalidate_it) {
267 + inode->i_op->revalidate_it(dentry, NULL);
270 /* Type check. The correct error return for type mismatches
271 * does not seem to be generally agreed upon. SunOS seems to
272 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
273 @@ -900,8 +952,9 @@ out_negative:
274 dentry->d_parent->d_name.name, dentry->d_name.name);
277 - printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
278 - dentry->d_parent->d_name.name, dentry->d_name.name);
279 + if(!dentry->d_parent->d_inode->i_op->mkdir_raw)
280 + printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
281 + dentry->d_parent->d_name.name, dentry->d_name.name);
285 diff -uprN linux/fs/nfsd/vfs.c linux-2.4.20/fs/nfsd/vfs.c
286 --- linux/fs/nfsd/vfs.c Fri Nov 29 05:23:15 2002
287 +++ linux-2.4.20/fs/nfsd/vfs.c Sun Oct 5 21:47:45 2003
288 @@ -77,6 +77,128 @@ struct raparms {
289 static struct raparms * raparml;
290 static struct raparms * raparm_cache;
292 +static int link_raw(struct dentry *dold, struct dentry *ddir,
293 + struct dentry *dnew)
297 + struct nameidata old_nd = { .dentry = dold };
298 + struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
299 + struct inode_operations *op = nd.dentry->d_inode->i_op;
300 + err = op->link_raw(&old_nd, &nd);
301 + d_instantiate(dnew, dold->d_inode);
302 + if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
303 + dold->d_inode->i_op->revalidate_it(dnew, NULL);
308 +static int unlink_raw(struct dentry *dentry, char *fname, int flen,
309 + struct dentry *rdentry)
312 + struct qstr last = { .name = fname, .len = flen };
313 + struct nameidata nd = { .dentry = dentry, .last = last };
314 + struct inode_operations *op = nd.dentry->d_inode->i_op;
315 + err = op->unlink_raw(&nd);
322 +static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
323 + struct dentry *rdentry)
326 + struct qstr last = { .name = fname, .len = flen };
327 + struct nameidata nd = { .dentry = dentry, .last = last };
328 + struct inode_operations *op = nd.dentry->d_inode->i_op;
329 + err = op->rmdir_raw(&nd);
331 + rdentry->d_inode->i_flags |= S_DEAD;
338 +static int symlink_raw(struct dentry *dentry, char *fname, int flen,
342 + struct qstr last = { .name = fname, .len = flen };
343 + struct nameidata nd = { .dentry = dentry, .last = last };
344 + struct inode_operations *op = nd.dentry->d_inode->i_op;
345 + err = op->symlink_raw(&nd, path);
350 +static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
353 + struct qstr last = { .name = fname, .len = flen };
354 + struct nameidata nd = { .dentry = dentry, .last = last };
355 + struct inode_operations *op = nd.dentry->d_inode->i_op;
356 + err = op->mkdir_raw(&nd, mode);
361 +static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
365 + struct qstr last = { .name = fname, .len = flen };
366 + struct nameidata nd = { .dentry = dentry, .last = last };
367 + struct inode_operations *op = nd.dentry->d_inode->i_op;
368 + err = op->mknod_raw(&nd, mode, dev);
373 +static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
374 + struct dentry *odentry, struct dentry *ndentry)
378 + struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
379 + struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
380 + struct inode_operations *op = old_nd.dentry->d_inode->i_op;
381 + err = op->rename_raw(&old_nd, &new_nd);
382 + d_move(odentry, ndentry);
387 +static int setattr_raw(struct inode *inode, struct iattr *iap)
391 + iap->ia_valid |= ATTR_RAW;
392 + err = inode->i_op->setattr_raw(inode, iap);
397 +int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
401 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
402 + if (!dentry->d_op->d_revalidate_it(dentry, 0, NULL, it) &&
403 + !d_invalidate(dentry)) {
415 * Look up one component of a pathname.
416 * N.B. After this call _both_ fhp and resfh need an fh_put
417 @@ -300,7 +422,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str
419 err = nfserr_notsync;
420 if (!check_guard || guardtime == inode->i_ctime) {
421 - err = notify_change(dentry, iap);
422 + if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
423 + err = setattr_raw(dentry->d_inode, iap);
425 + err = notify_change(dentry, iap);
429 @@ -427,6 +552,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
431 struct dentry *dentry;
433 + struct lookup_intent it;
436 /* If we get here, then the client has already done an "open", and (hopefully)
437 @@ -473,6 +599,14 @@ nfsd_open(struct svc_rqst *rqstp, struct
438 filp->f_mode = FMODE_READ;
441 + intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode);
443 + err = revalidate_it(dentry, &it);
450 if (filp->f_op && filp->f_op->open) {
451 err = filp->f_op->open(inode, filp);
452 @@ -487,7 +621,11 @@ nfsd_open(struct svc_rqst *rqstp, struct
453 atomic_dec(&filp->f_count);
458 + if (it.it_op_release)
459 + intent_release(&it);
464 @@ -818,7 +956,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
466 struct dentry *dentry, *dchild;
469 + int err, error = -EOPNOTSUPP;
473 @@ -834,20 +972,44 @@ nfsd_create(struct svc_rqst *rqstp, stru
474 dentry = fhp->fh_dentry;
475 dirp = dentry->d_inode;
479 + if (dirp->i_op->mkdir_raw)
480 + error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
487 + if (dirp->i_op->mknod_raw) {
488 + if (type == S_IFREG)
490 + error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev);
494 + printk("nfsd: bad file type %o in nfsd_create\n", type);
498 - if(!dirp->i_op || !dirp->i_op->lookup)
499 + if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
502 * Check whether the response file handle has been verified yet.
503 * If it has, the parent directory should already be locked.
505 - if (!resfhp->fh_dentry) {
506 - /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
508 + if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
509 + /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
510 + and nfsd_proc_create in case of lustre
512 + if (!resfhp->fh_dentry)
514 dchild = lookup_one_len(fname, dentry, flen);
515 err = PTR_ERR(dchild);
518 + resfhp->fh_dentry = NULL;
519 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
522 @@ -868,10 +1030,12 @@ nfsd_create(struct svc_rqst *rqstp, stru
523 * Make sure the child dentry is still negative ...
526 - if (dchild->d_inode) {
527 - dprintk("nfsd_create: dentry %s/%s not negative!\n",
528 - dentry->d_name.name, dchild->d_name.name);
530 + if ( error == -EOPNOTSUPP) {
531 + if (dchild->d_inode) {
532 + dprintk("nfsd_create: dentry %s/%s not negative!\n",
533 + dentry->d_name.name, dchild->d_name.name);
538 if (!(iap->ia_valid & ATTR_MODE))
539 @@ -884,16 +1048,19 @@ nfsd_create(struct svc_rqst *rqstp, stru
543 - err = vfs_create(dirp, dchild, iap->ia_mode);
544 + if (error == -EOPNOTSUPP)
545 + err = vfs_create(dirp, dchild, iap->ia_mode);
548 - err = vfs_mkdir(dirp, dchild, iap->ia_mode);
549 + if (error == -EOPNOTSUPP)
550 + err = vfs_mkdir(dirp, dchild, iap->ia_mode);
556 - err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
557 + if (error == -EOPNOTSUPP)
558 + err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
561 printk("nfsd: bad file type %o in nfsd_create\n", type);
562 @@ -962,7 +1129,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
563 /* Get all the sanity checks out of the way before
564 * we lock the parent. */
566 - if(!dirp->i_op || !dirp->i_op->lookup)
567 + if (dirp->i_op->mknod_raw) {
568 + err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
569 + if (err && err != -EOPNOTSUPP)
573 + if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
577 @@ -1013,6 +1186,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
578 case NFS3_CREATE_GUARDED:
581 + if(dirp->i_op->mknod_raw)
586 @@ -1119,7 +1294,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
589 struct dentry *dentry, *dnew;
591 + int err, cerr, error = -EOPNOTSUPP;
595 @@ -1133,12 +1308,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str
598 dentry = fhp->fh_dentry;
600 + if (dentry->d_inode->i_op->symlink_raw)
601 + error = symlink_raw(dentry, fname, flen, path);
603 dnew = lookup_one_len(fname, dentry, flen);
608 - err = vfs_symlink(dentry->d_inode, dnew, path);
610 + if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
611 + err = vfs_symlink(dentry->d_inode, dnew, path);
613 if (EX_ISSYNC(fhp->fh_export))
614 nfsd_sync_dir(dentry);
615 @@ -1148,7 +1329,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str
616 iap->ia_valid |= ATTR_CTIME;
617 iap->ia_mode = (iap->ia_mode&S_IALLUGO)
619 - err = notify_change(dnew, iap);
620 + if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
621 + err = setattr_raw(dnew->d_inode, iap);
623 + err = notify_change(dnew, iap);
624 if (!err && EX_ISSYNC(fhp->fh_export))
625 write_inode_now(dentry->d_inode, 1);
627 @@ -1206,7 +1390,10 @@ nfsd_link(struct svc_rqst *rqstp, struct
628 dold = tfhp->fh_dentry;
629 dest = dold->d_inode;
631 - err = vfs_link(dold, dirp, dnew);
632 + if (dirp->i_op->link_raw)
633 + err = link_raw(dold, ddir, dnew);
635 + err = vfs_link(dold, dirp, dnew);
637 if (EX_ISSYNC(ffhp->fh_export)) {
639 @@ -1291,7 +1478,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru
643 - err = vfs_rename(fdir, odentry, tdir, ndentry);
644 + if(fdir->i_op->rename_raw)
645 + err = rename_raw(fdentry, tdentry, odentry, ndentry);
647 + err = vfs_rename(fdir, odentry, tdir, ndentry);
648 if (!err && EX_ISSYNC(tfhp->fh_export)) {
649 nfsd_sync_dir(tdentry);
650 nfsd_sync_dir(fdentry);
651 @@ -1312,7 +1502,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
653 double_up(&tdir->i_sem, &fdir->i_sem);
654 ffhp->fh_locked = tfhp->fh_locked = 0;
660 @@ -1358,9 +1548,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
664 - err = vfs_unlink(dirp, rdentry);
665 + if (dirp->i_op->unlink_raw)
666 + err = unlink_raw(dentry, fname, flen, rdentry);
668 + err = vfs_unlink(dirp, rdentry);
669 } else { /* It's RMDIR */
670 - err = vfs_rmdir(dirp, rdentry);
671 + if (dirp->i_op->rmdir_raw)
672 + err = rmdir_raw(dentry, fname, flen, rdentry);
674 + err = vfs_rmdir(dirp, rdentry);
678 diff -uprN linux/include/linux/fs.h linux-2.4.20/include/linux/fs.h
679 --- linux/include/linux/fs.h Sun Oct 5 21:52:56 2003
680 +++ linux-2.4.20/include/linux/fs.h Sun Oct 5 22:25:20 2003
681 @@ -93,6 +93,9 @@ extern int leases_enable, dir_notify_ena
682 #define FS_SINGLE 8 /* Filesystem that can have only one superblock */
683 #define FS_NOMOUNT 16 /* Never mount from userland */
684 #define FS_LITTER 32 /* Keeps the tree in dcache */
685 +#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
686 + * exporting non device filesystems.
688 #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon
689 * as nfs_rename() will be cleaned up
691 @@ -1099,6 +1102,9 @@ extern int open_namei_it(const char *fil
692 struct nameidata *nd, struct lookup_intent *it);
693 extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
694 int flags, struct lookup_intent *it);
695 +extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
696 +extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
697 + struct lookup_intent *it);
698 extern int filp_close(struct file *, fl_owner_t id);
699 extern char * getname(const char *);
701 @@ -1369,6 +1375,8 @@ extern void path_release(struct nameidat
702 extern int follow_down(struct vfsmount **, struct dentry **);
703 extern int follow_up(struct vfsmount **, struct dentry **);
704 extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
705 +extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
706 + struct lookup_intent *);
707 extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct nameidata *);
708 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
709 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
710 @@ -1382,6 +1390,8 @@ extern ino_t iunique(struct super_block
712 typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
713 extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
714 +extern struct inode * ilookup4(struct super_block *, unsigned long,
715 + find_inode_t, void *);
716 static inline struct inode *iget(struct super_block *sb, unsigned long ino)
718 return iget4(sb, ino, NULL, NULL);
719 diff -uprN linux/kernel/ksyms.c linux-2.4.20/kernel/ksyms.c
720 --- linux/kernel/ksyms.c Sun Oct 5 21:52:51 2003
721 +++ linux-2.4.20/kernel/ksyms.c Sun Oct 5 22:25:20 2003
722 @@ -146,6 +146,7 @@ EXPORT_SYMBOL(fget);
723 EXPORT_SYMBOL(igrab);
724 EXPORT_SYMBOL(iunique);
725 EXPORT_SYMBOL(iget4);
726 +EXPORT_SYMBOL(ilookup4);
728 EXPORT_SYMBOL(force_delete);
729 EXPORT_SYMBOL(follow_up);
730 @@ -156,6 +157,7 @@ EXPORT_SYMBOL(path_walk);
731 EXPORT_SYMBOL(path_release);
732 EXPORT_SYMBOL(__user_walk);
733 EXPORT_SYMBOL(lookup_one_len);
734 +EXPORT_SYMBOL(lookup_one_len_it);
735 EXPORT_SYMBOL(lookup_hash);
736 EXPORT_SYMBOL(sys_close);
737 EXPORT_SYMBOL(dcache_lock);