]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ocfs2/namei.c
ocfs2: adjust code to match locking/unlocking order
[karo-tx-linux.git] / fs / ocfs2 / namei.c
index 948681e37cfdb3a863906e9f61cf3bac12b2b6e5..97c47d71efa721d9e1f669634538600c726ddc46 100644 (file)
@@ -1035,11 +1035,6 @@ leave:
        if (handle)
                ocfs2_commit_trans(osb, handle);
 
-       if (child_locked)
-               ocfs2_inode_unlock(inode, 1);
-
-       ocfs2_inode_unlock(dir, 1);
-
        if (orphan_dir) {
                /* This was locked for us in ocfs2_prepare_orphan_dir() */
                ocfs2_inode_unlock(orphan_dir, 1);
@@ -1047,6 +1042,11 @@ leave:
                iput(orphan_dir);
        }
 
+       if (child_locked)
+               ocfs2_inode_unlock(inode, 1);
+
+       ocfs2_inode_unlock(dir, 1);
+
        brelse(fe_bh);
        brelse(parent_node_bh);
 
@@ -1633,21 +1633,9 @@ static int ocfs2_rename(struct inode *old_dir,
        ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir);
        status = 0;
 bail:
-       if (rename_lock)
-               ocfs2_rename_unlock(osb);
-
        if (handle)
                ocfs2_commit_trans(osb, handle);
 
-       if (parents_locked)
-               ocfs2_double_unlock(old_dir, new_dir);
-
-       if (old_child_locked)
-               ocfs2_inode_unlock(old_inode, 1);
-
-       if (new_child_locked)
-               ocfs2_inode_unlock(new_inode, 1);
-
        if (orphan_dir) {
                /* This was locked for us in ocfs2_prepare_orphan_dir() */
                ocfs2_inode_unlock(orphan_dir, 1);
@@ -1655,6 +1643,18 @@ bail:
                iput(orphan_dir);
        }
 
+       if (new_child_locked)
+               ocfs2_inode_unlock(new_inode, 1);
+
+       if (old_child_locked)
+               ocfs2_inode_unlock(old_inode, 1);
+
+       if (parents_locked)
+               ocfs2_double_unlock(old_dir, new_dir);
+
+       if (rename_lock)
+               ocfs2_rename_unlock(osb);
+
        if (new_inode)
                sync_mapping_buffers(old_inode->i_mapping);
 
@@ -2601,27 +2601,6 @@ leave:
        return status;
 }
 
-static int ocfs2_dio_orphan_recovered(struct inode *inode)
-{
-       int ret;
-       struct buffer_head *di_bh = NULL;
-       struct ocfs2_dinode *di = NULL;
-
-       ret = ocfs2_inode_lock(inode, &di_bh, 1);
-       if (ret < 0) {
-               mlog_errno(ret);
-               return 0;
-       }
-
-       di = (struct ocfs2_dinode *) di_bh->b_data;
-       ret = !(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL));
-       ocfs2_inode_unlock(inode, 1);
-       brelse(di_bh);
-
-       return ret;
-}
-
-#define OCFS2_DIO_ORPHANED_FL_CHECK_INTERVAL 10000
 int ocfs2_add_inode_to_orphan(struct ocfs2_super *osb,
        struct inode *inode)
 {
@@ -2633,7 +2612,6 @@ int ocfs2_add_inode_to_orphan(struct ocfs2_super *osb,
        handle_t *handle = NULL;
        struct ocfs2_dinode *di = NULL;
 
-restart:
        status = ocfs2_inode_lock(inode, &di_bh, 1);
        if (status < 0) {
                mlog_errno(status);
@@ -2643,15 +2621,21 @@ restart:
        di = (struct ocfs2_dinode *) di_bh->b_data;
        /*
         * Another append dio crashed?
-        * If so, wait for recovery first.
+        * If so, manually recover it first.
         */
        if (unlikely(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL))) {
-               ocfs2_inode_unlock(inode, 1);
-               brelse(di_bh);
-               wait_event_interruptible_timeout(OCFS2_I(inode)->append_dio_wq,
-                               ocfs2_dio_orphan_recovered(inode),
-                               msecs_to_jiffies(OCFS2_DIO_ORPHANED_FL_CHECK_INTERVAL));
-               goto restart;
+               status = ocfs2_truncate_file(inode, di_bh, i_size_read(inode));
+               if (status < 0) {
+                       if (status != -ENOSPC)
+                               mlog_errno(status);
+                       goto bail_unlock_inode;
+               }
+
+               status = ocfs2_del_inode_from_orphan(osb, inode, di_bh, 0, 0);
+               if (status < 0) {
+                       mlog_errno(status);
+                       goto bail_unlock_inode;
+               }
        }
 
        status = ocfs2_prepare_orphan_dir(osb, &orphan_dir_inode,