powerpc/pseries/dlpar: Use kasprintf
[safe/jmp/linux-2.6] / fs / ocfs2 / refcounttree.c
index 30967e3..bd96f6c 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <linux/bio.h>
 #include <linux/blkdev.h>
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/writeback.h>
 #include <linux/pagevec.h>
@@ -276,7 +275,7 @@ static void ocfs2_erase_refcount_tree_from_list(struct ocfs2_super *osb,
        spin_unlock(&osb->osb_lock);
 }
 
-void ocfs2_kref_remove_refcount_tree(struct kref *kref)
+static void ocfs2_kref_remove_refcount_tree(struct kref *kref)
 {
        struct ocfs2_refcount_tree *tree =
                container_of(kref, struct ocfs2_refcount_tree, rf_getcnt);
@@ -524,23 +523,6 @@ out:
        return ret;
 }
 
-int ocfs2_lock_refcount_tree_by_inode(struct inode *inode, int rw,
-                                     struct ocfs2_refcount_tree **ret_tree,
-                                     struct buffer_head **ref_bh)
-{
-       int ret;
-       u64 ref_blkno;
-
-       ret = ocfs2_get_refcount_block(inode, &ref_blkno);
-       if (ret) {
-               mlog_errno(ret);
-               return ret;
-       }
-
-       return ocfs2_lock_refcount_tree(OCFS2_SB(inode->i_sb), ref_blkno,
-                                       rw, ret_tree, ref_bh);
-}
-
 void ocfs2_unlock_refcount_tree(struct ocfs2_super *osb,
                                struct ocfs2_refcount_tree *tree, int rw)
 {
@@ -643,7 +625,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode,
        rb = (struct ocfs2_refcount_block *)new_bh->b_data;
        memset(rb, 0, inode->i_sb->s_blocksize);
        strcpy((void *)rb, OCFS2_REFCOUNT_BLOCK_SIGNATURE);
-       rb->rf_suballoc_slot = cpu_to_le16(osb->slot_num);
+       rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
        rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
        rb->rf_fs_generation = cpu_to_le32(osb->fs_generation);
        rb->rf_blkno = cpu_to_le64(first_blkno);
@@ -969,6 +951,103 @@ out:
 }
 
 /*
+ * Find the end range for a leaf refcount block indicated by
+ * el->l_recs[index].e_blkno.
+ */
+static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci,
+                                      struct buffer_head *ref_root_bh,
+                                      struct ocfs2_extent_block *eb,
+                                      struct ocfs2_extent_list *el,
+                                      int index,  u32 *cpos_end)
+{
+       int ret, i, subtree_root;
+       u32 cpos;
+       u64 blkno;
+       struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
+       struct ocfs2_path *left_path = NULL, *right_path = NULL;
+       struct ocfs2_extent_tree et;
+       struct ocfs2_extent_list *tmp_el;
+
+       if (index < le16_to_cpu(el->l_next_free_rec) - 1) {
+               /*
+                * We have a extent rec after index, so just use the e_cpos
+                * of the next extent rec.
+                */
+               *cpos_end = le32_to_cpu(el->l_recs[index+1].e_cpos);
+               return 0;
+       }
+
+       if (!eb || (eb && !eb->h_next_leaf_blk)) {
+               /*
+                * We are the last extent rec, so any high cpos should
+                * be stored in this leaf refcount block.
+                */
+               *cpos_end = UINT_MAX;
+               return 0;
+       }
+
+       /*
+        * If the extent block isn't the last one, we have to find
+        * the subtree root between this extent block and the next
+        * leaf extent block and get the corresponding e_cpos from
+        * the subroot. Otherwise we may corrupt the b-tree.
+        */
+       ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh);
+
+       left_path = ocfs2_new_path_from_et(&et);
+       if (!left_path) {
+               ret = -ENOMEM;
+               mlog_errno(ret);
+               goto out;
+       }
+
+       cpos = le32_to_cpu(eb->h_list.l_recs[index].e_cpos);
+       ret = ocfs2_find_path(ci, left_path, cpos);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       right_path = ocfs2_new_path_from_path(left_path);
+       if (!right_path) {
+               ret = -ENOMEM;
+               mlog_errno(ret);
+               goto out;
+       }
+
+       ret = ocfs2_find_cpos_for_right_leaf(sb, left_path, &cpos);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       ret = ocfs2_find_path(ci, right_path, cpos);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       subtree_root = ocfs2_find_subtree_root(&et, left_path,
+                                              right_path);
+
+       tmp_el = left_path->p_node[subtree_root].el;
+       blkno = left_path->p_node[subtree_root+1].bh->b_blocknr;
+       for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) {
+               if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) {
+                       *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos);
+                       break;
+               }
+       }
+
+       BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec));
+
+out:
+       ocfs2_free_path(left_path);
+       ocfs2_free_path(right_path);
+       return ret;
+}
+
+/*
  * Given a cpos and len, try to find the refcount record which contains cpos.
  * 1. If cpos can be found in one refcount record, return the record.
  * 2. If cpos can't be found, return a fake record which start from cpos
@@ -983,10 +1062,10 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci,
                                  struct buffer_head **ret_bh)
 {
        int ret = 0, i, found;
-       u32 low_cpos;
+       u32 low_cpos, uninitialized_var(cpos_end);
        struct ocfs2_extent_list *el;
-       struct ocfs2_extent_rec *tmp, *rec = NULL;
-       struct ocfs2_extent_block *eb;
+       struct ocfs2_extent_rec *rec = NULL;
+       struct ocfs2_extent_block *eb = NULL;
        struct buffer_head *eb_bh = NULL, *ref_leaf_bh = NULL;
        struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
        struct ocfs2_refcount_block *rb =
@@ -1034,12 +1113,16 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci,
                }
        }
 
-       /* adjust len when we have ocfs2_extent_rec after it. */
-       if (found && i < le16_to_cpu(el->l_next_free_rec) - 1) {
-               tmp = &el->l_recs[i+1];
+       if (found) {
+               ret = ocfs2_get_refcount_cpos_end(ci, ref_root_bh,
+                                                 eb, el, i, &cpos_end);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out;
+               }
 
-               if (le32_to_cpu(tmp->e_cpos) < cpos + len)
-                       len = le32_to_cpu(tmp->e_cpos) - cpos;
+               if (cpos_end < low_cpos + len)
+                       len = cpos_end - low_cpos;
        }
 
        ret = ocfs2_read_refcount_block(ci, le64_to_cpu(rec->e_blkno),
@@ -1246,7 +1329,7 @@ static int ocfs2_expand_inline_ref_root(handle_t *handle,
        memcpy(new_bh->b_data, ref_root_bh->b_data, sb->s_blocksize);
 
        new_rb = (struct ocfs2_refcount_block *)new_bh->b_data;
-       new_rb->rf_suballoc_slot = cpu_to_le16(OCFS2_SB(sb)->slot_num);
+       new_rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
        new_rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
        new_rb->rf_blkno = cpu_to_le64(blkno);
        new_rb->rf_cpos = cpu_to_le32(0);
@@ -1418,7 +1501,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh,
 
        /* change old and new rl_used accordingly. */
        le16_add_cpu(&rl->rl_used, -num_moved);
-       new_rl->rl_used = cpu_to_le32(num_moved);
+       new_rl->rl_used = cpu_to_le16(num_moved);
 
        sort(&rl->rl_recs, le16_to_cpu(rl->rl_used),
             sizeof(struct ocfs2_refcount_rec),
@@ -1492,7 +1575,7 @@ static int ocfs2_new_leaf_refcount_block(handle_t *handle,
        new_rb = (struct ocfs2_refcount_block *)new_bh->b_data;
        memset(new_rb, 0, sb->s_blocksize);
        strcpy((void *)new_rb, OCFS2_REFCOUNT_BLOCK_SIGNATURE);
-       new_rb->rf_suballoc_slot = cpu_to_le16(OCFS2_SB(sb)->slot_num);
+       new_rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
        new_rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
        new_rb->rf_fs_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);
        new_rb->rf_blkno = cpu_to_le64(blkno);
@@ -1797,7 +1880,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
                recs_need++;
 
        /* If the leaf block don't have enough record, expand it. */
-       if (le16_to_cpu(rf_list->rl_used) + recs_need > rf_list->rl_count) {
+       if (le16_to_cpu(rf_list->rl_used) + recs_need >
+                                        le16_to_cpu(rf_list->rl_count)) {
                struct ocfs2_refcount_rec tmp_rec;
                u64 cpos = le64_to_cpu(orig_rec->r_cpos);
                len = le32_to_cpu(orig_rec->r_clusters);
@@ -1859,7 +1943,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
                memcpy(tail_rec, orig_rec, sizeof(struct ocfs2_refcount_rec));
                le64_add_cpu(&tail_rec->r_cpos,
                             le32_to_cpu(tail_rec->r_clusters) - len);
-               tail_rec->r_clusters = le32_to_cpu(len);
+               tail_rec->r_clusters = cpu_to_le32(len);
        }
 
        /*
@@ -2860,7 +2944,7 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
 
        while (offset < end) {
                page_index = offset >> PAGE_CACHE_SHIFT;
-               map_end = (page_index + 1) << PAGE_CACHE_SHIFT;
+               map_end = ((loff_t)page_index + 1) << PAGE_CACHE_SHIFT;
                if (map_end > end)
                        map_end = end;
 
@@ -2872,8 +2956,12 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
 
                page = grab_cache_page(mapping, page_index);
 
-               /* This page can't be dirtied before we CoW it out. */
-               BUG_ON(PageDirty(page));
+               /*
+                * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page
+                * can't be dirtied before we CoW it out.
+                */
+               if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize)
+                       BUG_ON(PageDirty(page));
 
                if (!PageUptodate(page)) {
                        ret = block_read_full_page(page, ocfs2_get_block);
@@ -3085,7 +3173,7 @@ static int ocfs2_cow_sync_writeback(struct super_block *sb,
 
        while (offset < end) {
                page_index = offset >> PAGE_CACHE_SHIFT;
-               map_end = (page_index + 1) << PAGE_CACHE_SHIFT;
+               map_end = ((loff_t)page_index + 1) << PAGE_CACHE_SHIFT;
                if (map_end > end)
                        map_end = end;
 
@@ -3840,8 +3928,7 @@ static int ocfs2_add_refcounted_extent(struct inode *inode,
        }
 
        ret = ocfs2_insert_extent(handle, et, cpos,
-                       cpu_to_le64(ocfs2_clusters_to_blocks(inode->i_sb,
-                                                            p_cluster)),
+                       ocfs2_clusters_to_blocks(inode->i_sb, p_cluster),
                        num_clusters, ext_flags, meta_ac);
        if (ret) {
                mlog_errno(ret);
@@ -3987,6 +4074,7 @@ static int ocfs2_complete_reflink(struct inode *s_inode,
        OCFS2_I(t_inode)->ip_dyn_features = OCFS2_I(s_inode)->ip_dyn_features;
        spin_unlock(&OCFS2_I(t_inode)->ip_lock);
        i_size_write(t_inode, size);
+       t_inode->i_blocks = s_inode->i_blocks;
 
        di->i_xattr_inline_size = s_di->i_xattr_inline_size;
        di->i_clusters = s_di->i_clusters;
@@ -4253,8 +4341,8 @@ static int ocfs2_user_path_parent(const char __user *path,
  * @new_dentry:        target dentry
  * @preserve:  if true, preserve all file attributes
  */
-int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
-                     struct dentry *new_dentry, bool preserve)
+static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
+                            struct dentry *new_dentry, bool preserve)
 {
        struct inode *inode = old_dentry->d_inode;
        int error;
@@ -4302,7 +4390,7 @@ int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
        }
 
        mutex_lock(&inode->i_mutex);
-       vfs_dq_init(dir);
+       dquot_initialize(dir);
        error = ocfs2_reflink(old_dentry, dir, new_dentry, preserve);
        mutex_unlock(&inode->i_mutex);
        if (!error)