免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: sisi8408
打印 上一主题 下一主题

Kernel Bug-Vulnerability-Comment library [复制链接]

论坛徽章:
0
91 [报告]
发表于 2008-02-09 12:58 |只看该作者

  1. static void internal_copy_pointers_items(struct buffer_info *dest_bi,
  2.                                          struct buffer_head *src,
  3.                                          int last_first, int cpy_num)
  4. {
  5.         /* ATTENTION! Number of node pointers in DEST is equal to number of items in DEST,
  6.          * as delimiting key have already inserted to buffer dest.
  7.          */
  8.         struct buffer_head *dest = dest_bi->bi_bh;
  9.         int nr_dest, nr_src;
  10.         int dest_order, src_order;
  11.         struct block_head *blkh;
  12.         struct reiserfs_key *key;
  13.         struct disk_child *dc;

  14.         nr_src = B_NR_ITEMS(src);

  15.         RFALSE(dest == NULL || src == NULL,
  16.                "src (%p) or dest (%p) buffer is 0", src, dest);
  17.         /*
  18.         2008-2-9 12:54
  19.         linux-2.6.23.12
  20.        
  21.         RFALSE(dest == NULL || src == NULL,
  22.                "src (%p) or dest (%p) buffer is 0", src, dest);
  23.         nr_src = B_NR_ITEMS(src);
  24.         */
  25. [...]
  26. }

复制代码

论坛徽章:
0
92 [报告]
发表于 2008-02-12 17:27 |只看该作者

  1. simple ops in Stree

  2. Unlike ext2, reiserfs is a modner FS and has attrs:
  3. 1, logging
  4. 2, extent inode attr
  5. 3, acl, posix or not
  6. 4, Stree, derived from Btree

  7. Like Btree, Stree consists of nodes and manages nodes,
  8. which only contains meta info. there are two kinds of nodes
  9. in Stree: interal and leaf, and for simplicity the internal
  10. is called node here, following the Btree def.

  11. By def in Stree, node, mapped to phyiscal block(block on disk) by BLKH,
  12. is just a array of KEY+DC(block pointer or disk child), though the format
  13. of the array is funny, and Mr HR, i guess, favorates block ops in crazy manner,
  14. which can be understood since the block_sz can be changed acoording to ur taste.

  15. Unlike node, leaf is used to store four types of items,
  16. 1, sd, stat data, or inode, the hot element of FS
  17. 2, de, dir entry, also hot
  18. 3, direct
  19. 4, indirect
  20. compared withext2, nothing is new but the way to manage them.

  21. Lets see a rather simple example on linux cmdline

  22. # echo a >> /mnt_HS/Stree/simple
  23. # echo $?
  24. 0

  25. /*
  26. * As in the whitepaper by Mr. HR, it is not simple to show Stree chart though
  27. * charmimg like Nina Reiser, here i do what i can.
  28. */

  29. and the corresponding image in Stree is

  30.         | BLKH[h+2] | P0 | ... | P[h+2] | ... | free space |

  31. where BLKH[h+2] represents the block of block_sz bytes pointed to by root node,
  32. i gas, and P[h+2] to dir `Stree',

  33.         | BLKH[h+1] | P0 | ... | PL[h+1] | P[h+1] | PR[h+1] | ... | free space |

  34. where P[h+1] to regular file `simple' or S in HR's dictionary,
  35. simlarly PL[h+1] to L, and PR[h+1] to R, finally and obviuosly h = 0,
  36. in this simple case.

  37.         | BLKH[h] | IH-0 | IH-1 | free space | I-1 | I-0 |

  38. where IH for Item Header, and IH-0 is of type `sd',
  39. I-0 is the socalled inode of `simple',
  40. IH-1, i gas, is of type `direct', and its body I-1 is just `a'.

  41. After another operation on `simple'

  42. # echo b >> /mnt_HS/Stree/simple

  43. i gas, the only chg in Stree is IH-1 and its body from `a' to `ab',
  44. lets check what HR did in v-3.6 of linux-2.6.23.12,

  45. /* first, ==========================
  46.    ip means Inserting or Pasting
  47. */
  48. static int ip_check_balance(struct tree_balance *tb, int h)
  49. {
  50. [...]
  51.         if (can_node_be_removed(vn->vn_mode, lfree, sfree, rfree, tb, h)
  52.             == NO_BALANCING_NEEDED)
  53.                 /* new item fits into node S[h] without any shifting */
  54.                 return NO_BALANCING_NEEDED;
  55. [...]
  56. }

  57. /* second, ==========================
  58. */
  59. static inline int can_node_be_removed(int mode, int lfree, int sfree, int rfree,
  60.                                       struct tree_balance *tb, int h)
  61. {
  62.         struct buffer_head *Sh = PATH_H_PBUFFER(tb->tb_path, h);
  63.         int levbytes = tb->insert_size[h];

  64.         struct item_head *ih;
  65.         struct reiserfs_key *r_key = NULL;

  66.         ih = B_N_PITEM_HEAD(Sh, 0);

  67.         if (tb->CFR[h])
  68.                 r_key = B_N_PDELIM_KEY(tb->CFR[h], tb->rkey[h]);
  69.         /*
  70.          * nicer to understand as:
  71.          * lfree + rfree < MAX_CHILD_SIZE(Sh) - sfree + levbytes
  72.          */
  73.         if (lfree + rfree + sfree < MAX_CHILD_SIZE(Sh) + levbytes
  74.             /* shifting may merge items which might save space */
  75.             - ((!h && op_is_left_mergeable(&ih->ih_key, Sh->b_size)) ? IH_SIZE : 0)
  76.             - ((!h && r_key && op_is_left_mergeable(r_key, Sh->b_size)) ? IH_SIZE : 0)
  77.             + (h ? KEY_SIZE : 0))
  78.         { /* node can not be removed */
  79.                 if (sfree >= levbytes) {
  80.                         /* new item fits into node S[h] without any shifting */
  81.                         if (!h)
  82.                                 tb->s0num = B_NR_ITEMS(Sh) + ((mode == M_INSERT) ? 1 : 0);
  83.                        
  84.                         set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
  85.                         return NO_BALANCING_NEEDED;
  86.                 }
  87.         }
  88.         PROC_INFO_INC(tb->tb_sb, can_node_be_removed[h]);
  89.         return !NO_BALANCING_NEEDED;
  90. }

  91. Oh Jesus, HR favorates shift much more, and i gas once more,
  92. meta data and balance are concerned by HR much more than file data?

  93. As u see, the code for the two ops, fix_node and do_balance, upon Stree is
  94. hard and harder to read, and i dream dig it no more harder
  95. in v-3.7 in the original track, and U r welcome to my dream.

复制代码

[ 本帖最后由 sisi8408 于 2008-2-12 17:29 编辑 ]

