diff options
-rw-r--r-- | fs/jfs/jfs_extent.c | 63 | ||||
-rw-r--r-- | fs/jfs/jfs_types.h | 29 | ||||
-rw-r--r-- | fs/jfs/jfs_xtree.c | 263 | ||||
-rw-r--r-- | fs/jfs/jfs_xtree.h | 2 |
4 files changed, 25 insertions, 332 deletions
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index 7ae1e3281de9..16bc326eeca4 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c | |||
@@ -362,11 +362,12 @@ exit: | |||
362 | int extHint(struct inode *ip, s64 offset, xad_t * xp) | 362 | int extHint(struct inode *ip, s64 offset, xad_t * xp) |
363 | { | 363 | { |
364 | struct super_block *sb = ip->i_sb; | 364 | struct super_block *sb = ip->i_sb; |
365 | struct xadlist xadl; | 365 | int nbperpage = JFS_SBI(sb)->nbperpage; |
366 | struct lxdlist lxdl; | ||
367 | lxd_t lxd; | ||
368 | s64 prev; | 366 | s64 prev; |
369 | int rc, nbperpage = JFS_SBI(sb)->nbperpage; | 367 | int rc = 0; |
368 | s64 xaddr; | ||
369 | int xlen; | ||
370 | int xflag; | ||
370 | 371 | ||
371 | /* init the hint as "no hint provided" */ | 372 | /* init the hint as "no hint provided" */ |
372 | XADaddress(xp, 0); | 373 | XADaddress(xp, 0); |
@@ -376,46 +377,30 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp) | |||
376 | */ | 377 | */ |
377 | prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage; | 378 | prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage; |
378 | 379 | ||
379 | /* if the offsets in the first page of the file, | 380 | /* if the offset is in the first page of the file, no hint provided. |
380 | * no hint provided. | ||
381 | */ | 381 | */ |
382 | if (prev < 0) | 382 | if (prev < 0) |
383 | return (0); | 383 | goto out; |
384 | |||
385 | /* prepare to lookup the previous page's extent info */ | ||
386 | lxdl.maxnlxd = 1; | ||
387 | lxdl.nlxd = 1; | ||
388 | lxdl.lxd = &lxd; | ||
389 | LXDoffset(&lxd, prev) | ||
390 | LXDlength(&lxd, nbperpage); | ||
391 | |||
392 | xadl.maxnxad = 1; | ||
393 | xadl.nxad = 0; | ||
394 | xadl.xad = xp; | ||
395 | |||
396 | /* perform the lookup */ | ||
397 | if ((rc = xtLookupList(ip, &lxdl, &xadl, 0))) | ||
398 | return (rc); | ||
399 | |||
400 | /* check if no extent exists for the previous page. | ||
401 | * this is possible for sparse files. | ||
402 | */ | ||
403 | if (xadl.nxad == 0) { | ||
404 | // assert(ISSPARSE(ip)); | ||
405 | return (0); | ||
406 | } | ||
407 | 384 | ||
408 | /* only preserve the abnr flag within the xad flags | 385 | rc = xtLookup(ip, prev, nbperpage, &xflag, &xaddr, &xlen, 0); |
409 | * of the returned hint. | ||
410 | */ | ||
411 | xp->flag &= XAD_NOTRECORDED; | ||
412 | 386 | ||
413 | if(xadl.nxad != 1 || lengthXAD(xp) != nbperpage) { | 387 | if ((rc == 0) && xlen) { |
414 | jfs_error(ip->i_sb, "extHint: corrupt xtree"); | 388 | if (xlen != nbperpage) { |
415 | return -EIO; | 389 | jfs_error(ip->i_sb, "extHint: corrupt xtree"); |
416 | } | 390 | rc = -EIO; |
391 | } | ||
392 | XADaddress(xp, xaddr); | ||
393 | XADlength(xp, xlen); | ||
394 | /* | ||
395 | * only preserve the abnr flag within the xad flags | ||
396 | * of the returned hint. | ||
397 | */ | ||
398 | xp->flag = xflag & XAD_NOTRECORDED; | ||
399 | } else | ||
400 | rc = 0; | ||
417 | 401 | ||
418 | return (0); | 402 | out: |
403 | return (rc); | ||
419 | } | 404 | } |
420 | 405 | ||
421 | 406 | ||
diff --git a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h index 649f9817accd..43ea3713c083 100644 --- a/fs/jfs/jfs_types.h +++ b/fs/jfs/jfs_types.h | |||
@@ -58,35 +58,6 @@ struct timestruc_t { | |||
58 | #define ONES 0xffffffffu /* all bit on */ | 58 | #define ONES 0xffffffffu /* all bit on */ |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * logical xd (lxd) | ||
62 | */ | ||
63 | typedef struct { | ||
64 | unsigned len:24; | ||
65 | unsigned off1:8; | ||
66 | u32 off2; | ||
67 | } lxd_t; | ||
68 | |||
69 | /* lxd_t field construction */ | ||
70 | #define LXDlength(lxd, length32) ( (lxd)->len = length32 ) | ||
71 | #define LXDoffset(lxd, offset64)\ | ||
72 | {\ | ||
73 | (lxd)->off1 = ((s64)offset64) >> 32;\ | ||
74 | (lxd)->off2 = (offset64) & 0xffffffff;\ | ||
75 | } | ||
76 | |||
77 | /* lxd_t field extraction */ | ||
78 | #define lengthLXD(lxd) ( (lxd)->len ) | ||
79 | #define offsetLXD(lxd)\ | ||
80 | ( ((s64)((lxd)->off1)) << 32 | (lxd)->off2 ) | ||
81 | |||
82 | /* lxd list */ | ||
83 | struct lxdlist { | ||
84 | s16 maxnlxd; | ||
85 | s16 nlxd; | ||
86 | lxd_t *lxd; | ||
87 | }; | ||
88 | |||
89 | /* | ||
90 | * physical xd (pxd) | 61 | * physical xd (pxd) |
91 | */ | 62 | */ |
92 | typedef struct { | 63 | typedef struct { |
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index ae3acafb447b..44380fb0d7c2 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c | |||
@@ -164,11 +164,8 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
164 | /* is lookup offset beyond eof ? */ | 164 | /* is lookup offset beyond eof ? */ |
165 | size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> | 165 | size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> |
166 | JFS_SBI(ip->i_sb)->l2bsize; | 166 | JFS_SBI(ip->i_sb)->l2bsize; |
167 | if (lstart >= size) { | 167 | if (lstart >= size) |
168 | jfs_err("xtLookup: lstart (0x%lx) >= size (0x%lx)", | ||
169 | (ulong) lstart, (ulong) size); | ||
170 | return 0; | 168 | return 0; |
171 | } | ||
172 | } | 169 | } |
173 | 170 | ||
174 | /* | 171 | /* |
@@ -220,264 +217,6 @@ int xtLookup(struct inode *ip, s64 lstart, | |||
220 | return rc; | 217 | return rc; |
221 | } | 218 | } |
222 | 219 | ||
223 | |||
224 | /* | ||
225 | * xtLookupList() | ||
226 | * | ||
227 | * function: map a single logical extent into a list of physical extent; | ||
228 | * | ||
229 | * parameter: | ||
230 | * struct inode *ip, | ||
231 | * struct lxdlist *lxdlist, lxd list (in) | ||
232 | * struct xadlist *xadlist, xad list (in/out) | ||
233 | * int flag) | ||
234 | * | ||
235 | * coverage of lxd by xad under assumption of | ||
236 | * . lxd's are ordered and disjoint. | ||
237 | * . xad's are ordered and disjoint. | ||
238 | * | ||
239 | * return: | ||
240 | * 0: success | ||
241 | * | ||
242 | * note: a page being written (even a single byte) is backed fully, | ||
243 | * except the last page which is only backed with blocks | ||
244 | * required to cover the last byte; | ||
245 | * the extent backing a page is fully contained within an xad; | ||
246 | */ | ||
247 | int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | ||
248 | struct xadlist * xadlist, int flag) | ||
249 | { | ||
250 | int rc = 0; | ||
251 | struct btstack btstack; | ||
252 | int cmp; | ||
253 | s64 bn; | ||
254 | struct metapage *mp; | ||
255 | xtpage_t *p; | ||
256 | int index; | ||
257 | lxd_t *lxd; | ||
258 | xad_t *xad, *pxd; | ||
259 | s64 size, lstart, lend, xstart, xend, pstart; | ||
260 | s64 llen, xlen, plen; | ||
261 | s64 xaddr, paddr; | ||
262 | int nlxd, npxd, maxnpxd; | ||
263 | |||
264 | npxd = xadlist->nxad = 0; | ||
265 | maxnpxd = xadlist->maxnxad; | ||
266 | pxd = xadlist->xad; | ||
267 | |||
268 | nlxd = lxdlist->nlxd; | ||
269 | lxd = lxdlist->lxd; | ||
270 | |||
271 | lstart = offsetLXD(lxd); | ||
272 | llen = lengthLXD(lxd); | ||
273 | lend = lstart + llen; | ||
274 | |||
275 | size = (ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> | ||
276 | JFS_SBI(ip->i_sb)->l2bsize; | ||
277 | |||
278 | /* | ||
279 | * search for the xad entry covering the logical extent | ||
280 | */ | ||
281 | search: | ||
282 | if (lstart >= size) | ||
283 | return 0; | ||
284 | |||
285 | if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0))) | ||
286 | return rc; | ||
287 | |||
288 | /* | ||
289 | * compute the physical extent covering logical extent | ||
290 | * | ||
291 | * N.B. search may have failed (e.g., hole in sparse file), | ||
292 | * and returned the index of the next entry. | ||
293 | */ | ||
294 | //map: | ||
295 | /* retrieve search result */ | ||
296 | XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); | ||
297 | |||
298 | /* is xad on the next sibling page ? */ | ||
299 | if (index == le16_to_cpu(p->header.nextindex)) { | ||
300 | if (p->header.flag & BT_ROOT) | ||
301 | goto mapend; | ||
302 | |||
303 | if ((bn = le64_to_cpu(p->header.next)) == 0) | ||
304 | goto mapend; | ||
305 | |||
306 | XT_PUTPAGE(mp); | ||
307 | |||
308 | /* get next sibling page */ | ||
309 | XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
310 | if (rc) | ||
311 | return rc; | ||
312 | |||
313 | index = XTENTRYSTART; | ||
314 | } | ||
315 | |||
316 | xad = &p->xad[index]; | ||
317 | |||
318 | /* | ||
319 | * is lxd covered by xad ? | ||
320 | */ | ||
321 | compare: | ||
322 | xstart = offsetXAD(xad); | ||
323 | xlen = lengthXAD(xad); | ||
324 | xend = xstart + xlen; | ||
325 | xaddr = addressXAD(xad); | ||
326 | |||
327 | compare1: | ||
328 | if (xstart < lstart) | ||
329 | goto compare2; | ||
330 | |||
331 | /* (lstart <= xstart) */ | ||
332 | |||
333 | /* lxd is NOT covered by xad */ | ||
334 | if (lend <= xstart) { | ||
335 | /* | ||
336 | * get next lxd | ||
337 | */ | ||
338 | if (--nlxd == 0) | ||
339 | goto mapend; | ||
340 | lxd++; | ||
341 | |||
342 | lstart = offsetLXD(lxd); | ||
343 | llen = lengthLXD(lxd); | ||
344 | lend = lstart + llen; | ||
345 | if (lstart >= size) | ||
346 | goto mapend; | ||
347 | |||
348 | /* compare with the current xad */ | ||
349 | goto compare1; | ||
350 | } | ||
351 | /* lxd is covered by xad */ | ||
352 | else { /* (xstart < lend) */ | ||
353 | |||
354 | /* initialize new pxd */ | ||
355 | pstart = xstart; | ||
356 | plen = min(lend - xstart, xlen); | ||
357 | paddr = xaddr; | ||
358 | |||
359 | goto cover; | ||
360 | } | ||
361 | |||
362 | /* (xstart < lstart) */ | ||
363 | compare2: | ||
364 | /* lxd is covered by xad */ | ||
365 | if (lstart < xend) { | ||
366 | /* initialize new pxd */ | ||
367 | pstart = lstart; | ||
368 | plen = min(xend - lstart, llen); | ||
369 | paddr = xaddr + (lstart - xstart); | ||
370 | |||
371 | goto cover; | ||
372 | } | ||
373 | /* lxd is NOT covered by xad */ | ||
374 | else { /* (xend <= lstart) */ | ||
375 | |||
376 | /* | ||
377 | * get next xad | ||
378 | * | ||
379 | * linear search next xad covering lxd on | ||
380 | * the current xad page, and then tree search | ||
381 | */ | ||
382 | if (index == le16_to_cpu(p->header.nextindex) - 1) { | ||
383 | if (p->header.flag & BT_ROOT) | ||
384 | goto mapend; | ||
385 | |||
386 | XT_PUTPAGE(mp); | ||
387 | goto search; | ||
388 | } else { | ||
389 | index++; | ||
390 | xad++; | ||
391 | |||
392 | /* compare with new xad */ | ||
393 | goto compare; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * lxd is covered by xad and a new pxd has been initialized | ||
399 | * (lstart <= xstart < lend) or (xstart < lstart < xend) | ||
400 | */ | ||
401 | cover: | ||
402 | /* finalize pxd corresponding to current xad */ | ||
403 | XT_PUTENTRY(pxd, xad->flag, pstart, plen, paddr); | ||
404 | |||
405 | if (++npxd >= maxnpxd) | ||
406 | goto mapend; | ||
407 | pxd++; | ||
408 | |||
409 | /* | ||
410 | * lxd is fully covered by xad | ||
411 | */ | ||
412 | if (lend <= xend) { | ||
413 | /* | ||
414 | * get next lxd | ||
415 | */ | ||
416 | if (--nlxd == 0) | ||
417 | goto mapend; | ||
418 | lxd++; | ||
419 | |||
420 | lstart = offsetLXD(lxd); | ||
421 | llen = lengthLXD(lxd); | ||
422 | lend = lstart + llen; | ||
423 | if (lstart >= size) | ||
424 | goto mapend; | ||
425 | |||
426 | /* | ||
427 | * test for old xad covering new lxd | ||
428 | * (old xstart < new lstart) | ||
429 | */ | ||
430 | goto compare2; | ||
431 | } | ||
432 | /* | ||
433 | * lxd is partially covered by xad | ||
434 | */ | ||
435 | else { /* (xend < lend) */ | ||
436 | |||
437 | /* | ||
438 | * get next xad | ||
439 | * | ||
440 | * linear search next xad covering lxd on | ||
441 | * the current xad page, and then next xad page search | ||
442 | */ | ||
443 | if (index == le16_to_cpu(p->header.nextindex) - 1) { | ||
444 | if (p->header.flag & BT_ROOT) | ||
445 | goto mapend; | ||
446 | |||
447 | if ((bn = le64_to_cpu(p->header.next)) == 0) | ||
448 | goto mapend; | ||
449 | |||
450 | XT_PUTPAGE(mp); | ||
451 | |||
452 | /* get next sibling page */ | ||
453 | XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
454 | if (rc) | ||
455 | return rc; | ||
456 | |||
457 | index = XTENTRYSTART; | ||
458 | xad = &p->xad[index]; | ||
459 | } else { | ||
460 | index++; | ||
461 | xad++; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * test for new xad covering old lxd | ||
466 | * (old lstart < new xstart) | ||
467 | */ | ||
468 | goto compare; | ||
469 | } | ||
470 | |||
471 | mapend: | ||
472 | xadlist->nxad = npxd; | ||
473 | |||
474 | //out: | ||
475 | XT_PUTPAGE(mp); | ||
476 | |||
477 | return rc; | ||
478 | } | ||
479 | |||
480 | |||
481 | /* | 220 | /* |
482 | * xtSearch() | 221 | * xtSearch() |
483 | * | 222 | * |
diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h index 70815c8a3d6a..08c0c749b986 100644 --- a/fs/jfs/jfs_xtree.h +++ b/fs/jfs/jfs_xtree.h | |||
@@ -110,8 +110,6 @@ typedef union { | |||
110 | */ | 110 | */ |
111 | extern int xtLookup(struct inode *ip, s64 lstart, s64 llen, | 111 | extern int xtLookup(struct inode *ip, s64 lstart, s64 llen, |
112 | int *pflag, s64 * paddr, int *plen, int flag); | 112 | int *pflag, s64 * paddr, int *plen, int flag); |
113 | extern int xtLookupList(struct inode *ip, struct lxdlist * lxdlist, | ||
114 | struct xadlist * xadlist, int flag); | ||
115 | extern void xtInitRoot(tid_t tid, struct inode *ip); | 113 | extern void xtInitRoot(tid_t tid, struct inode *ip); |
116 | extern int xtInsert(tid_t tid, struct inode *ip, | 114 | extern int xtInsert(tid_t tid, struct inode *ip, |
117 | int xflag, s64 xoff, int xlen, s64 * xaddrp, int flag); | 115 | int xflag, s64 xoff, int xlen, s64 * xaddrp, int flag); |