X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fkernel_patches%2Fpatches%2Fnfs_export_kernel-2.4.21-chaos.patch;h=db293ca44d43b87f7b6dbc462325aef4b438e92a;hb=ed19570f0ebf8968cedda1756ffbb87d30aa9613;hp=5d3064c76389a92925ab4ca26544fd25f8defd0b;hpb=c85a039f9ddee1bf024b76d0a6c3d0885a19009b;p=fs%2Flustre-release.git diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.21-chaos.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.21-chaos.patch index 5d3064c..db293ca 100644 --- a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.21-chaos.patch @@ -13,17 +13,17 @@ Index: linux-2.4.21-chaos/fs/file_table.c =================================================================== --- linux-2.4.21-chaos.orig/fs/file_table.c 2003-07-15 04:41:00.000000000 +0400 +++ linux-2.4.21-chaos/fs/file_table.c 2003-12-12 16:19:25.000000000 +0300 -@@ -82,7 +82,8 @@ +@@ -82,7 +82,8 @@ struct file * get_empty_filp(void) * and call the open function (if any). The caller must verify that * inode->i_fop is not NULL. */ -int init_private_file(struct file *filp, struct dentry *dentry, int mode) +int init_private_file_it(struct file *filp, struct dentry *dentry, int mode, -+ struct lookup_intent *it) ++ struct lookup_intent *it) { memset(filp, 0, sizeof(*filp)); filp->f_mode = mode; -@@ -90,12 +91,20 @@ +@@ -90,12 +91,20 @@ int init_private_file(struct file *filp, filp->f_dentry = dentry; filp->f_uid = current->fsuid; filp->f_gid = current->fsgid; @@ -48,20 +48,20 @@ Index: linux-2.4.21-chaos/fs/inode.c =================================================================== --- linux-2.4.21-chaos.orig/fs/inode.c 2003-12-12 16:18:15.000000000 +0300 +++ linux-2.4.21-chaos/fs/inode.c 2003-12-12 16:19:25.000000000 +0300 -@@ -1054,9 +1054,10 @@ +@@ -1054,9 +1054,10 @@ struct inode *igrab(struct inode *inode) return inode; } -struct inode *iget4_locked(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) +struct inode *ifind(struct super_block *sb, unsigned long ino, -+ struct list_head *head, -+ find_inode_t find_actor, void *opaque) ++ struct list_head *head, ++ find_inode_t find_actor, void *opaque) { - struct list_head * head = inode_hashtable + hash(sb,ino); struct inode * inode; spin_lock(&inode_lock); -@@ -1069,6 +1070,24 @@ +@@ -1069,6 +1070,24 @@ struct inode *iget4_locked(struct super_ } spin_unlock(&inode_lock); @@ -69,14 +69,14 @@ Index: linux-2.4.21-chaos/fs/inode.c +} + +struct inode *ilookup4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) ++ find_inode_t find_actor, void *opaque) +{ + struct list_head * head = inode_hashtable + hash(sb,ino); + return ifind(sb, ino, head, find_actor, opaque); +} + +struct inode *iget4_locked(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) ++ find_inode_t find_actor, void *opaque) +{ + struct list_head * head = inode_hashtable + hash(sb,ino); + struct inode *inode = ifind(sb, ino, head, find_actor, opaque); @@ -112,7 +112,7 @@ Index: linux-2.4.21-chaos/fs/namei.c #include #include -@@ -100,6 +101,7 @@ +@@ -100,6 +101,7 @@ void intent_release(struct lookup_intent it->it_op_release(it); } @@ -120,17 +120,17 @@ Index: linux-2.4.21-chaos/fs/namei.c /* In order to reduce some races, while at the same time doing additional * checking and hopefully speeding things up, we copy filenames to the -@@ -910,7 +912,8 @@ +@@ -910,7 +912,8 @@ struct dentry * lookup_hash(struct qstr /* SMP-safe */ -struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) +struct dentry * lookup_one_len_it(const char * name, struct dentry * base, -+ int len, struct lookup_intent *it) ++ int len, struct lookup_intent *it) { unsigned long hash; struct qstr this; -@@ -930,11 +933,16 @@ +@@ -930,11 +933,16 @@ struct dentry * lookup_one_len(const cha } this.hash = end_name_hash(hash); @@ -152,14 +152,14 @@ Index: linux-2.4.21-chaos/fs/nfsd/export.c =================================================================== --- linux-2.4.21-chaos.orig/fs/nfsd/export.c 2003-09-19 03:49:54.000000000 +0400 +++ linux-2.4.21-chaos/fs/nfsd/export.c 2003-12-12 16:19:25.000000000 +0300 -@@ -223,6 +223,11 @@ +@@ -223,6 +223,11 @@ exp_export(struct nfsctl_export *nxp) inode = nd.dentry->d_inode; dev = inode->i_dev; ino = inode->i_ino; + if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) && + !(nxp->ex_flags & NFSEXP_FSID)) { -+ nxp->ex_dev = inode->i_sb->s_dev; -+ nxp->ex_flags |= NFSEXP_FSID; ++ nxp->ex_dev = inode->i_sb->s_dev; ++ nxp->ex_flags |= NFSEXP_FSID; + } err = -EINVAL; @@ -168,23 +168,21 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c =================================================================== --- linux-2.4.21-chaos.orig/fs/nfsd/nfsfh.c 2003-09-19 03:49:54.000000000 +0400 +++ linux-2.4.21-chaos/fs/nfsd/nfsfh.c 2003-12-12 16:19:25.000000000 +0300 -@@ -36,6 +36,15 @@ +@@ -36,6 +36,13 @@ struct nfsd_getdents_callback { int sequence; /* sequence counter */ }; +static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry) +{ + if (inode->i_op->lookup_it) -+ return inode->i_op->lookup_it(inode, dentry, NULL, NULL, 0); -+ else -+ return inode->i_op->lookup(inode, dentry); -+ ++ return inode->i_op->lookup_it(inode, dentry, NULL, 0); ++ return inode->i_op->lookup(inode, dentry); +} + /* * A rather strange filldir function to capture * the name matching the specified inode number. -@@ -75,6 +84,8 @@ +@@ -75,6 +84,8 @@ static int nfsd_get_name(struct dentry * int error; struct file file; struct nfsd_getdents_callback buffer; @@ -193,7 +191,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c error = -ENOTDIR; if (!dir || !S_ISDIR(dir->i_mode)) -@@ -85,9 +96,37 @@ +@@ -85,9 +96,37 @@ static int nfsd_get_name(struct dentry * /* * Open the directory ... */ @@ -203,10 +201,10 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c + if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) && + (dentry->d_parent == dentry) ) { + it.it_op_release = NULL; -+ /* -+ * XXX Temporary Hack: Simulating init_private_file without -+ * f_op->open for disconnected dentry Since we don't have actual -+ * dentry->d_name to revalidate in revalidate_it() ++ /* ++ * XXX Temporary Hack: Simulate init_private_file without ++ * f_op->open for disconnected dentry as we don't have ++ * actual dentry->d_name to revalidate in revalidate_it() + */ + filp = &file; + memset(filp, 0, sizeof(*filp)); @@ -218,7 +216,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c + filp->f_op = dentry->d_inode->i_fop; + error = 0; + } else { -+ intent_init(&it, IT_OPEN, 0); ++ intent_init(&it, IT_OPEN, FMODE_READ); + error = revalidate_it(dentry, &it); + if (error) + goto out; @@ -227,13 +225,13 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c + } else { + error = init_private_file_it(&file, dentry, FMODE_READ, NULL); + } -+ if (error) ++ if (error) goto out; + error = -EINVAL; if (!file.f_op->readdir) goto out_close; -@@ -113,9 +152,13 @@ +@@ -113,9 +152,12 @@ static int nfsd_get_name(struct dentry * } out_close: @@ -241,14 +239,13 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c + if (file.f_op->release && !filp) file.f_op->release(dir, &file); out: -+ if (dentry->d_op && -+ dentry->d_op->d_revalidate_it && ++ if (dentry->d_op && dentry->d_op->d_revalidate_it && + it.it_op_release && !filp) + intent_release(&it); return error; } -@@ -274,7 +317,7 @@ +@@ -274,7 +317,7 @@ struct dentry *nfsd_findparent(struct de * it is well connected. But nobody returns different dentrys do they? */ down(&child->d_inode->i_sem); @@ -257,7 +254,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c up(&child->d_inode->i_sem); d_drop(tdentry); /* we never want ".." hashed */ if (!pdentry && tdentry->d_inode == NULL) { -@@ -307,6 +350,8 @@ +@@ -306,6 +350,8 @@ struct dentry *nfsd_findparent(struct de pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED; pdentry->d_op = child->d_op; } @@ -266,7 +263,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c } if (pdentry == NULL) pdentry = ERR_PTR(-ENOMEM); -@@ -464,6 +509,8 @@ +@@ -464,6 +509,8 @@ find_fh_dentry(struct super_block *sb, _ struct dentry *pdentry; struct inode *parent; @@ -275,27 +272,26 @@ Index: linux-2.4.21-chaos/fs/nfsd/nfsfh.c pdentry = nfsd_findparent(dentry); err = PTR_ERR(pdentry); if (IS_ERR(pdentry)) -@@ -672,6 +719,11 @@ +@@ -672,6 +719,10 @@ fh_verify(struct svc_rqst *rqstp, struct inode = dentry->d_inode; + /* cache coherency for non-device filesystems */ -+ if (inode->i_op && inode->i_op->revalidate_it) { -+ inode->i_op->revalidate_it(dentry, NULL); -+ } ++ if (inode->i_op && inode->i_op->revalidate_it) ++ inode->i_op->revalidate_it(dentry, NULL); + /* Type check. The correct error return for type mismatches * does not seem to be generally agreed upon. SunOS seems to * use EISDIR if file isn't S_IFREG; a comment in the NFSv3 -@@ -905,8 +957,9 @@ +@@ -905,8 +957,9 @@ out_negative: dentry->d_parent->d_name.name, dentry->d_name.name); goto out; out_uptodate: - printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", - dentry->d_parent->d_name.name, dentry->d_name.name); -+ if(!dentry->d_parent->d_inode->i_op->mkdir_raw) ++ if (!dentry->d_parent->d_inode->i_op->mkdir_raw) + printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -+ dentry->d_parent->d_name.name, dentry->d_name.name); ++ dentry->d_parent->d_name.name, dentry->d_name.name); goto out; } @@ -303,12 +299,12 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c =================================================================== --- linux-2.4.21-chaos.orig/fs/nfsd/vfs.c 2003-09-19 03:49:54.000000000 +0400 +++ linux-2.4.21-chaos/fs/nfsd/vfs.c 2003-12-12 16:19:25.000000000 +0300 -@@ -78,6 +78,128 @@ +@@ -78,6 +78,127 @@ static struct raparms * raparml; static struct raparms * raparm_cache; +static int link_raw(struct dentry *dold, struct dentry *ddir, -+ struct dentry *dnew) ++ struct dentry *dnew) +{ + int err; + @@ -316,18 +312,19 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c + struct nameidata nd = { .dentry = ddir, .last = dnew->d_name }; + struct inode_operations *op = nd.dentry->d_inode->i_op; + err = op->link_raw(&old_nd, &nd); ++ igrab(dold->d_inode); + d_instantiate(dnew, dold->d_inode); -+ if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it) ++ if (dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it) + dold->d_inode->i_op->revalidate_it(dnew, NULL); + + return err; +} + +static int unlink_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) ++ struct dentry *rdentry) +{ + int err; -+ struct qstr last = { .name = fname, .len = flen }; ++ struct qstr last = { .name = fname, .len = flen }; + struct nameidata nd = { .dentry = dentry, .last = last }; + struct inode_operations *op = nd.dentry->d_inode->i_op; + err = op->unlink_raw(&nd); @@ -338,14 +335,14 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c +} + +static int rmdir_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) ++ struct dentry *rdentry) +{ + int err; -+ struct qstr last = { .name = fname, .len = flen }; ++ struct qstr last = { .name = fname, .len = flen }; + struct nameidata nd = { .dentry = dentry, .last = last }; + struct inode_operations *op = nd.dentry->d_inode->i_op; + err = op->rmdir_raw(&nd); -+ if(!err) { ++ if (!err) { + rdentry->d_inode->i_flags |= S_DEAD; + d_delete(rdentry); + } @@ -353,11 +350,11 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c + return err; +} + -+static int symlink_raw(struct dentry *dentry, char *fname, int flen, -+ char *path) ++static int symlink_raw(struct dentry *dentry, char *fname, int flen, ++ char *path) +{ + int err; -+ struct qstr last = { .name = fname, .len = flen }; ++ struct qstr last = { .name = fname, .len = flen }; + struct nameidata nd = { .dentry = dentry, .last = last }; + struct inode_operations *op = nd.dentry->d_inode->i_op; + err = op->symlink_raw(&nd, path); @@ -368,7 +365,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c +static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode) +{ + int err; -+ struct qstr last = { .name = fname, .len = flen }; ++ struct qstr last = { .name = fname, .len = flen }; + struct nameidata nd = { .dentry = dentry, .last = last }; + struct inode_operations *op = nd.dentry->d_inode->i_op; + err = op->mkdir_raw(&nd, mode); @@ -377,19 +374,19 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c +} + +static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode, -+ dev_t dev) ++ dev_t dev) +{ + int err; -+ struct qstr last = { .name = fname, .len = flen }; ++ struct qstr last = { .name = fname, .len = flen }; + struct nameidata nd = { .dentry = dentry, .last = last }; + struct inode_operations *op = nd.dentry->d_inode->i_op; + err = op->mknod_raw(&nd, mode, dev); + + return err; -+} ++} + +static int rename_raw(struct dentry *fdentry, struct dentry *tdentry, -+ struct dentry *odentry, struct dentry *ndentry) ++ struct dentry *odentry, struct dentry *ndentry) +{ + int err; + @@ -417,11 +414,9 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c + int err = 0; + + if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(dentry, 0, NULL, it) && ++ if (!dentry->d_op->d_revalidate_it(dentry, 0, it) && + !d_invalidate(dentry)) { -+ dput(dentry); + err = -EINVAL; -+ dentry = NULL; + return err; + } + } @@ -432,19 +427,19 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c /* * Look up one component of a pathname. * N.B. After this call _both_ fhp and resfh need an fh_put -@@ -303,7 +425,10 @@ +@@ -303,7 +425,10 @@ nfsd_setattr(struct svc_rqst *rqstp, str } err = nfserr_notsync; if (!check_guard || guardtime == inode->i_ctime) { - err = notify_change(dentry, iap); -+ if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw) ++ if (dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw) + err = setattr_raw(dentry->d_inode, iap); + else + err = notify_change(dentry, iap); err = nfserrno(err); } if (size_change) { -@@ -430,6 +555,7 @@ +@@ -430,6 +555,7 @@ nfsd_open(struct svc_rqst *rqstp, struct { struct dentry *dentry; struct inode *inode; @@ -452,26 +447,28 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c int err; /* If we get here, then the client has already done an "open", and (hopefully) -@@ -476,6 +602,14 @@ +@@ -476,6 +602,18 @@ nfsd_open(struct svc_rqst *rqstp, struct filp->f_mode = FMODE_READ; } -+ intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode); ++#ifndef O_OWNER_OVERRIDE ++#define O_OWNER_OVERRIDE 0200000000 ++#endif ++ intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode | ++ O_OWNER_OVERRIDE); + + err = revalidate_it(dentry, &it); + if (err) + goto out_nfserr; -+ ++ + filp->f_it = ⁢ -+ ++ err = 0; if (filp->f_op && filp->f_op->open) { err = filp->f_op->open(inode, filp); -@@ -490,7 +624,11 @@ - atomic_dec(&filp->f_count); +@@ -490,6 +624,9 @@ nfsd_open(struct svc_rqst *rqstp, struct } } -+ out_nfserr: + if (it.it_op_release) + intent_release(&it); @@ -479,7 +476,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c if (err) err = nfserrno(err); out: -@@ -821,7 +959,7 @@ +@@ -821,7 +959,7 @@ nfsd_create(struct svc_rqst *rqstp, stru { struct dentry *dentry, *dchild; struct inode *dirp; @@ -488,33 +485,37 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c err = nfserr_perm; if (!flen) -@@ -837,20 +975,44 @@ +@@ -837,20 +975,47 @@ nfsd_create(struct svc_rqst *rqstp, stru dentry = fhp->fh_dentry; dirp = dentry->d_inode; + switch (type) { -+ case S_IFDIR: -+ if (dirp->i_op->mkdir_raw) -+ error = mkdir_raw(dentry, fname, flen, iap->ia_mode); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ case S_IFIFO: -+ case S_IFSOCK: -+ case S_IFREG: -+ if (dirp->i_op->mknod_raw) { -+ if (type == S_IFREG) -+ rdev = 0; -+ error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev); -+ } -+ break; -+ default: -+ printk("nfsd: bad file type %o in nfsd_create\n", type); ++ case S_IFDIR: ++ if (dirp->i_op->mkdir_raw) ++ error = mkdir_raw(dentry, fname, flen, iap->ia_mode); ++ break; ++ case S_IFCHR: ++ case S_IFBLK: ++ case S_IFIFO: ++ case S_IFSOCK: ++ case S_IFREG: ++ if (dirp->i_op->mknod_raw) { ++ if (type == S_IFREG) ++ rdev = 0; ++ error = mknod_raw(dentry, fname,flen,iap->ia_mode,rdev); ++ } ++ break; ++ default: ++ printk("nfsd: bad file type %o in nfsd_create\n", type); ++ } ++ if (error && error != -EOPNOTSUPP) { ++ err = error; ++ goto out_nfserr; + } + err = nfserr_notdir; - if(!dirp->i_op || !dirp->i_op->lookup) -+ if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) ++ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) goto out; /* * Check whether the response file handle has been verified yet. @@ -525,8 +526,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c - fh_lock(fhp); + if (!resfhp->fh_dentry || dirp->i_op->lookup_it) { + /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create -+ and nfsd_proc_create in case of lustre -+ */ ++ * and nfsd_proc_create in case of lustre */ + if (!resfhp->fh_dentry) + fh_lock(fhp); dchild = lookup_one_len(fname, dentry, flen); @@ -537,7 +537,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); if (err) goto out; -@@ -871,10 +1033,12 @@ +@@ -871,10 +1033,12 @@ nfsd_create(struct svc_rqst *rqstp, stru * Make sure the child dentry is still negative ... */ err = nfserr_exist; @@ -545,16 +545,16 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c - dprintk("nfsd_create: dentry %s/%s not negative!\n", - dentry->d_name.name, dchild->d_name.name); - goto out; -+ if ( error == -EOPNOTSUPP) { ++ if (error == -EOPNOTSUPP) { + if (dchild->d_inode) { + dprintk("nfsd_create: dentry %s/%s not negative!\n", + dentry->d_name.name, dchild->d_name.name); -+ goto out; ++ goto out; + } } if (!(iap->ia_valid & ATTR_MODE)) -@@ -887,16 +1051,19 @@ +@@ -887,16 +1051,19 @@ nfsd_create(struct svc_rqst *rqstp, stru err = nfserr_perm; switch (type) { case S_IFREG: @@ -572,12 +572,12 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c case S_IFIFO: case S_IFSOCK: - err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); -+ if (error == -EOPNOTSUPP) ++ if (error == -EOPNOTSUPP) + err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); break; default: printk("nfsd: bad file type %o in nfsd_create\n", type); -@@ -965,7 +1132,13 @@ +@@ -965,7 +1132,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s /* Get all the sanity checks out of the way before * we lock the parent. */ err = nfserr_notdir; @@ -585,23 +585,23 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c + if (dirp->i_op->mknod_raw) { + err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0); + if (err && err != -EOPNOTSUPP) -+ goto out; ++ goto out_nfserr; + } + -+ if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) ++ if (!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) goto out; fh_lock(fhp); -@@ -1016,6 +1189,8 @@ +@@ -1016,6 +1189,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s case NFS3_CREATE_GUARDED: err = nfserr_exist; } -+ if(dirp->i_op->mknod_raw) ++ if (dirp->i_op->mknod_raw) + err = 0; goto out; } -@@ -1122,7 +1297,7 @@ +@@ -1122,7 +1297,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str struct iattr *iap) { struct dentry *dentry, *dnew; @@ -610,11 +610,11 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c err = nfserr_noent; if (!flen || !plen) -@@ -1136,12 +1311,18 @@ +@@ -1136,12 +1311,18 @@ nfsd_symlink(struct svc_rqst *rqstp, str goto out; fh_lock(fhp); dentry = fhp->fh_dentry; -+ ++ + if (dentry->d_inode->i_op->symlink_raw) + error = symlink_raw(dentry, fname, flen, path); + @@ -630,7 +630,19 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c if (!err) { if (EX_ISSYNC(fhp->fh_export)) nfsd_sync_dir(dentry); -@@ -1211,7 +1392,10 @@ +@@ -1148,7 +1329,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str + iap->ia_valid |= ATTR_CTIME; + iap->ia_mode = (iap->ia_mode&S_IALLUGO) + | S_IFLNK; +- err = notify_change(dnew, iap); ++ if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw) ++ err = setattr_raw(dnew->d_inode, iap); ++ else ++ err = notify_change(dnew, iap); + if (err) + err = nfserrno(err); + else if (EX_ISSYNC(fhp->fh_export)) +@@ -1211,7 +1392,10 @@ nfsd_link(struct svc_rqst *rqstp, struct dold = tfhp->fh_dentry; dest = dold->d_inode; @@ -642,19 +654,19 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c if (!err) { if (EX_ISSYNC(ffhp->fh_export)) { nfsd_sync_dir(ddir); -@@ -1296,7 +1480,10 @@ +@@ -1296,7 +1480,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru err = nfserr_perm; } else #endif - err = vfs_rename(fdir, odentry, tdir, ndentry); -+ if(fdir->i_op->rename_raw) ++ if (fdir->i_op->rename_raw) + err = rename_raw(fdentry, tdentry, odentry, ndentry); + else + err = vfs_rename(fdir, odentry, tdir, ndentry); if (!err && EX_ISSYNC(tfhp->fh_export)) { nfsd_sync_dir(tdentry); nfsd_sync_dir(fdentry); -@@ -1317,7 +1504,7 @@ +@@ -1317,7 +1504,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru fill_post_wcc(tfhp); double_up(&tdir->i_sem, &fdir->i_sem); ffhp->fh_locked = tfhp->fh_locked = 0; @@ -663,7 +675,7 @@ Index: linux-2.4.21-chaos/fs/nfsd/vfs.c out: return err; } -@@ -1363,9 +1550,15 @@ +@@ -1363,9 +1550,15 @@ nfsd_unlink(struct svc_rqst *rqstp, stru err = nfserr_perm; } else #endif @@ -685,50 +697,48 @@ Index: linux-2.4.21-chaos/include/linux/fs.h =================================================================== --- linux-2.4.21-chaos.orig/include/linux/fs.h 2003-12-12 16:19:23.000000000 +0300 +++ linux-2.4.21-chaos/include/linux/fs.h 2003-12-12 16:19:25.000000000 +0300 -@@ -93,6 +93,9 @@ +@@ -93,6 +93,8 @@ #define FS_SINGLE 8 /* Filesystem that can have only one superblock */ #define FS_NOMOUNT 16 /* Never mount from userland */ #define FS_LITTER 32 /* Keeps the tree in dcache */ -+#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for -+ * exporting non device filesystems. -+ */ ++#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for ++ * exporting non device filesystems. */ #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon * as nfs_rename() will be cleaned up */ -@@ -1159,6 +1162,9 @@ +@@ -1159,6 +1162,9 @@ extern int open_namei_it(const char *fil struct nameidata *nd, struct lookup_intent *it); extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, int flags, struct lookup_intent *it); +extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it); +extern int init_private_file_it(struct file *, struct dentry *dentry, int mode, -+ struct lookup_intent *it); ++ struct lookup_intent *it); extern int filp_close(struct file *, fl_owner_t id); extern char * getname(const char *); -@@ -1458,6 +1464,8 @@ +@@ -1458,6 +1464,8 @@ extern void path_release(struct nameidat extern int follow_down(struct vfsmount **, struct dentry **); extern int follow_up(struct vfsmount **, struct dentry **); extern struct dentry * lookup_one_len(const char *, struct dentry *, int); +extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int, -+ struct lookup_intent *); ++ struct lookup_intent *); extern struct dentry * lookup_hash(struct qstr *, struct dentry *); #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -@@ -1477,7 +1485,8 @@ +@@ -1477,6 +1485,8 @@ typedef int (*find_inode_t)(struct inode extern struct inode * iget4_locked(struct super_block *, unsigned long, find_inode_t, void *); -- +extern struct inode * ilookup4(struct super_block *, unsigned long, -+ find_inode_t, void *); ++ find_inode_t, void *); + static inline struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) - { Index: linux-2.4.21-chaos/kernel/ksyms.c =================================================================== --- linux-2.4.21-chaos.orig/kernel/ksyms.c 2003-12-12 16:18:36.000000000 +0300 +++ linux-2.4.21-chaos/kernel/ksyms.c 2003-12-12 16:19:25.000000000 +0300 -@@ -178,6 +178,7 @@ +@@ -178,6 +178,7 @@ EXPORT_SYMBOL(fget); EXPORT_SYMBOL(igrab); EXPORT_SYMBOL(iunique); EXPORT_SYMBOL(iget4_locked); @@ -736,7 +746,7 @@ Index: linux-2.4.21-chaos/kernel/ksyms.c EXPORT_SYMBOL(unlock_new_inode); EXPORT_SYMBOL(iput); EXPORT_SYMBOL(inode_init_once); -@@ -191,6 +192,7 @@ +@@ -191,6 +192,7 @@ EXPORT_SYMBOL(path_walk); EXPORT_SYMBOL(path_release); EXPORT_SYMBOL(__user_walk); EXPORT_SYMBOL(lookup_one_len);