From 2dd52da58e66af04159fa5c130ae637a917c2223 Mon Sep 17 00:00:00 2001 From: yury <yury> Date: Thu, 21 Apr 2005 08:32:15 +0000 Subject: [PATCH] - fixes and cleanups in GNS: - mounting only on lookup() control path (revalidate() for possible mounts always return 0). This makes it possible to use lookup_one_len() from ll_gns_mount_object(), as lookup control path protected parent. - on revalidate cause mount for possible mount points only if revalidate is successful - removed not used dentry marking with MOUNT_PENDING, etc --- lustre/llite/dcache.c | 50 ++++++++++++++++++++++++++++------------ lustre/llite/llite_gns.c | 18 --------------- lustre/mds/mds_open.c | 4 ++-- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index bea605652f..90a41d37f0 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 a8e73c3379..05c7fe2ea7 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 2cf2d91a70..12eb36b464 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 */ } -- GitLab