On Mon 04-08-14 19:51:47, Jeff Mahoney wrote:
> Commits f1f007c308e (reiserfs: balance_leaf refactor, pull out
> balance_leaf_insert_left) and cf22df182bf (reiserfs: balance_leaf
> refactor, pull out balance_leaf_paste_left) missed that the `body'
> pointer was getting repositioned. Subsequent users of the pointer
> would expect it to be repositioned, and as a result, parts of the
> tree would get overwritten. The most common observed corruption
> is indirect block pointers being overwritten.
>
> Since the body value isn't actually used anymore in the called routines,
> we can pass back the offset it should be shifted. We constify the body
> and ih pointers in the balance_leaf as a mostly-free preventative measure.
Thanks. I've added the patch to my tree and I'll push it to Linus in this
merge window (after basic test runs finish).
Honza
>
> Cc: <[email protected]> # 3.16
> Reported-by: Jeff Chua <[email protected]>
> Signed-off-by: Jeff Mahoney <[email protected]>
> ---
> fs/reiserfs/do_balan.c | 111
> +++++++++++++++++++++++++++----------------------
> fs/reiserfs/lbalance.c | 5 +-
> fs/reiserfs/reiserfs.h | 9 ++-
> 3 files changed, 71 insertions(+), 54 deletions(-)
>
> --- a/fs/reiserfs/do_balan.c
> +++ b/fs/reiserfs/do_balan.c
> @@ -286,12 +286,14 @@ static int balance_leaf_when_delete(stru
> return 0;
> }
>
> -static void balance_leaf_insert_left(struct tree_balance *tb,
> - struct item_head *ih, const char *body)
> +static unsigned int balance_leaf_insert_left(struct tree_balance *tb,
> + struct item_head *const ih,
> + const char * const body)
> {
> int ret;
> struct buffer_info bi;
> int n = B_NR_ITEMS(tb->L[0]);
> + unsigned body_shift_bytes = 0;
>
> if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) {
> /* part of new item falls into L[0] */
> @@ -329,7 +331,7 @@ static void balance_leaf_insert_left(str
>
> put_ih_item_len(ih, new_item_len);
> if (tb->lbytes > tb->zeroes_num) {
> - body += (tb->lbytes - tb->zeroes_num);
> + body_shift_bytes = tb->lbytes - tb->zeroes_num;
> tb->zeroes_num = 0;
> } else
> tb->zeroes_num -= tb->lbytes;
> @@ -349,11 +351,12 @@ static void balance_leaf_insert_left(str
> tb->insert_size[0] = 0;
> tb->zeroes_num = 0;
> }
> + return body_shift_bytes;
> }
>
> static void balance_leaf_paste_left_shift_dirent(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> int n = B_NR_ITEMS(tb->L[0]);
> struct buffer_info bi;
> @@ -413,17 +416,18 @@ static void balance_leaf_paste_left_shif
> tb->pos_in_item -= tb->lbytes;
> }
>
> -static void balance_leaf_paste_left_shift(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body)
> +static unsigned int balance_leaf_paste_left_shift(struct tree_balance *tb,
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> int n = B_NR_ITEMS(tb->L[0]);
> struct buffer_info bi;
> + int body_shift_bytes = 0;
>
> if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) {
> balance_leaf_paste_left_shift_dirent(tb, ih, body);
> - return;
> + return 0;
> }
>
> RFALSE(tb->lbytes <= 0,
> @@ -497,7 +501,7 @@ static void balance_leaf_paste_left_shif
> * insert_size[0]
> */
> if (l_n > tb->zeroes_num) {
> - body += (l_n - tb->zeroes_num);
> + body_shift_bytes = l_n - tb->zeroes_num;
> tb->zeroes_num = 0;
> } else
> tb->zeroes_num -= l_n;
> @@ -526,13 +530,14 @@ static void balance_leaf_paste_left_shif
> */
> leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
> }
> + return body_shift_bytes;
> }
>
>
> /* appended item will be in L[0] in whole */
> static void balance_leaf_paste_left_whole(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> int n = B_NR_ITEMS(tb->L[0]);
> @@ -584,39 +589,44 @@ static void balance_leaf_paste_left_whol
> tb->zeroes_num = 0;
> }
>
> -static void balance_leaf_paste_left(struct tree_balance *tb,
> - struct item_head *ih, const char *body)
> +static unsigned int balance_leaf_paste_left(struct tree_balance *tb,
> + struct item_head * const ih,
> + const char * const body)
> {
> /* we must shift the part of the appended item */
> if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1)
> - balance_leaf_paste_left_shift(tb, ih, body);
> + return balance_leaf_paste_left_shift(tb, ih, body);
> else
> balance_leaf_paste_left_whole(tb, ih, body);
> + return 0;
> }
>
> /* Shift lnum[0] items from S[0] to the left neighbor L[0] */
> -static void balance_leaf_left(struct tree_balance *tb, struct item_head *ih,
> - const char *body, int flag)
> +static unsigned int balance_leaf_left(struct tree_balance *tb,
> + struct item_head * const ih,
> + const char * const body, int flag)
> {
> if (tb->lnum[0] <= 0)
> - return;
> + return 0;
>
> /* new item or it part falls to L[0], shift it too */
> if (tb->item_pos < tb->lnum[0]) {
> BUG_ON(flag != M_INSERT && flag != M_PASTE);
>
> if (flag == M_INSERT)
> - balance_leaf_insert_left(tb, ih, body);
> + return balance_leaf_insert_left(tb, ih, body);
> else /* M_PASTE */
> - balance_leaf_paste_left(tb, ih, body);
> + return balance_leaf_paste_left(tb, ih, body);
> } else
> /* new item doesn't fall into L[0] */
> leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
> + return 0;
> }
>
>
> static void balance_leaf_insert_right(struct tree_balance *tb,
> - struct item_head *ih, const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
>
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> @@ -704,7 +714,8 @@ static void balance_leaf_insert_right(st
>
>
> static void balance_leaf_paste_right_shift_dirent(struct tree_balance *tb,
> - struct item_head *ih, const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> struct buffer_info bi;
> @@ -754,7 +765,8 @@ static void balance_leaf_paste_right_shi
> }
>
> static void balance_leaf_paste_right_shift(struct tree_balance *tb,
> - struct item_head *ih, const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> int n_shift, n_rem, r_zeroes_number, version;
> @@ -831,7 +843,8 @@ static void balance_leaf_paste_right_shi
> }
>
> static void balance_leaf_paste_right_whole(struct tree_balance *tb,
> - struct item_head *ih, const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> int n = B_NR_ITEMS(tbS0);
> @@ -874,7 +887,8 @@ static void balance_leaf_paste_right_who
> }
>
> static void balance_leaf_paste_right(struct tree_balance *tb,
> - struct item_head *ih, const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> int n = B_NR_ITEMS(tbS0);
> @@ -896,8 +910,9 @@ static void balance_leaf_paste_right(str
> }
>
> /* shift rnum[0] items from S[0] to the right neighbor R[0] */
> -static void balance_leaf_right(struct tree_balance *tb, struct item_head *ih,
> - const char *body, int flag)
> +static void balance_leaf_right(struct tree_balance *tb,
> + struct item_head * const ih,
> + const char * const body, int flag)
> {
> if (tb->rnum[0] <= 0)
> return;
> @@ -911,8 +926,8 @@ static void balance_leaf_right(struct tr
> }
>
> static void balance_leaf_new_nodes_insert(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body,
> + struct item_head * const ih,
> + const char * const body,
> struct item_head *insert_key,
> struct buffer_head **insert_ptr,
> int i)
> @@ -1003,8 +1018,8 @@ static void balance_leaf_new_nodes_inser
>
> /* we append to directory item */
> static void balance_leaf_new_nodes_paste_dirent(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body,
> + struct item_head * const ih,
> + const char * const body,
> struct item_head *insert_key,
> struct buffer_head **insert_ptr,
> int i)
> @@ -1058,8 +1073,8 @@ static void balance_leaf_new_nodes_paste
> }
>
> static void balance_leaf_new_nodes_paste_shift(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body,
> + struct item_head * const ih,
> + const char * const body,
> struct item_head *insert_key,
> struct buffer_head **insert_ptr,
> int i)
> @@ -1131,8 +1146,8 @@ static void balance_leaf_new_nodes_paste
> }
>
> static void balance_leaf_new_nodes_paste_whole(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body,
> + struct item_head * const ih,
> + const char * const body,
> struct item_head *insert_key,
> struct buffer_head **insert_ptr,
> int i)
> @@ -1184,8 +1199,8 @@ static void balance_leaf_new_nodes_paste
>
> }
> static void balance_leaf_new_nodes_paste(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body,
> + struct item_head * const ih,
> + const char * const body,
> struct item_head *insert_key,
> struct buffer_head **insert_ptr,
> int i)
> @@ -1214,8 +1229,8 @@ static void balance_leaf_new_nodes_paste
>
> /* Fill new nodes that appear in place of S[0] */
> static void balance_leaf_new_nodes(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body,
> + struct item_head * const ih,
> + const char * const body,
> struct item_head *insert_key,
> struct buffer_head **insert_ptr,
> int flag)
> @@ -1254,8 +1269,8 @@ static void balance_leaf_new_nodes(struc
> }
>
> static void balance_leaf_finish_node_insert(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> struct buffer_info bi;
> @@ -1271,8 +1286,8 @@ static void balance_leaf_finish_node_ins
> }
>
> static void balance_leaf_finish_node_paste_dirent(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> struct item_head *pasted = item_head(tbS0, tb->item_pos);
> @@ -1305,8 +1320,8 @@ static void balance_leaf_finish_node_pas
> }
>
> static void balance_leaf_finish_node_paste(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body)
> + struct item_head * const ih,
> + const char * const body)
> {
> struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
> struct buffer_info bi;
> @@ -1349,8 +1364,8 @@ static void balance_leaf_finish_node_pas
> * of the affected item which remains in S
> */
> static void balance_leaf_finish_node(struct tree_balance *tb,
> - struct item_head *ih,
> - const char *body, int flag)
> + struct item_head * const ih,
> + const char * const body, int flag)
> {
> /* if we must insert or append into buffer S[0] */
> if (0 <= tb->item_pos && tb->item_pos < tb->s0num) {
> @@ -1402,7 +1417,7 @@ static int balance_leaf(struct tree_bala
> && is_indirect_le_ih(item_head(tbS0, tb->item_pos)))
> tb->pos_in_item *= UNFM_P_SIZE;
>
> - balance_leaf_left(tb, ih, body, flag);
> + body += balance_leaf_left(tb, ih, body, flag);
>
> /* tb->lnum[0] > 0 */
> /* Calculate new item position */
> --- a/fs/reiserfs/lbalance.c
> +++ b/fs/reiserfs/lbalance.c
> @@ -899,8 +899,9 @@ void leaf_delete_items(struct buffer_inf
>
> /* insert item into the leaf node in position before */
> void leaf_insert_into_buf(struct buffer_info *bi, int before,
> - struct item_head *inserted_item_ih,
> - const char *inserted_item_body, int zeros_number)
> + struct item_head * const inserted_item_ih,
> + const char * const inserted_item_body,
> + int zeros_number)
> {
> struct buffer_head *bh = bi->bi_bh;
> int nr, free_space;
> --- a/fs/reiserfs/reiserfs.h
> +++ b/fs/reiserfs/reiserfs.h
> @@ -3216,11 +3216,12 @@ int leaf_shift_right(struct tree_balance
> void leaf_delete_items(struct buffer_info *cur_bi, int last_first, int first,
> int del_num, int del_bytes);
> void leaf_insert_into_buf(struct buffer_info *bi, int before,
> - struct item_head *inserted_item_ih,
> - const char *inserted_item_body, int zeros_number);
> -void leaf_paste_in_buffer(struct buffer_info *bi, int pasted_item_num,
> - int pos_in_item, int paste_size, const char *body,
> + struct item_head * const inserted_item_ih,
> + const char * const inserted_item_body,
> int zeros_number);
> +void leaf_paste_in_buffer(struct buffer_info *bi, int pasted_item_num,
> + int pos_in_item, int paste_size,
> + const char * const body, int zeros_number);
> void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
> int pos_in_item, int cut_size);
> void leaf_paste_entries(struct buffer_info *bi, int item_num, int before,
>
>
> --
> Jeff Mahoney
> SUSE Labs
--
Jan Kara <[email protected]>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html