Whamcloud - gitweb
LU-3974 llite: use new struct dir_context 47/7747/14
authorJames Simmons <uja.ornl@gmail.com>
Thu, 13 Feb 2014 00:51:44 +0000 (19:51 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 1 Mar 2014 02:42:29 +0000 (02:42 +0000)
The readdir and nfs code over time has added more
parameters to be passed to be processed. For the 3.11
kernel a new struct dir_context was introduced to
minimize the impact of future expansion. This patch
addresses this change.

Signed-off-by: James Simmons <uja.ornl@gmail.com>
Change-Id: Ib42bf8cb06635a2a64e63b294d79e66ac82a1a5b
Reviewed-on: http://review.whamcloud.com/7747
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Reviewed-by: Peng Tao <bergwolf@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/autoconf/lustre-core.m4
lustre/llite/dir.c
lustre/llite/llite_internal.h
lustre/llite/llite_nfs.c

index 1d964cb..a3037e3 100644 (file)
@@ -1308,6 +1308,25 @@ LB_LINUX_TRY_COMPILE([
 ])
 
 #
+# 3.11 readdir now takes the new struct dir_context
+#
+AC_DEFUN([LC_HAVE_DIR_CONTEXT],
+[AC_MSG_CHECKING([if dir_context exist])
+LB_LINUX_TRY_COMPILE([
+       #include <linux/fs.h>
+],[
+       struct dir_context ctx;
+
+       ctx.pos = 0;
+],[
+       AC_DEFINE(HAVE_DIR_CONTEXT, 1, [dir_context exist])
+       AC_MSG_RESULT([yes])
+],[
+       AC_MSG_RESULT([no])
+])
+])
+
+#
 # 3.11 dentry_operations.d_compare() taken 5 arguments.
 #
 AC_DEFUN([LC_D_COMPARE_5ARGS],
@@ -1480,6 +1499,7 @@ AC_DEFUN([LC_PROG_LINUX],
         LC_BLKDEV_RELEASE_RETURN_INT
 
         # 3.11
+        LC_HAVE_DIR_CONTEXT
         LC_D_COMPARE_5ARGS
         LC_HAVE_DCOUNT
 
index 136b9b3..5775cc8 100644 (file)
@@ -195,9 +195,15 @@ struct lu_dirent *ll_dir_entry_next(struct inode *dir,
        return entry;
 }
 
+#ifdef HAVE_DIR_CONTEXT
+int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
+               struct dir_context *ctx)
+{
+#else
 int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
                void *cookie, filldir_t filldir)
 {
+#endif
        struct ll_sb_info       *sbi = ll_i2sbi(inode);
        struct ll_dir_chain     chain;
        struct lu_dirent        *ent;
@@ -241,12 +247,17 @@ int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
                fid_le_to_cpu(&fid, &ent->lde_fid);
                ino = cl_fid_build_ino(&fid, api32);
                type = ll_dirent_type_get(ent);
+
+#ifdef HAVE_DIR_CONTEXT
                /* For 'll_nfs_get_name_filldir()', it will try
                 * to access the 'ent' through its 'lde_name',
                 * so the parameter 'name' for 'filldir()' must
                 * be part of the 'ent'. */
+               done = !dir_emit(ctx, ent->lde_name, namelen, ino, type);
+#else
                done = filldir(cookie, ent->lde_name, namelen, lhash,
                               ino, type);
+#endif
                if (done) {
                        if (op_data->op_hash_offset != MDS_DIR_END_OFF)
                                op_data->op_hash_offset = last_hash;
@@ -268,7 +279,11 @@ int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
        RETURN(rc);
 }
 
+#ifdef HAVE_DIR_CONTEXT
+static int ll_iterate(struct file *filp, struct dir_context *ctx)
+#else
 static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
+#endif
 {
        struct inode            *inode  = filp->f_dentry->d_inode;
        struct ll_file_data     *lfd    = LUSTRE_FPRIVATE(filp);
@@ -302,22 +317,32 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
 
        op_data->op_hash_offset = pos;
        op_data->op_max_pages = sbi->ll_md_brw_size >> PAGE_CACHE_SHIFT;
+#ifdef HAVE_DIR_CONTEXT
+       ctx->pos = pos;
+       rc = ll_dir_read(inode, op_data, ctx);
+       pos = ctx->pos;
+#else
        rc = ll_dir_read(inode, op_data, cookie, filldir);
+#endif
        if (lfd != NULL)
                lfd->lfd_pos = op_data->op_hash_offset;
 
        if (pos == MDS_DIR_END_OFF) {
                if (api32)
-                       filp->f_pos = LL_DIR_END_OFF_32BIT;
+                       pos = LL_DIR_END_OFF_32BIT;
                else
-                       filp->f_pos = LL_DIR_END_OFF;
+                       pos = LL_DIR_END_OFF;
        } else {
                if (api32 && hash64)
-                       filp->f_pos = op_data->op_hash_offset >> 32;
+                       pos = op_data->op_hash_offset >> 32;
                else
-                       filp->f_pos = op_data->op_hash_offset;
+                       pos = op_data->op_hash_offset;
        }
-
+#ifdef HAVE_DIR_CONTEXT
+       ctx->pos = pos;
+#else
+       filp->f_pos = pos;
+#endif
        ll_finish_md_op_data(op_data);
        filp->f_version = inode->i_version;
 
@@ -1827,11 +1852,15 @@ int ll_dir_release(struct inode *inode, struct file *file)
 }
 
 struct file_operations ll_dir_operations = {
-        .llseek   = ll_dir_seek,
-        .open     = ll_dir_open,
-        .release  = ll_dir_release,
-        .read     = generic_read_dir,
-        .readdir  = ll_readdir,
-        .unlocked_ioctl   = ll_dir_ioctl,
-        .fsync    = ll_fsync,
+       .llseek         = ll_dir_seek,
+       .open           = ll_dir_open,
+       .release        = ll_dir_release,
+       .read           = generic_read_dir,
+#ifdef HAVE_DIR_CONTEXT
+       .iterate        = ll_iterate,
+#else
+       .readdir        = ll_readdir,
+#endif
+       .unlocked_ioctl = ll_dir_ioctl,
+       .fsync          = ll_fsync,
 };
index fb8b666..19ec0e8 100644 (file)
@@ -92,9 +92,12 @@ extern struct file_operations ll_pgcache_seq_fops;
 #define REMOTE_PERM_HASHSIZE 16
 
 struct ll_getname_data {
-        char            *lgd_name;      /* points to a buffer with NAME_MAX+1 size */
-        struct lu_fid    lgd_fid;       /* target fid we are looking for */
-        int              lgd_found;     /* inode matched? */
+#ifdef HAVE_DIR_CONTEXT
+       struct dir_context      ctx;
+#endif
+       char            *lgd_name;      /* points to a buffer with NAME_MAX+1 size */
+       struct lu_fid   lgd_fid;        /* target fid we are looking for */
+       int             lgd_found;      /* inode matched? */
 };
 
 /* llite setxid/access permission for user on remote client */
@@ -726,8 +729,13 @@ static void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) {}
 /* llite/dir.c */
 extern struct file_operations ll_dir_operations;
 extern struct inode_operations ll_dir_inode_operations;
+#ifdef HAVE_DIR_CONTEXT
+int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
+               struct dir_context *ctx);
+#else
 int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
                void *cookie, filldir_t filldir);
