Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'jfs-5.19' of https://github.com/kleikamp/linux-shaggy

Pull jfs updates from David Kleikamp:
"One bug fix and some code cleanup"

* tag 'jfs-5.19' of https://github.com/kleikamp/linux-shaggy:
fs/jfs: Remove dead code
fs: jfs: fix possible NULL pointer dereference in dbFree()

+3 -1652
-2
fs/jfs/Makefile
··· 13 13 resize.o xattr.o ioctl.o 14 14 15 15 jfs-$(CONFIG_JFS_POSIX_ACL) += acl.o 16 - 17 - ccflags-y := -D_JFS_4K
-18
fs/jfs/inode.c
··· 224 224 * this as a hole 225 225 */ 226 226 goto unlock; 227 - #ifdef _JFS_4K 228 227 XADoffset(&xad, lblock64); 229 228 XADlength(&xad, xlen); 230 229 XADaddress(&xad, xaddr); 231 - #else /* _JFS_4K */ 232 - /* 233 - * As long as block size = 4K, this isn't a problem. 234 - * We should mark the whole page not ABNR, but how 235 - * will we know to mark the other blocks BH_New? 236 - */ 237 - BUG(); 238 - #endif /* _JFS_4K */ 239 230 rc = extRecord(ip, &xad); 240 231 if (rc) 241 232 goto unlock; ··· 243 252 /* 244 253 * Allocate a new block 245 254 */ 246 - #ifdef _JFS_4K 247 255 if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) 248 256 goto unlock; 249 257 rc = extAlloc(ip, xlen, lblock64, &xad, false); ··· 252 262 set_buffer_new(bh_result); 253 263 map_bh(bh_result, ip->i_sb, addressXAD(&xad)); 254 264 bh_result->b_size = lengthXAD(&xad) << ip->i_blkbits; 255 - 256 - #else /* _JFS_4K */ 257 - /* 258 - * We need to do whatever it takes to keep all but the last buffers 259 - * in 4K pages - see jfs_write.c 260 - */ 261 - BUG(); 262 - #endif /* _JFS_4K */ 263 265 264 266 unlock: 265 267 /*
+2 -69
fs/jfs/jfs_dmap.c
··· 385 385 } 386 386 387 387 /* write the last buffer. */ 388 - write_metapage(mp); 388 + if (mp) 389 + write_metapage(mp); 389 390 390 391 IREAD_UNLOCK(ipbmap); 391 392 ··· 868 867 869 868 return (rc); 870 869 } 871 - 872 - #ifdef _NOTYET 873 - /* 874 - * NAME: dbAllocExact() 875 - * 876 - * FUNCTION: try to allocate the requested extent; 877 - * 878 - * PARAMETERS: 879 - * ip - pointer to in-core inode; 880 - * blkno - extent address; 881 - * nblocks - extent length; 882 - * 883 - * RETURN VALUES: 884 - * 0 - success 885 - * -ENOSPC - insufficient disk resources 886 - * -EIO - i/o error 887 - */ 888 - int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) 889 - { 890 - int rc; 891 - struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap; 892 - struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap; 893 - struct dmap *dp; 894 - s64 lblkno; 895 - struct metapage *mp; 896 - 897 - IREAD_LOCK(ipbmap, RDWRLOCK_DMAP); 898 - 899 - /* 900 - * validate extent request: 901 - * 902 - * note: defragfs policy: 903 - * max 64 blocks will be moved. 904 - * allocation request size must be satisfied from a single dmap. 905 - */ 906 - if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) { 907 - IREAD_UNLOCK(ipbmap); 908 - return -EINVAL; 909 - } 910 - 911 - if (nblocks > ((s64) 1 << bmp->db_maxfreebud)) { 912 - /* the free space is no longer available */ 913 - IREAD_UNLOCK(ipbmap); 914 - return -ENOSPC; 915 - } 916 - 917 - /* read in the dmap covering the extent */ 918 - lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage); 919 - mp = read_metapage(ipbmap, lblkno, PSIZE, 0); 920 - if (mp == NULL) { 921 - IREAD_UNLOCK(ipbmap); 922 - return -EIO; 923 - } 924 - dp = (struct dmap *) mp->data; 925 - 926 - /* try to allocate the requested extent */ 927 - rc = dbAllocNext(bmp, dp, blkno, nblocks); 928 - 929 - IREAD_UNLOCK(ipbmap); 930 - 931 - if (rc == 0) 932 - mark_metapage_dirty(mp); 933 - 934 - release_metapage(mp); 935 - 936 - return (rc); 937 - } 938 - #endif /* _NOTYET */ 939 870 940 871 /* 941 872 * NAME: dbReAlloc()
-298
fs/jfs/jfs_dtree.c
··· 2423 2423 return 0; 2424 2424 } 2425 2425 2426 - #ifdef _NOTYET 2427 - /* 2428 - * NAME: dtRelocate() 2429 - * 2430 - * FUNCTION: relocate dtpage (internal or leaf) of directory; 2431 - * This function is mainly used by defragfs utility. 2432 - */ 2433 - int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, 2434 - s64 nxaddr) 2435 - { 2436 - int rc = 0; 2437 - struct metapage *mp, *pmp, *lmp, *rmp; 2438 - dtpage_t *p, *pp, *rp = 0, *lp= 0; 2439 - s64 bn; 2440 - int index; 2441 - struct btstack btstack; 2442 - pxd_t *pxd; 2443 - s64 oxaddr, nextbn, prevbn; 2444 - int xlen, xsize; 2445 - struct tlock *tlck; 2446 - struct dt_lock *dtlck; 2447 - struct pxd_lock *pxdlock; 2448 - s8 *stbl; 2449 - struct lv *lv; 2450 - 2451 - oxaddr = addressPXD(opxd); 2452 - xlen = lengthPXD(opxd); 2453 - 2454 - jfs_info("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d", 2455 - (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr, 2456 - xlen); 2457 - 2458 - /* 2459 - * 1. get the internal parent dtpage covering 2460 - * router entry for the tartget page to be relocated; 2461 - */ 2462 - rc = dtSearchNode(ip, lmxaddr, opxd, &btstack); 2463 - if (rc) 2464 - return rc; 2465 - 2466 - /* retrieve search result */ 2467 - DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); 2468 - jfs_info("dtRelocate: parent router entry validated."); 2469 - 2470 - /* 2471 - * 2. relocate the target dtpage 2472 - */ 2473 - /* read in the target page from src extent */ 2474 - DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc); 2475 - if (rc) { 2476 - /* release the pinned parent page */ 2477 - DT_PUTPAGE(pmp); 2478 - return rc; 2479 - } 2480 - 2481 - /* 2482 - * read in sibling pages if any to update sibling pointers; 2483 - */ 2484 - rmp = NULL; 2485 - if (p->header.next) { 2486 - nextbn = le64_to_cpu(p->header.next); 2487 - DT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc); 2488 - if (rc) { 2489 - DT_PUTPAGE(mp); 2490 - DT_PUTPAGE(pmp); 2491 - return (rc); 2492 - } 2493 - } 2494 - 2495 - lmp = NULL; 2496 - if (p->header.prev) { 2497 - prevbn = le64_to_cpu(p->header.prev); 2498 - DT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc); 2499 - if (rc) { 2500 - DT_PUTPAGE(mp); 2501 - DT_PUTPAGE(pmp); 2502 - if (rmp) 2503 - DT_PUTPAGE(rmp); 2504 - return (rc); 2505 - } 2506 - } 2507 - 2508 - /* at this point, all xtpages to be updated are in memory */ 2509 - 2510 - /* 2511 - * update sibling pointers of sibling dtpages if any; 2512 - */ 2513 - if (lmp) { 2514 - tlck = txLock(tid, ip, lmp, tlckDTREE | tlckRELINK); 2515 - dtlck = (struct dt_lock *) & tlck->lock; 2516 - /* linelock header */ 2517 - ASSERT(dtlck->index == 0); 2518 - lv = & dtlck->lv[0]; 2519 - lv->offset = 0; 2520 - lv->length = 1; 2521 - dtlck->index++; 2522 - 2523 - lp->header.next = cpu_to_le64(nxaddr); 2524 - DT_PUTPAGE(lmp); 2525 - } 2526 - 2527 - if (rmp) { 2528 - tlck = txLock(tid, ip, rmp, tlckDTREE | tlckRELINK); 2529 - dtlck = (struct dt_lock *) & tlck->lock; 2530 - /* linelock header */ 2531 - ASSERT(dtlck->index == 0); 2532 - lv = & dtlck->lv[0]; 2533 - lv->offset = 0; 2534 - lv->length = 1; 2535 - dtlck->index++; 2536 - 2537 - rp->header.prev = cpu_to_le64(nxaddr); 2538 - DT_PUTPAGE(rmp); 2539 - } 2540 - 2541 - /* 2542 - * update the target dtpage to be relocated 2543 - * 2544 - * write LOG_REDOPAGE of LOG_NEW type for dst page 2545 - * for the whole target page (logredo() will apply 2546 - * after image and update bmap for allocation of the 2547 - * dst extent), and update bmap for allocation of 2548 - * the dst extent; 2549 - */ 2550 - tlck = txLock(tid, ip, mp, tlckDTREE | tlckNEW); 2551 - dtlck = (struct dt_lock *) & tlck->lock; 2552 - /* linelock header */ 2553 - ASSERT(dtlck->index == 0); 2554 - lv = & dtlck->lv[0]; 2555 - 2556 - /* update the self address in the dtpage header */ 2557 - pxd = &p->header.self; 2558 - PXDaddress(pxd, nxaddr); 2559 - 2560 - /* the dst page is the same as the src page, i.e., 2561 - * linelock for afterimage of the whole page; 2562 - */ 2563 - lv->offset = 0; 2564 - lv->length = p->header.maxslot; 2565 - dtlck->index++; 2566 - 2567 - /* update the buffer extent descriptor of the dtpage */ 2568 - xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize; 2569 - 2570 - /* unpin the relocated page */ 2571 - DT_PUTPAGE(mp); 2572 - jfs_info("dtRelocate: target dtpage relocated."); 2573 - 2574 - /* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec 2575 - * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec 2576 - * will also force a bmap update ). 2577 - */ 2578 - 2579 - /* 2580 - * 3. acquire maplock for the source extent to be freed; 2581 - */ 2582 - /* for dtpage relocation, write a LOG_NOREDOPAGE record 2583 - * for the source dtpage (logredo() will init NoRedoPage 2584 - * filter and will also update bmap for free of the source 2585 - * dtpage), and upadte bmap for free of the source dtpage; 2586 - */ 2587 - tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE); 2588 - pxdlock = (struct pxd_lock *) & tlck->lock; 2589 - pxdlock->flag = mlckFREEPXD; 2590 - PXDaddress(&pxdlock->pxd, oxaddr); 2591 - PXDlength(&pxdlock->pxd, xlen); 2592 - pxdlock->index = 1; 2593 - 2594 - /* 2595 - * 4. update the parent router entry for relocation; 2596 - * 2597 - * acquire tlck for the parent entry covering the target dtpage; 2598 - * write LOG_REDOPAGE to apply after image only; 2599 - */ 2600 - jfs_info("dtRelocate: update parent router entry."); 2601 - tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY); 2602 - dtlck = (struct dt_lock *) & tlck->lock; 2603 - lv = & dtlck->lv[dtlck->index]; 2604 - 2605 - /* update the PXD with the new address */ 2606 - stbl = DT_GETSTBL(pp); 2607 - pxd = (pxd_t *) & pp->slot[stbl[index]]; 2608 - PXDaddress(pxd, nxaddr); 2609 - lv->offset = stbl[index]; 2610 - lv->length = 1; 2611 - dtlck->index++; 2612 - 2613 - /* unpin the parent dtpage */ 2614 - DT_PUTPAGE(pmp); 2615 - 2616 - return rc; 2617 - } 2618 - 2619 - /* 2620 - * NAME: dtSearchNode() 2621 - * 2622 - * FUNCTION: Search for an dtpage containing a specified address 2623 - * This function is mainly used by defragfs utility. 2624 - * 2625 - * NOTE: Search result on stack, the found page is pinned at exit. 2626 - * The result page must be an internal dtpage. 2627 - * lmxaddr give the address of the left most page of the 2628 - * dtree level, in which the required dtpage resides. 2629 - */ 2630 - static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd, 2631 - struct btstack * btstack) 2632 - { 2633 - int rc = 0; 2634 - s64 bn; 2635 - struct metapage *mp; 2636 - dtpage_t *p; 2637 - int psize = 288; /* initial in-line directory */ 2638 - s8 *stbl; 2639 - int i; 2640 - pxd_t *pxd; 2641 - struct btframe *btsp; 2642 - 2643 - BT_CLR(btstack); /* reset stack */ 2644 - 2645 - /* 2646 - * descend tree to the level with specified leftmost page 2647 - * 2648 - * by convention, root bn = 0. 2649 - */ 2650 - for (bn = 0;;) { 2651 - /* get/pin the page to search */ 2652 - DT_GETPAGE(ip, bn, mp, psize, p, rc); 2653 - if (rc) 2654 - return rc; 2655 - 2656 - /* does the xaddr of leftmost page of the levevl 2657 - * matches levevl search key ? 2658 - */ 2659 - if (p->header.flag & BT_ROOT) { 2660 - if (lmxaddr == 0) 2661 - break; 2662 - } else if (addressPXD(&p->header.self) == lmxaddr) 2663 - break; 2664 - 2665 - /* 2666 - * descend down to leftmost child page 2667 - */ 2668 - if (p->header.flag & BT_LEAF) { 2669 - DT_PUTPAGE(mp); 2670 - return -ESTALE; 2671 - } 2672 - 2673 - /* get the leftmost entry */ 2674 - stbl = DT_GETSTBL(p); 2675 - pxd = (pxd_t *) & p->slot[stbl[0]]; 2676 - 2677 - /* get the child page block address */ 2678 - bn = addressPXD(pxd); 2679 - psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize; 2680 - /* unpin the parent page */ 2681 - DT_PUTPAGE(mp); 2682 - } 2683 - 2684 - /* 2685 - * search each page at the current levevl 2686 - */ 2687 - loop: 2688 - stbl = DT_GETSTBL(p); 2689 - for (i = 0; i < p->header.nextindex; i++) { 2690 - pxd = (pxd_t *) & p->slot[stbl[i]]; 2691 - 2692 - /* found the specified router entry */ 2693 - if (addressPXD(pxd) == addressPXD(kpxd) && 2694 - lengthPXD(pxd) == lengthPXD(kpxd)) { 2695 - btsp = btstack->top; 2696 - btsp->bn = bn; 2697 - btsp->index = i; 2698 - btsp->mp = mp; 2699 - 2700 - return 0; 2701 - } 2702 - } 2703 - 2704 - /* get the right sibling page if any */ 2705 - if (p->header.next) 2706 - bn = le64_to_cpu(p->header.next); 2707 - else { 2708 - DT_PUTPAGE(mp); 2709 - return -ESTALE; 2710 - } 2711 - 2712 - /* unpin current page */ 2713 - DT_PUTPAGE(mp); 2714 - 2715 - /* get the right sibling page */ 2716 - DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 2717 - if (rc) 2718 - return rc; 2719 - 2720 - goto loop; 2721 - } 2722 - #endif /* _NOTYET */ 2723 - 2724 2426 /* 2725 2427 * dtRelink() 2726 2428 *
-255
fs/jfs/jfs_extent.c
··· 16 16 * forward references 17 17 */ 18 18 static int extBalloc(struct inode *, s64, s64 *, s64 *); 19 - #ifdef _NOTYET 20 - static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *); 21 - #endif 22 19 static s64 extRoundDown(s64 nb); 23 20 24 21 #define DPD(a) (printk("(a): %d\n",(a))) ··· 174 177 return (0); 175 178 } 176 179 177 - 178 - #ifdef _NOTYET 179 - /* 180 - * NAME: extRealloc() 181 - * 182 - * FUNCTION: extend the allocation of a file extent containing a 183 - * partial back last page. 184 - * 185 - * PARAMETERS: 186 - * ip - the inode of the file. 187 - * cp - cbuf for the partial backed last page. 188 - * xlen - request size of the resulting extent. 189 - * xp - pointer to an xad. on successful exit, the xad 190 - * describes the newly allocated extent. 191 - * abnr - bool indicating whether the newly allocated extent 192 - * should be marked as allocated but not recorded. 193 - * 194 - * RETURN VALUES: 195 - * 0 - success 196 - * -EIO - i/o error. 197 - * -ENOSPC - insufficient disk resources. 198 - */ 199 - int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) 200 - { 201 - struct super_block *sb = ip->i_sb; 202 - s64 xaddr, xlen, nxaddr, delta, xoff; 203 - s64 ntail, nextend, ninsert; 204 - int rc, nbperpage = JFS_SBI(sb)->nbperpage; 205 - int xflag; 206 - 207 - /* This blocks if we are low on resources */ 208 - txBeginAnon(ip->i_sb); 209 - 210 - mutex_lock(&JFS_IP(ip)->commit_mutex); 211 - /* validate extent length */ 212 - if (nxlen > MAXXLEN) 213 - nxlen = MAXXLEN; 214 - 215 - /* get the extend (partial) page's disk block address and 216 - * number of blocks. 217 - */ 218 - xaddr = addressXAD(xp); 219 - xlen = lengthXAD(xp); 220 - xoff = offsetXAD(xp); 221 - 222 - /* if the extend page is abnr and if the request is for 223 - * the extent to be allocated and recorded, 224 - * make the page allocated and recorded. 225 - */ 226 - if ((xp->flag & XAD_NOTRECORDED) && !abnr) { 227 - xp->flag = 0; 228 - if ((rc = xtUpdate(0, ip, xp))) 229 - goto exit; 230 - } 231 - 232 - /* try to allocated the request number of blocks for the 233 - * extent. dbRealloc() first tries to satisfy the request 234 - * by extending the allocation in place. otherwise, it will 235 - * try to allocate a new set of blocks large enough for the 236 - * request. in satisfying a request, dbReAlloc() may allocate 237 - * less than what was request but will always allocate enough 238 - * space as to satisfy the extend page. 239 - */ 240 - if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr))) 241 - goto exit; 242 - 243 - /* Allocat blocks to quota. */ 244 - rc = dquot_alloc_block(ip, nxlen); 245 - if (rc) { 246 - dbFree(ip, nxaddr, (s64) nxlen); 247 - mutex_unlock(&JFS_IP(ip)->commit_mutex); 248 - return rc; 249 - } 250 - 251 - delta = nxlen - xlen; 252 - 253 - /* check if the extend page is not abnr but the request is abnr 254 - * and the allocated disk space is for more than one page. if this 255 - * is the case, there is a miss match of abnr between the extend page 256 - * and the one or more pages following the extend page. as a result, 257 - * two extents will have to be manipulated. the first will be that 258 - * of the extent of the extend page and will be manipulated thru 259 - * an xtExtend() or an xtTailgate(), depending upon whether the 260 - * disk allocation occurred as an inplace extension. the second 261 - * extent will be manipulated (created) through an xtInsert() and 262 - * will be for the pages following the extend page. 263 - */ 264 - if (abnr && (!(xp->flag & XAD_NOTRECORDED)) && (nxlen > nbperpage)) { 265 - ntail = nbperpage; 266 - nextend = ntail - xlen; 267 - ninsert = nxlen - nbperpage; 268 - 269 - xflag = XAD_NOTRECORDED; 270 - } else { 271 - ntail = nxlen; 272 - nextend = delta; 273 - ninsert = 0; 274 - 275 - xflag = xp->flag; 276 - } 277 - 278 - /* if we were able to extend the disk allocation in place, 279 - * extend the extent. otherwise, move the extent to a 280 - * new disk location. 281 - */ 282 - if (xaddr == nxaddr) { 283 - /* extend the extent */ 284 - if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { 285 - dbFree(ip, xaddr + xlen, delta); 286 - dquot_free_block(ip, nxlen); 287 - goto exit; 288 - } 289 - } else { 290 - /* 291 - * move the extent to a new location: 292 - * 293 - * xtTailgate() accounts for relocated tail extent; 294 - */ 295 - if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) { 296 - dbFree(ip, nxaddr, nxlen); 297 - dquot_free_block(ip, nxlen); 298 - goto exit; 299 - } 300 - } 301 - 302 - 303 - /* check if we need to also insert a new extent */ 304 - if (ninsert) { 305 - /* perform the insert. if it fails, free the blocks 306 - * to be inserted and make it appear that we only did 307 - * the xtExtend() or xtTailgate() above. 308 - */ 309 - xaddr = nxaddr + ntail; 310 - if (xtInsert (0, ip, xflag, xoff + ntail, (int) ninsert, 311 - &xaddr, 0)) { 312 - dbFree(ip, xaddr, (s64) ninsert); 313 - delta = nextend; 314 - nxlen = ntail; 315 - xflag = 0; 316 - } 317 - } 318 - 319 - /* set the return results */ 320 - XADaddress(xp, nxaddr); 321 - XADlength(xp, nxlen); 322 - XADoffset(xp, xoff); 323 - xp->flag = xflag; 324 - 325 - mark_inode_dirty(ip); 326 - exit: 327 - mutex_unlock(&JFS_IP(ip)->commit_mutex); 328 - return (rc); 329 - } 330 - #endif /* _NOTYET */ 331 - 332 - 333 180 /* 334 181 * NAME: extHint() 335 182 * ··· 264 423 return rc; 265 424 } 266 425 267 - 268 - #ifdef _NOTYET 269 - /* 270 - * NAME: extFill() 271 - * 272 - * FUNCTION: allocate disk space for a file page that represents 273 - * a file hole. 274 - * 275 - * PARAMETERS: 276 - * ip - the inode of the file. 277 - * cp - cbuf of the file page represent the hole. 278 - * 279 - * RETURN VALUES: 280 - * 0 - success 281 - * -EIO - i/o error. 282 - * -ENOSPC - insufficient disk resources. 283 - */ 284 - int extFill(struct inode *ip, xad_t * xp) 285 - { 286 - int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage; 287 - s64 blkno = offsetXAD(xp) >> ip->i_blkbits; 288 - 289 - // assert(ISSPARSE(ip)); 290 - 291 - /* initialize the extent allocation hint */ 292 - XADaddress(xp, 0); 293 - 294 - /* allocate an extent to fill the hole */ 295 - if ((rc = extAlloc(ip, nbperpage, blkno, xp, false))) 296 - return (rc); 297 - 298 - assert(lengthPXD(xp) == nbperpage); 299 - 300 - return (0); 301 - } 302 - #endif /* _NOTYET */ 303 - 304 - 305 426 /* 306 427 * NAME: extBalloc() 307 428 * ··· 352 549 353 550 return (0); 354 551 } 355 - 356 - 357 - #ifdef _NOTYET 358 - /* 359 - * NAME: extBrealloc() 360 - * 361 - * FUNCTION: attempt to extend an extent's allocation. 362 - * 363 - * Initially, we will try to extend the extent's allocation 364 - * in place. If this fails, we'll try to move the extent 365 - * to a new set of blocks. If moving the extent, we initially 366 - * will try to allocate disk blocks for the requested size 367 - * (newnblks). if this fails (new contiguous free blocks not 368 - * available), we'll try to allocate a smaller number of 369 - * blocks (producing a smaller extent), with this smaller 370 - * number of blocks consisting of the requested number of 371 - * blocks rounded down to the next smaller power of 2 372 - * number (i.e. 16 -> 8). We'll continue to round down and 373 - * retry the allocation until the number of blocks to allocate 374 - * is smaller than the number of blocks per page. 375 - * 376 - * PARAMETERS: 377 - * ip - the inode of the file. 378 - * blkno - starting block number of the extents current allocation. 379 - * nblks - number of blocks within the extents current allocation. 380 - * newnblks - pointer to a s64 value. on entry, this value is the 381 - * new desired extent size (number of blocks). on 382 - * successful exit, this value is set to the extent's actual 383 - * new size (new number of blocks). 384 - * newblkno - the starting block number of the extents new allocation. 385 - * 386 - * RETURN VALUES: 387 - * 0 - success 388 - * -EIO - i/o error. 389 - * -ENOSPC - insufficient disk resources. 390 - */ 391 - static int 392 - extBrealloc(struct inode *ip, 393 - s64 blkno, s64 nblks, s64 * newnblks, s64 * newblkno) 394 - { 395 - int rc; 396 - 397 - /* try to extend in place */ 398 - if ((rc = dbExtend(ip, blkno, nblks, *newnblks - nblks)) == 0) { 399 - *newblkno = blkno; 400 - return (0); 401 - } else { 402 - if (rc != -ENOSPC) 403 - return (rc); 404 - } 405 - 406 - /* in place extension not possible. 407 - * try to move the extent to a new set of blocks. 408 - */ 409 - return (extBalloc(ip, blkno, newnblks, newblkno)); 410 - } 411 - #endif /* _NOTYET */ 412 - 413 552 414 553 /* 415 554 * NAME: extRoundDown()
-8
fs/jfs/jfs_logmgr.c
··· 388 388 p = (caddr_t) &JFS_IP(tlck->ip)->i_xtroot; 389 389 linelock = (struct linelock *) & tlck->lock; 390 390 } 391 - #ifdef _JFS_WIP 392 - else if (tlck->flag & tlckINLINELOCK) { 393 - 394 - inlinelock = (struct inlinelock *) & tlck; 395 - p = (caddr_t) & inlinelock->pxd; 396 - linelock = (struct linelock *) & tlck; 397 - } 398 - #endif /* _JFS_WIP */ 399 391 else { 400 392 jfs_err("lmWriteRecord: UFO tlck:0x%p", tlck); 401 393 return 0; /* Probably should trap */
+1 -3
fs/jfs/jfs_mount.c
··· 307 307 } 308 308 309 309 bsize = le32_to_cpu(j_sb->s_bsize); 310 - #ifdef _JFS_4K 311 310 if (bsize != PSIZE) { 312 - jfs_err("Currently only 4K block size supported!"); 311 + jfs_err("Only 4K block size supported!"); 313 312 rc = -EINVAL; 314 313 goto out; 315 314 } 316 - #endif /* _JFS_4K */ 317 315 318 316 jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx", 319 317 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
-34
fs/jfs/jfs_txnmgr.c
··· 1490 1490 tlck->flag |= tlckWRITEPAGE; 1491 1491 } else 1492 1492 jfs_err("diLog: UFO type tlck:0x%p", tlck); 1493 - #ifdef _JFS_WIP 1494 - /* 1495 - * alloc/free external EA extent 1496 - * 1497 - * a maplock for txUpdateMap() to update bPWMAP for alloc/free 1498 - * of the extent has been formatted at txLock() time; 1499 - */ 1500 - else { 1501 - assert(tlck->type & tlckEA); 1502 - 1503 - /* log LOG_UPDATEMAP for logredo() to update bmap for 1504 - * alloc of new (and free of old) external EA extent; 1505 - */ 1506 - lrd->type = cpu_to_le16(LOG_UPDATEMAP); 1507 - pxdlock = (struct pxd_lock *) & tlck->lock; 1508 - nlock = pxdlock->index; 1509 - for (i = 0; i < nlock; i++, pxdlock++) { 1510 - if (pxdlock->flag & mlckALLOCPXD) 1511 - lrd->log.updatemap.type = 1512 - cpu_to_le16(LOG_ALLOCPXD); 1513 - else 1514 - lrd->log.updatemap.type = 1515 - cpu_to_le16(LOG_FREEPXD); 1516 - lrd->log.updatemap.nxd = cpu_to_le16(1); 1517 - lrd->log.updatemap.pxd = pxdlock->pxd; 1518 - lrd->backchain = 1519 - cpu_to_le32(lmLog(log, tblk, lrd, NULL)); 1520 - } 1521 - 1522 - /* update bmap */ 1523 - tlck->flag |= tlckUPDATEMAP; 1524 - } 1525 - #endif /* _JFS_WIP */ 1526 - 1527 1493 return; 1528 1494 } 1529 1495
-961
fs/jfs/jfs_xtree.c
··· 114 114 static int xtSplitRoot(tid_t tid, struct inode *ip, 115 115 struct xtsplit * split, struct metapage ** rmpp); 116 116 117 - #ifdef _STILL_TO_PORT 118 - static int xtDeleteUp(tid_t tid, struct inode *ip, struct metapage * fmp, 119 - xtpage_t * fp, struct btstack * btstack); 120 - 121 - static int xtSearchNode(struct inode *ip, 122 - xad_t * xad, 123 - int *cmpp, struct btstack * btstack, int flag); 124 - 125 - static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp); 126 - #endif /* _STILL_TO_PORT */ 127 - 128 117 /* 129 118 * xtLookup() 130 119 * ··· 1482 1493 return rc; 1483 1494 } 1484 1495 1485 - #ifdef _NOTYET 1486 - /* 1487 - * xtTailgate() 1488 - * 1489 - * function: split existing 'tail' extent 1490 - * (split offset >= start offset of tail extent), and 1491 - * relocate and extend the split tail half; 1492 - * 1493 - * note: existing extent may or may not have been committed. 1494 - * caller is responsible for pager buffer cache update, and 1495 - * working block allocation map update; 1496 - * update pmap: free old split tail extent, alloc new extent; 1497 - */ 1498 - int xtTailgate(tid_t tid, /* transaction id */ 1499 - struct inode *ip, s64 xoff, /* split/new extent offset */ 1500 - s32 xlen, /* new extent length */ 1501 - s64 xaddr, /* new extent address */ 1502 - int flag) 1503 - { 1504 - int rc = 0; 1505 - int cmp; 1506 - struct metapage *mp; /* meta-page buffer */ 1507 - xtpage_t *p; /* base B+-tree index page */ 1508 - s64 bn; 1509 - int index, nextindex, llen, rlen; 1510 - struct btstack btstack; /* traverse stack */ 1511 - struct xtsplit split; /* split information */ 1512 - xad_t *xad; 1513 - struct tlock *tlck; 1514 - struct xtlock *xtlck = 0; 1515 - struct tlock *mtlck; 1516 - struct maplock *pxdlock; 1517 - 1518 - /* 1519 - printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n", 1520 - (ulong)xoff, xlen, (ulong)xaddr); 1521 - */ 1522 - 1523 - /* there must exist extent to be tailgated */ 1524 - if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT))) 1525 - return rc; 1526 - 1527 - /* retrieve search result */ 1528 - XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); 1529 - 1530 - if (cmp != 0) { 1531 - XT_PUTPAGE(mp); 1532 - jfs_error(ip->i_sb, "couldn't find extent\n"); 1533 - return -EIO; 1534 - } 1535 - 1536 - /* entry found must be last entry */ 1537 - nextindex = le16_to_cpu(p->header.nextindex); 1538 - if (index != nextindex - 1) { 1539 - XT_PUTPAGE(mp); 1540 - jfs_error(ip->i_sb, "the entry found is not the last entry\n"); 1541 - return -EIO; 1542 - } 1543 - 1544 - BT_MARK_DIRTY(mp, ip); 1545 - /* 1546 - * acquire tlock of the leaf page containing original entry 1547 - */ 1548 - if (!test_cflag(COMMIT_Nolink, ip)) { 1549 - tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW); 1550 - xtlck = (struct xtlock *) & tlck->lock; 1551 - } 1552 - 1553 - /* completely replace extent ? */ 1554 - xad = &p->xad[index]; 1555 - /* 1556 - printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", 1557 - (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad)); 1558 - */ 1559 - if ((llen = xoff - offsetXAD(xad)) == 0) 1560 - goto updateOld; 1561 - 1562 - /* 1563 - * partially replace extent: insert entry for new extent 1564 - */ 1565 - //insertNew: 1566 - /* 1567 - * if the leaf page is full, insert the new entry and 1568 - * propagate up the router entry for the new page from split 1569 - * 1570 - * The xtSplitUp() will insert the entry and unpin the leaf page. 1571 - */ 1572 - if (nextindex == le16_to_cpu(p->header.maxentry)) { 1573 - /* xtSpliUp() unpins leaf pages */ 1574 - split.mp = mp; 1575 - split.index = index + 1; 1576 - split.flag = XAD_NEW; 1577 - split.off = xoff; /* split offset */ 1578 - split.len = xlen; 1579 - split.addr = xaddr; 1580 - split.pxdlist = NULL; 1581 - if ((rc = xtSplitUp(tid, ip, &split, &btstack))) 1582 - return rc; 1583 - 1584 - /* get back old page */ 1585 - XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 1586 - if (rc) 1587 - return rc; 1588 - /* 1589 - * if leaf root has been split, original root has been 1590 - * copied to new child page, i.e., original entry now 1591 - * resides on the new child page; 1592 - */ 1593 - if (p->header.flag & BT_INTERNAL) { 1594 - ASSERT(p->header.nextindex == 1595 - cpu_to_le16(XTENTRYSTART + 1)); 1596 - xad = &p->xad[XTENTRYSTART]; 1597 - bn = addressXAD(xad); 1598 - XT_PUTPAGE(mp); 1599 - 1600 - /* get new child page */ 1601 - XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 1602 - if (rc) 1603 - return rc; 1604 - 1605 - BT_MARK_DIRTY(mp, ip); 1606 - if (!test_cflag(COMMIT_Nolink, ip)) { 1607 - tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW); 1608 - xtlck = (struct xtlock *) & tlck->lock; 1609 - } 1610 - } 1611 - } 1612 - /* 1613 - * insert the new entry into the leaf page 1614 - */ 1615 - else { 1616 - /* insert the new entry: mark the entry NEW */ 1617 - xad = &p->xad[index + 1]; 1618 - XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr); 1619 - 1620 - /* advance next available entry index */ 1621 - le16_add_cpu(&p->header.nextindex, 1); 1622 - } 1623 - 1624 - /* get back old XAD */ 1625 - xad = &p->xad[index]; 1626 - 1627 - /* 1628 - * truncate/relocate old extent at split offset 1629 - */ 1630 - updateOld: 1631 - /* update dmap for old/committed/truncated extent */ 1632 - rlen = lengthXAD(xad) - llen; 1633 - if (!(xad->flag & XAD_NEW)) { 1634 - /* free from PWMAP at commit */ 1635 - if (!test_cflag(COMMIT_Nolink, ip)) { 1636 - mtlck = txMaplock(tid, ip, tlckMAP); 1637 - pxdlock = (struct maplock *) & mtlck->lock; 1638 - pxdlock->flag = mlckFREEPXD; 1639 - PXDaddress(&pxdlock->pxd, addressXAD(xad) + llen); 1640 - PXDlength(&pxdlock->pxd, rlen); 1641 - pxdlock->index = 1; 1642 - } 1643 - } else 1644 - /* free from WMAP */ 1645 - dbFree(ip, addressXAD(xad) + llen, (s64) rlen); 1646 - 1647 - if (llen) 1648 - /* truncate */ 1649 - XADlength(xad, llen); 1650 - else 1651 - /* replace */ 1652 - XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr); 1653 - 1654 - if (!test_cflag(COMMIT_Nolink, ip)) { 1655 - xtlck->lwm.offset = (xtlck->lwm.offset) ? 1656 - min(index, (int)xtlck->lwm.offset) : index; 1657 - xtlck->lwm.length = le16_to_cpu(p->header.nextindex) - 1658 - xtlck->lwm.offset; 1659 - } 1660 - 1661 - /* unpin the leaf page */ 1662 - XT_PUTPAGE(mp); 1663 - 1664 - return rc; 1665 - } 1666 - #endif /* _NOTYET */ 1667 - 1668 1496 /* 1669 1497 * xtUpdate() 1670 1498 * ··· 1559 1753 newindex = index + 1; 1560 1754 nextindex = le16_to_cpu(p->header.nextindex); 1561 1755 1562 - #ifdef _JFS_WIP_NOCOALESCE 1563 - if (xoff < nxoff) 1564 - goto updateRight; 1565 - 1566 - /* 1567 - * replace XAD with nXAD 1568 - */ 1569 - replace: /* (nxoff == xoff) */ 1570 - if (nxlen == xlen) { 1571 - /* replace XAD with nXAD:recorded */ 1572 - *xad = *nxad; 1573 - xad->flag = xflag & ~XAD_NOTRECORDED; 1574 - 1575 - goto out; 1576 - } else /* (nxlen < xlen) */ 1577 - goto updateLeft; 1578 - #endif /* _JFS_WIP_NOCOALESCE */ 1579 - 1580 - /* #ifdef _JFS_WIP_COALESCE */ 1581 1756 if (xoff < nxoff) 1582 1757 goto coalesceRight; 1583 1758 1584 1759 /* 1585 1760 * coalesce with left XAD 1586 1761 */ 1587 - //coalesceLeft: /* (xoff == nxoff) */ 1588 1762 /* is XAD first entry of page ? */ 1589 1763 if (index == XTENTRYSTART) 1590 1764 goto replace; ··· 1683 1897 jfs_error(ip->i_sb, "xoff >= nxoff\n"); 1684 1898 return -EIO; 1685 1899 } 1686 - /* #endif _JFS_WIP_COALESCE */ 1687 1900 1688 1901 /* 1689 1902 * split XAD into (lXAD, nXAD): ··· 2090 2305 2091 2306 return rc; 2092 2307 } 2093 - #ifdef _STILL_TO_PORT 2094 - 2095 - /* - TBD for defragmentaion/reorganization - 2096 - * 2097 - * xtDelete() 2098 - * 2099 - * function: 2100 - * delete the entry with the specified key. 2101 - * 2102 - * N.B.: whole extent of the entry is assumed to be deleted. 2103 - * 2104 - * parameter: 2105 - * 2106 - * return: 2107 - * ENOENT: if the entry is not found. 2108 - * 2109 - * exception: 2110 - */ 2111 - int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag) 2112 - { 2113 - int rc = 0; 2114 - struct btstack btstack; 2115 - int cmp; 2116 - s64 bn; 2117 - struct metapage *mp; 2118 - xtpage_t *p; 2119 - int index, nextindex; 2120 - struct tlock *tlck; 2121 - struct xtlock *xtlck; 2122 - 2123 - /* 2124 - * find the matching entry; xtSearch() pins the page 2125 - */ 2126 - if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0))) 2127 - return rc; 2128 - 2129 - XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); 2130 - if (cmp) { 2131 - /* unpin the leaf page */ 2132 - XT_PUTPAGE(mp); 2133 - return -ENOENT; 2134 - } 2135 - 2136 - /* 2137 - * delete the entry from the leaf page 2138 - */ 2139 - nextindex = le16_to_cpu(p->header.nextindex); 2140 - le16_add_cpu(&p->header.nextindex, -1); 2141 - 2142 - /* 2143 - * if the leaf page bocome empty, free the page 2144 - */ 2145 - if (p->header.nextindex == cpu_to_le16(XTENTRYSTART)) 2146 - return (xtDeleteUp(tid, ip, mp, p, &btstack)); 2147 - 2148 - BT_MARK_DIRTY(mp, ip); 2149 - /* 2150 - * acquire a transaction lock on the leaf page; 2151 - * 2152 - * action:xad deletion; 2153 - */ 2154 - tlck = txLock(tid, ip, mp, tlckXTREE); 2155 - xtlck = (struct xtlock *) & tlck->lock; 2156 - xtlck->lwm.offset = 2157 - (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index; 2158 - 2159 - /* if delete from middle, shift left/compact the remaining entries */ 2160 - if (index < nextindex - 1) 2161 - memmove(&p->xad[index], &p->xad[index + 1], 2162 - (nextindex - index - 1) * sizeof(xad_t)); 2163 - 2164 - XT_PUTPAGE(mp); 2165 - 2166 - return 0; 2167 - } 2168 - 2169 - 2170 - /* - TBD for defragmentaion/reorganization - 2171 - * 2172 - * xtDeleteUp() 2173 - * 2174 - * function: 2175 - * free empty pages as propagating deletion up the tree 2176 - * 2177 - * parameter: 2178 - * 2179 - * return: 2180 - */ 2181 - static int 2182 - xtDeleteUp(tid_t tid, struct inode *ip, 2183 - struct metapage * fmp, xtpage_t * fp, struct btstack * btstack) 2184 - { 2185 - int rc = 0; 2186 - struct metapage *mp; 2187 - xtpage_t *p; 2188 - int index, nextindex; 2189 - s64 xaddr; 2190 - int xlen; 2191 - struct btframe *parent; 2192 - struct tlock *tlck; 2193 - struct xtlock *xtlck; 2194 - 2195 - /* 2196 - * keep root leaf page which has become empty 2197 - */ 2198 - if (fp->header.flag & BT_ROOT) { 2199 - /* keep the root page */ 2200 - fp->header.flag &= ~BT_INTERNAL; 2201 - fp->header.flag |= BT_LEAF; 2202 - fp->header.nextindex = cpu_to_le16(XTENTRYSTART); 2203 - 2204 - /* XT_PUTPAGE(fmp); */ 2205 - 2206 - return 0; 2207 - } 2208 - 2209 - /* 2210 - * free non-root leaf page 2211 - */ 2212 - if ((rc = xtRelink(tid, ip, fp))) { 2213 - XT_PUTPAGE(fmp); 2214 - return rc; 2215 - } 2216 - 2217 - xaddr = addressPXD(&fp->header.self); 2218 - xlen = lengthPXD(&fp->header.self); 2219 - /* free the page extent */ 2220 - dbFree(ip, xaddr, (s64) xlen); 2221 - 2222 - /* free the buffer page */ 2223 - discard_metapage(fmp); 2224 - 2225 - /* 2226 - * propagate page deletion up the index tree 2227 - * 2228 - * If the delete from the parent page makes it empty, 2229 - * continue all the way up the tree. 2230 - * stop if the root page is reached (which is never deleted) or 2231 - * if the entry deletion does not empty the page. 2232 - */ 2233 - while ((parent = BT_POP(btstack)) != NULL) { 2234 - /* get/pin the parent page <sp> */ 2235 - XT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc); 2236 - if (rc) 2237 - return rc; 2238 - 2239 - index = parent->index; 2240 - 2241 - /* delete the entry for the freed child page from parent. 2242 - */ 2243 - nextindex = le16_to_cpu(p->header.nextindex); 2244 - 2245 - /* 2246 - * the parent has the single entry being deleted: 2247 - * free the parent page which has become empty. 2248 - */ 2249 - if (nextindex == 1) { 2250 - if (p->header.flag & BT_ROOT) { 2251 - /* keep the root page */ 2252 - p->header.flag &= ~BT_INTERNAL; 2253 - p->header.flag |= BT_LEAF; 2254 - p->header.nextindex = 2255 - cpu_to_le16(XTENTRYSTART); 2256 - 2257 - /* XT_PUTPAGE(mp); */ 2258 - 2259 - break; 2260 - } else { 2261 - /* free the parent page */ 2262 - if ((rc = xtRelink(tid, ip, p))) 2263 - return rc; 2264 - 2265 - xaddr = addressPXD(&p->header.self); 2266 - /* free the page extent */ 2267 - dbFree(ip, xaddr, 2268 - (s64) JFS_SBI(ip->i_sb)->nbperpage); 2269 - 2270 - /* unpin/free the buffer page */ 2271 - discard_metapage(mp); 2272 - 2273 - /* propagate up */ 2274 - continue; 2275 - } 2276 - } 2277 - /* 2278 - * the parent has other entries remaining: 2279 - * delete the router entry from the parent page. 2280 - */ 2281 - else { 2282 - BT_MARK_DIRTY(mp, ip); 2283 - /* 2284 - * acquire a transaction lock on the leaf page; 2285 - * 2286 - * action:xad deletion; 2287 - */ 2288 - tlck = txLock(tid, ip, mp, tlckXTREE); 2289 - xtlck = (struct xtlock *) & tlck->lock; 2290 - xtlck->lwm.offset = 2291 - (xtlck->lwm.offset) ? min(index, 2292 - xtlck->lwm. 2293 - offset) : index; 2294 - 2295 - /* if delete from middle, 2296 - * shift left/compact the remaining entries in the page 2297 - */ 2298 - if (index < nextindex - 1) 2299 - memmove(&p->xad[index], &p->xad[index + 1], 2300 - (nextindex - index - 2301 - 1) << L2XTSLOTSIZE); 2302 - 2303 - le16_add_cpu(&p->header.nextindex, -1); 2304 - jfs_info("xtDeleteUp(entry): 0x%lx[%d]", 2305 - (ulong) parent->bn, index); 2306 - } 2307 - 2308 - /* unpin the parent page */ 2309 - XT_PUTPAGE(mp); 2310 - 2311 - /* exit propagation up */ 2312 - break; 2313 - } 2314 - 2315 - return 0; 2316 - } 2317 - 2318 - 2319 - /* 2320 - * NAME: xtRelocate() 2321 - * 2322 - * FUNCTION: relocate xtpage or data extent of regular file; 2323 - * This function is mainly used by defragfs utility. 2324 - * 2325 - * NOTE: This routine does not have the logic to handle 2326 - * uncommitted allocated extent. The caller should call 2327 - * txCommit() to commit all the allocation before call 2328 - * this routine. 2329 - */ 2330 - int 2331 - xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ 2332 - s64 nxaddr, /* new xaddr */ 2333 - int xtype) 2334 - { /* extent type: XTPAGE or DATAEXT */ 2335 - int rc = 0; 2336 - struct tblock *tblk; 2337 - struct tlock *tlck; 2338 - struct xtlock *xtlck; 2339 - struct metapage *mp, *pmp, *lmp, *rmp; /* meta-page buffer */ 2340 - xtpage_t *p, *pp, *rp, *lp; /* base B+-tree index page */ 2341 - xad_t *xad; 2342 - pxd_t *pxd; 2343 - s64 xoff, xsize; 2344 - int xlen; 2345 - s64 oxaddr, sxaddr, dxaddr, nextbn, prevbn; 2346 - cbuf_t *cp; 2347 - s64 offset, nbytes, nbrd, pno; 2348 - int nb, npages, nblks; 2349 - s64 bn; 2350 - int cmp; 2351 - int index; 2352 - struct pxd_lock *pxdlock; 2353 - struct btstack btstack; /* traverse stack */ 2354 - 2355 - xtype = xtype & EXTENT_TYPE; 2356 - 2357 - xoff = offsetXAD(oxad); 2358 - oxaddr = addressXAD(oxad); 2359 - xlen = lengthXAD(oxad); 2360 - 2361 - /* validate extent offset */ 2362 - offset = xoff << JFS_SBI(ip->i_sb)->l2bsize; 2363 - if (offset >= ip->i_size) 2364 - return -ESTALE; /* stale extent */ 2365 - 2366 - jfs_info("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx", 2367 - xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr); 2368 - 2369 - /* 2370 - * 1. get and validate the parent xtpage/xad entry 2371 - * covering the source extent to be relocated; 2372 - */ 2373 - if (xtype == DATAEXT) { 2374 - /* search in leaf entry */ 2375 - rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0); 2376 - if (rc) 2377 - return rc; 2378 - 2379 - /* retrieve search result */ 2380 - XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); 2381 - 2382 - if (cmp) { 2383 - XT_PUTPAGE(pmp); 2384 - return -ESTALE; 2385 - } 2386 - 2387 - /* validate for exact match with a single entry */ 2388 - xad = &pp->xad[index]; 2389 - if (addressXAD(xad) != oxaddr || lengthXAD(xad) != xlen) { 2390 - XT_PUTPAGE(pmp); 2391 - return -ESTALE; 2392 - } 2393 - } else { /* (xtype == XTPAGE) */ 2394 - 2395 - /* search in internal entry */ 2396 - rc = xtSearchNode(ip, oxad, &cmp, &btstack, 0); 2397 - if (rc) 2398 - return rc; 2399 - 2400 - /* retrieve search result */ 2401 - XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); 2402 - 2403 - if (cmp) { 2404 - XT_PUTPAGE(pmp); 2405 - return -ESTALE; 2406 - } 2407 - 2408 - /* xtSearchNode() validated for exact match with a single entry 2409 - */ 2410 - xad = &pp->xad[index]; 2411 - } 2412 - jfs_info("xtRelocate: parent xad entry validated."); 2413 - 2414 - /* 2415 - * 2. relocate the extent 2416 - */ 2417 - if (xtype == DATAEXT) { 2418 - /* if the extent is allocated-but-not-recorded 2419 - * there is no real data to be moved in this extent, 2420 - */ 2421 - if (xad->flag & XAD_NOTRECORDED) 2422 - goto out; 2423 - else 2424 - /* release xtpage for cmRead()/xtLookup() */ 2425 - XT_PUTPAGE(pmp); 2426 - 2427 - /* 2428 - * cmRelocate() 2429 - * 2430 - * copy target data pages to be relocated; 2431 - * 2432 - * data extent must start at page boundary and 2433 - * multiple of page size (except the last data extent); 2434 - * read in each page of the source data extent into cbuf, 2435 - * update the cbuf extent descriptor of the page to be 2436 - * homeward bound to new dst data extent 2437 - * copy the data from the old extent to new extent. 2438 - * copy is essential for compressed files to avoid problems 2439 - * that can arise if there was a change in compression 2440 - * algorithms. 2441 - * it is a good strategy because it may disrupt cache 2442 - * policy to keep the pages in memory afterwards. 2443 - */ 2444 - offset = xoff << JFS_SBI(ip->i_sb)->l2bsize; 2445 - assert((offset & CM_OFFSET) == 0); 2446 - nbytes = xlen << JFS_SBI(ip->i_sb)->l2bsize; 2447 - pno = offset >> CM_L2BSIZE; 2448 - npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE; 2449 - /* 2450 - npages = ((offset + nbytes - 1) >> CM_L2BSIZE) - 2451 - (offset >> CM_L2BSIZE) + 1; 2452 - */ 2453 - sxaddr = oxaddr; 2454 - dxaddr = nxaddr; 2455 - 2456 - /* process the request one cache buffer at a time */ 2457 - for (nbrd = 0; nbrd < nbytes; nbrd += nb, 2458 - offset += nb, pno++, npages--) { 2459 - /* compute page size */ 2460 - nb = min(nbytes - nbrd, CM_BSIZE); 2461 - 2462 - /* get the cache buffer of the page */ 2463 - if (rc = cmRead(ip, offset, npages, &cp)) 2464 - break; 2465 - 2466 - assert(addressPXD(&cp->cm_pxd) == sxaddr); 2467 - assert(!cp->cm_modified); 2468 - 2469 - /* bind buffer with the new extent address */ 2470 - nblks = nb >> JFS_IP(ip->i_sb)->l2bsize; 2471 - cmSetXD(ip, cp, pno, dxaddr, nblks); 2472 - 2473 - /* release the cbuf, mark it as modified */ 2474 - cmPut(cp, true); 2475 - 2476 - dxaddr += nblks; 2477 - sxaddr += nblks; 2478 - } 2479 - 2480 - /* get back parent page */ 2481 - if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0))) 2482 - return rc; 2483 - 2484 - XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); 2485 - jfs_info("xtRelocate: target data extent relocated."); 2486 - } else { /* (xtype == XTPAGE) */ 2487 - 2488 - /* 2489 - * read in the target xtpage from the source extent; 2490 - */ 2491 - XT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc); 2492 - if (rc) { 2493 - XT_PUTPAGE(pmp); 2494 - return rc; 2495 - } 2496 - 2497 - /* 2498 - * read in sibling pages if any to update sibling pointers; 2499 - */ 2500 - rmp = NULL; 2501 - if (p->header.next) { 2502 - nextbn = le64_to_cpu(p->header.next); 2503 - XT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc); 2504 - if (rc) { 2505 - XT_PUTPAGE(pmp); 2506 - XT_PUTPAGE(mp); 2507 - return (rc); 2508 - } 2509 - } 2510 - 2511 - lmp = NULL; 2512 - if (p->header.prev) { 2513 - prevbn = le64_to_cpu(p->header.prev); 2514 - XT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc); 2515 - if (rc) { 2516 - XT_PUTPAGE(pmp); 2517 - XT_PUTPAGE(mp); 2518 - if (rmp) 2519 - XT_PUTPAGE(rmp); 2520 - return (rc); 2521 - } 2522 - } 2523 - 2524 - /* at this point, all xtpages to be updated are in memory */ 2525 - 2526 - /* 2527 - * update sibling pointers of sibling xtpages if any; 2528 - */ 2529 - if (lmp) { 2530 - BT_MARK_DIRTY(lmp, ip); 2531 - tlck = txLock(tid, ip, lmp, tlckXTREE | tlckRELINK); 2532 - lp->header.next = cpu_to_le64(nxaddr); 2533 - XT_PUTPAGE(lmp); 2534 - } 2535 - 2536 - if (rmp) { 2537 - BT_MARK_DIRTY(rmp, ip); 2538 - tlck = txLock(tid, ip, rmp, tlckXTREE | tlckRELINK); 2539 - rp->header.prev = cpu_to_le64(nxaddr); 2540 - XT_PUTPAGE(rmp); 2541 - } 2542 - 2543 - /* 2544 - * update the target xtpage to be relocated 2545 - * 2546 - * update the self address of the target page 2547 - * and write to destination extent; 2548 - * redo image covers the whole xtpage since it is new page 2549 - * to the destination extent; 2550 - * update of bmap for the free of source extent 2551 - * of the target xtpage itself: 2552 - * update of bmap for the allocation of destination extent 2553 - * of the target xtpage itself: 2554 - * update of bmap for the extents covered by xad entries in 2555 - * the target xtpage is not necessary since they are not 2556 - * updated; 2557 - * if not committed before this relocation, 2558 - * target page may contain XAD_NEW entries which must 2559 - * be scanned for bmap update (logredo() always 2560 - * scan xtpage REDOPAGE image for bmap update); 2561 - * if committed before this relocation (tlckRELOCATE), 2562 - * scan may be skipped by commit() and logredo(); 2563 - */ 2564 - BT_MARK_DIRTY(mp, ip); 2565 - /* tlckNEW init xtlck->lwm.offset = XTENTRYSTART; */ 2566 - tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW); 2567 - xtlck = (struct xtlock *) & tlck->lock; 2568 - 2569 - /* update the self address in the xtpage header */ 2570 - pxd = &p->header.self; 2571 - PXDaddress(pxd, nxaddr); 2572 - 2573 - /* linelock for the after image of the whole page */ 2574 - xtlck->lwm.length = 2575 - le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset; 2576 - 2577 - /* update the buffer extent descriptor of target xtpage */ 2578 - xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize; 2579 - bmSetXD(mp, nxaddr, xsize); 2580 - 2581 - /* unpin the target page to new homeward bound */ 2582 - XT_PUTPAGE(mp); 2583 - jfs_info("xtRelocate: target xtpage relocated."); 2584 - } 2585 - 2586 - /* 2587 - * 3. acquire maplock for the source extent to be freed; 2588 - * 2589 - * acquire a maplock saving the src relocated extent address; 2590 - * to free of the extent at commit time; 2591 - */ 2592 - out: 2593 - /* if DATAEXT relocation, write a LOG_UPDATEMAP record for 2594 - * free PXD of the source data extent (logredo() will update 2595 - * bmap for free of source data extent), and update bmap for 2596 - * free of the source data extent; 2597 - */ 2598 - if (xtype == DATAEXT) 2599 - tlck = txMaplock(tid, ip, tlckMAP); 2600 - /* if XTPAGE relocation, write a LOG_NOREDOPAGE record 2601 - * for the source xtpage (logredo() will init NoRedoPage 2602 - * filter and will also update bmap for free of the source 2603 - * xtpage), and update bmap for free of the source xtpage; 2604 - * N.B. We use tlckMAP instead of tlkcXTREE because there 2605 - * is no buffer associated with this lock since the buffer 2606 - * has been redirected to the target location. 2607 - */ 2608 - else /* (xtype == XTPAGE) */ 2609 - tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE); 2610 - 2611 - pxdlock = (struct pxd_lock *) & tlck->lock; 2612 - pxdlock->flag = mlckFREEPXD; 2613 - PXDaddress(&pxdlock->pxd, oxaddr); 2614 - PXDlength(&pxdlock->pxd, xlen); 2615 - pxdlock->index = 1; 2616 - 2617 - /* 2618 - * 4. update the parent xad entry for relocation; 2619 - * 2620 - * acquire tlck for the parent entry with XAD_NEW as entry 2621 - * update which will write LOG_REDOPAGE and update bmap for 2622 - * allocation of XAD_NEW destination extent; 2623 - */ 2624 - jfs_info("xtRelocate: update parent xad entry."); 2625 - BT_MARK_DIRTY(pmp, ip); 2626 - tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW); 2627 - xtlck = (struct xtlock *) & tlck->lock; 2628 - 2629 - /* update the XAD with the new destination extent; */ 2630 - xad = &pp->xad[index]; 2631 - xad->flag |= XAD_NEW; 2632 - XADaddress(xad, nxaddr); 2633 - 2634 - xtlck->lwm.offset = min(index, xtlck->lwm.offset); 2635 - xtlck->lwm.length = le16_to_cpu(pp->header.nextindex) - 2636 - xtlck->lwm.offset; 2637 - 2638 - /* unpin the parent xtpage */ 2639 - XT_PUTPAGE(pmp); 2640 - 2641 - return rc; 2642 - } 2643 - 2644 - 2645 - /* 2646 - * xtSearchNode() 2647 - * 2648 - * function: search for the internal xad entry covering specified extent. 2649 - * This function is mainly used by defragfs utility. 2650 - * 2651 - * parameters: 2652 - * ip - file object; 2653 - * xad - extent to find; 2654 - * cmpp - comparison result: 2655 - * btstack - traverse stack; 2656 - * flag - search process flag; 2657 - * 2658 - * returns: 2659 - * btstack contains (bn, index) of search path traversed to the entry. 2660 - * *cmpp is set to result of comparison with the entry returned. 2661 - * the page containing the entry is pinned at exit. 2662 - */ 2663 - static int xtSearchNode(struct inode *ip, xad_t * xad, /* required XAD entry */ 2664 - int *cmpp, struct btstack * btstack, int flag) 2665 - { 2666 - int rc = 0; 2667 - s64 xoff, xaddr; 2668 - int xlen; 2669 - int cmp = 1; /* init for empty page */ 2670 - s64 bn; /* block number */ 2671 - struct metapage *mp; /* meta-page buffer */ 2672 - xtpage_t *p; /* page */ 2673 - int base, index, lim; 2674 - struct btframe *btsp; 2675 - s64 t64; 2676 - 2677 - BT_CLR(btstack); 2678 - 2679 - xoff = offsetXAD(xad); 2680 - xlen = lengthXAD(xad); 2681 - xaddr = addressXAD(xad); 2682 - 2683 - /* 2684 - * search down tree from root: 2685 - * 2686 - * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of 2687 - * internal page, child page Pi contains entry with k, Ki <= K < Kj. 2688 - * 2689 - * if entry with search key K is not found 2690 - * internal page search find the entry with largest key Ki 2691 - * less than K which point to the child page to search; 2692 - * leaf page search find the entry with smallest key Kj 2693 - * greater than K so that the returned index is the position of 2694 - * the entry to be shifted right for insertion of new entry. 2695 - * for empty tree, search key is greater than any key of the tree. 2696 - * 2697 - * by convention, root bn = 0. 2698 - */ 2699 - for (bn = 0;;) { 2700 - /* get/pin the page to search */ 2701 - XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 2702 - if (rc) 2703 - return rc; 2704 - if (p->header.flag & BT_LEAF) { 2705 - XT_PUTPAGE(mp); 2706 - return -ESTALE; 2707 - } 2708 - 2709 - lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART; 2710 - 2711 - /* 2712 - * binary search with search key K on the current page 2713 - */ 2714 - for (base = XTENTRYSTART; lim; lim >>= 1) { 2715 - index = base + (lim >> 1); 2716 - 2717 - XT_CMP(cmp, xoff, &p->xad[index], t64); 2718 - if (cmp == 0) { 2719 - /* 2720 - * search hit 2721 - * 2722 - * verify for exact match; 2723 - */ 2724 - if (xaddr == addressXAD(&p->xad[index]) && 2725 - xoff == offsetXAD(&p->xad[index])) { 2726 - *cmpp = cmp; 2727 - 2728 - /* save search result */ 2729 - btsp = btstack->top; 2730 - btsp->bn = bn; 2731 - btsp->index = index; 2732 - btsp->mp = mp; 2733 - 2734 - return 0; 2735 - } 2736 - 2737 - /* descend/search its child page */ 2738 - goto next; 2739 - } 2740 - 2741 - if (cmp > 0) { 2742 - base = index + 1; 2743 - --lim; 2744 - } 2745 - } 2746 - 2747 - /* 2748 - * search miss - non-leaf page: 2749 - * 2750 - * base is the smallest index with key (Kj) greater than 2751 - * search key (K) and may be zero or maxentry index. 2752 - * if base is non-zero, decrement base by one to get the parent 2753 - * entry of the child page to search. 2754 - */ 2755 - index = base ? base - 1 : base; 2756 - 2757 - /* 2758 - * go down to child page 2759 - */ 2760 - next: 2761 - /* get the child page block number */ 2762 - bn = addressXAD(&p->xad[index]); 2763 - 2764 - /* unpin the parent page */ 2765 - XT_PUTPAGE(mp); 2766 - } 2767 - } 2768 - 2769 - 2770 - /* 2771 - * xtRelink() 2772 - * 2773 - * function: 2774 - * link around a freed page. 2775 - * 2776 - * Parameter: 2777 - * int tid, 2778 - * struct inode *ip, 2779 - * xtpage_t *p) 2780 - * 2781 - * returns: 2782 - */ 2783 - static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p) 2784 - { 2785 - int rc = 0; 2786 - struct metapage *mp; 2787 - s64 nextbn, prevbn; 2788 - struct tlock *tlck; 2789 - 2790 - nextbn = le64_to_cpu(p->header.next); 2791 - prevbn = le64_to_cpu(p->header.prev); 2792 - 2793 - /* update prev pointer of the next page */ 2794 - if (nextbn != 0) { 2795 - XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); 2796 - if (rc) 2797 - return rc; 2798 - 2799 - /* 2800 - * acquire a transaction lock on the page; 2801 - * 2802 - * action: update prev pointer; 2803 - */ 2804 - BT_MARK_DIRTY(mp, ip); 2805 - tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK); 2806 - 2807 - /* the page may already have been tlock'd */ 2808 - 2809 - p->header.prev = cpu_to_le64(prevbn); 2810 - 2811 - XT_PUTPAGE(mp); 2812 - } 2813 - 2814 - /* update next pointer of the previous page */ 2815 - if (prevbn != 0) { 2816 - XT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc); 2817 - if (rc) 2818 - return rc; 2819 - 2820 - /* 2821 - * acquire a transaction lock on the page; 2822 - * 2823 - * action: update next pointer; 2824 - */ 2825 - BT_MARK_DIRTY(mp, ip); 2826 - tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK); 2827 - 2828 - /* the page may already have been tlock'd */ 2829 - 2830 - p->header.next = le64_to_cpu(nextbn); 2831 - 2832 - XT_PUTPAGE(mp); 2833 - } 2834 - 2835 - return 0; 2836 - } 2837 - #endif /* _STILL_TO_PORT */ 2838 - 2839 2308 2840 2309 /* 2841 2310 * xtInitRoot()
-4
fs/jfs/jfs_xtree.h
··· 95 95 int xflag, s64 xoff, int xlen, s64 * xaddrp, int flag); 96 96 extern int xtExtend(tid_t tid, struct inode *ip, s64 xoff, int xlen, 97 97 int flag); 98 - #ifdef _NOTYET 99 - extern int xtTailgate(tid_t tid, struct inode *ip, 100 - s64 xoff, int xlen, s64 xaddr, int flag); 101 - #endif 102 98 extern int xtUpdate(tid_t tid, struct inode *ip, struct xad *nxad); 103 99 extern int xtDelete(tid_t tid, struct inode *ip, s64 xoff, int xlen, 104 100 int flag);