From 0f26c84fb61bf4f4594d01c05c1a03fae2e2aac3 Mon Sep 17 00:00:00 2001 From: yury Date: Mon, 25 Apr 2005 16:52:59 +0000 Subject: [PATCH] - added more comments in GNS stuff about possible odd conditions --- lustre/llite/llite_gns.c | 26 +++++++++++++++----------- lustre/llite/namei.c | 23 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/lustre/llite/llite_gns.c b/lustre/llite/llite_gns.c index b703532..6411b4f 100644 --- a/lustre/llite/llite_gns.c +++ b/lustre/llite/llite_gns.c @@ -107,11 +107,16 @@ ll_gns_mount_object(struct dentry *dentry, struct vfsmount *mnt) spin_lock(&sbi->ll_gns_lock); if (sbi->ll_gns_state == LL_GNS_MOUNTING || sbi->ll_gns_state == LL_GNS_FINISHED) { + /* + * check if another control thread is trying to mount some GNS + * dentry too. Letting it know that we busy and make + * ll_lookup_it() ti restart syscall and try again later. + */ spin_unlock(&sbi->ll_gns_lock); CDEBUG(D_INODE, "GNS is in progress now, throwing " "-ERESTARTSYS to restart syscall and let " "it finish.\n"); - RETURN(-ERESTARTSYS); + RETURN(-EBUSY); } LASSERT(sbi->ll_gns_state == LL_GNS_IDLE); @@ -140,22 +145,21 @@ 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. */ - dchild = lookup_one_len(sbi->ll_gns_oname, dentry, - strlen(sbi->ll_gns_oname)); + + /* + * recursive lookup with trying to mount SUID bit marked directories on + * the way is not possible here, as lookup_one_len() does not pass nd to + * ->lookup() and this is checked in ll_lookup_it(). So, do not handle + * possible -EBUSY here. + */ + dchild = ll_lookup_one_len(sbi->ll_gns_oname, dentry, + strlen(sbi->ll_gns_oname)); up(&sbi->ll_gns_sem); cleanup_phase = 2; if (IS_ERR(dchild)) { rc = PTR_ERR(dchild); - - if (rc == -ERESTARTSYS) { - CDEBUG(D_INODE, "possible endless loop is detected " - "due to mount object is directory marked by " - "SUID bit.\n"); - GOTO(cleanup, rc = -ELOOP); - } - CERROR("can't find mount object %*s/%*s err = %d.\n", (int)dentry->d_name.len, dentry->d_name.name, strlen(sbi->ll_gns_oname), sbi->ll_gns_oname, diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 92fffb4..bb703c2 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -405,12 +405,31 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, ((flags & LOOKUP_CONTINUE) || (orig_it & (IT_CHDIR | IT_OPEN)))) { rc = ll_gns_mount_object(dentry, nd->mnt); - if (rc == -ERESTARTSYS) { + if (rc == -EBUSY) { /* * making system to restart syscall as currently GNS is * in mounting progress. */ - GOTO(out, retval = ERR_PTR(rc)); + GOTO(out, retval = ERR_PTR(-ERESTARTSYS)); + } + + if (rc) { + /* + * just reporting about GNS failures, lookup() is + * successful, do not stop it. + * + * GNS failure may be that found object is found in SUID + * bit marked dir but it is not regular file and we + * should lookup further until we find correct mount + * object. This will allow to perform GNS mount is the + * following case for instance: + * + * /mnt/lustre/gns_mount/.mntinfo/.mntinfo/..../.mntinfo + * where all ".mntinfo" are dirs and only last one is + * reg file. + */ + CDEBUG(D_INODE, "failed to mount %*s, err %d\n", + (int)dentry->d_name.len, dentry->d_name.name); } } -- 1.8.3.1