论坛徽章:
0
93 [报告]
发表于 2008-02-13 20:15 |只看该作者

  1. static void create_virtual_node(struct tree_balance *tb, int h)
  2. {
  3.         struct item_head *ih;
  4.         struct virtual_node *vn = tb->tb_vn;
  5.         int new_num;
  6.         struct buffer_head *Sh = PATH_H_PBUFFER(tb->tb_path, h);

  7.         if (!h) {
  8.                 create_virtual_leaf(tb, h);
  9.                 return;
  10.         }
  11.         /* size of v node */
  12.         vn->vn_size = MAX_CHILD_SIZE(Sh) - B_FREE_SPACE(Sh)
  13.                         + tb->insert_size[h];
  14.         vn->vn_nr_item = (vn->vn_size - DC_SIZE) / (DC_SIZE + KEY_SIZE);
  15. }

  16. static void create_virtual_leaf(struct tree_balance *tb, int h)
  17. {
  18.         struct item_head *ih;
  19.         struct virtual_node *vn = tb->tb_vn;
  20.         int new_num;
  21.         struct buffer_head *Sh = PATH_H_PBUFFER(tb->tb_path, h);
  22.        
  23.         vn->vn_size = MAX_CHILD_SIZE(Sh) - B_FREE_SPACE(Sh) + tb->insert_size[h];
  24.        
  25.         /* number of items in v node  */
  26.         vn->vn_nr_item = B_NR_ITEMS(Sh) +
  27.                          ((vn->vn_mode == M_INSERT) ? 1 : 0) -
  28.                              ((vn->vn_mode == M_DELETE) ? 1 : 0);

  29.         /* first v item */
  30.         vn->vn_vi = (struct virtual_item *)(tb->tb_vn + 1);
  31.        
  32.         memset(vn->vn_vi, 0, vn->vn_nr_item * sizeof(struct virtual_item));
  33.        
  34.         vn->vn_free_ptr += vn->vn_nr_item * sizeof(struct virtual_item);
  35.         /*
  36.          * first item in S[h]
  37.          */
  38.         ih = B_N_PITEM_HEAD(Sh, 0);
  39.         /*
  40.          * define the mergeability for 0-th item,
  41.          * if it is not being deleted
  42.          */
  43.         if (op_is_left_mergeable(&ih->ih_key, Sh->b_size)
  44.             && (vn->vn_mode != M_DELETE || vn->vn_affected_item_num))
  45.                 vn->vn_vi[0].vi_type |= VI_TYPE_LEFT_MERGEABLE;

  46.         /*
  47.          * go through all items those remain in the virtual node,
  48.          * except for the new (inserted) one
  49.          */
  50.         for (new_num = 0; new_num < vn->vn_nr_item; new_num++) {
  51.                 int j;
  52.                 struct virtual_item *vi = vn->vn_vi + new_num;
  53.                 int is_affected = new_num == vn->vn_affected_item_num;

  54.                 if (is_affected && vn->vn_mode == M_INSERT)
  55.                         continue;

  56.                 /* get item number in source node */
  57.                 j = old_item_num(new_num, vn->vn_affected_item_num, vn->vn_mode);
  58.                 /*
  59.                  * vi->vi_item_len += ih_item_len(ih + j) + IH_SIZE;
  60.                  *
  61.                  * and its still amazing why IH_SIZE counted even if !is_affected.
  62.                                  *
  63.                                  * Jesus, its used, at least, by check_left/right

  64.         for (i = 0; i < vn->vn_nr_item;
  65.              i++, ih_size = IH_SIZE, d_size = 0, vi++) {
  66.                 d_size += vi->vi_item_len;

  67.         for (i = vn->vn_nr_item - 1; i >= 0;
  68.              i--, d_size = 0, ih_size = IH_SIZE, vi--) {
  69.                 d_size += vi->vi_item_len;
  70.                                  *
  71.                                  */
  72.                 vi->vi_item_len = ih_item_len(ih + j) + IH_SIZE;
  73.                 vi->vi_ih   = ih + j;
  74.                 vi->vi_item = B_I_PITEM(Sh, ih + j);
  75.                 vi->vi_uarea = vn->vn_free_ptr;
  76.                 /*
  77.                  * FIXME: there is no check, that item operation did not
  78.                  * consume too much memory
  79.                  */
  80.                 vn->vn_free_ptr +=
  81.                         op_create_vi(vn, vi, is_affected, tb->insert_size[0]);

  82.                 if (tb->vn_buf + tb->vn_buf_size < vn->vn_free_ptr)
  83.                         reiserfs_panic(tb->tb_sb,
  84.                                        "vs-8030: create_virtual_node: "
  85.                                        "virtual node space consumed");
  86.                
  87.                 if (!is_affected) /* this item is not being changed */
  88.                         continue;

  89.                 if (vn->vn_mode == M_PASTE || vn->vn_mode == M_CUT) {
  90.                         /*vn->vn_vi[new_num].vi_item_len += tb->insert_size[0]; */
  91.                         vi->vi_item_len += tb->insert_size[0];
  92.                         vi->vi_new_data = vn->vn_data;
  93.                 }
  94.         }

  95.         /* virtual inserted item is not defined yet */
  96.         if (vn->vn_mode == M_INSERT) {
  97.                 struct virtual_item *vi = vn->vn_vi + vn->vn_affected_item_num;

  98.                 RFALSE(vn->vn_ins_ih == 0,
  99.                        "vs-8040: item header of inserted item is not specified");

  100.                 vi->vi_item_len = tb->insert_size[0];
  101.                 vi->vi_ih = vn->vn_ins_ih;
  102.                 vi->vi_item = vn->vn_data;
  103.                 vi->vi_uarea = vn->vn_free_ptr;

  104.                 op_create_vi(vn, vi, 0 /*not pasted or cut */ ,
  105.                              tb->insert_size[0]);
  106.         }

  107.         /* set right merge flag we take right delimiting key and
  108.          * check whether it is a mergeable item
  109.          */
  110.         if (tb->CFR[0]) {
  111.                 struct reiserfs_key *key;

  112.                 key = B_N_PDELIM_KEY(tb->CFR[0], tb->rkey[0]);

  113.                 if (op_is_left_mergeable(key, Sh->b_size) &&
  114.                     (vn->vn_mode != M_DELETE ||
  115.                      vn->vn_affected_item_num != B_NR_ITEMS(Sh) - 1))
  116.                         vn->vn_vi[vn->vn_nr_item - 1].vi_type |= VI_TYPE_RIGHT_MERGEABLE;

  117. #ifdef CONFIG_REISERFS_CHECK
  118.                 if (op_is_left_mergeable(key, Sh->b_size) &&
  119.                     !(vn->vn_mode != M_DELETE
  120.                       || vn->vn_affected_item_num != B_NR_ITEMS(Sh) - 1)) {
  121.                         /* we delete last item and
  122.                          * it could be merged with right neighbor's first item
  123.                          */
  124.                         if (!
  125.                             (B_NR_ITEMS(Sh) == 1
  126.                              && is_direntry_le_ih(B_N_PITEM_HEAD(Sh, 0))
  127.                              && I_ENTRY_COUNT(B_N_PITEM_HEAD(Sh, 0)) == 1)) {
  128.                                 /* node contains more than 1 item, or item is not directory item, or this item contains more than 1 entry */
  129.                                 print_block(Sh, 0, -1, -1);
  130.                                 reiserfs_panic(tb->tb_sb,
  131.                                                "vs-8045: create_virtual_node: rdkey %k, affected item==%d (mode==%c) Must be %c",
  132.                                                key, vn->vn_affected_item_num,
  133.                                                vn->vn_mode, M_DELETE);
  134.                         }
  135.                 }
  136. #endif
  137.         }
  138. }
复制代码

[ 本帖最后由 sisi8408 于 2008-2-13 20:45 编辑 ]

论坛徽章:
0
94 [报告]
发表于 2008-02-15 03:44 |只看该作者
linux-2.6.24/fs/dcache.c

static void switch_names(struct dentry *dentry, struct dentry *target)
{
        if (dname_external(target)) {
                if (dname_external(dentry)) {
                        /*
                         * Both external: swap the pointers
                         */
                        do_switch(target->d_name.name, dentry->d_name.name);
                } else {
                        /*
                         * dentry:internal, target:external.  Steal target's
                         * storage and make target internal.
                         */
                        memcpy(target->d_iname, dentry->d_name.name,
                                        dentry->d_name.len + 1);
                        dentry->d_name.name = target->d_name.name;
                        target->d_name.name = target->d_iname;
                }
        } else {
                if (dname_external(dentry)) {
                        /*
                         * dentry:external, target:internal.  Give dentry's
                         * storage to target and make dentry internal
                         */
                        memcpy(dentry->d_iname, target->d_name.name,
                                        target->d_name.len + 1);
                        target->d_name.name = dentry->d_name.name;
                        dentry->d_name.name = dentry->d_iname;
                } else {
                        /*
                         * Both are internal.  Just copy target to dentry
                         */
                        memcpy(dentry->d_iname, target->d_name.name,
                                        target->d_name.len + 1);

                }
        }
}

论坛徽章:
0
95 [报告]
发表于 2008-02-16 14:54 |只看该作者

