X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fdcache.c;h=5790afb3222a39423ab831c5b3c0e039bfcce401;hb=32e547aa9cb913f5736ee3d58cb79f4e63ce2c0b;hp=732a8415e662a50025662cec647dd3f792d1467f;hpb=65d0add6057b138e753761b04583339cf39b84f6;p=fs%2Flustre-release.git diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 732a841..5790afb 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2015, Intel Corporation. + * Copyright (c) 2011, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -42,7 +38,6 @@ #define DEBUG_SUBSYSTEM S_LLITE #include -#include #include #include "llite_internal.h" @@ -82,7 +77,14 @@ static void ll_release(struct dentry *de) * This avoids a race where ll_lookup_it() instantiates a dentry, but we get * an AST before calling d_revalidate_it(). The dentry still exists (marked * INVALID) so d_lookup() matches it, but we have no lock on it (so - * lock_match() fails) and we spin around real_lookup(). */ + * lock_match() fails) and we spin around real_lookup(). + * + * This race doesn't apply to lookups in d_alloc_parallel(), and for + * those we want to ensure that only one dentry with a given name is + * in ll_lookup_nd() at a time. So allow invalid dentries to match + * while d_in_lookup(). We will be called again when the lookup + * completes, and can give a different answer then. + */ #ifdef HAVE_D_COMPARE_7ARGS static int ll_dcompare(const struct dentry *parent, const struct inode *pinode, const struct dentry *dentry, const struct inode *inode, @@ -92,12 +94,15 @@ static int ll_dcompare(const struct dentry *parent, const struct inode *pinode, static int ll_dcompare(const struct dentry *parent, const struct dentry *dentry, unsigned int len, const char *str, const struct qstr *name) +#elif defined(HAVE_D_COMPARE_4ARGS) +static int ll_dcompare(const struct dentry *dentry, unsigned int len, + const char *str, const struct qstr *name) #else static int ll_dcompare(struct dentry *parent, struct qstr *d_name, struct qstr *name) #endif { -#if !defined(HAVE_D_COMPARE_7ARGS) && !defined(HAVE_D_COMPARE_5ARGS) +#if !defined(HAVE_D_COMPARE_7ARGS) && !defined(HAVE_D_COMPARE_5ARGS) && !defined(HAVE_D_COMPARE_4ARGS) /* XXX: (ugh !) d_name must be in-dentry structure */ struct dentry *dentry = container_of(d_name, struct dentry, d_name); unsigned int len = d_name->len; @@ -119,6 +124,10 @@ static int ll_dcompare(struct dentry *parent, struct qstr *d_name, if (d_mountpoint((struct dentry *)dentry)) RETURN(0); + /* ensure exclusion against parallel lookup of the same name */ + if (d_in_lookup((struct dentry *)dentry)) + return 0; + if (d_lustre_invalid(dentry)) RETURN(1); @@ -150,17 +159,6 @@ static int ll_ddelete(HAVE_D_DELETE_CONST struct dentry *de) LASSERT(ll_d_count(de) == 1); #endif - /* Disable this piece of code temproarily because this is called - * inside dcache_lock so it's not appropriate to do lots of work - * here. ATTENTION: Before this piece of code enabling, LU-2487 must be - * resolved. */ -#if 0 - /* if not ldlm lock for this inode, set i_nlink to 0 so that - * this inode can be recycled later b=20433 */ - if (de->d_inode && !find_cbdata(de->d_inode)) - clear_nlink(de->d_inode); -#endif - if (d_lustre_invalid((struct dentry *)de)) RETURN(1); RETURN(0); @@ -182,12 +180,13 @@ int ll_d_init(struct dentry *de) if (likely(lld != NULL)) { spin_lock(&de->d_lock); if (likely(de->d_fsdata == NULL)) { - de->d_fsdata = lld; - __d_lustre_invalidate(de); #ifdef HAVE_DCACHE_LOCK /* kernel >= 2.6.38 d_op is set in d_alloc() */ de->d_op = &ll_d_ops; + smp_mb(); #endif + de->d_fsdata = lld; + __d_lustre_invalidate(de); } else { OBD_FREE_PTR(lld); } @@ -208,8 +207,8 @@ void ll_intent_drop_lock(struct lookup_intent *it) handle.cookie = it->it_lock_handle; - CDEBUG(D_DLMTRACE, "releasing lock with cookie "LPX64 - " from it %p\n", handle.cookie, it); + CDEBUG(D_DLMTRACE, "releasing lock with cookie %#llx from it %p\n", + handle.cookie, it); ldlm_lock_decref(&handle, it->it_lock_mode); /* bug 494: intent_release may be called multiple times, from @@ -219,7 +218,7 @@ void ll_intent_drop_lock(struct lookup_intent *it) handle.cookie = it->it_remote_lock_handle; CDEBUG(D_DLMTRACE, "releasing remote lock with cookie" - LPX64" from it %p\n", handle.cookie, it); + "%#llx from it %p\n", handle.cookie, it); ldlm_lock_decref(&handle, it->it_remote_lock_mode); it->it_remote_lock_mode = 0; @@ -263,14 +262,6 @@ void ll_invalidate_aliases(struct inode *inode) dentry->d_name.name, dentry, dentry->d_parent, dentry->d_inode, dentry->d_flags); - if (unlikely(dentry == dentry->d_sb->s_root)) { - CERROR("%s: called on root dentry=%p, fid="DFID"\n", - ll_get_fsname(dentry->d_sb, NULL, 0), - dentry, PFID(ll_inode2fid(inode))); - lustre_dump_dentry(dentry, 1); - libcfs_debug_dumpstack(NULL); - } - d_lustre_invalidate(dentry, 0); } ll_unlock_dcache(inode); @@ -331,27 +322,30 @@ static int ll_revalidate_dentry(struct dentry *dentry, return 1; /* Symlink - always valid as long as the dentry was found */ +#ifdef HAVE_IOP_GET_LINK + if (dentry->d_inode && dentry->d_inode->i_op->get_link) +#else if (dentry->d_inode && dentry->d_inode->i_op->follow_link) +#endif 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)) - return 1; - #ifndef HAVE_DCACHE_LOCK if (lookup_flags & LOOKUP_RCU) return -ECHILD; #endif - ll_statahead(dir, &dentry, dentry->d_inode == NULL); + if (dentry_may_statahead(dir, dentry)) + ll_statahead(dir, &dentry, dentry->d_inode == NULL); + return 1; }