From 44958192651b526101dec9a9e491532f62838496 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Wed, 12 Feb 2014 19:51:44 -0500 Subject: [PATCH] LU-3974 llite: use new struct dir_context 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 Change-Id: Ib42bf8cb06635a2a64e63b294d79e66ac82a1a5b Reviewed-on: http://review.whamcloud.com/7747 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Bob Glossman Reviewed-by: Peng Tao Reviewed-by: Oleg Drokin --- lustre/autoconf/lustre-core.m4 | 20 ++++++++++++++++ lustre/llite/dir.c | 53 ++++++++++++++++++++++++++++++++---------- lustre/llite/llite_internal.h | 14 ++++++++--- lustre/llite/llite_nfs.c | 17 ++++++++++---- 4 files changed, 84 insertions(+), 20 deletions(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 1d964cb..a3037e3 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -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 +],[ + 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 diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 136b9b3..5775cc8 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -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, }; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index fb8b666..19ec0e8 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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); diff --git a/lustre/llite/llite_nfs.c b/lustre/llite/llite_nfs.c index f96d17e..713e846 100644 --- a/lustre/llite/llite_nfs.c +++ b/lustre/llite/llite_nfs.c @@ -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) -- 1.8.3.1