diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-01-30 08:31:50 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-01-30 08:31:50 -0500 |
commit | e13940ba56157a663944f2a827be96b6b787e260 (patch) | |
tree | 0bdc3669ed3cd3498b2dd73ed23003976d588c02 /fs/gfs2/dir.c | |
parent | 9b124fbb8ddb3d0b17f5a807414d85cbaf527a56 (diff) |
[GFS2] Make dir.c independant of jdata.c
Copy & rename various jdata functions into dir.c. The plan
being that directory metadata format will not change although
the journalled data format for "normal" files will change.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 264 |
1 files changed, 255 insertions, 9 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 93d3704ac58c..ada283a0f5f3 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -65,11 +65,11 @@ | |||
65 | #include "dir.h" | 65 | #include "dir.h" |
66 | #include "glock.h" | 66 | #include "glock.h" |
67 | #include "inode.h" | 67 | #include "inode.h" |
68 | #include "jdata.h" | ||
69 | #include "meta_io.h" | 68 | #include "meta_io.h" |
70 | #include "quota.h" | 69 | #include "quota.h" |
71 | #include "rgrp.h" | 70 | #include "rgrp.h" |
72 | #include "trans.h" | 71 | #include "trans.h" |
72 | #include "bmap.h" | ||
73 | 73 | ||
74 | #define IS_LEAF 1 /* Hashed (leaf) directory */ | 74 | #define IS_LEAF 1 /* Hashed (leaf) directory */ |
75 | #define IS_DINODE 2 /* Linear (stuffed dinode block) directory */ | 75 | #define IS_DINODE 2 /* Linear (stuffed dinode block) directory */ |
@@ -86,6 +86,252 @@ typedef int (*leaf_call_t) (struct gfs2_inode *dip, | |||
86 | uint32_t index, uint32_t len, uint64_t leaf_no, | 86 | uint32_t index, uint32_t len, uint64_t leaf_no, |
87 | void *data); | 87 | void *data); |
88 | 88 | ||
89 | static int gfs2_dir_get_buffer(struct gfs2_inode *ip, uint64_t block, int new, | ||
90 | struct buffer_head **bhp) | ||
91 | { | ||
92 | struct buffer_head *bh; | ||
93 | int error = 0; | ||
94 | |||
95 | if (new) { | ||
96 | bh = gfs2_meta_new(ip->i_gl, block); | ||
97 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | ||
98 | gfs2_metatype_set(bh, GFS2_METATYPE_JD, GFS2_FORMAT_JD); | ||
99 | gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); | ||
100 | } else { | ||
101 | error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh); | ||
102 | if (error) | ||
103 | return error; | ||
104 | if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_JD)) { | ||
105 | brelse(bh); | ||
106 | return -EIO; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | *bhp = bh; | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | |||
115 | |||
116 | static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, | ||
117 | unsigned int offset, unsigned int size) | ||
118 | |||
119 | { | ||
120 | struct buffer_head *dibh; | ||
121 | int error; | ||
122 | |||
123 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
124 | if (error) | ||
125 | return error; | ||
126 | |||
127 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
128 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_inode), buf, size); | ||
129 | if (ip->i_di.di_size < offset + size) | ||
130 | ip->i_di.di_size = offset + size; | ||
131 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | ||
132 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | ||
133 | |||
134 | brelse(dibh); | ||
135 | |||
136 | return size; | ||
137 | } | ||
138 | |||
139 | |||
140 | |||
141 | /** | ||
142 | * gfs2_dir_write_data - Write directory information to the inode | ||
143 | * @ip: The GFS2 inode | ||
144 | * @buf: The buffer containing information to be written | ||
145 | * @offset: The file offset to start writing at | ||
146 | * @size: The amount of data to write | ||
147 | * | ||
148 | * Returns: The number of bytes correctly written or error code | ||
149 | */ | ||
150 | static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf, | ||
151 | uint64_t offset, unsigned int size) | ||
152 | { | ||
153 | struct gfs2_sbd *sdp = ip->i_sbd; | ||
154 | struct buffer_head *dibh; | ||
155 | uint64_t lblock, dblock; | ||
156 | uint32_t extlen = 0; | ||
157 | unsigned int o; | ||
158 | int copied = 0; | ||
159 | int error = 0; | ||
160 | |||
161 | if (!size) | ||
162 | return 0; | ||
163 | |||
164 | if (gfs2_is_stuffed(ip) && | ||
165 | offset + size <= sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) | ||
166 | return gfs2_dir_write_stuffed(ip, buf, (unsigned int)offset, size); | ||
167 | |||
168 | if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip))) | ||
169 | return -EINVAL; | ||
170 | |||
171 | if (gfs2_is_stuffed(ip)) { | ||
172 | error = gfs2_unstuff_dinode(ip, NULL, NULL); | ||
173 | if (error) | ||
174 | return error; | ||
175 | } | ||
176 | |||
177 | lblock = offset; | ||
178 | o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header); | ||
179 | |||
180 | while (copied < size) { | ||
181 | unsigned int amount; | ||
182 | struct buffer_head *bh; | ||
183 | int new; | ||
184 | |||
185 | amount = size - copied; | ||
186 | if (amount > sdp->sd_sb.sb_bsize - o) | ||
187 | amount = sdp->sd_sb.sb_bsize - o; | ||
188 | |||
189 | if (!extlen) { | ||
190 | new = 1; | ||
191 | error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen); | ||
192 | if (error) | ||
193 | goto fail; | ||
194 | error = -EIO; | ||
195 | if (gfs2_assert_withdraw(sdp, dblock)) | ||
196 | goto fail; | ||
197 | } | ||
198 | |||
199 | error = gfs2_dir_get_buffer(ip, dblock, (amount == sdp->sd_jbsize) ? 1 : new, &bh); | ||
200 | if (error) | ||
201 | goto fail; | ||
202 | |||
203 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | ||
204 | memcpy(bh->b_data + o, buf, amount); | ||
205 | brelse(bh); | ||
206 | if (error) | ||
207 | goto fail; | ||
208 | |||
209 | copied += amount; | ||
210 | lblock++; | ||
211 | dblock++; | ||
212 | extlen--; | ||
213 | |||
214 | o = sizeof(struct gfs2_meta_header); | ||
215 | } | ||
216 | |||
217 | out: | ||
218 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
219 | if (error) | ||
220 | return error; | ||
221 | |||
222 | if (ip->i_di.di_size < offset + copied) | ||
223 | ip->i_di.di_size = offset + copied; | ||
224 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | ||
225 | |||
226 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
227 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | ||
228 | brelse(dibh); | ||
229 | |||
230 | return copied; | ||
231 | fail: | ||
232 | if (copied) | ||
233 | goto out; | ||
234 | return error; | ||
235 | } | ||
236 | |||
237 | static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf, | ||
238 | unsigned int offset, unsigned int size) | ||
239 | { | ||
240 | struct buffer_head *dibh; | ||
241 | int error; | ||
242 | |||
243 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
244 | if (!error) { | ||
245 | offset += sizeof(struct gfs2_dinode); | ||
246 | memcpy(buf, dibh->b_data + offset, size); | ||
247 | brelse(dibh); | ||
248 | } | ||
249 | |||
250 | return (error) ? error : size; | ||
251 | } | ||
252 | |||
253 | |||
254 | /** | ||
255 | * gfs2_dir_read_data - Read a data from a directory inode | ||
256 | * @ip: The GFS2 Inode | ||
257 | * @buf: The buffer to place result into | ||
258 | * @offset: File offset to begin jdata_readng from | ||
259 | * @size: Amount of data to transfer | ||
260 | * | ||
261 | * Returns: The amount of data actually copied or the error | ||
262 | */ | ||
263 | static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, | ||
264 | uint64_t offset, unsigned int size) | ||
265 | { | ||
266 | struct gfs2_sbd *sdp = ip->i_sbd; | ||
267 | uint64_t lblock, dblock; | ||
268 | uint32_t extlen = 0; | ||
269 | unsigned int o; | ||
270 | int copied = 0; | ||
271 | int error = 0; | ||
272 | |||
273 | if (offset >= ip->i_di.di_size) | ||
274 | return 0; | ||
275 | |||
276 | if ((offset + size) > ip->i_di.di_size) | ||
277 | size = ip->i_di.di_size - offset; | ||
278 | |||
279 | if (!size) | ||
280 | return 0; | ||
281 | |||
282 | if (gfs2_is_stuffed(ip)) | ||
283 | return gfs2_dir_read_stuffed(ip, buf, (unsigned int)offset, size); | ||
284 | |||
285 | if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip))) | ||
286 | return -EINVAL; | ||
287 | |||
288 | lblock = offset; | ||
289 | o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header); | ||
290 | |||
291 | while (copied < size) { | ||
292 | unsigned int amount; | ||
293 | struct buffer_head *bh; | ||
294 | int new; | ||
295 | |||
296 | amount = size - copied; | ||
297 | if (amount > sdp->sd_sb.sb_bsize - o) | ||
298 | amount = sdp->sd_sb.sb_bsize - o; | ||
299 | |||
300 | if (!extlen) { | ||
301 | new = 0; | ||
302 | error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen); | ||
303 | if (error) | ||
304 | goto fail; | ||
305 | } | ||
306 | |||
307 | if (extlen > 1) | ||
308 | gfs2_meta_ra(ip->i_gl, dblock, extlen); | ||
309 | |||
310 | if (dblock) { | ||
311 | error = gfs2_dir_get_buffer(ip, dblock, new, &bh); | ||
312 | if (error) | ||
313 | goto fail; | ||
314 | dblock++; | ||
315 | extlen--; | ||
316 | } else | ||
317 | bh = NULL; | ||
318 | |||
319 | memcpy(buf, bh->b_data + o, amount); | ||
320 | brelse(bh); | ||
321 | if (error) | ||
322 | goto fail; | ||
323 | |||
324 | copied += amount; | ||
325 | lblock++; | ||
326 | |||
327 | o = sizeof(struct gfs2_meta_header); | ||
328 | } | ||
329 | |||
330 | return copied; | ||
331 | fail: | ||
332 | return (copied) ? copied : error; | ||
333 | } | ||
334 | |||
89 | /** | 335 | /** |
90 | * int gfs2_filecmp - Compare two filenames | 336 | * int gfs2_filecmp - Compare two filenames |
91 | * @file1: The first filename | 337 | * @file1: The first filename |
@@ -428,7 +674,7 @@ static int get_leaf_nr(struct gfs2_inode *dip, uint32_t index, | |||
428 | uint64_t leaf_no; | 674 | uint64_t leaf_no; |
429 | int error; | 675 | int error; |
430 | 676 | ||
431 | error = gfs2_jdata_read_mem(dip, (char *)&leaf_no, | 677 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, |
432 | index * sizeof(uint64_t), | 678 | index * sizeof(uint64_t), |
433 | sizeof(uint64_t)); | 679 | sizeof(uint64_t)); |
434 | if (error != sizeof(uint64_t)) | 680 | if (error != sizeof(uint64_t)) |
@@ -683,7 +929,7 @@ static int dir_split_leaf(struct gfs2_inode *dip, uint32_t index, | |||
683 | 929 | ||
684 | lp = kcalloc(half_len, sizeof(uint64_t), GFP_KERNEL | __GFP_NOFAIL); | 930 | lp = kcalloc(half_len, sizeof(uint64_t), GFP_KERNEL | __GFP_NOFAIL); |
685 | 931 | ||
686 | error = gfs2_jdata_read_mem(dip, (char *)lp, start * sizeof(uint64_t), | 932 | error = gfs2_dir_read_data(dip, (char *)lp, start * sizeof(uint64_t), |
687 | half_len * sizeof(uint64_t)); | 933 | half_len * sizeof(uint64_t)); |
688 | if (error != half_len * sizeof(uint64_t)) { | 934 | if (error != half_len * sizeof(uint64_t)) { |
689 | if (error >= 0) | 935 | if (error >= 0) |
@@ -696,7 +942,7 @@ static int dir_split_leaf(struct gfs2_inode *dip, uint32_t index, | |||
696 | for (x = 0; x < half_len; x++) | 942 | for (x = 0; x < half_len; x++) |
697 | lp[x] = cpu_to_be64(bn); | 943 | lp[x] = cpu_to_be64(bn); |
698 | 944 | ||
699 | error = gfs2_jdata_write_mem(dip, (char *)lp, start * sizeof(uint64_t), | 945 | error = gfs2_dir_write_data(dip, (char *)lp, start * sizeof(uint64_t), |
700 | half_len * sizeof(uint64_t)); | 946 | half_len * sizeof(uint64_t)); |
701 | if (error != half_len * sizeof(uint64_t)) { | 947 | if (error != half_len * sizeof(uint64_t)) { |
702 | if (error >= 0) | 948 | if (error >= 0) |
@@ -816,7 +1062,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
816 | buf = kcalloc(3, sdp->sd_hash_bsize, GFP_KERNEL | __GFP_NOFAIL); | 1062 | buf = kcalloc(3, sdp->sd_hash_bsize, GFP_KERNEL | __GFP_NOFAIL); |
817 | 1063 | ||
818 | for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { | 1064 | for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { |
819 | error = gfs2_jdata_read_mem(dip, (char *)buf, | 1065 | error = gfs2_dir_read_data(dip, (char *)buf, |
820 | block * sdp->sd_hash_bsize, | 1066 | block * sdp->sd_hash_bsize, |
821 | sdp->sd_hash_bsize); | 1067 | sdp->sd_hash_bsize); |
822 | if (error != sdp->sd_hash_bsize) { | 1068 | if (error != sdp->sd_hash_bsize) { |
@@ -833,7 +1079,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
833 | *to++ = *from; | 1079 | *to++ = *from; |
834 | } | 1080 | } |
835 | 1081 | ||
836 | error = gfs2_jdata_write_mem(dip, | 1082 | error = gfs2_dir_write_data(dip, |
837 | (char *)buf + sdp->sd_hash_bsize, | 1083 | (char *)buf + sdp->sd_hash_bsize, |
838 | block * sdp->sd_sb.sb_bsize, | 1084 | block * sdp->sd_sb.sb_bsize, |
839 | sdp->sd_sb.sb_bsize); | 1085 | sdp->sd_sb.sb_bsize); |
@@ -1424,7 +1670,7 @@ static int dir_e_read(struct gfs2_inode *dip, uint64_t *offset, void *opaque, | |||
1424 | ht_offset = index - lp_offset; | 1670 | ht_offset = index - lp_offset; |
1425 | 1671 | ||
1426 | if (ht_offset_cur != ht_offset) { | 1672 | if (ht_offset_cur != ht_offset) { |
1427 | error = gfs2_jdata_read_mem(dip, (char *)lp, | 1673 | error = gfs2_dir_read_data(dip, (char *)lp, |
1428 | ht_offset * sizeof(uint64_t), | 1674 | ht_offset * sizeof(uint64_t), |
1429 | sdp->sd_hash_bsize); | 1675 | sdp->sd_hash_bsize); |
1430 | if (error != sdp->sd_hash_bsize) { | 1676 | if (error != sdp->sd_hash_bsize) { |
@@ -1839,7 +2085,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1839 | ht_offset = index - lp_offset; | 2085 | ht_offset = index - lp_offset; |
1840 | 2086 | ||
1841 | if (ht_offset_cur != ht_offset) { | 2087 | if (ht_offset_cur != ht_offset) { |
1842 | error = gfs2_jdata_read_mem(dip, (char *)lp, | 2088 | error = gfs2_dir_read_data(dip, (char *)lp, |
1843 | ht_offset * sizeof(uint64_t), | 2089 | ht_offset * sizeof(uint64_t), |
1844 | sdp->sd_hash_bsize); | 2090 | sdp->sd_hash_bsize); |
1845 | if (error != sdp->sd_hash_bsize) { | 2091 | if (error != sdp->sd_hash_bsize) { |
@@ -1965,7 +2211,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len, | |||
1965 | dip->i_di.di_blocks--; | 2211 | dip->i_di.di_blocks--; |
1966 | } | 2212 | } |
1967 | 2213 | ||
1968 | error = gfs2_jdata_write_mem(dip, ht, index * sizeof(uint64_t), size); | 2214 | error = gfs2_dir_write_data(dip, ht, index * sizeof(uint64_t), size); |
1969 | if (error != size) { | 2215 | if (error != size) { |
1970 | if (error >= 0) | 2216 | if (error >= 0) |
1971 | error = -EIO; | 2217 | error = -EIO; |