+#endif
 int ll_get_mdt_idx(struct inode *inode);
 int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi, const struct lu_fid *fid);
 
index f96d17e..713e846 100644 (file)
@@ -230,7 +230,14 @@ static int ll_get_name(struct dentry *dentry, char *name,
                        struct dentry *child)
 {
        struct inode *dir = dentry->d_inode;
-       struct ll_getname_data lgd;
+       struct ll_getname_data lgd = {
+               .lgd_name       = name,
+               .lgd_fid        = ll_i2info(child->d_inode)->lli_fid,
+#ifdef HAVE_DIR_CONTEXT
+               .ctx.actor      = ll_nfs_get_name_filldir,
+#endif
+               .lgd_found = 0,
+       };
        struct md_op_data *op_data;
        int rc;
        ENTRY;
@@ -241,10 +248,6 @@ static int ll_get_name(struct dentry *dentry, char *name,
         if (!dir->i_fop)
                 GOTO(out, rc = -EINVAL);
 
-        lgd.lgd_name = name;
-        lgd.lgd_fid = ll_i2info(child->d_inode)->lli_fid;
-        lgd.lgd_found = 0;
-
        op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0,
                                     LUSTRE_OPC_ANY, dir);
        if (IS_ERR(op_data))
@@ -254,7 +257,11 @@ static int ll_get_name(struct dentry *dentry, char *name,
        op_data->op_max_pages =
                ll_i2sbi(dir)->ll_md_brw_size >> PAGE_CACHE_SHIFT;
        mutex_lock(&dir->i_mutex);
+#ifdef HAVE_DIR_CONTEXT
+       rc = ll_dir_read(dir, op_data, &lgd.ctx);
+#else
        rc = ll_dir_read(dir, op_data, &lgd, ll_nfs_get_name_filldir);
+#endif
        mutex_unlock(&dir->i_mutex);
        ll_finish_md_op_data(op_data);
        if (!rc && !lgd.lgd_found)