Whamcloud - gitweb
LU-1718 client: Restore NFS export for Lustre on 3.X kernels
authorJames Simmons <uja.ornl@gmail.com>
Mon, 27 Aug 2012 18:55:07 +0000 (14:55 -0400)
committerOleg Drokin <green@whamcloud.com>
Sun, 7 Oct 2012 05:01:29 +0000 (01:01 -0400)
In Linux 3.0+ kernels struct file_system_type changed the
get_sb function to a new function called mount which was
different in that the vfsmount data was no longer passed in.
The vfsmount data was used by the llite layer for nfs export
function called get_name to search for filp that was then used
with the ll_readdir method. The approach to solve this change
was to go the route of btrfs and gfs2 to refactor some of the
llite methods to implement a directory scan independent of
filp which could be shared with nfs export funtionality.

Signed-off-by: James Simmons <uja.ornl@gmail.com>
Change-Id: I72730476b120cec1ede6e03c774c9e470a1a5a70
Reviewed-on: http://review.whamcloud.com/3624
Tested-by: Hudson
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
lustre/llite/dir.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/llite_nfs.c
lustre/llite/statahead.c

index 1554eca..3965d20 100644 (file)
  */
 
 /* returns the page unlocked, but with a reference */
-static int ll_dir_readpage(struct file *file, struct page *page0)
+static int ll_dir_filler(void *_hash, struct page *page0)
 {
         struct inode *inode = page0->mapping->host;
         int hash64 = ll_i2sbi(inode)->ll_flags & LL_SBI_64BIT_HASH;
@@ -147,7 +147,7 @@ static int ll_dir_readpage(struct file *file, struct page *page0)
         struct ptlrpc_request *request;
         struct mdt_body *body;
         struct md_op_data *op_data;
-        __u64 hash;
+       __u64 hash = *((__u64 *)_hash);
         struct page **page_pool;
         struct page *page;
 #ifndef HAVE_ADD_TO_PAGE_CACHE_LRU
@@ -161,13 +161,6 @@ static int ll_dir_readpage(struct file *file, struct page *page0)
         int rc;
         ENTRY;
 
-        if (file) {
-                struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
-
-                hash = fd->fd_dir.lfd_next;
-        } else {
-                hash = ll_i2info(inode)->lli_sa_pos;
-        }
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) hash "LPU64"\n",
                inode->i_ino, inode->i_generation, inode, hash);
 
@@ -251,16 +244,6 @@ static int ll_dir_readpage(struct file *file, struct page *page0)
         return rc;
 }
 
-#ifndef MS_HAS_NEW_AOPS
-struct address_space_operations ll_dir_aops = {
-        .readpage  = ll_dir_readpage,
-};
-#else
-struct address_space_operations_ext ll_dir_aops = {
-        .orig_aops.readpage  = ll_dir_readpage,
-};
-#endif
-
 static void ll_check_page(struct inode *dir, struct page *page)
 {
         /* XXX: check page format later */
@@ -310,7 +293,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
                  * hence, can avoid restart.
                  *
                  * In fact, page cannot be locked here at all, because
-                 * ll_dir_readpage() does synchronous io.
+                * ll_dir_filler() does synchronous io.
                  */
                 wait_on_page(page);
                 if (PageUptodate(page)) {
@@ -353,7 +336,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
         return page;
 }
 
-struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
+struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
                              struct ll_dir_chain *chain)
 {
         ldlm_policy_data_t policy = {.l_inodebits = {MDS_INODELOCK_UPDATE} };
@@ -431,7 +414,7 @@ struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
         }
 
         page = read_cache_page(mapping, hash_x_index(hash, hash64),
-                               (filler_t*)mapping->a_ops->readpage, filp);
+                              ll_dir_filler, &lhash);
         if (IS_ERR(page)) {
                 CERROR("read cache page: "DFID" at "LPU64": rc %ld\n",
                        PFID(ll_inode2fid(dir)), hash, PTR_ERR(page));
@@ -489,37 +472,23 @@ fail:
         goto out_unlock;
 }
 
