Whamcloud - gitweb
adding 2.6-sles10 target and kernel config files for the sles10 kernel
[fs/lustre-release.git] / lustre / kernel_patches / patches / nfs_export_kernel-2.4.21-chaos.patch
index 5d3064c..db293ca 100644 (file)
@@ -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 <asm/namei.h>
  #include <asm/uaccess.h>
-@@ -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 = &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);