1 /* 2 * Copyright (C) International Business Machines Corp., 2000-2004 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 /* 20 * jfs_dtree.c: directory B+-tree manager 21 * 22 * B+-tree with variable length key directory: 23 * 24 * each directory page is structured as an array of 32-byte 25 * directory entry slots initialized as a freelist 26 * to avoid search/compaction of free space at insertion. 27 * when an entry is inserted, a number of slots are allocated 28 * from the freelist as required to store variable length data 29 * of the entry; when the entry is deleted, slots of the entry 30 * are returned to freelist. 31 * 32 * leaf entry stores full name as key and file serial number 33 * (aka inode number) as data. 34 * internal/router entry stores sufffix compressed name 35 * as key and simple extent descriptor as data. 36 * 37 * each directory page maintains a sorted entry index table 38 * which stores the start slot index of sorted entries 39 * to allow binary search on the table. 40 * 41 * directory starts as a root/leaf page in on-disk inode 42 * inline data area. 43 * when it becomes full, it starts a leaf of a external extent 44 * of length of 1 block. each time the first leaf becomes full, 45 * it is extended rather than split (its size is doubled), 46 * until its length becoms 4 KBytes, from then the extent is split 47 * with new 4 Kbyte extent when it becomes full 48 * to reduce external fragmentation of small directories. 49 * 50 * blah, blah, blah, for linear scan of directory in pieces by 51 * readdir(). 52 * 53 * 54 * case-insensitive directory file system 55 * 56 * names are stored in case-sensitive way in leaf entry. 57 * but stored, searched and compared in case-insensitive (uppercase) order 58 * (i.e., both search key and entry key are folded for search/compare): 59 * (note that case-sensitive order is BROKEN in storage, e.g., 60 * sensitive: Ad, aB, aC, aD -> insensitive: aB, aC, aD, Ad 61 * 62 * entries which folds to the same key makes up a equivalent class 63 * whose members are stored as contiguous cluster (may cross page boundary) 64 * but whose order is arbitrary and acts as duplicate, e.g., 65 * abc, Abc, aBc, abC) 66 * 67 * once match is found at leaf, requires scan forward/backward 68 * either for, in case-insensitive search, duplicate 69 * or for, in case-sensitive search, for exact match 70 * 71 * router entry must be created/stored in case-insensitive way 72 * in internal entry: 73 * (right most key of left page and left most key of right page 74 * are folded, and its suffix compression is propagated as router 75 * key in parent) 76 * (e.g., if split occurs <abc> and <aBd>, <ABD> trather than <aB> 77 * should be made the router key for the split) 78 * 79 * case-insensitive search: 80 * 81 * fold search key; 82 * 83 * case-insensitive search of B-tree: 84 * for internal entry, router key is already folded; 85 * for leaf entry, fold the entry key before comparison. 86 * 87 * if (leaf entry case-insensitive match found) 88 * if (next entry satisfies case-insensitive match) 89 * return EDUPLICATE; 90 * if (prev entry satisfies case-insensitive match) 91 * return EDUPLICATE; 92 * return match; 93 * else 94 * return no match; 95 * 96 * serialization: 97 * target directory inode lock is being held on entry/exit 98 * of all main directory service routines. 99 * 100 * log based recovery: 101 */ 102 103 #include <linux/fs.h> 104 #include <linux/quotaops.h> 105 #include "jfs_incore.h" 106 #include "jfs_superblock.h" 107 #include "jfs_filsys.h" 108 #include "jfs_metapage.h" 109 #include "jfs_dmap.h" 110 #include "jfs_unicode.h" 111 #include "jfs_debug.h" 112 113 /* dtree split parameter */ 114 struct dtsplit { 115 struct metapage *mp; 116 s16 index; 117 s16 nslot; 118 struct component_name *key; 119 ddata_t *data; 120 struct pxdlist *pxdlist; 121 }; 122 123 #define DT_PAGE(IP, MP) BT_PAGE(IP, MP, dtpage_t, i_dtroot) 124 125 /* get page buffer for specified block address */ 126 #define DT_GETPAGE(IP, BN, MP, SIZE, P, RC)\ 127 {\ 128 BT_GETPAGE(IP, BN, MP, dtpage_t, SIZE, P, RC, i_dtroot)\ 129 if (!(RC))\ 130 {\ 131 if (((P)->header.nextindex > (((BN)==0)?DTROOTMAXSLOT:(P)->header.maxslot)) ||\ 132 ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT)))\ 133 {\ 134 BT_PUTPAGE(MP);\ 135 jfs_error((IP)->i_sb, "DT_GETPAGE: dtree page corrupt");\ 136 MP = NULL;\ 137 RC = -EIO;\ 138 }\ 139 }\ 140 } 141 142 /* for consistency */ 143 #define DT_PUTPAGE(MP) BT_PUTPAGE(MP) 144 145 #define DT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \ 146 BT_GETSEARCH(IP, LEAF, BN, MP, dtpage_t, P, INDEX, i_dtroot) 147 148 /* 149 * forward references 150 */ 151 static int dtSplitUp(tid_t tid, struct inode *ip, 152 struct dtsplit * split, struct btstack * btstack); 153 154 static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, 155 struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rxdp); 156 157 static int dtExtendPage(tid_t tid, struct inode *ip, 158 struct dtsplit * split, struct btstack * btstack); 159 160 static int dtSplitRoot(tid_t tid, struct inode *ip, 161 struct dtsplit * split, struct metapage ** rmpp); 162 163 static int dtDeleteUp(tid_t tid, struct inode *ip, struct metapage * fmp, 164 dtpage_t * fp, struct btstack * btstack); 165 166 static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p); 167 168 static int dtReadFirst(struct inode *ip, struct btstack * btstack); 169 170 static int dtReadNext(struct inode *ip, 171 loff_t * offset, struct btstack * btstack); 172 173 static int dtCompare(struct component_name * key, dtpage_t * p, int si); 174 175 static int ciCompare(struct component_name * key, dtpage_t * p, int si, 176 int flag); 177 178 static void dtGetKey(dtpage_t * p, int i, struct component_name * key, 179 int flag); 180 181 static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, 182 int ri, struct component_name * key, int flag); 183 184 static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key, 185 ddata_t * data, struct dt_lock **); 186 187 static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp, 188 struct dt_lock ** sdtlock, struct dt_lock ** ddtlock, 189 int do_index); 190 191 static void dtDeleteEntry(dtpage_t * p, int fi, struct dt_lock ** dtlock); 192 193 static void dtTruncateEntry(dtpage_t * p, int ti, struct dt_lock ** dtlock); 194 195 static void dtLinelockFreelist(dtpage_t * p, int m, struct dt_lock ** dtlock); 196 197 #define ciToUpper(c) UniStrupr((c)->name) 198 199 /* 200 * read_index_page() 201 * 202 * Reads a page of a directory's index table. 203 * Having metadata mapped into the directory inode's address space 204 * presents a multitude of problems. We avoid this by mapping to 205 * the absolute address space outside of the *_metapage routines 206 */ 207 static struct metapage *read_index_page(struct inode *inode, s64 blkno) 208 { 209 int rc; 210 s64 xaddr; 211 int xflag; 212 s32 xlen; 213 214 rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); 215 if (rc || (xaddr == 0)) 216 return NULL; 217 218 return read_metapage(inode, xaddr, PSIZE, 1); 219 } 220 221 /* 222 * get_index_page() 223 * 224 * Same as get_index_page(), but get's a new page without reading 225 */ 226 static struct metapage *get_index_page(struct inode *inode, s64 blkno) 227 { 228 int rc; 229 s64 xaddr; 230 int xflag; 231 s32 xlen; 232 233 rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); 234 if (rc || (xaddr == 0)) 235 return NULL; 236 237 return get_metapage(inode, xaddr, PSIZE, 1); 238 } 239 240 /* 241 * find_index() 242 * 243 * Returns dtree page containing directory table entry for specified 244 * index and pointer to its entry. 245 * 246 * mp must be released by caller. 247 */ 248 static struct dir_table_slot *find_index(struct inode *ip, u32 index, 249 struct metapage ** mp, s64 *lblock) 250 { 251 struct jfs_inode_info *jfs_ip = JFS_IP(ip); 252 s64 blkno; 253 s64 offset; 254 int page_offset; 255 struct dir_table_slot *slot; 256 static int maxWarnings = 10; 257 258 if (index < 2) { 259 if (maxWarnings) { 260 jfs_warn("find_entry called with index = %d", index); 261 maxWarnings--; 262 } 263 return NULL; 264 } 265 266 if (index >= jfs_ip->next_index) { 267 jfs_warn("find_entry called with index >= next_index"); 268 return NULL; 269 } 270 271 if (jfs_dirtable_inline(ip)) { 272 /* 273 * Inline directory table 274 */ 275 *mp = NULL; 276 slot = &jfs_ip->i_dirtable[index - 2]; 277 } else { 278 offset = (index - 2) * sizeof(struct dir_table_slot); 279 page_offset = offset & (PSIZE - 1); 280 blkno = ((offset + 1) >> L2PSIZE) << 281 JFS_SBI(ip->i_sb)->l2nbperpage; 282 283 if (*mp && (*lblock != blkno)) { 284 release_metapage(*mp); 285 *mp = NULL; 286 } 287 if (!(*mp)) { 288 *lblock = blkno; 289 *mp = read_index_page(ip, blkno); 290 } 291 if (!(*mp)) { 292 jfs_err("free_index: error reading directory table"); 293 return NULL; 294 } 295 296 slot = 297 (struct dir_table_slot *) ((char *) (*mp)->data + 298 page_offset); 299 } 300 return slot; 301 } 302 303 static inline void lock_index(tid_t tid, struct inode *ip, struct metapage * mp, 304 u32 index) 305 { 306 struct tlock *tlck; 307 struct linelock *llck; 308 struct lv *lv; 309 310 tlck = txLock(tid, ip, mp, tlckDATA); 311 llck = (struct linelock *) tlck->lock; 312 313 if (llck->index >= llck->maxcnt) 314 llck = txLinelock(llck); 315 lv = &llck->lv[llck->index]; 316 317 /* 318 * Linelock slot size is twice the size of directory table 319 * slot size. 512 entries per page. 320 */ 321 lv->offset = ((index - 2) & 511) >> 1; 322 lv->length = 1; 323 llck->index++; 324 } 325 326 /* 327 * add_index() 328 * 329 * Adds an entry to the directory index table. This is used to provide 330 * each directory entry with a persistent index in which to resume 331 * directory traversals 332 */ 333 static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) 334 { 335 struct super_block *sb = ip->i_sb; 336 struct jfs_sb_info *sbi = JFS_SBI(sb); 337 struct jfs_inode_info *jfs_ip = JFS_IP(ip); 338 u64 blkno; 339 struct dir_table_slot *dirtab_slot; 340 u32 index; 341 struct linelock *llck; 342 struct lv *lv; 343 struct metapage *mp; 344 s64 offset; 345 uint page_offset; 346 struct tlock *tlck; 347 s64 xaddr; 348 349 ASSERT(DO_INDEX(ip)); 350 351 if (jfs_ip->next_index < 2) { 352 jfs_warn("add_index: next_index = %d. Resetting!", 353 jfs_ip->next_index); 354 jfs_ip->next_index = 2; 355 } 356 357 index = jfs_ip->next_index++; 358 359 if (index <= MAX_INLINE_DIRTABLE_ENTRY) { 360 /* 361 * i_size reflects size of index table, or 8 bytes per entry. 362 */ 363 ip->i_size = (loff_t) (index - 1) << 3; 364 365 /* 366 * dir table fits inline within inode 367 */ 368 dirtab_slot = &jfs_ip->i_dirtable[index-2]; 369 dirtab_slot->flag = DIR_INDEX_VALID; 370 dirtab_slot->slot = slot; 371 DTSaddress(dirtab_slot, bn); 372 373 set_cflag(COMMIT_Dirtable, ip); 374 375 return index; 376 } 377 if (index == (MAX_INLINE_DIRTABLE_ENTRY + 1)) { 378 struct dir_table_slot temp_table[12]; 379 380 /* 381 * It's time to move the inline table to an external 382 * page and begin to build the xtree 383 */ 384 if (dquot_alloc_block(ip, sbi->nbperpage)) 385 goto clean_up; 386 if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { 387 dquot_free_block(ip, sbi->nbperpage); 388 goto clean_up; 389 } 390 391 /* 392 * Save the table, we're going to overwrite it with the 393 * xtree root 394 */ 395 memcpy(temp_table, &jfs_ip->i_dirtable, sizeof(temp_table)); 396 397 /* 398 * Initialize empty x-tree 399 */ 400 xtInitRoot(tid, ip); 401 402 /* 403 * Add the first block to the xtree 404 */ 405 if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) { 406 /* This really shouldn't fail */ 407 jfs_warn("add_index: xtInsert failed!"); 408 memcpy(&jfs_ip->i_dirtable, temp_table, 409 sizeof (temp_table)); 410 dbFree(ip, xaddr, sbi->nbperpage); 411 dquot_free_block(ip, sbi->nbperpage); 412 goto clean_up; 413 } 414 ip->i_size = PSIZE; 415 416 mp = get_index_page(ip, 0); 417 if (!mp) { 418 jfs_err("add_index: get_metapage failed!"); 419 xtTruncate(tid, ip, 0, COMMIT_PWMAP); 420 memcpy(&jfs_ip->i_dirtable, temp_table, 421 sizeof (temp_table)); 422 goto clean_up; 423 } 424 tlck = txLock(tid, ip, mp, tlckDATA); 425 llck = (struct linelock *) & tlck->lock; 426 ASSERT(llck->index == 0); 427 lv = &llck->lv[0]; 428 429 lv->offset = 0; 430 lv->length = 6; /* tlckDATA slot size is 16 bytes */ 431 llck->index++; 432 433 memcpy(mp->data, temp_table, sizeof(temp_table)); 434 435 mark_metapage_dirty(mp); 436 release_metapage(mp); 437 438 /* 439 * Logging is now directed by xtree tlocks 440 */ 441 clear_cflag(COMMIT_Dirtable, ip); 442 } 443 444 offset = (index - 2) * sizeof(struct dir_table_slot); 445 page_offset = offset & (PSIZE - 1); 446 blkno = ((offset + 1) >> L2PSIZE) << sbi->l2nbperpage; 447 if (page_offset == 0) { 448 /* 449 * This will be the beginning of a new page 450 */ 451 xaddr = 0; 452 if (xtInsert(tid, ip, 0, blkno, sbi->nbperpage, &xaddr, 0)) { 453 jfs_warn("add_index: xtInsert failed!"); 454 goto clean_up; 455 } 456 ip->i_size += PSIZE; 457 458 if ((mp = get_index_page(ip, blkno))) 459 memset(mp->data, 0, PSIZE); /* Just looks better */ 460 else 461 xtTruncate(tid, ip, offset, COMMIT_PWMAP); 462 } else 463 mp = read_index_page(ip, blkno); 464 465 if (!mp) { 466 jfs_err("add_index: get/read_metapage failed!"); 467 goto clean_up; 468 } 469 470 lock_index(tid, ip, mp, index); 471 472 dirtab_slot = 473 (struct dir_table_slot *) ((char *) mp->data + page_offset); 474 dirtab_slot->flag = DIR_INDEX_VALID; 475 dirtab_slot->slot = slot; 476 DTSaddress(dirtab_slot, bn); 477 478 mark_metapage_dirty(mp); 479 release_metapage(mp); 480 481 return index; 482 483 clean_up: 484 485 jfs_ip->next_index--; 486 487 return 0; 488 } 489 490 /* 491 * free_index() 492 * 493 * Marks an entry to the directory index table as free. 494 */ 495 static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next) 496 { 497 struct dir_table_slot *dirtab_slot; 498 s64 lblock; 499 struct metapage *mp = NULL; 500 501 dirtab_slot = find_index(ip, index, &mp, &lblock); 502 503 if (!dirtab_slot) 504 return; 505 506 dirtab_slot->flag = DIR_INDEX_FREE; 507 dirtab_slot->slot = dirtab_slot->addr1 = 0; 508 dirtab_slot->addr2 = cpu_to_le32(next); 509 510 if (mp) { 511 lock_index(tid, ip, mp, index); 512 mark_metapage_dirty(mp); 513 release_metapage(mp); 514 } else 515 set_cflag(COMMIT_Dirtable, ip); 516 } 517 518 /* 519 * modify_index() 520 * 521 * Changes an entry in the directory index table 522 */ 523 static void modify_index(tid_t tid, struct inode *ip, u32 index, s64 bn, 524 int slot, struct metapage ** mp, s64 *lblock) 525 { 526 struct dir_table_slot *dirtab_slot; 527 528 dirtab_slot = find_index(ip, index, mp, lblock); 529 530 if (!dirtab_slot) 531 return; 532 533 DTSaddress(dirtab_slot, bn); 534 dirtab_slot->slot = slot; 535 536 if (*mp) { 537 lock_index(tid, ip, *mp, index); 538 mark_metapage_dirty(*mp); 539 } else 540 set_cflag(COMMIT_Dirtable, ip); 541 } 542 543 /* 544 * read_index() 545 * 546 * reads a directory table slot 547 */ 548 static int read_index(struct inode *ip, u32 index, 549 struct dir_table_slot * dirtab_slot) 550 { 551 s64 lblock; 552 struct metapage *mp = NULL; 553 struct dir_table_slot *slot; 554 555 slot = find_index(ip, index, &mp, &lblock); 556 if (!slot) { 557 return -EIO; 558 } 559 560 memcpy(dirtab_slot, slot, sizeof(struct dir_table_slot)); 561 562 if (mp) 563 release_metapage(mp); 564 565 return 0; 566 } 567 568 /* 569 * dtSearch() 570 * 571 * function: 572 * Search for the entry with specified key 573 * 574 * parameter: 575 * 576 * return: 0 - search result on stack, leaf page pinned; 577 * errno - I/O error 578 */ 579 int dtSearch(struct inode *ip, struct component_name * key, ino_t * data, 580 struct btstack * btstack, int flag) 581 { 582 int rc = 0; 583 int cmp = 1; /* init for empty page */ 584 s64 bn; 585 struct metapage *mp; 586 dtpage_t *p; 587 s8 *stbl; 588 int base, index, lim; 589 struct btframe *btsp; 590 pxd_t *pxd; 591 int psize = 288; /* initial in-line directory */ 592 ino_t inumber; 593 struct component_name ciKey; 594 struct super_block *sb = ip->i_sb; 595 596 ciKey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), GFP_NOFS); 597 if (!ciKey.name) { 598 rc = -ENOMEM; 599 goto dtSearch_Exit2; 600 } 601 602 603 /* uppercase search key for c-i directory */ 604 UniStrcpy(ciKey.name, key->name); 605 ciKey.namlen = key->namlen; 606 607 /* only uppercase if case-insensitive support is on */ 608 if ((JFS_SBI(sb)->mntflag & JFS_OS2) == JFS_OS2) { 609 ciToUpper(&ciKey); 610 } 611 BT_CLR(btstack); /* reset stack */ 612 613 /* init level count for max pages to split */ 614 btstack->nsplit = 1; 615 616 /* 617 * search down tree from root: 618 * 619 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of 620 * internal page, child page Pi contains entry with k, Ki <= K < Kj. 621 * 622 * if entry with search key K is not found 623 * internal page search find the entry with largest key Ki 624 * less than K which point to the child page to search; 625 * leaf page search find the entry with smallest key Kj 626 * greater than K so that the returned index is the position of 627 * the entry to be shifted right for insertion of new entry. 628 * for empty tree, search key is greater than any key of the tree. 629 * 630 * by convention, root bn = 0. 631 */ 632 for (bn = 0;;) { 633 /* get/pin the page to search */ 634 DT_GETPAGE(ip, bn, mp, psize, p, rc); 635 if (rc) 636 goto dtSearch_Exit1; 637 638 /* get sorted entry table of the page */ 639 stbl = DT_GETSTBL(p); 640 641 /* 642 * binary search with search key K on the current page. 643 */ 644 for (base = 0, lim = p->header.nextindex; lim; lim >>= 1) { 645 index = base + (lim >> 1); 646 647 if (p->header.flag & BT_LEAF) { 648 /* uppercase leaf name to compare */ 649 cmp = 650 ciCompare(&ciKey, p, stbl[index], 651 JFS_SBI(sb)->mntflag); 652 } else { 653 /* router key is in uppercase */ 654 655 cmp = dtCompare(&ciKey, p, stbl[index]); 656 657 658 } 659 if (cmp == 0) { 660 /* 661 * search hit 662 */ 663 /* search hit - leaf page: 664 * return the entry found 665 */ 666 if (p->header.flag & BT_LEAF) { 667 inumber = le32_to_cpu( 668 ((struct ldtentry *) & p->slot[stbl[index]])->inumber); 669 670 /* 671 * search for JFS_LOOKUP 672 */ 673 if (flag == JFS_LOOKUP) { 674 *data = inumber; 675 rc = 0; 676 goto out; 677 } 678 679 /* 680 * search for JFS_CREATE 681 */ 682 if (flag == JFS_CREATE) { 683 *data = inumber; 684 rc = -EEXIST; 685 goto out; 686 } 687 688 /* 689 * search for JFS_REMOVE or JFS_RENAME 690 */ 691 if ((flag == JFS_REMOVE || 692 flag == JFS_RENAME) && 693 *data != inumber) { 694 rc = -ESTALE; 695 goto out; 696 } 697 698 /* 699 * JFS_REMOVE|JFS_FINDDIR|JFS_RENAME 700 */ 701 /* save search result */ 702 *data = inumber; 703 btsp = btstack->top; 704 btsp->bn = bn; 705 btsp->index = index; 706 btsp->mp = mp; 707 708 rc = 0; 709 goto dtSearch_Exit1; 710 } 711 712 /* search hit - internal page: 713 * descend/search its child page 714 */ 715 goto getChild; 716 } 717 718 if (cmp > 0) { 719 base = index + 1; 720 --lim; 721 } 722 } 723 724 /* 725 * search miss 726 * 727 * base is the smallest index with key (Kj) greater than 728 * search key (K) and may be zero or (maxindex + 1) index. 729 */ 730 /* 731 * search miss - leaf page 732 * 733 * return location of entry (base) where new entry with 734 * search key K is to be inserted. 735 */ 736 if (p->header.flag & BT_LEAF) { 737 /* 738 * search for JFS_LOOKUP, JFS_REMOVE, or JFS_RENAME 739 */ 740 if (flag == JFS_LOOKUP || flag == JFS_REMOVE || 741 flag == JFS_RENAME) { 742 rc = -ENOENT; 743 goto out; 744 } 745 746 /* 747 * search for JFS_CREATE|JFS_FINDDIR: 748 * 749 * save search result 750 */ 751 *data = 0; 752 btsp = btstack->top; 753 btsp->bn = bn; 754 btsp->index = base; 755 btsp->mp = mp; 756 757 rc = 0; 758 goto dtSearch_Exit1; 759 } 760 761 /* 762 * search miss - internal page 763 * 764 * if base is non-zero, decrement base by one to get the parent 765 * entry of the child page to search. 766 */ 767 index = base ? base - 1 : base; 768 769 /* 770 * go down to child page 771 */ 772 getChild: 773 /* update max. number of pages to split */ 774 if (BT_STACK_FULL(btstack)) { 775 /* Something's corrupted, mark filesystem dirty so 776 * chkdsk will fix it. 777 */ 778 jfs_error(sb, "stack overrun in dtSearch!"); 779 BT_STACK_DUMP(btstack); 780 rc = -EIO; 781 goto out; 782 } 783 btstack->nsplit++; 784 785 /* push (bn, index) of the parent page/entry */ 786 BT_PUSH(btstack, bn, index); 787 788 /* get the child page block number */ 789 pxd = (pxd_t *) & p->slot[stbl[index]]; 790 bn = addressPXD(pxd); 791 psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize; 792 793 /* unpin the parent page */ 794 DT_PUTPAGE(mp); 795 } 796 797 out: 798 DT_PUTPAGE(mp); 799 800 dtSearch_Exit1: 801 802 kfree(ciKey.name); 803 804 dtSearch_Exit2: 805 806 return rc; 807 } 808 809 810 /* 811 * dtInsert() 812 * 813 * function: insert an entry to directory tree 814 * 815 * parameter: 816 * 817 * return: 0 - success; 818 * errno - failure; 819 */ 820 int dtInsert(tid_t tid, struct inode *ip, 821 struct component_name * name, ino_t * fsn, struct btstack * btstack) 822 { 823 int rc = 0; 824 struct metapage *mp; /* meta-page buffer */ 825 dtpage_t *p; /* base B+-tree index page */ 826 s64 bn; 827 int index; 828 struct dtsplit split; /* split information */ 829 ddata_t data; 830 struct dt_lock *dtlck; 831 int n; 832 struct tlock *tlck; 833 struct lv *lv; 834 835 /* 836 * retrieve search result 837 * 838 * dtSearch() returns (leaf page pinned, index at which to insert). 839 * n.b. dtSearch() may return index of (maxindex + 1) of 840 * the full page. 841 */ 842 DT_GETSEARCH(ip, btstack->top, bn, mp, p, index); 843 844 /* 845 * insert entry for new key 846 */ 847 if (DO_INDEX(ip)) { 848 if (JFS_IP(ip)->next_index == DIREND) { 849 DT_PUTPAGE(mp); 850 return -EMLINK; 851 } 852 n = NDTLEAF(name->namlen); 853 data.leaf.tid = tid; 854 data.leaf.ip = ip; 855 } else { 856 n = NDTLEAF_LEGACY(name->namlen); 857 data.leaf.ip = NULL; /* signifies legacy directory format */ 858 } 859 data.leaf.ino = *fsn; 860 861 /* 862 * leaf page does not have enough room for new entry: 863 * 864 * extend/split the leaf page; 865 * 866 * dtSplitUp() will insert the entry and unpin the leaf page. 867 */ 868 if (n > p->header.freecnt) { 869 split.mp = mp; 870 split.index = index; 871 split.nslot = n; 872 split.key = name; 873 split.data = &data; 874 rc = dtSplitUp(tid, ip, &split, btstack); 875 return rc; 876 } 877 878 /* 879 * leaf page does have enough room for new entry: 880 * 881 * insert the new data entry into the leaf page; 882 */ 883 BT_MARK_DIRTY(mp, ip); 884 /* 885 * acquire a transaction lock on the leaf page 886 */ 887 tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); 888 dtlck = (struct dt_lock *) & tlck->lock; 889 ASSERT(dtlck->index == 0); 890 lv = & dtlck->lv[0]; 891 892 /* linelock header */ 893 lv->offset = 0; 894 lv->length = 1; 895 dtlck->index++; 896 897 dtInsertEntry(p, index, name, &data, &dtlck); 898 899 /* linelock stbl of non-root leaf page */ 900 if (!(p->header.flag & BT_ROOT)) { 901 if (dtlck->index >= dtlck->maxcnt) 902 dtlck = (struct dt_lock *) txLinelock(dtlck); 903 lv = & dtlck->lv[dtlck->index]; 904 n = index >> L2DTSLOTSIZE; 905 lv->offset = p->header.stblindex + n; 906 lv->length = 907 ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1; 908 dtlck->index++; 909 } 910 911 /* unpin the leaf page */ 912 DT_PUTPAGE(mp); 913 914 return 0; 915 } 916 917 918 /* 919 * dtSplitUp() 920 * 921 * function: propagate insertion bottom up; 922 * 923 * parameter: 924 * 925 * return: 0 - success; 926 * errno - failure; 927 * leaf page unpinned; 928 */ 929 static int dtSplitUp(tid_t tid, 930 struct inode *ip, struct dtsplit * split, struct btstack * btstack) 931 { 932 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); 933 int rc = 0; 934 struct metapage *smp; 935 dtpage_t *sp; /* split page */ 936 struct metapage *rmp; 937 dtpage_t *rp; /* new right page split from sp */ 938 pxd_t rpxd; /* new right page extent descriptor */ 939 struct metapage *lmp; 940 dtpage_t *lp; /* left child page */ 941 int skip; /* index of entry of insertion */ 942 struct btframe *parent; /* parent page entry on traverse stack */ 943 s64 xaddr, nxaddr; 944 int xlen, xsize; 945 struct pxdlist pxdlist; 946 pxd_t *pxd; 947 struct component_name key = { 0, NULL }; 948 ddata_t *data = split->data; 949 int n; 950 struct dt_lock *dtlck; 951 struct tlock *tlck; 952 struct lv *lv; 953 int quota_allocation = 0; 954 955 /* get split page */ 956 smp = split->mp; 957 sp = DT_PAGE(ip, smp); 958 959 key.name = kmalloc((JFS_NAME_MAX + 2) * sizeof(wchar_t), GFP_NOFS); 960 if (!key.name) { 961 DT_PUTPAGE(smp); 962 rc = -ENOMEM; 963 goto dtSplitUp_Exit; 964 } 965 966 /* 967 * split leaf page 968 * 969 * The split routines insert the new entry, and 970 * acquire txLock as appropriate. 971 */ 972 /* 973 * split root leaf page: 974 */ 975 if (sp->header.flag & BT_ROOT) { 976 /* 977 * allocate a single extent child page 978 */ 979 xlen = 1; 980 n = sbi->bsize >> L2DTSLOTSIZE; 981 n -= (n + 31) >> L2DTSLOTSIZE; /* stbl size */ 982 n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */ 983 if (n <= split->nslot) 984 xlen++; 985 if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) { 986 DT_PUTPAGE(smp); 987 goto freeKeyName; 988 } 989 990 pxdlist.maxnpxd = 1; 991 pxdlist.npxd = 0; 992 pxd = &pxdlist.pxd[0]; 993 PXDaddress(pxd, xaddr); 994 PXDlength(pxd, xlen); 995 split->pxdlist = &pxdlist; 996 rc = dtSplitRoot(tid, ip, split, &rmp); 997 998 if (rc) 999 dbFree(ip, xaddr, xlen); 1000 else 1001 DT_PUTPAGE(rmp); 1002 1003 DT_PUTPAGE(smp); 1004 1005 if (!DO_INDEX(ip)) 1006 ip->i_size = xlen << sbi->l2bsize; 1007 1008 goto freeKeyName; 1009 } 1010 1011 /* 1012 * extend first leaf page 1013 * 1014 * extend the 1st extent if less than buffer page size 1015 * (dtExtendPage() reurns leaf page unpinned) 1016 */ 1017 pxd = &sp->header.self; 1018 xlen = lengthPXD(pxd); 1019 xsize = xlen << sbi->l2bsize; 1020 if (xsize < PSIZE) { 1021 xaddr = addressPXD(pxd); 1022 n = xsize >> L2DTSLOTSIZE; 1023 n -= (n + 31) >> L2DTSLOTSIZE; /* stbl size */ 1024 if ((n + sp->header.freecnt) <= split->nslot) 1025 n = xlen + (xlen << 1); 1026 else 1027 n = xlen; 1028 1029 /* Allocate blocks to quota. */ 1030 rc = dquot_alloc_block(ip, n); 1031 if (rc) 1032 goto extendOut; 1033 quota_allocation += n; 1034 1035 if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen, 1036 (s64) n, &nxaddr))) 1037 goto extendOut; 1038 1039 pxdlist.maxnpxd = 1; 1040 pxdlist.npxd = 0; 1041 pxd = &pxdlist.pxd[0]; 1042 PXDaddress(pxd, nxaddr) 1043 PXDlength(pxd, xlen + n); 1044 split->pxdlist = &pxdlist; 1045 if ((rc = dtExtendPage(tid, ip, split, btstack))) { 1046 nxaddr = addressPXD(pxd); 1047 if (xaddr != nxaddr) { 1048 /* free relocated extent */ 1049 xlen = lengthPXD(pxd); 1050 dbFree(ip, nxaddr, (s64) xlen); 1051 } else { 1052 /* free extended delta */ 1053 xlen = lengthPXD(pxd) - n; 1054 xaddr = addressPXD(pxd) + xlen; 1055 dbFree(ip, xaddr, (s64) n); 1056 } 1057 } else if (!DO_INDEX(ip)) 1058 ip->i_size = lengthPXD(pxd) << sbi->l2bsize; 1059 1060 1061 extendOut: 1062 DT_PUTPAGE(smp); 1063 goto freeKeyName; 1064 } 1065 1066 /* 1067 * split leaf page <sp> into <sp> and a new right page <rp>. 1068 * 1069 * return <rp> pinned and its extent descriptor <rpxd> 1070 */ 1071 /* 1072 * allocate new directory page extent and 1073 * new index page(s) to cover page split(s) 1074 * 1075 * allocation hint: ? 1076 */ 1077 n = btstack->nsplit; 1078 pxdlist.maxnpxd = pxdlist.npxd = 0; 1079 xlen = sbi->nbperpage; 1080 for (pxd = pxdlist.pxd; n > 0; n--, pxd++) { 1081 if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)) == 0) { 1082 PXDaddress(pxd, xaddr); 1083 PXDlength(pxd, xlen); 1084 pxdlist.maxnpxd++; 1085 continue; 1086 } 1087 1088 DT_PUTPAGE(smp); 1089 1090 /* undo allocation */ 1091 goto splitOut; 1092 } 1093 1094 split->pxdlist = &pxdlist; 1095 if ((rc = dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd))) { 1096 DT_PUTPAGE(smp); 1097 1098 /* undo allocation */ 1099 goto splitOut; 1100 } 1101 1102 if (!DO_INDEX(ip)) 1103 ip->i_size += PSIZE; 1104 1105 /* 1106 * propagate up the router entry for the leaf page just split 1107 * 1108 * insert a router entry for the new page into the parent page, 1109 * propagate the insert/split up the tree by walking back the stack 1110 * of (bn of parent page, index of child page entry in parent page) 1111 * that were traversed during the search for the page that split. 1112 * 1113 * the propagation of insert/split up the tree stops if the root 1114 * splits or the page inserted into doesn't have to split to hold 1115 * the new entry. 1116 * 1117 * the parent entry for the split page remains the same, and 1118 * a new entry is inserted at its right with the first key and 1119 * block number of the new right page. 1120 * 1121 * There are a maximum of 4 pages pinned at any time: 1122 * two children, left parent and right parent (when the parent splits). 1123 * keep the child pages pinned while working on the parent. 1124 * make sure that all pins are released at exit. 1125 */ 1126 while ((parent = BT_POP(btstack)) != NULL) { 1127 /* parent page specified by stack frame <parent> */ 1128 1129 /* keep current child pages (<lp>, <rp>) pinned */ 1130 lmp = smp; 1131 lp = sp; 1132 1133 /* 1134 * insert router entry in parent for new right child page <rp> 1135 */ 1136 /* get the parent page <sp> */ 1137 DT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc); 1138 if (rc) { 1139 DT_PUTPAGE(lmp); 1140 DT_PUTPAGE(rmp); 1141 goto splitOut; 1142 } 1143 1144 /* 1145 * The new key entry goes ONE AFTER the index of parent entry, 1146 * because the split was to the right. 1147 */ 1148 skip = parent->index + 1; 1149 1150 /* 1151 * compute the key for the router entry 1152 * 1153 * key suffix compression: 1154 * for internal pages that have leaf pages as children, 1155 * retain only what's needed to distinguish between 1156 * the new entry and the entry on the page to its left. 1157 * If the keys compare equal, retain the entire key. 1158 * 1159 * note that compression is performed only at computing 1160 * router key at the lowest internal level. 1161 * further compression of the key between pairs of higher 1162 * level internal pages loses too much information and 1163 * the search may fail. 1164 * (e.g., two adjacent leaf pages of {a, ..., x} {xx, ...,} 1165 * results in two adjacent parent entries (a)(xx). 1166 * if split occurs between these two entries, and 1167 * if compression is applied, the router key of parent entry 1168 * of right page (x) will divert search for x into right 1169 * subtree and miss x in the left subtree.) 1170 * 1171 * the entire key must be retained for the next-to-leftmost 1172 * internal key at any level of the tree, or search may fail 1173 * (e.g., ?) 1174 */ 1175 switch (rp->header.flag & BT_TYPE) { 1176 case BT_LEAF: 1177 /* 1178 * compute the length of prefix for suffix compression 1179 * between last entry of left page and first entry 1180 * of right page 1181 */ 1182 if ((sp->header.flag & BT_ROOT && skip > 1) || 1183 sp->header.prev != 0 || skip > 1) { 1184 /* compute uppercase router prefix key */ 1185 rc = ciGetLeafPrefixKey(lp, 1186 lp->header.nextindex-1, 1187 rp, 0, &key, 1188 sbi->mntflag); 1189 if (rc) { 1190 DT_PUTPAGE(lmp); 1191 DT_PUTPAGE(rmp); 1192 DT_PUTPAGE(smp); 1193 goto splitOut; 1194 } 1195 } else { 1196 /* next to leftmost entry of 1197 lowest internal level */ 1198 1199 /* compute uppercase router key */ 1200 dtGetKey(rp, 0, &key, sbi->mntflag); 1201 key.name[key.namlen] = 0; 1202 1203 if ((sbi->mntflag & JFS_OS2) == JFS_OS2) 1204 ciToUpper(&key); 1205 } 1206 1207 n = NDTINTERNAL(key.namlen); 1208 break; 1209 1210 case BT_INTERNAL: 1211 dtGetKey(rp, 0, &key, sbi->mntflag); 1212 n = NDTINTERNAL(key.namlen); 1213 break; 1214 1215 default: 1216 jfs_err("dtSplitUp(): UFO!"); 1217 break; 1218 } 1219 1220 /* unpin left child page */ 1221 DT_PUTPAGE(lmp); 1222 1223 /* 1224 * compute the data for the router entry 1225 */ 1226 data->xd = rpxd; /* child page xd */ 1227 1228 /* 1229 * parent page is full - split the parent page 1230 */ 1231 if (n > sp->header.freecnt) { 1232 /* init for parent page split */ 1233 split->mp = smp; 1234 split->index = skip; /* index at insert */ 1235 split->nslot = n; 1236 split->key = &key; 1237 /* split->data = data; */ 1238 1239 /* unpin right child page */ 1240 DT_PUTPAGE(rmp); 1241 1242 /* The split routines insert the new entry, 1243 * acquire txLock as appropriate. 1244 * return <rp> pinned and its block number <rbn>. 1245 */ 1246 rc = (sp->header.flag & BT_ROOT) ? 1247 dtSplitRoot(tid, ip, split, &rmp) : 1248 dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd); 1249 if (rc) { 1250 DT_PUTPAGE(smp); 1251 goto splitOut; 1252 } 1253 1254 /* smp and rmp are pinned */ 1255 } 1256 /* 1257 * parent page is not full - insert router entry in parent page 1258 */ 1259 else { 1260 BT_MARK_DIRTY(smp, ip); 1261 /* 1262 * acquire a transaction lock on the parent page 1263 */ 1264 tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY); 1265 dtlck = (struct dt_lock *) & tlck->lock; 1266 ASSERT(dtlck->index == 0); 1267 lv = & dtlck->lv[0]; 1268 1269 /* linelock header */ 1270 lv->offset = 0; 1271 lv->length = 1; 1272 dtlck->index++; 1273 1274 /* linelock stbl of non-root parent page */ 1275 if (!(sp->header.flag & BT_ROOT)) { 1276 lv++; 1277 n = skip >> L2DTSLOTSIZE; 1278 lv->offset = sp->header.stblindex + n; 1279 lv->length = 1280 ((sp->header.nextindex - 1281 1) >> L2DTSLOTSIZE) - n + 1; 1282 dtlck->index++; 1283 } 1284 1285 dtInsertEntry(sp, skip, &key, data, &dtlck); 1286 1287 /* exit propagate up */ 1288 break; 1289 } 1290 } 1291 1292 /* unpin current split and its right page */ 1293 DT_PUTPAGE(smp); 1294 DT_PUTPAGE(rmp); 1295 1296 /* 1297 * free remaining extents allocated for split 1298 */ 1299 splitOut: 1300 n = pxdlist.npxd; 1301 pxd = &pxdlist.pxd[n]; 1302 for (; n < pxdlist.maxnpxd; n++, pxd++) 1303 dbFree(ip, addressPXD(pxd), (s64) lengthPXD(pxd)); 1304 1305 freeKeyName: 1306 kfree(key.name); 1307 1308 /* Rollback quota allocation */ 1309 if (rc && quota_allocation) 1310 dquot_free_block(ip, quota_allocation); 1311 1312 dtSplitUp_Exit: 1313 1314 return rc; 1315 } 1316 1317 1318 /* 1319 * dtSplitPage() 1320 * 1321 * function: Split a non-root page of a btree. 1322 * 1323 * parameter: 1324 * 1325 * return: 0 - success; 1326 * errno - failure; 1327 * return split and new page pinned; 1328 */ 1329 static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, 1330 struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp) 1331 { 1332 int rc = 0; 1333 struct metapage *smp; 1334 dtpage_t *sp; 1335 struct metapage *rmp; 1336 dtpage_t *rp; /* new right page allocated */ 1337 s64 rbn; /* new right page block number */ 1338 struct metapage *mp; 1339 dtpage_t *p; 1340 s64 nextbn; 1341 struct pxdlist *pxdlist; 1342 pxd_t *pxd; 1343 int skip, nextindex, half, left, nxt, off, si; 1344 struct ldtentry *ldtentry; 1345 struct idtentry *idtentry; 1346 u8 *stbl; 1347 struct dtslot *f; 1348 int fsi, stblsize; 1349 int n; 1350 struct dt_lock *sdtlck, *rdtlck; 1351 struct tlock *tlck; 1352 struct dt_lock *dtlck; 1353 struct lv *slv, *rlv, *lv; 1354 1355 /* get split page */ 1356 smp = split->mp; 1357 sp = DT_PAGE(ip, smp); 1358 1359 /* 1360 * allocate the new right page for the split 1361 */ 1362 pxdlist = split->pxdlist; 1363 pxd = &pxdlist->pxd[pxdlist->npxd]; 1364 pxdlist->npxd++; 1365 rbn = addressPXD(pxd); 1366 rmp = get_metapage(ip, rbn, PSIZE, 1); 1367 if (rmp == NULL) 1368 return -EIO; 1369 1370 /* Allocate blocks to quota. */ 1371 rc = dquot_alloc_block(ip, lengthPXD(pxd)); 1372 if (rc) { 1373 release_metapage(rmp); 1374 return rc; 1375 } 1376 1377 jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); 1378 1379 BT_MARK_DIRTY(rmp, ip); 1380 /* 1381 * acquire a transaction lock on the new right page 1382 */ 1383 tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW); 1384 rdtlck = (struct dt_lock *) & tlck->lock; 1385 1386 rp = (dtpage_t *) rmp->data; 1387 *rpp = rp; 1388 rp->header.self = *pxd; 1389 1390 BT_MARK_DIRTY(smp, ip); 1391 /* 1392 * acquire a transaction lock on the split page 1393 * 1394 * action: 1395 */ 1396 tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY); 1397 sdtlck = (struct dt_lock *) & tlck->lock; 1398 1399 /* linelock header of split page */ 1400 ASSERT(sdtlck->index == 0); 1401 slv = & sdtlck->lv[0]; 1402 slv->offset = 0; 1403 slv->length = 1; 1404 sdtlck->index++; 1405 1406 /* 1407 * initialize/update sibling pointers between sp and rp 1408 */ 1409 nextbn = le64_to_cpu(sp->header.next); 1410 rp->header.next = cpu_to_le64(nextbn); 1411 rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self)); 1412 sp->header.next = cpu_to_le64(rbn); 1413 1414 /* 1415 * initialize new right page 1416 */ 1417 rp->header.flag = sp->header.flag; 1418 1419 /* compute sorted entry table at start of extent data area */ 1420 rp->header.nextindex = 0; 1421 rp->header.stblindex = 1; 1422 1423 n = PSIZE >> L2DTSLOTSIZE; 1424 rp->header.maxslot = n; 1425 stblsize = (n + 31) >> L2DTSLOTSIZE; /* in unit of slot */ 1426 1427 /* init freelist */ 1428 fsi = rp->header.stblindex + stblsize; 1429 rp->header.freelist = fsi; 1430 rp->header.freecnt = rp->header.maxslot - fsi; 1431 1432 /* 1433 * sequential append at tail: append without split 1434 * 1435 * If splitting the last page on a level because of appending 1436 * a entry to it (skip is maxentry), it's likely that the access is 1437 * sequential. Adding an empty page on the side of the level is less 1438 * work and can push the fill factor much higher than normal. 1439 * If we're wrong it's no big deal, we'll just do the split the right 1440 * way next time. 1441 * (It may look like it's equally easy to do a similar hack for 1442 * reverse sorted data, that is, split the tree left, 1443 * but it's not. Be my guest.) 1444 */ 1445 if (nextbn == 0 && split->index == sp->header.nextindex) { 1446 /* linelock header + stbl (first slot) of new page */ 1447 rlv = & rdtlck->lv[rdtlck->index]; 1448 rlv->offset = 0; 1449 rlv->length = 2; 1450 rdtlck->index++; 1451 1452 /* 1453 * initialize freelist of new right page 1454 */ 1455 f = &rp->slot[fsi]; 1456 for (fsi++; fsi < rp->header.maxslot; f++, fsi++) 1457 f->next = fsi; 1458 f->next = -1; 1459 1460 /* insert entry at the first entry of the new right page */ 1461 dtInsertEntry(rp, 0, split->key, split->data, &rdtlck); 1462 1463 goto out; 1464 } 1465 1466 /* 1467 * non-sequential insert (at possibly middle page) 1468 */ 1469 1470 /* 1471 * update prev pointer of previous right sibling page; 1472 */ 1473 if (nextbn != 0) { 1474 DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); 1475 if (rc) { 1476 discard_metapage(rmp); 1477 return rc; 1478 } 1479 1480 BT_MARK_DIRTY(mp, ip); 1481 /* 1482 * acquire a transaction lock on the next page 1483 */ 1484 tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); 1485 jfs_info("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p", 1486 tlck, ip, mp); 1487 dtlck = (struct dt_lock *) & tlck->lock; 1488 1489 /* linelock header of previous right sibling page */ 1490 lv = & dtlck->lv[dtlck->index]; 1491 lv->offset = 0; 1492 lv->length = 1; 1493 dtlck->index++; 1494 1495 p->header.prev = cpu_to_le64(rbn); 1496 1497 DT_PUTPAGE(mp); 1498 } 1499 1500 /* 1501 * split the data between the split and right pages. 1502 */ 1503 skip = split->index; 1504 half = (PSIZE >> L2DTSLOTSIZE) >> 1; /* swag */ 1505 left = 0; 1506 1507 /* 1508 * compute fill factor for split pages 1509 * 1510 * <nxt> traces the next entry to move to rp 1511 * <off> traces the next entry to stay in sp 1512 */ 1513 stbl = (u8 *) & sp->slot[sp->header.stblindex]; 1514 nextindex = sp->header.nextindex; 1515 for (nxt = off = 0; nxt < nextindex; ++off) { 1516 if (off == skip) 1517 /* check for fill factor with new entry size */ 1518 n = split->nslot; 1519 else { 1520 si = stbl[nxt]; 1521 switch (sp->header.flag & BT_TYPE) { 1522 case BT_LEAF: 1523 ldtentry = (struct ldtentry *) & sp->slot[si]; 1524 if (DO_INDEX(ip)) 1525 n = NDTLEAF(ldtentry->namlen); 1526 else 1527 n = NDTLEAF_LEGACY(ldtentry-> 1528 namlen); 1529 break; 1530 1531 case BT_INTERNAL: 1532 idtentry = (struct idtentry *) & sp->slot[si]; 1533 n = NDTINTERNAL(idtentry->namlen); 1534 break; 1535 1536 default: 1537 break; 1538 } 1539 1540 ++nxt; /* advance to next entry to move in sp */ 1541 } 1542 1543 left += n; 1544 if (left >= half) 1545 break; 1546 } 1547 1548 /* <nxt> poins to the 1st entry to move */ 1549 1550 /* 1551 * move entries to right page 1552 * 1553 * dtMoveEntry() initializes rp and reserves entry for insertion 1554 * 1555 * split page moved out entries are linelocked; 1556 * new/right page moved in entries are linelocked; 1557 */ 1558 /* linelock header + stbl of new right page */ 1559 rlv = & rdtlck->lv[rdtlck->index]; 1560 rlv->offset = 0; 1561 rlv->length = 5; 1562 rdtlck->index++; 1563 1564 dtMoveEntry(sp, nxt, rp, &sdtlck, &rdtlck, DO_INDEX(ip)); 1565 1566 sp->header.nextindex = nxt; 1567 1568 /* 1569 * finalize freelist of new right page 1570 */ 1571 fsi = rp->header.freelist; 1572 f = &rp->slot[fsi]; 1573 for (fsi++; fsi < rp->header.maxslot; f++, fsi++) 1574 f->next = fsi; 1575 f->next = -1; 1576 1577 /* 1578 * Update directory index table for entries now in right page 1579 */ 1580 if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) { 1581 s64 lblock; 1582 1583 mp = NULL; 1584 stbl = DT_GETSTBL(rp); 1585 for (n = 0; n < rp->header.nextindex; n++) { 1586 ldtentry = (struct ldtentry *) & rp->slot[stbl[n]]; 1587 modify_index(tid, ip, le32_to_cpu(ldtentry->index), 1588 rbn, n, &mp, &lblock); 1589 } 1590 if (mp) 1591 release_metapage(mp); 1592 } 1593 1594 /* 1595 * the skipped index was on the left page, 1596 */ 1597 if (skip <= off) { 1598 /* insert the new entry in the split page */ 1599 dtInsertEntry(sp, skip, split->key, split->data, &sdtlck); 1600 1601 /* linelock stbl of split page */ 1602 if (sdtlck->index >= sdtlck->maxcnt) 1603 sdtlck = (struct dt_lock *) txLinelock(sdtlck); 1604 slv = & sdtlck->lv[sdtlck->index]; 1605 n = skip >> L2DTSLOTSIZE; 1606 slv->offset = sp->header.stblindex + n; 1607 slv->length = 1608 ((sp->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1; 1609 sdtlck->index++; 1610 } 1611 /* 1612 * the skipped index was on the right page, 1613 */ 1614 else { 1615 /* adjust the skip index to reflect the new position */ 1616 skip -= nxt; 1617 1618 /* insert the new entry in the right page */ 1619 dtInsertEntry(rp, skip, split->key, split->data, &rdtlck); 1620 } 1621 1622 out: 1623 *rmpp = rmp; 1624 *rpxdp = *pxd; 1625 1626 return rc; 1627 } 1628 1629 1630 /* 1631 * dtExtendPage() 1632 * 1633 * function: extend 1st/only directory leaf page 1634 * 1635 * parameter: 1636 * 1637 * return: 0 - success; 1638 * errno - failure; 1639 * return extended page pinned; 1640 */ 1641 static int dtExtendPage(tid_t tid, 1642 struct inode *ip, struct dtsplit * split, struct btstack * btstack) 1643 { 1644 struct super_block *sb = ip->i_sb; 1645 int rc; 1646 struct metapage *smp, *pmp, *mp; 1647 dtpage_t *sp, *pp; 1648 struct pxdlist *pxdlist; 1649 pxd_t *pxd, *tpxd; 1650 int xlen, xsize; 1651 int newstblindex, newstblsize; 1652 int oldstblindex, oldstblsize; 1653 int fsi, last; 1654 struct dtslot *f; 1655 struct btframe *parent; 1656 int n; 1657 struct dt_lock *dtlck; 1658 s64 xaddr, txaddr; 1659 struct tlock *tlck; 1660 struct pxd_lock *pxdlock; 1661 struct lv *lv; 1662 uint type; 1663 struct ldtentry *ldtentry; 1664 u8 *stbl; 1665 1666 /* get page to extend */ 1667 smp = split->mp; 1668 sp = DT_PAGE(ip, smp); 1669 1670 /* get parent/root page */ 1671 parent = BT_POP(btstack); 1672 DT_GETPAGE(ip, parent->bn, pmp, PSIZE, pp, rc); 1673 if (rc) 1674 return (rc); 1675 1676 /* 1677 * extend the extent 1678 */ 1679 pxdlist = split->pxdlist; 1680 pxd = &pxdlist->pxd[pxdlist->npxd]; 1681 pxdlist->npxd++; 1682 1683 xaddr = addressPXD(pxd); 1684 tpxd = &sp->header.self; 1685 txaddr = addressPXD(tpxd); 1686 /* in-place extension */ 1687 if (xaddr == txaddr) { 1688 type = tlckEXTEND; 1689 } 1690 /* relocation */ 1691 else { 1692 type = tlckNEW; 1693 1694 /* save moved extent descriptor for later free */ 1695 tlck = txMaplock(tid, ip, tlckDTREE | tlckRELOCATE); 1696 pxdlock = (struct pxd_lock *) & tlck->lock; 1697 pxdlock->flag = mlckFREEPXD; 1698 pxdlock->pxd = sp->header.self; 1699 pxdlock->index = 1; 1700 1701 /* 1702 * Update directory index table to reflect new page address 1703 */ 1704 if (DO_INDEX(ip)) { 1705 s64 lblock; 1706 1707 mp = NULL; 1708 stbl = DT_GETSTBL(sp); 1709 for (n = 0; n < sp->header.nextindex; n++) { 1710 ldtentry = 1711 (struct ldtentry *) & sp->slot[stbl[n]]; 1712 modify_index(tid, ip, 1713 le32_to_cpu(ldtentry->index), 1714 xaddr, n, &mp, &lblock); 1715 } 1716 if (mp) 1717 release_metapage(mp); 1718 } 1719 } 1720 1721 /* 1722 * extend the page 1723 */ 1724 sp->header.self = *pxd; 1725 1726 jfs_info("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p", ip, smp, sp); 1727 1728 BT_MARK_DIRTY(smp, ip); 1729 /* 1730 * acquire a transaction lock on the extended/leaf page 1731 */ 1732 tlck = txLock(tid, ip, smp, tlckDTREE | type); 1733 dtlck = (struct dt_lock *) & tlck->lock; 1734 lv = & dtlck->lv[0]; 1735 1736 /* update buffer extent descriptor of extended page */ 1737 xlen = lengthPXD(pxd); 1738 xsize = xlen << JFS_SBI(sb)->l2bsize; 1739 1740 /* 1741 * copy old stbl to new stbl at start of extended area 1742 */ 1743 oldstblindex = sp->header.stblindex; 1744 oldstblsize = (sp->header.maxslot + 31) >> L2DTSLOTSIZE; 1745 newstblindex = sp->header.maxslot; 1746 n = xsize >> L2DTSLOTSIZE; 1747 newstblsize = (n + 31) >> L2DTSLOTSIZE; 1748 memcpy(&sp->slot[newstblindex], &sp->slot[oldstblindex], 1749 sp->header.nextindex); 1750 1751 /* 1752 * in-line extension: linelock old area of extended page 1753 */ 1754 if (type == tlckEXTEND) { 1755 /* linelock header */ 1756 lv->offset = 0; 1757 lv->length = 1; 1758 dtlck->index++; 1759 lv++; 1760 1761 /* linelock new stbl of extended page */ 1762 lv->offset = newstblindex; 1763 lv->length = newstblsize; 1764 } 1765 /* 1766 * relocation: linelock whole relocated area 1767 */ 1768 else { 1769 lv->offset = 0; 1770 lv->length = sp->header.maxslot + newstblsize; 1771 } 1772 1773 dtlck->index++; 1774 1775 sp->header.maxslot = n; 1776 sp->header.stblindex = newstblindex; 1777 /* sp->header.nextindex remains the same */ 1778 1779 /* 1780 * add old stbl region at head of freelist 1781 */ 1782 fsi = oldstblindex; 1783 f = &sp->slot[fsi]; 1784 last = sp->header.freelist; 1785 for (n = 0; n < oldstblsize; n++, fsi++, f++) { 1786 f->next = last; 1787 last = fsi; 1788 } 1789 sp->header.freelist = last; 1790 sp->header.freecnt += oldstblsize; 1791 1792 /* 1793 * append free region of newly extended area at tail of freelist 1794 */ 1795 /* init free region of newly extended area */ 1796 fsi = n = newstblindex + newstblsize; 1797 f = &sp->slot[fsi]; 1798 for (fsi++; fsi < sp->header.maxslot; f++, fsi++) 1799 f->next = fsi; 1800 f->next = -1; 1801 1802 /* append new free region at tail of old freelist */ 1803 fsi = sp->header.freelist; 1804 if (fsi == -1) 1805 sp->header.freelist = n; 1806 else { 1807 do { 1808 f = &sp->slot[fsi]; 1809 fsi = f->next; 1810 } while (fsi != -1); 1811 1812 f->next = n; 1813 } 1814 1815 sp->header.freecnt += sp->header.maxslot - n; 1816 1817 /* 1818 * insert the new entry 1819 */ 1820 dtInsertEntry(sp, split->index, split->key, split->data, &dtlck); 1821 1822 BT_MARK_DIRTY(pmp, ip); 1823 /* 1824 * linelock any freeslots residing in old extent 1825 */ 1826 if (type == tlckEXTEND) { 1827 n = sp->header.maxslot >> 2; 1828 if (sp->header.freelist < n) 1829 dtLinelockFreelist(sp, n, &dtlck); 1830 } 1831 1832 /* 1833 * update parent entry on the parent/root page 1834 */ 1835 /* 1836 * acquire a transaction lock on the parent/root page 1837 */ 1838 tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY); 1839 dtlck = (struct dt_lock *) & tlck->lock; 1840 lv = & dtlck->lv[dtlck->index]; 1841 1842 /* linelock parent entry - 1st slot */ 1843 lv->offset = 1; 1844 lv->length = 1; 1845 dtlck->index++; 1846 1847 /* update the parent pxd for page extension */ 1848 tpxd = (pxd_t *) & pp->slot[1]; 1849 *tpxd = *pxd; 1850 1851 DT_PUTPAGE(pmp); 1852 return 0; 1853 } 1854 1855 1856 /* 1857 * dtSplitRoot() 1858 * 1859 * function: 1860 * split the full root page into 1861 * original/root/split page and new right page 1862 * i.e., root remains fixed in tree anchor (inode) and 1863 * the root is copied to a single new right child page 1864 * since root page << non-root page, and 1865 * the split root page contains a single entry for the 1866 * new right child page. 1867 * 1868 * parameter: 1869 * 1870 * return: 0 - success; 1871 * errno - failure; 1872 * return new page pinned; 1873 */ 1874 static int dtSplitRoot(tid_t tid, 1875 struct inode *ip, struct dtsplit * split, struct metapage ** rmpp) 1876 { 1877 struct super_block *sb = ip->i_sb; 1878 struct metapage *smp; 1879 dtroot_t *sp; 1880 struct metapage *rmp; 1881 dtpage_t *rp; 1882 s64 rbn; 1883 int xlen; 1884 int xsize; 1885 struct dtslot *f; 1886 s8 *stbl; 1887 int fsi, stblsize, n; 1888 struct idtentry *s; 1889 pxd_t *ppxd; 1890 struct pxdlist *pxdlist; 1891 pxd_t *pxd; 1892 struct dt_lock *dtlck; 1893 struct tlock *tlck; 1894 struct lv *lv; 1895 int rc; 1896 1897 /* get split root page */ 1898 smp = split->mp; 1899 sp = &JFS_IP(ip)->i_dtroot; 1900 1901 /* 1902 * allocate/initialize a single (right) child page 1903 * 1904 * N.B. at first split, a one (or two) block to fit new entry 1905 * is allocated; at subsequent split, a full page is allocated; 1906 */ 1907 pxdlist = split->pxdlist; 1908 pxd = &pxdlist->pxd[pxdlist->npxd]; 1909 pxdlist->npxd++; 1910 rbn = addressPXD(pxd); 1911 xlen = lengthPXD(pxd); 1912 xsize = xlen << JFS_SBI(sb)->l2bsize; 1913 rmp = get_metapage(ip, rbn, xsize, 1); 1914 if (!rmp) 1915 return -EIO; 1916 1917 rp = rmp->data; 1918 1919 /* Allocate blocks to quota. */ 1920 rc = dquot_alloc_block(ip, lengthPXD(pxd)); 1921 if (rc) { 1922 release_metapage(rmp); 1923 return rc; 1924 } 1925 1926 BT_MARK_DIRTY(rmp, ip); 1927 /* 1928 * acquire a transaction lock on the new right page 1929 */ 1930 tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW); 1931 dtlck = (struct dt_lock *) & tlck->lock; 1932 1933 rp->header.flag = 1934 (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL; 1935 rp->header.self = *pxd; 1936 1937 /* initialize sibling pointers */ 1938 rp->header.next = 0; 1939 rp->header.prev = 0; 1940 1941 /* 1942 * move in-line root page into new right page extent 1943 */ 1944 /* linelock header + copied entries + new stbl (1st slot) in new page */ 1945 ASSERT(dtlck->index == 0); 1946 lv = & dtlck->lv[0]; 1947 lv->offset = 0; 1948 lv->length = 10; /* 1 + 8 + 1 */ 1949 dtlck->index++; 1950 1951 n = xsize >> L2DTSLOTSIZE; 1952 rp->header.maxslot = n; 1953 stblsize = (n + 31) >> L2DTSLOTSIZE; 1954 1955 /* copy old stbl to new stbl at start of extended area */ 1956 rp->header.stblindex = DTROOTMAXSLOT; 1957 stbl = (s8 *) & rp->slot[DTROOTMAXSLOT]; 1958 memcpy(stbl, sp->header.stbl, sp->header.nextindex); 1959 rp->header.nextindex = sp->header.nextindex; 1960 1961 /* copy old data area to start of new data area */ 1962 memcpy(&rp->slot[1], &sp->slot[1], IDATASIZE); 1963 1964 /* 1965 * append free region of newly extended area at tail of freelist 1966 */ 1967 /* init free region of newly extended area */ 1968 fsi = n = DTROOTMAXSLOT + stblsize; 1969 f = &rp->slot[fsi]; 1970 for (fsi++; fsi < rp->header.maxslot; f++, fsi++) 1971 f->next = fsi; 1972 f->next = -1; 1973 1974 /* append new free region at tail of old freelist */ 1975 fsi = sp->header.freelist; 1976 if (fsi == -1) 1977 rp->header.freelist = n; 1978 else { 1979 rp->header.freelist = fsi; 1980 1981 do { 1982 f = &rp->slot[fsi]; 1983 fsi = f->next; 1984 } while (fsi != -1); 1985 1986 f->next = n; 1987 } 1988 1989 rp->header.freecnt = sp->header.freecnt + rp->header.maxslot - n; 1990 1991 /* 1992 * Update directory index table for entries now in right page 1993 */ 1994 if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) { 1995 s64 lblock; 1996 struct metapage *mp = NULL; 1997 struct ldtentry *ldtentry; 1998 1999 stbl = DT_GETSTBL(rp); 2000 for (n = 0; n < rp->header.nextindex; n++) { 2001 ldtentry = (struct ldtentry *) & rp->slot[stbl[n]]; 2002 modify_index(tid, ip, le32_to_cpu(ldtentry->index), 2003 rbn, n, &mp, &lblock); 2004 } 2005 if (mp) 2006 release_metapage(mp); 2007 } 2008 /* 2009 * insert the new entry into the new right/child page 2010 * (skip index in the new right page will not change) 2011 */ 2012 dtInsertEntry(rp, split->index, split->key, split->data, &dtlck); 2013 2014 /* 2015 * reset parent/root page 2016 * 2017 * set the 1st entry offset to 0, which force the left-most key 2018 * at any level of the tree to be less than any search key. 2019 * 2020 * The btree comparison code guarantees that the left-most key on any 2021 * level of the tree is never used, so it doesn't need to be filled in. 2022 */ 2023 BT_MARK_DIRTY(smp, ip); 2024 /* 2025 * acquire a transaction lock on the root page (in-memory inode) 2026 */ 2027 tlck = txLock(tid, ip, smp, tlckDTREE | tlckNEW | tlckBTROOT); 2028 dtlck = (struct dt_lock *) & tlck->lock; 2029 2030 /* linelock root */ 2031 ASSERT(dtlck->index == 0); 2032 lv = & dtlck->lv[0]; 2033 lv->offset = 0; 2034 lv->length = DTROOTMAXSLOT; 2035 dtlck->index++; 2036 2037 /* update page header of root */ 2038 if (sp->header.flag & BT_LEAF) { 2039 sp->header.flag &= ~BT_LEAF; 2040 sp->header.flag |= BT_INTERNAL; 2041 } 2042 2043 /* init the first entry */ 2044 s = (struct idtentry *) & sp->slot[DTENTRYSTART]; 2045 ppxd = (pxd_t *) s; 2046 *ppxd = *pxd; 2047 s->next = -1; 2048 s->namlen = 0; 2049 2050 stbl = sp->header.stbl; 2051 stbl[0] = DTENTRYSTART; 2052 sp->header.nextindex = 1; 2053 2054 /* init freelist */ 2055 fsi = DTENTRYSTART + 1; 2056 f = &sp->slot[fsi]; 2057 2058 /* init free region of remaining area */ 2059 for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++) 2060 f->next = fsi; 2061 f->next = -1; 2062 2063 sp->header.freelist = DTENTRYSTART + 1; 2064 sp->header.freecnt = DTROOTMAXSLOT - (DTENTRYSTART + 1); 2065 2066 *rmpp = rmp; 2067 2068 return 0; 2069 } 2070 2071 2072 /* 2073 * dtDelete() 2074 * 2075 * function: delete the entry(s) referenced by a key. 2076 * 2077 * parameter: 2078 * 2079 * return: 2080 */ 2081 int dtDelete(tid_t tid, 2082 struct inode *ip, struct component_name * key, ino_t * ino, int flag) 2083 { 2084 int rc = 0; 2085 s64 bn; 2086 struct metapage *mp, *imp; 2087 dtpage_t *p; 2088 int index; 2089 struct btstack btstack; 2090 struct dt_lock *dtlck; 2091 struct tlock *tlck; 2092 struct lv *lv; 2093 int i; 2094 struct ldtentry *ldtentry; 2095 u8 *stbl; 2096 u32 table_index, next_index; 2097 struct metapage *nmp; 2098 dtpage_t *np; 2099 2100 /* 2101 * search for the entry to delete: 2102 * 2103 * dtSearch() returns (leaf page pinned, index at which to delete). 2104 */ 2105 if ((rc = dtSearch(ip, key, ino, &btstack, flag))) 2106 return rc; 2107 2108 /* retrieve search result */ 2109 DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); 2110 2111 /* 2112 * We need to find put the index of the next entry into the 2113 * directory index table in order to resume a readdir from this 2114 * entry. 2115 */ 2116 if (DO_INDEX(ip)) { 2117 stbl = DT_GETSTBL(p); 2118 ldtentry = (struct ldtentry *) & p->slot[stbl[index]]; 2119 table_index = le32_to_cpu(ldtentry->index); 2120 if (index == (p->header.nextindex - 1)) { 2121 /* 2122 * Last entry in this leaf page 2123 */ 2124 if ((p->header.flag & BT_ROOT) 2125 || (p->header.next == 0)) 2126 next_index = -1; 2127 else { 2128 /* Read next leaf page */ 2129 DT_GETPAGE(ip, le64_to_cpu(p->header.next), 2130 nmp, PSIZE, np, rc); 2131 if (rc) 2132 next_index = -1; 2133 else { 2134 stbl = DT_GETSTBL(np); 2135 ldtentry = 2136 (struct ldtentry *) & np-> 2137 slot[stbl[0]]; 2138 next_index = 2139 le32_to_cpu(ldtentry->index); 2140 DT_PUTPAGE(nmp); 2141 } 2142 } 2143 } else { 2144 ldtentry = 2145 (struct ldtentry *) & p->slot[stbl[index + 1]]; 2146 next_index = le32_to_cpu(ldtentry->index); 2147 } 2148 free_index(tid, ip, table_index, next_index); 2149 } 2150 /* 2151 * the leaf page becomes empty, delete the page 2152 */ 2153 if (p->header.nextindex == 1) { 2154 /* delete empty page */ 2155 rc = dtDeleteUp(tid, ip, mp, p, &btstack); 2156 } 2157 /* 2158 * the leaf page has other entries remaining: 2159 * 2160 * delete the entry from the leaf page. 2161 */ 2162 else { 2163 BT_MARK_DIRTY(mp, ip); 2164 /* 2165 * acquire a transaction lock on the leaf page 2166 */ 2167 tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); 2168 dtlck = (struct dt_lock *) & tlck->lock; 2169 2170 /* 2171 * Do not assume that dtlck->index will be zero. During a 2172 * rename within a directory, this transaction may have 2173 * modified this page already when adding the new entry. 2174 */ 2175 2176 /* linelock header */ 2177 if (dtlck->index >= dtlck->maxcnt) 2178 dtlck = (struct dt_lock *) txLinelock(dtlck); 2179 lv = & dtlck->lv[dtlck->index]; 2180 lv->offset = 0; 2181 lv->length = 1; 2182 dtlck->index++; 2183 2184 /* linelock stbl of non-root leaf page */ 2185 if (!(p->header.flag & BT_ROOT)) { 2186 if (dtlck->index >= dtlck->maxcnt) 2187 dtlck = (struct dt_lock *) txLinelock(dtlck); 2188 lv = & dtlck->lv[dtlck->index]; 2189 i = index >> L2DTSLOTSIZE; 2190 lv->offset = p->header.stblindex + i; 2191 lv->length = 2192 ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - 2193 i + 1; 2194 dtlck->index++; 2195 } 2196 2197 /* free the leaf entry */ 2198 dtDeleteEntry(p, index, &dtlck); 2199 2200 /* 2201 * Update directory index table for entries moved in stbl 2202 */ 2203 if (DO_INDEX(ip) && index < p->header.nextindex) { 2204 s64 lblock; 2205 2206 imp = NULL; 2207 stbl = DT_GETSTBL(p); 2208 for (i = index; i < p->header.nextindex; i++) { 2209 ldtentry = 2210 (struct ldtentry *) & p->slot[stbl[i]]; 2211 modify_index(tid, ip, 2212 le32_to_cpu(ldtentry->index), 2213 bn, i, &imp, &lblock); 2214 } 2215 if (imp) 2216 release_metapage(imp); 2217 } 2218 2219 DT_PUTPAGE(mp); 2220 } 2221 2222 return rc; 2223 } 2224 2225 2226 /* 2227 * dtDeleteUp() 2228 * 2229 * function: 2230 * free empty pages as propagating deletion up the tree 2231 * 2232 * parameter: 2233 * 2234 * return: 2235 */ 2236 static int dtDeleteUp(tid_t tid, struct inode *ip, 2237 struct metapage * fmp, dtpage_t * fp, struct btstack * btstack) 2238 { 2239 int rc = 0; 2240 struct metapage *mp; 2241 dtpage_t *p; 2242 int index, nextindex; 2243 int xlen; 2244 struct btframe *parent; 2245 struct dt_lock *dtlck; 2246 struct tlock *tlck; 2247 struct lv *lv; 2248 struct pxd_lock *pxdlock; 2249 int i; 2250 2251 /* 2252 * keep the root leaf page which has become empty 2253 */ 2254 if (BT_IS_ROOT(fmp)) { 2255 /* 2256 * reset the root 2257 * 2258 * dtInitRoot() acquires txlock on the root 2259 */ 2260 dtInitRoot(tid, ip, PARENT(ip)); 2261 2262 DT_PUTPAGE(fmp); 2263 2264 return 0; 2265 } 2266 2267 /* 2268 * free the non-root leaf page 2269 */ 2270 /* 2271 * acquire a transaction lock on the page 2272 * 2273 * write FREEXTENT|NOREDOPAGE log record 2274 * N.B. linelock is overlaid as freed extent descriptor, and 2275 * the buffer page is freed; 2276 */ 2277 tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE); 2278 pxdlock = (struct pxd_lock *) & tlck->lock; 2279 pxdlock->flag = mlckFREEPXD; 2280 pxdlock->pxd = fp->header.self; 2281 pxdlock->index = 1; 2282 2283 /* update sibling pointers */ 2284 if ((rc = dtRelink(tid, ip, fp))) { 2285 BT_PUTPAGE(fmp); 2286 return rc; 2287 } 2288 2289 xlen = lengthPXD(&fp->header.self); 2290 2291 /* Free quota allocation. */ 2292 dquot_free_block(ip, xlen); 2293 2294 /* free/invalidate its buffer page */ 2295 discard_metapage(fmp); 2296 2297 /* 2298 * propagate page deletion up the directory tree 2299 * 2300 * If the delete from the parent page makes it empty, 2301 * continue all the way up the tree. 2302 * stop if the root page is reached (which is never deleted) or 2303 * if the entry deletion does not empty the page. 2304 */ 2305 while ((parent = BT_POP(btstack)) != NULL) { 2306 /* pin the parent page <sp> */ 2307 DT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc); 2308 if (rc) 2309 return rc; 2310 2311 /* 2312 * free the extent of the child page deleted 2313 */ 2314 index = parent->index; 2315 2316 /* 2317 * delete the entry for the child page from parent 2318 */ 2319 nextindex = p->header.nextindex; 2320 2321 /* 2322 * the parent has the single entry being deleted: 2323 * 2324 * free the parent page which has become empty. 2325 */ 2326 if (nextindex == 1) { 2327 /* 2328 * keep the root internal page which has become empty 2329 */ 2330 if (p->header.flag & BT_ROOT) { 2331 /* 2332 * reset the root 2333 * 2334 * dtInitRoot() acquires txlock on the root 2335 */ 2336 dtInitRoot(tid, ip, PARENT(ip)); 2337 2338 DT_PUTPAGE(mp); 2339 2340 return 0; 2341 } 2342 /* 2343 * free the parent page 2344 */ 2345 else { 2346 /* 2347 * acquire a transaction lock on the page 2348 * 2349 * write FREEXTENT|NOREDOPAGE log record 2350 */ 2351 tlck = 2352 txMaplock(tid, ip, 2353 tlckDTREE | tlckFREE); 2354 pxdlock = (struct pxd_lock *) & tlck->lock; 2355 pxdlock->flag = mlckFREEPXD; 2356 pxdlock->pxd = p->header.self; 2357 pxdlock->index = 1; 2358 2359 /* update sibling pointers */ 2360 if ((rc = dtRelink(tid, ip, p))) { 2361 DT_PUTPAGE(mp); 2362 return rc; 2363 } 2364 2365 xlen = lengthPXD(&p->header.self); 2366 2367 /* Free quota allocation */ 2368 dquot_free_block(ip, xlen); 2369 2370 /* free/invalidate its buffer page */ 2371 discard_metapage(mp); 2372 2373 /* propagate up */ 2374 continue; 2375 } 2376 } 2377 2378 /* 2379 * the parent has other entries remaining: 2380 * 2381 * delete the router entry from the parent page. 2382 */ 2383 BT_MARK_DIRTY(mp, ip); 2384 /* 2385 * acquire a transaction lock on the page 2386 * 2387 * action: router entry deletion 2388 */ 2389 tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); 2390 dtlck = (struct dt_lock *) & tlck->lock; 2391 2392 /* linelock header */ 2393 if (dtlck->index >= dtlck->maxcnt) 2394 dtlck = (struct dt_lock *) txLinelock(dtlck); 2395 lv = & dtlck->lv[dtlck->index]; 2396 lv->offset = 0; 2397 lv->length = 1; 2398 dtlck->index++; 2399 2400 /* linelock stbl of non-root leaf page */ 2401 if (!(p->header.flag & BT_ROOT)) { 2402 if (dtlck->index < dtlck->maxcnt) 2403 lv++; 2404 else { 2405 dtlck = (struct dt_lock *) txLinelock(dtlck); 2406 lv = & dtlck->lv[0]; 2407 } 2408 i = index >> L2DTSLOTSIZE; 2409 lv->offset = p->header.stblindex + i; 2410 lv->length = 2411 ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - 2412 i + 1; 2413 dtlck->index++; 2414 } 2415 2416 /* free the router entry */ 2417 dtDeleteEntry(p, index, &dtlck); 2418 2419 /* reset key of new leftmost entry of level (for consistency) */ 2420 if (index == 0 && 2421 ((p->header.flag & BT_ROOT) || p->header.prev == 0)) 2422 dtTruncateEntry(p, 0, &dtlck); 2423 2424 /* unpin the parent page */ 2425 DT_PUTPAGE(mp); 2426 2427 /* exit propagation up */ 2428 break; 2429 } 2430 2431 if (!DO_INDEX(ip)) 2432 ip->i_size -= PSIZE; 2433 2434 return 0; 2435 } 2436 2437 #ifdef _NOTYET 2438 /* 2439 * NAME: dtRelocate() 2440 * 2441 * FUNCTION: relocate dtpage (internal or leaf) of directory; 2442 * This function is mainly used by defragfs utility. 2443 */ 2444 int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd, 2445 s64 nxaddr) 2446 { 2447 int rc = 0; 2448 struct metapage *mp, *pmp, *lmp, *rmp; 2449 dtpage_t *p, *pp, *rp = 0, *lp= 0; 2450 s64 bn; 2451 int index; 2452 struct btstack btstack; 2453 pxd_t *pxd; 2454 s64 oxaddr, nextbn, prevbn; 2455 int xlen, xsize; 2456 struct tlock *tlck; 2457 struct dt_lock *dtlck; 2458 struct pxd_lock *pxdlock; 2459 s8 *stbl; 2460 struct lv *lv; 2461 2462 oxaddr = addressPXD(opxd); 2463 xlen = lengthPXD(opxd); 2464 2465 jfs_info("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d", 2466 (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr, 2467 xlen); 2468 2469 /* 2470 * 1. get the internal parent dtpage covering 2471 * router entry for the tartget page to be relocated; 2472 */ 2473 rc = dtSearchNode(ip, lmxaddr, opxd, &btstack); 2474 if (rc) 2475 return rc; 2476 2477 /* retrieve search result */ 2478 DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); 2479 jfs_info("dtRelocate: parent router entry validated."); 2480 2481 /* 2482 * 2. relocate the target dtpage 2483 */ 2484 /* read in the target page from src extent */ 2485 DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc); 2486 if (rc) { 2487 /* release the pinned parent page */ 2488 DT_PUTPAGE(pmp); 2489 return rc; 2490 } 2491 2492 /* 2493 * read in sibling pages if any to update sibling pointers; 2494 */ 2495 rmp = NULL; 2496 if (p->header.next) { 2497 nextbn = le64_to_cpu(p->header.next); 2498 DT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc); 2499 if (rc) { 2500 DT_PUTPAGE(mp); 2501 DT_PUTPAGE(pmp); 2502 return (rc); 2503 } 2504 } 2505 2506 lmp = NULL; 2507 if (p->header.prev) { 2508 prevbn = le64_to_cpu(p->header.prev); 2509 DT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc); 2510 if (rc) { 2511 DT_PUTPAGE(mp); 2512 DT_PUTPAGE(pmp); 2513 if (rmp) 2514 DT_PUTPAGE(rmp); 2515 return (rc); 2516 } 2517 } 2518 2519 /* at this point, all xtpages to be updated are in memory */ 2520 2521 /* 2522 * update sibling pointers of sibling dtpages if any; 2523 */ 2524 if (lmp) { 2525 tlck = txLock(tid, ip, lmp, tlckDTREE | tlckRELINK); 2526 dtlck = (struct dt_lock *) & tlck->lock; 2527 /* linelock header */ 2528 ASSERT(dtlck->index == 0); 2529 lv = & dtlck->lv[0]; 2530 lv->offset = 0; 2531 lv->length = 1; 2532 dtlck->index++; 2533 2534 lp->header.next = cpu_to_le64(nxaddr); 2535 DT_PUTPAGE(lmp); 2536 } 2537 2538 if (rmp) { 2539 tlck = txLock(tid, ip, rmp, tlckDTREE | tlckRELINK); 2540 dtlck = (struct dt_lock *) & tlck->lock; 2541 /* linelock header */ 2542 ASSERT(dtlck->index == 0); 2543 lv = & dtlck->lv[0]; 2544 lv->offset = 0; 2545 lv->length = 1; 2546 dtlck->index++; 2547 2548 rp->header.prev = cpu_to_le64(nxaddr); 2549 DT_PUTPAGE(rmp); 2550 } 2551 2552 /* 2553 * update the target dtpage to be relocated 2554 * 2555 * write LOG_REDOPAGE of LOG_NEW type for dst page 2556 * for the whole target page (logredo() will apply 2557 * after image and update bmap for allocation of the 2558 * dst extent), and update bmap for allocation of 2559 * the dst extent; 2560 */ 2561 tlck = txLock(tid, ip, mp, tlckDTREE | tlckNEW); 2562 dtlck = (struct dt_lock *) & tlck->lock; 2563 /* linelock header */ 2564 ASSERT(dtlck->index == 0); 2565 lv = & dtlck->lv[0]; 2566 2567 /* update the self address in the dtpage header */ 2568 pxd = &p->header.self; 2569 PXDaddress(pxd, nxaddr); 2570 2571 /* the dst page is the same as the src page, i.e., 2572 * linelock for afterimage of the whole page; 2573 */ 2574 lv->offset = 0; 2575 lv->length = p->header.maxslot; 2576 dtlck->index++; 2577 2578 /* update the buffer extent descriptor of the dtpage */ 2579 xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize; 2580 2581 /* unpin the relocated page */ 2582 DT_PUTPAGE(mp); 2583 jfs_info("dtRelocate: target dtpage relocated."); 2584 2585 /* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec 2586 * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec 2587 * will also force a bmap update ). 2588 */ 2589 2590 /* 2591 * 3. acquire maplock for the source extent to be freed; 2592 */ 2593 /* for dtpage relocation, write a LOG_NOREDOPAGE record 2594 * for the source dtpage (logredo() will init NoRedoPage 2595 * filter and will also update bmap for free of the source 2596 * dtpage), and upadte bmap for free of the source dtpage; 2597 */ 2598 tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE); 2599 pxdlock = (struct pxd_lock *) & tlck->lock; 2600 pxdlock->flag = mlckFREEPXD; 2601 PXDaddress(&pxdlock->pxd, oxaddr); 2602 PXDlength(&pxdlock->pxd, xlen); 2603 pxdlock->index = 1; 2604 2605 /* 2606 * 4. update the parent router entry for relocation; 2607 * 2608 * acquire tlck for the parent entry covering the target dtpage; 2609 * write LOG_REDOPAGE to apply after image only; 2610 */ 2611 jfs_info("dtRelocate: update parent router entry."); 2612 tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY); 2613 dtlck = (struct dt_lock *) & tlck->lock; 2614 lv = & dtlck->lv[dtlck->index]; 2615 2616 /* update the PXD with the new address */ 2617 stbl = DT_GETSTBL(pp); 2618 pxd = (pxd_t *) & pp->slot[stbl[index]]; 2619 PXDaddress(pxd, nxaddr); 2620 lv->offset = stbl[index]; 2621 lv->length = 1; 2622 dtlck->index++; 2623 2624 /* unpin the parent dtpage */ 2625 DT_PUTPAGE(pmp); 2626 2627 return rc; 2628 } 2629 2630 /* 2631 * NAME: dtSearchNode() 2632 * 2633 * FUNCTION: Search for an dtpage containing a specified address 2634 * This function is mainly used by defragfs utility. 2635 * 2636 * NOTE: Search result on stack, the found page is pinned at exit. 2637 * The result page must be an internal dtpage. 2638 * lmxaddr give the address of the left most page of the 2639 * dtree level, in which the required dtpage resides. 2640 */ 2641 static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd, 2642 struct btstack * btstack) 2643 { 2644 int rc = 0; 2645 s64 bn; 2646 struct metapage *mp; 2647 dtpage_t *p; 2648 int psize = 288; /* initial in-line directory */ 2649 s8 *stbl; 2650 int i; 2651 pxd_t *pxd; 2652 struct btframe *btsp; 2653 2654 BT_CLR(btstack); /* reset stack */ 2655 2656 /* 2657 * descend tree to the level with specified leftmost page 2658 * 2659 * by convention, root bn = 0. 2660 */ 2661 for (bn = 0;;) { 2662 /* get/pin the page to search */ 2663 DT_GETPAGE(ip, bn, mp, psize, p, rc); 2664 if (rc) 2665 return rc; 2666 2667 /* does the xaddr of leftmost page of the levevl 2668 * matches levevl search key ? 2669 */ 2670 if (p->header.flag & BT_ROOT) { 2671 if (lmxaddr == 0) 2672 break; 2673 } else if (addressPXD(&p->header.self) == lmxaddr) 2674 break; 2675 2676 /* 2677 * descend down to leftmost child page 2678 */ 2679 if (p->header.flag & BT_LEAF) { 2680 DT_PUTPAGE(mp); 2681 return -ESTALE; 2682 } 2683 2684 /* get the leftmost entry */ 2685 stbl = DT_GETSTBL(p); 2686 pxd = (pxd_t *) & p->slot[stbl[0]]; 2687 2688 /* get the child page block address */ 2689 bn = addressPXD(pxd); 2690 psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize; 2691 /* unpin the parent page */ 2692 DT_PUTPAGE(mp); 2693 } 2694 2695 /* 2696 * search each page at the current levevl 2697 */ 2698 loop: 2699 stbl = DT_GETSTBL(p); 2700 for (i = 0; i < p->header.nextindex; i++) { 2701 pxd = (pxd_t *) & p->slot[stbl[i]]; 2702 2703 /* found the specified router entry */ 2704 if (addressPXD(pxd) == addressPXD(kpxd) && 2705 lengthPXD(pxd) == lengthPXD(kpxd)) { 2706 btsp = btstack->top; 2707 btsp->bn = bn; 2708 btsp->index = i; 2709 btsp->mp = mp; 2710 2711 return 0; 2712 } 2713 } 2714 2715 /* get the right sibling page if any */ 2716 if (p->header.next) 2717 bn = le64_to_cpu(p->header.next); 2718 else { 2719 DT_PUTPAGE(mp); 2720 return -ESTALE; 2721 } 2722 2723 /* unpin current page */ 2724 DT_PUTPAGE(mp); 2725 2726 /* get the right sibling page */ 2727 DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 2728 if (rc) 2729 return rc; 2730 2731 goto loop; 2732 } 2733 #endif /* _NOTYET */ 2734 2735 /* 2736 * dtRelink() 2737 * 2738 * function: 2739 * link around a freed page. 2740 * 2741 * parameter: 2742 * fp: page to be freed 2743 * 2744 * return: 2745 */ 2746 static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p) 2747 { 2748 int rc; 2749 struct metapage *mp; 2750 s64 nextbn, prevbn; 2751 struct tlock *tlck; 2752 struct dt_lock *dtlck; 2753 struct lv *lv; 2754 2755 nextbn = le64_to_cpu(p->header.next); 2756 prevbn = le64_to_cpu(p->header.prev); 2757 2758 /* update prev pointer of the next page */ 2759 if (nextbn != 0) { 2760 DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); 2761 if (rc) 2762 return rc; 2763 2764 BT_MARK_DIRTY(mp, ip); 2765 /* 2766 * acquire a transaction lock on the next page 2767 * 2768 * action: update prev pointer; 2769 */ 2770 tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); 2771 jfs_info("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p", 2772 tlck, ip, mp); 2773 dtlck = (struct dt_lock *) & tlck->lock; 2774 2775 /* linelock header */ 2776 if (dtlck->index >= dtlck->maxcnt) 2777 dtlck = (struct dt_lock *) txLinelock(dtlck); 2778 lv = & dtlck->lv[dtlck->index]; 2779 lv->offset = 0; 2780 lv->length = 1; 2781 dtlck->index++; 2782 2783 p->header.prev = cpu_to_le64(prevbn); 2784 DT_PUTPAGE(mp); 2785 } 2786 2787 /* update next pointer of the previous page */ 2788 if (prevbn != 0) { 2789 DT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc); 2790 if (rc) 2791 return rc; 2792 2793 BT_MARK_DIRTY(mp, ip); 2794 /* 2795 * acquire a transaction lock on the prev page 2796 * 2797 * action: update next pointer; 2798 */ 2799 tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); 2800 jfs_info("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p", 2801 tlck, ip, mp); 2802 dtlck = (struct dt_lock *) & tlck->lock; 2803 2804 /* linelock header */ 2805 if (dtlck->index >= dtlck->maxcnt) 2806 dtlck = (struct dt_lock *) txLinelock(dtlck); 2807 lv = & dtlck->lv[dtlck->index]; 2808 lv->offset = 0; 2809 lv->length = 1; 2810 dtlck->index++; 2811 2812 p->header.next = cpu_to_le64(nextbn); 2813 DT_PUTPAGE(mp); 2814 } 2815 2816 return 0; 2817 } 2818 2819 2820 /* 2821 * dtInitRoot() 2822 * 2823 * initialize directory root (inline in inode) 2824 */ 2825 void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot) 2826 { 2827 struct jfs_inode_info *jfs_ip = JFS_IP(ip); 2828 dtroot_t *p; 2829 int fsi; 2830 struct dtslot *f; 2831 struct tlock *tlck; 2832 struct dt_lock *dtlck; 2833 struct lv *lv; 2834 u16 xflag_save; 2835 2836 /* 2837 * If this was previously an non-empty directory, we need to remove 2838 * the old directory table. 2839 */ 2840 if (DO_INDEX(ip)) { 2841 if (!jfs_dirtable_inline(ip)) { 2842 struct tblock *tblk = tid_to_tblock(tid); 2843 /* 2844 * We're playing games with the tid's xflag. If 2845 * we're removing a regular file, the file's xtree 2846 * is committed with COMMIT_PMAP, but we always 2847 * commit the directories xtree with COMMIT_PWMAP. 2848 */ 2849 xflag_save = tblk->xflag; 2850 tblk->xflag = 0; 2851 /* 2852 * xtTruncate isn't guaranteed to fully truncate 2853 * the xtree. The caller needs to check i_size 2854 * after committing the transaction to see if 2855 * additional truncation is needed. The 2856 * COMMIT_Stale flag tells caller that we 2857 * initiated the truncation. 2858 */ 2859 xtTruncate(tid, ip, 0, COMMIT_PWMAP); 2860 set_cflag(COMMIT_Stale, ip); 2861 2862 tblk->xflag = xflag_save; 2863 } else 2864 ip->i_size = 1; 2865 2866 jfs_ip->next_index = 2; 2867 } else 2868 ip->i_size = IDATASIZE; 2869 2870 /* 2871 * acquire a transaction lock on the root 2872 * 2873 * action: directory initialization; 2874 */ 2875 tlck = txLock(tid, ip, (struct metapage *) & jfs_ip->bxflag, 2876 tlckDTREE | tlckENTRY | tlckBTROOT); 2877 dtlck = (struct dt_lock *) & tlck->lock; 2878 2879 /* linelock root */ 2880 ASSERT(dtlck->index == 0); 2881 lv = & dtlck->lv[0]; 2882 lv->offset = 0; 2883 lv->length = DTROOTMAXSLOT; 2884 dtlck->index++; 2885 2886 p = &jfs_ip->i_dtroot; 2887 2888 p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF; 2889 2890 p->header.nextindex = 0; 2891 2892 /* init freelist */ 2893 fsi = 1; 2894 f = &p->slot[fsi]; 2895 2896 /* init data area of root */ 2897 for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++) 2898 f->next = fsi; 2899 f->next = -1; 2900 2901 p->header.freelist = 1; 2902 p->header.freecnt = 8; 2903 2904 /* init '..' entry */ 2905 p->header.idotdot = cpu_to_le32(idotdot); 2906 2907 return; 2908 } 2909 2910 /* 2911 * add_missing_indices() 2912 * 2913 * function: Fix dtree page in which one or more entries has an invalid index. 2914 * fsck.jfs should really fix this, but it currently does not. 2915 * Called from jfs_readdir when bad index is detected. 2916 */ 2917 static void add_missing_indices(struct inode *inode, s64 bn) 2918 { 2919 struct ldtentry *d; 2920 struct dt_lock *dtlck; 2921 int i; 2922 uint index; 2923 struct lv *lv; 2924 struct metapage *mp; 2925 dtpage_t *p; 2926 int rc; 2927 s8 *stbl; 2928 tid_t tid; 2929 struct tlock *tlck; 2930 2931 tid = txBegin(inode->i_sb, 0); 2932 2933 DT_GETPAGE(inode, bn, mp, PSIZE, p, rc); 2934 2935 if (rc) { 2936 printk(KERN_ERR "DT_GETPAGE failed!\n"); 2937 goto end; 2938 } 2939 BT_MARK_DIRTY(mp, inode); 2940 2941 ASSERT(p->header.flag & BT_LEAF); 2942 2943 tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY); 2944 if (BT_IS_ROOT(mp)) 2945 tlck->type |= tlckBTROOT; 2946 2947 dtlck = (struct dt_lock *) &tlck->lock; 2948 2949 stbl = DT_GETSTBL(p); 2950 for (i = 0; i < p->header.nextindex; i++) { 2951 d = (struct ldtentry *) &p->slot[stbl[i]]; 2952 index = le32_to_cpu(d->index); 2953 if ((index < 2) || (index >= JFS_IP(inode)->next_index)) { 2954 d->index = cpu_to_le32(add_index(tid, inode, bn, i)); 2955 if (dtlck->index >= dtlck->maxcnt) 2956 dtlck = (struct dt_lock *) txLinelock(dtlck); 2957 lv = &dtlck->lv[dtlck->index]; 2958 lv->offset = stbl[i]; 2959 lv->length = 1; 2960 dtlck->index++; 2961 } 2962 } 2963 2964 DT_PUTPAGE(mp); 2965 (void) txCommit(tid, 1, &inode, 0); 2966 end: 2967 txEnd(tid); 2968 } 2969 2970 /* 2971 * Buffer to hold directory entry info while traversing a dtree page 2972 * before being fed to the filldir function 2973 */ 2974 struct jfs_dirent { 2975 loff_t position; 2976 int ino; 2977 u16 name_len; 2978 char name[0]; 2979 }; 2980 2981 /* 2982 * function to determine next variable-sized jfs_dirent in buffer 2983 */ 2984 static inline struct jfs_dirent *next_jfs_dirent(struct jfs_dirent *dirent) 2985 { 2986 return (struct jfs_dirent *) 2987 ((char *)dirent + 2988 ((sizeof (struct jfs_dirent) + dirent->name_len + 1 + 2989 sizeof (loff_t) - 1) & 2990 ~(sizeof (loff_t) - 1))); 2991 } 2992 2993 /* 2994 * jfs_readdir() 2995 * 2996 * function: read directory entries sequentially 2997 * from the specified entry offset 2998 * 2999 * parameter: 3000 * 3001 * return: offset = (pn, index) of start entry 3002 * of next jfs_readdir()/dtRead() 3003 */ 3004 int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 3005 { 3006 struct inode *ip = filp->f_path.dentry->d_inode; 3007 struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab; 3008 int rc = 0; 3009 loff_t dtpos; /* legacy OS/2 style position */ 3010 struct dtoffset { 3011 s16 pn; 3012 s16 index; 3013 s32 unused; 3014 } *dtoffset = (struct dtoffset *) &dtpos; 3015 s64 bn; 3016 struct metapage *mp; 3017 dtpage_t *p; 3018 int index; 3019 s8 *stbl; 3020 struct btstack btstack; 3021 int i, next; 3022 struct ldtentry *d; 3023 struct dtslot *t; 3024 int d_namleft, len, outlen; 3025 unsigned long dirent_buf; 3026 char *name_ptr; 3027 u32 dir_index; 3028 int do_index = 0; 3029 uint loop_count = 0; 3030 struct jfs_dirent *jfs_dirent; 3031 int jfs_dirents; 3032 int overflow, fix_page, page_fixed = 0; 3033 static int unique_pos = 2; /* If we can't fix broken index */ 3034 3035 if (filp->f_pos == DIREND) 3036 return 0; 3037 3038 if (DO_INDEX(ip)) { 3039 /* 3040 * persistent index is stored in directory entries. 3041 * Special cases: 0 = . 3042 * 1 = .. 3043 * -1 = End of directory 3044 */ 3045 do_index = 1; 3046 3047 dir_index = (u32) filp->f_pos; 3048 3049 if (dir_index > 1) { 3050 struct dir_table_slot dirtab_slot; 3051 3052 if (dtEmpty(ip) || 3053 (dir_index >= JFS_IP(ip)->next_index)) { 3054 /* Stale position. Directory has shrunk */ 3055 filp->f_pos = DIREND; 3056 return 0; 3057 } 3058 repeat: 3059 rc = read_index(ip, dir_index, &dirtab_slot); 3060 if (rc) { 3061 filp->f_pos = DIREND; 3062 return rc; 3063 } 3064 if (dirtab_slot.flag == DIR_INDEX_FREE) { 3065 if (loop_count++ > JFS_IP(ip)->next_index) { 3066 jfs_err("jfs_readdir detected " 3067 "infinite loop!"); 3068 filp->f_pos = DIREND; 3069 return 0; 3070 } 3071 dir_index = le32_to_cpu(dirtab_slot.addr2); 3072 if (dir_index == -1) { 3073 filp->f_pos = DIREND; 3074 return 0; 3075 } 3076 goto repeat; 3077 } 3078 bn = addressDTS(&dirtab_slot); 3079 index = dirtab_slot.slot; 3080 DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 3081 if (rc) { 3082 filp->f_pos = DIREND; 3083 return 0; 3084 } 3085 if (p->header.flag & BT_INTERNAL) { 3086 jfs_err("jfs_readdir: bad index table"); 3087 DT_PUTPAGE(mp); 3088 filp->f_pos = -1; 3089 return 0; 3090 } 3091 } else { 3092 if (dir_index == 0) { 3093 /* 3094 * self "." 3095 */ 3096 filp->f_pos = 0; 3097 if (filldir(dirent, ".", 1, 0, ip->i_ino, 3098 DT_DIR)) 3099 return 0; 3100 } 3101 /* 3102 * parent ".." 3103 */ 3104 filp->f_pos = 1; 3105 if (filldir(dirent, "..", 2, 1, PARENT(ip), DT_DIR)) 3106 return 0; 3107 3108 /* 3109 * Find first entry of left-most leaf 3110 */ 3111 if (dtEmpty(ip)) { 3112 filp->f_pos = DIREND; 3113 return 0; 3114 } 3115 3116 if ((rc = dtReadFirst(ip, &btstack))) 3117 return rc; 3118 3119 DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); 3120 } 3121 } else { 3122 /* 3123 * Legacy filesystem - OS/2 & Linux JFS < 0.3.6 3124 * 3125 * pn = index = 0: First entry "." 3126 * pn = 0; index = 1: Second entry ".." 3127 * pn > 0: Real entries, pn=1 -> leftmost page 3128 * pn = index = -1: No more entries 3129 */ 3130 dtpos = filp->f_pos; 3131 if (dtpos == 0) { 3132 /* build "." entry */ 3133 3134 if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino, 3135 DT_DIR)) 3136 return 0; 3137 dtoffset->index = 1; 3138 filp->f_pos = dtpos; 3139 } 3140 3141 if (dtoffset->pn == 0) { 3142 if (dtoffset->index == 1) { 3143 /* build ".." entry */ 3144 3145 if (filldir(dirent, "..", 2, filp->f_pos, 3146 PARENT(ip), DT_DIR)) 3147 return 0; 3148 } else { 3149 jfs_err("jfs_readdir called with " 3150 "invalid offset!"); 3151 } 3152 dtoffset->pn = 1; 3153 dtoffset->index = 0; 3154 filp->f_pos = dtpos; 3155 } 3156 3157 if (dtEmpty(ip)) { 3158 filp->f_pos = DIREND; 3159 return 0; 3160 } 3161 3162 if ((rc = dtReadNext(ip, &filp->f_pos, &btstack))) { 3163 jfs_err("jfs_readdir: unexpected rc = %d " 3164 "from dtReadNext", rc); 3165 filp->f_pos = DIREND; 3166 return 0; 3167 } 3168 /* get start leaf page and index */ 3169 DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); 3170 3171 /* offset beyond directory eof ? */ 3172 if (bn < 0) { 3173 filp->f_pos = DIREND; 3174 return 0; 3175 } 3176 } 3177 3178 dirent_buf = __get_free_page(GFP_KERNEL); 3179 if (dirent_buf == 0) { 3180 DT_PUTPAGE(mp); 3181 jfs_warn("jfs_readdir: __get_free_page failed!"); 3182 filp->f_pos = DIREND; 3183 return -ENOMEM; 3184 } 3185 3186 while (1) { 3187 jfs_dirent = (struct jfs_dirent *) dirent_buf; 3188 jfs_dirents = 0; 3189 overflow = fix_page = 0; 3190 3191 stbl = DT_GETSTBL(p); 3192 3193 for (i = index; i < p->header.nextindex; i++) { 3194 d = (struct ldtentry *) & p->slot[stbl[i]]; 3195 3196 if (((long) jfs_dirent + d->namlen + 1) > 3197 (dirent_buf + PAGE_SIZE)) { 3198 /* DBCS codepages could overrun dirent_buf */ 3199 index = i; 3200 overflow = 1; 3201 break; 3202 } 3203 3204 d_namleft = d->namlen; 3205 name_ptr = jfs_dirent->name; 3206 jfs_dirent->ino = le32_to_cpu(d->inumber); 3207 3208 if (do_index) { 3209 len = min(d_namleft, DTLHDRDATALEN); 3210 jfs_dirent->position = le32_to_cpu(d->index); 3211 /* 3212 * d->index should always be valid, but it 3213 * isn't. fsck.jfs doesn't create the 3214 * directory index for the lost+found 3215 * directory. Rather than let it go, 3216 * we can try to fix it. 3217 */ 3218 if ((jfs_dirent->position < 2) || 3219 (jfs_dirent->position >= 3220 JFS_IP(ip)->next_index)) { 3221 if (!page_fixed && !isReadOnly(ip)) { 3222 fix_page = 1; 3223 /* 3224 * setting overflow and setting 3225 * index to i will cause the 3226 * same page to be processed 3227 * again starting here 3228 */ 3229 overflow = 1; 3230 index = i; 3231 break; 3232 } 3233 jfs_dirent->position = unique_pos++; 3234 } 3235 } else { 3236 jfs_dirent->position = dtpos; 3237 len = min(d_namleft, DTLHDRDATALEN_LEGACY); 3238 } 3239 3240 /* copy the name of head/only segment */ 3241 outlen = jfs_strfromUCS_le(name_ptr, d->name, len, 3242 codepage); 3243 jfs_dirent->name_len = outlen; 3244 3245 /* copy name in the additional segment(s) */ 3246 next = d->next; 3247 while (next >= 0) { 3248 t = (struct dtslot *) & p->slot[next]; 3249 name_ptr += outlen; 3250 d_namleft -= len; 3251 /* Sanity Check */ 3252 if (d_namleft == 0) { 3253 jfs_error(ip->i_sb, 3254 "JFS:Dtree error: ino = " 3255 "%ld, bn=%Ld, index = %d", 3256 (long)ip->i_ino, 3257 (long long)bn, 3258 i); 3259 goto skip_one; 3260 } 3261 len = min(d_namleft, DTSLOTDATALEN); 3262 outlen = jfs_strfromUCS_le(name_ptr, t->name, 3263 len, codepage); 3264 jfs_dirent->name_len += outlen; 3265 3266 next = t->next; 3267 } 3268 3269 jfs_dirents++; 3270 jfs_dirent = next_jfs_dirent(jfs_dirent); 3271 skip_one: 3272 if (!do_index) 3273 dtoffset->index++; 3274 } 3275 3276 if (!overflow) { 3277 /* Point to next leaf page */ 3278 if (p->header.flag & BT_ROOT) 3279 bn = 0; 3280 else { 3281 bn = le64_to_cpu(p->header.next); 3282 index = 0; 3283 /* update offset (pn:index) for new page */ 3284 if (!do_index) { 3285 dtoffset->pn++; 3286 dtoffset->index = 0; 3287 } 3288 } 3289 page_fixed = 0; 3290 } 3291 3292 /* unpin previous leaf page */ 3293 DT_PUTPAGE(mp); 3294 3295 jfs_dirent = (struct jfs_dirent *) dirent_buf; 3296 while (jfs_dirents--) { 3297 filp->f_pos = jfs_dirent->position; 3298 if (filldir(dirent, jfs_dirent->name, 3299 jfs_dirent->name_len, filp->f_pos, 3300 jfs_dirent->ino, DT_UNKNOWN)) 3301 goto out; 3302 jfs_dirent = next_jfs_dirent(jfs_dirent); 3303 } 3304 3305 if (fix_page) { 3306 add_missing_indices(ip, bn); 3307 page_fixed = 1; 3308 } 3309 3310 if (!overflow && (bn == 0)) { 3311 filp->f_pos = DIREND; 3312 break; 3313 } 3314 3315 DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 3316 if (rc) { 3317 free_page(dirent_buf); 3318 return rc; 3319 } 3320 } 3321 3322 out: 3323 free_page(dirent_buf); 3324 3325 return rc; 3326 } 3327 3328 3329 /* 3330 * dtReadFirst() 3331 * 3332 * function: get the leftmost page of the directory 3333 */ 3334 static int dtReadFirst(struct inode *ip, struct btstack * btstack) 3335 { 3336 int rc = 0; 3337 s64 bn; 3338 int psize = 288; /* initial in-line directory */ 3339 struct metapage *mp; 3340 dtpage_t *p; 3341 s8 *stbl; 3342 struct btframe *btsp; 3343 pxd_t *xd; 3344 3345 BT_CLR(btstack); /* reset stack */ 3346 3347 /* 3348 * descend leftmost path of the tree 3349 * 3350 * by convention, root bn = 0. 3351 */ 3352 for (bn = 0;;) { 3353 DT_GETPAGE(ip, bn, mp, psize, p, rc); 3354 if (rc) 3355 return rc; 3356 3357 /* 3358 * leftmost leaf page 3359 */ 3360 if (p->header.flag & BT_LEAF) { 3361 /* return leftmost entry */ 3362 btsp = btstack->top; 3363 btsp->bn = bn; 3364 btsp->index = 0; 3365 btsp->mp = mp; 3366 3367 return 0; 3368 } 3369 3370 /* 3371 * descend down to leftmost child page 3372 */ 3373 if (BT_STACK_FULL(btstack)) { 3374 DT_PUTPAGE(mp); 3375 jfs_error(ip->i_sb, "dtReadFirst: btstack overrun"); 3376 BT_STACK_DUMP(btstack); 3377 return -EIO; 3378 } 3379 /* push (bn, index) of the parent page/entry */ 3380 BT_PUSH(btstack, bn, 0); 3381 3382 /* get the leftmost entry */ 3383 stbl = DT_GETSTBL(p); 3384 xd = (pxd_t *) & p->slot[stbl[0]]; 3385 3386 /* get the child page block address */ 3387 bn = addressPXD(xd); 3388 psize = lengthPXD(xd) << JFS_SBI(ip->i_sb)->l2bsize; 3389 3390 /* unpin the parent page */ 3391 DT_PUTPAGE(mp); 3392 } 3393 } 3394 3395 3396 /* 3397 * dtReadNext() 3398 * 3399 * function: get the page of the specified offset (pn:index) 3400 * 3401 * return: if (offset > eof), bn = -1; 3402 * 3403 * note: if index > nextindex of the target leaf page, 3404 * start with 1st entry of next leaf page; 3405 */ 3406 static int dtReadNext(struct inode *ip, loff_t * offset, 3407 struct btstack * btstack) 3408 { 3409 int rc = 0; 3410 struct dtoffset { 3411 s16 pn; 3412 s16 index; 3413 s32 unused; 3414 } *dtoffset = (struct dtoffset *) offset; 3415 s64 bn; 3416 struct metapage *mp; 3417 dtpage_t *p; 3418 int index; 3419 int pn; 3420 s8 *stbl; 3421 struct btframe *btsp, *parent; 3422 pxd_t *xd; 3423 3424 /* 3425 * get leftmost leaf page pinned 3426 */ 3427 if ((rc = dtReadFirst(ip, btstack))) 3428 return rc; 3429 3430 /* get leaf page */ 3431 DT_GETSEARCH(ip, btstack->top, bn, mp, p, index); 3432 3433 /* get the start offset (pn:index) */ 3434 pn = dtoffset->pn - 1; /* Now pn = 0 represents leftmost leaf */ 3435 index = dtoffset->index; 3436 3437 /* start at leftmost page ? */ 3438 if (pn == 0) { 3439 /* offset beyond eof ? */ 3440 if (index < p->header.nextindex) 3441 goto out; 3442 3443 if (p->header.flag & BT_ROOT) { 3444 bn = -1; 3445 goto out; 3446 } 3447 3448 /* start with 1st entry of next leaf page */ 3449 dtoffset->pn++; 3450 dtoffset->index = index = 0; 3451 goto a; 3452 } 3453 3454 /* start at non-leftmost page: scan parent pages for large pn */ 3455 if (p->header.flag & BT_ROOT) { 3456 bn = -1; 3457 goto out; 3458 } 3459 3460 /* start after next leaf page ? */ 3461 if (pn > 1) 3462 goto b; 3463 3464 /* get leaf page pn = 1 */ 3465 a: 3466 bn = le64_to_cpu(p->header.next); 3467 3468 /* unpin leaf page */ 3469 DT_PUTPAGE(mp); 3470 3471 /* offset beyond eof ? */ 3472 if (bn == 0) { 3473 bn = -1; 3474 goto out; 3475 } 3476 3477 goto c; 3478 3479 /* 3480 * scan last internal page level to get target leaf page 3481 */ 3482 b: 3483 /* unpin leftmost leaf page */ 3484 DT_PUTPAGE(mp); 3485 3486 /* get left most parent page */ 3487 btsp = btstack->top; 3488 parent = btsp - 1; 3489 bn = parent->bn; 3490 DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 3491 if (rc) 3492 return rc; 3493 3494 /* scan parent pages at last internal page level */ 3495 while (pn >= p->header.nextindex) { 3496 pn -= p->header.nextindex; 3497 3498 /* get next parent page address */ 3499 bn = le64_to_cpu(p->header.next); 3500 3501 /* unpin current parent page */ 3502 DT_PUTPAGE(mp); 3503 3504 /* offset beyond eof ? */ 3505 if (bn == 0) { 3506 bn = -1; 3507 goto out; 3508 } 3509 3510 /* get next parent page */ 3511 DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 3512 if (rc) 3513 return rc; 3514 3515 /* update parent page stack frame */ 3516 parent->bn = bn; 3517 } 3518 3519 /* get leaf page address */ 3520 stbl = DT_GETSTBL(p); 3521 xd = (pxd_t *) & p->slot[stbl[pn]]; 3522 bn = addressPXD(xd); 3523 3524 /* unpin parent page */ 3525 DT_PUTPAGE(mp); 3526 3527 /* 3528 * get target leaf page 3529 */ 3530 c: 3531 DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 3532 if (rc) 3533 return rc; 3534 3535 /* 3536 * leaf page has been completed: 3537 * start with 1st entry of next leaf page 3538 */ 3539 if (index >= p->header.nextindex) { 3540 bn = le64_to_cpu(p->header.next); 3541 3542 /* unpin leaf page */ 3543 DT_PUTPAGE(mp); 3544 3545 /* offset beyond eof ? */ 3546 if (bn == 0) { 3547 bn = -1; 3548 goto out; 3549 } 3550 3551 /* get next leaf page */ 3552 DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); 3553 if (rc) 3554 return rc; 3555 3556 /* start with 1st entry of next leaf page */ 3557 dtoffset->pn++; 3558 dtoffset->index = 0; 3559 } 3560 3561 out: 3562 /* return target leaf page pinned */ 3563 btsp = btstack->top; 3564 btsp->bn = bn; 3565 btsp->index = dtoffset->index; 3566 btsp->mp = mp; 3567 3568 return 0; 3569 } 3570 3571 3572 /* 3573 * dtCompare() 3574 * 3575 * function: compare search key with an internal entry 3576 * 3577 * return: 3578 * < 0 if k is < record 3579 * = 0 if k is = record 3580 * > 0 if k is > record 3581 */ 3582 static int dtCompare(struct component_name * key, /* search key */ 3583 dtpage_t * p, /* directory page */ 3584 int si) 3585 { /* entry slot index */ 3586 wchar_t *kname; 3587 __le16 *name; 3588 int klen, namlen, len, rc; 3589 struct idtentry *ih; 3590 struct dtslot *t; 3591 3592 /* 3593 * force the left-most key on internal pages, at any level of 3594 * the tree, to be less than any search key. 3595 * this obviates having to update the leftmost key on an internal 3596 * page when the user inserts a new key in the tree smaller than 3597 * anything that has been stored. 3598 * 3599 * (? if/when dtSearch() narrows down to 1st entry (index = 0), 3600 * at any internal page at any level of the tree, 3601 * it descends to child of the entry anyway - 3602 * ? make the entry as min size dummy entry) 3603 * 3604 * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF)) 3605 * return (1); 3606 */ 3607 3608 kname = key->name; 3609 klen = key->namlen; 3610 3611 ih = (struct idtentry *) & p->slot[si]; 3612 si = ih->next; 3613 name = ih->name; 3614 namlen = ih->namlen; 3615 len = min(namlen, DTIHDRDATALEN); 3616 3617 /* compare with head/only segment */ 3618 len = min(klen, len); 3619 if ((rc = UniStrncmp_le(kname, name, len))) 3620 return rc; 3621 3622 klen -= len; 3623 namlen -= len; 3624 3625 /* compare with additional segment(s) */ 3626 kname += len; 3627 while (klen > 0 && namlen > 0) { 3628 /* compare with next name segment */ 3629 t = (struct dtslot *) & p->slot[si]; 3630 len = min(namlen, DTSLOTDATALEN); 3631 len = min(klen, len); 3632 name = t->name; 3633 if ((rc = UniStrncmp_le(kname, name, len))) 3634 return rc; 3635 3636 klen -= len; 3637 namlen -= len; 3638 kname += len; 3639 si = t->next; 3640 } 3641 3642 return (klen - namlen); 3643 } 3644 3645 3646 3647 3648 /* 3649 * ciCompare() 3650 * 3651 * function: compare search key with an (leaf/internal) entry 3652 * 3653 * return: 3654 * < 0 if k is < record 3655 * = 0 if k is = record 3656 * > 0 if k is > record 3657 */ 3658 static int ciCompare(struct component_name * key, /* search key */ 3659 dtpage_t * p, /* directory page */ 3660 int si, /* entry slot index */ 3661 int flag) 3662 { 3663 wchar_t *kname, x; 3664 __le16 *name; 3665 int klen, namlen, len, rc; 3666 struct ldtentry *lh; 3667 struct idtentry *ih; 3668 struct dtslot *t; 3669 int i; 3670 3671 /* 3672 * force the left-most key on internal pages, at any level of 3673 * the tree, to be less than any search key. 3674 * this obviates having to update the leftmost key on an internal 3675 * page when the user inserts a new key in the tree smaller than 3676 * anything that has been stored. 3677 * 3678 * (? if/when dtSearch() narrows down to 1st entry (index = 0), 3679 * at any internal page at any level of the tree, 3680 * it descends to child of the entry anyway - 3681 * ? make the entry as min size dummy entry) 3682 * 3683 * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF)) 3684 * return (1); 3685 */ 3686 3687 kname = key->name; 3688 klen = key->namlen; 3689 3690 /* 3691 * leaf page entry 3692 */ 3693 if (p->header.flag & BT_LEAF) { 3694 lh = (struct ldtentry *) & p->slot[si]; 3695 si = lh->next; 3696 name = lh->name; 3697 namlen = lh->namlen; 3698 if (flag & JFS_DIR_INDEX) 3699 len = min(namlen, DTLHDRDATALEN); 3700 else 3701 len = min(namlen, DTLHDRDATALEN_LEGACY); 3702 } 3703 /* 3704 * internal page entry 3705 */ 3706 else { 3707 ih = (struct idtentry *) & p->slot[si]; 3708 si = ih->next; 3709 name = ih->name; 3710 namlen = ih->namlen; 3711 len = min(namlen, DTIHDRDATALEN); 3712 } 3713 3714 /* compare with head/only segment */ 3715 len = min(klen, len); 3716 for (i = 0; i < len; i++, kname++, name++) { 3717 /* only uppercase if case-insensitive support is on */ 3718 if ((flag & JFS_OS2) == JFS_OS2) 3719 x = UniToupper(le16_to_cpu(*name)); 3720 else 3721 x = le16_to_cpu(*name); 3722 if ((rc = *kname - x)) 3723 return rc; 3724 } 3725 3726 klen -= len; 3727 namlen -= len; 3728 3729 /* compare with additional segment(s) */ 3730 while (klen > 0 && namlen > 0) { 3731 /* compare with next name segment */ 3732 t = (struct dtslot *) & p->slot[si]; 3733 len = min(namlen, DTSLOTDATALEN); 3734 len = min(klen, len); 3735 name = t->name; 3736 for (i = 0; i < len; i++, kname++, name++) { 3737 /* only uppercase if case-insensitive support is on */ 3738 if ((flag & JFS_OS2) == JFS_OS2) 3739 x = UniToupper(le16_to_cpu(*name)); 3740 else 3741 x = le16_to_cpu(*name); 3742 3743 if ((rc = *kname - x)) 3744 return rc; 3745 } 3746 3747 klen -= len; 3748 namlen -= len; 3749 si = t->next; 3750 } 3751 3752 return (klen - namlen); 3753 } 3754 3755 3756 /* 3757 * ciGetLeafPrefixKey() 3758 * 3759 * function: compute prefix of suffix compression 3760 * from two adjacent leaf entries 3761 * across page boundary 3762 * 3763 * return: non-zero on error 3764 * 3765 */ 3766 static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp, 3767 int ri, struct component_name * key, int flag) 3768 { 3769 int klen, namlen; 3770 wchar_t *pl, *pr, *kname; 3771 struct component_name lkey; 3772 struct component_name rkey; 3773 3774 lkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), 3775 GFP_KERNEL); 3776 if (lkey.name == NULL) 3777 return -ENOMEM; 3778 3779 rkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), 3780 GFP_KERNEL); 3781 if (rkey.name == NULL) { 3782 kfree(lkey.name); 3783 return -ENOMEM; 3784 } 3785 3786 /* get left and right key */ 3787 dtGetKey(lp, li, &lkey, flag); 3788 lkey.name[lkey.namlen] = 0; 3789 3790 if ((flag & JFS_OS2) == JFS_OS2) 3791 ciToUpper(&lkey); 3792 3793 dtGetKey(rp, ri, &rkey, flag); 3794 rkey.name[rkey.namlen] = 0; 3795 3796 3797 if ((flag & JFS_OS2) == JFS_OS2) 3798 ciToUpper(&rkey); 3799 3800 /* compute prefix */ 3801 klen = 0; 3802 kname = key->name; 3803 namlen = min(lkey.namlen, rkey.namlen); 3804 for (pl = lkey.name, pr = rkey.name; 3805 namlen; pl++, pr++, namlen--, klen++, kname++) { 3806 *kname = *pr; 3807 if (*pl != *pr) { 3808 key->namlen = klen + 1; 3809 goto free_names; 3810 } 3811 } 3812 3813 /* l->namlen <= r->namlen since l <= r */ 3814 if (lkey.namlen < rkey.namlen) { 3815 *kname = *pr; 3816 key->namlen = klen + 1; 3817 } else /* l->namelen == r->namelen */ 3818 key->namlen = klen; 3819 3820 free_names: 3821 kfree(lkey.name); 3822 kfree(rkey.name); 3823 return 0; 3824 } 3825 3826 3827 3828 /* 3829 * dtGetKey() 3830 * 3831 * function: get key of the entry 3832 */ 3833 static void dtGetKey(dtpage_t * p, int i, /* entry index */ 3834 struct component_name * key, int flag) 3835 { 3836 int si; 3837 s8 *stbl; 3838 struct ldtentry *lh; 3839 struct idtentry *ih; 3840 struct dtslot *t; 3841 int namlen, len; 3842 wchar_t *kname; 3843 __le16 *name; 3844 3845 /* get entry */ 3846 stbl = DT_GETSTBL(p); 3847 si = stbl[i]; 3848 if (p->header.flag & BT_LEAF) { 3849 lh = (struct ldtentry *) & p->slot[si]; 3850 si = lh->next; 3851 namlen = lh->namlen; 3852 name = lh->name; 3853 if (flag & JFS_DIR_INDEX) 3854 len = min(namlen, DTLHDRDATALEN); 3855 else 3856 len = min(namlen, DTLHDRDATALEN_LEGACY); 3857 } else { 3858 ih = (struct idtentry *) & p->slot[si]; 3859 si = ih->next; 3860 namlen = ih->namlen; 3861 name = ih->name; 3862 len = min(namlen, DTIHDRDATALEN); 3863 } 3864 3865 key->namlen = namlen; 3866 kname = key->name; 3867 3868 /* 3869 * move head/only segment 3870 */ 3871 UniStrncpy_from_le(kname, name, len); 3872 3873 /* 3874 * move additional segment(s) 3875 */ 3876 while (si >= 0) { 3877 /* get next segment */ 3878 t = &p->slot[si]; 3879 kname += len; 3880 namlen -= len; 3881 len = min(namlen, DTSLOTDATALEN); 3882 UniStrncpy_from_le(kname, t->name, len); 3883 3884 si = t->next; 3885 } 3886 } 3887 3888 3889 /* 3890 * dtInsertEntry() 3891 * 3892 * function: allocate free slot(s) and 3893 * write a leaf/internal entry 3894 * 3895 * return: entry slot index 3896 */ 3897 static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key, 3898 ddata_t * data, struct dt_lock ** dtlock) 3899 { 3900 struct dtslot *h, *t; 3901 struct ldtentry *lh = NULL; 3902 struct idtentry *ih = NULL; 3903 int hsi, fsi, klen, len, nextindex; 3904 wchar_t *kname; 3905 __le16 *name; 3906 s8 *stbl; 3907 pxd_t *xd; 3908 struct dt_lock *dtlck = *dtlock; 3909 struct lv *lv; 3910 int xsi, n; 3911 s64 bn = 0; 3912 struct metapage *mp = NULL; 3913 3914 klen = key->namlen; 3915 kname = key->name; 3916 3917 /* allocate a free slot */ 3918 hsi = fsi = p->header.freelist; 3919 h = &p->slot[fsi]; 3920 p->header.freelist = h->next; 3921 --p->header.freecnt; 3922 3923 /* open new linelock */ 3924 if (dtlck->index >= dtlck->maxcnt) 3925 dtlck = (struct dt_lock *) txLinelock(dtlck); 3926 3927 lv = & dtlck->lv[dtlck->index]; 3928 lv->offset = hsi; 3929 3930 /* write head/only segment */ 3931 if (p->header.flag & BT_LEAF) { 3932 lh = (struct ldtentry *) h; 3933 lh->next = h->next; 3934 lh->inumber = cpu_to_le32(data->leaf.ino); 3935 lh->namlen = klen; 3936 name = lh->name; 3937 if (data->leaf.ip) { 3938 len = min(klen, DTLHDRDATALEN); 3939 if (!(p->header.flag & BT_ROOT)) 3940 bn = addressPXD(&p->header.self); 3941 lh->index = cpu_to_le32(add_index(data->leaf.tid, 3942 data->leaf.ip, 3943 bn, index)); 3944 } else 3945 len = min(klen, DTLHDRDATALEN_LEGACY); 3946 } else { 3947 ih = (struct idtentry *) h; 3948 ih->next = h->next; 3949 xd = (pxd_t *) ih; 3950 *xd = data->xd; 3951 ih->namlen = klen; 3952 name = ih->name; 3953 len = min(klen, DTIHDRDATALEN); 3954 } 3955 3956 UniStrncpy_to_le(name, kname, len); 3957 3958 n = 1; 3959 xsi = hsi; 3960 3961 /* write additional segment(s) */ 3962 t = h; 3963 klen -= len; 3964 while (klen) { 3965 /* get free slot */ 3966 fsi = p->header.freelist; 3967 t = &p->slot[fsi]; 3968 p->header.freelist = t->next; 3969 --p->header.freecnt; 3970 3971 /* is next slot contiguous ? */ 3972 if (fsi != xsi + 1) { 3973 /* close current linelock */ 3974 lv->length = n; 3975 dtlck->index++; 3976 3977 /* open new linelock */ 3978 if (dtlck->index < dtlck->maxcnt) 3979 lv++; 3980 else { 3981 dtlck = (struct dt_lock *) txLinelock(dtlck); 3982 lv = & dtlck->lv[0]; 3983 } 3984 3985 lv->offset = fsi; 3986 n = 0; 3987 } 3988 3989 kname += len; 3990 len = min(klen, DTSLOTDATALEN); 3991 UniStrncpy_to_le(t->name, kname, len); 3992 3993 n++; 3994 xsi = fsi; 3995 klen -= len; 3996 } 3997 3998 /* close current linelock */ 3999 lv->length = n; 4000 dtlck->index++; 4001 4002 *dtlock = dtlck; 4003 4004 /* terminate last/only segment */ 4005 if (h == t) { 4006 /* single segment entry */ 4007 if (p->header.flag & BT_LEAF) 4008 lh->next = -1; 4009 else 4010 ih->next = -1; 4011 } else 4012 /* multi-segment entry */ 4013 t->next = -1; 4014 4015 /* if insert into middle, shift right succeeding entries in stbl */ 4016 stbl = DT_GETSTBL(p); 4017 nextindex = p->header.nextindex; 4018 if (index < nextindex) { 4019 memmove(stbl + index + 1, stbl + index, nextindex - index); 4020 4021 if ((p->header.flag & BT_LEAF) && data->leaf.ip) { 4022 s64 lblock; 4023 4024 /* 4025 * Need to update slot number for entries that moved 4026 * in the stbl 4027 */ 4028 mp = NULL; 4029 for (n = index + 1; n <= nextindex; n++) { 4030 lh = (struct ldtentry *) & (p->slot[stbl[n]]); 4031 modify_index(data->leaf.tid, data->leaf.ip, 4032 le32_to_cpu(lh->index), bn, n, 4033 &mp, &lblock); 4034 } 4035 if (mp) 4036 release_metapage(mp); 4037 } 4038 } 4039 4040 stbl[index] = hsi; 4041 4042 /* advance next available entry index of stbl */ 4043 ++p->header.nextindex; 4044 } 4045 4046 4047 /* 4048 * dtMoveEntry() 4049 * 4050 * function: move entries from split/left page to new/right page 4051 * 4052 * nextindex of dst page and freelist/freecnt of both pages 4053 * are updated. 4054 */ 4055 static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp, 4056 struct dt_lock ** sdtlock, struct dt_lock ** ddtlock, 4057 int do_index) 4058 { 4059 int ssi, next; /* src slot index */ 4060 int di; /* dst entry index */ 4061 int dsi; /* dst slot index */ 4062 s8 *sstbl, *dstbl; /* sorted entry table */ 4063 int snamlen, len; 4064 struct ldtentry *slh, *dlh = NULL; 4065 struct idtentry *sih, *dih = NULL; 4066 struct dtslot *h, *s, *d; 4067 struct dt_lock *sdtlck = *sdtlock, *ddtlck = *ddtlock; 4068 struct lv *slv, *dlv; 4069 int xssi, ns, nd; 4070 int sfsi; 4071 4072 sstbl = (s8 *) & sp->slot[sp->header.stblindex]; 4073 dstbl = (s8 *) & dp->slot[dp->header.stblindex]; 4074 4075 dsi = dp->header.freelist; /* first (whole page) free slot */ 4076 sfsi = sp->header.freelist; 4077 4078 /* linelock destination entry slot */ 4079 dlv = & ddtlck->lv[ddtlck->index]; 4080 dlv->offset = dsi; 4081 4082 /* linelock source entry slot */ 4083 slv = & sdtlck->lv[sdtlck->index]; 4084 slv->offset = sstbl[si]; 4085 xssi = slv->offset - 1; 4086 4087 /* 4088 * move entries 4089 */ 4090 ns = nd = 0; 4091 for (di = 0; si < sp->header.nextindex; si++, di++) { 4092 ssi = sstbl[si]; 4093 dstbl[di] = dsi; 4094 4095 /* is next slot contiguous ? */ 4096 if (ssi != xssi + 1) { 4097 /* close current linelock */ 4098 slv->length = ns; 4099 sdtlck->index++; 4100 4101 /* open new linelock */ 4102 if (sdtlck->index < sdtlck->maxcnt) 4103 slv++; 4104 else { 4105 sdtlck = (struct dt_lock *) txLinelock(sdtlck); 4106 slv = & sdtlck->lv[0]; 4107 } 4108 4109 slv->offset = ssi; 4110 ns = 0; 4111 } 4112 4113 /* 4114 * move head/only segment of an entry 4115 */ 4116 /* get dst slot */ 4117 h = d = &dp->slot[dsi]; 4118 4119 /* get src slot and move */ 4120 s = &sp->slot[ssi]; 4121 if (sp->header.flag & BT_LEAF) { 4122 /* get source entry */ 4123 slh = (struct ldtentry *) s; 4124 dlh = (struct ldtentry *) h; 4125 snamlen = slh->namlen; 4126 4127 if (do_index) { 4128 len = min(snamlen, DTLHDRDATALEN); 4129 dlh->index = slh->index; /* little-endian */ 4130 } else 4131 len = min(snamlen, DTLHDRDATALEN_LEGACY); 4132 4133 memcpy(dlh, slh, 6 + len * 2); 4134 4135 next = slh->next; 4136 4137 /* update dst head/only segment next field */ 4138 dsi++; 4139 dlh->next = dsi; 4140 } else { 4141 sih = (struct idtentry *) s; 4142 snamlen = sih->namlen; 4143 4144 len = min(snamlen, DTIHDRDATALEN); 4145 dih = (struct idtentry *) h; 4146 memcpy(dih, sih, 10 + len * 2); 4147 next = sih->next; 4148 4149 dsi++; 4150 dih->next = dsi; 4151 } 4152 4153 /* free src head/only segment */ 4154 s->next = sfsi; 4155 s->cnt = 1; 4156 sfsi = ssi; 4157 4158 ns++; 4159 nd++; 4160 xssi = ssi; 4161 4162 /* 4163 * move additional segment(s) of the entry 4164 */ 4165 snamlen -= len; 4166 while ((ssi = next) >= 0) { 4167 /* is next slot contiguous ? */ 4168 if (ssi != xssi + 1) { 4169 /* close current linelock */ 4170 slv->length = ns; 4171 sdtlck->index++; 4172 4173 /* open new linelock */ 4174 if (sdtlck->index < sdtlck->maxcnt) 4175 slv++; 4176 else { 4177 sdtlck = 4178 (struct dt_lock *) 4179 txLinelock(sdtlck); 4180 slv = & sdtlck->lv[0]; 4181 } 4182 4183 slv->offset = ssi; 4184 ns = 0; 4185 } 4186 4187 /* get next source segment */ 4188 s = &sp->slot[ssi]; 4189 4190 /* get next destination free slot */ 4191 d++; 4192 4193 len = min(snamlen, DTSLOTDATALEN); 4194 UniStrncpy_le(d->name, s->name, len); 4195 4196 ns++; 4197 nd++; 4198 xssi = ssi; 4199 4200 dsi++; 4201 d->next = dsi; 4202 4203 /* free source segment */ 4204 next = s->next; 4205 s->next = sfsi; 4206 s->cnt = 1; 4207 sfsi = ssi; 4208 4209 snamlen -= len; 4210 } /* end while */ 4211 4212 /* terminate dst last/only segment */ 4213 if (h == d) { 4214 /* single segment entry */ 4215 if (dp->header.flag & BT_LEAF) 4216 dlh->next = -1; 4217 else 4218 dih->next = -1; 4219 } else 4220 /* multi-segment entry */ 4221 d->next = -1; 4222 } /* end for */ 4223 4224 /* close current linelock */ 4225 slv->length = ns; 4226 sdtlck->index++; 4227 *sdtlock = sdtlck; 4228 4229 dlv->length = nd; 4230 ddtlck->index++; 4231 *ddtlock = ddtlck; 4232 4233 /* update source header */ 4234 sp->header.freelist = sfsi; 4235 sp->header.freecnt += nd; 4236 4237 /* update destination header */ 4238 dp->header.nextindex = di; 4239 4240 dp->header.freelist = dsi; 4241 dp->header.freecnt -= nd; 4242 } 4243 4244 4245 /* 4246 * dtDeleteEntry() 4247 * 4248 * function: free a (leaf/internal) entry 4249 * 4250 * log freelist header, stbl, and each segment slot of entry 4251 * (even though last/only segment next field is modified, 4252 * physical image logging requires all segment slots of 4253 * the entry logged to avoid applying previous updates 4254 * to the same slots) 4255 */ 4256 static void dtDeleteEntry(dtpage_t * p, int fi, struct dt_lock ** dtlock) 4257 { 4258 int fsi; /* free entry slot index */ 4259 s8 *stbl; 4260 struct dtslot *t; 4261 int si, freecnt; 4262 struct dt_lock *dtlck = *dtlock; 4263 struct lv *lv; 4264 int xsi, n; 4265 4266 /* get free entry slot index */ 4267 stbl = DT_GETSTBL(p); 4268 fsi = stbl[fi]; 4269 4270 /* open new linelock */ 4271 if (dtlck->index >= dtlck->maxcnt) 4272 dtlck = (struct dt_lock *) txLinelock(dtlck); 4273 lv = & dtlck->lv[dtlck->index]; 4274 4275 lv->offset = fsi; 4276 4277 /* get the head/only segment */ 4278 t = &p->slot[fsi]; 4279 if (p->header.flag & BT_LEAF) 4280 si = ((struct ldtentry *) t)->next; 4281 else 4282 si = ((struct idtentry *) t)->next; 4283 t->next = si; 4284 t->cnt = 1; 4285 4286 n = freecnt = 1; 4287 xsi = fsi; 4288 4289 /* find the last/only segment */ 4290 while (si >= 0) { 4291 /* is next slot contiguous ? */ 4292 if (si != xsi + 1) { 4293 /* close current linelock */ 4294 lv->length = n; 4295 dtlck->index++; 4296 4297 /* open new linelock */ 4298 if (dtlck->index < dtlck->maxcnt) 4299 lv++; 4300 else { 4301 dtlck = (struct dt_lock *) txLinelock(dtlck); 4302 lv = & dtlck->lv[0]; 4303 } 4304 4305 lv->offset = si; 4306 n = 0; 4307 } 4308 4309 n++; 4310 xsi = si; 4311 freecnt++; 4312 4313 t = &p->slot[si]; 4314 t->cnt = 1; 4315 si = t->next; 4316 } 4317 4318 /* close current linelock */ 4319 lv->length = n; 4320 dtlck->index++; 4321 4322 *dtlock = dtlck; 4323 4324 /* update freelist */ 4325 t->next = p->header.freelist; 4326 p->header.freelist = fsi; 4327 p->header.freecnt += freecnt; 4328 4329 /* if delete from middle, 4330 * shift left the succedding entries in the stbl 4331 */ 4332 si = p->header.nextindex; 4333 if (fi < si - 1) 4334 memmove(&stbl[fi], &stbl[fi + 1], si - fi - 1); 4335 4336 p->header.nextindex--; 4337 } 4338 4339 4340 /* 4341 * dtTruncateEntry() 4342 * 4343 * function: truncate a (leaf/internal) entry 4344 * 4345 * log freelist header, stbl, and each segment slot of entry 4346 * (even though last/only segment next field is modified, 4347 * physical image logging requires all segment slots of 4348 * the entry logged to avoid applying previous updates 4349 * to the same slots) 4350 */ 4351 static void dtTruncateEntry(dtpage_t * p, int ti, struct dt_lock ** dtlock) 4352 { 4353 int tsi; /* truncate entry slot index */ 4354 s8 *stbl; 4355 struct dtslot *t; 4356 int si, freecnt; 4357 struct dt_lock *dtlck = *dtlock; 4358 struct lv *lv; 4359 int fsi, xsi, n; 4360 4361 /* get free entry slot index */ 4362 stbl = DT_GETSTBL(p); 4363 tsi = stbl[ti]; 4364 4365 /* open new linelock */ 4366 if (dtlck->index >= dtlck->maxcnt) 4367 dtlck = (struct dt_lock *) txLinelock(dtlck); 4368 lv = & dtlck->lv[dtlck->index]; 4369 4370 lv->offset = tsi; 4371 4372 /* get the head/only segment */ 4373 t = &p->slot[tsi]; 4374 ASSERT(p->header.flag & BT_INTERNAL); 4375 ((struct idtentry *) t)->namlen = 0; 4376 si = ((struct idtentry *) t)->next; 4377 ((struct idtentry *) t)->next = -1; 4378 4379 n = 1; 4380 freecnt = 0; 4381 fsi = si; 4382 xsi = tsi; 4383 4384 /* find the last/only segment */ 4385 while (si >= 0) { 4386 /* is next slot contiguous ? */ 4387 if (si != xsi + 1) { 4388 /* close current linelock */ 4389 lv->length = n; 4390 dtlck->index++; 4391 4392 /* open new linelock */ 4393 if (dtlck->index < dtlck->maxcnt) 4394 lv++; 4395 else { 4396 dtlck = (struct dt_lock *) txLinelock(dtlck); 4397 lv = & dtlck->lv[0]; 4398 } 4399 4400 lv->offset = si; 4401 n = 0; 4402 } 4403 4404 n++; 4405 xsi = si; 4406 freecnt++; 4407 4408 t = &p->slot[si]; 4409 t->cnt = 1; 4410 si = t->next; 4411 } 4412 4413 /* close current linelock */ 4414 lv->length = n; 4415 dtlck->index++; 4416 4417 *dtlock = dtlck; 4418 4419 /* update freelist */ 4420 if (freecnt == 0) 4421 return; 4422 t->next = p->header.freelist; 4423 p->header.freelist = fsi; 4424 p->header.freecnt += freecnt; 4425 } 4426 4427 4428 /* 4429 * dtLinelockFreelist() 4430 */ 4431 static void dtLinelockFreelist(dtpage_t * p, /* directory page */ 4432 int m, /* max slot index */ 4433 struct dt_lock ** dtlock) 4434 { 4435 int fsi; /* free entry slot index */ 4436 struct dtslot *t; 4437 int si; 4438 struct dt_lock *dtlck = *dtlock; 4439 struct lv *lv; 4440 int xsi, n; 4441 4442 /* get free entry slot index */ 4443 fsi = p->header.freelist; 4444 4445 /* open new linelock */ 4446 if (dtlck->index >= dtlck->maxcnt) 4447 dtlck = (struct dt_lock *) txLinelock(dtlck); 4448 lv = & dtlck->lv[dtlck->index]; 4449 4450 lv->offset = fsi; 4451 4452 n = 1; 4453 xsi = fsi; 4454 4455 t = &p->slot[fsi]; 4456 si = t->next; 4457 4458 /* find the last/only segment */ 4459 while (si < m && si >= 0) { 4460 /* is next slot contiguous ? */ 4461 if (si != xsi + 1) { 4462 /* close current linelock */ 4463 lv->length = n; 4464 dtlck->index++; 4465 4466 /* open new linelock */ 4467 if (dtlck->index < dtlck->maxcnt) 4468 lv++; 4469 else { 4470 dtlck = (struct dt_lock *) txLinelock(dtlck); 4471 lv = & dtlck->lv[0]; 4472 } 4473 4474 lv->offset = si; 4475 n = 0; 4476 } 4477 4478 n++; 4479 xsi = si; 4480 4481 t = &p->slot[si]; 4482 si = t->next; 4483 } 4484 4485 /* close current linelock */ 4486 lv->length = n; 4487 dtlck->index++; 4488 4489 *dtlock = dtlck; 4490 } 4491 4492 4493 /* 4494 * NAME: dtModify 4495 * 4496 * FUNCTION: Modify the inode number part of a directory entry 4497 * 4498 * PARAMETERS: 4499 * tid - Transaction id 4500 * ip - Inode of parent directory 4501 * key - Name of entry to be modified 4502 * orig_ino - Original inode number expected in entry 4503 * new_ino - New inode number to put into entry 4504 * flag - JFS_RENAME 4505 * 4506 * RETURNS: 4507 * -ESTALE - If entry found does not match orig_ino passed in 4508 * -ENOENT - If no entry can be found to match key 4509 * 0 - If successfully modified entry 4510 */ 4511 int dtModify(tid_t tid, struct inode *ip, 4512 struct component_name * key, ino_t * orig_ino, ino_t new_ino, int flag) 4513 { 4514 int rc; 4515 s64 bn; 4516 struct metapage *mp; 4517 dtpage_t *p; 4518 int index; 4519 struct btstack btstack; 4520 struct tlock *tlck; 4521 struct dt_lock *dtlck; 4522 struct lv *lv; 4523 s8 *stbl; 4524 int entry_si; /* entry slot index */ 4525 struct ldtentry *entry; 4526 4527 /* 4528 * search for the entry to modify: 4529 * 4530 * dtSearch() returns (leaf page pinned, index at which to modify). 4531 */ 4532 if ((rc = dtSearch(ip, key, orig_ino, &btstack, flag))) 4533 return rc; 4534 4535 /* retrieve search result */ 4536 DT_GETSEARCH(ip, btstack.top, bn, mp, p, index); 4537 4538 BT_MARK_DIRTY(mp, ip); 4539 /* 4540 * acquire a transaction lock on the leaf page of named entry 4541 */ 4542 tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY); 4543 dtlck = (struct dt_lock *) & tlck->lock; 4544 4545 /* get slot index of the entry */ 4546 stbl = DT_GETSTBL(p); 4547 entry_si = stbl[index]; 4548 4549 /* linelock entry */ 4550 ASSERT(dtlck->index == 0); 4551 lv = & dtlck->lv[0]; 4552 lv->offset = entry_si; 4553 lv->length = 1; 4554 dtlck->index++; 4555 4556 /* get the head/only segment */ 4557 entry = (struct ldtentry *) & p->slot[entry_si]; 4558 4559 /* substitute the inode number of the entry */ 4560 entry->inumber = cpu_to_le32(new_ino); 4561 4562 /* unpin the leaf page */ 4563 DT_PUTPAGE(mp); 4564 4565 return 0; 4566 } 4567