-int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
+int ll_dir_read(struct inode *inode, __u64 *_pos, void *cookie,
+               filldir_t filldir)
 {
-        struct inode         *inode      = filp->f_dentry->d_inode;
         struct ll_inode_info *info       = ll_i2info(inode);
         struct ll_sb_info    *sbi        = ll_i2sbi(inode);
-        struct ll_file_data  *fd         = LUSTRE_FPRIVATE(filp);
-        __u64                 pos        = fd->fd_dir.lfd_pos;
+       __u64                 pos        = *_pos;
         int                   api32      = ll_need_32bit_api(sbi);
         int                   hash64     = sbi->ll_flags & LL_SBI_64BIT_HASH;
         struct page          *page;
         struct ll_dir_chain   chain;
-        int                   done;
-        int                   rc;
+       int                   done = 0;
+       int                   rc = 0;
         ENTRY;
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu 32bit_api %d\n",
-               inode->i_ino, inode->i_generation, inode,
-               (unsigned long)pos, i_size_read(inode), api32);
-
-        if (pos == MDS_DIR_END_OFF)
-                /*
-                 * end-of-file.
-                 */
-                GOTO(out, rc = 0);
-
-        rc    = 0;
-        done  = 0;
         ll_dir_chain_init(&chain);
 
-        fd->fd_dir.lfd_next = pos;
-        page = ll_get_dir_page(filp, inode, pos, &chain);
+       page = ll_get_dir_page(inode, pos, &chain);
 
         while (rc == 0 && !done) {
                 struct lu_dirpage *dp;
@@ -592,8 +561,8 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
                                         ll_release_page(page,
                                             le32_to_cpu(dp->ldp_flags) &
                                                         LDF_COLLIDE);
-                                        fd->fd_dir.lfd_next = pos;
-                                        page = ll_get_dir_page(filp, inode, pos,
+                                       next = pos;
+                                       page = ll_get_dir_page(inode, pos,
                                                                &chain);
                                 } else {
                                         /*
@@ -614,7 +583,34 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
                 }
         }
 
-        fd->fd_dir.lfd_pos = pos;
+       *_pos = pos;
+       ll_dir_chain_fini(&chain);
+       RETURN(rc);
+}
+
+static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
+{
+       struct inode            *inode  = filp->f_dentry->d_inode;
+       struct ll_file_data     *lfd    = LUSTRE_FPRIVATE(filp);
+       struct ll_sb_info       *sbi    = ll_i2sbi(inode);
+       __u64                   pos     = lfd->lfd_pos;
+       int                     hash64  = sbi->ll_flags & LL_SBI_64BIT_HASH;
+       int                     api32   = ll_need_32bit_api(sbi);
+       int                     rc;
+       ENTRY;
+
+       CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu "
+              " 32bit_api %d\n", inode->i_ino, inode->i_generation,
+              inode, (unsigned long)pos, i_size_read(inode), api32);
+
+       if (pos == MDS_DIR_END_OFF)
+               /*
+                * end-of-file.
+                */
+               GOTO(out, rc = 0);
+
+       rc = ll_dir_read(inode, &pos, cookie, filldir);
+       lfd->lfd_pos = pos;
         if (pos == MDS_DIR_END_OFF) {
                 if (api32)
                         filp->f_pos = LL_DIR_END_OFF_32BIT;
@@ -629,8 +625,6 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
         filp->f_version = inode->i_version;
         touch_atime(filp->f_vfsmnt, filp->f_dentry);
 
-        ll_dir_chain_fini(&chain);
-
 out:
         if (!rc)
                 ll_stats_ops_tally(sbi, LPROC_LL_READDIR, 1);
@@ -1511,11 +1505,11 @@ static loff_t ll_dir_seek(struct file *file, loff_t offset, int origin)
                 if (offset != file->f_pos) {
                         if ((api32 && offset == LL_DIR_END_OFF_32BIT) ||
                             (!api32 && offset == LL_DIR_END_OFF))
-                                fd->fd_dir.lfd_pos = MDS_DIR_END_OFF;
+                               fd->lfd_pos = MDS_DIR_END_OFF;
                         else if (api32 && sbi->ll_flags & LL_SBI_64BIT_HASH)
-                                fd->fd_dir.lfd_pos = offset << 32;
+                               fd->lfd_pos = offset << 32;
                         else
-                                fd->fd_dir.lfd_pos = offset;
+                               fd->lfd_pos = offset;
                         file->f_pos = offset;
                         file->f_version = 0;
                 }
index a6c1221..ab60e58 100644 (file)
@@ -192,7 +192,6 @@ struct ll_inode_info {
                          * cleanup the dir readahead. */
                         void                           *d_opendir_key;
                         struct ll_statahead_info       *d_sai;
-                        __u64                           d_sa_pos;
                         struct posix_acl               *d_def_acl;
                         /* protect statahead stuff. */
                         cfs_spinlock_t                  d_sa_lock;
@@ -204,7 +203,6 @@ struct ll_inode_info {
 #define lli_readdir_mutex       u.d.d_readdir_mutex
 #define lli_opendir_key         u.d.d_opendir_key
 #define lli_sai                 u.d.d_sai
-#define lli_sa_pos              u.d.d_sa_pos
 #define lli_def_acl             u.d.d_def_acl
 #define lli_sa_lock             u.d.d_sa_lock
 #define lli_opendir_pid         u.d.d_opendir_pid
@@ -491,7 +489,6 @@ struct ll_sb_info {
                                                  * clustred nfs */
         struct rmtacl_ctl_table   ll_rct;
         struct eacl_table         ll_et;
-        struct vfsmount          *ll_mnt;
 };
 
 #define LL_DEFAULT_MAX_RW_CHUNK      (32 * 1024 * 1024)
@@ -589,18 +586,13 @@ struct ll_readahead_state {
         unsigned long   ras_consecutive_stride_requests;
 };
 
-struct ll_file_dir {
-        __u64 lfd_pos;
-        __u64 lfd_next;
-};
-
 extern cfs_mem_cache_t *ll_file_data_slab;
 struct lustre_handle;
 struct ll_file_data {
         struct ll_readahead_state fd_ras;
         int fd_omode;
         struct ccc_grouplock fd_grouplock;
-        struct ll_file_dir fd_dir;
+       __u64 lfd_pos;
         __u32 fd_flags;
         struct file *fd_file;
        /* Indicate whether need to report failure when close.
@@ -670,9 +662,10 @@ static void lprocfs_llite_init_vars(struct lprocfs_static_vars *lvars)
 void ll_release_page(struct page *page, int remove);
 extern struct file_operations ll_dir_operations;
 extern struct inode_operations ll_dir_inode_operations;
-struct page *ll_get_dir_page(struct file *filp, struct inode *dir, __u64 hash,
+struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
                              struct ll_dir_chain *chain);
-int ll_readdir(struct file *filp, void *cookie, filldir_t filldir);
+int ll_dir_read(struct inode *inode, __u64 *_pos, void *cookie,
+               filldir_t filldir);
 
 int ll_get_mdt_idx(struct inode *inode);
 char *ll_get_fsname(struct inode *inode);
index f3210d7..9769ec3 100644 (file)
@@ -63,10 +63,8 @@ DEFINE_SPINLOCK(ll_sb_lock);
 
 #ifndef MS_HAS_NEW_AOPS
 extern struct address_space_operations ll_aops;
-extern struct address_space_operations ll_dir_aops;
 #else
 extern struct address_space_operations_ext ll_aops;
-extern struct address_space_operations_ext ll_dir_aops;
 #endif
 
 #ifndef log2
@@ -469,7 +467,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
         CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&sbi->ll_root_fid));
 
         sb->s_op = &lustre_super_operations;
-#if THREAD_SIZE >= 8192 /*b=17630*/ && !defined(HAVE_FSTYPE_MOUNT) /*LU-812*/
+#if THREAD_SIZE >= 8192 /*b=17630*/
         sb->s_export_op = &lustre_export_operations;
 #endif
 
@@ -564,7 +562,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
         uuid = obd_get_uuid(sbi->ll_md_exp);
         if (uuid != NULL)
                 sb->s_dev = get_uuid2int(uuid->uuid, strlen(uuid->uuid));
-        sbi->ll_mnt = mnt;
 
         if (data != NULL)
                 OBD_FREE_PTR(data);
@@ -912,7 +909,6 @@ void ll_lli_init(struct ll_inode_info *lli)
                 cfs_mutex_init(&lli->lli_readdir_mutex);
                 lli->lli_opendir_key = NULL;
                 lli->lli_sai = NULL;
-                lli->lli_sa_pos = 0;
                 lli->lli_def_acl = NULL;
                 cfs_spin_lock_init(&lli->lli_sa_lock);
                 lli->lli_opendir_pid = 0;
@@ -1845,7 +1841,6 @@ void ll_read_inode2(struct inode *inode, void *opaque)
         } else if (S_ISDIR(inode->i_mode)) {
                 inode->i_op = &ll_dir_inode_operations;
                 inode->i_fop = &ll_dir_operations;
-                inode->i_mapping->a_ops = (struct address_space_operations *)&ll_dir_aops;
                 EXIT;
         } else if (S_ISLNK(inode->i_mode)) {
                 inode->i_op = &ll_fast_symlink_inode_operations;
index 809a564..1f18337 100644 (file)
@@ -217,8 +217,8 @@ static int ll_get_name(struct dentry *dentry, char *name,
                        struct dentry *child)
 {
         struct inode *dir = dentry->d_inode;
-        struct file *filp;
         struct ll_getname_data lgd;
+       __u64 offset = 0;
         int rc;
         ENTRY;
 
@@ -228,27 +228,17 @@ static int ll_get_name(struct dentry *dentry, char *name,
         if (!dir->i_fop)
                 GOTO(out, rc = -EINVAL);
 
-        filp = ll_dentry_open(dget(dentry), mntget(ll_i2sbi(dir)->ll_mnt),
-                              O_RDONLY, current_cred());
-        if (IS_ERR(filp))
-                GOTO(out, rc = PTR_ERR(filp));
-
-        if (!filp->f_op->readdir)
-                GOTO(out_close, rc = -EINVAL);
-
         lgd.lgd_name = name;
         lgd.lgd_fid = ll_i2info(child->d_inode)->lli_fid;
         lgd.lgd_found = 0;
 
         cfs_mutex_lock(&dir->i_mutex);
-        rc = ll_readdir(filp, &lgd, ll_nfs_get_name_filldir);
+       rc = ll_dir_read(dir, &offset, &lgd, ll_nfs_get_name_filldir);
         cfs_mutex_unlock(&dir->i_mutex);
         if (!rc && !lgd.lgd_found)
                 rc = -ENOENT;
         EXIT;
 
-out_close:
-        fput(filp);
 out:
         return rc;
 }
index ce04b27..5cf4b9c 100644 (file)
@@ -1117,9 +1117,8 @@ static int ll_statahead_thread(void *arg)
         cfs_spin_unlock(&plli->lli_sa_lock);
         cfs_waitq_signal(&thread->t_ctl_waitq);
 
-        plli->lli_sa_pos = 0;
         ll_dir_chain_init(&chain);
-        page = ll_get_dir_page(NULL, dir, pos, &chain);
+       page = ll_get_dir_page(dir, pos, &chain);
 
         while (1) {
                 struct lu_dirpage *dp;
@@ -1276,9 +1275,8 @@ do_it:
                          */
                         ll_release_page(page, le32_to_cpu(dp->ldp_flags) &
                                               LDF_COLLIDE);
-                        plli->lli_sa_pos = pos;
                         sai->sai_in_readpage = 1;
-                        page = ll_get_dir_page(NULL, dir, pos, &chain);
+                       page = ll_get_dir_page(dir, pos, &chain);
                         sai->sai_in_readpage = 0;
                 } else {
                         LASSERT(le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
@@ -1394,7 +1392,6 @@ enum {
 
 static int is_first_dirent(struct inode *dir, struct dentry *dentry)
 {
-        struct ll_inode_info *lli    = ll_i2info(dir);
         struct ll_dir_chain   chain;
         struct qstr          *target = &dentry->d_name;
         struct page          *page;
@@ -1403,9 +1400,8 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
         int                   rc     = LS_NONE_FIRST_DE;
         ENTRY;
 
-        lli->lli_sa_pos = 0;
         ll_dir_chain_init(&chain);
-        page = ll_get_dir_page(NULL, dir, pos, &chain);
+       page = ll_get_dir_page(dir, pos, &chain);
 
         while (1) {
                 struct lu_dirpage *dp;
@@ -1492,8 +1488,7 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
                          */
                         ll_release_page(page, le32_to_cpu(dp->ldp_flags) &
                                               LDF_COLLIDE);
-                        lli->lli_sa_pos = pos;
-                        page = ll_get_dir_page(NULL, dir, pos, &chain);
+                       page = ll_get_dir_page(dir, pos, &chain);
                 } else {
                         /*
                          * go into overflow page.