Whamcloud - gitweb
NFS export patch for lustre
authorgirish_c <girish_c>
Wed, 18 Jun 2003 16:39:43 +0000 (16:39 +0000)
committergirish_c <girish_c>
Wed, 18 Jun 2003 16:39:43 +0000 (16:39 +0000)
1) Patch is updated with review comments
2) All Connectathon tests passes except bigfile(30 MB)test

lustre/kernel_patches/patches/nfs_export-2.4.18-18.patch [new file with mode: 0644]

diff --git a/lustre/kernel_patches/patches/nfs_export-2.4.18-18.patch b/lustre/kernel_patches/patches/nfs_export-2.4.18-18.patch
new file mode 100644 (file)
index 0000000..01c2727
--- /dev/null
@@ -0,0 +1,514 @@
+diff -urN linux/fs/inode.c linux_n/fs/inode.c
+--- linux/fs/inode.c   2003-06-18 21:39:14.000000000 +0530
++++ linux_n/fs/inode.c 2003-06-18 21:39:53.000000000 +0530
+@@ -987,6 +987,24 @@
+ }
++struct inode *search_icache_for_lustre(struct super_block *sb, unsigned long ino)
++{
++      struct list_head * head = inode_hashtable + hash(sb,ino);
++      struct inode * inode;
++
++      spin_lock(&inode_lock);
++      inode = find_inode(sb, ino, head, NULL, NULL);
++      if (inode) {
++              __iget(inode);
++              spin_unlock(&inode_lock);
++              wait_on_inode(inode);
++              return inode;
++      }
++      spin_unlock(&inode_lock);
++      
++      return NULL;
++}
++
+ struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque)
+ {
+       struct list_head * head = inode_hashtable + hash(sb,ino);
+diff -urN linux/fs/namei.c linux_n/fs/namei.c
+--- linux/fs/namei.c   2003-06-18 21:39:13.000000000 +0530
++++ linux_n/fs/namei.c 2003-06-18 21:39:41.000000000 +0530
+@@ -918,8 +918,7 @@
+ }
+-/* 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)
+ {
+       unsigned long hash;
+       struct qstr this;
+@@ -939,11 +938,17 @@
+       }
+       this.hash = end_name_hash(hash);
+-      return lookup_hash_it(&this, base, NULL);
++      return lookup_hash_it(&this, base, it);
+ access:
+       return ERR_PTR(-EACCES);
+ }
++/* SMP-safe */
++struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
++{
++      return lookup_one_len_it(name, base, len, NULL);
++}
++
+ /*
+  *    namei()
+  *
+diff -urN linux/fs/nfsd/export.c linux_n/fs/nfsd/export.c
+--- linux/fs/nfsd/export.c     2003-01-21 04:00:34.000000000 +0530
++++ linux_n/fs/nfsd/export.c   2003-06-18 21:39:42.000000000 +0530
+@@ -289,6 +289,7 @@
+        *       either using fh_to_dentry (prefered)
+        *       or using read_inode (the hack).
+        */
++/*
+       if (!((inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV)
+             || (nxp->ex_flags & NFSEXP_FSID))
+           ||
+@@ -297,7 +298,7 @@
+               dprintk("exp_export: export of invalid fs type.\n");
+               goto finish;
+       }
+-
++*/
+       if ((parent = exp_child(clp, dev, nd.dentry)) != NULL) {
+               dprintk("exp_export: export not valid (Rule 3).\n");
+               goto finish;
+diff -urN linux/fs/nfsd/nfsfh.c linux_n/fs/nfsd/nfsfh.c
+--- linux/fs/nfsd/nfsfh.c      2003-01-21 04:00:34.000000000 +0530
++++ linux_n/fs/nfsd/nfsfh.c    2003-06-18 21:39:42.000000000 +0530
+@@ -60,6 +60,11 @@
+       return result;
+ }
++static struct dentry * lookup2(struct inode *inode, struct dentry *dentry)
++{
++    return inode->i_op->lookup2(inode, dentry, NULL);
++}
++
+ /**
+  * nfsd_get_name - default nfsd_operations->get_name function
+  * @dentry: the directory in which to find a name
+@@ -275,7 +280,10 @@
+        * it is well connected.  But nobody returns different dentrys do they?
+        */
+       down(&child->d_inode->i_sem);
+-      pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
++      if (child->d_inode->i_op->lookup2)
++             pdentry = lookup2(child->d_inode, tdentry);
++        else
++             pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
+       up(&child->d_inode->i_sem);
+       d_drop(tdentry); /* we never want ".." hashed */
+       if (!pdentry && tdentry->d_inode == NULL) {
+@@ -666,6 +674,9 @@
+       }
+       inode = dentry->d_inode;
++      
++      if (inode->i_op && inode->i_op->revalidate)     //girish:- to keep (lustre)cache coherency
++              inode->i_op->revalidate(dentry);
+       /* Type check. The correct error return for type mismatches
+        * does not seem to be generally agreed upon. SunOS seems to
+@@ -905,8 +916,9 @@
+               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->mkdir2)
++              printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
++                      dentry->d_parent->d_name.name, dentry->d_name.name);
+       goto out;
+ }
+diff -urN linux/fs/nfsd/nfsproc.c linux_n/fs/nfsd/nfsproc.c
+--- linux/fs/nfsd/nfsproc.c    2003-01-21 04:00:34.000000000 +0530
++++ linux_n/fs/nfsd/nfsproc.c  2003-06-18 21:39:30.000000000 +0530
+@@ -199,6 +199,7 @@
+       struct dentry   *dchild;
+       int             nfserr, type, mode;
+       dev_t           rdev = NODEV;
++    struct lookup_intent it = { .it_op = IT_CREAT };
+       dprintk("nfsd: CREATE   %s %.*s\n",
+               SVCFH_fmt(dirfhp), argp->len, argp->name);
+@@ -217,7 +218,7 @@
+       if (isdotent(argp->name, argp->len))
+               goto done;
+       fh_lock(dirfhp);
+-      dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len);
++      dchild = lookup_one_len_it(argp->name, dirfhp->fh_dentry, argp->len, &it);
+       if (IS_ERR(dchild)) {
+               nfserr = nfserrno(PTR_ERR(dchild));
+               goto out_unlock;
+diff -urN linux/fs/nfsd/vfs.c linux_n/fs/nfsd/vfs.c
+--- linux/fs/nfsd/vfs.c        2003-06-18 21:39:13.000000000 +0530
++++ linux_n/fs/nfsd/vfs.c      2003-06-18 21:41:40.000000000 +0530
+@@ -77,6 +77,75 @@
+ static struct raparms *               raparml;
+ static struct raparms *               raparm_cache;
++
++static int link2(struct inode *src, struct inode *dir, const char *name, int len, struct dentry *dnew)
++{
++      int error;
++      
++      error = dir->i_op->link2(src, dir, name, len);
++      d_instantiate(dnew, src);
++      if(src->i_op && src->i_op->revalidate)
++              src->i_op->revalidate(dnew);
++              
++      return error;
++}
++
++static int unlink2(struct inode *dir, const char *name, int len)
++{
++      return dir->i_op->unlink2(dir, name, len);
++}
++
++static int symlink2(struct inode *dir, const char *name, int len, const char *tgt)
++{
++      return dir->i_op->symlink2(dir, name, len, tgt);
++} 
++
++static int mkdir2(struct inode *dir, const char *name, int len, int mode)
++{
++      return dir->i_op->mkdir2(dir, name, len, mode);
++}
++
++static int rmdir2(struct inode *dir, const char *name, int len)
++{
++      return dir->i_op->rmdir2(dir, name, len);
++}     
++
++static int mknod2(struct inode *dir, const char *name, int len, int mode, int rdev)
++{
++    return dir->i_op->mknod(dir, name, len, mode);
++}
++
++static int rename2(struct inode *src, struct inode *tgt, struct dentry *odentry, struct dentry *ndentry)
++{
++      int err;
++
++      err = src->i_op->rename2(src,
++                                      tgt, 
++                                      odentry->d_name.name,
++                                      odentry->d_name.len,
++                                      ndentry->d_name.name,
++                                      ndentry->d_name.len);
++      d_move(odentry, ndentry);
++
++      return err;
++}     
++
++static int open2(struct dentry *dentry, struct lookup_intent *it)
++{
++      int err = 0;
++      
++      if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
++              if (!dentry->d_op->d_revalidate2(dentry, 0, it) && !d_invalidate(dentry)) {
++                      dput(dentry);
++                      err = -EINVAL;
++                      dentry = NULL;
++                      return err;
++              }       
++      }
++
++      return err;
++}
++
+ /*
+  * Look up one component of a pathname.
+  * N.B. After this call _both_ fhp and resfh need an fh_put
+@@ -425,9 +494,11 @@
+ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
+                       int access, struct file *filp)
+ {
+-      struct dentry   *dentry;
+-      struct inode    *inode;
+-      int             err;
++        struct dentry   *dentry;
++        struct inode    *inode;
++        int             err;
++
++      struct lookup_intent it = { .it_op = IT_OPEN };
+       /* If we get here, then the client has already done an "open", and (hopefully)
+        * checked permission - so allow OWNER_OVERRIDE in case a chmod has now revoked
+@@ -472,7 +543,9 @@
+               filp->f_flags = O_RDONLY|O_LARGEFILE;
+               filp->f_mode  = FMODE_READ;
+       }
+-
++      if(err = open2(dentry, &it))
++              goto out_nfserr;
++      
+       err = 0;
+       if (filp->f_op && filp->f_op->open) {
+               err = filp->f_op->open(inode, filp);
+@@ -487,6 +560,8 @@
+                       atomic_dec(&filp->f_count);
+               }
+       }
++      intent_release(dentry, &it);
++      
+ out_nfserr:
+       if (err)
+               err = nfserrno(err);
+@@ -825,6 +900,7 @@
+       struct dentry   *dentry, *dchild;
+       struct inode    *dirp;
+       int             err;
++      int             error = -EOPNOTSUPP;
+       err = nfserr_perm;
+       if (!flen)
+@@ -839,9 +915,25 @@
+       dentry = fhp->fh_dentry;
+       dirp = dentry->d_inode;
++      
++      switch (type) {
++      case S_IFDIR:
++                      if (dirp->i_op->mkdir2) 
++                      error = mkdir2(dirp, fname, flen, iap->ia_mode);
++              break;
++      case S_IFCHR:
++      case S_IFBLK:
++      case S_IFIFO:
++      case S_IFSOCK:
++                      if (dirp->i_op->mknod2) 
++                      error = mknod2(dirp, fname, flen, iap->ia_mode, rdev);
++              break;
++      default:
++              printk("nfsd: bad file type %o in nfsd_create\n", type);
++      }
+       err = nfserr_notdir;
+-      if(!dirp->i_op || !dirp->i_op->lookup)
++      if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup2))
+               goto out;
+       /*
+        * Check whether the response file handle has been verified yet.
+@@ -874,11 +966,13 @@
+        * Make sure the child dentry is still negative ...
+        */
+       err = nfserr_exist;
+-      if (dchild->d_inode) {
+-              dprintk("nfsd_create: dentry %s/%s not negative!\n",
+-                      dentry->d_name.name, dchild->d_name.name);
+-              goto out; 
+-      }
++      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; 
++              }
++        }
+       if (!(iap->ia_valid & ATTR_MODE))
+               iap->ia_mode = 0;
+@@ -893,13 +987,16 @@
+               err = vfs_create(dirp, dchild, iap->ia_mode);
+               break;
+       case S_IFDIR:
+-              err = vfs_mkdir(dirp, dchild, iap->ia_mode);
++              if ( error == -EOPNOTSUPP)
++                      err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+               break;
+       case S_IFCHR:
+       case S_IFBLK:
+       case S_IFIFO:
+       case S_IFSOCK:
+-              err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
++              err = error;
++              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);
+@@ -949,6 +1046,7 @@
+       int             err;
+       __u32           v_mtime=0, v_atime=0;
+       int             v_mode=0;
++      struct lookup_intent it = { .it_op = IT_CREAT|IT_OPEN, .it_flags = 35137, .it_mode = iap->ia_mode };
+       err = nfserr_perm;
+       if (!flen)
+@@ -968,17 +1066,22 @@
+       /* Get all the sanity checks out of the way before
+        * we lock the parent. */
+       err = nfserr_notdir;
+-      if(!dirp->i_op || !dirp->i_op->lookup)
++      if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup2))
+               goto out;
+       fh_lock(fhp);
+       /*
+        * Compose the response file handle.
+        */
+-      dchild = lookup_one_len(fname, dentry, flen);
++      if (dirp->i_op->lookup2) {
++              dchild = lookup_one_len_it(fname, dentry, flen, &it);
++      } else
++              dchild = lookup_one_len(fname, dentry, flen);
++
+       err = PTR_ERR(dchild);
+-      if (IS_ERR(dchild))
++      if (IS_ERR(dchild)) {
+               goto out_nfserr;
++      }
+       err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
+       if (err)
+@@ -1023,6 +1126,7 @@
+       }
+       err = vfs_create(dirp, dchild, iap->ia_mode);
++
+       if (err < 0)
+               goto out_nfserr;
+@@ -1047,6 +1151,8 @@
+               iap->ia_atime = v_atime;
+               iap->ia_mode  = v_mode;
+       }
++      
++      iap->ia_valid |= ATTR_FROM_OPEN; 
+       /* Set file attributes.
+        * Mode has already been set but we might need to reset it
+@@ -1058,6 +1164,9 @@
+       if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0)
+               err = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
++      if (dirp->i_op->lookup2) {
++              intent_release(dchild, &it);
++      }
+  out:
+       fh_unlock(fhp);
+       return err;
+@@ -1125,7 +1234,7 @@
+                               struct iattr *iap)
+ {
+       struct dentry   *dentry, *dnew;
+-      int             err, cerr;
++      int             err, cerr, error;
+       err = nfserr_noent;
+       if (!flen || !plen)
+@@ -1139,12 +1248,19 @@
+               goto out;
+       fh_lock(fhp);
+       dentry = fhp->fh_dentry;
++      
++      if (dentry->d_inode->i_op->symlink2) 
++              error = symlink2(dentry->d_inode, fname, flen, path);
++              
+       dnew = lookup_one_len(fname, dentry, flen);
+       err = PTR_ERR(dnew);
+       if (IS_ERR(dnew))
+               goto out_nfserr;
+-      err = vfs_symlink(dentry->d_inode, dnew, path);
++      err = error;
++      if (error == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink2) 
++              err = vfs_symlink(dentry->d_inode, dnew, path);
++
+       if (!err) {
+               if (EX_ISSYNC(fhp->fh_export))
+                       nfsd_sync_dir(dentry);
+@@ -1212,7 +1328,12 @@
+       dold = tfhp->fh_dentry;
+       dest = dold->d_inode;
+-      err = vfs_link(dold, dirp, dnew);
++      if (dirp->i_op->link2) 
++              err = link2(dest, dirp, name, len, dnew);
++
++      if (err == -EOPNOTSUPP || !dirp->i_op->link2) 
++             err = vfs_link(dold, dirp, dnew);
++
+       if (!err) {
+               if (EX_ISSYNC(ffhp->fh_export)) {
+                       nfsd_sync_dir(ddir);
+@@ -1298,8 +1419,13 @@
+                       err = nfserr_perm;
+       } else
+ #endif
+-      err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
++      if(fdir->i_op->rename2) 
++              err = rename2(fdir, tdir, odentry, ndentry);
++      else
++          if(err == -EOPNOTSUPP || !fdir->i_op->rename2)      
++              err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
+       unlock_kernel();
++      
+       if (!err && EX_ISSYNC(tfhp->fh_export)) {
+               nfsd_sync_dir(tdentry);
+               nfsd_sync_dir(fdentry);
+@@ -1366,9 +1492,17 @@
+                       err = nfserr_perm;
+               } else
+ #endif
+-              err = vfs_unlink(dirp, rdentry);
++              {
++        if (dirp->i_op->unlink2)
++              err = unlink2(dirp, fname, flen);
++        if( err == -EOPNOTSUPP || !dirp->i_op->unlink2)
++          err = vfs_unlink(dirp, rdentry);
++        }
+       } else { /* It's RMDIR */
+-              err = vfs_rmdir(dirp, rdentry);
++              if (dirp->i_op->rmdir2)
++          err = rmdir2(dirp, fname, flen);
++              if( err == -EOPNOTSUPP || !dirp->i_op->rmdir2)  
++                      err = vfs_rmdir(dirp, rdentry);
+       }
+       dput(rdentry);
+diff -urN linux/include/linux/fs.h linux_n/include/linux/fs.h
+--- linux/include/linux/fs.h   2003-06-18 21:39:14.000000000 +0530
++++ linux_n/include/linux/fs.h 2003-06-18 21:39:53.000000000 +0530
+@@ -1407,6 +1407,7 @@
+ extern void path_release(struct nameidata *);
+ extern int follow_down(struct vfsmount **, struct dentry **);
+ extern int follow_up(struct vfsmount **, struct dentry **);
++extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int, struct lookup_intent *);
+ extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
+ extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
+ #define user_path_walk(name,nd)        __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
+@@ -1421,6 +1422,7 @@
+ extern ino_t iunique(struct super_block *, ino_t);
+ typedef int (*find_inode_t)(struct inode *, unsigned long, void *);
++extern struct inode * search_icache_for_lustre(struct super_block *, unsigned long);
+ extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *);
+ static inline struct inode *iget(struct super_block *sb, unsigned long ino)
+ {
+diff -urN linux/kernel/ksyms.c linux_n/kernel/ksyms.c
+--- linux/kernel/ksyms.c       2003-06-18 21:39:13.000000000 +0530
++++ linux_n/kernel/ksyms.c     2003-06-18 21:39:53.000000000 +0530
+@@ -154,6 +154,7 @@
+ EXPORT_SYMBOL(fget);
+ EXPORT_SYMBOL(igrab);
+ EXPORT_SYMBOL(iunique);
++EXPORT_SYMBOL(search_icache_for_lustre);
+ EXPORT_SYMBOL(iget4);
+ EXPORT_SYMBOL(iput);
+ EXPORT_SYMBOL(inode_init_once);
+@@ -165,6 +166,7 @@
+ EXPORT_SYMBOL(path_walk);
+ EXPORT_SYMBOL(path_release);
+ EXPORT_SYMBOL(__user_walk);
++EXPORT_SYMBOL(lookup_one_len_it);
+ EXPORT_SYMBOL(lookup_one_len);
+ EXPORT_SYMBOL(lookup_hash);
+ EXPORT_SYMBOL(sys_close);