Whamcloud - gitweb
- fixes and cleanups in GNS:
authoryury <yury>
Thu, 21 Apr 2005 08:32:15 +0000 (08:32 +0000)
committeryury <yury>
Thu, 21 Apr 2005 08:32:15 +0000 (08:32 +0000)
  - 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
lustre/llite/llite_gns.c
lustre/mds/mds_open.c

index bea6056..90a41d3 100644 (file)
@@ -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;
index a8e73c3..05c7fe2 100644 (file)
@@ -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;
 }
index 2cf2d91..12eb36b 100644 (file)
@@ -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
                  */
         }