Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-extents-search-2.6.9-rhel4.patch
1 Index: linux-2.6.9-full/include/linux/ext3_extents.h
2 ===================================================================
3 --- linux-2.6.9-full.orig/include/linux/ext3_extents.h  2007-03-23 15:57:00.000000000 +0300
4 +++ linux-2.6.9-full/include/linux/ext3_extents.h       2007-03-26 22:08:16.000000000 +0400
5 @@ -242,6 +242,8 @@ struct ext3_extent_tree_stats {
6         int leaf_num;
7  };
8  
9 +extern int ext3_ext_search_left(struct ext3_extents_tree *, struct ext3_ext_path *, unsigned long *, unsigned long *);
10 +extern int ext3_ext_search_right(struct ext3_extents_tree *, struct ext3_ext_path *, unsigned long *, unsigned long *);
11  extern void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *);
12  extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *);
13  extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *);
14 Index: linux-2.6.9-full/fs/ext3/extents.c
15 ===================================================================
16 --- linux-2.6.9-full.orig/fs/ext3/extents.c     2007-03-23 15:57:00.000000000 +0300
17 +++ linux-2.6.9-full/fs/ext3/extents.c  2007-03-26 22:07:37.000000000 +0400
18 @@ -929,6 +929,150 @@ repeat:
19  }
20  
21  /*
22 + * search the closest allocated block to the left for *logical
23 + * and returns it at @logical + it's physical address at @phys
24 + * if *logical is the smallest allocated block, the function
25 + * returns 0 at @phys
26 + * return value contains 0 (success) or error code
27 + */
28 +int
29 +ext3_ext_search_left(struct ext3_extents_tree *tree, struct ext3_ext_path *path,
30 +                       unsigned long *logical, unsigned long *phys)
31 +{
32 +       struct ext3_extent_idx *ix;
33 +       struct ext3_extent *ex;
34 +       int depth;
35 +
36 +       BUG_ON(path == NULL);
37 +       depth = path->p_depth;
38 +       *phys = 0;
39 +
40 +       if (depth == 0 && path->p_ext == NULL)
41 +               return 0;
42 +
43 +       /* usually extent in the path covers blocks smaller
44 +        * then *logical, but it can be that extent is the
45 +        * first one in the file */
46 +
47 +       ex = path[depth].p_ext;
48 +       if (*logical < ex->ee_block) {
49 +               BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
50 +               while (--depth >= 0) {
51 +                       ix = path[depth].p_idx;
52 +                       BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
53 +               }
54 +               return 0;
55 +       }
56 +
57 +       BUG_ON(*logical < ex->ee_block + ex->ee_len);
58 +
59 +       *logical = ex->ee_block + ex->ee_len - 1;
60 +       *phys = ex->ee_start + ex->ee_len - 1;
61 +       return 0;
62 +}
63 +EXPORT_SYMBOL(ext3_ext_search_left);
64 +
65 +/*
66 + * search the closest allocated block to the right for *logical
67 + * and returns it at @logical + it's physical address at @phys
68 + * if *logical is the smallest allocated block, the function
69 + * returns 0 at @phys
70 + * return value contains 0 (success) or error code
71 + */
72 +int
73 +ext3_ext_search_right(struct ext3_extents_tree *tree, struct ext3_ext_path *path,
74 +                       unsigned long *logical, unsigned long *phys)
75 +{
76 +       struct buffer_head *bh = NULL;
77 +       struct ext3_extent_header *eh;
78 +       struct ext3_extent_idx *ix;
79 +       struct ext3_extent *ex;
80 +       unsigned long block;
81 +       int depth;
82 +
83 +       BUG_ON(path == NULL);
84 +       depth = path->p_depth;
85 +       *phys = 0;
86 +
87 +       if (depth == 0 && path->p_ext == NULL)
88 +               return 0;
89 +
90 +       /* usually extent in the path covers blocks smaller
91 +        * then *logical, but it can be that extent is the
92 +        * first one in the file */
93 +
94 +       ex = path[depth].p_ext;
95 +       if (*logical < ex->ee_block) {
96 +               BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
97 +               while (--depth >= 0) {
98 +                       ix = path[depth].p_idx;
99 +                       BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
100 +               }
101 +               *logical = ex->ee_block;
102 +               *phys = ex->ee_start;
103 +               return 0;
104 +       }
105 +
106 +       BUG_ON(*logical < ex->ee_block + ex->ee_len);
107 +
108 +       if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
109 +               /* next allocated block in this leaf */
110 +               ex++;
111 +               *logical = ex->ee_block;
112 +               *phys = ex->ee_start;
113 +               return 0;
114 +       }
115 +
116 +       /* go up and search for index to the right */
117 +       while (--depth >= 0) {
118 +               ix = path[depth].p_idx;
119 +               if (ix != EXT_LAST_INDEX(path[depth].p_hdr))
120 +                       break;
121 +       }
122 +
123 +       if (depth < 0) {
124 +               /* we've gone up to the root and
125 +                * found no index to the right */
126 +               return 0;
127 +       }
128 +
129 +       /* we've found index to the right, let's
130 +        * follow it and find the closest allocated
131 +        * block to the right */
132 +       ix++;
133 +       block = ix->ei_leaf;
134 +       while (++depth < path->p_depth) {
135 +               bh = sb_bread(tree->inode->i_sb, block);
136 +               if (bh == NULL)
137 +                       return -EIO;
138 +               eh = EXT_BLOCK_HDR(bh);
139 +               if (ext3_ext_check_header(eh)) {
140 +                       brelse(bh);
141 +                       return -EIO;
142 +               }
143 +               ix = EXT_FIRST_INDEX(eh);
144 +               block = ix->ei_leaf;
145 +               brelse(bh);
146 +       }
147 +
148 +       bh = sb_bread(tree->inode->i_sb, block);
149 +       if (bh == NULL)
150 +               return -EIO;
151 +       eh = EXT_BLOCK_HDR(bh);
152 +       if (ext3_ext_check_header(eh)) {
153 +               brelse(bh);
154 +               return -EIO;
155 +       }
156 +       ex = EXT_FIRST_EXTENT(eh);
157 +       *logical = ex->ee_block;
158 +       *phys = ex->ee_start;
159 +       brelse(bh);
160 +       return 0;
161 +
162 +}
163 +EXPORT_SYMBOL(ext3_ext_search_right);
164 +
165 +/*
166   * returns allocated block in subsequent extent or EXT_MAX_BLOCK
167   * NOTE: it consider block number from index entry as
168   * allocated block. thus, index entries have to be consistent