回复 #94 daemeon 的帖子

itis only u, at least uptonow, play cool game like this,
and it sounds cooler if u show ur nice comment.

论坛徽章:
0
96 [报告]
发表于 2008-02-16 14:56 |只看该作者

  1. static void balance_leaf_do_split(struct tree_balance *tb,
  2.                                    struct item_head *ih,
  3.                                    const char *body,
  4.                                    int flag,
  5.                                    struct item_head *insert_key,
  6.                                    struct buffer_head **insert_ptr)
  7. {
  8.         struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
  9.         /* index of the affected item */
  10.         int item_pos = PATH_LAST_POSITION(tb->tb_path);

  11.         struct buffer_info bi;

  12.         int n, i, ret_val;
  13.         int pos_in_item;
  14.         int zeros_num;

  15.         struct buffer_head *S_new[2];
  16.         int snum[2];
  17.         int sbytes[2];
  18.        
  19.         if (!tb->blknum[0])
  20.                 return;

  21.         if (!(flag == M_INSERT || flag == M_PASTE) {
  22.                 reiserfs_panic(tb->tb_sb,
  23.                         "PAP-12245: balance_leaf: blknum > 2: unexpectable mode: %s(%d)",
  24.                         (flag == M_DELETE) ? "DELETE" :
  25.                         ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
  26.                 return;
  27.         }
  28.        
  29.         RFALSE(tb->blknum[0] < 1 || tb->blknum[0] > 3,
  30.                 "PAP-12180: blknum can not be %d. It must be in range [1,3]",
  31.                 tb->blknum[0]);

  32.         /* Fill new nodes that appear in place of S[0] */
  33.         snum[0] = tb->s1num;
  34.         snum[1] = tb->s2num;
  35.         sbytes[0] = tb->s1bytes;
  36.         sbytes[1] = tb->s2bytes;

  37.         for (i = tb->blknum[0] - 2; i >= 0; i--) {
  38.                 RFALSE(!snum[i], "PAP-12200: snum[%d] == %d. Must be > 0", i, snum[i]);
  39.                 /* here we shift from S to S_new nodes */
  40.                 S_new[i] = get_FEB(tb);
  41.                 /* initialized block type and tree level */
  42.                 set_blkh_level(B_BLK_HEAD(S_new[i]), DISK_LEAF_NODE_LEVEL);

  43.                 n = B_NR_ITEMS(tbS0);
  44.                
  45.                 if (flag == M_INSERT) {
  46.                         if (!(n - snum[i] < item_pos)) {
  47.                                 /* new item or it part don't falls into S_new[i] */
  48.                                 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
  49.                                                 snum[i], sbytes[i], S_new[i]);
  50.                                 goto next;
  51.                         }
  52.                         goto long_tail_insert;
  53.                 } else {
  54.                         if (!(n - snum[i] <= item_pos)) {
  55.                                 /* pasted item doesn't fall into S_new[i] */
  56.                                 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
  57.                                                 snum[i], sbytes[i], S_new[i]);
  58.                                 goto next;
  59.                         }
  60.                         goto long_tail_paste;
  61.                 }

  62.         long_tail_insert:
  63.                 if (item_pos == n - snum[i] + 1 && sbytes[i] != -1) {
  64.                         /* part of new item falls into S_new[i] */
  65.                         int old_key_comp, old_len, r_zeros_number;
  66.                         const char *r_body;
  67.                         int version;
  68.                        
  69.                         /* Move snum[i]-1 items from S[0] to S_new[i] */
  70.                         leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
  71.                                         snum[i] -1, -1, S_new[i]);
  72.                         /* Remember key component and item length */
  73.                         version = ih_version(ih);
  74.                         old_key_comp = le_ih_k_offset(ih);
  75.                         old_len = ih_item_len(ih);
  76.                        
  77.                         /*Calculate key component and item length to insert into S_new[i] */
  78.                         set_le_ih_k_offset(ih,
  79.                             le_ih_k_offset(ih) +
  80.                                ((old_len - sbytes[i]) << (is_indirect_le_ih(ih) ?
  81.                                                                  tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT : 0)));
  82.                         put_ih_item_len(ih, sbytes[i]);
  83.                         /* Insert part of the item into S_new[i] before 0-th item */
  84.                         bi.tb = tb;
  85.                         bi.bi_bh = S_new[i];
  86.                         bi.bi_parent = NULL;
  87.                         bi.bi_position = 0;
  88.                        
  89.                         if ((old_len - sbytes[i]) > zeros_num) {
  90.                                 r_zeros_number = 0;
  91.                                 r_body = body + (old_len - sbytes[i]) - zeros_num;
  92.                         } else {
  93.                                 r_body = body;
  94.                                 r_zeros_number = zeros_num - (old_len - sbytes[i]);
  95.                                 zeros_num -= r_zeros_number;
  96.                         }
  97.                         leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeros_number);
  98.                        
  99.                         /* Calculate key component and item length to insert into S[i] */
  100.                         set_le_ih_k_offset(ih, old_key_comp);
  101.                         put_ih_item_len(ih, old_len - sbytes[i]);
  102.                         tb->insert_size[0] -= sbytes[i];
  103.                
  104.                 } else { /* whole new item falls into S_new[i] */
  105.                         /* Shift snum[0] - 1 items to S_new[i] (sbytes[i] of split item) */
  106.                         leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
  107.                                         snum[i] -1, sbytes[i], S_new[i]);
  108.                         /* Insert new item into S_new[i] */
  109.                         bi.tb = tb;
  110.                         bi.bi_bh = S_new[i];
  111.                         bi.bi_parent = NULL;
  112.                         bi.bi_position = 0;
  113.                        
  114.                         leaf_insert_into_buf(&bi, item_pos - n + snum[i] - 1,
  115.                                                 ih, body, zeros_num);
  116.                         zeros_num = tb->insert_size[0] = 0;
  117.                 }
  118.                 goto next;
  119.        
  120.         long_tail_paste:
  121.                 if (item_pos == n - snum[i] && sbytes[i] != -1) {
  122.                         /* we must shift part of the appended item */
  123.                         struct item_head *aux_ih;
  124.                        
  125.                         RFALSE(ih, "PAP-12210: ih must be 0");
  126.                        
  127.                         aux_ih = B_N_PITEM_HEAD(tbS0, item_pos);
  128.                         if (is_direntry_le_ih(aux_ih)) {
  129.                                 /* we append to directory item */
  130.                                 int entry_count = ih_entry_count(aux_ih);
  131.                                
  132.                                 if (entry_count - sbytes[i] < pos_in_item
  133.                                     && pos_in_item <= entry_count) {
  134.                                         /* new directory entry falls into S_new[i] */
  135.                                         RFALSE(!tb->insert_size[0],
  136.                                                "PAP-12215: insert_size is already 0");
  137.                                         RFALSE(sbytes[i] - 1 >= entry_count,
  138.                                                "PAP-12220: there are no so much entries (%d), only %d",
  139.                                                sbytes[i] - 1, entry_count);
  140.                                        
  141.                                         /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
  142.                                         leaf_move_items(LEAF_FROM_S_TO_SNEW, tb, snum[i],
  143.                                                              sbytes[i] - 1, S_new[i]);
  144.                                         /* Paste given directory entry to directory item */
  145.                                         bi.tb = tb;
  146.                                         bi.bi_bh = S_new[i];
  147.                                         bi.bi_parent = NULL;
  148.                                         bi.bi_position = 0;
  149.                                        
  150.                                         leaf_paste_in_buffer(&bi, 0,
  151.                                                 pos_in_item - entry_count + sbytes[i] - 1,
  152.                                                 tb->insert_size[0], body, zeros_num);
  153.                                        
  154.                                         /* paste new directory entry */
  155.                                         leaf_paste_entries(bi.bi_bh, 0,
  156.                                                 pos_in_item - entry_count + sbytes[i] - 1,
  157.                                                 1,
  158.                                                 (struct reiserfs_de_head *) body,
  159.                                                 body + DEH_SIZE, tb->insert_size[0]);
  160.                                        
  161.                                         tb->insert_size[0] = 0;
  162.                                         pos_in_item++;
  163.                                 } else {
  164.                                         /* new directory entry doesn't fall into S_new[i] */
  165.                                         leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
  166.                                                 snum[i], sbytes[i], S_new[i]);
  167.                                 }
  168.                         } else { /* regular object */
  169.                                 int n_shift, n_rem, r_zeros_number;
  170.                                 const char *r_body;
  171.                                
  172.                                 RFALSE(pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos))
  173.                                        || tb->insert_size[0] <= 0,
  174.                                        "PAP-12225: item too short or insert_size <= 0");
  175.                                 /* Calculate number of bytes which must be
  176.                                  * shifted from appended item */
  177.                                 n_shift = sbytes[i] - tb->insert_size[0];
  178.                                 if (n_shift < 0)
  179.                                         n_shift = 0;
  180.                                
  181.                                 leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
  182.                                                 snum[i], n_shift, S_new[i]);
  183.                                
  184.                                 /* Calculate number of bytes which must remain
  185.                                  * in body after append to S_new[i] */
  186.                                 n_rem = tb->insert_size[0] - sbytes[i];
  187.                                 if (n_rem < 0)
  188.                                         n_rem = 0;
  189.                                 /* Append part of body into S_new[0] */
  190.                                 bi.tb = tb;
  191.                                 bi.bi_bh = S_new[i];
  192.                                 bi.bi_parent = NULL;
  193.                                 bi.bi_position = 0;
  194.                                
  195.                                 if (n_rem > zeros_num) {
  196.                                         r_zeros_number = 0;
  197.                                         r_body = body + n_rem - zeros_num;
  198.                                 } else {
  199.                                         r_body = body;
  200.                                         r_zeros_number = zeros_num - n_rem;
  201.                                         zeros_num -= r_zeros_number;
  202.                                 }
  203.                                 leaf_paste_in_buffer(&bi, 0, n_shift,
  204.                                                      tb->insert_size[0] - n_rem,
  205.                                                      r_body, r_zeros_number);
  206.                                 {
  207.                                         /* 2008-2-16 14:19
  208.                                          * itis not easy to format,
  209.                                          * needless to say to debug HR.
  210.                                          */
  211.                                         struct item_head *tmp;
  212.                                        
  213.                                         tmp = B_N_PITEM_HEAD(S_new[i], 0);
  214.                                         if (is_indirect_le_ih(tmp)) {
  215.                                                 set_ih_free_space(tmp, 0);
  216.                                                
  217.                                                 set_le_ih_k_offset(tmp,
  218.                                                     le_ih_k_offset(tmp) +
  219.                                                         (n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT)));
  220.                                         } else {
  221.                                                 set_le_ih_k_offset(tmp,
  222.                                                     le_ih_k_offset(tmp) + n_rem);
  223.                                         }
  224.                                 }
  225.                                 tb->insert_size[0] = n_rem;
  226.                                 if (!n_rem)
  227.                                         pos_in_item++;
  228.                         }
  229.                 } else { /* item falls wholly into S_new[i] */
  230.                         int ret_val;
  231.                         struct item_head *pasted;
  232. #ifdef CONFIG_REISERFS_CHECK
  233.                         struct item_head *ih = B_N_PITEM_HEAD(tbS0, item_pos);
  234.                        
  235.                         if (!is_direntry_le_ih(ih) &&
  236.                             (pos_in_item != ih_item_len(ih)
  237.                              || tb->insert_size[0] <= 0))
  238.                                 reiserfs_panic(tb->tb_sb,
  239.                                                "PAP-12235: balance_leaf: pos_in_item must be equal to ih_item_len");
  240. #endif        /* CONFIG_REISERFS_CHECK */
  241.                         ret_val = leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
  242.                                                  snum[i], sbytes[i], S_new[i]);
  243.                         RFALSE(ret_val,
  244.                                "PAP-12240: unexpected value returned by leaf_move_items (%d)",
  245.                                ret_val);
  246.                         /* paste into item */
  247.                         bi.tb = tb;
  248.                         bi.bi_bh = S_new[i];
  249.                         bi.bi_parent = NULL;
  250.                         bi.bi_position = 0;
  251.                        
  252.                         leaf_paste_in_buffer(&bi, item_pos - n + snum[i],
  253.                                              pos_in_item,
  254.                                              tb->insert_size[0],
  255.                                              body, zeros_num);
  256.                        
  257.                         pasted = B_N_PITEM_HEAD(S_new[i], item_pos - n + snum[i]);
  258.                         if (is_direntry_le_ih(pasted))
  259.                                 leaf_paste_entries(bi.bi_bh,
  260.                                                    item_pos - n + snum[i],
  261.                                                    pos_in_item, 1,
  262.                                                    (struct reiserfs_de_head *)body,
  263.                                                    body + DEH_SIZE,
  264.                                                    tb->insert_size[0]);
  265.                         /* if we paste to indirect item update ih_free_space */
  266.                         if (is_indirect_le_ih(pasted))
  267.                                 set_ih_free_space(pasted, 0);
  268.                         zeros_num = tb->insert_size[0] = 0;
  269.                 }
  270.                 goto next;
  271.        
  272.         next:
  273.                 memcpy(insert_key + i, B_N_PKEY(S_new[i], 0), KEY_SIZE);
  274.                 insert_ptr[i] = S_new[i];

  275.                 RFALSE(!buffer_journaled(S_new[i])
  276.                        || buffer_journal_dirty(S_new[i])
  277.                        || buffer_dirty(S_new[i]),
  278.                        "PAP-12247: S_new[%d] : (%b)", i, S_new[i]);
  279.         } /* for loop */
  280. }
