From 9573911bfb4a2c3d7e2047c9d5f5440d9c7e7db5 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Wed, 6 Jul 2016 00:38:19 -0400 Subject: [PATCH] LU-8371 llite: Trust creates in revalidate too. By forcing creates to always go via lookup we lose some important caching benefits too. Instead let's trust creates with positive cached entries. Then we have 3 possible outcomes: 1. Negative dentry - we go via atomic_open and do the create by name there. 2. Positive dentry, no contention - we just go straight to ll_intent_file_open and open by fid. 3. positive dentry, contention - by the time we reach the server, the inode is gone. We get ENOENT which is unacceptable to return from create. But since we know it's a create, we substitute it with ESTALE and VFS retries again with LOOKUP_REVAL set, we catch that in revalidate and force a lookup (same path as before this patch). Change-Id: I7b006a50703bfb37e8747dca0f95b2c512b82429 Signed-off-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/21168 Reviewed-by: James Simmons Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo --- lustre/llite/dcache.c | 10 +++++----- lustre/llite/file.c | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 22861ca..c42e89d 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -328,12 +328,12 @@ static int ll_revalidate_dentry(struct dentry *dentry, return 1; /* - * 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. + * VFS warns us that this is the second go around and previous + * operation failed (most likely open|creat), so this time + * we better talk to the server via the lookup path by name, + * not by fid. */ - if ((lookup_flags & (LOOKUP_OPEN | LOOKUP_CREATE)) == - (LOOKUP_OPEN | LOOKUP_CREATE)) + if (lookup_flags & LOOKUP_REVAL) return 0; if (!dentry_may_statahead(dir, dentry)) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 4dc7b5d..b7bd2bf 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -414,6 +414,16 @@ out: ptlrpc_req_finished(req); ll_intent_drop_lock(itp); + /* We did open by fid, but by the time we got to the server, + * the object disappeared. If this is a create, we cannot really + * tell the userspace that the file it was trying to create + * does not exist. Instead let's return -ESTALE, and the VFS will + * retry the create with LOOKUP_REVAL that we are going to catch + * in ll_revalidate_dentry() and use lookup then. + */ + if (rc == -ENOENT && itp->it_op & IT_CREAT) + rc = -ESTALE; + RETURN(rc); } -- 1.8.3.1