From 65d0add6057b138e753761b04583339cf39b84f6 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Fri, 20 May 2016 12:16:46 -0400 Subject: [PATCH] LU-8019 llite: Restore proper opencache operations Just returning 0 from revalidate for all opens broke open cache because when we enter ll_lookup_nd, we have no inode and need to do an RPC to get there which defeats the purpose. Instead allow returning 1 for non-creating opens, mark all dentries passing via ll_iget_for_nfs as such so that ll_file_open would know where did we come from and request the open lock with the handle. Change-Id: Id8a0ade892bc26cee96a9ba2b1498cc3199255f0 Signed-off-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/20354 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Li Xi --- lustre/llite/dcache.c | 14 +++++++------- lustre/llite/file.c | 17 +++++++++++++++-- lustre/llite/llite_internal.h | 1 + lustre/llite/llite_nfs.c | 18 ++++++++++++++++++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 8c3db0a..732a841 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -334,13 +334,13 @@ static int ll_revalidate_dentry(struct dentry *dentry, if (dentry->d_inode && dentry->d_inode->i_op->follow_link) return 1; - /* Last path component lookup for open or create - we always - * return 0 here to go through re-lookup and properly signal - * MDS whenever we do or do not want an open-cache to be engaged. - * For create we also ensure the entry is really created no matter - * what races might have happened. - * LU-4367 */ - if (lookup_flags & (LOOKUP_OPEN | LOOKUP_CREATE)) + /* + * if open&create is set, talk to MDS to make sure file is created if + * necessary, because we can't do this in ->open() later since that's + * called on an inode. return 0 here to let lookup to handle this. + */ + if ((lookup_flags & (LOOKUP_OPEN | LOOKUP_CREATE)) == + (LOOKUP_OPEN | LOOKUP_CREATE)) return 0; if (!dentry_may_statahead(dir, dentry)) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index cfc01f4..328be3b 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -584,6 +584,7 @@ restart: } else { LASSERT(*och_usecount == 0); if (!it->it_disposition) { + struct ll_dentry_data *ldd = ll_d2d(file->f_path.dentry); /* We cannot just request lock handle now, new ELC code means that one of other OPEN locks for this file could be cancelled, and since blocking ast handler @@ -597,12 +598,24 @@ restart: * handle to be returned from LOOKUP|OPEN request, * for example if the target entry was a symlink. * - * Always fetch MDS_OPEN_LOCK if this is not setstripe. + * Only fetch MDS_OPEN_LOCK if this is in NFS path, + * marked by a bit set in ll_iget_for_nfs. Clear the + * bit so that it's not confusing later callers. * + * NB; when ldd is NULL, it must have come via normal + * lookup path only, since ll_iget_for_nfs always calls + * ll_d_init(). + */ + if (ldd && ldd->lld_nfs_dentry) { + ldd->lld_nfs_dentry = 0; + it->it_flags |= MDS_OPEN_LOCK; + } + + /* * Always specify MDS_OPEN_BY_FID because we don't want * to get file with different fid. */ - it->it_flags |= MDS_OPEN_LOCK | MDS_OPEN_BY_FID; + it->it_flags |= MDS_OPEN_BY_FID; rc = ll_intent_file_open(file, NULL, 0, it); if (rc) GOTO(out_openerr, rc); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 20956f4..f93ca61 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -81,6 +81,7 @@ struct ll_dentry_data { struct lookup_intent *lld_it; unsigned int lld_sa_generation; unsigned int lld_invalid:1; + unsigned int lld_nfs_dentry:1; struct rcu_head lld_rcu_head; }; diff --git a/lustre/llite/llite_nfs.c b/lustre/llite/llite_nfs.c index 9e19e78..0442210 100644 --- a/lustre/llite/llite_nfs.c +++ b/lustre/llite/llite_nfs.c @@ -137,6 +137,24 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren /* N.B. d_obtain_alias() drops inode ref on error */ result = d_obtain_alias(inode); + if (!IS_ERR(result)) { + int rc; + + rc = ll_d_init(result); + if (rc < 0) { + dput(result); + result = ERR_PTR(rc); + } else { + struct ll_dentry_data *ldd = ll_d2d(result); + + /* + * Need to signal to the ll_file_open that + * we came from NFS and so opencache needs to be + * enabled for this one + */ + ldd->lld_nfs_dentry = 1; + } + } RETURN(result); } -- 1.8.3.1