KVM: MMU: invalidate and flush on spte small->large page size change
[safe/jmp/linux-2.6] / fs / reiserfs / do_balan.c
index e788fbc..60c0804 100644 (file)
 #include <linux/buffer_head.h>
 #include <linux/kernel.h>
 
-#ifdef CONFIG_REISERFS_CHECK
+static inline void buffer_info_init_left(struct tree_balance *tb,
+                                         struct buffer_info *bi)
+{
+       bi->tb          = tb;
+       bi->bi_bh       = tb->L[0];
+       bi->bi_parent   = tb->FL[0];
+       bi->bi_position = get_left_neighbor_position(tb, 0);
+}
 
-struct tree_balance *cur_tb = NULL;    /* detects whether more than one
-                                          copy of tb exists as a means
-                                          of checking whether schedule
-                                          is interrupting do_balance */
-#endif
+static inline void buffer_info_init_right(struct tree_balance *tb,
+                                          struct buffer_info *bi)
+{
+       bi->tb          = tb;
+       bi->bi_bh       = tb->R[0];
+       bi->bi_parent   = tb->FR[0];
+       bi->bi_position = get_right_neighbor_position(tb, 0);
+}
+
+static inline void buffer_info_init_tbS0(struct tree_balance *tb,
+                                         struct buffer_info *bi)
+{
+       bi->tb          = tb;
+       bi->bi_bh        = PATH_PLAST_BUFFER(tb->tb_path);
+       bi->bi_parent   = PATH_H_PPARENT(tb->tb_path, 0);
+       bi->bi_position = PATH_H_POSITION(tb->tb_path, 1);
+}
+
+static inline void buffer_info_init_bh(struct tree_balance *tb,
+                                       struct buffer_info *bi,
+                                       struct buffer_head *bh)
+{
+       bi->tb          = tb;
+       bi->bi_bh       = bh;
+       bi->bi_parent   = NULL;
+       bi->bi_position = 0;
+}
 
 inline void do_balance_mark_leaf_dirty(struct tree_balance *tb,
                                       struct buffer_head *bh, int flag)
@@ -39,21 +68,21 @@ inline void do_balance_mark_leaf_dirty(struct tree_balance *tb,
 #define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
 #define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty
 
-/* summary: 
+/* summary:
  if deleting something ( tb->insert_size[0] < 0 )
    return(balance_leaf_when_delete()); (flag d handled here)
  else
    if lnum is larger than 0 we put items into the left node
    if rnum is larger than 0 we put items into the right node
    if snum1 is larger than 0 we put items into the new node s1
-   if snum2 is larger than 0 we put items into the new node s2 
+   if snum2 is larger than 0 we put items into the new node s2
 Note that all *num* count new items being created.
 
 It would be easier to read balance_leaf() if each of these summary
 lines was a separate procedure rather than being inlined.  I think
 that there are many passages here and in balance_leaf_when_delete() in
 which two calls to one procedure can replace two passages, and it
-might save cache space and improve software maintenance costs to do so.  
+might save cache space and improve software maintenance costs to do so.
 
 Vladimir made the perceptive comment that we should offload most of
 the decision making in this function into fix_nodes/check_balance, and
@@ -86,6 +115,7 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
               "PAP-12010: tree can not be empty");
 
        ih = B_N_PITEM_HEAD(tbS0, item_pos);
+       buffer_info_init_tbS0(tb, &bi);
 
        /* Delete or truncate the item */
 
@@ -96,10 +126,6 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
                       "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
                       -tb->insert_size[0], ih);
 
