1 Index: linux-2.4.29/fs/Makefile
2 ===================================================================
3 --- linux-2.4.29.orig/fs/Makefile 2005-04-07 19:31:00.000000000 +0300
4 +++ linux-2.4.29/fs/Makefile 2005-05-03 15:59:07.943621928 +0300
9 -export-objs := filesystems.o open.o dcache.o buffer.o dquot.o inode.o
10 +export-objs := filesystems.o open.o dcache.o buffer.o dquot.o inode.o \
11 + namei.o file_table.o
14 obj-y := open.o read_write.o devices.o file_table.o buffer.o \
15 Index: linux-2.4.29/fs/file_table.c
16 ===================================================================
17 --- linux-2.4.29.orig/fs/file_table.c 2005-04-07 18:52:26.000000000 +0300
18 +++ linux-2.4.29/fs/file_table.c 2005-05-03 15:59:07.945621624 +0300
20 * and call the open function (if any). The caller must verify that
21 * inode->i_fop is not NULL.
23 -int init_private_file(struct file *filp, struct dentry *dentry, int mode)
24 +int init_private_file_it(struct file *filp, struct dentry *dentry, int mode,
25 + struct lookup_intent *it)
27 memset(filp, 0, sizeof(*filp));
30 filp->f_dentry = dentry;
31 filp->f_uid = current->fsuid;
32 filp->f_gid = current->fsgid;
35 filp->f_op = dentry->d_inode->i_fop;
37 return filp->f_op->open(dentry->d_inode, filp);
41 +EXPORT_SYMBOL(init_private_file_it);
43 +int init_private_file(struct file *filp, struct dentry *dentry, int mode)
45 + return init_private_file_it(filp, dentry, mode, NULL);
48 void fastcall fput(struct file * file)
50 Index: linux-2.4.29/fs/inode.c
51 ===================================================================
52 --- linux-2.4.29.orig/fs/inode.c 2005-04-07 19:18:51.000000000 +0300
53 +++ linux-2.4.29/fs/inode.c 2005-05-03 16:02:40.198354304 +0300
54 @@ -1154,6 +1154,24 @@
56 spin_unlock(&inode_lock);
61 +struct inode *ilookup4(struct super_block *sb, unsigned long ino,
62 + find_inode_t find_actor, void *opaque)
64 + struct list_head * head = inode_hashtable + hash(sb,ino);
65 + return ifind(sb, ino, head, find_actor, opaque);
68 +static inline struct inode *ifind(struct super_block *sb, unsigned long ino,
69 + struct list_head *head,
70 + find_inode_t find_actor, void *opaque)
72 + struct inode *inode = ifind(sb, ino, head, find_actor, opaque);
77 * get_new_inode() will do the right thing, re-trying the search
78 * in case it had to block at any point.
79 Index: linux-2.4.29/fs/namei.c
80 ===================================================================
81 --- linux-2.4.29.orig/fs/namei.c 2005-04-07 19:14:06.000000000 +0300
82 +++ linux-2.4.29/fs/namei.c 2005-05-03 15:59:07.953620408 +0300
84 #include <linux/dnotify.h>
85 #include <linux/smp_lock.h>
86 #include <linux/personality.h>
87 +#include <linux/module.h>
89 #include <asm/namei.h>
90 #include <asm/uaccess.h>
92 it->it_op_release(it);
95 +EXPORT_SYMBOL(intent_release);
97 /* In order to reduce some races, while at the same time doing additional
98 * checking and hopefully speeding things up, we copy filenames to the
103 -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
104 +struct dentry * lookup_one_len_it(const char * name, struct dentry * base,
105 + int len, struct lookup_intent *it)
109 @@ -930,11 +933,16 @@
111 this.hash = end_name_hash(hash);
113 - return lookup_hash_it(&this, base, NULL);
114 + return lookup_hash_it(&this, base, it);
116 return ERR_PTR(-EACCES);
119 +struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
121 + return lookup_one_len_it(name, base, len, NULL);
127 Index: linux-2.4.29/fs/nfsd/export.c
128 ===================================================================
129 --- linux-2.4.29.orig/fs/nfsd/export.c 2005-04-07 18:53:59.000000000 +0300
130 +++ linux-2.4.29/fs/nfsd/export.c 2005-05-03 15:59:07.955620104 +0300
132 inode = nd.dentry->d_inode;
135 + if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) &&
136 + !(nxp->ex_flags & NFSEXP_FSID)) {
137 + nxp->ex_dev = inode->i_sb->s_dev;
138 + nxp->ex_flags |= NFSEXP_FSID;
142 exp = exp_get(clp, dev, ino);
143 Index: linux-2.4.29/fs/nfsd/nfsfh.c
144 ===================================================================
145 --- linux-2.4.29.orig/fs/nfsd/nfsfh.c 2005-04-07 18:53:14.000000000 +0300
146 +++ linux-2.4.29/fs/nfsd/nfsfh.c 2005-05-03 15:59:07.958619648 +0300
148 int sequence; /* sequence counter */
151 +static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry)
153 + if (inode->i_op->lookup_it)
154 + return inode->i_op->lookup_it(inode, dentry, NULL, 0);
155 + return inode->i_op->lookup(inode, dentry);
159 * A rather strange filldir function to capture
160 * the name matching the specified inode number.
164 struct nfsd_getdents_callback buffer;
165 + struct lookup_intent it;
166 + struct file *filp = NULL;
169 if (!dir || !S_ISDIR(dir->i_mode))
172 * Open the directory ...
174 - error = init_private_file(&file, dentry, FMODE_READ);
175 + if (dentry->d_op && dentry->d_op->d_revalidate_it) {
176 + if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) &&
177 + (dentry->d_parent == dentry) ) {
178 + it.it_op_release = NULL;
180 + * XXX Temporary Hack: Simulate init_private_file without
181 + * f_op->open for disconnected dentry as we don't have
182 + * actual dentry->d_name to revalidate in revalidate_it()
185 + memset(filp, 0, sizeof(*filp));
186 + filp->f_mode = FMODE_READ;
187 + atomic_set(&filp->f_count, 1);
188 + filp->f_dentry = dentry;
189 + filp->f_uid = current->fsuid;
190 + filp->f_gid = current->fsgid;
191 + filp->f_op = dentry->d_inode->i_fop;
194 + intent_init(&it, IT_OPEN, FMODE_READ);
195 + error = revalidate_it(dentry, &it);
198 + error = init_private_file_it(&file, dentry, FMODE_READ, &it);
201 + error = init_private_file_it(&file, dentry, FMODE_READ, NULL);
207 if (!file.f_op->readdir)
213 - if (file.f_op->release)
214 + if (file.f_op->release && !filp)
215 file.f_op->release(dir, &file);
217 + if (dentry->d_op && dentry->d_op->d_revalidate_it &&
218 + it.it_op_release && !filp)
219 + intent_release(&it);
224 * it is well connected. But nobody returns different dentrys do they?
226 down(&child->d_inode->i_sem);
227 - pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
228 + pdentry = lookup_it(child->d_inode, tdentry);
229 up(&child->d_inode->i_sem);
230 d_drop(tdentry); /* we never want ".." hashed */
231 if (!pdentry && tdentry->d_inode == NULL) {
233 pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
234 pdentry->d_op = child->d_op;
236 + if (child->d_op && child->d_op->d_revalidate_it)
237 + pdentry->d_op = child->d_op;
240 pdentry = ERR_PTR(-ENOMEM);
242 struct dentry *pdentry;
243 struct inode *parent;
245 + if (result->d_op && result->d_op->d_revalidate_it)
246 + dentry->d_op = result->d_op;
247 pdentry = nfsd_findparent(dentry);
248 err = PTR_ERR(pdentry);
252 inode = dentry->d_inode;
254 + /* cache coherency for non-device filesystems */
255 + if (inode->i_op && inode->i_op->revalidate_it)
256 + inode->i_op->revalidate_it(dentry, NULL);
258 /* Type check. The correct error return for type mismatches
259 * does not seem to be generally agreed upon. SunOS seems to
260 * use EISDIR if file isn't S_IFREG; a comment in the NFSv3
262 dentry->d_parent->d_name.name, dentry->d_name.name);
265 - printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
266 - dentry->d_parent->d_name.name, dentry->d_name.name);
267 + if (!dentry->d_parent->d_inode->i_op->mkdir_raw)
268 + printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
269 + dentry->d_parent->d_name.name, dentry->d_name.name);
273 Index: linux-2.4.29/fs/nfsd/vfs.c
274 ===================================================================
275 --- linux-2.4.29.orig/fs/nfsd/vfs.c 2005-04-07 18:53:19.000000000 +0300
276 +++ linux-2.4.29/fs/nfsd/vfs.c 2005-05-03 15:59:07.965618584 +0300
278 static struct raparms * raparml;
279 static struct raparms * raparm_cache;
281 +static int link_raw(struct dentry *dold, struct dentry *ddir,
282 + struct dentry *dnew)
286 + struct nameidata old_nd = { .dentry = dold };
287 + struct nameidata nd = { .dentry = ddir, .last = dnew->d_name };
288 + struct inode_operations *op = nd.dentry->d_inode->i_op;
289 + err = op->link_raw(&old_nd, &nd);
290 + d_instantiate(dnew, dold->d_inode);
291 + if (dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it)
292 + dold->d_inode->i_op->revalidate_it(dnew, NULL);
297 +static int unlink_raw(struct dentry *dentry, char *fname, int flen,
298 + struct dentry *rdentry)
301 + struct qstr last = { .name = fname, .len = flen };
302 + struct nameidata nd = { .dentry = dentry, .last = last };
303 + struct inode_operations *op = nd.dentry->d_inode->i_op;
304 + err = op->unlink_raw(&nd);
311 +static int rmdir_raw(struct dentry *dentry, char *fname, int flen,
312 + struct dentry *rdentry)
315 + struct qstr last = { .name = fname, .len = flen };
316 + struct nameidata nd = { .dentry = dentry, .last = last };
317 + struct inode_operations *op = nd.dentry->d_inode->i_op;
318 + err = op->rmdir_raw(&nd);
320 + rdentry->d_inode->i_flags |= S_DEAD;
327 +static int symlink_raw(struct dentry *dentry, char *fname, int flen,
331 + struct qstr last = { .name = fname, .len = flen };
332 + struct nameidata nd = { .dentry = dentry, .last = last };
333 + struct inode_operations *op = nd.dentry->d_inode->i_op;
334 + err = op->symlink_raw(&nd, path);
339 +static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode)
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->mkdir_raw(&nd, mode);
350 +static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode,
354 + struct qstr last = { .name = fname, .len = flen };
355 + struct nameidata nd = { .dentry = dentry, .last = last };
356 + struct inode_operations *op = nd.dentry->d_inode->i_op;
357 + err = op->mknod_raw(&nd, mode, dev);
362 +static int rename_raw(struct dentry *fdentry, struct dentry *tdentry,
363 + struct dentry *odentry, struct dentry *ndentry)
367 + struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name};
368 + struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name};
369 + struct inode_operations *op = old_nd.dentry->d_inode->i_op;
370 + err = op->rename_raw(&old_nd, &new_nd);
371 + d_move(odentry, ndentry);
376 +static int setattr_raw(struct inode *inode, struct iattr *iap)
380 + iap->ia_valid |= ATTR_RAW;
381 + err = inode->i_op->setattr_raw(inode, iap);
386 +int revalidate_it(struct dentry *dentry, struct lookup_intent *it)
390 + if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
391 + if (!dentry->d_op->d_revalidate_it(dentry, 0, it) &&
392 + !d_invalidate(dentry)) {
402 * Look up one component of a pathname.
403 * N.B. After this call _both_ fhp and resfh need an fh_put
406 err = nfserr_notsync;
407 if (!check_guard || guardtime == inode->i_ctime) {
408 - err = notify_change(dentry, iap);
409 + if (dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw)
410 + err = setattr_raw(dentry->d_inode, iap);
412 + err = notify_change(dentry, iap);
418 struct dentry *dentry;
420 + struct lookup_intent it;
423 /* If we get here, then the client has already done an "open", and (hopefully)
425 filp->f_mode = FMODE_READ;
428 +#ifndef O_OWNER_OVERRIDE
429 +#define O_OWNER_OVERRIDE 0200000000
431 + intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode |
434 + err = revalidate_it(dentry, &it);
441 if (filp->f_op && filp->f_op->open) {
442 err = filp->f_op->open(inode, filp);
447 + if (it.it_op_release)
448 + intent_release(&it);
455 struct dentry *dentry, *dchild;
458 + int err, error = -EOPNOTSUPP;
462 @@ -853,20 +992,47 @@
463 dentry = fhp->fh_dentry;
464 dirp = dentry->d_inode;
468 + if (dirp->i_op->mkdir_raw)
469 + error = mkdir_raw(dentry, fname, flen, iap->ia_mode);
476 + if (dirp->i_op->mknod_raw) {
477 + if (type == S_IFREG)
479 + error = mknod_raw(dentry, fname,flen,iap->ia_mode,rdev);
483 + printk("nfsd: bad file type %o in nfsd_create\n", type);
485 + if (error && error != -EOPNOTSUPP) {
491 - if(!dirp->i_op || !dirp->i_op->lookup)
492 + if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
495 * Check whether the response file handle has been verified yet.
496 * If it has, the parent directory should already be locked.
498 - if (!resfhp->fh_dentry) {
499 - /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
501 + if (!resfhp->fh_dentry || dirp->i_op->lookup_it) {
502 + /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create
503 + * and nfsd_proc_create in case of lustre */
504 + if (!resfhp->fh_dentry)
506 dchild = lookup_one_len(fname, dentry, flen);
507 err = PTR_ERR(dchild);
510 + resfhp->fh_dentry = NULL;
511 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
514 @@ -887,10 +1053,12 @@
515 * Make sure the child dentry is still negative ...
518 - if (dchild->d_inode) {
519 - dprintk("nfsd_create: dentry %s/%s not negative!\n",
520 - dentry->d_name.name, dchild->d_name.name);
522 + if (error == -EOPNOTSUPP) {
523 + if (dchild->d_inode) {
524 + dprintk("nfsd_create: dentry %s/%s not negative!\n",
525 + dentry->d_name.name, dchild->d_name.name);
530 if (!(iap->ia_valid & ATTR_MODE))
531 @@ -903,16 +1071,19 @@
535 - err = vfs_create(dirp, dchild, iap->ia_mode);
536 + if (error == -EOPNOTSUPP)
537 + err = vfs_create(dirp, dchild, iap->ia_mode);
540 - err = vfs_mkdir(dirp, dchild, iap->ia_mode);
541 + if (error == -EOPNOTSUPP)
542 + err = vfs_mkdir(dirp, dchild, iap->ia_mode);
548 - err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
549 + if (error == -EOPNOTSUPP)
550 + err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
553 printk("nfsd: bad file type %o in nfsd_create\n", type);
554 @@ -981,7 +1152,13 @@
555 /* Get all the sanity checks out of the way before
556 * we lock the parent. */
558 - if(!dirp->i_op || !dirp->i_op->lookup)
559 + if (dirp->i_op->mknod_raw) {
560 + err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0);
561 + if (err && err != -EOPNOTSUPP)
565 + if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it))
569 @@ -1032,6 +1209,8 @@
570 case NFS3_CREATE_GUARDED:
573 + if (dirp->i_op->mknod_raw)
578 @@ -1138,7 +1317,7 @@
581 struct dentry *dentry, *dnew;
583 + int err, cerr, error = -EOPNOTSUPP;
587 @@ -1152,12 +1331,18 @@
590 dentry = fhp->fh_dentry;
592 + if (dentry->d_inode->i_op->symlink_raw)
593 + error = symlink_raw(dentry, fname, flen, path);
595 dnew = lookup_one_len(fname, dentry, flen);
600 - err = vfs_symlink(dentry->d_inode, dnew, path);
602 + if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw)
603 + err = vfs_symlink(dentry->d_inode, dnew, path);
605 if (EX_ISSYNC(fhp->fh_export))
606 nfsd_sync_dir(dentry);
607 @@ -1167,7 +1352,10 @@
608 iap->ia_valid |= ATTR_CTIME;
609 iap->ia_mode = (iap->ia_mode&S_IALLUGO)
611 - err = notify_change(dnew, iap);
612 + if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw)
613 + err = setattr_raw(dnew->d_inode, iap);
615 + err = notify_change(dnew, iap);
618 else if (EX_ISSYNC(fhp->fh_export))
619 @@ -1227,7 +1415,10 @@
620 dold = tfhp->fh_dentry;
621 dest = dold->d_inode;
623 - err = vfs_link(dold, dirp, dnew);
624 + if (dirp->i_op->link_raw)
625 + err = link_raw(dold, ddir, dnew);
627 + err = vfs_link(dold, dirp, dnew);
629 if (EX_ISSYNC(ffhp->fh_export)) {
631 @@ -1312,7 +1503,10 @@
635 - err = vfs_rename(fdir, odentry, tdir, ndentry);
636 + if (fdir->i_op->rename_raw)
637 + err = rename_raw(fdentry, tdentry, odentry, ndentry);
639 + err = vfs_rename(fdir, odentry, tdir, ndentry);
640 if (!err && EX_ISSYNC(tfhp->fh_export)) {
641 nfsd_sync_dir(tdentry);
642 nfsd_sync_dir(fdentry);
643 @@ -1333,7 +1527,7 @@
645 double_up(&tdir->i_sem, &fdir->i_sem);
646 ffhp->fh_locked = tfhp->fh_locked = 0;
652 @@ -1379,9 +1573,15 @@
656 - err = vfs_unlink(dirp, rdentry);
657 + if (dirp->i_op->unlink_raw)
658 + err = unlink_raw(dentry, fname, flen, rdentry);
660 + err = vfs_unlink(dirp, rdentry);
661 } else { /* It's RMDIR */
662 - err = vfs_rmdir(dirp, rdentry);
663 + if (dirp->i_op->rmdir_raw)
664 + err = rmdir_raw(dentry, fname, flen, rdentry);
666 + err = vfs_rmdir(dirp, rdentry);
670 Index: linux-2.4.29/include/linux/fs.h
671 ===================================================================
672 --- linux-2.4.29.orig/include/linux/fs.h 2005-04-07 19:31:00.000000000 +0300
673 +++ linux-2.4.29/include/linux/fs.h 2005-05-03 16:05:36.094614008 +0300
675 #define FS_SINGLE 8 /* Filesystem that can have only one superblock */
676 #define FS_NOMOUNT 16 /* Never mount from userland */
677 #define FS_LITTER 32 /* Keeps the tree in dcache */
678 +#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for
679 + * exporting non device filesystems. */
680 #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon
681 * as nfs_rename() will be cleaned up
683 @@ -1118,6 +1120,9 @@
684 struct nameidata *nd, struct lookup_intent *it);
685 extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
686 int flags, struct lookup_intent *it);
687 +extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it);
688 +extern int init_private_file_it(struct file *, struct dentry *dentry, int mode,
689 + struct lookup_intent *it);
690 extern int filp_close(struct file *, fl_owner_t id);
691 extern char * getname(const char *);
693 @@ -1417,6 +1422,8 @@
694 extern int follow_down(struct vfsmount **, struct dentry **);
695 extern int follow_up(struct vfsmount **, struct dentry **);
696 extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
697 +extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int,
698 + struct lookup_intent *);
699 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
700 #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
701 #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
702 @@ -1437,6 +1444,8 @@
704 extern struct inode * iget4_locked(struct super_block *, unsigned long,
705 find_inode_t, void *);
706 +extern struct inode * ilookup4(struct super_block *, unsigned long,
707 + find_inode_t, void *);
709 static inline struct inode *iget4(struct super_block *sb, unsigned long ino,
710 find_inode_t find_actor, void *opaque)
711 Index: linux-2.4.29/kernel/ksyms.c
712 ===================================================================
713 --- linux-2.4.29.orig/kernel/ksyms.c 2005-04-07 19:31:00.000000000 +0300
714 +++ linux-2.4.29/kernel/ksyms.c 2005-05-03 16:04:09.445786632 +0300
716 EXPORT_SYMBOL(ilookup);
717 EXPORT_SYMBOL(iget4_locked);
718 EXPORT_SYMBOL(unlock_new_inode);
719 +EXPORT_SYMBOL(ilookup4);
721 EXPORT_SYMBOL(inode_init_once);
722 EXPORT_SYMBOL(__inode_init_once);
724 EXPORT_SYMBOL(path_release);
725 EXPORT_SYMBOL(__user_walk);
726 EXPORT_SYMBOL(lookup_one_len);
727 +EXPORT_SYMBOL(lookup_one_len_it);
728 EXPORT_SYMBOL(lookup_hash);
729 EXPORT_SYMBOL(sys_close);
730 EXPORT_SYMBOL(dcache_lock);