Whamcloud - gitweb
- added more comments in GNS stuff about possible odd conditions
authoryury <yury>
Mon, 25 Apr 2005 16:52:59 +0000 (16:52 +0000)
committeryury <yury>
Mon, 25 Apr 2005 16:52:59 +0000 (16:52 +0000)
lustre/llite/llite_gns.c
lustre/llite/namei.c

index b703532..6411b4f 100644 (file)
@@ -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,
index 92fffb4..bb703c2 100644 (file)
@@ -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);
                 }
         }