复制代码

论坛徽章:
0
97 [报告]
发表于 2008-02-16 14:57 |只看该作者

  1. static void balance_leaf_shift_right(struct tree_balance *tb,
  2.                                    struct item_head *ih,
  3.                                    const char *body,
  4.                                    int flag,
  5.                                    struct item_head *insert_key,
  6.                                    struct buffer_head **insert_ptr)
  7. {
  8.         struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
  9.         /* index of the affected item */
  10.         int item_pos = PATH_LAST_POSITION(tb->tb_path);
  11.        
  12.         struct buffer_info bi;

  13.         int n, ret_val;
  14.         int pos_in_item;
  15.         int zeros_num;
  16.        
  17.         if (!(tb->rnum[0] > 0)) /* right shift not needed */
  18.                 return;
  19.        
  20.         zeros_num = 0;
  21.         if (flag == M_INSERT && body == 0)
  22.                 zeros_num = ih_item_len(ih);

  23.         pos_in_item = tb->tb_path->pos_in_item;
  24.         /* for indirect item pos_in_item is measured in unformatted node
  25.          * pointers. Recalculate to bytes
  26.          */
  27.         if (flag != M_INSERT &&
  28.             is_indirect_le_ih(B_N_PITEM_HEAD(tbS0, item_pos)))
  29.                 pos_in_item *= UNFM_P_SIZE;

  30.         n = B_NR_ITEMS(tbS0);
  31.        
  32.         if (flag == M_INSERT) {
  33.                 if (!(n - tb->rnum[0] < item_pos)) {
  34.                         /* new item or part of it doesn't fall into R[0] */
  35.                         leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
  36.                         return;
  37.                 }
  38.                 if (!(item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1)) {
  39.                         /* whole new item falls into R[0] */

  40.                         /* Shift rnum[0]-1 items to R[0] */
  41.                         ret_val = leaf_shift_right(tb, tb->rnum[0] -1, tb->rbytes);
  42.                        
  43.                         /* Insert new item into R[0] */
  44.                         bi.tb = tb;
  45.                         bi.bi_bh = tb->R[0];
  46.                         bi.bi_parent = tb->FR[0];
  47.                         bi.bi_position = get_right_neighbor_position(tb, 0);
  48.                        
  49.                         leaf_insert_into_buf(&bi, item_pos - n + tb->rnum[0] - 1,
  50.                                              ih, body, zeros_num);
  51.                         if (item_pos - n + tb->rnum[0] - 1 == 0) {
  52.                                 replace_key(tb, tb->CFR[0], tb->rkey[0],
  53.                                             tb->R[0], 0);
  54.                         }
  55.                         zeros_num = tb->insert_size[0] = 0;
  56.                 } else {
  57.                         loff_t old_key_comp, old_len, r_zeros_number;
  58.                         const char *r_body;
  59.                         int version;
  60.                         loff_t offset;
  61.                        
  62.                         leaf_shift_right(tb, tb->rnum[0] -1, -1);
  63.                        
  64.                         version = ih_version(ih);
  65.                         /* Remember key component and item length */
  66.                         old_key_comp = le_ih_k_offset(ih);
  67.                         old_len = ih_item_len(ih);
  68.                        
  69.                         /* Calculate key component and item length to insert into R[0] */
  70.                         offset = le_ih_k_offset(ih) +
  71.                                  ((old_len - tb->rbytes) << (is_indirect_le_ih(ih) ?
  72.                                   tb->tb_sb-> s_blocksize_bits - UNFM_P_SHIFT : 0));
  73.                         set_le_ih_k_offset(ih, offset);
  74.                         put_ih_item_len(ih, tb->rbytes);
  75.                        
  76.                         /* Insert part of the item into R[0] */
  77.                         bi.tb = tb;
  78.                         bi.bi_bh = tb->R[0];
  79.                         bi.bi_parent = tb->FR[0];
  80.                         bi.bi_position = get_right_neighbor_position(tb, 0);
  81.                        
  82.                         if ((old_len - tb->rbytes) > zeros_num) {
  83.                                 r_zeros_number = 0;
  84.                                 r_body = body + (old_len - tb->rbytes) - zeros_num;
  85.                         } else {
  86.                                 r_body = body;
  87.                                 r_zeros_number = zeros_num - (old_len - tb->rbytes);
  88.                                 zeros_num -= r_zeros_number;
  89.                         }
  90.                         leaf_insert_into_buf(&bi, 0, ih, r_body, r_zeros_number);
  91.                        
  92.                         /* Replace right delimiting key by first key in R[0] */
  93.                         replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
  94.                        
  95.                         /* Calculate key component and item length to insert into S[0] */
  96.                         set_le_ih_k_offset(ih, old_key_comp);
  97.                         put_ih_item_len(ih, old_len - tb->rbytes);
  98.                        
  99.                         tb->insert_size[0] -= tb->rbytes;
  100.                 }
  101.         }
  102.         else if (flag == M_PASTE) {
  103.                 if (!(n - tb->rnum[0] <= item_pos)) {
  104.                         /* new item doesn't fall into R[0] */
  105.                         leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
  106.                 }
  107.                 else if (!(item_pos == n - tb->rnum[0] && tb->rbytes != -1)) {
  108.                         /* pasted item in whole falls into R[0] */
  109.                         struct item_head *pasted;
  110.                        
  111.                         ret_val = leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
  112.                        
  113.                         /* append item in R[0] */
  114.                         /* if (pos_in_item >= 0) */ {
  115.                                 bi.tb = tb;
  116.                                 bi.bi_bh = tb->R[0];
  117.                                 bi.bi_parent = tb->FR[0];
  118.                                 bi.bi_position = get_right_neighbor_position(tb, 0);
  119.                                
  120.                                 leaf_paste_in_buffer(&bi, item_pos - n + tb->rnum[0],
  121.                                                      pos_in_item, tb->insert_size[0],
  122.                                                      body, zeros_num);
  123.                         }
  124.                         /* paste new entry, if item is directory item */
  125.                         pasted = B_N_PITEM_HEAD(tb->R[0], item_pos - n + tb->rnum[0]);
  126.                        
  127.                         if (is_direntry_le_ih(pasted) && pos_in_item >= 0) {
  128.                                 leaf_paste_entries(bi.bi_bh, item_pos - n + tb->rnum[0],
  129.                                                    pos_in_item, 1,
  130.                                                    (struct reiserfs_de_head *)body,
  131.                                                    body + DEH_SIZE,
  132.                                                    tb->insert_size[0]);
  133.                                 if (!pos_in_item) {
  134.                                         RFALSE(item_pos - n + tb->rnum[0],
  135.                                                "PAP-12165: directory item must be first item of node when pasting is in 0th position");
  136.                                         /* update delimiting keys */
  137.                                         replace_key(tb, tb->CFR[0], tb->rkey[0],
  138.                                                     tb->R[0], 0);
  139.                                 }
  140.                         }

  141.                         if (is_indirect_le_ih(pasted))
  142.                                 set_ih_free_space(pasted, 0);
  143.                        
  144.                         zeros_num = tb->insert_size[0] = 0;
  145.                 }
  146.                 else if (is_direntry_le_ih(B_N_PITEM_HEAD(tbS0, item_pos))) {
  147.                         /* we append to directory item */
  148.                         int entry_count;

  149.                         RFALSE(zeros_num,
  150.                                "PAP-12145: invalid parameter in case of a directory");
  151.                        
  152.                         entry_count = I_ENTRY_COUNT(B_N_PITEM_HEAD(tbS0, item_pos));
  153.                         if (entry_count - tb->rbytes < pos_in_item) {
  154.                                 /* new directory entry falls into R[0] */
  155.                                 int paste_entry_position;
  156.                                
  157.                                 RFALSE(tb->rbytes - 1 >= entry_count ||
  158.                                         !tb->insert_size[0],
  159.                                        "PAP-12150: no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d",
  160.                                        tb->rbytes, entry_count);
  161.                                
  162.                                 /* Shift rnum[0] items in whole.
  163.                                  * Shift rbytes-1 directory entries from directory item number rnum[0] */
  164.                                 leaf_shift_right(tb, tb->rnum[0], tb->rbytes -1);
  165.                                
  166.                                 /* Paste given directory entry to directory item */
  167.                                 paste_entry_position = pos_in_item - entry_count +
  168.                                                         tb->rbytes - 1;
  169.                                 bi.tb = tb;
  170.                                 bi.bi_bh = tb->R[0];
  171.                                 bi.bi_parent = tb->FR[0];
  172.                                 bi.bi_position = get_right_neighbor_position(tb, 0);
  173.                                
  174.                                 leaf_paste_in_buffer(&bi, 0, paste_entry_position,
  175.                                                      tb->insert_size[0],
  176.                                                      body, zeros_num);
  177.                                 /* paste entry */
  178.                                 leaf_paste_entries(bi.bi_bh, 0,
  179.                                                    paste_entry_position, 1,
  180.                                                    (struct reiserfs_de_head *) body,
  181.                                                    body + DEH_SIZE,
  182.                                                    tb->insert_size[0]);
  183.                                 if (paste_entry_position == 0) {
  184.                                         /* change delimiting keys */
  185.                                         replace_key(tb, tb->CFR[0], tb->rkey[0],
  186.                                                     tb->R[0], 0);
  187.                                 }
  188.                                
  189.                                 tb->insert_size[0] = 0;
  190.                                 pos_in_item++;
  191.                        
  192.                         } else { /* new directory entry doesn't fall into R[0] */
  193.                                 leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
  194.                         }
  195.                
  196.                 } else { /* regular object */
  197.                         int n_shift, n_rem, r_zeros_number;
  198.                         const char *r_body;
  199.                        
  200.                         /* Calculate number of bytes which must be
  201.                          * shifted from appended item */
  202.                         n_shift = tb->rbytes - tb->insert_size[0];
  203.                         if (n_shift < 0)
  204.                                 n_shift = 0;
  205.                        
  206.                         RFALSE(pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)),
  207.                                "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
  208.                                pos_in_item, ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)));
  209.                        
  210.                         leaf_shift_right(tb, tb->rnum[0], n_shift);
  211.                        
  212.                         /* Calculate number of bytes which must remain in body
  213.                          * after appending to R[0] */
  214.                         n_rem = tb->insert_size[0] - tb->rbytes;
  215.                         if (n_rem < 0)
  216.                                 n_rem = 0;
  217.                        
  218.                         {
  219.                                 int version;
  220.                                 unsigned long temp_rem = n_rem;
  221.                                
  222.                                 version = ih_version(B_N_PITEM_HEAD(tb->R[0], 0));
  223.                                 if (is_indirect_le_key(version, B_N_PKEY(tb->R[0], 0)))
  224.                                         temp_rem = n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT);
  225.                                
  226.                                 set_le_key_k_offset(version, B_N_PKEY(tb->R[0], 0),
  227.                                     le_key_k_offset(version, B_N_PKEY(tb->R[0], 0)) + temp_rem);
  228.                                
  229.                                 set_le_key_k_offset(version, B_N_PDELIM_KEY(tb->CFR[0], tb->rkey[0]),
  230.                                     le_key_k_offset(version, B_N_PDELIM_KEY(tb->CFR[0], tb->rkey[0])) + temp_rem);
  231.                         }
  232.                         /*
  233.                          k_offset (B_N_PKEY(tb->R[0],0)) += n_rem;
  234.                            k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;
  235.                           */
  236.                         do_balance_mark_internal_dirty(tb, tb->CFR[0], 0);

  237.                         /* Append part of body into R[0] */
  238.                         bi.tb = tb;
  239.                         bi.bi_bh = tb->R[0];
  240.                         bi.bi_parent = tb->FR[0];
  241.                         bi.bi_position = get_right_neighbor_position(tb, 0);
  242.                        
  243.                         if (n_rem > zeros_num) {
  244.                                 r_zeros_number = 0;
  245.                                 r_body = body + n_rem - zeros_num;
  246.                         } else {
  247.                                 r_body = body;
  248.                                 r_zeros_number = zeros_num - n_rem;
  249.                                 zeros_num -= r_zeros_number;
  250.                         }
  251.                        
  252.                         leaf_paste_in_buffer(&bi, 0, n_shift,
  253.                                              tb->insert_size[0] - n_rem,
  254.                                              r_body, r_zeros_number);
  255.                        
  256.                         if (is_indirect_le_ih(B_N_PITEM_HEAD(tb->R[0], 0))) {
  257.                 #if 0
  258.                                 RFALSE(n_rem, "PAP-12160: paste more than one unformatted node pointer");
  259.                 #endif
  260.                                 set_ih_free_space(B_N_PITEM_HEAD(tb->R[0], 0), 0);
  261.                         }
  262.                        
  263.                         tb->insert_size[0] = n_rem;
  264.                         if (!n_rem)
  265.                                 pos_in_item++;
  266.                 }
  267.         }
  268.         else {
  269.                 reiserfs_panic(tb->tb_sb,
  270.                        "PAP-12175: balance_leaf: rnum > 0: unexpectable mode: %s(%d)",
  271.                        (flag == M_DELETE) ? "DELETE" :
  272.                        ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
  273.         }
  274. }
