diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index bea605652f93ff1bb7d763bfe07dcfc4e9400b20..90a41d37f06e7c3535ef5389e4812421b9bab319 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -289,16 +289,31 @@ int ll_intent_alloc(struct lookup_intent *it) return 0; } +static inline int +ll_special_name(struct dentry *de) +{ + if (de->d_name.name[0] == '.') switch (de->d_name.len) { + case 2: + if (de->d_name.name[1] == '.') + return 1; + case 1: + return 1; + default: + return 0; + } + return 0; +} + int ll_revalidate_it(struct dentry *de, int flags, struct nameidata *nd, struct lookup_intent *it) { struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; struct ptlrpc_request *req = NULL; - int orig_it, err, rc = 0; struct obd_export *exp; struct it_cb_data icbd; struct lustre_id pid; struct lustre_id cid; + int orig_it, rc = 0; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:name=%s (%p), intent=%s\n", de->d_name.name, @@ -467,13 +482,15 @@ revalidate_finish: GOTO(out, rc); out: - if (req != NULL && rc == 1) + if (req != NULL && rc == 1) { ptlrpc_req_finished(req); + req = NULL; + } if (rc == 0) { if (it == &lookup_it) { ll_intent_release(it); - if (req) /* Special case: We did lookup and it failed, + if (req) /* special case: We did lookup and it failed, need to free request */ ptlrpc_req_finished(req); } @@ -490,21 +507,24 @@ out: de->d_flags &= ~DCACHE_LUSTRE_INVALID; if (it == &lookup_it) ll_intent_release(it); - + + /* + * if we found that this is possible GNS mount and dentry is still valid + * and may be used by system, we drop the lock and return 0, that means + * that re-lookup is needed. Such a way we cause real mounting only in + * lookup control path, which is always made with parent's i_sem taken. + * --umka + */ if (!((de->d_inode->i_mode & S_ISUID) && S_ISDIR(de->d_inode->i_mode)) || !(flags & LOOKUP_CONTINUE || (orig_it & (IT_CHDIR | IT_OPEN)))) - return rc; - - if (nd != NULL) { - err = ll_gns_mount_object(de, nd->mnt); - if (err == -ERESTARTSYS) { - /* - * making system to restart syscall as currently GNS is - * in mounting progress. - */ - return err; - } + return rc; + + /* special "." and ".." has to be always revalidated */ + if (rc && !ll_special_name(de) && nd != NULL && !(nd->flags & LOOKUP_LAST)) { + ll_intent_drop_lock(it); + return 0; } + return rc; do_lookup: it = &lookup_it; diff --git a/lustre/llite/llite_gns.c b/lustre/llite/llite_gns.c index a8e73c33792b5882a81242280409ae7382f30b4a..05c7fe2ea7d15a5cf42b946d44378867627ddf02 100644 --- a/lustre/llite/llite_gns.c +++ b/lustre/llite/llite_gns.c @@ -115,10 +115,6 @@ ll_gns_mount_object(struct dentry *dentry, struct vfsmount *mnt) } LASSERT(sbi->ll_gns_state == LL_GNS_IDLE); - spin_lock(&dentry->d_lock); - dentry->d_flags |= DCACHE_GNS_MOUNTING; - spin_unlock(&dentry->d_lock); - /* mounting started */ sbi->ll_gns_state = LL_GNS_MOUNTING; spin_unlock(&sbi->ll_gns_lock); @@ -144,13 +140,6 @@ ll_gns_mount_object(struct dentry *dentry, struct vfsmount *mnt) * mount object name is taken from sbi, where it is set in mount time or * via /proc/fs... tunable. It may be ".mntinfo" or so. */ - - /* - * FIXME: lookup_one_len() requires dentry->d_inode->i_sem to be locked, - * but we can't use ll_lookup_one_len() as this function is called from - * different contol paths and some of them take dentry->d_inode->i_sem - * and others do not. - */ dchild = lookup_one_len(sbi->ll_gns_oname, dentry, strlen(sbi->ll_gns_oname)); up(&sbi->ll_gns_sem); @@ -283,9 +272,6 @@ ll_gns_mount_object(struct dentry *dentry, struct vfsmount *mnt) mntput(mnt); dput(dentry); } - spin_lock(&dentry->d_lock); - dentry->d_flags &= ~DCACHE_GNS_PENDING; - spin_unlock(&dentry->d_lock); } else { CERROR("usermode upcall %s failed to mount %s, err %d\n", sbi->ll_gns_upcall, path, rc); @@ -314,10 +300,6 @@ cleanup: spin_lock(&sbi->ll_gns_lock); sbi->ll_gns_state = LL_GNS_IDLE; spin_unlock(&sbi->ll_gns_lock); - - spin_lock(&dentry->d_lock); - dentry->d_flags &= ~DCACHE_GNS_MOUNTING; - spin_unlock(&dentry->d_lock); } return rc; } diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 2cf2d91a704d1da2dc30a4056aa5406e42e96c5f..12eb36b46489205d54074e52daa3e07780240f74 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -1183,9 +1183,9 @@ got_child: GOTO(cleanup, rc = -EACCES); /* - * here was checking for possible GNS mount point to skip their + * here was checking for possible GNS mount points to skip their * open. I removed it as its detection based only on SUID bit is - * not reliable. Opening such an dirs should not cause any + * not reliable. Opening such a dirs should not cause any * problems, at least tests show that. --umka */ }