-               bi.tb = tb;
-               bi.bi_bh = tbS0;
-               bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
-               bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
                leaf_delete_items(&bi, 0, item_pos, 1, -1);
 
                if (!item_pos && tb->CFL[0]) {
@@ -121,10 +147,6 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
                break;
 
        case M_CUT:{            /* cut item in S[0] */
-                       bi.tb = tb;
-                       bi.bi_bh = tbS0;
-                       bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
-                       bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
                        if (is_direntry_le_ih(ih)) {
 
                                /* UFS unlink semantics are such that you can only delete one directory entry at a time. */
@@ -258,15 +280,15 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,    /* item h
     )
 {
        struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
-       int item_pos = PATH_LAST_POSITION(tb->tb_path); /*  index into the array of item headers in S[0] 
+       int item_pos = PATH_LAST_POSITION(tb->tb_path); /*  index into the array of item headers in S[0]
                                                           of the affected item */
        struct buffer_info bi;
        struct buffer_head *S_new[2];   /* new nodes allocated to hold what could not fit into S */
        int snum[2];            /* number of items that will be placed
                                   into S_new (includes partially shifted
                                   items) */
-       int sbytes[2];          /* if an item is partially shifted into S_new then 
-                                  if it is a directory item 
+       int sbytes[2];          /* if an item is partially shifted into S_new then
+                                  if it is a directory item
                                   it is the number of entries from the item that are shifted into S_new
                                   else
                                   it is the number of bytes from the item that are shifted into S_new
@@ -325,11 +347,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                               ih_item_len(ih));
 
                                        /* Insert new item into L[0] */
-                                       bi.tb = tb;
-                                       bi.bi_bh = tb->L[0];
-                                       bi.bi_parent = tb->FL[0];
-                                       bi.bi_position =
-                                           get_left_neighbor_position(tb, 0);
+                                       buffer_info_init_left(tb, &bi);
                                        leaf_insert_into_buf(&bi,
                                                             n + item_pos -
                                                             ret_val, ih, body,
@@ -369,11 +387,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                            leaf_shift_left(tb, tb->lnum[0] - 1,
                                                            tb->lbytes);
                                        /* Insert new item into L[0] */
-                                       bi.tb = tb;
-                                       bi.bi_bh = tb->L[0];
-                                       bi.bi_parent = tb->FL[0];
-                                       bi.bi_position =
-                                           get_left_neighbor_position(tb, 0);
+                                       buffer_info_init_left(tb, &bi);
                                        leaf_insert_into_buf(&bi,
                                                             n + item_pos -
                                                             ret_val, ih, body,
@@ -429,13 +443,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                                        }
 
                                                        /* Append given directory entry to directory item */
-                                                       bi.tb = tb;
-                                                       bi.bi_bh = tb->L[0];
-                                                       bi.bi_parent =
-                                                           tb->FL[0];
-                                                       bi.bi_position =
-                                                           get_left_neighbor_position
-                                                           (tb, 0);
+                                                       buffer_info_init_left(tb, &bi);
                                                        leaf_paste_in_buffer
                                                            (&bi,
                                                             n + item_pos -
@@ -523,13 +531,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                                                             (tbS0,
                                                                              item_pos)));
                                                        /* Append to body of item in L[0] */
-                                                       bi.tb = tb;
-                                                       bi.bi_bh = tb->L[0];
-                                                       bi.bi_parent =
-                                                           tb->FL[0];
-                                                       bi.bi_position =
-                                                           get_left_neighbor_position
-                                                           (tb, 0);
+                                                       buffer_info_init_left(tb, &bi);
                                                        leaf_paste_in_buffer
                                                            (&bi,
                                                             n + item_pos -
@@ -680,11 +682,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                            leaf_shift_left(tb, tb->lnum[0],
                                                            tb->lbytes);
                                        /* Append to body of item in L[0] */
-                                       bi.tb = tb;
-                                       bi.bi_bh = tb->L[0];
-                                       bi.bi_parent = tb->FL[0];
-                                       bi.bi_position =
-                                           get_left_neighbor_position(tb, 0);
+                                       buffer_info_init_left(tb, &bi);
                                        leaf_paste_in_buffer(&bi,
                                                             n + item_pos -
                                                             ret_val,
@@ -776,11 +774,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                        set_le_ih_k_offset(ih, offset);
                                        put_ih_item_len(ih, tb->rbytes);
                                        /* Insert part of the item into R[0] */
-                                       bi.tb = tb;
-                                       bi.bi_bh = tb->R[0];
-                                       bi.bi_parent = tb->FR[0];
-                                       bi.bi_position =
-                                           get_right_neighbor_position(tb, 0);
+                                       buffer_info_init_right(tb, &bi);
                                        if ((old_len - tb->rbytes) > zeros_num) {
                                                r_zeros_number = 0;
                                                r_body =
@@ -817,11 +811,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                                             tb->rnum[0] - 1,
                                                             tb->rbytes);
                                        /* Insert new item into R[0] */
-                                       bi.tb = tb;
-                                       bi.bi_bh = tb->R[0];
-                                       bi.bi_parent = tb->FR[0];
-                                       bi.bi_position =
-                                           get_right_neighbor_position(tb, 0);
+                                       buffer_info_init_right(tb, &bi);
                                        leaf_insert_into_buf(&bi,
                                                             item_pos - n +
                                                             tb->rnum[0] - 1,
@@ -881,13 +871,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,     /* item h
                                                            pos_in_item -
                                                            entry_count +
                                                            tb->rbytes - 1;
-                                                       bi.tb = tb;
-                                                       bi.bi_bh = tb->R[0];
-                                                       bi.bi_parent =
-                                                           tb->FR[0];
-                                                       bi.bi_position =
-                                                           get_right_neighbor_position
-                                                           (tb, 0);
+                                                       buffer_info_init_right(tb, &bi);
                                                        leaf_paste_in_buffer
                                                            (&bi, 0,
                                                             paste_entry_position,
@@ -1018,12 +1002,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                                    (tb, tb->CFR[0], 0);
 
                                                /* Append part of body into R[0] */
-                                               bi.tb = tb;
-                                               bi.bi_bh = tb->R[0];
-                                               bi.bi_parent = tb->FR[0];
-                                               bi.bi_position =
-                                                   get_right_neighbor_position
-                                                   (tb, 0);
+                                               buffer_info_init_right(tb, &bi);
                                                if (n_rem > zeros_num) {
                                                        r_zeros_number = 0;
                                                        r_body =
@@ -1070,12 +1049,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                                             tb->rbytes);
                                        /* append item in R[0] */
                                        if (pos_in_item >= 0) {
-                                               bi.tb = tb;
-                                               bi.bi_bh = tb->R[0];
-                                               bi.bi_parent = tb->FR[0];
-                                               bi.bi_position =
-                                                   get_right_neighbor_position
-                                                   (tb, 0);
+                                               buffer_info_init_right(tb, &bi);
                                                leaf_paste_in_buffer(&bi,
                                                                     item_pos -
                                                                     n +
@@ -1231,10 +1205,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                        put_ih_item_len(ih, sbytes[i]);
 
                                        /* Insert part of the item into S_new[i] before 0-th item */
-                                       bi.tb = tb;
-                                       bi.bi_bh = S_new[i];
-                                       bi.bi_parent = NULL;
-                                       bi.bi_position = 0;
+                                       buffer_info_init_bh(tb, &bi, S_new[i]);
 
                                        if ((old_len - sbytes[i]) > zeros_num) {
                                                r_zeros_number = 0;
@@ -1266,10 +1237,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                                        S_new[i]);
 
                                        /* Insert new item into S_new[i] */
-                                       bi.tb = tb;
-                                       bi.bi_bh = S_new[i];
-                                       bi.bi_parent = NULL;
-                                       bi.bi_position = 0;
+                                       buffer_info_init_bh(tb, &bi, S_new[i]);
                                        leaf_insert_into_buf(&bi,
                                                             item_pos - n +
                                                             snum[i] - 1, ih,
@@ -1294,9 +1262,8 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,    /* item h
 
                                        RFALSE(ih, "PAP-12210: ih must be 0");
 
-                                       if (is_direntry_le_ih
-                                           (aux_ih =
-                                            B_N_PITEM_HEAD(tbS0, item_pos))) {
+                                       aux_ih = B_N_PITEM_HEAD(tbS0, item_pos);
+                                       if (is_direntry_le_ih(aux_ih)) {
                                                /* we append to directory item */
 
                                                int entry_count;
@@ -1326,10 +1293,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                                             sbytes[i] - 1,
                                                             S_new[i]);
                                                        /* Paste given directory entry to directory item */
-                                                       bi.tb = tb;
-                                                       bi.bi_bh = S_new[i];
-                                                       bi.bi_parent = NULL;
-                                                       bi.bi_position = 0;
+                                                       buffer_info_init_bh(tb, &bi, S_new[i]);
                                                        leaf_paste_in_buffer
                                                            (&bi, 0,
                                                             pos_in_item -
@@ -1399,11 +1363,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                                if (n_rem < 0)
                                                        n_rem = 0;
                                                /* Append part of body into S_new[0] */
-                                               bi.tb = tb;
-                                               bi.bi_bh = S_new[i];
-                                               bi.bi_parent = NULL;
-                                               bi.bi_position = 0;
-
+                                               buffer_info_init_bh(tb, &bi, S_new[i]);
                                                if (n_rem > zeros_num) {
                                                        r_zeros_number = 0;
                                                        r_body =
@@ -1490,10 +1450,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                               leaf_mi);
 
                                        /* paste into item */
-                                       bi.tb = tb;
-                                       bi.bi_bh = S_new[i];
-                                       bi.bi_parent = NULL;
-                                       bi.bi_position = 0;
+                                       buffer_info_init_bh(tb, &bi, S_new[i]);
                                        leaf_paste_in_buffer(&bi,
                                                             item_pos - n +
                                                             snum[i],
@@ -1560,10 +1517,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
 
                switch (flag) {
                case M_INSERT:  /* insert item into S[0] */
-                       bi.tb = tb;
-                       bi.bi_bh = tbS0;
-                       bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
-                       bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
+                       buffer_info_init_tbS0(tb, &bi);
                        leaf_insert_into_buf(&bi, item_pos, ih, body,
                                             zeros_num);
 
@@ -1590,14 +1544,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                                       "PAP-12260: insert_size is 0 already");
 
                                                /* prepare space */
-                                               bi.tb = tb;
-                                               bi.bi_bh = tbS0;
-                                               bi.bi_parent =
-                                                   PATH_H_PPARENT(tb->tb_path,
-                                                                  0);
-                                               bi.bi_position =
-                                                   PATH_H_POSITION(tb->tb_path,
-                                                                   1);
+                                               buffer_info_init_tbS0(tb, &bi);
                                                leaf_paste_in_buffer(&bi,
                                                                     item_pos,
                                                                     pos_in_item,
@@ -1645,14 +1592,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,   /* item h
                                                RFALSE(tb->insert_size[0] <= 0,
                                                       "PAP-12275: insert size must not be %d",
                                                       tb->insert_size[0]);
-                                               bi.tb = tb;
-                                               bi.bi_bh = tbS0;
-                                               bi.bi_parent =
-                                                   PATH_H_PPARENT(tb->tb_path,
-                                                                  0);
-                                               bi.bi_position =
-                                                   PATH_H_POSITION(tb->tb_path,
-                                                                   1);
+                                               buffer_info_init_tbS0(tb, &bi);
                                                leaf_paste_in_buffer(&bi,
                                                                     item_pos,
                                                                     pos_in_item,
@@ -1725,7 +1665,6 @@ void make_empty_node(struct buffer_info *bi)
 struct buffer_head *get_FEB(struct tree_balance *tb)
 {
        int i;
-       struct buffer_head *first_b;
        struct buffer_info bi;
 
        for (i = 0; i < MAX_FEB_SIZE; i++)
@@ -1735,16 +1674,13 @@ struct buffer_head *get_FEB(struct tree_balance *tb)
        if (i == MAX_FEB_SIZE)
                reiserfs_panic(tb->tb_sb, "vs-12300", "FEB list is empty");
 
-       bi.tb = tb;
-       bi.bi_bh = first_b = tb->FEB[i];
-       bi.bi_parent = NULL;
-       bi.bi_position = 0;
+       buffer_info_init_bh(tb, &bi, tb->FEB[i]);
        make_empty_node(&bi);
-       set_buffer_uptodate(first_b);
+       set_buffer_uptodate(tb->FEB[i]);
+       tb->used[i] = tb->FEB[i];
        tb->FEB[i] = NULL;
-       tb->used[i] = first_b;
 
-       return (first_b);
+       return tb->used[i];
 }
 
 /* This is now used because reiserfs_free_block has to be able to
@@ -1896,11 +1832,12 @@ static int check_before_balancing(struct tree_balance *tb)
 {
        int retval = 0;
 
-       if (cur_tb) {
+       if (REISERFS_SB(tb->tb_sb)->cur_tb) {
                reiserfs_panic(tb->tb_sb, "vs-12335", "suspect that schedule "
                               "occurred based on cur_tb not being null at "
                               "this point in code. do_balance cannot properly "
-                              "handle schedule occurring while it runs.");
+                              "handle concurrent tree accesses on a same "
+                              "mount point.");
        }
 
        /* double check that buffers that we will modify are unlocked. (fix_nodes should already have
@@ -2038,11 +1975,11 @@ static inline void do_balance_starts(struct tree_balance *tb)
        /* store_print_tb (tb); */
 
        /* do not delete, just comment it out */
-/*    print_tb(flag, PATH_LAST_POSITION(tb->tb_path), tb->tb_path->pos_in_item, tb, 
+/*    print_tb(flag, PATH_LAST_POSITION(tb->tb_path), tb->tb_path->pos_in_item, tb,
             "check");*/
        RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB");
 #ifdef CONFIG_REISERFS_CHECK
-       cur_tb = tb;
+       REISERFS_SB(tb->tb_sb)->cur_tb = tb;
 #endif
 }
 
@@ -2052,7 +1989,7 @@ static inline void do_balance_completed(struct tree_balance *tb)
 #ifdef CONFIG_REISERFS_CHECK
        check_leaf_level(tb);
        check_internal_levels(tb);
-       cur_tb = NULL;
+       REISERFS_SB(tb->tb_sb)->cur_tb = NULL;
 #endif
 
        /* reiserfs_free_block is no longer schedule safe.  So, we need to