复制代码

论坛徽章:
0
98 [报告]
发表于 2008-02-16 14:58 |只看该作者

  1. /*
  2. * @ih,           item header of inserted item, this is on little endian
  3. * @body,  body of inserted item or bytes to paste
  4. * @flag,  i - insert, d - delete, c - cut, p - paste, see comment to do_balance
  5. * @insert_key,         in our processing of one level,
  6. *                 we sometimes determine what must be inserted into the next higher level.
  7. *                 This insertion consists of a key or two keys and
  8. *                 their corresponding pointers.
  9. * @insert_ptr,         inserted node-ptrs for the next level
  10. */
  11. static void balance_leaf_shift_left(struct tree_balance *tb,
  12.                                    struct item_head *ih,
  13.                                    const char *body,
  14.                                    int flag,
  15.                                    struct item_head *insert_key,
  16.                                    struct buffer_head **insert_ptr)
  17. {
  18.         struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
  19.         /*  index of the affected item */
  20.         int item_pos = PATH_LAST_POSITION(tb->tb_path);
  21.        
  22.         struct buffer_info bi;

  23.         int ret_val;
  24.         int pos_in_item;
  25.         int zeros_num;
  26.        
  27.         if (!(tb->lnum[0] > 0)) /* left shift not needed */
  28.                 return;
  29.        
  30.         zeros_num = 0;
  31.         if (flag == M_INSERT && body == 0)
  32.                 zeros_num = ih_item_len(ih);

  33.         pos_in_item = tb->tb_path->pos_in_item;
  34.         /* for indirect item pos_in_item is measured in unformatted node
  35.          * pointers. Recalculate to bytes
  36.          */
  37.         if (flag != M_INSERT &&
  38.             is_indirect_le_ih(B_N_PITEM_HEAD(tbS0, item_pos)))
  39.                 pos_in_item *= UNFM_P_SIZE;
  40.         /*
  41.          * lets compare the affted item with lnum[h] computed in fix_node.
  42.          *
  43.          * left shift, defed by Hans, as to
  44.          * move lnum[h] items starting at I-0 in S to L
  45.          */
  46.         if (!(item_pos < tb->lnum[0])) {
  47.                 /* new item doesn't fall into L[0] */
  48.                 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
  49.                 return;
  50.         }

  51.         n = B_NR_ITEMS(tb->L[0]);

  52.         if (flag == M_INSERT) {
  53.                 if (item_pos == tb->lnum[0] -1 && tb->lbytes != -1) {
  54.                         /* part of new item falls into L[0] */
  55.                         int new_item_len;
  56.                         int version;
  57.                        
  58.                         /* shift lnum[0]-1 items entirely */
  59.                         ret_val = leaf_shift_left(tb, tb->lnum[0] -1, -1);
  60.                        
  61.                         /* Calculate item length to insert to S[0] */
  62.                         new_item_len = ih_item_len(ih) - tb->lbytes;
  63.                        
  64.                         /* Calculate and check item length to insert to L[0] */
  65.                         put_ih_item_len(ih, tb->lbytes /*ih_item_len(ih) - new_item_len*/);
  66.                         RFALSE(tb->lbytes <= 0,
  67.                                 "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d",
  68.                                 ih_item_len(ih));

  69.                         /* Insert new item into L[0] */
  70.                         bi.tb = tb;
  71.                         bi.bi_bh = tb->L[0];
  72.                         bi.bi_parent = tb->FL[0];
  73.                         bi.bi_position = get_left_neighbor_position(tb, 0);
  74.                        
  75.                         leaf_insert_into_buf(&bi, n + item_pos - ret_val,
  76.                                                 ih, body,
  77.                                                 zeros_num > ih_item_len(ih) ?
  78.                                                 ih_item_len(ih) : zeros_num);
  79.                        
  80.                         version = ih_version(ih);
  81.                         /* Calculate key component,
  82.                          * item length and body to insert into S[0]
  83.                          */
  84.                         set_le_ih_k_offset(ih,
  85.                             le_ih_k_offset(ih) +
  86.                             (tb->lbytes << (is_indirect_le_ih(ih) ?
  87.                                 tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT : 0)));

  88.                         put_ih_item_len(ih, new_item_len);
  89.                        
  90.                         if (tb->lbytes > zeros_num) {
  91.                                 body += (tb->lbytes - zeros_num);
  92.                                 zeros_num = 0;
  93.                         } else
  94.                                 zeros_num -= tb->lbytes;

  95.                         RFALSE(ih_item_len(ih) <= 0,
  96.                                "PAP-12085: there is nothing to insert into S[0]: ih_item_len=%d",
  97.                                ih_item_len(ih));
  98.                 } else {
  99.                         /* new item in whole falls into L[0] */
  100.                        
  101.                         /* Shift lnum[0]-1 items to L[0] */
  102.                         ret_val = leaf_shift_left(tb, tb->lnum[0] -1, tb->lbytes);
  103.                        
  104.                         /* Insert new item into L[0] */
  105.                         bi.tb = tb;
  106.                         bi.bi_bh = tb->L[0];
  107.                         bi.bi_parent = tb->FL[0];
  108.                         bi.bi_position = get_left_neighbor_position(tb, 0);
  109.                        
  110.                         leaf_insert_into_buf(&bi, n + item_pos - ret_val,
  111.                                                 ih, body, zeros_num);
  112.                         tb->insert_size[0] = 0;
  113.                         zeros_num = 0;
  114.                 }
  115.         }
  116.         else if (flag == M_PASTE) {
  117.                 if (!(item_pos == tb->lnum[0] -1 && tb->lbytes != -1)) {
  118.                         /* appended item will be in L[0] in whole */
  119.                         struct item_head *pasted;

  120.                         if (!item_pos &&
  121.                             op_is_left_mergeable(B_N_PKEY(tbS0, 0), tbS0->b_size)) {
  122.                                     /* if we paste into first item of S[0], and
  123.                                      * it is left mergable,
  124.                                      * then increment pos_in_item by the size of
  125.                                      * the last item in L[0]
  126.                                      */
  127.                                 pasted = B_N_PITEM_HEAD(tb->L[0], n -1);
  128.                                
  129.                                 if (is_direntry_le_ih(pasted))
  130.                                         pos_in_item += ih_entry_count(pasted);
  131.                                 else
  132.                                         pos_in_item += ih_item_len(pasted);
  133.                         }
  134.                         /* Shift lnum[0] in whole */
  135.                         ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
  136.                        
  137.                         /* Append to body of item in L[0] */
  138.                         bi.tb = tb;
  139.                         bi.bi_bh = tb->L[0];
  140.                         bi.bi_parent = tb->FL[0];
  141.                         bi.bi_position = get_left_neighbor_position(tb, 0);
  142.                        
  143.                         leaf_paste_in_buffer(&bi, n + item_pos - ret_val,
  144.                                         pos_in_item, tb->insert_size[0],
  145.                                         body, zeros_num);
  146.                        
  147.                         /* if appended item is directory, paste entry */
  148.                         pasted = B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val);
  149.                         if (is_direntry_le_ih(pasted))
  150.                                 leaf_paste_entries(bi.bi_bh, n + item_pos - ret_val,
  151.                                                 pos_in_item, 1,
  152.                                                 (struct reiserfs_de_head *)body,
  153.                                                 body + DEH_SIZE,
  154.                                                 tb->insert_size[0]);
  155.                         /* if appended item is indirect item,
  156.                          * put unformatted node into un list
  157.                          */
  158.                         if (is_indirect_le_ih(pasted))
  159.                                 set_ih_free_space(pasted, 0);
  160.                        
  161.                         tb->insert_size[0] = 0;
  162.                         zeros_num = 0;
  163.                         return;
  164.                 }
  165.                 /* we must shift the part of the appended item */
  166.                 if (is_direntry_le_ih(B_N_PITEM_HEAD(tbS0, item_pos))) {
  167.                         /* case of directory item */
  168.                         RFALSE(zeros_num,
  169.                                "PAP-12090: invalid parameter in case of a directory");
  170.                        
  171.                         if (tb->lbytes > pos_in_item) {
  172.                                 /* new directory entry falls into L[0] */
  173.                                 struct item_head *pasted;
  174.                                 int l_pos_in_item = pos_in_item;
  175.                                
  176.                                 /* Shift lnum[0] items in whole.
  177.                                  * Shift lbytes - 1 entries from given directory item
  178.                                  */
  179.                                 ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes -1);
  180.                                 if (ret_val && !item_pos) {
  181.                                         pasted = B_N_PITEM_HEAD(tb->L[0], B_NR_ITEMS(tb->L[0]) -1);
  182.                                         l_pos_in_item += I_ENTRY_COUNT(pasted) - (tb->lbytes -1);
  183.                                 }
  184.                                 /* Append given directory entry to directory item */
  185.                                 bi.tb = tb;
  186.                                 bi.bi_bh = tb->L[0];
  187.                                 bi.bi_parent = tb->FL[0];
  188.                                 bi.bi_position = get_left_neighbor_position(tb, 0);
  189.                                
  190.                                 leaf_paste_in_buffer(&bi, n + item_pos - ret_val,
  191.                                                         l_pos_in_item,
  192.                                                         tb->insert_size[0],
  193.                                                         body, zeros_num);
  194.                                
  195.                                 /* previous string prepared space for pasting new entry,
  196.                                  * following string pastes this entry */
  197.                                 /* when we have merge directory item,
  198.                                  * pos_in_item has been changed too */
  199.                                 /* paste new directory entry. 1 is entry number */
  200.                                 leaf_paste_entries(bi.bi_bh, n + item_pos - ret_val,
  201.                                                    l_pos_in_item, 1,
  202.                                                    (struct reiserfs_de_head *) body,
  203.                                                    body + DEH_SIZE,
  204.                                                    tb->insert_size[0]);
  205.                                 tb->insert_size[0] = 0;
  206.                         } else {
  207.                                 /* new directory item doesn't fall into L[0] */
  208.                                 /* Shift lnum[0]-1 items in whole.
  209.                                  * Shift lbytes directory entries from directory item number lnum[0] */
  210.                                 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
  211.                         }
  212.                        
  213.                         /* Calculate new position to append in item body */
  214.                         pos_in_item -= tb->lbytes;
  215.                
  216.                 } else { /* regular object */
  217.                         RFALSE(tb->lbytes <= 0,
  218.                                "PAP-12095: there is nothing to shift to L[0]. lbytes=%d",
  219.                                tb->lbytes);
  220.                        
  221.                         RFALSE(pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)),
  222.                                "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d",
  223.                                ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)), pos_in_item);
  224.                        
  225.                         if (tb->lbytes >= pos_in_item) {
  226.                                 /* appended item will be in L[0] in whole */
  227.                                 /* this bytes number must be appended to
  228.                                  * the last item of L[h] */
  229.                                 int l_n = tb->lbytes - pos_in_item;
  230.                                
  231.                                 /* Calculate new insert_size[0] */
  232.                                 tb->insert_size[0] -= l_n;

  233.                                 RFALSE(tb->insert_size[0] <= 0,
  234.                                       "PAP-12105: there is nothing to paste into L[0]. insert_size=%d",
  235.                                        tb->insert_size[0]);
  236.                                
  237.                                 ret_val = leaf_shift_left(tb, tb->lnum[0],
  238.                                                ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)));
  239.                                 /* Append to body of item in L[0] */
  240.                                 bi.tb = tb;
  241.                                 bi.bi_bh = tb->L[0];
  242.                                 bi.bi_parent = tb->FL[0];
  243.                                 bi.bi_position = get_left_neighbor_position(tb, 0);
  244.                                
  245.                                 leaf_paste_in_buffer(&bi, n + item_pos - ret_val,
  246.                                             ih_item_len(B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val)),
  247.                                             l_n, body, zeros_num > l_n ? l_n : zeros_num);
  248.                                
  249.                                 /* 0-th item in S0 can be only of DIRECT type when l_n != 0 */
  250.                                 {
  251.                                         int version;
  252.                                         int temp_l = l_n;
  253.                                        
  254.                                         RFALSE(ih_item_len(B_N_PITEM_HEAD(tbS0, 0)),
  255.                                                 "PAP-12106: item length must be 0");
  256.                                         RFALSE(comp_short_le_keys(B_N_PKEY(tbS0, 0),
  257.                                                                   B_N_PKEY(tb->L[0], n + item_pos - ret_val)),
  258.                                                 "PAP-12107: items must be of the same file");
  259.                                        
  260.                                         if (is_indirect_le_ih(B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val)))
  261.                                                 temp_l = l_n << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT);
  262.                                        
  263.                                         /* update key of first item in S0 */
  264.                                         version = ih_version(B_N_PITEM_HEAD(tbS0, 0));
  265.                                         set_le_key_k_offset(version, B_N_PKEY(tbS0, 0),
  266.                                             le_key_k_offset(version, B_N_PKEY(tbS0, 0)) + temp_l);
  267.                                         /* update left delimiting key */
  268.                                         set_le_key_k_offset(version,
  269.                                             B_N_PDELIM_KEY(tb->CFL[0], tb->lkey[0]),
  270.                                             le_key_k_offset(version,
  271.                                               B_N_PDELIM_KEY(tb->CFL[0], tb->lkey[0])) + temp_l);
  272.                                 }
  273.                                 /* Calculate new body, position in item and insert_size[0] */
  274.                                 if (l_n > zeros_num) {
  275.                                         body += (l_n - zeros_num);
  276.                                         zeros_num = 0;
  277.                                 } else
  278.                                         zeros_num -= l_n;
  279.                                 pos_in_item = 0;
  280.                                
  281.                                 RFALSE(comp_short_le_keys(B_N_PKEY(tbS0, 0),
  282.                                                           B_N_PKEY(tb->L[0], B_NR_ITEMS(tb->L[0]) - 1))
  283.                                         || !op_is_left_mergeable(B_N_PKEY(tbS0, 0), tbS0->b_size)
  284.                                         || !op_is_left_mergeable(B_N_PDELIM_KEY(tb->CFL[0], tb->lkey[0]), tbS0->b_size),
  285.                                         "PAP-12120: item must be merge-able with left neighboring item");
  286.                        
  287.                         } else { /* only part of the appended item will be in L[0] */
  288.                                 /* Calculate position in item for append in S[0] */
  289.                                 pos_in_item -= tb->lbytes;

  290.                                 RFALSE(pos_in_item <= 0,
  291.                                        "PAP-12125: no place for paste. pos_in_item=%d",
  292.                                        pos_in_item);
  293.                                
  294.                                 /* Shift lnum[0] items in whole.
  295.                                  * Shift lbytes byte from item number lnum[0] */
  296.                                 leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
  297.                         }
  298.                 }
  299.         } else {
  300.                 reiserfs_panic(tb->tb_sb,
  301.                        "PAP-12130: balance_leaf: lnum > 0: unexpectable mode: %s(%d)",
  302.                        (flag == M_DELETE) ? "DELETE" :
  303.                        ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
  304.         }
  305. }
