]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ocfs2/dcache.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6-omap-h63xx.git] / fs / ocfs2 / dcache.c
index 09efe240e652e3dd4e56601c61ebcb754b1cfc1a..b1cc7c381e889b5d898ad5f3e2a9bddeb9b39fd1 100644 (file)
@@ -128,9 +128,9 @@ static int ocfs2_match_dentry(struct dentry *dentry,
 /*
  * Walk the inode alias list, and find a dentry which has a given
  * parent. ocfs2_dentry_attach_lock() wants to find _any_ alias as it
- * is looking for a dentry_lock reference. The vote thread is looking
- * to unhash aliases, so we allow it to skip any that already have
- * that property.
+ * is looking for a dentry_lock reference. The downconvert thread is
+ * looking to unhash aliases, so we allow it to skip any that already
+ * have that property.
  */
 struct dentry *ocfs2_find_local_alias(struct inode *inode,
                                      u64 parent_blkno,
@@ -183,9 +183,6 @@ DEFINE_SPINLOCK(dentry_attach_lock);
  * The dir cluster lock (held at either PR or EX mode) protects us
  * from unlink and rename on other nodes.
  *
- * The 'create' flag tells us whether we're doing this as a result of
- * a file creation.
- *
  * A dput() can happen asynchronously due to pruning, so we cover
  * attaching and detaching the dentry lock with a
  * dentry_attach_lock.
@@ -199,16 +196,15 @@ DEFINE_SPINLOCK(dentry_attach_lock);
  */
 int ocfs2_dentry_attach_lock(struct dentry *dentry,
                             struct inode *inode,
-                            u64 parent_blkno,
-                            int create)
+                            u64 parent_blkno)
 {
        int ret;
        struct dentry *alias;
        struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
 
-       mlog(0, "Attach \"%.*s\", parent %llu, create %d, fsdata: %p\n",
+       mlog(0, "Attach \"%.*s\", parent %llu, fsdata: %p\n",
             dentry->d_name.len, dentry->d_name.name,
-            (unsigned long long)parent_blkno, create, dl);
+            (unsigned long long)parent_blkno, dl);
 
        /*
         * Negative dentry. We ignore these for now.
@@ -242,10 +238,9 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry,
                 * since we have it pinned, so our reference is safe.
                 */
                dl = alias->d_fsdata;
-               mlog_bug_on_msg(!dl, "parent %llu, ino %llu, create %d\n",
+               mlog_bug_on_msg(!dl, "parent %llu, ino %llu\n",
                                (unsigned long long)parent_blkno,
-                               (unsigned long long)OCFS2_I(inode)->ip_blkno,
-                               create);
+                               (unsigned long long)OCFS2_I(inode)->ip_blkno);
 
                mlog_bug_on_msg(dl->dl_parent_blkno != parent_blkno,
                                " \"%.*s\": old parent: %llu, new: %llu\n",
@@ -271,7 +266,7 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry,
        dl->dl_count = 0;
        /*
         * Does this have to happen below, for all attaches, in case
-        * the struct inode gets blown away by votes?
+        * the struct inode gets blown away by the downconvert thread?
         */
        dl->dl_inode = igrab(inode);
        dl->dl_parent_blkno = parent_blkno;
@@ -283,32 +278,17 @@ out_attach:
        dl->dl_count++;
        spin_unlock(&dentry_attach_lock);
 
-       /*
-        * Creation of a new file means that nobody can possibly have
-        * this name in the system, which means that acquiry of those
-        * locks can easily be optimized.
-        */
-       if (create) {
-               ret = ocfs2_create_new_lock(OCFS2_SB(inode->i_sb),
-                                           &dl->dl_lockres, 0);
-               if (ret)
-                       mlog_errno(ret);
-               goto out;
-       }
-
        /*
         * This actually gets us our PRMODE level lock. From now on,
         * we'll have a notification if one of these names is
         * destroyed on another node.
         */
        ret = ocfs2_dentry_lock(dentry, 0);
-       if (ret) {
+       if (!ret)
+               ocfs2_dentry_unlock(dentry, 0);
+       else
                mlog_errno(ret);
-               goto out;
-       }
-       ocfs2_dentry_unlock(dentry, 0);
 
-out:
        dput(alias);
 
        return ret;
@@ -338,9 +318,9 @@ out:
 static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
                                   struct ocfs2_dentry_lock *dl)
 {
+       iput(dl->dl_inode);
        ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
        ocfs2_lock_res_free(&dl->dl_lockres);
-       iput(dl->dl_inode);
        kfree(dl);
 }
 
@@ -364,12 +344,24 @@ static void ocfs2_dentry_iput(struct dentry *dentry, struct inode *inode)
 {
        struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
 
-       mlog_bug_on_msg(!dl && !(dentry->d_flags & DCACHE_DISCONNECTED),
-                       "dentry: %.*s\n", dentry->d_name.len,
-                       dentry->d_name.name);
+       if (!dl) {
+               /*
+                * No dentry lock is ok if we're disconnected or
+                * unhashed.
+                */
+               if (!(dentry->d_flags & DCACHE_DISCONNECTED) &&
+                   !d_unhashed(dentry)) {
+                       unsigned long long ino = 0ULL;
+                       if (inode)
+                               ino = (unsigned long long)OCFS2_I(inode)->ip_blkno;
+                       mlog(ML_ERROR, "Dentry is missing cluster lock. "
+                            "inode: %llu, d_flags: 0x%x, d_name: %.*s\n",
+                            ino, dentry->d_flags, dentry->d_name.len,
+                            dentry->d_name.name);
+               }
 
-       if (!dl)
                goto out;
+       }
 
        mlog_bug_on_msg(dl->dl_count == 0, "dentry: %.*s, count: %u\n",
                        dentry->d_name.len, dentry->d_name.name,
@@ -396,7 +388,7 @@ out:
  * directory locks. The dentries have already been deleted on other
  * nodes via ocfs2_remote_dentry_delete().
  *
- * Normally, the VFS handles the d_move() for the file sytem, after
+ * Normally, the VFS handles the d_move() for the file system, after
  * the ->rename() callback. OCFS2 wants to handle this internally, so
  * the new lock can be created atomically with respect to the cluster.
  */
@@ -414,15 +406,17 @@ void ocfs2_dentry_move(struct dentry *dentry, struct dentry *target,
         * XXX: Is there any advantage to dropping the lock here?
         */
        if (old_dir == new_dir)
-               return;
+               goto out_move;
 
        ocfs2_dentry_lock_put(osb, dentry->d_fsdata);
 
        dentry->d_fsdata = NULL;
-       ret = ocfs2_dentry_attach_lock(dentry, inode,
-                                      OCFS2_I(new_dir)->ip_blkno, 0);
+       ret = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(new_dir)->ip_blkno);
        if (ret)
                mlog_errno(ret);
+
+out_move:
+       d_move(dentry, target);
 }
 
 struct dentry_operations ocfs2_dentry_ops = {