]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ocfs2/alloc.c
Merge branch 'task_killable' of git://git.kernel.org/pub/scm/linux/kernel/git/willy...
[linux-2.6-omap-h63xx.git] / fs / ocfs2 / alloc.c
index 72cefe25382b04aee17c0ea3b3aeb508627564e2..e6df06ac64059bb495a742f892530e1dd3212f3b 100644 (file)
@@ -2389,6 +2389,18 @@ static int __ocfs2_rotate_tree_left(struct inode *inode,
                        goto out;
                }
 
+               /*
+                * Caller might still want to make changes to the
+                * tree root, so re-add it to the journal here.
+                */
+               ret = ocfs2_journal_access(handle, inode,
+                                          path_root_bh(left_path),
+                                          OCFS2_JOURNAL_ACCESS_WRITE);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out;
+               }
+
                ret = ocfs2_rotate_subtree_left(inode, handle, left_path,
                                                right_path, subtree_root,
                                                dealloc, &deleted);
@@ -3289,16 +3301,6 @@ static int ocfs2_insert_path(struct inode *inode,
        int ret, subtree_index;
        struct buffer_head *leaf_bh = path_leaf_bh(right_path);
 
-       /*
-        * Pass both paths to the journal. The majority of inserts
-        * will be touching all components anyway.
-        */
-       ret = ocfs2_journal_access_path(inode, handle, right_path);
-       if (ret < 0) {
-               mlog_errno(ret);
-               goto out;
-       }
-
        if (left_path) {
                int credits = handle->h_buffer_credits;
 
@@ -3323,6 +3325,16 @@ static int ocfs2_insert_path(struct inode *inode,
                }
        }
 
+       /*
+        * Pass both paths to the journal. The majority of inserts
+        * will be touching all components anyway.
+        */
+       ret = ocfs2_journal_access_path(inode, handle, right_path);
+       if (ret < 0) {
+               mlog_errno(ret);
+               goto out;
+       }
+
        if (insert->ins_split != SPLIT_NONE) {
                /*
                 * We could call ocfs2_insert_at_leaf() for some types
@@ -3331,6 +3343,17 @@ static int ocfs2_insert_path(struct inode *inode,
                 */
                ocfs2_split_record(inode, left_path, right_path,
                                   insert_rec, insert->ins_split);
+
+               /*
+                * Split might have modified either leaf and we don't
+                * have a guarantee that the later edge insert will
+                * dirty this for us.
+                */
+               if (left_path)
+                       ret = ocfs2_journal_dirty(handle,
+                                                 path_leaf_bh(left_path));
+                       if (ret)
+                               mlog_errno(ret);
        } else
                ocfs2_insert_at_leaf(insert_rec, path_leaf_el(right_path),
                                     insert, inode);
@@ -3430,6 +3453,17 @@ static int ocfs2_do_insert_extent(struct inode *inode,
                        mlog_errno(ret);
                        goto out;
                }
+
+               /*
+                * ocfs2_rotate_tree_right() might have extended the
+                * transaction without re-journaling our tree root.
+                */
+               ret = ocfs2_journal_access(handle, inode, di_bh,
+                                          OCFS2_JOURNAL_ACCESS_WRITE);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out;
+               }
        } else if (type->ins_appending == APPEND_TAIL
                   && type->ins_contig != CONTIG_LEFT) {
                ret = ocfs2_append_rec_to_path(inode, handle, insert_rec,
@@ -3941,12 +3975,12 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
 {
        int ret = 0;
        struct ocfs2_extent_list *el = path_leaf_el(path);
-       struct buffer_head *eb_bh, *last_eb_bh = NULL;
+       struct buffer_head *last_eb_bh = NULL;
        struct ocfs2_extent_rec *rec = &el->l_recs[split_index];
        struct ocfs2_merge_ctxt ctxt;
        struct ocfs2_extent_list *rightmost_el;
 
-       if (!rec->e_flags & OCFS2_EXT_UNWRITTEN) {
+       if (!(rec->e_flags & OCFS2_EXT_UNWRITTEN)) {
                ret = -EIO;
                mlog_errno(ret);
                goto out;
@@ -3960,14 +3994,6 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
                goto out;
        }
 
-       eb_bh = path_leaf_bh(path);
-       ret = ocfs2_journal_access(handle, inode, eb_bh,
-                                  OCFS2_JOURNAL_ACCESS_WRITE);
-       if (ret) {
-               mlog_errno(ret);
-               goto out;
-       }
-
        ctxt.c_contig_type = ocfs2_figure_merge_contig_type(inode, el,
                                                            split_index,
                                                            split_rec);
@@ -4029,8 +4055,6 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
                        mlog_errno(ret);
        }
 
-       ocfs2_journal_dirty(handle, eb_bh);
-
 out:
        brelse(last_eb_bh);
        return ret;
@@ -4707,7 +4731,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
 
        mutex_lock(&data_alloc_inode->i_mutex);
 
-       status = ocfs2_meta_lock(data_alloc_inode, &data_alloc_bh, 1);
+       status = ocfs2_inode_lock(data_alloc_inode, &data_alloc_bh, 1);
        if (status < 0) {
                mlog_errno(status);
                goto out_mutex;
@@ -4729,7 +4753,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
 
 out_unlock:
        brelse(data_alloc_bh);
-       ocfs2_meta_unlock(data_alloc_inode, 1);
+       ocfs2_inode_unlock(data_alloc_inode, 1);
 
 out_mutex:
        mutex_unlock(&data_alloc_inode->i_mutex);
@@ -5053,7 +5077,7 @@ static int ocfs2_free_cached_items(struct ocfs2_super *osb,
 
        mutex_lock(&inode->i_mutex);
 
-       ret = ocfs2_meta_lock(inode, &di_bh, 1);
+       ret = ocfs2_inode_lock(inode, &di_bh, 1);
        if (ret) {
                mlog_errno(ret);
                goto out_mutex;
@@ -5094,7 +5118,7 @@ out_journal:
        ocfs2_commit_trans(osb, handle);
 
 out_unlock:
-       ocfs2_meta_unlock(inode, 1);
+       ocfs2_inode_unlock(inode, 1);
        brelse(di_bh);
 out_mutex:
        mutex_unlock(&inode->i_mutex);
@@ -5835,6 +5859,15 @@ static void ocfs2_zero_dinode_id2(struct inode *inode, struct ocfs2_dinode *di)
        memset(&di->id2, 0, blocksize - offsetof(struct ocfs2_dinode, id2));
 }
 
+void ocfs2_dinode_new_extent_list(struct inode *inode,
+                                 struct ocfs2_dinode *di)
+{
+       ocfs2_zero_dinode_id2(inode, di);
+       di->id2.i_list.l_tree_depth = 0;
+       di->id2.i_list.l_next_free_rec = 0;
+       di->id2.i_list.l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(inode->i_sb));
+}
+
 void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di)
 {
        struct ocfs2_inode_info *oi = OCFS2_I(inode);
@@ -5863,7 +5896,6 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
        struct ocfs2_inode_info *oi = OCFS2_I(inode);
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
-       struct ocfs2_extent_list *el = &di->id2.i_list;
        struct ocfs2_alloc_context *data_ac = NULL;
        struct page **pages = NULL;
        loff_t end = osb->s_clustersize;
@@ -5956,11 +5988,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
        di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
        spin_unlock(&oi->ip_lock);
 
-       ocfs2_zero_dinode_id2(inode, di);
-
-       el->l_tree_depth = 0;
-       el->l_next_free_rec = 0;
-       el->l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(inode->i_sb));
+       ocfs2_dinode_new_extent_list(inode, di);
 
        ocfs2_journal_dirty(handle, di_bh);
 
@@ -6089,8 +6117,6 @@ start:
        mlog(0, "clusters_to_del = %u in this pass, tail blk=%llu\n",
             clusters_to_del, (unsigned long long)path_leaf_bh(path)->b_blocknr);
 
-       BUG_ON(clusters_to_del == 0);
-
        mutex_lock(&tl_inode->i_mutex);
        tl_sem = 1;
        /* ocfs2_truncate_log_needs_flush guarantees us at least one