复制代码

论坛徽章:
0
99 [报告]
发表于 2008-02-17 03:22 |只看该作者
linux-2.6.24/fs/dcache.c

int
block_page_mkwrite(struct vm_area_struct *vma, struct page *page,
                   get_block_t get_block)
{
        struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
        unsigned long end;
        loff_t size;
        int ret = -EINVAL;

        lock_page(page);
        size = i_size_read(inode);
        if ((page->mapping != inode->i_mapping) ||
            (page_offset(page) > size)) {
                /* page got truncated out from underneath us */
                goto out_unlock;
        }

        /* page is wholly or partially inside EOF */
        if (((page->index + 1) << PAGE_CACHE_SHIFT) > size)
                end = size & ~PAGE_CACHE_MASK;
        else
                end = PAGE_CACHE_SIZE;

        ret = block_prepare_write(page, 0, end, get_block);
        if (!ret)
                ret = block_commit_write(page, 0, end);

out_unlock:
        unlock_page(page);
        return ret;
}

论坛徽章:
0
100 [报告]
发表于 2008-02-17 11:02 |只看该作者
u do disk cache, i do get block, hehe

  1. static void balance_leaf_do_remain(struct tree_balance *tb,
  2.                                 struct item_head *ih,
  3.                                 const char *body,
  4.                                 int flag,
  5.                                 int *p_pos_in_item,
  6.                                 int *p_item_pos,
  7.                                 int *p_zeros_num)
  8. {
  9.         struct buffer_info bi;
  10.         int zeros_num, item_pos, pos_in_item;

  11.         struct item_head *pasted;
  12.         struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
  13.        
  14.         if (!(flag == M_INSERT || flag == M_PASTE) {
  15.                 reiserfs_panic(tb->tb_sb,
  16.                         "JZ-0001: balance_leaf:unexpectable mode: %s(%d)",
  17.                         (flag == M_DELETE) ? "DELETE" :
  18.                         ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
  19.                 return;
  20.         }

  21.         zeros_num = *p_zeros_num;
  22.         item_pos = *p_item_pos;
  23.         pos_in_item = *p_pos_in_item;
  24.        
  25.         if (flag == M_INSERT) {
  26.                 bi.tb = tb;
  27.                 bi.bi_bh = tbS0;
  28.                 bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
  29.                 bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
  30.                 /*
  31.                  * zeros_num maybe chged in shifting
  32.                  */
  33.                 leaf_insert_into_buf(&bi, item_pos, ih, body, zeros_num);
  34.                 /* If we insert the first key change the delimiting key */
  35.                 if (item_pos == 0) {
  36.                         if (tb->CFL[0])        /* can be 0 in reiserfsck */
  37.                                 replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0, 0);
  38.                 }
  39.                 goto out;
  40.         }

  41.         pasted = B_N_PITEM_HEAD(tbS0, item_pos);
  42.         /* when directory, may be new entry already pasted */
  43.         if (is_direntry_le_ih(pasted)) {
  44.                 if (0<= pos_in_item && pos_in_item <= ih_entry_count(pasted)) {
  45.                         RFALSE(!tb->insert_size[0],
  46.                                "PAP-12260: insert_size is 0 already");
  47.                         /* prepare space */
  48.                         bi.tb = tb;
  49.                         bi.bi_bh = tbS0;
  50.                         bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
  51.                         bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
  52.                        
  53.                         leaf_paste_in_buffer(&bi, item_pos, pos_in_item,
  54.                                              tb->insert_size[0],
  55.                                              body, zeros_num);
  56.                         /* paste entry */
  57.                         leaf_paste_entries(bi.bi_bh, item_pos, pos_in_item, 1,
  58.                                            (struct reiserfs_de_head *)body,
  59.                                            body + DEH_SIZE,
  60.                                            tb->insert_size[0]);
  61.                        
  62.                         if (!item_pos && !pos_in_item) {
  63.                                 RFALSE(!tb->CFL[0] || !tb->L[0],
  64.                                        "PAP-12270: CFL[0]/L[0] must be specified");
  65.                                 if (tb->CFL[0])
  66.                                         replace_key(tb, tb->CFL[0], tb->lkey[0],
  67.                                                     tbS0, 0);
  68.                         }
  69.                         tb->insert_size[0] = 0;
  70.                 }
  71.         } else { /* regular object */
  72.                 if (pos_in_item == ih_item_len(pasted)) {
  73.                         RFALSE(tb->insert_size[0] <= 0,
  74.                                "PAP-12275: insert size must not be %d",
  75.                                tb->insert_size[0]);
  76.                         bi.tb = tb;
  77.                         bi.bi_bh = tbS0;
  78.                         bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
  79.                         bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
  80.                        
  81.                         leaf_paste_in_buffer(&bi, item_pos, pos_in_item,
  82.                                              tb->insert_size[0],
  83.                                              body, zeros_num);
  84.                        
  85.                         if (is_indirect_le_ih(pasted)) {
  86.                 #if 0
  87.                                 RFALSE(tb->insert_size[0] != UNFM_P_SIZE,
  88.                                        "PAP-12280: insert_size for indirect item must be %d, not %d",
  89.                                        UNFM_P_SIZE, tb->insert_size[0]);
  90.                 #endif
  91.                                 set_ih_free_space(pasted, 0);
  92.                         }
  93.                         tb->insert_size[0] = 0;
  94.                 }
  95. #ifdef CONFIG_REISERFS_CHECK
  96.                 else {
  97.                         if (tb->insert_size[0]) {
  98.                                 print_cur_tb("12285");
  99.                                 reiserfs_panic(tb->tb_sb,
  100.                                        "PAP-12285: balance_leaf: insert_size must be 0 (%d)",
  101.                                                tb->insert_size[0]);
  102.                         }
  103.                 }
  104. #endif
  105.         }
  106. out:
  107.         *p_item_pos = item_pos;
  108.         *p_pos_in_item = pos_in_item;
  109.         *p_zeros_num = zeros_num;
  110. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP