aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jfs/jfs_extent.c63
-rw-r--r--fs/jfs/jfs_types.h29
-rw-r--r--fs/jfs/jfs_xtree.c263
-rw-r--r--fs/jfs/jfs_xtree.h2
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:
362int extHint(struct inode *ip, s64 offset, xad_t * xp) 362int 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); 402out:
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 */
63typedef 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 */
83struct lxdlist {
84 s16 maxnlxd;
85 s16 nlxd;
86 lxd_t *lxd;
87};
88
89/*
90 * physical xd (pxd) 61 * physical xd (pxd)
91 */ 62 */
92typedef struct { 63typedef 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 */
247int 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 */
111extern int xtLookup(struct inode *ip, s64 lstart, s64 llen, 111extern 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);
113extern int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
114 struct xadlist * xadlist, int flag);
115extern void xtInitRoot(tid_t tid, struct inode *ip); 113extern void xtInitRoot(tid_t tid, struct inode *ip);
116extern int xtInsert(tid_t tid, struct inode *ip, 114extern 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);