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

Merge tag 'xfs-5.5-merge-16' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull XFS updates from Darrick Wong:
"For this release, we changed quite a few things.

Highlights:

- Fixed some long tail latency problems in the block allocator

- Removed some long deprecated (and for the past several years no-op)
mount options and ioctls

- Strengthened the extended attribute and directory verifiers

- Audited and fixed all the places where we could return EFSCORRUPTED
without logging anything

- Refactored the old SGI space allocation ioctls to make the
equivalent fallocate calls

- Fixed a race between fallocate and directio

- Fixed an integer overflow when files have more than a few
billion(!) extents

- Fixed a longstanding bug where quota accounting could be incorrect
when performing unwritten extent conversion on a freshly mounted fs

- Fixed various complaints in scrub about soft lockups and
unresponsiveness to signals

- De-vtable'd the directory handling code, which should make it
faster

- Converted to the new mount api, for better or for worse

- Cleaned up some memory leaks

and quite a lot of other smaller fixes and cleanups.

A more detailed summary:

- Fill out the build string

- Prevent inode fork extent count overflows

- Refactor the allocator to reduce long tail latency

- Rework incore log locking a little to reduce spinning

- Break up the xfs_iomap_begin functions into smaller more cohesive
parts

- Fix allocation alignment being dropped too early when the
allocation request is for more blocks than an AG is large

- Other small cleanups

- Clean up file buftarg retrieval helpers

- Hoist the resvsp and unresvsp ioctls to the vfs

- Remove the undocumented biosize mount option, since it has never
been mentioned as existing or supported on linux

- Clean up some of the mount option printing and parsing

- Enhance attr leaf verifier to check block structure

- Check dirent and attr names for invalid characters before passing
them to the vfs

- Refactor open-coded bmbt walking

- Fix a few places where we return EIO instead of EFSCORRUPTED after
failing metadata sanity checks

- Fix a synchronization problem between fallocate and aio dio
corrupting the file length

- Clean up various loose ends in the iomap and bmap code

- Convert to the new mount api

- Make sure we always log something when returning EFSCORRUPTED

- Fix some problems where long running scrub loops could trigger soft
lockup warnings and/or fail to exit due to fatal signals pending

- Fix various Coverity complaints

- Remove most of the function pointers from the directory code to
reduce indirection penalties

- Ensure that dquots are attached to the inode when performing
unwritten extent conversion after io

- Deuglify incore projid and crtime types

- Fix another AGI/AGF locking order deadlock when renaming

- Clean up some quota typedefs

- Remove the FSSETDM ioctls which haven't done anything in 20 years

- Fix some memory leaks when mounting the log fails

- Fix an underflow when updating an xattr leaf freemap

- Remove some trivial wrappers

- Report metadata corruption as an error, not a (potentially) fatal
assertion

- Clean up the dir/attr buffer mapping code

- Allow fatal signals to kill scrub during parent pointer checks"

* tag 'xfs-5.5-merge-16' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (198 commits)
xfs: allow parent directory scans to be interrupted with fatal signals
xfs: remove the mappedbno argument to xfs_da_get_buf
xfs: remove the mappedbno argument to xfs_da_read_buf
xfs: split xfs_da3_node_read
xfs: remove the mappedbno argument to xfs_dir3_leafn_read
xfs: remove the mappedbno argument to xfs_dir3_leaf_read
xfs: remove the mappedbno argument to xfs_attr3_leaf_read
xfs: remove the mappedbno argument to xfs_da_reada_buf
xfs: improve the xfs_dabuf_map calling conventions
xfs: refactor xfs_dabuf_map
xfs: simplify mappedbno handling in xfs_da_{get,read}_buf
xfs: report corruption only as a regular error
xfs: Remove kmem_zone_free() wrapper
xfs: Remove kmem_zone_destroy() wrapper
xfs: Remove slab init wrappers
xfs: fix attr leaf header freemap.size underflow
xfs: fix some memory leaks in log recovery
xfs: fix another missing include
xfs: remove XFS_IOC_FSSETDM and XFS_IOC_FSSETDM_BY_HANDLE
xfs: remove duplicated include from xfs_dir2_data.c
...

+5841 -6284
+14 -2
fs/compat_ioctl.c
··· 185 185 /* handled by some ->ioctl(); always a pointer to int */ 186 186 case FIONREAD: 187 187 goto found_handler; 188 - /* these two get messy on amd64 due to alignment differences */ 188 + /* these get messy on amd64 due to alignment differences */ 189 189 #if defined(CONFIG_X86_64) 190 190 case FS_IOC_RESVSP_32: 191 191 case FS_IOC_RESVSP64_32: 192 - error = compat_ioctl_preallocate(f.file, compat_ptr(arg)); 192 + error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg)); 193 + goto out_fput; 194 + case FS_IOC_UNRESVSP_32: 195 + case FS_IOC_UNRESVSP64_32: 196 + error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE, 197 + compat_ptr(arg)); 198 + goto out_fput; 199 + case FS_IOC_ZERO_RANGE_32: 200 + error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE, 201 + compat_ptr(arg)); 193 202 goto out_fput; 194 203 #else 195 204 case FS_IOC_RESVSP: 196 205 case FS_IOC_RESVSP64: 206 + case FS_IOC_UNRESVSP: 207 + case FS_IOC_UNRESVSP64: 208 + case FS_IOC_ZERO_RANGE: 197 209 goto found_handler; 198 210 #endif 199 211
+11 -5
fs/ioctl.c
··· 467 467 * Only the l_start, l_len and l_whence fields of the 'struct space_resv' 468 468 * are used here, rest are ignored. 469 469 */ 470 - int ioctl_preallocate(struct file *filp, void __user *argp) 470 + int ioctl_preallocate(struct file *filp, int mode, void __user *argp) 471 471 { 472 472 struct inode *inode = file_inode(filp); 473 473 struct space_resv sr; ··· 488 488 return -EINVAL; 489 489 } 490 490 491 - return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); 491 + return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, 492 + sr.l_len); 492 493 } 493 494 494 495 /* on ia32 l_start is on a 32-bit boundary */ 495 496 #if defined CONFIG_COMPAT && defined(CONFIG_X86_64) 496 497 /* just account for different alignment */ 497 - int compat_ioctl_preallocate(struct file *file, 498 + int compat_ioctl_preallocate(struct file *file, int mode, 498 499 struct space_resv_32 __user *argp) 499 500 { 500 501 struct inode *inode = file_inode(file); ··· 517 516 return -EINVAL; 518 517 } 519 518 520 - return vfs_fallocate(file, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); 519 + return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); 521 520 } 522 521 #endif 523 522 ··· 534 533 return put_user(i_size_read(inode) - filp->f_pos, p); 535 534 case FS_IOC_RESVSP: 536 535 case FS_IOC_RESVSP64: 537 - return ioctl_preallocate(filp, p); 536 + return ioctl_preallocate(filp, 0, p); 537 + case FS_IOC_UNRESVSP: 538 + case FS_IOC_UNRESVSP64: 539 + return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p); 540 + case FS_IOC_ZERO_RANGE: 541 + return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p); 538 542 } 539 543 540 544 return vfs_ioctl(filp, cmd, arg);
-1
fs/xfs/Makefile
··· 27 27 xfs_bmap_btree.o \ 28 28 xfs_btree.o \ 29 29 xfs_da_btree.o \ 30 - xfs_da_format.o \ 31 30 xfs_defer.o \ 32 31 xfs_dir2.o \ 33 32 xfs_dir2_block.o \
+1 -1
fs/xfs/kmem.c
··· 32 32 33 33 34 34 /* 35 - * __vmalloc() will allocate data pages and auxillary structures (e.g. 35 + * __vmalloc() will allocate data pages and auxiliary structures (e.g. 36 36 * pagetables) with GFP_KERNEL, yet we may be under GFP_NOFS context here. Hence 37 37 * we need to tell memory reclaim that we are in such a context via 38 38 * PF_MEMALLOC_NOFS to prevent memory reclaim re-entering the filesystem here
-30
fs/xfs/kmem.h
··· 78 78 * Zone interfaces 79 79 */ 80 80 81 - #define KM_ZONE_HWALIGN SLAB_HWCACHE_ALIGN 82 - #define KM_ZONE_RECLAIM SLAB_RECLAIM_ACCOUNT 83 - #define KM_ZONE_SPREAD SLAB_MEM_SPREAD 84 - #define KM_ZONE_ACCOUNT SLAB_ACCOUNT 85 - 86 81 #define kmem_zone kmem_cache 87 82 #define kmem_zone_t struct kmem_cache 88 - 89 - static inline kmem_zone_t * 90 - kmem_zone_init(int size, char *zone_name) 91 - { 92 - return kmem_cache_create(zone_name, size, 0, 0, NULL); 93 - } 94 - 95 - static inline kmem_zone_t * 96 - kmem_zone_init_flags(int size, char *zone_name, slab_flags_t flags, 97 - void (*construct)(void *)) 98 - { 99 - return kmem_cache_create(zone_name, size, 0, flags, construct); 100 - } 101 - 102 - static inline void 103 - kmem_zone_free(kmem_zone_t *zone, void *ptr) 104 - { 105 - kmem_cache_free(zone, ptr); 106 - } 107 - 108 - static inline void 109 - kmem_zone_destroy(kmem_zone_t *zone) 110 - { 111 - kmem_cache_destroy(zone); 112 - } 113 83 114 84 extern void *kmem_zone_alloc(kmem_zone_t *, xfs_km_flags_t); 115 85
+2
fs/xfs/libxfs/xfs_ag_resv.c
··· 19 19 #include "xfs_btree.h" 20 20 #include "xfs_refcount_btree.h" 21 21 #include "xfs_ialloc_btree.h" 22 + #include "xfs_sb.h" 23 + #include "xfs_ag_resv.h" 22 24 23 25 /* 24 26 * Per-AG Block Reservations
+752 -500
fs/xfs/libxfs/xfs_alloc.c
··· 146 146 xfs_extlen_t len, /* length of extent */ 147 147 int *stat) /* success/failure */ 148 148 { 149 + int error; 150 + 149 151 cur->bc_rec.a.ar_startblock = bno; 150 152 cur->bc_rec.a.ar_blockcount = len; 151 - return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); 153 + error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); 154 + cur->bc_private.a.priv.abt.active = (*stat == 1); 155 + return error; 152 156 } 153 157 154 158 /* ··· 166 162 xfs_extlen_t len, /* length of extent */ 167 163 int *stat) /* success/failure */ 168 164 { 165 + int error; 166 + 169 167 cur->bc_rec.a.ar_startblock = bno; 170 168 cur->bc_rec.a.ar_blockcount = len; 171 - return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); 169 + error = xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); 170 + cur->bc_private.a.priv.abt.active = (*stat == 1); 171 + return error; 172 172 } 173 173 174 174 /* ··· 186 178 xfs_extlen_t len, /* length of extent */ 187 179 int *stat) /* success/failure */ 188 180 { 181 + int error; 189 182 cur->bc_rec.a.ar_startblock = bno; 190 183 cur->bc_rec.a.ar_blockcount = len; 191 - return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); 184 + error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); 185 + cur->bc_private.a.priv.abt.active = (*stat == 1); 186 + return error; 187 + } 188 + 189 + static inline bool 190 + xfs_alloc_cur_active( 191 + struct xfs_btree_cur *cur) 192 + { 193 + return cur && cur->bc_private.a.priv.abt.active; 192 194 } 193 195 194 196 /* ··· 331 313 xfs_extlen_t newlen1=0; /* length with newbno1 */ 332 314 xfs_extlen_t newlen2=0; /* length with newbno2 */ 333 315 xfs_agblock_t wantend; /* end of target extent */ 334 - bool userdata = xfs_alloc_is_userdata(datatype); 316 + bool userdata = datatype & XFS_ALLOC_USERDATA; 335 317 336 318 ASSERT(freelen >= wantlen); 337 319 freeend = freebno + freelen; ··· 451 433 #ifdef DEBUG 452 434 if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i))) 453 435 return error; 454 - XFS_WANT_CORRUPTED_RETURN(mp, 455 - i == 1 && nfbno1 == fbno && nflen1 == flen); 436 + if (XFS_IS_CORRUPT(mp, 437 + i != 1 || 438 + nfbno1 != fbno || 439 + nflen1 != flen)) 440 + return -EFSCORRUPTED; 456 441 #endif 457 442 } else { 458 443 if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i))) 459 444 return error; 460 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 445 + if (XFS_IS_CORRUPT(mp, i != 1)) 446 + return -EFSCORRUPTED; 461 447 } 462 448 /* 463 449 * Look up the record in the by-block tree if necessary. ··· 470 448 #ifdef DEBUG 471 449 if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i))) 472 450 return error; 473 - XFS_WANT_CORRUPTED_RETURN(mp, 474 - i == 1 && nfbno1 == fbno && nflen1 == flen); 451 + if (XFS_IS_CORRUPT(mp, 452 + i != 1 || 453 + nfbno1 != fbno || 454 + nflen1 != flen)) 455 + return -EFSCORRUPTED; 475 456 #endif 476 457 } else { 477 458 if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i))) 478 459 return error; 479 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 460 + if (XFS_IS_CORRUPT(mp, i != 1)) 461 + return -EFSCORRUPTED; 480 462 } 481 463 482 464 #ifdef DEBUG ··· 491 465 bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]); 492 466 cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); 493 467 494 - XFS_WANT_CORRUPTED_RETURN(mp, 495 - bnoblock->bb_numrecs == cntblock->bb_numrecs); 468 + if (XFS_IS_CORRUPT(mp, 469 + bnoblock->bb_numrecs != 470 + cntblock->bb_numrecs)) 471 + return -EFSCORRUPTED; 496 472 } 497 473 #endif 498 474 ··· 524 496 */ 525 497 if ((error = xfs_btree_delete(cnt_cur, &i))) 526 498 return error; 527 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 499 + if (XFS_IS_CORRUPT(mp, i != 1)) 500 + return -EFSCORRUPTED; 528 501 /* 529 502 * Add new by-size btree entry(s). 530 503 */ 531 504 if (nfbno1 != NULLAGBLOCK) { 532 505 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) 533 506 return error; 534 - XFS_WANT_CORRUPTED_RETURN(mp, i == 0); 507 + if (XFS_IS_CORRUPT(mp, i != 0)) 508 + return -EFSCORRUPTED; 535 509 if ((error = xfs_btree_insert(cnt_cur, &i))) 536 510 return error; 537 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 511 + if (XFS_IS_CORRUPT(mp, i != 1)) 512 + return -EFSCORRUPTED; 538 513 } 539 514 if (nfbno2 != NULLAGBLOCK) { 540 515 if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) 541 516 return error; 542 - XFS_WANT_CORRUPTED_RETURN(mp, i == 0); 517 + if (XFS_IS_CORRUPT(mp, i != 0)) 518 + return -EFSCORRUPTED; 543 519 if ((error = xfs_btree_insert(cnt_cur, &i))) 544 520 return error; 545 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 521 + if (XFS_IS_CORRUPT(mp, i != 1)) 522 + return -EFSCORRUPTED; 546 523 } 547 524 /* 548 525 * Fix up the by-block btree entry(s). ··· 558 525 */ 559 526 if ((error = xfs_btree_delete(bno_cur, &i))) 560 527 return error; 561 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 528 + if (XFS_IS_CORRUPT(mp, i != 1)) 529 + return -EFSCORRUPTED; 562 530 } else { 563 531 /* 564 532 * Update the by-block entry to start later|be shorter. ··· 573 539 */ 574 540 if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) 575 541 return error; 576 - XFS_WANT_CORRUPTED_RETURN(mp, i == 0); 542 + if (XFS_IS_CORRUPT(mp, i != 0)) 543 + return -EFSCORRUPTED; 577 544 if ((error = xfs_btree_insert(bno_cur, &i))) 578 545 return error; 579 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 546 + if (XFS_IS_CORRUPT(mp, i != 1)) 547 + return -EFSCORRUPTED; 580 548 } 581 549 return 0; 582 550 } ··· 720 684 721 685 xfs_trans_agblocks_delta(tp, len); 722 686 if (unlikely(be32_to_cpu(agf->agf_freeblks) > 723 - be32_to_cpu(agf->agf_length))) 687 + be32_to_cpu(agf->agf_length))) { 688 + xfs_buf_corruption_error(agbp); 724 689 return -EFSCORRUPTED; 690 + } 725 691 726 692 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS); 727 693 return 0; 728 694 } 729 695 730 696 /* 731 - * Allocation group level functions. 697 + * Block allocation algorithm and data structures. 732 698 */ 699 + struct xfs_alloc_cur { 700 + struct xfs_btree_cur *cnt; /* btree cursors */ 701 + struct xfs_btree_cur *bnolt; 702 + struct xfs_btree_cur *bnogt; 703 + xfs_extlen_t cur_len;/* current search length */ 704 + xfs_agblock_t rec_bno;/* extent startblock */ 705 + xfs_extlen_t rec_len;/* extent length */ 706 + xfs_agblock_t bno; /* alloc bno */ 707 + xfs_extlen_t len; /* alloc len */ 708 + xfs_extlen_t diff; /* diff from search bno */ 709 + unsigned int busy_gen;/* busy state */ 710 + bool busy; 711 + }; 712 + 713 + /* 714 + * Set up cursors, etc. in the extent allocation cursor. This function can be 715 + * called multiple times to reset an initialized structure without having to 716 + * reallocate cursors. 717 + */ 718 + static int 719 + xfs_alloc_cur_setup( 720 + struct xfs_alloc_arg *args, 721 + struct xfs_alloc_cur *acur) 722 + { 723 + int error; 724 + int i; 725 + 726 + ASSERT(args->alignment == 1 || args->type != XFS_ALLOCTYPE_THIS_BNO); 727 + 728 + acur->cur_len = args->maxlen; 729 + acur->rec_bno = 0; 730 + acur->rec_len = 0; 731 + acur->bno = 0; 732 + acur->len = 0; 733 + acur->diff = -1; 734 + acur->busy = false; 735 + acur->busy_gen = 0; 736 + 737 + /* 738 + * Perform an initial cntbt lookup to check for availability of maxlen 739 + * extents. If this fails, we'll return -ENOSPC to signal the caller to 740 + * attempt a small allocation. 741 + */ 742 + if (!acur->cnt) 743 + acur->cnt = xfs_allocbt_init_cursor(args->mp, args->tp, 744 + args->agbp, args->agno, XFS_BTNUM_CNT); 745 + error = xfs_alloc_lookup_ge(acur->cnt, 0, args->maxlen, &i); 746 + if (error) 747 + return error; 748 + 749 + /* 750 + * Allocate the bnobt left and right search cursors. 751 + */ 752 + if (!acur->bnolt) 753 + acur->bnolt = xfs_allocbt_init_cursor(args->mp, args->tp, 754 + args->agbp, args->agno, XFS_BTNUM_BNO); 755 + if (!acur->bnogt) 756 + acur->bnogt = xfs_allocbt_init_cursor(args->mp, args->tp, 757 + args->agbp, args->agno, XFS_BTNUM_BNO); 758 + return i == 1 ? 0 : -ENOSPC; 759 + } 760 + 761 + static void 762 + xfs_alloc_cur_close( 763 + struct xfs_alloc_cur *acur, 764 + bool error) 765 + { 766 + int cur_error = XFS_BTREE_NOERROR; 767 + 768 + if (error) 769 + cur_error = XFS_BTREE_ERROR; 770 + 771 + if (acur->cnt) 772 + xfs_btree_del_cursor(acur->cnt, cur_error); 773 + if (acur->bnolt) 774 + xfs_btree_del_cursor(acur->bnolt, cur_error); 775 + if (acur->bnogt) 776 + xfs_btree_del_cursor(acur->bnogt, cur_error); 777 + acur->cnt = acur->bnolt = acur->bnogt = NULL; 778 + } 779 + 780 + /* 781 + * Check an extent for allocation and track the best available candidate in the 782 + * allocation structure. The cursor is deactivated if it has entered an out of 783 + * range state based on allocation arguments. Optionally return the extent 784 + * extent geometry and allocation status if requested by the caller. 785 + */ 786 + static int 787 + xfs_alloc_cur_check( 788 + struct xfs_alloc_arg *args, 789 + struct xfs_alloc_cur *acur, 790 + struct xfs_btree_cur *cur, 791 + int *new) 792 + { 793 + int error, i; 794 + xfs_agblock_t bno, bnoa, bnew; 795 + xfs_extlen_t len, lena, diff = -1; 796 + bool busy; 797 + unsigned busy_gen = 0; 798 + bool deactivate = false; 799 + bool isbnobt = cur->bc_btnum == XFS_BTNUM_BNO; 800 + 801 + *new = 0; 802 + 803 + error = xfs_alloc_get_rec(cur, &bno, &len, &i); 804 + if (error) 805 + return error; 806 + if (XFS_IS_CORRUPT(args->mp, i != 1)) 807 + return -EFSCORRUPTED; 808 + 809 + /* 810 + * Check minlen and deactivate a cntbt cursor if out of acceptable size 811 + * range (i.e., walking backwards looking for a minlen extent). 812 + */ 813 + if (len < args->minlen) { 814 + deactivate = !isbnobt; 815 + goto out; 816 + } 817 + 818 + busy = xfs_alloc_compute_aligned(args, bno, len, &bnoa, &lena, 819 + &busy_gen); 820 + acur->busy |= busy; 821 + if (busy) 822 + acur->busy_gen = busy_gen; 823 + /* deactivate a bnobt cursor outside of locality range */ 824 + if (bnoa < args->min_agbno || bnoa > args->max_agbno) { 825 + deactivate = isbnobt; 826 + goto out; 827 + } 828 + if (lena < args->minlen) 829 + goto out; 830 + 831 + args->len = XFS_EXTLEN_MIN(lena, args->maxlen); 832 + xfs_alloc_fix_len(args); 833 + ASSERT(args->len >= args->minlen); 834 + if (args->len < acur->len) 835 + goto out; 836 + 837 + /* 838 + * We have an aligned record that satisfies minlen and beats or matches 839 + * the candidate extent size. Compare locality for near allocation mode. 840 + */ 841 + ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO); 842 + diff = xfs_alloc_compute_diff(args->agbno, args->len, 843 + args->alignment, args->datatype, 844 + bnoa, lena, &bnew); 845 + if (bnew == NULLAGBLOCK) 846 + goto out; 847 + 848 + /* 849 + * Deactivate a bnobt cursor with worse locality than the current best. 850 + */ 851 + if (diff > acur->diff) { 852 + deactivate = isbnobt; 853 + goto out; 854 + } 855 + 856 + ASSERT(args->len > acur->len || 857 + (args->len == acur->len && diff <= acur->diff)); 858 + acur->rec_bno = bno; 859 + acur->rec_len = len; 860 + acur->bno = bnew; 861 + acur->len = args->len; 862 + acur->diff = diff; 863 + *new = 1; 864 + 865 + /* 866 + * We're done if we found a perfect allocation. This only deactivates 867 + * the current cursor, but this is just an optimization to terminate a 868 + * cntbt search that otherwise runs to the edge of the tree. 869 + */ 870 + if (acur->diff == 0 && acur->len == args->maxlen) 871 + deactivate = true; 872 + out: 873 + if (deactivate) 874 + cur->bc_private.a.priv.abt.active = false; 875 + trace_xfs_alloc_cur_check(args->mp, cur->bc_btnum, bno, len, diff, 876 + *new); 877 + return 0; 878 + } 879 + 880 + /* 881 + * Complete an allocation of a candidate extent. Remove the extent from both 882 + * trees and update the args structure. 883 + */ 884 + STATIC int 885 + xfs_alloc_cur_finish( 886 + struct xfs_alloc_arg *args, 887 + struct xfs_alloc_cur *acur) 888 + { 889 + int error; 890 + 891 + ASSERT(acur->cnt && acur->bnolt); 892 + ASSERT(acur->bno >= acur->rec_bno); 893 + ASSERT(acur->bno + acur->len <= acur->rec_bno + acur->rec_len); 894 + ASSERT(acur->rec_bno + acur->rec_len <= 895 + be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 896 + 897 + error = xfs_alloc_fixup_trees(acur->cnt, acur->bnolt, acur->rec_bno, 898 + acur->rec_len, acur->bno, acur->len, 0); 899 + if (error) 900 + return error; 901 + 902 + args->agbno = acur->bno; 903 + args->len = acur->len; 904 + args->wasfromfl = 0; 905 + 906 + trace_xfs_alloc_cur(args); 907 + return 0; 908 + } 909 + 910 + /* 911 + * Locality allocation lookup algorithm. This expects a cntbt cursor and uses 912 + * bno optimized lookup to search for extents with ideal size and locality. 913 + */ 914 + STATIC int 915 + xfs_alloc_cntbt_iter( 916 + struct xfs_alloc_arg *args, 917 + struct xfs_alloc_cur *acur) 918 + { 919 + struct xfs_btree_cur *cur = acur->cnt; 920 + xfs_agblock_t bno; 921 + xfs_extlen_t len, cur_len; 922 + int error; 923 + int i; 924 + 925 + if (!xfs_alloc_cur_active(cur)) 926 + return 0; 927 + 928 + /* locality optimized lookup */ 929 + cur_len = acur->cur_len; 930 + error = xfs_alloc_lookup_ge(cur, args->agbno, cur_len, &i); 931 + if (error) 932 + return error; 933 + if (i == 0) 934 + return 0; 935 + error = xfs_alloc_get_rec(cur, &bno, &len, &i); 936 + if (error) 937 + return error; 938 + 939 + /* check the current record and update search length from it */ 940 + error = xfs_alloc_cur_check(args, acur, cur, &i); 941 + if (error) 942 + return error; 943 + ASSERT(len >= acur->cur_len); 944 + acur->cur_len = len; 945 + 946 + /* 947 + * We looked up the first record >= [agbno, len] above. The agbno is a 948 + * secondary key and so the current record may lie just before or after 949 + * agbno. If it is past agbno, check the previous record too so long as 950 + * the length matches as it may be closer. Don't check a smaller record 951 + * because that could deactivate our cursor. 952 + */ 953 + if (bno > args->agbno) { 954 + error = xfs_btree_decrement(cur, 0, &i); 955 + if (!error && i) { 956 + error = xfs_alloc_get_rec(cur, &bno, &len, &i); 957 + if (!error && i && len == acur->cur_len) 958 + error = xfs_alloc_cur_check(args, acur, cur, 959 + &i); 960 + } 961 + if (error) 962 + return error; 963 + } 964 + 965 + /* 966 + * Increment the search key until we find at least one allocation 967 + * candidate or if the extent we found was larger. Otherwise, double the 968 + * search key to optimize the search. Efficiency is more important here 969 + * than absolute best locality. 970 + */ 971 + cur_len <<= 1; 972 + if (!acur->len || acur->cur_len >= cur_len) 973 + acur->cur_len++; 974 + else 975 + acur->cur_len = cur_len; 976 + 977 + return error; 978 + } 733 979 734 980 /* 735 981 * Deal with the case where only small freespaces remain. Either return the ··· 1045 727 error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i); 1046 728 if (error) 1047 729 goto error; 1048 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error); 730 + if (XFS_IS_CORRUPT(args->mp, i != 1)) { 731 + error = -EFSCORRUPTED; 732 + goto error; 733 + } 1049 734 goto out; 1050 735 } 1051 736 ··· 1065 744 goto out; 1066 745 1067 746 xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1, 1068 - xfs_alloc_allow_busy_reuse(args->datatype)); 747 + (args->datatype & XFS_ALLOC_NOBUSY)); 1069 748 1070 - if (xfs_alloc_is_userdata(args->datatype)) { 749 + if (args->datatype & XFS_ALLOC_USERDATA) { 1071 750 struct xfs_buf *bp; 1072 751 1073 752 bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno); 1074 - if (!bp) { 753 + if (XFS_IS_CORRUPT(args->mp, !bp)) { 1075 754 error = -EFSCORRUPTED; 1076 755 goto error; 1077 756 } ··· 1079 758 } 1080 759 *fbnop = args->agbno = fbno; 1081 760 *flenp = args->len = 1; 1082 - XFS_WANT_CORRUPTED_GOTO(args->mp, 1083 - fbno < be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), 1084 - error); 761 + if (XFS_IS_CORRUPT(args->mp, 762 + fbno >= be32_to_cpu( 763 + XFS_BUF_TO_AGF(args->agbp)->agf_length))) { 764 + error = -EFSCORRUPTED; 765 + goto error; 766 + } 1085 767 args->wasfromfl = 1; 1086 768 trace_xfs_alloc_small_freelist(args); 1087 769 ··· 1239 915 error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i); 1240 916 if (error) 1241 917 goto error0; 1242 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 918 + if (XFS_IS_CORRUPT(args->mp, i != 1)) { 919 + error = -EFSCORRUPTED; 920 + goto error0; 921 + } 1243 922 ASSERT(fbno <= args->agbno); 1244 923 1245 924 /* ··· 1311 984 } 1312 985 1313 986 /* 1314 - * Search the btree in a given direction via the search cursor and compare 1315 - * the records found against the good extent we've already found. 987 + * Search a given number of btree records in a given direction. Check each 988 + * record against the good extent we've already found. 1316 989 */ 1317 990 STATIC int 1318 - xfs_alloc_find_best_extent( 1319 - struct xfs_alloc_arg *args, /* allocation argument structure */ 1320 - struct xfs_btree_cur **gcur, /* good cursor */ 1321 - struct xfs_btree_cur **scur, /* searching cursor */ 1322 - xfs_agblock_t gdiff, /* difference for search comparison */ 1323 - xfs_agblock_t *sbno, /* extent found by search */ 1324 - xfs_extlen_t *slen, /* extent length */ 1325 - xfs_agblock_t *sbnoa, /* aligned extent found by search */ 1326 - xfs_extlen_t *slena, /* aligned extent length */ 1327 - int dir) /* 0 = search right, 1 = search left */ 991 + xfs_alloc_walk_iter( 992 + struct xfs_alloc_arg *args, 993 + struct xfs_alloc_cur *acur, 994 + struct xfs_btree_cur *cur, 995 + bool increment, 996 + bool find_one, /* quit on first candidate */ 997 + int count, /* rec count (-1 for infinite) */ 998 + int *stat) 1328 999 { 1329 - xfs_agblock_t new; 1330 - xfs_agblock_t sdiff; 1331 1000 int error; 1332 1001 int i; 1333 - unsigned busy_gen; 1334 1002 1335 - /* The good extent is perfect, no need to search. */ 1336 - if (!gdiff) 1337 - goto out_use_good; 1003 + *stat = 0; 1338 1004 1339 1005 /* 1340 - * Look until we find a better one, run out of space or run off the end. 1006 + * Search so long as the cursor is active or we find a better extent. 1007 + * The cursor is deactivated if it extends beyond the range of the 1008 + * current allocation candidate. 1341 1009 */ 1342 - do { 1343 - error = xfs_alloc_get_rec(*scur, sbno, slen, &i); 1010 + while (xfs_alloc_cur_active(cur) && count) { 1011 + error = xfs_alloc_cur_check(args, acur, cur, &i); 1344 1012 if (error) 1345 - goto error0; 1346 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1347 - xfs_alloc_compute_aligned(args, *sbno, *slen, 1348 - sbnoa, slena, &busy_gen); 1349 - 1350 - /* 1351 - * The good extent is closer than this one. 1352 - */ 1353 - if (!dir) { 1354 - if (*sbnoa > args->max_agbno) 1355 - goto out_use_good; 1356 - if (*sbnoa >= args->agbno + gdiff) 1357 - goto out_use_good; 1358 - } else { 1359 - if (*sbnoa < args->min_agbno) 1360 - goto out_use_good; 1361 - if (*sbnoa <= args->agbno - gdiff) 1362 - goto out_use_good; 1013 + return error; 1014 + if (i == 1) { 1015 + *stat = 1; 1016 + if (find_one) 1017 + break; 1363 1018 } 1019 + if (!xfs_alloc_cur_active(cur)) 1020 + break; 1364 1021 1365 - /* 1366 - * Same distance, compare length and pick the best. 1367 - */ 1368 - if (*slena >= args->minlen) { 1369 - args->len = XFS_EXTLEN_MIN(*slena, args->maxlen); 1370 - xfs_alloc_fix_len(args); 1371 - 1372 - sdiff = xfs_alloc_compute_diff(args->agbno, args->len, 1373 - args->alignment, 1374 - args->datatype, *sbnoa, 1375 - *slena, &new); 1376 - 1377 - /* 1378 - * Choose closer size and invalidate other cursor. 1379 - */ 1380 - if (sdiff < gdiff) 1381 - goto out_use_search; 1382 - goto out_use_good; 1383 - } 1384 - 1385 - if (!dir) 1386 - error = xfs_btree_increment(*scur, 0, &i); 1022 + if (increment) 1023 + error = xfs_btree_increment(cur, 0, &i); 1387 1024 else 1388 - error = xfs_btree_decrement(*scur, 0, &i); 1025 + error = xfs_btree_decrement(cur, 0, &i); 1389 1026 if (error) 1390 - goto error0; 1391 - } while (i); 1027 + return error; 1028 + if (i == 0) 1029 + cur->bc_private.a.priv.abt.active = false; 1392 1030 1393 - out_use_good: 1394 - xfs_btree_del_cursor(*scur, XFS_BTREE_NOERROR); 1395 - *scur = NULL; 1031 + if (count > 0) 1032 + count--; 1033 + } 1034 + 1396 1035 return 0; 1036 + } 1397 1037 1398 - out_use_search: 1399 - xfs_btree_del_cursor(*gcur, XFS_BTREE_NOERROR); 1400 - *gcur = NULL; 1038 + /* 1039 + * Search the by-bno and by-size btrees in parallel in search of an extent with 1040 + * ideal locality based on the NEAR mode ->agbno locality hint. 1041 + */ 1042 + STATIC int 1043 + xfs_alloc_ag_vextent_locality( 1044 + struct xfs_alloc_arg *args, 1045 + struct xfs_alloc_cur *acur, 1046 + int *stat) 1047 + { 1048 + struct xfs_btree_cur *fbcur = NULL; 1049 + int error; 1050 + int i; 1051 + bool fbinc; 1052 + 1053 + ASSERT(acur->len == 0); 1054 + ASSERT(args->type == XFS_ALLOCTYPE_NEAR_BNO); 1055 + 1056 + *stat = 0; 1057 + 1058 + error = xfs_alloc_lookup_ge(acur->cnt, args->agbno, acur->cur_len, &i); 1059 + if (error) 1060 + return error; 1061 + error = xfs_alloc_lookup_le(acur->bnolt, args->agbno, 0, &i); 1062 + if (error) 1063 + return error; 1064 + error = xfs_alloc_lookup_ge(acur->bnogt, args->agbno, 0, &i); 1065 + if (error) 1066 + return error; 1067 + 1068 + /* 1069 + * Search the bnobt and cntbt in parallel. Search the bnobt left and 1070 + * right and lookup the closest extent to the locality hint for each 1071 + * extent size key in the cntbt. The entire search terminates 1072 + * immediately on a bnobt hit because that means we've found best case 1073 + * locality. Otherwise the search continues until the cntbt cursor runs 1074 + * off the end of the tree. If no allocation candidate is found at this 1075 + * point, give up on locality, walk backwards from the end of the cntbt 1076 + * and take the first available extent. 1077 + * 1078 + * The parallel tree searches balance each other out to provide fairly 1079 + * consistent performance for various situations. The bnobt search can 1080 + * have pathological behavior in the worst case scenario of larger 1081 + * allocation requests and fragmented free space. On the other hand, the 1082 + * bnobt is able to satisfy most smaller allocation requests much more 1083 + * quickly than the cntbt. The cntbt search can sift through fragmented 1084 + * free space and sets of free extents for larger allocation requests 1085 + * more quickly than the bnobt. Since the locality hint is just a hint 1086 + * and we don't want to scan the entire bnobt for perfect locality, the 1087 + * cntbt search essentially bounds the bnobt search such that we can 1088 + * find good enough locality at reasonable performance in most cases. 1089 + */ 1090 + while (xfs_alloc_cur_active(acur->bnolt) || 1091 + xfs_alloc_cur_active(acur->bnogt) || 1092 + xfs_alloc_cur_active(acur->cnt)) { 1093 + 1094 + trace_xfs_alloc_cur_lookup(args); 1095 + 1096 + /* 1097 + * Search the bnobt left and right. In the case of a hit, finish 1098 + * the search in the opposite direction and we're done. 1099 + */ 1100 + error = xfs_alloc_walk_iter(args, acur, acur->bnolt, false, 1101 + true, 1, &i); 1102 + if (error) 1103 + return error; 1104 + if (i == 1) { 1105 + trace_xfs_alloc_cur_left(args); 1106 + fbcur = acur->bnogt; 1107 + fbinc = true; 1108 + break; 1109 + } 1110 + error = xfs_alloc_walk_iter(args, acur, acur->bnogt, true, true, 1111 + 1, &i); 1112 + if (error) 1113 + return error; 1114 + if (i == 1) { 1115 + trace_xfs_alloc_cur_right(args); 1116 + fbcur = acur->bnolt; 1117 + fbinc = false; 1118 + break; 1119 + } 1120 + 1121 + /* 1122 + * Check the extent with best locality based on the current 1123 + * extent size search key and keep track of the best candidate. 1124 + */ 1125 + error = xfs_alloc_cntbt_iter(args, acur); 1126 + if (error) 1127 + return error; 1128 + if (!xfs_alloc_cur_active(acur->cnt)) { 1129 + trace_xfs_alloc_cur_lookup_done(args); 1130 + break; 1131 + } 1132 + } 1133 + 1134 + /* 1135 + * If we failed to find anything due to busy extents, return empty 1136 + * handed so the caller can flush and retry. If no busy extents were 1137 + * found, walk backwards from the end of the cntbt as a last resort. 1138 + */ 1139 + if (!xfs_alloc_cur_active(acur->cnt) && !acur->len && !acur->busy) { 1140 + error = xfs_btree_decrement(acur->cnt, 0, &i); 1141 + if (error) 1142 + return error; 1143 + if (i) { 1144 + acur->cnt->bc_private.a.priv.abt.active = true; 1145 + fbcur = acur->cnt; 1146 + fbinc = false; 1147 + } 1148 + } 1149 + 1150 + /* 1151 + * Search in the opposite direction for a better entry in the case of 1152 + * a bnobt hit or walk backwards from the end of the cntbt. 1153 + */ 1154 + if (fbcur) { 1155 + error = xfs_alloc_walk_iter(args, acur, fbcur, fbinc, true, -1, 1156 + &i); 1157 + if (error) 1158 + return error; 1159 + } 1160 + 1161 + if (acur->len) 1162 + *stat = 1; 1163 + 1401 1164 return 0; 1165 + } 1402 1166 1403 - error0: 1404 - /* caller invalidates cursors */ 1405 - return error; 1167 + /* Check the last block of the cnt btree for allocations. */ 1168 + static int 1169 + xfs_alloc_ag_vextent_lastblock( 1170 + struct xfs_alloc_arg *args, 1171 + struct xfs_alloc_cur *acur, 1172 + xfs_agblock_t *bno, 1173 + xfs_extlen_t *len, 1174 + bool *allocated) 1175 + { 1176 + int error; 1177 + int i; 1178 + 1179 + #ifdef DEBUG 1180 + /* Randomly don't execute the first algorithm. */ 1181 + if (prandom_u32() & 1) 1182 + return 0; 1183 + #endif 1184 + 1185 + /* 1186 + * Start from the entry that lookup found, sequence through all larger 1187 + * free blocks. If we're actually pointing at a record smaller than 1188 + * maxlen, go to the start of this block, and skip all those smaller 1189 + * than minlen. 1190 + */ 1191 + if (len || args->alignment > 1) { 1192 + acur->cnt->bc_ptrs[0] = 1; 1193 + do { 1194 + error = xfs_alloc_get_rec(acur->cnt, bno, len, &i); 1195 + if (error) 1196 + return error; 1197 + if (XFS_IS_CORRUPT(args->mp, i != 1)) 1198 + return -EFSCORRUPTED; 1199 + if (*len >= args->minlen) 1200 + break; 1201 + error = xfs_btree_increment(acur->cnt, 0, &i); 1202 + if (error) 1203 + return error; 1204 + } while (i); 1205 + ASSERT(*len >= args->minlen); 1206 + if (!i) 1207 + return 0; 1208 + } 1209 + 1210 + error = xfs_alloc_walk_iter(args, acur, acur->cnt, true, false, -1, &i); 1211 + if (error) 1212 + return error; 1213 + 1214 + /* 1215 + * It didn't work. We COULD be in a case where there's a good record 1216 + * somewhere, so try again. 1217 + */ 1218 + if (acur->len == 0) 1219 + return 0; 1220 + 1221 + trace_xfs_alloc_near_first(args); 1222 + *allocated = true; 1223 + return 0; 1406 1224 } 1407 1225 1408 1226 /* ··· 1556 1084 * and of the form k * prod + mod unless there's nothing that large. 1557 1085 * Return the starting a.g. block, or NULLAGBLOCK if we can't do it. 1558 1086 */ 1559 - STATIC int /* error */ 1087 + STATIC int 1560 1088 xfs_alloc_ag_vextent_near( 1561 - xfs_alloc_arg_t *args) /* allocation argument structure */ 1089 + struct xfs_alloc_arg *args) 1562 1090 { 1563 - xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */ 1564 - xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */ 1565 - xfs_btree_cur_t *cnt_cur; /* cursor for count btree */ 1566 - xfs_agblock_t gtbno; /* start bno of right side entry */ 1567 - xfs_agblock_t gtbnoa; /* aligned ... */ 1568 - xfs_extlen_t gtdiff; /* difference to right side entry */ 1569 - xfs_extlen_t gtlen; /* length of right side entry */ 1570 - xfs_extlen_t gtlena; /* aligned ... */ 1571 - xfs_agblock_t gtnew; /* useful start bno of right side */ 1572 - int error; /* error code */ 1573 - int i; /* result code, temporary */ 1574 - int j; /* result code, temporary */ 1575 - xfs_agblock_t ltbno; /* start bno of left side entry */ 1576 - xfs_agblock_t ltbnoa; /* aligned ... */ 1577 - xfs_extlen_t ltdiff; /* difference to left side entry */ 1578 - xfs_extlen_t ltlen; /* length of left side entry */ 1579 - xfs_extlen_t ltlena; /* aligned ... */ 1580 - xfs_agblock_t ltnew; /* useful start bno of left side */ 1581 - xfs_extlen_t rlen; /* length of returned extent */ 1582 - bool busy; 1583 - unsigned busy_gen; 1584 - #ifdef DEBUG 1585 - /* 1586 - * Randomly don't execute the first algorithm. 1587 - */ 1588 - int dofirst; /* set to do first algorithm */ 1091 + struct xfs_alloc_cur acur = {}; 1092 + int error; /* error code */ 1093 + int i; /* result code, temporary */ 1094 + xfs_agblock_t bno; 1095 + xfs_extlen_t len; 1589 1096 1590 - dofirst = prandom_u32() & 1; 1591 - #endif 1592 - 1593 - /* handle unitialized agbno range so caller doesn't have to */ 1097 + /* handle uninitialized agbno range so caller doesn't have to */ 1594 1098 if (!args->min_agbno && !args->max_agbno) 1595 1099 args->max_agbno = args->mp->m_sb.sb_agblocks - 1; 1596 1100 ASSERT(args->min_agbno <= args->max_agbno); ··· 1578 1130 args->agbno = args->max_agbno; 1579 1131 1580 1132 restart: 1581 - bno_cur_lt = NULL; 1582 - bno_cur_gt = NULL; 1583 - ltlen = 0; 1584 - gtlena = 0; 1585 - ltlena = 0; 1586 - busy = false; 1133 + len = 0; 1587 1134 1588 1135 /* 1589 - * Get a cursor for the by-size btree. 1136 + * Set up cursors and see if there are any free extents as big as 1137 + * maxlen. If not, pick the last entry in the tree unless the tree is 1138 + * empty. 1590 1139 */ 1591 - cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 1592 - args->agno, XFS_BTNUM_CNT); 1593 - 1594 - /* 1595 - * See if there are any free extents as big as maxlen. 1596 - */ 1597 - if ((error = xfs_alloc_lookup_ge(cnt_cur, 0, args->maxlen, &i))) 1598 - goto error0; 1599 - /* 1600 - * If none, then pick up the last entry in the tree unless the 1601 - * tree is empty. 1602 - */ 1603 - if (!i) { 1604 - if ((error = xfs_alloc_ag_vextent_small(args, cnt_cur, &ltbno, 1605 - &ltlen, &i))) 1606 - goto error0; 1607 - if (i == 0 || ltlen == 0) { 1608 - xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1140 + error = xfs_alloc_cur_setup(args, &acur); 1141 + if (error == -ENOSPC) { 1142 + error = xfs_alloc_ag_vextent_small(args, acur.cnt, &bno, 1143 + &len, &i); 1144 + if (error) 1145 + goto out; 1146 + if (i == 0 || len == 0) { 1609 1147 trace_xfs_alloc_near_noentry(args); 1610 - return 0; 1148 + goto out; 1611 1149 } 1612 1150 ASSERT(i == 1); 1151 + } else if (error) { 1152 + goto out; 1613 1153 } 1614 - args->wasfromfl = 0; 1615 1154 1616 1155 /* 1617 1156 * First algorithm. ··· 1607 1172 * near the right edge of the tree. If it's in the last btree leaf 1608 1173 * block, then we just examine all the entries in that block 1609 1174 * that are big enough, and pick the best one. 1610 - * This is written as a while loop so we can break out of it, 1611 - * but we never loop back to the top. 1612 1175 */ 1613 - while (xfs_btree_islastblock(cnt_cur, 0)) { 1614 - xfs_extlen_t bdiff; 1615 - int besti=0; 1616 - xfs_extlen_t blen=0; 1617 - xfs_agblock_t bnew=0; 1176 + if (xfs_btree_islastblock(acur.cnt, 0)) { 1177 + bool allocated = false; 1618 1178 1619 - #ifdef DEBUG 1620 - if (dofirst) 1621 - break; 1622 - #endif 1623 - /* 1624 - * Start from the entry that lookup found, sequence through 1625 - * all larger free blocks. If we're actually pointing at a 1626 - * record smaller than maxlen, go to the start of this block, 1627 - * and skip all those smaller than minlen. 1628 - */ 1629 - if (ltlen || args->alignment > 1) { 1630 - cnt_cur->bc_ptrs[0] = 1; 1631 - do { 1632 - if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, 1633 - &ltlen, &i))) 1634 - goto error0; 1635 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1636 - if (ltlen >= args->minlen) 1637 - break; 1638 - if ((error = xfs_btree_increment(cnt_cur, 0, &i))) 1639 - goto error0; 1640 - } while (i); 1641 - ASSERT(ltlen >= args->minlen); 1642 - if (!i) 1643 - break; 1644 - } 1645 - i = cnt_cur->bc_ptrs[0]; 1646 - for (j = 1, blen = 0, bdiff = 0; 1647 - !error && j && (blen < args->maxlen || bdiff > 0); 1648 - error = xfs_btree_increment(cnt_cur, 0, &j)) { 1649 - /* 1650 - * For each entry, decide if it's better than 1651 - * the previous best entry. 1652 - */ 1653 - if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i))) 1654 - goto error0; 1655 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1656 - busy = xfs_alloc_compute_aligned(args, ltbno, ltlen, 1657 - &ltbnoa, &ltlena, &busy_gen); 1658 - if (ltlena < args->minlen) 1659 - continue; 1660 - if (ltbnoa < args->min_agbno || ltbnoa > args->max_agbno) 1661 - continue; 1662 - args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 1663 - xfs_alloc_fix_len(args); 1664 - ASSERT(args->len >= args->minlen); 1665 - if (args->len < blen) 1666 - continue; 1667 - ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, 1668 - args->alignment, args->datatype, ltbnoa, 1669 - ltlena, &ltnew); 1670 - if (ltnew != NULLAGBLOCK && 1671 - (args->len > blen || ltdiff < bdiff)) { 1672 - bdiff = ltdiff; 1673 - bnew = ltnew; 1674 - blen = args->len; 1675 - besti = cnt_cur->bc_ptrs[0]; 1676 - } 1677 - } 1678 - /* 1679 - * It didn't work. We COULD be in a case where 1680 - * there's a good record somewhere, so try again. 1681 - */ 1682 - if (blen == 0) 1683 - break; 1684 - /* 1685 - * Point at the best entry, and retrieve it again. 1686 - */ 1687 - cnt_cur->bc_ptrs[0] = besti; 1688 - if ((error = xfs_alloc_get_rec(cnt_cur, &ltbno, &ltlen, &i))) 1689 - goto error0; 1690 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1691 - ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 1692 - args->len = blen; 1693 - 1694 - /* 1695 - * We are allocating starting at bnew for blen blocks. 1696 - */ 1697 - args->agbno = bnew; 1698 - ASSERT(bnew >= ltbno); 1699 - ASSERT(bnew + blen <= ltbno + ltlen); 1700 - /* 1701 - * Set up a cursor for the by-bno tree. 1702 - */ 1703 - bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, 1704 - args->agbp, args->agno, XFS_BTNUM_BNO); 1705 - /* 1706 - * Fix up the btree entries. 1707 - */ 1708 - if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, 1709 - ltlen, bnew, blen, XFSA_FIXUP_CNT_OK))) 1710 - goto error0; 1711 - xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1712 - xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); 1713 - 1714 - trace_xfs_alloc_near_first(args); 1715 - return 0; 1716 - } 1717 - /* 1718 - * Second algorithm. 1719 - * Search in the by-bno tree to the left and to the right 1720 - * simultaneously, until in each case we find a space big enough, 1721 - * or run into the edge of the tree. When we run into the edge, 1722 - * we deallocate that cursor. 1723 - * If both searches succeed, we compare the two spaces and pick 1724 - * the better one. 1725 - * With alignment, it's possible for both to fail; the upper 1726 - * level algorithm that picks allocation groups for allocations 1727 - * is not supposed to do this. 1728 - */ 1729 - /* 1730 - * Allocate and initialize the cursor for the leftward search. 1731 - */ 1732 - bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 1733 - args->agno, XFS_BTNUM_BNO); 1734 - /* 1735 - * Lookup <= bno to find the leftward search's starting point. 1736 - */ 1737 - if ((error = xfs_alloc_lookup_le(bno_cur_lt, args->agbno, args->maxlen, &i))) 1738 - goto error0; 1739 - if (!i) { 1740 - /* 1741 - * Didn't find anything; use this cursor for the rightward 1742 - * search. 1743 - */ 1744 - bno_cur_gt = bno_cur_lt; 1745 - bno_cur_lt = NULL; 1746 - } 1747 - /* 1748 - * Found something. Duplicate the cursor for the rightward search. 1749 - */ 1750 - else if ((error = xfs_btree_dup_cursor(bno_cur_lt, &bno_cur_gt))) 1751 - goto error0; 1752 - /* 1753 - * Increment the cursor, so we will point at the entry just right 1754 - * of the leftward entry if any, or to the leftmost entry. 1755 - */ 1756 - if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) 1757 - goto error0; 1758 - if (!i) { 1759 - /* 1760 - * It failed, there are no rightward entries. 1761 - */ 1762 - xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_NOERROR); 1763 - bno_cur_gt = NULL; 1764 - } 1765 - /* 1766 - * Loop going left with the leftward cursor, right with the 1767 - * rightward cursor, until either both directions give up or 1768 - * we find an entry at least as big as minlen. 1769 - */ 1770 - do { 1771 - if (bno_cur_lt) { 1772 - if ((error = xfs_alloc_get_rec(bno_cur_lt, &ltbno, &ltlen, &i))) 1773 - goto error0; 1774 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1775 - busy |= xfs_alloc_compute_aligned(args, ltbno, ltlen, 1776 - &ltbnoa, &ltlena, &busy_gen); 1777 - if (ltlena >= args->minlen && ltbnoa >= args->min_agbno) 1778 - break; 1779 - if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i))) 1780 - goto error0; 1781 - if (!i || ltbnoa < args->min_agbno) { 1782 - xfs_btree_del_cursor(bno_cur_lt, 1783 - XFS_BTREE_NOERROR); 1784 - bno_cur_lt = NULL; 1785 - } 1786 - } 1787 - if (bno_cur_gt) { 1788 - if ((error = xfs_alloc_get_rec(bno_cur_gt, &gtbno, &gtlen, &i))) 1789 - goto error0; 1790 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1791 - busy |= xfs_alloc_compute_aligned(args, gtbno, gtlen, 1792 - &gtbnoa, &gtlena, &busy_gen); 1793 - if (gtlena >= args->minlen && gtbnoa <= args->max_agbno) 1794 - break; 1795 - if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) 1796 - goto error0; 1797 - if (!i || gtbnoa > args->max_agbno) { 1798 - xfs_btree_del_cursor(bno_cur_gt, 1799 - XFS_BTREE_NOERROR); 1800 - bno_cur_gt = NULL; 1801 - } 1802 - } 1803 - } while (bno_cur_lt || bno_cur_gt); 1804 - 1805 - /* 1806 - * Got both cursors still active, need to find better entry. 1807 - */ 1808 - if (bno_cur_lt && bno_cur_gt) { 1809 - if (ltlena >= args->minlen) { 1810 - /* 1811 - * Left side is good, look for a right side entry. 1812 - */ 1813 - args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 1814 - xfs_alloc_fix_len(args); 1815 - ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, 1816 - args->alignment, args->datatype, ltbnoa, 1817 - ltlena, &ltnew); 1818 - 1819 - error = xfs_alloc_find_best_extent(args, 1820 - &bno_cur_lt, &bno_cur_gt, 1821 - ltdiff, &gtbno, &gtlen, 1822 - &gtbnoa, &gtlena, 1823 - 0 /* search right */); 1824 - } else { 1825 - ASSERT(gtlena >= args->minlen); 1826 - 1827 - /* 1828 - * Right side is good, look for a left side entry. 1829 - */ 1830 - args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen); 1831 - xfs_alloc_fix_len(args); 1832 - gtdiff = xfs_alloc_compute_diff(args->agbno, args->len, 1833 - args->alignment, args->datatype, gtbnoa, 1834 - gtlena, &gtnew); 1835 - 1836 - error = xfs_alloc_find_best_extent(args, 1837 - &bno_cur_gt, &bno_cur_lt, 1838 - gtdiff, &ltbno, &ltlen, 1839 - &ltbnoa, &ltlena, 1840 - 1 /* search left */); 1841 - } 1842 - 1179 + error = xfs_alloc_ag_vextent_lastblock(args, &acur, &bno, &len, 1180 + &allocated); 1843 1181 if (error) 1844 - goto error0; 1182 + goto out; 1183 + if (allocated) 1184 + goto alloc_finish; 1845 1185 } 1186 + 1187 + /* 1188 + * Second algorithm. Combined cntbt and bnobt search to find ideal 1189 + * locality. 1190 + */ 1191 + error = xfs_alloc_ag_vextent_locality(args, &acur, &i); 1192 + if (error) 1193 + goto out; 1846 1194 1847 1195 /* 1848 1196 * If we couldn't get anything, give up. 1849 1197 */ 1850 - if (bno_cur_lt == NULL && bno_cur_gt == NULL) { 1851 - xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1852 - 1853 - if (busy) { 1198 + if (!acur.len) { 1199 + if (acur.busy) { 1854 1200 trace_xfs_alloc_near_busy(args); 1855 - xfs_extent_busy_flush(args->mp, args->pag, busy_gen); 1201 + xfs_extent_busy_flush(args->mp, args->pag, 1202 + acur.busy_gen); 1856 1203 goto restart; 1857 1204 } 1858 1205 trace_xfs_alloc_size_neither(args); 1859 1206 args->agbno = NULLAGBLOCK; 1860 - return 0; 1207 + goto out; 1861 1208 } 1862 1209 1863 - /* 1864 - * At this point we have selected a freespace entry, either to the 1865 - * left or to the right. If it's on the right, copy all the 1866 - * useful variables to the "left" set so we only have one 1867 - * copy of this code. 1868 - */ 1869 - if (bno_cur_gt) { 1870 - bno_cur_lt = bno_cur_gt; 1871 - bno_cur_gt = NULL; 1872 - ltbno = gtbno; 1873 - ltbnoa = gtbnoa; 1874 - ltlen = gtlen; 1875 - ltlena = gtlena; 1876 - j = 1; 1877 - } else 1878 - j = 0; 1210 + alloc_finish: 1211 + /* fix up btrees on a successful allocation */ 1212 + error = xfs_alloc_cur_finish(args, &acur); 1879 1213 1880 - /* 1881 - * Fix up the length and compute the useful address. 1882 - */ 1883 - args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); 1884 - xfs_alloc_fix_len(args); 1885 - rlen = args->len; 1886 - (void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment, 1887 - args->datatype, ltbnoa, ltlena, &ltnew); 1888 - ASSERT(ltnew >= ltbno); 1889 - ASSERT(ltnew + rlen <= ltbnoa + ltlena); 1890 - ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); 1891 - ASSERT(ltnew >= args->min_agbno && ltnew <= args->max_agbno); 1892 - args->agbno = ltnew; 1893 - 1894 - if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur_lt, ltbno, ltlen, 1895 - ltnew, rlen, XFSA_FIXUP_BNO_OK))) 1896 - goto error0; 1897 - 1898 - if (j) 1899 - trace_xfs_alloc_near_greater(args); 1900 - else 1901 - trace_xfs_alloc_near_lesser(args); 1902 - 1903 - xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1904 - xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR); 1905 - return 0; 1906 - 1907 - error0: 1908 - trace_xfs_alloc_near_error(args); 1909 - if (cnt_cur != NULL) 1910 - xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); 1911 - if (bno_cur_lt != NULL) 1912 - xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_ERROR); 1913 - if (bno_cur_gt != NULL) 1914 - xfs_btree_del_cursor(bno_cur_gt, XFS_BTREE_ERROR); 1214 + out: 1215 + xfs_alloc_cur_close(&acur, error); 1915 1216 return error; 1916 1217 } 1917 1218 ··· 1716 1545 error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i); 1717 1546 if (error) 1718 1547 goto error0; 1719 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1548 + if (XFS_IS_CORRUPT(args->mp, i != 1)) { 1549 + error = -EFSCORRUPTED; 1550 + goto error0; 1551 + } 1720 1552 1721 1553 busy = xfs_alloc_compute_aligned(args, fbno, flen, 1722 1554 &rbno, &rlen, &busy_gen); ··· 1753 1579 * This can't happen in the second case above. 1754 1580 */ 1755 1581 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); 1756 - XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 || 1757 - (rlen <= flen && rbno + rlen <= fbno + flen), error0); 1582 + if (XFS_IS_CORRUPT(args->mp, 1583 + rlen != 0 && 1584 + (rlen > flen || 1585 + rbno + rlen > fbno + flen))) { 1586 + error = -EFSCORRUPTED; 1587 + goto error0; 1588 + } 1758 1589 if (rlen < args->maxlen) { 1759 1590 xfs_agblock_t bestfbno; 1760 1591 xfs_extlen_t bestflen; ··· 1778 1599 if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, 1779 1600 &i))) 1780 1601 goto error0; 1781 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1602 + if (XFS_IS_CORRUPT(args->mp, i != 1)) { 1603 + error = -EFSCORRUPTED; 1604 + goto error0; 1605 + } 1782 1606 if (flen < bestrlen) 1783 1607 break; 1784 1608 busy = xfs_alloc_compute_aligned(args, fbno, flen, 1785 1609 &rbno, &rlen, &busy_gen); 1786 1610 rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); 1787 - XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 || 1788 - (rlen <= flen && rbno + rlen <= fbno + flen), 1789 - error0); 1611 + if (XFS_IS_CORRUPT(args->mp, 1612 + rlen != 0 && 1613 + (rlen > flen || 1614 + rbno + rlen > fbno + flen))) { 1615 + error = -EFSCORRUPTED; 1616 + goto error0; 1617 + } 1790 1618 if (rlen > bestrlen) { 1791 1619 bestrlen = rlen; 1792 1620 bestrbno = rbno; ··· 1806 1620 if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen, 1807 1621 &i))) 1808 1622 goto error0; 1809 - XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); 1623 + if (XFS_IS_CORRUPT(args->mp, i != 1)) { 1624 + error = -EFSCORRUPTED; 1625 + goto error0; 1626 + } 1810 1627 rlen = bestrlen; 1811 1628 rbno = bestrbno; 1812 1629 flen = bestflen; ··· 1832 1643 xfs_alloc_fix_len(args); 1833 1644 1834 1645 rlen = args->len; 1835 - XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0); 1646 + if (XFS_IS_CORRUPT(args->mp, rlen > flen)) { 1647 + error = -EFSCORRUPTED; 1648 + goto error0; 1649 + } 1836 1650 /* 1837 1651 * Allocate and initialize a cursor for the by-block tree. 1838 1652 */ ··· 1849 1657 cnt_cur = bno_cur = NULL; 1850 1658 args->len = rlen; 1851 1659 args->agbno = rbno; 1852 - XFS_WANT_CORRUPTED_GOTO(args->mp, 1853 - args->agbno + args->len <= 1854 - be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), 1855 - error0); 1660 + if (XFS_IS_CORRUPT(args->mp, 1661 + args->agbno + args->len > 1662 + be32_to_cpu( 1663 + XFS_BUF_TO_AGF(args->agbp)->agf_length))) { 1664 + error = -EFSCORRUPTED; 1665 + goto error0; 1666 + } 1856 1667 trace_xfs_alloc_size_done(args); 1857 1668 return 0; 1858 1669 ··· 1927 1732 */ 1928 1733 if ((error = xfs_alloc_get_rec(bno_cur, &ltbno, &ltlen, &i))) 1929 1734 goto error0; 1930 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1735 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1736 + error = -EFSCORRUPTED; 1737 + goto error0; 1738 + } 1931 1739 /* 1932 1740 * It's not contiguous, though. 1933 1741 */ ··· 1942 1744 * space was invalid, it's (partly) already free. 1943 1745 * Very bad. 1944 1746 */ 1945 - XFS_WANT_CORRUPTED_GOTO(mp, 1946 - ltbno + ltlen <= bno, error0); 1747 + if (XFS_IS_CORRUPT(mp, ltbno + ltlen > bno)) { 1748 + error = -EFSCORRUPTED; 1749 + goto error0; 1750 + } 1947 1751 } 1948 1752 } 1949 1753 /* ··· 1960 1760 */ 1961 1761 if ((error = xfs_alloc_get_rec(bno_cur, &gtbno, &gtlen, &i))) 1962 1762 goto error0; 1963 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1763 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1764 + error = -EFSCORRUPTED; 1765 + goto error0; 1766 + } 1964 1767 /* 1965 1768 * It's not contiguous, though. 1966 1769 */ ··· 1975 1772 * space was invalid, it's (partly) already free. 1976 1773 * Very bad. 1977 1774 */ 1978 - XFS_WANT_CORRUPTED_GOTO(mp, gtbno >= bno + len, error0); 1775 + if (XFS_IS_CORRUPT(mp, bno + len > gtbno)) { 1776 + error = -EFSCORRUPTED; 1777 + goto error0; 1778 + } 1979 1779 } 1980 1780 } 1981 1781 /* ··· 1995 1789 */ 1996 1790 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) 1997 1791 goto error0; 1998 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1792 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1793 + error = -EFSCORRUPTED; 1794 + goto error0; 1795 + } 1999 1796 if ((error = xfs_btree_delete(cnt_cur, &i))) 2000 1797 goto error0; 2001 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1798 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1799 + error = -EFSCORRUPTED; 1800 + goto error0; 1801 + } 2002 1802 /* 2003 1803 * Delete the old by-size entry on the right. 2004 1804 */ 2005 1805 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) 2006 1806 goto error0; 2007 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1807 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1808 + error = -EFSCORRUPTED; 1809 + goto error0; 1810 + } 2008 1811 if ((error = xfs_btree_delete(cnt_cur, &i))) 2009 1812 goto error0; 2010 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1813 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1814 + error = -EFSCORRUPTED; 1815 + goto error0; 1816 + } 2011 1817 /* 2012 1818 * Delete the old by-block entry for the right block. 2013 1819 */ 2014 1820 if ((error = xfs_btree_delete(bno_cur, &i))) 2015 1821 goto error0; 2016 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1822 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1823 + error = -EFSCORRUPTED; 1824 + goto error0; 1825 + } 2017 1826 /* 2018 1827 * Move the by-block cursor back to the left neighbor. 2019 1828 */ 2020 1829 if ((error = xfs_btree_decrement(bno_cur, 0, &i))) 2021 1830 goto error0; 2022 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1831 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1832 + error = -EFSCORRUPTED; 1833 + goto error0; 1834 + } 2023 1835 #ifdef DEBUG 2024 1836 /* 2025 1837 * Check that this is the right record: delete didn't ··· 2050 1826 if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen, 2051 1827 &i))) 2052 1828 goto error0; 2053 - XFS_WANT_CORRUPTED_GOTO(mp, 2054 - i == 1 && xxbno == ltbno && xxlen == ltlen, 2055 - error0); 1829 + if (XFS_IS_CORRUPT(mp, 1830 + i != 1 || 1831 + xxbno != ltbno || 1832 + xxlen != ltlen)) { 1833 + error = -EFSCORRUPTED; 1834 + goto error0; 1835 + } 2056 1836 } 2057 1837 #endif 2058 1838 /* ··· 2077 1849 */ 2078 1850 if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) 2079 1851 goto error0; 2080 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1852 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1853 + error = -EFSCORRUPTED; 1854 + goto error0; 1855 + } 2081 1856 if ((error = xfs_btree_delete(cnt_cur, &i))) 2082 1857 goto error0; 2083 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1858 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1859 + error = -EFSCORRUPTED; 1860 + goto error0; 1861 + } 2084 1862 /* 2085 1863 * Back up the by-block cursor to the left neighbor, and 2086 1864 * update its length. 2087 1865 */ 2088 1866 if ((error = xfs_btree_decrement(bno_cur, 0, &i))) 2089 1867 goto error0; 2090 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1868 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1869 + error = -EFSCORRUPTED; 1870 + goto error0; 1871 + } 2091 1872 nbno = ltbno; 2092 1873 nlen = len + ltlen; 2093 1874 if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) ··· 2112 1875 */ 2113 1876 if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) 2114 1877 goto error0; 2115 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1878 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1879 + error = -EFSCORRUPTED; 1880 + goto error0; 1881 + } 2116 1882 if ((error = xfs_btree_delete(cnt_cur, &i))) 2117 1883 goto error0; 2118 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1884 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1885 + error = -EFSCORRUPTED; 1886 + goto error0; 1887 + } 2119 1888 /* 2120 1889 * Update the starting block and length of the right 2121 1890 * neighbor in the by-block tree. ··· 2140 1897 nlen = len; 2141 1898 if ((error = xfs_btree_insert(bno_cur, &i))) 2142 1899 goto error0; 2143 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1900 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1901 + error = -EFSCORRUPTED; 1902 + goto error0; 1903 + } 2144 1904 } 2145 1905 xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); 2146 1906 bno_cur = NULL; ··· 2152 1906 */ 2153 1907 if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) 2154 1908 goto error0; 2155 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, error0); 1909 + if (XFS_IS_CORRUPT(mp, i != 0)) { 1910 + error = -EFSCORRUPTED; 1911 + goto error0; 1912 + } 2156 1913 if ((error = xfs_btree_insert(cnt_cur, &i))) 2157 1914 goto error0; 2158 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1915 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1916 + error = -EFSCORRUPTED; 1917 + goto error0; 1918 + } 2159 1919 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 2160 1920 cnt_cur = NULL; 2161 1921 ··· 2241 1989 * reservations and AGFL rules in place, we can return this extent. 2242 1990 */ 2243 1991 if (pag->pagf_longest > delta) 2244 - return pag->pagf_longest - delta; 1992 + return min_t(xfs_extlen_t, pag->pag_mount->m_ag_max_usable, 1993 + pag->pagf_longest - delta); 2245 1994 2246 1995 /* Otherwise, let the caller try for 1 block if there's space. */ 2247 1996 return pag->pagf_flcount > 0 || pag->pagf_longest > 0; ··· 2340 2087 return error; 2341 2088 2342 2089 bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno); 2343 - if (!bp) 2090 + if (XFS_IS_CORRUPT(tp->t_mountp, !bp)) 2344 2091 return -EFSCORRUPTED; 2345 2092 xfs_trans_binval(tp, bp); 2346 2093 ··· 2506 2253 * somewhere else if we are not being asked to try harder at this 2507 2254 * point 2508 2255 */ 2509 - if (pag->pagf_metadata && xfs_alloc_is_userdata(args->datatype) && 2256 + if (pag->pagf_metadata && (args->datatype & XFS_ALLOC_USERDATA) && 2510 2257 (flags & XFS_ALLOC_FLAG_TRYLOCK)) { 2511 2258 ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); 2512 2259 goto out_agbp_relse; ··· 3209 2956 args->len); 3210 2957 #endif 3211 2958 3212 - /* Zero the extent if we were asked to do so */ 3213 - if (args->datatype & XFS_ALLOC_USERDATA_ZERO) { 3214 - error = xfs_zero_extent(args->ip, args->fsbno, args->len); 3215 - if (error) 3216 - goto error0; 3217 - } 3218 - 3219 2959 } 3220 2960 xfs_perag_put(args->pag); 3221 2961 return 0; ··· 3284 3038 if (error) 3285 3039 return error; 3286 3040 3287 - XFS_WANT_CORRUPTED_GOTO(mp, agbno < mp->m_sb.sb_agblocks, err); 3041 + if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) { 3042 + error = -EFSCORRUPTED; 3043 + goto err; 3044 + } 3288 3045 3289 3046 /* validate the extent size is legal now we have the agf locked */ 3290 - XFS_WANT_CORRUPTED_GOTO(mp, 3291 - agbno + len <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_length), 3292 - err); 3047 + if (XFS_IS_CORRUPT(mp, 3048 + agbno + len > 3049 + be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_length))) { 3050 + error = -EFSCORRUPTED; 3051 + goto err; 3052 + } 3293 3053 3294 3054 error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type); 3295 3055 if (error)
+1 -15
fs/xfs/libxfs/xfs_alloc.h
··· 54 54 struct xfs_mount *mp; /* file system mount point */ 55 55 struct xfs_buf *agbp; /* buffer for a.g. freelist header */ 56 56 struct xfs_perag *pag; /* per-ag struct for this agno */ 57 - struct xfs_inode *ip; /* for userdata zeroing method */ 58 57 xfs_fsblock_t fsbno; /* file system block number */ 59 58 xfs_agnumber_t agno; /* allocation group number */ 60 59 xfs_agblock_t agbno; /* allocation group-relative block # */ ··· 82 83 */ 83 84 #define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ 84 85 #define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ 85 - #define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ 86 - #define XFS_ALLOC_NOBUSY (1 << 3)/* Busy extents not allowed */ 87 - 88 - static inline bool 89 - xfs_alloc_is_userdata(int datatype) 90 - { 91 - return (datatype & ~XFS_ALLOC_NOBUSY) != 0; 92 - } 93 - 94 - static inline bool 95 - xfs_alloc_allow_busy_reuse(int datatype) 96 - { 97 - return (datatype & XFS_ALLOC_NOBUSY) == 0; 98 - } 86 + #define XFS_ALLOC_NOBUSY (1 << 2)/* Busy extents not allowed */ 99 87 100 88 /* freespace limit calculations */ 101 89 #define XFS_ALLOC_AGFL_RESERVE 4
+1
fs/xfs/libxfs/xfs_alloc_btree.c
··· 507 507 508 508 cur->bc_private.a.agbp = agbp; 509 509 cur->bc_private.a.agno = agno; 510 + cur->bc_private.a.priv.abt.active = false; 510 511 511 512 if (xfs_sb_version_hascrc(&mp->m_sb)) 512 513 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
+11 -13
fs/xfs/libxfs/xfs_attr.c
··· 589 589 */ 590 590 dp = args->dp; 591 591 args->blkno = 0; 592 - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 592 + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp); 593 593 if (error) 594 594 return error; 595 595 ··· 715 715 * remove the "old" attr from that block (neat, huh!) 716 716 */ 717 717 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, 718 - -1, &bp); 718 + &bp); 719 719 if (error) 720 720 return error; 721 721 ··· 769 769 */ 770 770 dp = args->dp; 771 771 args->blkno = 0; 772 - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 772 + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp); 773 773 if (error) 774 774 return error; 775 775 ··· 813 813 trace_xfs_attr_leaf_get(args); 814 814 815 815 args->blkno = 0; 816 - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 816 + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp); 817 817 if (error) 818 818 return error; 819 819 ··· 1173 1173 ASSERT(state->path.blk[0].bp); 1174 1174 state->path.blk[0].bp = NULL; 1175 1175 1176 - error = xfs_attr3_leaf_read(args->trans, args->dp, 0, -1, &bp); 1176 + error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp); 1177 1177 if (error) 1178 1178 goto out; 1179 1179 ··· 1266 1266 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1267 1267 for (blk = path->blk, level = 0; level < path->active; blk++, level++) { 1268 1268 if (blk->disk_blkno) { 1269 - error = xfs_da3_node_read(state->args->trans, 1270 - state->args->dp, 1271 - blk->blkno, blk->disk_blkno, 1272 - &blk->bp, XFS_ATTR_FORK); 1269 + error = xfs_da3_node_read_mapped(state->args->trans, 1270 + state->args->dp, blk->disk_blkno, 1271 + &blk->bp, XFS_ATTR_FORK); 1273 1272 if (error) 1274 1273 return error; 1275 1274 } else { ··· 1284 1285 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1285 1286 for (blk = path->blk, level = 0; level < path->active; blk++, level++) { 1286 1287 if (blk->disk_blkno) { 1287 - error = xfs_da3_node_read(state->args->trans, 1288 - state->args->dp, 1289 - blk->blkno, blk->disk_blkno, 1290 - &blk->bp, XFS_ATTR_FORK); 1288 + error = xfs_da3_node_read_mapped(state->args->trans, 1289 + state->args->dp, blk->disk_blkno, 1290 + &blk->bp, XFS_ATTR_FORK); 1291 1291 if (error) 1292 1292 return error; 1293 1293 } else {
+102 -32
fs/xfs/libxfs/xfs_attr_leaf.c
··· 233 233 } 234 234 235 235 static xfs_failaddr_t 236 + xfs_attr3_leaf_verify_entry( 237 + struct xfs_mount *mp, 238 + char *buf_end, 239 + struct xfs_attr_leafblock *leaf, 240 + struct xfs_attr3_icleaf_hdr *leafhdr, 241 + struct xfs_attr_leaf_entry *ent, 242 + int idx, 243 + __u32 *last_hashval) 244 + { 245 + struct xfs_attr_leaf_name_local *lentry; 246 + struct xfs_attr_leaf_name_remote *rentry; 247 + char *name_end; 248 + unsigned int nameidx; 249 + unsigned int namesize; 250 + __u32 hashval; 251 + 252 + /* hash order check */ 253 + hashval = be32_to_cpu(ent->hashval); 254 + if (hashval < *last_hashval) 255 + return __this_address; 256 + *last_hashval = hashval; 257 + 258 + nameidx = be16_to_cpu(ent->nameidx); 259 + if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize) 260 + return __this_address; 261 + 262 + /* 263 + * Check the name information. The namelen fields are u8 so we can't 264 + * possibly exceed the maximum name length of 255 bytes. 265 + */ 266 + if (ent->flags & XFS_ATTR_LOCAL) { 267 + lentry = xfs_attr3_leaf_name_local(leaf, idx); 268 + namesize = xfs_attr_leaf_entsize_local(lentry->namelen, 269 + be16_to_cpu(lentry->valuelen)); 270 + name_end = (char *)lentry + namesize; 271 + if (lentry->namelen == 0) 272 + return __this_address; 273 + } else { 274 + rentry = xfs_attr3_leaf_name_remote(leaf, idx); 275 + namesize = xfs_attr_leaf_entsize_remote(rentry->namelen); 276 + name_end = (char *)rentry + namesize; 277 + if (rentry->namelen == 0) 278 + return __this_address; 279 + if (!(ent->flags & XFS_ATTR_INCOMPLETE) && 280 + rentry->valueblk == 0) 281 + return __this_address; 282 + } 283 + 284 + if (name_end > buf_end) 285 + return __this_address; 286 + 287 + return NULL; 288 + } 289 + 290 + static xfs_failaddr_t 236 291 xfs_attr3_leaf_verify( 237 292 struct xfs_buf *bp) 238 293 { ··· 295 240 struct xfs_mount *mp = bp->b_mount; 296 241 struct xfs_attr_leafblock *leaf = bp->b_addr; 297 242 struct xfs_attr_leaf_entry *entries; 243 + struct xfs_attr_leaf_entry *ent; 244 + char *buf_end; 298 245 uint32_t end; /* must be 32bit - see below */ 246 + __u32 last_hashval = 0; 299 247 int i; 300 248 xfs_failaddr_t fa; 301 249 ··· 331 273 (char *)bp->b_addr + ichdr.firstused) 332 274 return __this_address; 333 275 334 - /* XXX: need to range check rest of attr header values */ 335 - /* XXX: hash order check? */ 276 + buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize; 277 + for (i = 0, ent = entries; i < ichdr.count; ent++, i++) { 278 + fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr, 279 + ent, i, &last_hashval); 280 + if (fa) 281 + return fa; 282 + } 336 283 337 284 /* 338 285 * Quickly check the freemap information. Attribute data has to be ··· 430 367 struct xfs_trans *tp, 431 368 struct xfs_inode *dp, 432 369 xfs_dablk_t bno, 433 - xfs_daddr_t mappedbno, 434 370 struct xfs_buf **bpp) 435 371 { 436 372 int err; 437 373 438 - err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, 439 - XFS_ATTR_FORK, &xfs_attr3_leaf_buf_ops); 374 + err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK, 375 + &xfs_attr3_leaf_buf_ops); 440 376 if (!err && tp && *bpp) 441 377 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF); 442 378 return err; ··· 515 453 * special case for dev/uuid inodes, they have fixed size data forks. 516 454 */ 517 455 int 518 - xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) 456 + xfs_attr_shortform_bytesfit( 457 + struct xfs_inode *dp, 458 + int bytes) 519 459 { 520 - int offset; 521 - int minforkoff; /* lower limit on valid forkoff locations */ 522 - int maxforkoff; /* upper limit on valid forkoff locations */ 523 - int dsize; 524 - xfs_mount_t *mp = dp->i_mount; 460 + struct xfs_mount *mp = dp->i_mount; 461 + int64_t dsize; 462 + int minforkoff; 463 + int maxforkoff; 464 + int offset; 525 465 526 466 /* rounded down */ 527 467 offset = (XFS_LITINO(mp, dp->i_d.di_version) - bytes) >> 3; ··· 589 525 * A data fork btree root must have space for at least 590 526 * MINDBTPTRS key/ptr pairs if the data fork is small or empty. 591 527 */ 592 - minforkoff = max(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); 528 + minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); 593 529 minforkoff = roundup(minforkoff, 8) >> 3; 594 530 595 531 /* attr fork btree root can have at least this many key/ptr pairs */ ··· 828 764 } 829 765 830 766 /* 831 - * Retreive the attribute value and length. 767 + * Retrieve the attribute value and length. 832 768 * 833 769 * If ATTR_KERNOVAL is specified, only the length needs to be returned. 834 770 * Unlike a lookup, we only return an error if the attribute does not ··· 988 924 char *endp; 989 925 struct xfs_ifork *ifp; 990 926 int i; 991 - int size; 927 + int64_t size; 992 928 993 929 ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL); 994 930 ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK); ··· 1144 1080 struct xfs_attr_leafblock *leaf; 1145 1081 struct xfs_attr3_icleaf_hdr icleafhdr; 1146 1082 struct xfs_attr_leaf_entry *entries; 1147 - struct xfs_da_node_entry *btree; 1148 1083 struct xfs_da3_icnode_hdr icnodehdr; 1149 1084 struct xfs_da_intnode *node; 1150 1085 struct xfs_inode *dp = args->dp; ··· 1158 1095 error = xfs_da_grow_inode(args, &blkno); 1159 1096 if (error) 1160 1097 goto out; 1161 - error = xfs_attr3_leaf_read(args->trans, dp, 0, -1, &bp1); 1098 + error = xfs_attr3_leaf_read(args->trans, dp, 0, &bp1); 1162 1099 if (error) 1163 1100 goto out; 1164 1101 1165 - error = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp2, XFS_ATTR_FORK); 1102 + error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK); 1166 1103 if (error) 1167 1104 goto out; 1168 1105 ··· 1183 1120 if (error) 1184 1121 goto out; 1185 1122 node = bp1->b_addr; 1186 - dp->d_ops->node_hdr_from_disk(&icnodehdr, node); 1187 - btree = dp->d_ops->node_tree_p(node); 1123 + xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node); 1188 1124 1189 1125 leaf = bp2->b_addr; 1190 1126 xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf); 1191 1127 entries = xfs_attr3_leaf_entryp(leaf); 1192 1128 1193 1129 /* both on-disk, don't endian-flip twice */ 1194 - btree[0].hashval = entries[icleafhdr.count - 1].hashval; 1195 - btree[0].before = cpu_to_be32(blkno); 1130 + icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval; 1131 + icnodehdr.btree[0].before = cpu_to_be32(blkno); 1196 1132 icnodehdr.count = 1; 1197 - dp->d_ops->node_hdr_to_disk(node, &icnodehdr); 1133 + xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr); 1198 1134 xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1); 1199 1135 error = 0; 1200 1136 out: ··· 1223 1161 1224 1162 trace_xfs_attr_leaf_create(args); 1225 1163 1226 - error = xfs_da_get_buf(args->trans, args->dp, blkno, -1, &bp, 1164 + error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp, 1227 1165 XFS_ATTR_FORK); 1228 1166 if (error) 1229 1167 return error; ··· 1509 1447 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { 1510 1448 if (ichdr->freemap[i].base == tmp) { 1511 1449 ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t); 1512 - ichdr->freemap[i].size -= sizeof(xfs_attr_leaf_entry_t); 1450 + ichdr->freemap[i].size -= 1451 + min_t(uint16_t, ichdr->freemap[i].size, 1452 + sizeof(xfs_attr_leaf_entry_t)); 1513 1453 } 1514 1454 } 1515 1455 ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index); ··· 1995 1931 if (blkno == 0) 1996 1932 continue; 1997 1933 error = xfs_attr3_leaf_read(state->args->trans, state->args->dp, 1998 - blkno, -1, &bp); 1934 + blkno, &bp); 1999 1935 if (error) 2000 1936 return error; 2001 1937 ··· 2345 2281 leaf = bp->b_addr; 2346 2282 xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); 2347 2283 entries = xfs_attr3_leaf_entryp(leaf); 2348 - if (ichdr.count >= args->geo->blksize / 8) 2284 + if (ichdr.count >= args->geo->blksize / 8) { 2285 + xfs_buf_corruption_error(bp); 2349 2286 return -EFSCORRUPTED; 2287 + } 2350 2288 2351 2289 /* 2352 2290 * Binary search. (note: small blocks will skip this loop) ··· 2364 2298 else 2365 2299 break; 2366 2300 } 2367 - if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) 2301 + if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) { 2302 + xfs_buf_corruption_error(bp); 2368 2303 return -EFSCORRUPTED; 2369 - if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) 2304 + } 2305 + if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) { 2306 + xfs_buf_corruption_error(bp); 2370 2307 return -EFSCORRUPTED; 2308 + } 2371 2309 2372 2310 /* 2373 2311 * Since we may have duplicate hashval's, find the first matching ··· 2731 2661 /* 2732 2662 * Set up the operation. 2733 2663 */ 2734 - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 2664 + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp); 2735 2665 if (error) 2736 2666 return error; 2737 2667 ··· 2798 2728 /* 2799 2729 * Set up the operation. 2800 2730 */ 2801 - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp); 2731 + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp); 2802 2732 if (error) 2803 2733 return error; 2804 2734 ··· 2860 2790 /* 2861 2791 * Read the block containing the "old" attr 2862 2792 */ 2863 - error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp1); 2793 + error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, &bp1); 2864 2794 if (error) 2865 2795 return error; 2866 2796 ··· 2869 2799 */ 2870 2800 if (args->blkno2 != args->blkno) { 2871 2801 error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno2, 2872 - -1, &bp2); 2802 + &bp2); 2873 2803 if (error) 2874 2804 return error; 2875 2805 } else {
+26 -4
fs/xfs/libxfs/xfs_attr_leaf.h
··· 17 17 struct xfs_trans; 18 18 19 19 /* 20 + * Incore version of the attribute leaf header. 21 + */ 22 + struct xfs_attr3_icleaf_hdr { 23 + uint32_t forw; 24 + uint32_t back; 25 + uint16_t magic; 26 + uint16_t count; 27 + uint16_t usedbytes; 28 + /* 29 + * Firstused is 32-bit here instead of 16-bit like the on-disk variant 30 + * to support maximum fsb size of 64k without overflow issues throughout 31 + * the attr code. Instead, the overflow condition is handled on 32 + * conversion to/from disk. 33 + */ 34 + uint32_t firstused; 35 + __u8 holes; 36 + struct { 37 + uint16_t base; 38 + uint16_t size; 39 + } freemap[XFS_ATTR_LEAF_MAPSIZE]; 40 + }; 41 + 42 + /* 20 43 * Used to keep a list of "remote value" extents when unlinking an inode. 21 44 */ 22 45 typedef struct xfs_attr_inactive_list { ··· 90 67 struct xfs_da_args *args); 91 68 int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer, 92 69 struct xfs_da_args *args); 93 - void xfs_attr3_leaf_list_int(struct xfs_buf *bp, 94 - struct xfs_attr_list_context *context); 70 + int xfs_attr3_leaf_list_int(struct xfs_buf *bp, 71 + struct xfs_attr_list_context *context); 95 72 96 73 /* 97 74 * Routines used for shrinking the Btree. ··· 108 85 struct xfs_buf *leaf2_bp); 109 86 int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local); 110 87 int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, 111 - xfs_dablk_t bno, xfs_daddr_t mappedbno, 112 - struct xfs_buf **bpp); 88 + xfs_dablk_t bno, struct xfs_buf **bpp); 113 89 void xfs_attr3_leaf_hdr_from_disk(struct xfs_da_geometry *geo, 114 90 struct xfs_attr3_icleaf_hdr *to, 115 91 struct xfs_attr_leafblock *from);
+1
fs/xfs/libxfs/xfs_attr_remote.c
··· 19 19 #include "xfs_trans.h" 20 20 #include "xfs_bmap.h" 21 21 #include "xfs_attr.h" 22 + #include "xfs_attr_remote.h" 22 23 #include "xfs_trace.h" 23 24 #include "xfs_error.h" 24 25
+1
fs/xfs/libxfs/xfs_bit.c
··· 5 5 */ 6 6 #include "xfs.h" 7 7 #include "xfs_log_format.h" 8 + #include "xfs_bit.h" 8 9 9 10 /* 10 11 * XFS bit manipulation routines, used in non-realtime code.
+399 -293
fs/xfs/libxfs/xfs_bmap.c
··· 384 384 xfs_check_block(block, mp, 0, 0); 385 385 pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); 386 386 bno = be64_to_cpu(*pp); 387 - XFS_WANT_CORRUPTED_GOTO(mp, 388 - xfs_verify_fsbno(mp, bno), error0); 387 + if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, bno))) { 388 + error = -EFSCORRUPTED; 389 + goto error0; 390 + } 389 391 if (bp_release) { 390 392 bp_release = 0; 391 393 xfs_trans_brelse(NULL, bp); ··· 614 612 pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); 615 613 cbno = be64_to_cpu(*pp); 616 614 #ifdef DEBUG 617 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, 618 - xfs_btree_check_lptr(cur, cbno, 1)); 615 + if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) 616 + return -EFSCORRUPTED; 619 617 #endif 620 618 error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF, 621 619 &xfs_bmbt_buf_ops); ··· 731 729 ip->i_d.di_nblocks++; 732 730 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); 733 731 abp = xfs_btree_get_bufl(mp, tp, args.fsbno); 734 - if (!abp) { 732 + if (XFS_IS_CORRUPT(mp, !abp)) { 735 733 error = -EFSCORRUPTED; 736 734 goto out_unreserve_dquot; 737 735 } ··· 939 937 if (error) 940 938 goto error0; 941 939 /* must be at least one entry */ 942 - XFS_WANT_CORRUPTED_GOTO(mp, stat == 1, error0); 940 + if (XFS_IS_CORRUPT(mp, stat != 1)) { 941 + error = -EFSCORRUPTED; 942 + goto error0; 943 + } 943 944 if ((error = xfs_btree_new_iroot(cur, flags, &stat))) 944 945 goto error0; 945 946 if (stat == 0) { ··· 1089 1084 goto trans_cancel; 1090 1085 if (XFS_IFORK_Q(ip)) 1091 1086 goto trans_cancel; 1092 - if (ip->i_d.di_anextents != 0) { 1087 + if (XFS_IS_CORRUPT(mp, ip->i_d.di_anextents != 0)) { 1093 1088 error = -EFSCORRUPTED; 1094 1089 goto trans_cancel; 1095 1090 } ··· 1160 1155 * Internal and external extent tree search functions. 1161 1156 */ 1162 1157 1158 + struct xfs_iread_state { 1159 + struct xfs_iext_cursor icur; 1160 + xfs_extnum_t loaded; 1161 + }; 1162 + 1163 + /* Stuff every bmbt record from this block into the incore extent map. */ 1164 + static int 1165 + xfs_iread_bmbt_block( 1166 + struct xfs_btree_cur *cur, 1167 + int level, 1168 + void *priv) 1169 + { 1170 + struct xfs_iread_state *ir = priv; 1171 + struct xfs_mount *mp = cur->bc_mp; 1172 + struct xfs_inode *ip = cur->bc_private.b.ip; 1173 + struct xfs_btree_block *block; 1174 + struct xfs_buf *bp; 1175 + struct xfs_bmbt_rec *frp; 1176 + xfs_extnum_t num_recs; 1177 + xfs_extnum_t j; 1178 + int whichfork = cur->bc_private.b.whichfork; 1179 + 1180 + block = xfs_btree_get_block(cur, level, &bp); 1181 + 1182 + /* Abort if we find more records than nextents. */ 1183 + num_recs = xfs_btree_get_numrecs(block); 1184 + if (unlikely(ir->loaded + num_recs > 1185 + XFS_IFORK_NEXTENTS(ip, whichfork))) { 1186 + xfs_warn(ip->i_mount, "corrupt dinode %llu, (btree extents).", 1187 + (unsigned long long)ip->i_ino); 1188 + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block, 1189 + sizeof(*block), __this_address); 1190 + return -EFSCORRUPTED; 1191 + } 1192 + 1193 + /* Copy records into the incore cache. */ 1194 + frp = XFS_BMBT_REC_ADDR(mp, block, 1); 1195 + for (j = 0; j < num_recs; j++, frp++, ir->loaded++) { 1196 + struct xfs_bmbt_irec new; 1197 + xfs_failaddr_t fa; 1198 + 1199 + xfs_bmbt_disk_get_all(frp, &new); 1200 + fa = xfs_bmap_validate_extent(ip, whichfork, &new); 1201 + if (fa) { 1202 + xfs_inode_verifier_error(ip, -EFSCORRUPTED, 1203 + "xfs_iread_extents(2)", frp, 1204 + sizeof(*frp), fa); 1205 + return -EFSCORRUPTED; 1206 + } 1207 + xfs_iext_insert(ip, &ir->icur, &new, 1208 + xfs_bmap_fork_to_state(whichfork)); 1209 + trace_xfs_read_extent(ip, &ir->icur, 1210 + xfs_bmap_fork_to_state(whichfork), _THIS_IP_); 1211 + xfs_iext_next(XFS_IFORK_PTR(ip, whichfork), &ir->icur); 1212 + } 1213 + 1214 + return 0; 1215 + } 1216 + 1163 1217 /* 1164 1218 * Read in extents from a btree-format inode. 1165 1219 */ ··· 1228 1164 struct xfs_inode *ip, 1229 1165 int whichfork) 1230 1166 { 1231 - struct xfs_mount *mp = ip->i_mount; 1232 - int state = xfs_bmap_fork_to_state(whichfork); 1167 + struct xfs_iread_state ir; 1233 1168 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 1234 - xfs_extnum_t nextents = XFS_IFORK_NEXTENTS(ip, whichfork); 1235 - struct xfs_btree_block *block = ifp->if_broot; 1236 - struct xfs_iext_cursor icur; 1237 - struct xfs_bmbt_irec new; 1238 - xfs_fsblock_t bno; 1239 - struct xfs_buf *bp; 1240 - xfs_extnum_t i, j; 1241 - int level; 1242 - __be64 *pp; 1169 + struct xfs_mount *mp = ip->i_mount; 1170 + struct xfs_btree_cur *cur; 1243 1171 int error; 1244 1172 1245 1173 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 1246 1174 1247 - if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 1248 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 1249 - return -EFSCORRUPTED; 1250 - } 1251 - 1252 - /* 1253 - * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 1254 - */ 1255 - level = be16_to_cpu(block->bb_level); 1256 - if (unlikely(level == 0)) { 1257 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 1258 - return -EFSCORRUPTED; 1259 - } 1260 - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); 1261 - bno = be64_to_cpu(*pp); 1262 - 1263 - /* 1264 - * Go down the tree until leaf level is reached, following the first 1265 - * pointer (leftmost) at each level. 1266 - */ 1267 - while (level-- > 0) { 1268 - error = xfs_btree_read_bufl(mp, tp, bno, &bp, 1269 - XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); 1270 - if (error) 1271 - goto out; 1272 - block = XFS_BUF_TO_BLOCK(bp); 1273 - if (level == 0) 1274 - break; 1275 - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); 1276 - bno = be64_to_cpu(*pp); 1277 - XFS_WANT_CORRUPTED_GOTO(mp, 1278 - xfs_verify_fsbno(mp, bno), out_brelse); 1279 - xfs_trans_brelse(tp, bp); 1280 - } 1281 - 1282 - /* 1283 - * Here with bp and block set to the leftmost leaf node in the tree. 1284 - */ 1285 - i = 0; 1286 - xfs_iext_first(ifp, &icur); 1287 - 1288 - /* 1289 - * Loop over all leaf nodes. Copy information to the extent records. 1290 - */ 1291 - for (;;) { 1292 - xfs_bmbt_rec_t *frp; 1293 - xfs_fsblock_t nextbno; 1294 - xfs_extnum_t num_recs; 1295 - 1296 - num_recs = xfs_btree_get_numrecs(block); 1297 - if (unlikely(i + num_recs > nextents)) { 1298 - xfs_warn(ip->i_mount, 1299 - "corrupt dinode %Lu, (btree extents).", 1300 - (unsigned long long) ip->i_ino); 1301 - xfs_inode_verifier_error(ip, -EFSCORRUPTED, 1302 - __func__, block, sizeof(*block), 1303 - __this_address); 1304 - error = -EFSCORRUPTED; 1305 - goto out_brelse; 1306 - } 1307 - /* 1308 - * Read-ahead the next leaf block, if any. 1309 - */ 1310 - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); 1311 - if (nextbno != NULLFSBLOCK) 1312 - xfs_btree_reada_bufl(mp, nextbno, 1, 1313 - &xfs_bmbt_buf_ops); 1314 - /* 1315 - * Copy records into the extent records. 1316 - */ 1317 - frp = XFS_BMBT_REC_ADDR(mp, block, 1); 1318 - for (j = 0; j < num_recs; j++, frp++, i++) { 1319 - xfs_failaddr_t fa; 1320 - 1321 - xfs_bmbt_disk_get_all(frp, &new); 1322 - fa = xfs_bmap_validate_extent(ip, whichfork, &new); 1323 - if (fa) { 1324 - error = -EFSCORRUPTED; 1325 - xfs_inode_verifier_error(ip, error, 1326 - "xfs_iread_extents(2)", 1327 - frp, sizeof(*frp), fa); 1328 - goto out_brelse; 1329 - } 1330 - xfs_iext_insert(ip, &icur, &new, state); 1331 - trace_xfs_read_extent(ip, &icur, state, _THIS_IP_); 1332 - xfs_iext_next(ifp, &icur); 1333 - } 1334 - xfs_trans_brelse(tp, bp); 1335 - bno = nextbno; 1336 - /* 1337 - * If we've reached the end, stop. 1338 - */ 1339 - if (bno == NULLFSBLOCK) 1340 - break; 1341 - error = xfs_btree_read_bufl(mp, tp, bno, &bp, 1342 - XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops); 1343 - if (error) 1344 - goto out; 1345 - block = XFS_BUF_TO_BLOCK(bp); 1346 - } 1347 - 1348 - if (i != XFS_IFORK_NEXTENTS(ip, whichfork)) { 1175 + if (XFS_IS_CORRUPT(mp, 1176 + XFS_IFORK_FORMAT(ip, whichfork) != 1177 + XFS_DINODE_FMT_BTREE)) { 1349 1178 error = -EFSCORRUPTED; 1350 1179 goto out; 1351 1180 } 1352 - ASSERT(i == xfs_iext_count(ifp)); 1181 + 1182 + ir.loaded = 0; 1183 + xfs_iext_first(ifp, &ir.icur); 1184 + cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); 1185 + error = xfs_btree_visit_blocks(cur, xfs_iread_bmbt_block, 1186 + XFS_BTREE_VISIT_RECORDS, &ir); 1187 + xfs_btree_del_cursor(cur, error); 1188 + if (error) 1189 + goto out; 1190 + 1191 + if (XFS_IS_CORRUPT(mp, 1192 + ir.loaded != XFS_IFORK_NEXTENTS(ip, whichfork))) { 1193 + error = -EFSCORRUPTED; 1194 + goto out; 1195 + } 1196 + ASSERT(ir.loaded == xfs_iext_count(ifp)); 1353 1197 1354 1198 ifp->if_flags |= XFS_IFEXTENTS; 1355 1199 return 0; 1356 - 1357 - out_brelse: 1358 - xfs_trans_brelse(tp, bp); 1359 1200 out: 1360 1201 xfs_iext_destroy(ifp); 1361 1202 return error; ··· 1287 1318 xfs_fileoff_t lowest, max; 1288 1319 int error; 1289 1320 1290 - ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE || 1291 - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS || 1321 + ASSERT(xfs_ifork_has_extents(ip, whichfork) || 1292 1322 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 1293 1323 1294 1324 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { ··· 1343 1375 case XFS_DINODE_FMT_EXTENTS: 1344 1376 break; 1345 1377 default: 1346 - return -EIO; 1378 + ASSERT(0); 1379 + return -EFSCORRUPTED; 1347 1380 } 1348 1381 1349 1382 if (!(ifp->if_flags & XFS_IFEXTENTS)) { ··· 1443 1474 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) 1444 1475 return 0; 1445 1476 1446 - if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && 1447 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) 1448 - return -EIO; 1477 + if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ip, whichfork))) 1478 + return -EFSCORRUPTED; 1449 1479 1450 1480 error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty); 1451 1481 if (error || is_empty) ··· 1621 1653 error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i); 1622 1654 if (error) 1623 1655 goto done; 1624 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1656 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1657 + error = -EFSCORRUPTED; 1658 + goto done; 1659 + } 1625 1660 error = xfs_btree_delete(bma->cur, &i); 1626 1661 if (error) 1627 1662 goto done; 1628 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1663 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1664 + error = -EFSCORRUPTED; 1665 + goto done; 1666 + } 1629 1667 error = xfs_btree_decrement(bma->cur, 0, &i); 1630 1668 if (error) 1631 1669 goto done; 1632 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1670 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1671 + error = -EFSCORRUPTED; 1672 + goto done; 1673 + } 1633 1674 error = xfs_bmbt_update(bma->cur, &LEFT); 1634 1675 if (error) 1635 1676 goto done; ··· 1664 1687 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i); 1665 1688 if (error) 1666 1689 goto done; 1667 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1690 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1691 + error = -EFSCORRUPTED; 1692 + goto done; 1693 + } 1668 1694 error = xfs_bmbt_update(bma->cur, &LEFT); 1669 1695 if (error) 1670 1696 goto done; ··· 1697 1717 error = xfs_bmbt_lookup_eq(bma->cur, &RIGHT, &i); 1698 1718 if (error) 1699 1719 goto done; 1700 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1720 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1721 + error = -EFSCORRUPTED; 1722 + goto done; 1723 + } 1701 1724 error = xfs_bmbt_update(bma->cur, &PREV); 1702 1725 if (error) 1703 1726 goto done; ··· 1725 1742 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); 1726 1743 if (error) 1727 1744 goto done; 1728 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 1745 + if (XFS_IS_CORRUPT(mp, i != 0)) { 1746 + error = -EFSCORRUPTED; 1747 + goto done; 1748 + } 1729 1749 error = xfs_btree_insert(bma->cur, &i); 1730 1750 if (error) 1731 1751 goto done; 1732 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1752 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1753 + error = -EFSCORRUPTED; 1754 + goto done; 1755 + } 1733 1756 } 1734 1757 break; 1735 1758 ··· 1766 1777 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i); 1767 1778 if (error) 1768 1779 goto done; 1769 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1780 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1781 + error = -EFSCORRUPTED; 1782 + goto done; 1783 + } 1770 1784 error = xfs_bmbt_update(bma->cur, &LEFT); 1771 1785 if (error) 1772 1786 goto done; ··· 1790 1798 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); 1791 1799 if (error) 1792 1800 goto done; 1793 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 1801 + if (XFS_IS_CORRUPT(mp, i != 0)) { 1802 + error = -EFSCORRUPTED; 1803 + goto done; 1804 + } 1794 1805 error = xfs_btree_insert(bma->cur, &i); 1795 1806 if (error) 1796 1807 goto done; 1797 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1808 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1809 + error = -EFSCORRUPTED; 1810 + goto done; 1811 + } 1798 1812 } 1799 1813 1800 1814 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { ··· 1841 1843 error = xfs_bmbt_lookup_eq(bma->cur, &old, &i); 1842 1844 if (error) 1843 1845 goto done; 1844 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1846 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1847 + error = -EFSCORRUPTED; 1848 + goto done; 1849 + } 1845 1850 error = xfs_bmbt_update(bma->cur, &RIGHT); 1846 1851 if (error) 1847 1852 goto done; ··· 1876 1875 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); 1877 1876 if (error) 1878 1877 goto done; 1879 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 1878 + if (XFS_IS_CORRUPT(mp, i != 0)) { 1879 + error = -EFSCORRUPTED; 1880 + goto done; 1881 + } 1880 1882 error = xfs_btree_insert(bma->cur, &i); 1881 1883 if (error) 1882 1884 goto done; 1883 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1885 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1886 + error = -EFSCORRUPTED; 1887 + goto done; 1888 + } 1884 1889 } 1885 1890 1886 1891 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { ··· 1962 1955 error = xfs_bmbt_lookup_eq(bma->cur, new, &i); 1963 1956 if (error) 1964 1957 goto done; 1965 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 1958 + if (XFS_IS_CORRUPT(mp, i != 0)) { 1959 + error = -EFSCORRUPTED; 1960 + goto done; 1961 + } 1966 1962 error = xfs_btree_insert(bma->cur, &i); 1967 1963 if (error) 1968 1964 goto done; 1969 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1965 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1966 + error = -EFSCORRUPTED; 1967 + goto done; 1968 + } 1970 1969 } 1971 1970 1972 1971 if (xfs_bmap_needs_btree(bma->ip, whichfork)) { ··· 2166 2153 error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i); 2167 2154 if (error) 2168 2155 goto done; 2169 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2156 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2157 + error = -EFSCORRUPTED; 2158 + goto done; 2159 + } 2170 2160 if ((error = xfs_btree_delete(cur, &i))) 2171 2161 goto done; 2172 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2162 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2163 + error = -EFSCORRUPTED; 2164 + goto done; 2165 + } 2173 2166 if ((error = xfs_btree_decrement(cur, 0, &i))) 2174 2167 goto done; 2175 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2168 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2169 + error = -EFSCORRUPTED; 2170 + goto done; 2171 + } 2176 2172 if ((error = xfs_btree_delete(cur, &i))) 2177 2173 goto done; 2178 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2174 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2175 + error = -EFSCORRUPTED; 2176 + goto done; 2177 + } 2179 2178 if ((error = xfs_btree_decrement(cur, 0, &i))) 2180 2179 goto done; 2181 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2180 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2181 + error = -EFSCORRUPTED; 2182 + goto done; 2183 + } 2182 2184 error = xfs_bmbt_update(cur, &LEFT); 2183 2185 if (error) 2184 2186 goto done; ··· 2219 2191 error = xfs_bmbt_lookup_eq(cur, &PREV, &i); 2220 2192 if (error) 2221 2193 goto done; 2222 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2194 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2195 + error = -EFSCORRUPTED; 2196 + goto done; 2197 + } 2223 2198 if ((error = xfs_btree_delete(cur, &i))) 2224 2199 goto done; 2225 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2200 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2201 + error = -EFSCORRUPTED; 2202 + goto done; 2203 + } 2226 2204 if ((error = xfs_btree_decrement(cur, 0, &i))) 2227 2205 goto done; 2228 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2206 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2207 + error = -EFSCORRUPTED; 2208 + goto done; 2209 + } 2229 2210 error = xfs_bmbt_update(cur, &LEFT); 2230 2211 if (error) 2231 2212 goto done; ··· 2263 2226 error = xfs_bmbt_lookup_eq(cur, &RIGHT, &i); 2264 2227 if (error) 2265 2228 goto done; 2266 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2229 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2230 + error = -EFSCORRUPTED; 2231 + goto done; 2232 + } 2267 2233 if ((error = xfs_btree_delete(cur, &i))) 2268 2234 goto done; 2269 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2235 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2236 + error = -EFSCORRUPTED; 2237 + goto done; 2238 + } 2270 2239 if ((error = xfs_btree_decrement(cur, 0, &i))) 2271 2240 goto done; 2272 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2241 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2242 + error = -EFSCORRUPTED; 2243 + goto done; 2244 + } 2273 2245 error = xfs_bmbt_update(cur, &PREV); 2274 2246 if (error) 2275 2247 goto done; ··· 2301 2255 error = xfs_bmbt_lookup_eq(cur, new, &i); 2302 2256 if (error) 2303 2257 goto done; 2304 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2258 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2259 + error = -EFSCORRUPTED; 2260 + goto done; 2261 + } 2305 2262 error = xfs_bmbt_update(cur, &PREV); 2306 2263 if (error) 2307 2264 goto done; ··· 2334 2285 error = xfs_bmbt_lookup_eq(cur, &old, &i); 2335 2286 if (error) 2336 2287 goto done; 2337 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2288 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2289 + error = -EFSCORRUPTED; 2290 + goto done; 2291 + } 2338 2292 error = xfs_bmbt_update(cur, &PREV); 2339 2293 if (error) 2340 2294 goto done; ··· 2371 2319 error = xfs_bmbt_lookup_eq(cur, &old, &i); 2372 2320 if (error) 2373 2321 goto done; 2374 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2322 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2323 + error = -EFSCORRUPTED; 2324 + goto done; 2325 + } 2375 2326 error = xfs_bmbt_update(cur, &PREV); 2376 2327 if (error) 2377 2328 goto done; 2378 2329 cur->bc_rec.b = *new; 2379 2330 if ((error = xfs_btree_insert(cur, &i))) 2380 2331 goto done; 2381 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2332 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2333 + error = -EFSCORRUPTED; 2334 + goto done; 2335 + } 2382 2336 } 2383 2337 break; 2384 2338 ··· 2411 2353 error = xfs_bmbt_lookup_eq(cur, &old, &i); 2412 2354 if (error) 2413 2355 goto done; 2414 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2356 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2357 + error = -EFSCORRUPTED; 2358 + goto done; 2359 + } 2415 2360 error = xfs_bmbt_update(cur, &PREV); 2416 2361 if (error) 2417 2362 goto done; ··· 2448 2387 error = xfs_bmbt_lookup_eq(cur, &old, &i); 2449 2388 if (error) 2450 2389 goto done; 2451 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2390 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2391 + error = -EFSCORRUPTED; 2392 + goto done; 2393 + } 2452 2394 error = xfs_bmbt_update(cur, &PREV); 2453 2395 if (error) 2454 2396 goto done; 2455 2397 error = xfs_bmbt_lookup_eq(cur, new, &i); 2456 2398 if (error) 2457 2399 goto done; 2458 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 2400 + if (XFS_IS_CORRUPT(mp, i != 0)) { 2401 + error = -EFSCORRUPTED; 2402 + goto done; 2403 + } 2459 2404 if ((error = xfs_btree_insert(cur, &i))) 2460 2405 goto done; 2461 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2406 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2407 + error = -EFSCORRUPTED; 2408 + goto done; 2409 + } 2462 2410 } 2463 2411 break; 2464 2412 ··· 2501 2431 error = xfs_bmbt_lookup_eq(cur, &old, &i); 2502 2432 if (error) 2503 2433 goto done; 2504 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2434 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2435 + error = -EFSCORRUPTED; 2436 + goto done; 2437 + } 2505 2438 /* new right extent - oldext */ 2506 2439 error = xfs_bmbt_update(cur, &r[1]); 2507 2440 if (error) ··· 2513 2440 cur->bc_rec.b = PREV; 2514 2441 if ((error = xfs_btree_insert(cur, &i))) 2515 2442 goto done; 2516 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2443 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2444 + error = -EFSCORRUPTED; 2445 + goto done; 2446 + } 2517 2447 /* 2518 2448 * Reset the cursor to the position of the new extent 2519 2449 * we are about to insert as we can't trust it after ··· 2525 2449 error = xfs_bmbt_lookup_eq(cur, new, &i); 2526 2450 if (error) 2527 2451 goto done; 2528 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 2452 + if (XFS_IS_CORRUPT(mp, i != 0)) { 2453 + error = -EFSCORRUPTED; 2454 + goto done; 2455 + } 2529 2456 /* new middle extent - newext */ 2530 2457 if ((error = xfs_btree_insert(cur, &i))) 2531 2458 goto done; 2532 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2459 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2460 + error = -EFSCORRUPTED; 2461 + goto done; 2462 + } 2533 2463 } 2534 2464 break; 2535 2465 ··· 2818 2736 error = xfs_bmbt_lookup_eq(cur, &right, &i); 2819 2737 if (error) 2820 2738 goto done; 2821 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2739 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2740 + error = -EFSCORRUPTED; 2741 + goto done; 2742 + } 2822 2743 error = xfs_btree_delete(cur, &i); 2823 2744 if (error) 2824 2745 goto done; 2825 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2746 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2747 + error = -EFSCORRUPTED; 2748 + goto done; 2749 + } 2826 2750 error = xfs_btree_decrement(cur, 0, &i); 2827 2751 if (error) 2828 2752 goto done; 2829 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2753 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2754 + error = -EFSCORRUPTED; 2755 + goto done; 2756 + } 2830 2757 error = xfs_bmbt_update(cur, &left); 2831 2758 if (error) 2832 2759 goto done; ··· 2861 2770 error = xfs_bmbt_lookup_eq(cur, &old, &i); 2862 2771 if (error) 2863 2772 goto done; 2864 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2773 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2774 + error = -EFSCORRUPTED; 2775 + goto done; 2776 + } 2865 2777 error = xfs_bmbt_update(cur, &left); 2866 2778 if (error) 2867 2779 goto done; ··· 2891 2797 error = xfs_bmbt_lookup_eq(cur, &old, &i); 2892 2798 if (error) 2893 2799 goto done; 2894 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2800 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2801 + error = -EFSCORRUPTED; 2802 + goto done; 2803 + } 2895 2804 error = xfs_bmbt_update(cur, &right); 2896 2805 if (error) 2897 2806 goto done; ··· 2917 2820 error = xfs_bmbt_lookup_eq(cur, new, &i); 2918 2821 if (error) 2919 2822 goto done; 2920 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 2823 + if (XFS_IS_CORRUPT(mp, i != 0)) { 2824 + error = -EFSCORRUPTED; 2825 + goto done; 2826 + } 2921 2827 error = xfs_btree_insert(cur, &i); 2922 2828 if (error) 2923 2829 goto done; 2924 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 2830 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2831 + error = -EFSCORRUPTED; 2832 + goto done; 2833 + } 2925 2834 } 2926 2835 break; 2927 2836 } ··· 3162 3059 mp = ap->ip->i_mount; 3163 3060 nullfb = ap->tp->t_firstblock == NULLFSBLOCK; 3164 3061 rt = XFS_IS_REALTIME_INODE(ap->ip) && 3165 - xfs_alloc_is_userdata(ap->datatype); 3062 + (ap->datatype & XFS_ALLOC_USERDATA); 3166 3063 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, 3167 3064 ap->tp->t_firstblock); 3168 3065 /* ··· 3515 3412 3516 3413 if (ap->flags & XFS_BMAPI_COWFORK) 3517 3414 align = xfs_get_cowextsz_hint(ap->ip); 3518 - else if (xfs_alloc_is_userdata(ap->datatype)) 3415 + else if (ap->datatype & XFS_ALLOC_USERDATA) 3519 3416 align = xfs_get_extsz_hint(ap->ip); 3520 3417 if (align) { 3521 3418 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, ··· 3530 3427 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, 3531 3428 ap->tp->t_firstblock); 3532 3429 if (nullfb) { 3533 - if (xfs_alloc_is_userdata(ap->datatype) && 3430 + if ((ap->datatype & XFS_ALLOC_USERDATA) && 3534 3431 xfs_inode_is_filestream(ap->ip)) { 3535 3432 ag = xfs_filestream_lookup_ag(ap->ip); 3536 3433 ag = (ag != NULLAGNUMBER) ? ag : 0; ··· 3570 3467 * enough for the request. If one isn't found, then adjust 3571 3468 * the minimum allocation size to the largest space found. 3572 3469 */ 3573 - if (xfs_alloc_is_userdata(ap->datatype) && 3470 + if ((ap->datatype & XFS_ALLOC_USERDATA) && 3574 3471 xfs_inode_is_filestream(ap->ip)) 3575 3472 error = xfs_bmap_btalloc_filestreams(ap, &args, &blen); 3576 3473 else ··· 3604 3501 args.mod = args.prod - args.mod; 3605 3502 } 3606 3503 /* 3607 - * If we are not low on available data blocks, and the 3608 - * underlying logical volume manager is a stripe, and 3609 - * the file offset is zero then try to allocate data 3610 - * blocks on stripe unit boundary. 3611 - * NOTE: ap->aeof is only set if the allocation length 3612 - * is >= the stripe unit and the allocation offset is 3613 - * at the end of file. 3504 + * If we are not low on available data blocks, and the underlying 3505 + * logical volume manager is a stripe, and the file offset is zero then 3506 + * try to allocate data blocks on stripe unit boundary. NOTE: ap->aeof 3507 + * is only set if the allocation length is >= the stripe unit and the 3508 + * allocation offset is at the end of file. 3614 3509 */ 3615 3510 if (!(ap->tp->t_flags & XFS_TRANS_LOWMODE) && ap->aeof) { 3616 3511 if (!ap->offset) { ··· 3616 3515 atype = args.type; 3617 3516 isaligned = 1; 3618 3517 /* 3619 - * Adjust for alignment 3518 + * Adjust minlen to try and preserve alignment if we 3519 + * can't guarantee an aligned maxlen extent. 3620 3520 */ 3621 - if (blen > args.alignment && blen <= args.maxlen) 3521 + if (blen > args.alignment && 3522 + blen <= args.maxlen + args.alignment) 3622 3523 args.minlen = blen - args.alignment; 3623 3524 args.minalignslop = 0; 3624 3525 } else { ··· 3658 3555 args.wasdel = ap->wasdel; 3659 3556 args.resv = XFS_AG_RESV_NONE; 3660 3557 args.datatype = ap->datatype; 3661 - if (ap->datatype & XFS_ALLOC_USERDATA_ZERO) 3662 - args.ip = ap->ip; 3663 3558 3664 3559 error = xfs_alloc_vextent(&args); 3665 3560 if (error) ··· 3740 3639 ap->length = 0; 3741 3640 } 3742 3641 return 0; 3743 - } 3744 - 3745 - /* 3746 - * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 3747 - * It figures out where to ask the underlying allocator to put the new extent. 3748 - */ 3749 - STATIC int 3750 - xfs_bmap_alloc( 3751 - struct xfs_bmalloca *ap) /* bmap alloc argument struct */ 3752 - { 3753 - if (XFS_IS_REALTIME_INODE(ap->ip) && 3754 - xfs_alloc_is_userdata(ap->datatype)) 3755 - return xfs_bmap_rtalloc(ap); 3756 - return xfs_bmap_btalloc(ap); 3757 3642 } 3758 3643 3759 3644 /* Trim extent to fit a logical block range. */ ··· 3903 3816 XFS_BMAPI_COWFORK))); 3904 3817 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)); 3905 3818 3906 - if (unlikely(XFS_TEST_ERROR( 3907 - (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 3908 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 3909 - mp, XFS_ERRTAG_BMAPIFORMAT))) { 3910 - XFS_ERROR_REPORT("xfs_bmapi_read", XFS_ERRLEVEL_LOW, mp); 3819 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || 3820 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { 3911 3821 return -EFSCORRUPTED; 3912 3822 } 3913 3823 ··· 4095 4011 } 4096 4012 4097 4013 static int 4014 + xfs_bmap_alloc_userdata( 4015 + struct xfs_bmalloca *bma) 4016 + { 4017 + struct xfs_mount *mp = bma->ip->i_mount; 4018 + int whichfork = xfs_bmapi_whichfork(bma->flags); 4019 + int error; 4020 + 4021 + /* 4022 + * Set the data type being allocated. For the data fork, the first data 4023 + * in the file is treated differently to all other allocations. For the 4024 + * attribute fork, we only need to ensure the allocated range is not on 4025 + * the busy list. 4026 + */ 4027 + bma->datatype = XFS_ALLOC_NOBUSY; 4028 + if (whichfork == XFS_DATA_FORK) { 4029 + bma->datatype |= XFS_ALLOC_USERDATA; 4030 + if (bma->offset == 0) 4031 + bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA; 4032 + 4033 + if (mp->m_dalign && bma->length >= mp->m_dalign) { 4034 + error = xfs_bmap_isaeof(bma, whichfork); 4035 + if (error) 4036 + return error; 4037 + } 4038 + 4039 + if (XFS_IS_REALTIME_INODE(bma->ip)) 4040 + return xfs_bmap_rtalloc(bma); 4041 + } 4042 + 4043 + return xfs_bmap_btalloc(bma); 4044 + } 4045 + 4046 + static int 4098 4047 xfs_bmapi_allocate( 4099 4048 struct xfs_bmalloca *bma) 4100 4049 { ··· 4146 4029 if (bma->wasdel) { 4147 4030 bma->length = (xfs_extlen_t)bma->got.br_blockcount; 4148 4031 bma->offset = bma->got.br_startoff; 4149 - xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev); 4032 + if (!xfs_iext_peek_prev_extent(ifp, &bma->icur, &bma->prev)) 4033 + bma->prev.br_startoff = NULLFILEOFF; 4150 4034 } else { 4151 4035 bma->length = XFS_FILBLKS_MIN(bma->length, MAXEXTLEN); 4152 4036 if (!bma->eof) ··· 4155 4037 bma->got.br_startoff - bma->offset); 4156 4038 } 4157 4039 4158 - /* 4159 - * Set the data type being allocated. For the data fork, the first data 4160 - * in the file is treated differently to all other allocations. For the 4161 - * attribute fork, we only need to ensure the allocated range is not on 4162 - * the busy list. 4163 - */ 4164 - if (!(bma->flags & XFS_BMAPI_METADATA)) { 4165 - bma->datatype = XFS_ALLOC_NOBUSY; 4166 - if (whichfork == XFS_DATA_FORK) { 4167 - if (bma->offset == 0) 4168 - bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA; 4169 - else 4170 - bma->datatype |= XFS_ALLOC_USERDATA; 4171 - } 4172 - if (bma->flags & XFS_BMAPI_ZERO) 4173 - bma->datatype |= XFS_ALLOC_USERDATA_ZERO; 4174 - } 4040 + if (bma->flags & XFS_BMAPI_CONTIG) 4041 + bma->minlen = bma->length; 4042 + else 4043 + bma->minlen = 1; 4175 4044 4176 - bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; 4045 + if (bma->flags & XFS_BMAPI_METADATA) 4046 + error = xfs_bmap_btalloc(bma); 4047 + else 4048 + error = xfs_bmap_alloc_userdata(bma); 4049 + if (error || bma->blkno == NULLFSBLOCK) 4050 + return error; 4177 4051 4178 - /* 4179 - * Only want to do the alignment at the eof if it is userdata and 4180 - * allocation length is larger than a stripe unit. 4181 - */ 4182 - if (mp->m_dalign && bma->length >= mp->m_dalign && 4183 - !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { 4184 - error = xfs_bmap_isaeof(bma, whichfork); 4052 + if (bma->flags & XFS_BMAPI_ZERO) { 4053 + error = xfs_zero_extent(bma->ip, bma->blkno, bma->length); 4185 4054 if (error) 4186 4055 return error; 4187 4056 } 4188 4057 4189 - error = xfs_bmap_alloc(bma); 4190 - if (error) 4191 - return error; 4192 - 4193 - if (bma->blkno == NULLFSBLOCK) 4194 - return 0; 4195 4058 if ((ifp->if_flags & XFS_IFBROOT) && !bma->cur) 4196 4059 bma->cur = xfs_bmbt_init_cursor(mp, bma->tp, bma->ip, whichfork); 4197 4060 /* ··· 4412 4313 ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != 4413 4314 (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); 4414 4315 4415 - if (unlikely(XFS_TEST_ERROR( 4416 - (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4417 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 4418 - mp, XFS_ERRTAG_BMAPIFORMAT))) { 4419 - XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp); 4316 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || 4317 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { 4420 4318 return -EFSCORRUPTED; 4421 4319 } 4422 4320 ··· 4607 4511 bma.wasdel = true; 4608 4512 bma.offset = bma.got.br_startoff; 4609 4513 bma.length = max_t(xfs_filblks_t, bma.got.br_blockcount, MAXEXTLEN); 4610 - bma.total = XFS_EXTENTADD_SPACE_RES(ip->i_mount, XFS_DATA_FORK); 4611 4514 bma.minleft = xfs_bmapi_minleft(tp, ip, whichfork); 4612 4515 if (whichfork == XFS_COW_FORK) 4613 4516 bma.flags = XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC; ··· 4679 4584 ASSERT((flags & (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)) != 4680 4585 (XFS_BMAPI_ATTRFORK | XFS_BMAPI_PREALLOC)); 4681 4586 4682 - if (unlikely(XFS_TEST_ERROR( 4683 - (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 4684 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 4685 - mp, XFS_ERRTAG_BMAPIFORMAT))) { 4686 - XFS_ERROR_REPORT("xfs_bmapi_remap", XFS_ERRLEVEL_LOW, mp); 4587 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || 4588 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { 4687 4589 return -EFSCORRUPTED; 4688 4590 } 4689 4591 ··· 5111 5019 error = xfs_bmbt_lookup_eq(cur, &got, &i); 5112 5020 if (error) 5113 5021 goto done; 5114 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 5022 + if (XFS_IS_CORRUPT(mp, i != 1)) { 5023 + error = -EFSCORRUPTED; 5024 + goto done; 5025 + } 5115 5026 } 5116 5027 5117 5028 if (got.br_startoff == del->br_startoff) ··· 5138 5043 } 5139 5044 if ((error = xfs_btree_delete(cur, &i))) 5140 5045 goto done; 5141 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 5046 + if (XFS_IS_CORRUPT(mp, i != 1)) { 5047 + error = -EFSCORRUPTED; 5048 + goto done; 5049 + } 5142 5050 break; 5143 5051 case BMAP_LEFT_FILLING: 5144 5052 /* ··· 5212 5114 error = xfs_bmbt_lookup_eq(cur, &got, &i); 5213 5115 if (error) 5214 5116 goto done; 5215 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 5117 + if (XFS_IS_CORRUPT(mp, i != 1)) { 5118 + error = -EFSCORRUPTED; 5119 + goto done; 5120 + } 5216 5121 /* 5217 5122 * Update the btree record back 5218 5123 * to the original value. ··· 5232 5131 error = -ENOSPC; 5233 5132 goto done; 5234 5133 } 5235 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 5134 + if (XFS_IS_CORRUPT(mp, i != 1)) { 5135 + error = -EFSCORRUPTED; 5136 + goto done; 5137 + } 5236 5138 } else 5237 5139 flags |= xfs_ilog_fext(whichfork); 5238 5140 XFS_IFORK_NEXT_SET(ip, whichfork, ··· 5302 5198 int isrt; /* freeing in rt area */ 5303 5199 int logflags; /* transaction logging flags */ 5304 5200 xfs_extlen_t mod; /* rt extent offset */ 5305 - struct xfs_mount *mp; /* mount structure */ 5201 + struct xfs_mount *mp = ip->i_mount; 5306 5202 int tmp_logflags; /* partial logging flags */ 5307 5203 int wasdel; /* was a delayed alloc extent */ 5308 5204 int whichfork; /* data or attribute fork */ ··· 5319 5215 whichfork = xfs_bmapi_whichfork(flags); 5320 5216 ASSERT(whichfork != XFS_COW_FORK); 5321 5217 ifp = XFS_IFORK_PTR(ip, whichfork); 5322 - if (unlikely( 5323 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 5324 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 5325 - XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW, 5326 - ip->i_mount); 5218 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork))) 5327 5219 return -EFSCORRUPTED; 5328 - } 5329 - mp = ip->i_mount; 5330 5220 if (XFS_FORCED_SHUTDOWN(mp)) 5331 5221 return -EIO; 5332 5222 ··· 5714 5616 error = xfs_bmbt_lookup_eq(cur, got, &i); 5715 5617 if (error) 5716 5618 return error; 5717 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 5619 + if (XFS_IS_CORRUPT(mp, i != 1)) 5620 + return -EFSCORRUPTED; 5718 5621 5719 5622 error = xfs_btree_delete(cur, &i); 5720 5623 if (error) 5721 5624 return error; 5722 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 5625 + if (XFS_IS_CORRUPT(mp, i != 1)) 5626 + return -EFSCORRUPTED; 5723 5627 5724 5628 /* lookup and update size of the previous extent */ 5725 5629 error = xfs_bmbt_lookup_eq(cur, left, &i); 5726 5630 if (error) 5727 5631 return error; 5728 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 5632 + if (XFS_IS_CORRUPT(mp, i != 1)) 5633 + return -EFSCORRUPTED; 5729 5634 5730 5635 error = xfs_bmbt_update(cur, &new); 5731 5636 if (error) ··· 5776 5675 error = xfs_bmbt_lookup_eq(cur, &prev, &i); 5777 5676 if (error) 5778 5677 return error; 5779 - XFS_WANT_CORRUPTED_RETURN(mp, i == 1); 5678 + if (XFS_IS_CORRUPT(mp, i != 1)) 5679 + return -EFSCORRUPTED; 5780 5680 5781 5681 error = xfs_bmbt_update(cur, got); 5782 5682 if (error) ··· 5813 5711 int error = 0; 5814 5712 int logflags = 0; 5815 5713 5816 - if (unlikely(XFS_TEST_ERROR( 5817 - (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 5818 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 5819 - mp, XFS_ERRTAG_BMAPIFORMAT))) { 5820 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 5714 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || 5715 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { 5821 5716 return -EFSCORRUPTED; 5822 5717 } 5823 5718 ··· 5838 5739 *done = true; 5839 5740 goto del_cursor; 5840 5741 } 5841 - XFS_WANT_CORRUPTED_GOTO(mp, !isnullstartblock(got.br_startblock), 5842 - del_cursor); 5742 + if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) { 5743 + error = -EFSCORRUPTED; 5744 + goto del_cursor; 5745 + } 5843 5746 5844 5747 new_startoff = got.br_startoff - offset_shift_fsb; 5845 5748 if (xfs_iext_peek_prev_extent(ifp, &icur, &prev)) { ··· 5930 5829 int error = 0; 5931 5830 int logflags = 0; 5932 5831 5933 - if (unlikely(XFS_TEST_ERROR( 5934 - (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 5935 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 5936 - mp, XFS_ERRTAG_BMAPIFORMAT))) { 5937 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 5832 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || 5833 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { 5938 5834 return -EFSCORRUPTED; 5939 5835 } 5940 5836 ··· 5964 5866 goto del_cursor; 5965 5867 } 5966 5868 } 5967 - XFS_WANT_CORRUPTED_GOTO(mp, !isnullstartblock(got.br_startblock), 5968 - del_cursor); 5869 + if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) { 5870 + error = -EFSCORRUPTED; 5871 + goto del_cursor; 5872 + } 5969 5873 5970 - if (stop_fsb >= got.br_startoff + got.br_blockcount) { 5971 - error = -EIO; 5874 + if (XFS_IS_CORRUPT(mp, 5875 + stop_fsb >= got.br_startoff + got.br_blockcount)) { 5876 + error = -EFSCORRUPTED; 5972 5877 goto del_cursor; 5973 5878 } 5974 5879 ··· 6036 5935 int logflags = 0; 6037 5936 int i = 0; 6038 5937 6039 - if (unlikely(XFS_TEST_ERROR( 6040 - (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 6041 - XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), 6042 - mp, XFS_ERRTAG_BMAPIFORMAT))) { 6043 - XFS_ERROR_REPORT("xfs_bmap_split_extent_at", 6044 - XFS_ERRLEVEL_LOW, mp); 5938 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, whichfork)) || 5939 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { 6045 5940 return -EFSCORRUPTED; 6046 5941 } 6047 5942 ··· 6071 5974 error = xfs_bmbt_lookup_eq(cur, &got, &i); 6072 5975 if (error) 6073 5976 goto del_cursor; 6074 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); 5977 + if (XFS_IS_CORRUPT(mp, i != 1)) { 5978 + error = -EFSCORRUPTED; 5979 + goto del_cursor; 5980 + } 6075 5981 } 6076 5982 6077 5983 got.br_blockcount = gotblkcnt; ··· 6099 5999 error = xfs_bmbt_lookup_eq(cur, &new, &i); 6100 6000 if (error) 6101 6001 goto del_cursor; 6102 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, del_cursor); 6002 + if (XFS_IS_CORRUPT(mp, i != 0)) { 6003 + error = -EFSCORRUPTED; 6004 + goto del_cursor; 6005 + } 6103 6006 error = xfs_btree_insert(cur, &i); 6104 6007 if (error) 6105 6008 goto del_cursor; 6106 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); 6009 + if (XFS_IS_CORRUPT(mp, i != 1)) { 6010 + error = -EFSCORRUPTED; 6011 + goto del_cursor; 6012 + } 6107 6013 } 6108 6014 6109 6015 /*
+57 -40
fs/xfs/libxfs/xfs_btree.c
··· 105 105 xfs_failaddr_t fa; 106 106 107 107 fa = __xfs_btree_check_lblock(cur, block, level, bp); 108 - if (unlikely(XFS_TEST_ERROR(fa != NULL, mp, 109 - XFS_ERRTAG_BTREE_CHECK_LBLOCK))) { 108 + if (XFS_IS_CORRUPT(mp, fa != NULL) || 109 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) { 110 110 if (bp) 111 111 trace_xfs_btree_corrupt(bp, _RET_IP_); 112 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 113 112 return -EFSCORRUPTED; 114 113 } 115 114 return 0; ··· 168 169 xfs_failaddr_t fa; 169 170 170 171 fa = __xfs_btree_check_sblock(cur, block, level, bp); 171 - if (unlikely(XFS_TEST_ERROR(fa != NULL, mp, 172 - XFS_ERRTAG_BTREE_CHECK_SBLOCK))) { 172 + if (XFS_IS_CORRUPT(mp, fa != NULL) || 173 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) { 173 174 if (bp) 174 175 trace_xfs_btree_corrupt(bp, _RET_IP_); 175 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 176 176 return -EFSCORRUPTED; 177 177 } 178 178 return 0; ··· 382 384 /* 383 385 * Free the cursor. 384 386 */ 385 - kmem_zone_free(xfs_btree_cur_zone, cur); 387 + kmem_cache_free(xfs_btree_cur_zone, cur); 386 388 } 387 389 388 390 /* ··· 712 714 ASSERT(agbno != NULLAGBLOCK); 713 715 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 714 716 return xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, 0); 715 - } 716 - 717 - /* 718 - * Check for the cursor referring to the last block at the given level. 719 - */ 720 - int /* 1=is last block, 0=not last block */ 721 - xfs_btree_islastblock( 722 - xfs_btree_cur_t *cur, /* btree cursor */ 723 - int level) /* level to check */ 724 - { 725 - struct xfs_btree_block *block; /* generic btree block pointer */ 726 - xfs_buf_t *bp; /* buffer containing block */ 727 - 728 - block = xfs_btree_get_block(cur, level, &bp); 729 - xfs_btree_check_block(cur, block, level, bp); 730 - if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 731 - return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); 732 - else 733 - return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); 734 717 } 735 718 736 719 /* ··· 1799 1820 1800 1821 out_bad: 1801 1822 *blkp = NULL; 1823 + xfs_buf_corruption_error(bp); 1802 1824 xfs_trans_brelse(cur->bc_tp, bp); 1803 1825 return -EFSCORRUPTED; 1804 1826 } ··· 1847 1867 XFS_BTREE_STATS_INC(cur, lookup); 1848 1868 1849 1869 /* No such thing as a zero-level tree. */ 1850 - if (cur->bc_nlevels == 0) 1870 + if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0)) 1851 1871 return -EFSCORRUPTED; 1852 1872 1853 1873 block = NULL; ··· 1967 1987 error = xfs_btree_increment(cur, 0, &i); 1968 1988 if (error) 1969 1989 goto error0; 1970 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1990 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1991 + return -EFSCORRUPTED; 1971 1992 *stat = 1; 1972 1993 return 0; 1973 1994 } ··· 2423 2442 if (error) 2424 2443 goto error0; 2425 2444 i = xfs_btree_firstrec(tcur, level); 2426 - XFS_WANT_CORRUPTED_GOTO(tcur->bc_mp, i == 1, error0); 2445 + if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) { 2446 + error = -EFSCORRUPTED; 2447 + goto error0; 2448 + } 2427 2449 2428 2450 error = xfs_btree_decrement(tcur, level, &i); 2429 2451 if (error) ··· 2593 2609 if (error) 2594 2610 goto error0; 2595 2611 i = xfs_btree_lastrec(tcur, level); 2596 - XFS_WANT_CORRUPTED_GOTO(tcur->bc_mp, i == 1, error0); 2612 + if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) { 2613 + error = -EFSCORRUPTED; 2614 + goto error0; 2615 + } 2597 2616 2598 2617 error = xfs_btree_increment(tcur, level, &i); 2599 2618 if (error) ··· 3450 3463 goto error0; 3451 3464 } 3452 3465 3453 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3466 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3467 + error = -EFSCORRUPTED; 3468 + goto error0; 3469 + } 3454 3470 level++; 3455 3471 3456 3472 /* ··· 3857 3867 * Actually any entry but the first would suffice. 3858 3868 */ 3859 3869 i = xfs_btree_lastrec(tcur, level); 3860 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3870 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3871 + error = -EFSCORRUPTED; 3872 + goto error0; 3873 + } 3861 3874 3862 3875 error = xfs_btree_increment(tcur, level, &i); 3863 3876 if (error) 3864 3877 goto error0; 3865 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3878 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3879 + error = -EFSCORRUPTED; 3880 + goto error0; 3881 + } 3866 3882 3867 3883 i = xfs_btree_lastrec(tcur, level); 3868 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3884 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3885 + error = -EFSCORRUPTED; 3886 + goto error0; 3887 + } 3869 3888 3870 3889 /* Grab a pointer to the block. */ 3871 3890 right = xfs_btree_get_block(tcur, level, &rbp); ··· 3918 3919 rrecs = xfs_btree_get_numrecs(right); 3919 3920 if (!xfs_btree_ptr_is_null(cur, &lptr)) { 3920 3921 i = xfs_btree_firstrec(tcur, level); 3921 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3922 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3923 + error = -EFSCORRUPTED; 3924 + goto error0; 3925 + } 3922 3926 3923 3927 error = xfs_btree_decrement(tcur, level, &i); 3924 3928 if (error) 3925 3929 goto error0; 3926 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3930 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3931 + error = -EFSCORRUPTED; 3932 + goto error0; 3933 + } 3927 3934 } 3928 3935 } 3929 3936 ··· 3943 3938 * previous block. 3944 3939 */ 3945 3940 i = xfs_btree_firstrec(tcur, level); 3946 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3941 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3942 + error = -EFSCORRUPTED; 3943 + goto error0; 3944 + } 3947 3945 3948 3946 error = xfs_btree_decrement(tcur, level, &i); 3949 3947 if (error) 3950 3948 goto error0; 3951 3949 i = xfs_btree_firstrec(tcur, level); 3952 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); 3950 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 3951 + error = -EFSCORRUPTED; 3952 + goto error0; 3953 + } 3953 3954 3954 3955 /* Grab a pointer to the block. */ 3955 3956 left = xfs_btree_get_block(tcur, level, &lbp); ··· 4297 4286 xfs_btree_visit_blocks( 4298 4287 struct xfs_btree_cur *cur, 4299 4288 xfs_btree_visit_blocks_fn fn, 4289 + unsigned int flags, 4300 4290 void *data) 4301 4291 { 4302 4292 union xfs_btree_ptr lptr; ··· 4323 4311 4324 4312 /* save for the next iteration of the loop */ 4325 4313 xfs_btree_copy_ptrs(cur, &lptr, ptr, 1); 4314 + 4315 + if (!(flags & XFS_BTREE_VISIT_LEAVES)) 4316 + continue; 4317 + } else if (!(flags & XFS_BTREE_VISIT_RECORDS)) { 4318 + continue; 4326 4319 } 4327 4320 4328 4321 /* for each buffer in the level */ ··· 4430 4413 bbcoi.buffer_list = buffer_list; 4431 4414 4432 4415 return xfs_btree_visit_blocks(cur, xfs_btree_block_change_owner, 4433 - &bbcoi); 4416 + XFS_BTREE_VISIT_ALL, &bbcoi); 4434 4417 } 4435 4418 4436 4419 /* Verify the v5 fields of a long-format btree block. */ ··· 4882 4865 { 4883 4866 *blocks = 0; 4884 4867 return xfs_btree_visit_blocks(cur, xfs_btree_count_blocks_helper, 4885 - blocks); 4868 + XFS_BTREE_VISIT_ALL, blocks); 4886 4869 } 4887 4870 4888 4871 /* Compare two btree pointers. */
+28 -9
fs/xfs/libxfs/xfs_btree.h
··· 183 183 unsigned long nr_ops; /* # record updates */ 184 184 int shape_changes; /* # of extent splits */ 185 185 } refc; 186 + struct { 187 + bool active; /* allocation cursor state */ 188 + } abt; 186 189 }; 187 190 188 191 /* ··· 316 313 struct xfs_trans *tp, /* transaction pointer */ 317 314 xfs_agnumber_t agno, /* allocation group number */ 318 315 xfs_agblock_t agbno); /* allocation group block number */ 319 - 320 - /* 321 - * Check for the cursor referring to the last block at the given level. 322 - */ 323 - int /* 1=is last block, 0=not last block */ 324 - xfs_btree_islastblock( 325 - xfs_btree_cur_t *cur, /* btree cursor */ 326 - int level); /* level to check */ 327 316 328 317 /* 329 318 * Compute first and last byte offsets for the fields given. ··· 477 482 478 483 typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level, 479 484 void *data); 485 + /* Visit record blocks. */ 486 + #define XFS_BTREE_VISIT_RECORDS (1 << 0) 487 + /* Visit leaf blocks. */ 488 + #define XFS_BTREE_VISIT_LEAVES (1 << 1) 489 + /* Visit all blocks. */ 490 + #define XFS_BTREE_VISIT_ALL (XFS_BTREE_VISIT_RECORDS | \ 491 + XFS_BTREE_VISIT_LEAVES) 480 492 int xfs_btree_visit_blocks(struct xfs_btree_cur *cur, 481 - xfs_btree_visit_blocks_fn fn, void *data); 493 + xfs_btree_visit_blocks_fn fn, unsigned int flags, void *data); 482 494 483 495 int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_extlen_t *blocks); 484 496 ··· 515 513 int xfs_btree_has_record(struct xfs_btree_cur *cur, union xfs_btree_irec *low, 516 514 union xfs_btree_irec *high, bool *exists); 517 515 bool xfs_btree_has_more_records(struct xfs_btree_cur *cur); 516 + 517 + /* Does this cursor point to the last block in the given level? */ 518 + static inline bool 519 + xfs_btree_islastblock( 520 + xfs_btree_cur_t *cur, 521 + int level) 522 + { 523 + struct xfs_btree_block *block; 524 + struct xfs_buf *bp; 525 + 526 + block = xfs_btree_get_block(cur, level, &bp); 527 + ASSERT(block && xfs_btree_check_block(cur, block, level, bp) == 0); 528 + 529 + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 530 + return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); 531 + return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); 532 + } 518 533 519 534 #endif /* __XFS_BTREE_H__ */
+316 -354
fs/xfs/libxfs/xfs_da_btree.c
··· 12 12 #include "xfs_trans_resv.h" 13 13 #include "xfs_bit.h" 14 14 #include "xfs_mount.h" 15 + #include "xfs_inode.h" 15 16 #include "xfs_dir2.h" 16 17 #include "xfs_dir2_priv.h" 17 - #include "xfs_inode.h" 18 18 #include "xfs_trans.h" 19 19 #include "xfs_bmap.h" 20 20 #include "xfs_attr_leaf.h" ··· 107 107 #ifdef DEBUG 108 108 memset((char *)state, 0, sizeof(*state)); 109 109 #endif /* DEBUG */ 110 - kmem_zone_free(xfs_da_state_zone, state); 110 + kmem_cache_free(xfs_da_state_zone, state); 111 + } 112 + 113 + static inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork) 114 + { 115 + if (whichfork == XFS_DATA_FORK) 116 + return mp->m_dir_geo->fsbcount; 117 + return mp->m_attr_geo->fsbcount; 118 + } 119 + 120 + void 121 + xfs_da3_node_hdr_from_disk( 122 + struct xfs_mount *mp, 123 + struct xfs_da3_icnode_hdr *to, 124 + struct xfs_da_intnode *from) 125 + { 126 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 127 + struct xfs_da3_intnode *from3 = (struct xfs_da3_intnode *)from; 128 + 129 + to->forw = be32_to_cpu(from3->hdr.info.hdr.forw); 130 + to->back = be32_to_cpu(from3->hdr.info.hdr.back); 131 + to->magic = be16_to_cpu(from3->hdr.info.hdr.magic); 132 + to->count = be16_to_cpu(from3->hdr.__count); 133 + to->level = be16_to_cpu(from3->hdr.__level); 134 + to->btree = from3->__btree; 135 + ASSERT(to->magic == XFS_DA3_NODE_MAGIC); 136 + } else { 137 + to->forw = be32_to_cpu(from->hdr.info.forw); 138 + to->back = be32_to_cpu(from->hdr.info.back); 139 + to->magic = be16_to_cpu(from->hdr.info.magic); 140 + to->count = be16_to_cpu(from->hdr.__count); 141 + to->level = be16_to_cpu(from->hdr.__level); 142 + to->btree = from->__btree; 143 + ASSERT(to->magic == XFS_DA_NODE_MAGIC); 144 + } 145 + } 146 + 147 + void 148 + xfs_da3_node_hdr_to_disk( 149 + struct xfs_mount *mp, 150 + struct xfs_da_intnode *to, 151 + struct xfs_da3_icnode_hdr *from) 152 + { 153 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 154 + struct xfs_da3_intnode *to3 = (struct xfs_da3_intnode *)to; 155 + 156 + ASSERT(from->magic == XFS_DA3_NODE_MAGIC); 157 + to3->hdr.info.hdr.forw = cpu_to_be32(from->forw); 158 + to3->hdr.info.hdr.back = cpu_to_be32(from->back); 159 + to3->hdr.info.hdr.magic = cpu_to_be16(from->magic); 160 + to3->hdr.__count = cpu_to_be16(from->count); 161 + to3->hdr.__level = cpu_to_be16(from->level); 162 + } else { 163 + ASSERT(from->magic == XFS_DA_NODE_MAGIC); 164 + to->hdr.info.forw = cpu_to_be32(from->forw); 165 + to->hdr.info.back = cpu_to_be32(from->back); 166 + to->hdr.info.magic = cpu_to_be16(from->magic); 167 + to->hdr.__count = cpu_to_be16(from->count); 168 + to->hdr.__level = cpu_to_be16(from->level); 169 + } 111 170 } 112 171 113 172 /* ··· 204 145 struct xfs_mount *mp = bp->b_mount; 205 146 struct xfs_da_intnode *hdr = bp->b_addr; 206 147 struct xfs_da3_icnode_hdr ichdr; 207 - const struct xfs_dir_ops *ops; 208 148 xfs_failaddr_t fa; 209 149 210 - ops = xfs_dir_get_ops(mp, NULL); 211 - 212 - ops->node_hdr_from_disk(&ichdr, hdr); 150 + xfs_da3_node_hdr_from_disk(mp, &ichdr, hdr); 213 151 214 152 fa = xfs_da3_blkinfo_verify(bp, bp->b_addr); 215 153 if (fa) ··· 331 275 .verify_struct = xfs_da3_node_verify_struct, 332 276 }; 333 277 278 + static int 279 + xfs_da3_node_set_type( 280 + struct xfs_trans *tp, 281 + struct xfs_buf *bp) 282 + { 283 + struct xfs_da_blkinfo *info = bp->b_addr; 284 + 285 + switch (be16_to_cpu(info->magic)) { 286 + case XFS_DA_NODE_MAGIC: 287 + case XFS_DA3_NODE_MAGIC: 288 + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF); 289 + return 0; 290 + case XFS_ATTR_LEAF_MAGIC: 291 + case XFS_ATTR3_LEAF_MAGIC: 292 + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_ATTR_LEAF_BUF); 293 + return 0; 294 + case XFS_DIR2_LEAFN_MAGIC: 295 + case XFS_DIR3_LEAFN_MAGIC: 296 + xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF); 297 + return 0; 298 + default: 299 + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp, 300 + info, sizeof(*info)); 301 + xfs_trans_brelse(tp, bp); 302 + return -EFSCORRUPTED; 303 + } 304 + } 305 + 334 306 int 335 307 xfs_da3_node_read( 336 308 struct xfs_trans *tp, 337 309 struct xfs_inode *dp, 338 310 xfs_dablk_t bno, 311 + struct xfs_buf **bpp, 312 + int whichfork) 313 + { 314 + int error; 315 + 316 + error = xfs_da_read_buf(tp, dp, bno, 0, bpp, whichfork, 317 + &xfs_da3_node_buf_ops); 318 + if (error || !*bpp || !tp) 319 + return error; 320 + return xfs_da3_node_set_type(tp, *bpp); 321 + } 322 + 323 + int 324 + xfs_da3_node_read_mapped( 325 + struct xfs_trans *tp, 326 + struct xfs_inode *dp, 339 327 xfs_daddr_t mappedbno, 340 328 struct xfs_buf **bpp, 341 - int which_fork) 329 + int whichfork) 342 330 { 343 - int err; 331 + struct xfs_mount *mp = dp->i_mount; 332 + int error; 344 333 345 - err = xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, 346 - which_fork, &xfs_da3_node_buf_ops); 347 - if (!err && tp && *bpp) { 348 - struct xfs_da_blkinfo *info = (*bpp)->b_addr; 349 - int type; 334 + error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, mappedbno, 335 + XFS_FSB_TO_BB(mp, xfs_dabuf_nfsb(mp, whichfork)), 0, 336 + bpp, &xfs_da3_node_buf_ops); 337 + if (error || !*bpp) 338 + return error; 350 339 351 - switch (be16_to_cpu(info->magic)) { 352 - case XFS_DA_NODE_MAGIC: 353 - case XFS_DA3_NODE_MAGIC: 354 - type = XFS_BLFT_DA_NODE_BUF; 355 - break; 356 - case XFS_ATTR_LEAF_MAGIC: 357 - case XFS_ATTR3_LEAF_MAGIC: 358 - type = XFS_BLFT_ATTR_LEAF_BUF; 359 - break; 360 - case XFS_DIR2_LEAFN_MAGIC: 361 - case XFS_DIR3_LEAFN_MAGIC: 362 - type = XFS_BLFT_DIR_LEAFN_BUF; 363 - break; 364 - default: 365 - XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 366 - tp->t_mountp, info, sizeof(*info)); 367 - xfs_trans_brelse(tp, *bpp); 368 - *bpp = NULL; 369 - return -EFSCORRUPTED; 370 - } 371 - xfs_trans_buf_set_type(tp, *bpp, type); 372 - } 373 - return err; 340 + if (whichfork == XFS_ATTR_FORK) 341 + xfs_buf_set_ref(*bpp, XFS_ATTR_BTREE_REF); 342 + else 343 + xfs_buf_set_ref(*bpp, XFS_DIR_BTREE_REF); 344 + 345 + if (!tp) 346 + return 0; 347 + return xfs_da3_node_set_type(tp, *bpp); 374 348 } 375 349 376 350 /*======================================================================== ··· 429 343 trace_xfs_da_node_create(args); 430 344 ASSERT(level <= XFS_DA_NODE_MAXDEPTH); 431 345 432 - error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, whichfork); 346 + error = xfs_da_get_buf(tp, dp, blkno, &bp, whichfork); 433 347 if (error) 434 348 return error; 435 349 bp->b_ops = &xfs_da3_node_buf_ops; ··· 449 363 } 450 364 ichdr.level = level; 451 365 452 - dp->d_ops->node_hdr_to_disk(node, &ichdr); 366 + xfs_da3_node_hdr_to_disk(dp->i_mount, node, &ichdr); 453 367 xfs_trans_log_buf(tp, bp, 454 - XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size)); 368 + XFS_DA_LOGRANGE(node, &node->hdr, args->geo->node_hdr_size)); 455 369 456 370 *bpp = bp; 457 371 return 0; ··· 590 504 node = oldblk->bp->b_addr; 591 505 if (node->hdr.info.forw) { 592 506 if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) { 507 + xfs_buf_corruption_error(oldblk->bp); 593 508 error = -EFSCORRUPTED; 594 509 goto out; 595 510 } ··· 603 516 node = oldblk->bp->b_addr; 604 517 if (node->hdr.info.back) { 605 518 if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) { 519 + xfs_buf_corruption_error(oldblk->bp); 606 520 error = -EFSCORRUPTED; 607 521 goto out; 608 522 } ··· 656 568 657 569 dp = args->dp; 658 570 tp = args->trans; 659 - error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork); 571 + error = xfs_da_get_buf(tp, dp, blkno, &bp, args->whichfork); 660 572 if (error) 661 573 return error; 662 574 node = bp->b_addr; ··· 665 577 oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) { 666 578 struct xfs_da3_icnode_hdr icnodehdr; 667 579 668 - dp->d_ops->node_hdr_from_disk(&icnodehdr, oldroot); 669 - btree = dp->d_ops->node_tree_p(oldroot); 580 + xfs_da3_node_hdr_from_disk(dp->i_mount, &icnodehdr, oldroot); 581 + btree = icnodehdr.btree; 670 582 size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot); 671 583 level = icnodehdr.level; 672 584 ··· 677 589 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF); 678 590 } else { 679 591 struct xfs_dir3_icleaf_hdr leafhdr; 680 - struct xfs_dir2_leaf_entry *ents; 681 592 682 593 leaf = (xfs_dir2_leaf_t *)oldroot; 683 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 684 - ents = dp->d_ops->leaf_ents_p(leaf); 594 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 685 595 686 596 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || 687 597 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); 688 - size = (int)((char *)&ents[leafhdr.count] - (char *)leaf); 598 + size = (int)((char *)&leafhdr.ents[leafhdr.count] - 599 + (char *)leaf); 689 600 level = 0; 690 601 691 602 /* ··· 724 637 return error; 725 638 726 639 node = bp->b_addr; 727 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 728 - btree = dp->d_ops->node_tree_p(node); 640 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 641 + btree = nodehdr.btree; 729 642 btree[0].hashval = cpu_to_be32(blk1->hashval); 730 643 btree[0].before = cpu_to_be32(blk1->blkno); 731 644 btree[1].hashval = cpu_to_be32(blk2->hashval); 732 645 btree[1].before = cpu_to_be32(blk2->blkno); 733 646 nodehdr.count = 2; 734 - dp->d_ops->node_hdr_to_disk(node, &nodehdr); 647 + xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr); 735 648 736 649 #ifdef DEBUG 737 650 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || ··· 773 686 trace_xfs_da_node_split(state->args); 774 687 775 688 node = oldblk->bp->b_addr; 776 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 689 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 777 690 778 691 /* 779 692 * With V2 dirs the extra block is data or freespace. ··· 820 733 * If we had double-split op below us, then add the extra block too. 821 734 */ 822 735 node = oldblk->bp->b_addr; 823 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 736 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 824 737 if (oldblk->index <= nodehdr.count) { 825 738 oldblk->index++; 826 739 xfs_da3_node_add(state, oldblk, addblk); ··· 875 788 876 789 node1 = blk1->bp->b_addr; 877 790 node2 = blk2->bp->b_addr; 878 - dp->d_ops->node_hdr_from_disk(&nodehdr1, node1); 879 - dp->d_ops->node_hdr_from_disk(&nodehdr2, node2); 880 - btree1 = dp->d_ops->node_tree_p(node1); 881 - btree2 = dp->d_ops->node_tree_p(node2); 791 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1); 792 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2); 793 + btree1 = nodehdr1.btree; 794 + btree2 = nodehdr2.btree; 882 795 883 796 /* 884 797 * Figure out how many entries need to move, and in which direction. ··· 891 804 tmpnode = node1; 892 805 node1 = node2; 893 806 node2 = tmpnode; 894 - dp->d_ops->node_hdr_from_disk(&nodehdr1, node1); 895 - dp->d_ops->node_hdr_from_disk(&nodehdr2, node2); 896 - btree1 = dp->d_ops->node_tree_p(node1); 897 - btree2 = dp->d_ops->node_tree_p(node2); 807 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1); 808 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2); 809 + btree1 = nodehdr1.btree; 810 + btree2 = nodehdr2.btree; 898 811 swap = 1; 899 812 } 900 813 ··· 956 869 /* 957 870 * Log header of node 1 and all current bits of node 2. 958 871 */ 959 - dp->d_ops->node_hdr_to_disk(node1, &nodehdr1); 872 + xfs_da3_node_hdr_to_disk(dp->i_mount, node1, &nodehdr1); 960 873 xfs_trans_log_buf(tp, blk1->bp, 961 - XFS_DA_LOGRANGE(node1, &node1->hdr, dp->d_ops->node_hdr_size)); 874 + XFS_DA_LOGRANGE(node1, &node1->hdr, 875 + state->args->geo->node_hdr_size)); 962 876 963 - dp->d_ops->node_hdr_to_disk(node2, &nodehdr2); 877 + xfs_da3_node_hdr_to_disk(dp->i_mount, node2, &nodehdr2); 964 878 xfs_trans_log_buf(tp, blk2->bp, 965 879 XFS_DA_LOGRANGE(node2, &node2->hdr, 966 - dp->d_ops->node_hdr_size + 880 + state->args->geo->node_hdr_size + 967 881 (sizeof(btree2[0]) * nodehdr2.count))); 968 882 969 883 /* ··· 974 886 if (swap) { 975 887 node1 = blk1->bp->b_addr; 976 888 node2 = blk2->bp->b_addr; 977 - dp->d_ops->node_hdr_from_disk(&nodehdr1, node1); 978 - dp->d_ops->node_hdr_from_disk(&nodehdr2, node2); 979 - btree1 = dp->d_ops->node_tree_p(node1); 980 - btree2 = dp->d_ops->node_tree_p(node2); 889 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr1, node1); 890 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr2, node2); 891 + btree1 = nodehdr1.btree; 892 + btree2 = nodehdr2.btree; 981 893 } 982 894 blk1->hashval = be32_to_cpu(btree1[nodehdr1.count - 1].hashval); 983 895 blk2->hashval = be32_to_cpu(btree2[nodehdr2.count - 1].hashval); ··· 1009 921 trace_xfs_da_node_add(state->args); 1010 922 1011 923 node = oldblk->bp->b_addr; 1012 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1013 - btree = dp->d_ops->node_tree_p(node); 924 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 925 + btree = nodehdr.btree; 1014 926 1015 927 ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count); 1016 928 ASSERT(newblk->blkno != 0); ··· 1033 945 tmp + sizeof(*btree))); 1034 946 1035 947 nodehdr.count += 1; 1036 - dp->d_ops->node_hdr_to_disk(node, &nodehdr); 948 + xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr); 1037 949 xfs_trans_log_buf(state->args->trans, oldblk->bp, 1038 - XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size)); 950 + XFS_DA_LOGRANGE(node, &node->hdr, 951 + state->args->geo->node_hdr_size)); 1039 952 1040 953 /* 1041 954 * Copy the last hash value from the oldblk to propagate upwards. ··· 1171 1082 xfs_dablk_t child; 1172 1083 struct xfs_buf *bp; 1173 1084 struct xfs_da3_icnode_hdr oldroothdr; 1174 - struct xfs_da_node_entry *btree; 1175 1085 int error; 1176 1086 struct xfs_inode *dp = state->args->dp; 1177 1087 ··· 1180 1092 1181 1093 args = state->args; 1182 1094 oldroot = root_blk->bp->b_addr; 1183 - dp->d_ops->node_hdr_from_disk(&oldroothdr, oldroot); 1095 + xfs_da3_node_hdr_from_disk(dp->i_mount, &oldroothdr, oldroot); 1184 1096 ASSERT(oldroothdr.forw == 0); 1185 1097 ASSERT(oldroothdr.back == 0); 1186 1098 ··· 1194 1106 * Read in the (only) child block, then copy those bytes into 1195 1107 * the root block's buffer and free the original child block. 1196 1108 */ 1197 - btree = dp->d_ops->node_tree_p(oldroot); 1198 - child = be32_to_cpu(btree[0].before); 1109 + child = be32_to_cpu(oldroothdr.btree[0].before); 1199 1110 ASSERT(child != 0); 1200 - error = xfs_da3_node_read(args->trans, dp, child, -1, &bp, 1201 - args->whichfork); 1111 + error = xfs_da3_node_read(args->trans, dp, child, &bp, args->whichfork); 1202 1112 if (error) 1203 1113 return error; 1204 1114 xfs_da_blkinfo_onlychild_validate(bp->b_addr, oldroothdr.level); ··· 1258 1172 blk = &state->path.blk[ state->path.active-1 ]; 1259 1173 info = blk->bp->b_addr; 1260 1174 node = (xfs_da_intnode_t *)info; 1261 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1175 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 1262 1176 if (nodehdr.count > (state->args->geo->node_ents >> 1)) { 1263 1177 *action = 0; /* blk over 50%, don't try to join */ 1264 1178 return 0; /* blk over 50%, don't try to join */ ··· 1310 1224 blkno = nodehdr.back; 1311 1225 if (blkno == 0) 1312 1226 continue; 1313 - error = xfs_da3_node_read(state->args->trans, dp, 1314 - blkno, -1, &bp, state->args->whichfork); 1227 + error = xfs_da3_node_read(state->args->trans, dp, blkno, &bp, 1228 + state->args->whichfork); 1315 1229 if (error) 1316 1230 return error; 1317 1231 1318 1232 node = bp->b_addr; 1319 - dp->d_ops->node_hdr_from_disk(&thdr, node); 1233 + xfs_da3_node_hdr_from_disk(dp->i_mount, &thdr, node); 1320 1234 xfs_trans_brelse(state->args->trans, bp); 1321 1235 1322 1236 if (count - thdr.count >= 0) ··· 1358 1272 struct xfs_buf *bp, 1359 1273 int *count) 1360 1274 { 1361 - struct xfs_da_intnode *node; 1362 - struct xfs_da_node_entry *btree; 1363 1275 struct xfs_da3_icnode_hdr nodehdr; 1364 1276 1365 - node = bp->b_addr; 1366 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1277 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, bp->b_addr); 1367 1278 if (count) 1368 1279 *count = nodehdr.count; 1369 1280 if (!nodehdr.count) 1370 1281 return 0; 1371 - btree = dp->d_ops->node_tree_p(node); 1372 - return be32_to_cpu(btree[nodehdr.count - 1].hashval); 1282 + return be32_to_cpu(nodehdr.btree[nodehdr.count - 1].hashval); 1373 1283 } 1374 1284 1375 1285 /* ··· 1410 1328 struct xfs_da3_icnode_hdr nodehdr; 1411 1329 1412 1330 node = blk->bp->b_addr; 1413 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1414 - btree = dp->d_ops->node_tree_p(node); 1331 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 1332 + btree = nodehdr.btree; 1415 1333 if (be32_to_cpu(btree[blk->index].hashval) == lasthash) 1416 1334 break; 1417 1335 blk->hashval = lasthash; ··· 1442 1360 trace_xfs_da_node_remove(state->args); 1443 1361 1444 1362 node = drop_blk->bp->b_addr; 1445 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1363 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 1446 1364 ASSERT(drop_blk->index < nodehdr.count); 1447 1365 ASSERT(drop_blk->index >= 0); 1448 1366 ··· 1450 1368 * Copy over the offending entry, or just zero it out. 1451 1369 */ 1452 1370 index = drop_blk->index; 1453 - btree = dp->d_ops->node_tree_p(node); 1371 + btree = nodehdr.btree; 1454 1372 if (index < nodehdr.count - 1) { 1455 1373 tmp = nodehdr.count - index - 1; 1456 1374 tmp *= (uint)sizeof(xfs_da_node_entry_t); ··· 1463 1381 xfs_trans_log_buf(state->args->trans, drop_blk->bp, 1464 1382 XFS_DA_LOGRANGE(node, &btree[index], sizeof(btree[index]))); 1465 1383 nodehdr.count -= 1; 1466 - dp->d_ops->node_hdr_to_disk(node, &nodehdr); 1384 + xfs_da3_node_hdr_to_disk(dp->i_mount, node, &nodehdr); 1467 1385 xfs_trans_log_buf(state->args->trans, drop_blk->bp, 1468 - XFS_DA_LOGRANGE(node, &node->hdr, dp->d_ops->node_hdr_size)); 1386 + XFS_DA_LOGRANGE(node, &node->hdr, state->args->geo->node_hdr_size)); 1469 1387 1470 1388 /* 1471 1389 * Copy the last hash value from the block to propagate upwards. ··· 1498 1416 1499 1417 drop_node = drop_blk->bp->b_addr; 1500 1418 save_node = save_blk->bp->b_addr; 1501 - dp->d_ops->node_hdr_from_disk(&drop_hdr, drop_node); 1502 - dp->d_ops->node_hdr_from_disk(&save_hdr, save_node); 1503 - drop_btree = dp->d_ops->node_tree_p(drop_node); 1504 - save_btree = dp->d_ops->node_tree_p(save_node); 1419 + xfs_da3_node_hdr_from_disk(dp->i_mount, &drop_hdr, drop_node); 1420 + xfs_da3_node_hdr_from_disk(dp->i_mount, &save_hdr, save_node); 1421 + drop_btree = drop_hdr.btree; 1422 + save_btree = save_hdr.btree; 1505 1423 tp = state->args->trans; 1506 1424 1507 1425 /* ··· 1535 1453 memcpy(&save_btree[sindex], &drop_btree[0], tmp); 1536 1454 save_hdr.count += drop_hdr.count; 1537 1455 1538 - dp->d_ops->node_hdr_to_disk(save_node, &save_hdr); 1456 + xfs_da3_node_hdr_to_disk(dp->i_mount, save_node, &save_hdr); 1539 1457 xfs_trans_log_buf(tp, save_blk->bp, 1540 1458 XFS_DA_LOGRANGE(save_node, &save_node->hdr, 1541 - dp->d_ops->node_hdr_size)); 1459 + state->args->geo->node_hdr_size)); 1542 1460 1543 1461 /* 1544 1462 * Save the last hashval in the remaining block for upward propagation. ··· 1599 1517 */ 1600 1518 blk->blkno = blkno; 1601 1519 error = xfs_da3_node_read(args->trans, args->dp, blkno, 1602 - -1, &blk->bp, args->whichfork); 1520 + &blk->bp, args->whichfork); 1603 1521 if (error) { 1604 1522 blk->blkno = 0; 1605 1523 state->path.active--; ··· 1623 1541 break; 1624 1542 } 1625 1543 1626 - if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) 1544 + if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) { 1545 + xfs_buf_corruption_error(blk->bp); 1627 1546 return -EFSCORRUPTED; 1547 + } 1628 1548 1629 1549 blk->magic = XFS_DA_NODE_MAGIC; 1630 1550 ··· 1634 1550 * Search an intermediate node for a match. 1635 1551 */ 1636 1552 node = blk->bp->b_addr; 1637 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1638 - btree = dp->d_ops->node_tree_p(node); 1553 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, node); 1554 + btree = nodehdr.btree; 1639 1555 1640 1556 /* Tree taller than we can handle; bail out! */ 1641 - if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) 1557 + if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) { 1558 + xfs_buf_corruption_error(blk->bp); 1642 1559 return -EFSCORRUPTED; 1560 + } 1643 1561 1644 1562 /* Check the level from the root. */ 1645 1563 if (blkno == args->geo->leafblk) 1646 1564 expected_level = nodehdr.level - 1; 1647 - else if (expected_level != nodehdr.level) 1565 + else if (expected_level != nodehdr.level) { 1566 + xfs_buf_corruption_error(blk->bp); 1648 1567 return -EFSCORRUPTED; 1649 - else 1568 + } else 1650 1569 expected_level--; 1651 1570 1652 1571 max = nodehdr.count; ··· 1699 1612 } 1700 1613 1701 1614 /* We can't point back to the root. */ 1702 - if (blkno == args->geo->leafblk) 1615 + if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk)) 1703 1616 return -EFSCORRUPTED; 1704 1617 } 1705 1618 1706 - if (expected_level != 0) 1619 + if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0)) 1707 1620 return -EFSCORRUPTED; 1708 1621 1709 1622 /* ··· 1765 1678 1766 1679 node1 = node1_bp->b_addr; 1767 1680 node2 = node2_bp->b_addr; 1768 - dp->d_ops->node_hdr_from_disk(&node1hdr, node1); 1769 - dp->d_ops->node_hdr_from_disk(&node2hdr, node2); 1770 - btree1 = dp->d_ops->node_tree_p(node1); 1771 - btree2 = dp->d_ops->node_tree_p(node2); 1681 + xfs_da3_node_hdr_from_disk(dp->i_mount, &node1hdr, node1); 1682 + xfs_da3_node_hdr_from_disk(dp->i_mount, &node2hdr, node2); 1683 + btree1 = node1hdr.btree; 1684 + btree2 = node2hdr.btree; 1772 1685 1773 1686 if (node1hdr.count > 0 && node2hdr.count > 0 && 1774 1687 ((be32_to_cpu(btree2[0].hashval) < be32_to_cpu(btree1[0].hashval)) || ··· 1833 1746 if (old_info->back) { 1834 1747 error = xfs_da3_node_read(args->trans, dp, 1835 1748 be32_to_cpu(old_info->back), 1836 - -1, &bp, args->whichfork); 1749 + &bp, args->whichfork); 1837 1750 if (error) 1838 1751 return error; 1839 1752 ASSERT(bp != NULL); ··· 1854 1767 if (old_info->forw) { 1855 1768 error = xfs_da3_node_read(args->trans, dp, 1856 1769 be32_to_cpu(old_info->forw), 1857 - -1, &bp, args->whichfork); 1770 + &bp, args->whichfork); 1858 1771 if (error) 1859 1772 return error; 1860 1773 ASSERT(bp != NULL); ··· 1913 1826 if (drop_info->back) { 1914 1827 error = xfs_da3_node_read(args->trans, args->dp, 1915 1828 be32_to_cpu(drop_info->back), 1916 - -1, &bp, args->whichfork); 1829 + &bp, args->whichfork); 1917 1830 if (error) 1918 1831 return error; 1919 1832 ASSERT(bp != NULL); ··· 1930 1843 if (drop_info->forw) { 1931 1844 error = xfs_da3_node_read(args->trans, args->dp, 1932 1845 be32_to_cpu(drop_info->forw), 1933 - -1, &bp, args->whichfork); 1846 + &bp, args->whichfork); 1934 1847 if (error) 1935 1848 return error; 1936 1849 ASSERT(bp != NULL); ··· 1965 1878 { 1966 1879 struct xfs_da_state_blk *blk; 1967 1880 struct xfs_da_blkinfo *info; 1968 - struct xfs_da_intnode *node; 1969 1881 struct xfs_da_args *args; 1970 1882 struct xfs_da_node_entry *btree; 1971 1883 struct xfs_da3_icnode_hdr nodehdr; ··· 1987 1901 ASSERT((path->active > 0) && (path->active < XFS_DA_NODE_MAXDEPTH)); 1988 1902 level = (path->active-1) - 1; /* skip bottom layer in path */ 1989 1903 for (blk = &path->blk[level]; level >= 0; blk--, level--) { 1990 - node = blk->bp->b_addr; 1991 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1992 - btree = dp->d_ops->node_tree_p(node); 1904 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, 1905 + blk->bp->b_addr); 1993 1906 1994 1907 if (forward && (blk->index < nodehdr.count - 1)) { 1995 1908 blk->index++; 1996 - blkno = be32_to_cpu(btree[blk->index].before); 1909 + blkno = be32_to_cpu(nodehdr.btree[blk->index].before); 1997 1910 break; 1998 1911 } else if (!forward && (blk->index > 0)) { 1999 1912 blk->index--; 2000 - blkno = be32_to_cpu(btree[blk->index].before); 1913 + blkno = be32_to_cpu(nodehdr.btree[blk->index].before); 2001 1914 break; 2002 1915 } 2003 1916 } ··· 2014 1929 /* 2015 1930 * Read the next child block into a local buffer. 2016 1931 */ 2017 - error = xfs_da3_node_read(args->trans, dp, blkno, -1, &bp, 1932 + error = xfs_da3_node_read(args->trans, dp, blkno, &bp, 2018 1933 args->whichfork); 2019 1934 if (error) 2020 1935 return error; ··· 2047 1962 case XFS_DA_NODE_MAGIC: 2048 1963 case XFS_DA3_NODE_MAGIC: 2049 1964 blk->magic = XFS_DA_NODE_MAGIC; 2050 - node = (xfs_da_intnode_t *)info; 2051 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 2052 - btree = dp->d_ops->node_tree_p(node); 1965 + xfs_da3_node_hdr_from_disk(dp->i_mount, &nodehdr, 1966 + bp->b_addr); 1967 + btree = nodehdr.btree; 2053 1968 blk->hashval = be32_to_cpu(btree[nodehdr.count - 1].hashval); 2054 1969 if (forward) 2055 1970 blk->index = 0; ··· 2128 2043 return (args->namelen == len && memcmp(args->name, name, len) == 0) ? 2129 2044 XFS_CMP_EXACT : XFS_CMP_DIFFERENT; 2130 2045 } 2131 - 2132 - static xfs_dahash_t 2133 - xfs_default_hashname( 2134 - struct xfs_name *name) 2135 - { 2136 - return xfs_da_hashname(name->name, name->len); 2137 - } 2138 - 2139 - const struct xfs_nameops xfs_default_nameops = { 2140 - .hashname = xfs_default_hashname, 2141 - .compname = xfs_da_compname 2142 - }; 2143 2046 2144 2047 int 2145 2048 xfs_da_grow_inode_int( ··· 2286 2213 error = xfs_bmap_last_before(tp, dp, &lastoff, w); 2287 2214 if (error) 2288 2215 return error; 2289 - if (unlikely(lastoff == 0)) { 2290 - XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW, 2291 - mp); 2216 + if (XFS_IS_CORRUPT(mp, lastoff == 0)) 2292 2217 return -EFSCORRUPTED; 2293 - } 2294 2218 /* 2295 2219 * Read the last block in the btree space. 2296 2220 */ 2297 2221 last_blkno = (xfs_dablk_t)lastoff - args->geo->fsbcount; 2298 - error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w); 2222 + error = xfs_da3_node_read(tp, dp, last_blkno, &last_buf, w); 2299 2223 if (error) 2300 2224 return error; 2301 2225 /* ··· 2310 2240 struct xfs_dir2_leaf_entry *ents; 2311 2241 2312 2242 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 2313 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, dead_leaf2); 2314 - ents = dp->d_ops->leaf_ents_p(dead_leaf2); 2243 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, 2244 + dead_leaf2); 2245 + ents = leafhdr.ents; 2315 2246 dead_level = 0; 2316 2247 dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval); 2317 2248 } else { 2318 2249 struct xfs_da3_icnode_hdr deadhdr; 2319 2250 2320 2251 dead_node = (xfs_da_intnode_t *)dead_info; 2321 - dp->d_ops->node_hdr_from_disk(&deadhdr, dead_node); 2322 - btree = dp->d_ops->node_tree_p(dead_node); 2252 + xfs_da3_node_hdr_from_disk(dp->i_mount, &deadhdr, dead_node); 2253 + btree = deadhdr.btree; 2323 2254 dead_level = deadhdr.level; 2324 2255 dead_hash = be32_to_cpu(btree[deadhdr.count - 1].hashval); 2325 2256 } ··· 2329 2258 * If the moved block has a left sibling, fix up the pointers. 2330 2259 */ 2331 2260 if ((sib_blkno = be32_to_cpu(dead_info->back))) { 2332 - error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w); 2261 + error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w); 2333 2262 if (error) 2334 2263 goto done; 2335 2264 sib_info = sib_buf->b_addr; 2336 - if (unlikely( 2337 - be32_to_cpu(sib_info->forw) != last_blkno || 2338 - sib_info->magic != dead_info->magic)) { 2339 - XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)", 2340 - XFS_ERRLEVEL_LOW, mp); 2265 + if (XFS_IS_CORRUPT(mp, 2266 + be32_to_cpu(sib_info->forw) != last_blkno || 2267 + sib_info->magic != dead_info->magic)) { 2341 2268 error = -EFSCORRUPTED; 2342 2269 goto done; 2343 2270 } ··· 2349 2280 * If the moved block has a right sibling, fix up the pointers. 2350 2281 */ 2351 2282 if ((sib_blkno = be32_to_cpu(dead_info->forw))) { 2352 - error = xfs_da3_node_read(tp, dp, sib_blkno, -1, &sib_buf, w); 2283 + error = xfs_da3_node_read(tp, dp, sib_blkno, &sib_buf, w); 2353 2284 if (error) 2354 2285 goto done; 2355 2286 sib_info = sib_buf->b_addr; 2356 - if (unlikely( 2357 - be32_to_cpu(sib_info->back) != last_blkno || 2358 - sib_info->magic != dead_info->magic)) { 2359 - XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)", 2360 - XFS_ERRLEVEL_LOW, mp); 2287 + if (XFS_IS_CORRUPT(mp, 2288 + be32_to_cpu(sib_info->back) != last_blkno || 2289 + sib_info->magic != dead_info->magic)) { 2361 2290 error = -EFSCORRUPTED; 2362 2291 goto done; 2363 2292 } ··· 2371 2304 * Walk down the tree looking for the parent of the moved block. 2372 2305 */ 2373 2306 for (;;) { 2374 - error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w); 2307 + error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w); 2375 2308 if (error) 2376 2309 goto done; 2377 2310 par_node = par_buf->b_addr; 2378 - dp->d_ops->node_hdr_from_disk(&par_hdr, par_node); 2379 - if (level >= 0 && level != par_hdr.level + 1) { 2380 - XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", 2381 - XFS_ERRLEVEL_LOW, mp); 2311 + xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node); 2312 + if (XFS_IS_CORRUPT(mp, 2313 + level >= 0 && level != par_hdr.level + 1)) { 2382 2314 error = -EFSCORRUPTED; 2383 2315 goto done; 2384 2316 } 2385 2317 level = par_hdr.level; 2386 - btree = dp->d_ops->node_tree_p(par_node); 2318 + btree = par_hdr.btree; 2387 2319 for (entno = 0; 2388 2320 entno < par_hdr.count && 2389 2321 be32_to_cpu(btree[entno].hashval) < dead_hash; 2390 2322 entno++) 2391 2323 continue; 2392 - if (entno == par_hdr.count) { 2393 - XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)", 2394 - XFS_ERRLEVEL_LOW, mp); 2324 + if (XFS_IS_CORRUPT(mp, entno == par_hdr.count)) { 2395 2325 error = -EFSCORRUPTED; 2396 2326 goto done; 2397 2327 } ··· 2413 2349 par_blkno = par_hdr.forw; 2414 2350 xfs_trans_brelse(tp, par_buf); 2415 2351 par_buf = NULL; 2416 - if (unlikely(par_blkno == 0)) { 2417 - XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)", 2418 - XFS_ERRLEVEL_LOW, mp); 2352 + if (XFS_IS_CORRUPT(mp, par_blkno == 0)) { 2419 2353 error = -EFSCORRUPTED; 2420 2354 goto done; 2421 2355 } 2422 - error = xfs_da3_node_read(tp, dp, par_blkno, -1, &par_buf, w); 2356 + error = xfs_da3_node_read(tp, dp, par_blkno, &par_buf, w); 2423 2357 if (error) 2424 2358 goto done; 2425 2359 par_node = par_buf->b_addr; 2426 - dp->d_ops->node_hdr_from_disk(&par_hdr, par_node); 2427 - if (par_hdr.level != level) { 2428 - XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", 2429 - XFS_ERRLEVEL_LOW, mp); 2360 + xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node); 2361 + if (XFS_IS_CORRUPT(mp, par_hdr.level != level)) { 2430 2362 error = -EFSCORRUPTED; 2431 2363 goto done; 2432 2364 } 2433 - btree = dp->d_ops->node_tree_p(par_node); 2365 + btree = par_hdr.btree; 2434 2366 entno = 0; 2435 2367 } 2436 2368 /* ··· 2489 2429 return error; 2490 2430 } 2491 2431 2492 - /* 2493 - * See if the mapping(s) for this btree block are valid, i.e. 2494 - * don't contain holes, are logically contiguous, and cover the whole range. 2495 - */ 2496 - STATIC int 2497 - xfs_da_map_covers_blocks( 2498 - int nmap, 2499 - xfs_bmbt_irec_t *mapp, 2500 - xfs_dablk_t bno, 2501 - int count) 2502 - { 2503 - int i; 2504 - xfs_fileoff_t off; 2505 - 2506 - for (i = 0, off = bno; i < nmap; i++) { 2507 - if (mapp[i].br_startblock == HOLESTARTBLOCK || 2508 - mapp[i].br_startblock == DELAYSTARTBLOCK) { 2509 - return 0; 2510 - } 2511 - if (off != mapp[i].br_startoff) { 2512 - return 0; 2513 - } 2514 - off += mapp[i].br_blockcount; 2515 - } 2516 - return off == bno + count; 2517 - } 2518 - 2519 - /* 2520 - * Convert a struct xfs_bmbt_irec to a struct xfs_buf_map. 2521 - * 2522 - * For the single map case, it is assumed that the caller has provided a pointer 2523 - * to a valid xfs_buf_map. For the multiple map case, this function will 2524 - * allocate the xfs_buf_map to hold all the maps and replace the caller's single 2525 - * map pointer with the allocated map. 2526 - */ 2527 - static int 2528 - xfs_buf_map_from_irec( 2529 - struct xfs_mount *mp, 2530 - struct xfs_buf_map **mapp, 2531 - int *nmaps, 2532 - struct xfs_bmbt_irec *irecs, 2533 - int nirecs) 2534 - { 2535 - struct xfs_buf_map *map; 2536 - int i; 2537 - 2538 - ASSERT(*nmaps == 1); 2539 - ASSERT(nirecs >= 1); 2540 - 2541 - if (nirecs > 1) { 2542 - map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), 2543 - KM_NOFS); 2544 - if (!map) 2545 - return -ENOMEM; 2546 - *mapp = map; 2547 - } 2548 - 2549 - *nmaps = nirecs; 2550 - map = *mapp; 2551 - for (i = 0; i < *nmaps; i++) { 2552 - ASSERT(irecs[i].br_startblock != DELAYSTARTBLOCK && 2553 - irecs[i].br_startblock != HOLESTARTBLOCK); 2554 - map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock); 2555 - map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount); 2556 - } 2557 - return 0; 2558 - } 2559 - 2560 - /* 2561 - * Map the block we are given ready for reading. There are three possible return 2562 - * values: 2563 - * -1 - will be returned if we land in a hole and mappedbno == -2 so the 2564 - * caller knows not to execute a subsequent read. 2565 - * 0 - if we mapped the block successfully 2566 - * >0 - positive error number if there was an error. 2567 - */ 2568 2432 static int 2569 2433 xfs_dabuf_map( 2570 2434 struct xfs_inode *dp, 2571 2435 xfs_dablk_t bno, 2572 - xfs_daddr_t mappedbno, 2436 + unsigned int flags, 2573 2437 int whichfork, 2574 - struct xfs_buf_map **map, 2438 + struct xfs_buf_map **mapp, 2575 2439 int *nmaps) 2576 2440 { 2577 2441 struct xfs_mount *mp = dp->i_mount; 2578 - int nfsb; 2579 - int error = 0; 2580 - struct xfs_bmbt_irec irec; 2581 - struct xfs_bmbt_irec *irecs = &irec; 2582 - int nirecs; 2442 + int nfsb = xfs_dabuf_nfsb(mp, whichfork); 2443 + struct xfs_bmbt_irec irec, *irecs = &irec; 2444 + struct xfs_buf_map *map = *mapp; 2445 + xfs_fileoff_t off = bno; 2446 + int error = 0, nirecs, i; 2583 2447 2584 - ASSERT(map && *map); 2585 - ASSERT(*nmaps == 1); 2448 + if (nfsb > 1) 2449 + irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_NOFS); 2586 2450 2587 - if (whichfork == XFS_DATA_FORK) 2588 - nfsb = mp->m_dir_geo->fsbcount; 2589 - else 2590 - nfsb = mp->m_attr_geo->fsbcount; 2451 + nirecs = nfsb; 2452 + error = xfs_bmapi_read(dp, bno, nfsb, irecs, &nirecs, 2453 + xfs_bmapi_aflag(whichfork)); 2454 + if (error) 2455 + goto out_free_irecs; 2591 2456 2592 2457 /* 2593 - * Caller doesn't have a mapping. -2 means don't complain 2594 - * if we land in a hole. 2458 + * Use the caller provided map for the single map case, else allocate a 2459 + * larger one that needs to be free by the caller. 2595 2460 */ 2596 - if (mappedbno == -1 || mappedbno == -2) { 2597 - /* 2598 - * Optimize the one-block case. 2599 - */ 2600 - if (nfsb != 1) 2601 - irecs = kmem_zalloc(sizeof(irec) * nfsb, 2602 - KM_NOFS); 2603 - 2604 - nirecs = nfsb; 2605 - error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, 2606 - &nirecs, xfs_bmapi_aflag(whichfork)); 2607 - if (error) 2608 - goto out; 2609 - } else { 2610 - irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno); 2611 - irecs->br_startoff = (xfs_fileoff_t)bno; 2612 - irecs->br_blockcount = nfsb; 2613 - irecs->br_state = 0; 2614 - nirecs = 1; 2461 + if (nirecs > 1) { 2462 + map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_NOFS); 2463 + if (!map) 2464 + goto out_free_irecs; 2465 + *mapp = map; 2615 2466 } 2616 2467 2617 - if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) { 2618 - error = mappedbno == -2 ? -1 : -EFSCORRUPTED; 2619 - if (unlikely(error == -EFSCORRUPTED)) { 2620 - if (xfs_error_level >= XFS_ERRLEVEL_LOW) { 2621 - int i; 2622 - xfs_alert(mp, "%s: bno %lld dir: inode %lld", 2623 - __func__, (long long)bno, 2624 - (long long)dp->i_ino); 2625 - for (i = 0; i < *nmaps; i++) { 2626 - xfs_alert(mp, 2627 - "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d", 2628 - i, 2629 - (long long)irecs[i].br_startoff, 2630 - (long long)irecs[i].br_startblock, 2631 - (long long)irecs[i].br_blockcount, 2632 - irecs[i].br_state); 2633 - } 2634 - } 2635 - XFS_ERROR_REPORT("xfs_da_do_buf(1)", 2636 - XFS_ERRLEVEL_LOW, mp); 2637 - } 2638 - goto out; 2468 + for (i = 0; i < nirecs; i++) { 2469 + if (irecs[i].br_startblock == HOLESTARTBLOCK || 2470 + irecs[i].br_startblock == DELAYSTARTBLOCK) 2471 + goto invalid_mapping; 2472 + if (off != irecs[i].br_startoff) 2473 + goto invalid_mapping; 2474 + 2475 + map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock); 2476 + map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount); 2477 + off += irecs[i].br_blockcount; 2639 2478 } 2640 - error = xfs_buf_map_from_irec(mp, map, nmaps, irecs, nirecs); 2641 - out: 2479 + 2480 + if (off != bno + nfsb) 2481 + goto invalid_mapping; 2482 + 2483 + *nmaps = nirecs; 2484 + out_free_irecs: 2642 2485 if (irecs != &irec) 2643 2486 kmem_free(irecs); 2644 2487 return error; 2488 + 2489 + invalid_mapping: 2490 + /* Caller ok with no mapping. */ 2491 + if (XFS_IS_CORRUPT(mp, !(flags & XFS_DABUF_MAP_HOLE_OK))) { 2492 + error = -EFSCORRUPTED; 2493 + if (xfs_error_level >= XFS_ERRLEVEL_LOW) { 2494 + xfs_alert(mp, "%s: bno %u inode %llu", 2495 + __func__, bno, dp->i_ino); 2496 + 2497 + for (i = 0; i < nirecs; i++) { 2498 + xfs_alert(mp, 2499 + "[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d", 2500 + i, irecs[i].br_startoff, 2501 + irecs[i].br_startblock, 2502 + irecs[i].br_blockcount, 2503 + irecs[i].br_state); 2504 + } 2505 + } 2506 + } else { 2507 + *nmaps = 0; 2508 + } 2509 + goto out_free_irecs; 2645 2510 } 2646 2511 2647 2512 /* ··· 2574 2589 */ 2575 2590 int 2576 2591 xfs_da_get_buf( 2577 - struct xfs_trans *trans, 2592 + struct xfs_trans *tp, 2578 2593 struct xfs_inode *dp, 2579 2594 xfs_dablk_t bno, 2580 - xfs_daddr_t mappedbno, 2581 2595 struct xfs_buf **bpp, 2582 2596 int whichfork) 2583 2597 { 2598 + struct xfs_mount *mp = dp->i_mount; 2584 2599 struct xfs_buf *bp; 2585 - struct xfs_buf_map map; 2586 - struct xfs_buf_map *mapp; 2587 - int nmap; 2600 + struct xfs_buf_map map, *mapp = &map; 2601 + int nmap = 1; 2588 2602 int error; 2589 2603 2590 2604 *bpp = NULL; 2591 - mapp = &map; 2592 - nmap = 1; 2593 - error = xfs_dabuf_map(dp, bno, mappedbno, whichfork, 2594 - &mapp, &nmap); 2595 - if (error) { 2596 - /* mapping a hole is not an error, but we don't continue */ 2597 - if (error == -1) 2598 - error = 0; 2605 + error = xfs_dabuf_map(dp, bno, 0, whichfork, &mapp, &nmap); 2606 + if (error || nmap == 0) 2599 2607 goto out_free; 2600 - } 2601 2608 2602 - bp = xfs_trans_get_buf_map(trans, dp->i_mount->m_ddev_targp, 2603 - mapp, nmap, 0); 2609 + bp = xfs_trans_get_buf_map(tp, mp->m_ddev_targp, mapp, nmap, 0); 2604 2610 error = bp ? bp->b_error : -EIO; 2605 2611 if (error) { 2606 2612 if (bp) 2607 - xfs_trans_brelse(trans, bp); 2613 + xfs_trans_brelse(tp, bp); 2608 2614 goto out_free; 2609 2615 } 2610 2616 ··· 2613 2637 */ 2614 2638 int 2615 2639 xfs_da_read_buf( 2616 - struct xfs_trans *trans, 2640 + struct xfs_trans *tp, 2617 2641 struct xfs_inode *dp, 2618 2642 xfs_dablk_t bno, 2619 - xfs_daddr_t mappedbno, 2643 + unsigned int flags, 2620 2644 struct xfs_buf **bpp, 2621 2645 int whichfork, 2622 2646 const struct xfs_buf_ops *ops) 2623 2647 { 2648 + struct xfs_mount *mp = dp->i_mount; 2624 2649 struct xfs_buf *bp; 2625 - struct xfs_buf_map map; 2626 - struct xfs_buf_map *mapp; 2627 - int nmap; 2650 + struct xfs_buf_map map, *mapp = &map; 2651 + int nmap = 1; 2628 2652 int error; 2629 2653 2630 2654 *bpp = NULL; 2631 - mapp = &map; 2632 - nmap = 1; 2633 - error = xfs_dabuf_map(dp, bno, mappedbno, whichfork, 2634 - &mapp, &nmap); 2635 - if (error) { 2636 - /* mapping a hole is not an error, but we don't continue */ 2637 - if (error == -1) 2638 - error = 0; 2655 + error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap); 2656 + if (error || !nmap) 2639 2657 goto out_free; 2640 - } 2641 2658 2642 - error = xfs_trans_read_buf_map(dp->i_mount, trans, 2643 - dp->i_mount->m_ddev_targp, 2644 - mapp, nmap, 0, &bp, ops); 2659 + error = xfs_trans_read_buf_map(mp, tp, mp->m_ddev_targp, mapp, nmap, 0, 2660 + &bp, ops); 2645 2661 if (error) 2646 2662 goto out_free; 2647 2663 ··· 2656 2688 xfs_da_reada_buf( 2657 2689 struct xfs_inode *dp, 2658 2690 xfs_dablk_t bno, 2659 - xfs_daddr_t mappedbno, 2691 + unsigned int flags, 2660 2692 int whichfork, 2661 2693 const struct xfs_buf_ops *ops) 2662 2694 { ··· 2667 2699 2668 2700 mapp = &map; 2669 2701 nmap = 1; 2670 - error = xfs_dabuf_map(dp, bno, mappedbno, whichfork, 2671 - &mapp, &nmap); 2672 - if (error) { 2673 - /* mapping a hole is not an error, but we don't continue */ 2674 - if (error == -1) 2675 - error = 0; 2702 + error = xfs_dabuf_map(dp, bno, flags, whichfork, &mapp, &nmap); 2703 + if (error || !nmap) 2676 2704 goto out_free; 2677 - } 2678 2705 2679 - mappedbno = mapp[0].bm_bn; 2680 2706 xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, ops); 2681 2707 2682 2708 out_free:
+48 -25
fs/xfs/libxfs/xfs_da_btree.h
··· 10 10 struct xfs_inode; 11 11 struct xfs_trans; 12 12 struct zone; 13 - struct xfs_dir_ops; 14 13 15 14 /* 16 15 * Directory/attribute geometry information. There will be one of these for each ··· 17 18 * structures will be attached to the xfs_mount. 18 19 */ 19 20 struct xfs_da_geometry { 20 - int blksize; /* da block size in bytes */ 21 - int fsbcount; /* da block size in filesystem blocks */ 21 + unsigned int blksize; /* da block size in bytes */ 22 + unsigned int fsbcount; /* da block size in filesystem blocks */ 22 23 uint8_t fsblog; /* log2 of _filesystem_ block size */ 23 24 uint8_t blklog; /* log2 of da block size */ 24 - uint node_ents; /* # of entries in a danode */ 25 - int magicpct; /* 37% of block size in bytes */ 25 + unsigned int node_hdr_size; /* danode header size in bytes */ 26 + unsigned int node_ents; /* # of entries in a danode */ 27 + unsigned int magicpct; /* 37% of block size in bytes */ 26 28 xfs_dablk_t datablk; /* blockno of dir data v2 */ 29 + unsigned int leaf_hdr_size; /* dir2 leaf header size */ 30 + unsigned int leaf_max_ents; /* # of entries in dir2 leaf */ 27 31 xfs_dablk_t leafblk; /* blockno of leaf data v2 */ 32 + unsigned int free_hdr_size; /* dir2 free header size */ 33 + unsigned int free_max_bests; /* # of bests entries in dir2 free */ 28 34 xfs_dablk_t freeblk; /* blockno of free data v2 */ 35 + 36 + xfs_dir2_data_aoff_t data_first_offset; 37 + size_t data_entry_offset; 29 38 }; 30 39 31 40 /*======================================================================== ··· 132 125 } xfs_da_state_t; 133 126 134 127 /* 128 + * In-core version of the node header to abstract the differences in the v2 and 129 + * v3 disk format of the headers. Callers need to convert to/from disk format as 130 + * appropriate. 131 + */ 132 + struct xfs_da3_icnode_hdr { 133 + uint32_t forw; 134 + uint32_t back; 135 + uint16_t magic; 136 + uint16_t count; 137 + uint16_t level; 138 + 139 + /* 140 + * Pointer to the on-disk format entries, which are behind the 141 + * variable size (v4 vs v5) header in the on-disk block. 142 + */ 143 + struct xfs_da_node_entry *btree; 144 + }; 145 + 146 + /* 135 147 * Utility macros to aid in logging changed structure fields. 136 148 */ 137 149 #define XFS_DA_LOGOFF(BASE, ADDR) ((char *)(ADDR) - (char *)(BASE)) 138 150 #define XFS_DA_LOGRANGE(BASE, ADDR, SIZE) \ 139 151 (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \ 140 152 (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1) 141 - 142 - /* 143 - * Name ops for directory and/or attr name operations 144 - */ 145 - struct xfs_nameops { 146 - xfs_dahash_t (*hashname)(struct xfs_name *); 147 - enum xfs_dacmp (*compname)(struct xfs_da_args *, 148 - const unsigned char *, int); 149 - }; 150 - 151 153 152 154 /*======================================================================== 153 155 * Function prototypes. ··· 188 172 int xfs_da3_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, 189 173 xfs_da_state_blk_t *new_blk); 190 174 int xfs_da3_node_read(struct xfs_trans *tp, struct xfs_inode *dp, 191 - xfs_dablk_t bno, xfs_daddr_t mappedbno, 192 - struct xfs_buf **bpp, int which_fork); 175 + xfs_dablk_t bno, struct xfs_buf **bpp, int whichfork); 176 + int xfs_da3_node_read_mapped(struct xfs_trans *tp, struct xfs_inode *dp, 177 + xfs_daddr_t mappedbno, struct xfs_buf **bpp, 178 + int whichfork); 193 179 194 180 /* 195 181 * Utility routines. 196 182 */ 183 + 184 + #define XFS_DABUF_MAP_HOLE_OK (1 << 0) 185 + 197 186 int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); 198 187 int xfs_da_grow_inode_int(struct xfs_da_args *args, xfs_fileoff_t *bno, 199 188 int count); 200 189 int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, 201 - xfs_dablk_t bno, xfs_daddr_t mappedbno, 202 - struct xfs_buf **bp, int whichfork); 190 + xfs_dablk_t bno, struct xfs_buf **bp, int whichfork); 203 191 int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, 204 - xfs_dablk_t bno, xfs_daddr_t mappedbno, 205 - struct xfs_buf **bpp, int whichfork, 206 - const struct xfs_buf_ops *ops); 192 + xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp, 193 + int whichfork, const struct xfs_buf_ops *ops); 207 194 int xfs_da_reada_buf(struct xfs_inode *dp, xfs_dablk_t bno, 208 - xfs_daddr_t mapped_bno, int whichfork, 209 - const struct xfs_buf_ops *ops); 195 + unsigned int flags, int whichfork, 196 + const struct xfs_buf_ops *ops); 210 197 int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, 211 198 struct xfs_buf *dead_buf); 212 199 ··· 221 202 xfs_da_state_t *xfs_da_state_alloc(void); 222 203 void xfs_da_state_free(xfs_da_state_t *state); 223 204 205 + void xfs_da3_node_hdr_from_disk(struct xfs_mount *mp, 206 + struct xfs_da3_icnode_hdr *to, struct xfs_da_intnode *from); 207 + void xfs_da3_node_hdr_to_disk(struct xfs_mount *mp, 208 + struct xfs_da_intnode *to, struct xfs_da3_icnode_hdr *from); 209 + 224 210 extern struct kmem_zone *xfs_da_state_zone; 225 - extern const struct xfs_nameops xfs_default_nameops; 226 211 227 212 #endif /* __XFS_DA_BTREE_H__ */
-888
fs/xfs/libxfs/xfs_da_format.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. 4 - * Copyright (c) 2013 Red Hat, Inc. 5 - * All Rights Reserved. 6 - */ 7 - #include "xfs.h" 8 - #include "xfs_fs.h" 9 - #include "xfs_shared.h" 10 - #include "xfs_format.h" 11 - #include "xfs_log_format.h" 12 - #include "xfs_trans_resv.h" 13 - #include "xfs_mount.h" 14 - #include "xfs_inode.h" 15 - #include "xfs_dir2.h" 16 - 17 - /* 18 - * Shortform directory ops 19 - */ 20 - static int 21 - xfs_dir2_sf_entsize( 22 - struct xfs_dir2_sf_hdr *hdr, 23 - int len) 24 - { 25 - int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ 26 - 27 - count += len; /* name */ 28 - count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */ 29 - return count; 30 - } 31 - 32 - static int 33 - xfs_dir3_sf_entsize( 34 - struct xfs_dir2_sf_hdr *hdr, 35 - int len) 36 - { 37 - return xfs_dir2_sf_entsize(hdr, len) + sizeof(uint8_t); 38 - } 39 - 40 - static struct xfs_dir2_sf_entry * 41 - xfs_dir2_sf_nextentry( 42 - struct xfs_dir2_sf_hdr *hdr, 43 - struct xfs_dir2_sf_entry *sfep) 44 - { 45 - return (struct xfs_dir2_sf_entry *) 46 - ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen)); 47 - } 48 - 49 - static struct xfs_dir2_sf_entry * 50 - xfs_dir3_sf_nextentry( 51 - struct xfs_dir2_sf_hdr *hdr, 52 - struct xfs_dir2_sf_entry *sfep) 53 - { 54 - return (struct xfs_dir2_sf_entry *) 55 - ((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen)); 56 - } 57 - 58 - 59 - /* 60 - * For filetype enabled shortform directories, the file type field is stored at 61 - * the end of the name. Because it's only a single byte, endian conversion is 62 - * not necessary. For non-filetype enable directories, the type is always 63 - * unknown and we never store the value. 64 - */ 65 - static uint8_t 66 - xfs_dir2_sfe_get_ftype( 67 - struct xfs_dir2_sf_entry *sfep) 68 - { 69 - return XFS_DIR3_FT_UNKNOWN; 70 - } 71 - 72 - static void 73 - xfs_dir2_sfe_put_ftype( 74 - struct xfs_dir2_sf_entry *sfep, 75 - uint8_t ftype) 76 - { 77 - ASSERT(ftype < XFS_DIR3_FT_MAX); 78 - } 79 - 80 - static uint8_t 81 - xfs_dir3_sfe_get_ftype( 82 - struct xfs_dir2_sf_entry *sfep) 83 - { 84 - uint8_t ftype; 85 - 86 - ftype = sfep->name[sfep->namelen]; 87 - if (ftype >= XFS_DIR3_FT_MAX) 88 - return XFS_DIR3_FT_UNKNOWN; 89 - return ftype; 90 - } 91 - 92 - static void 93 - xfs_dir3_sfe_put_ftype( 94 - struct xfs_dir2_sf_entry *sfep, 95 - uint8_t ftype) 96 - { 97 - ASSERT(ftype < XFS_DIR3_FT_MAX); 98 - 99 - sfep->name[sfep->namelen] = ftype; 100 - } 101 - 102 - /* 103 - * Inode numbers in short-form directories can come in two versions, 104 - * either 4 bytes or 8 bytes wide. These helpers deal with the 105 - * two forms transparently by looking at the headers i8count field. 106 - * 107 - * For 64-bit inode number the most significant byte must be zero. 108 - */ 109 - static xfs_ino_t 110 - xfs_dir2_sf_get_ino( 111 - struct xfs_dir2_sf_hdr *hdr, 112 - uint8_t *from) 113 - { 114 - if (hdr->i8count) 115 - return get_unaligned_be64(from) & 0x00ffffffffffffffULL; 116 - else 117 - return get_unaligned_be32(from); 118 - } 119 - 120 - static void 121 - xfs_dir2_sf_put_ino( 122 - struct xfs_dir2_sf_hdr *hdr, 123 - uint8_t *to, 124 - xfs_ino_t ino) 125 - { 126 - ASSERT((ino & 0xff00000000000000ULL) == 0); 127 - 128 - if (hdr->i8count) 129 - put_unaligned_be64(ino, to); 130 - else 131 - put_unaligned_be32(ino, to); 132 - } 133 - 134 - static xfs_ino_t 135 - xfs_dir2_sf_get_parent_ino( 136 - struct xfs_dir2_sf_hdr *hdr) 137 - { 138 - return xfs_dir2_sf_get_ino(hdr, hdr->parent); 139 - } 140 - 141 - static void 142 - xfs_dir2_sf_put_parent_ino( 143 - struct xfs_dir2_sf_hdr *hdr, 144 - xfs_ino_t ino) 145 - { 146 - xfs_dir2_sf_put_ino(hdr, hdr->parent, ino); 147 - } 148 - 149 - /* 150 - * In short-form directory entries the inode numbers are stored at variable 151 - * offset behind the entry name. If the entry stores a filetype value, then it 152 - * sits between the name and the inode number. Hence the inode numbers may only 153 - * be accessed through the helpers below. 154 - */ 155 - static xfs_ino_t 156 - xfs_dir2_sfe_get_ino( 157 - struct xfs_dir2_sf_hdr *hdr, 158 - struct xfs_dir2_sf_entry *sfep) 159 - { 160 - return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen]); 161 - } 162 - 163 - static void 164 - xfs_dir2_sfe_put_ino( 165 - struct xfs_dir2_sf_hdr *hdr, 166 - struct xfs_dir2_sf_entry *sfep, 167 - xfs_ino_t ino) 168 - { 169 - xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen], ino); 170 - } 171 - 172 - static xfs_ino_t 173 - xfs_dir3_sfe_get_ino( 174 - struct xfs_dir2_sf_hdr *hdr, 175 - struct xfs_dir2_sf_entry *sfep) 176 - { 177 - return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen + 1]); 178 - } 179 - 180 - static void 181 - xfs_dir3_sfe_put_ino( 182 - struct xfs_dir2_sf_hdr *hdr, 183 - struct xfs_dir2_sf_entry *sfep, 184 - xfs_ino_t ino) 185 - { 186 - xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen + 1], ino); 187 - } 188 - 189 - 190 - /* 191 - * Directory data block operations 192 - */ 193 - 194 - /* 195 - * For special situations, the dirent size ends up fixed because we always know 196 - * what the size of the entry is. That's true for the "." and "..", and 197 - * therefore we know that they are a fixed size and hence their offsets are 198 - * constant, as is the first entry. 199 - * 200 - * Hence, this calculation is written as a macro to be able to be calculated at 201 - * compile time and so certain offsets can be calculated directly in the 202 - * structure initaliser via the macro. There are two macros - one for dirents 203 - * with ftype and without so there are no unresolvable conditionals in the 204 - * calculations. We also use round_up() as XFS_DIR2_DATA_ALIGN is always a power 205 - * of 2 and the compiler doesn't reject it (unlike roundup()). 206 - */ 207 - #define XFS_DIR2_DATA_ENTSIZE(n) \ 208 - round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \ 209 - sizeof(xfs_dir2_data_off_t)), XFS_DIR2_DATA_ALIGN) 210 - 211 - #define XFS_DIR3_DATA_ENTSIZE(n) \ 212 - round_up((offsetof(struct xfs_dir2_data_entry, name[0]) + (n) + \ 213 - sizeof(xfs_dir2_data_off_t) + sizeof(uint8_t)), \ 214 - XFS_DIR2_DATA_ALIGN) 215 - 216 - static int 217 - xfs_dir2_data_entsize( 218 - int n) 219 - { 220 - return XFS_DIR2_DATA_ENTSIZE(n); 221 - } 222 - 223 - static int 224 - xfs_dir3_data_entsize( 225 - int n) 226 - { 227 - return XFS_DIR3_DATA_ENTSIZE(n); 228 - } 229 - 230 - static uint8_t 231 - xfs_dir2_data_get_ftype( 232 - struct xfs_dir2_data_entry *dep) 233 - { 234 - return XFS_DIR3_FT_UNKNOWN; 235 - } 236 - 237 - static void 238 - xfs_dir2_data_put_ftype( 239 - struct xfs_dir2_data_entry *dep, 240 - uint8_t ftype) 241 - { 242 - ASSERT(ftype < XFS_DIR3_FT_MAX); 243 - } 244 - 245 - static uint8_t 246 - xfs_dir3_data_get_ftype( 247 - struct xfs_dir2_data_entry *dep) 248 - { 249 - uint8_t ftype = dep->name[dep->namelen]; 250 - 251 - if (ftype >= XFS_DIR3_FT_MAX) 252 - return XFS_DIR3_FT_UNKNOWN; 253 - return ftype; 254 - } 255 - 256 - static void 257 - xfs_dir3_data_put_ftype( 258 - struct xfs_dir2_data_entry *dep, 259 - uint8_t type) 260 - { 261 - ASSERT(type < XFS_DIR3_FT_MAX); 262 - ASSERT(dep->namelen != 0); 263 - 264 - dep->name[dep->namelen] = type; 265 - } 266 - 267 - /* 268 - * Pointer to an entry's tag word. 269 - */ 270 - static __be16 * 271 - xfs_dir2_data_entry_tag_p( 272 - struct xfs_dir2_data_entry *dep) 273 - { 274 - return (__be16 *)((char *)dep + 275 - xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); 276 - } 277 - 278 - static __be16 * 279 - xfs_dir3_data_entry_tag_p( 280 - struct xfs_dir2_data_entry *dep) 281 - { 282 - return (__be16 *)((char *)dep + 283 - xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16)); 284 - } 285 - 286 - /* 287 - * location of . and .. in data space (always block 0) 288 - */ 289 - static struct xfs_dir2_data_entry * 290 - xfs_dir2_data_dot_entry_p( 291 - struct xfs_dir2_data_hdr *hdr) 292 - { 293 - return (struct xfs_dir2_data_entry *) 294 - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); 295 - } 296 - 297 - static struct xfs_dir2_data_entry * 298 - xfs_dir2_data_dotdot_entry_p( 299 - struct xfs_dir2_data_hdr *hdr) 300 - { 301 - return (struct xfs_dir2_data_entry *) 302 - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 303 - XFS_DIR2_DATA_ENTSIZE(1)); 304 - } 305 - 306 - static struct xfs_dir2_data_entry * 307 - xfs_dir2_data_first_entry_p( 308 - struct xfs_dir2_data_hdr *hdr) 309 - { 310 - return (struct xfs_dir2_data_entry *) 311 - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 312 - XFS_DIR2_DATA_ENTSIZE(1) + 313 - XFS_DIR2_DATA_ENTSIZE(2)); 314 - } 315 - 316 - static struct xfs_dir2_data_entry * 317 - xfs_dir2_ftype_data_dotdot_entry_p( 318 - struct xfs_dir2_data_hdr *hdr) 319 - { 320 - return (struct xfs_dir2_data_entry *) 321 - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 322 - XFS_DIR3_DATA_ENTSIZE(1)); 323 - } 324 - 325 - static struct xfs_dir2_data_entry * 326 - xfs_dir2_ftype_data_first_entry_p( 327 - struct xfs_dir2_data_hdr *hdr) 328 - { 329 - return (struct xfs_dir2_data_entry *) 330 - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr) + 331 - XFS_DIR3_DATA_ENTSIZE(1) + 332 - XFS_DIR3_DATA_ENTSIZE(2)); 333 - } 334 - 335 - static struct xfs_dir2_data_entry * 336 - xfs_dir3_data_dot_entry_p( 337 - struct xfs_dir2_data_hdr *hdr) 338 - { 339 - return (struct xfs_dir2_data_entry *) 340 - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); 341 - } 342 - 343 - static struct xfs_dir2_data_entry * 344 - xfs_dir3_data_dotdot_entry_p( 345 - struct xfs_dir2_data_hdr *hdr) 346 - { 347 - return (struct xfs_dir2_data_entry *) 348 - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) + 349 - XFS_DIR3_DATA_ENTSIZE(1)); 350 - } 351 - 352 - static struct xfs_dir2_data_entry * 353 - xfs_dir3_data_first_entry_p( 354 - struct xfs_dir2_data_hdr *hdr) 355 - { 356 - return (struct xfs_dir2_data_entry *) 357 - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr) + 358 - XFS_DIR3_DATA_ENTSIZE(1) + 359 - XFS_DIR3_DATA_ENTSIZE(2)); 360 - } 361 - 362 - static struct xfs_dir2_data_free * 363 - xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) 364 - { 365 - return hdr->bestfree; 366 - } 367 - 368 - static struct xfs_dir2_data_free * 369 - xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) 370 - { 371 - return ((struct xfs_dir3_data_hdr *)hdr)->best_free; 372 - } 373 - 374 - static struct xfs_dir2_data_entry * 375 - xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr) 376 - { 377 - return (struct xfs_dir2_data_entry *) 378 - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); 379 - } 380 - 381 - static struct xfs_dir2_data_unused * 382 - xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr) 383 - { 384 - return (struct xfs_dir2_data_unused *) 385 - ((char *)hdr + sizeof(struct xfs_dir2_data_hdr)); 386 - } 387 - 388 - static struct xfs_dir2_data_entry * 389 - xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr) 390 - { 391 - return (struct xfs_dir2_data_entry *) 392 - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); 393 - } 394 - 395 - static struct xfs_dir2_data_unused * 396 - xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) 397 - { 398 - return (struct xfs_dir2_data_unused *) 399 - ((char *)hdr + sizeof(struct xfs_dir3_data_hdr)); 400 - } 401 - 402 - 403 - /* 404 - * Directory Leaf block operations 405 - */ 406 - static int 407 - xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo) 408 - { 409 - return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) / 410 - (uint)sizeof(struct xfs_dir2_leaf_entry); 411 - } 412 - 413 - static struct xfs_dir2_leaf_entry * 414 - xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp) 415 - { 416 - return lp->__ents; 417 - } 418 - 419 - static int 420 - xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo) 421 - { 422 - return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) / 423 - (uint)sizeof(struct xfs_dir2_leaf_entry); 424 - } 425 - 426 - static struct xfs_dir2_leaf_entry * 427 - xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp) 428 - { 429 - return ((struct xfs_dir3_leaf *)lp)->__ents; 430 - } 431 - 432 - static void 433 - xfs_dir2_leaf_hdr_from_disk( 434 - struct xfs_dir3_icleaf_hdr *to, 435 - struct xfs_dir2_leaf *from) 436 - { 437 - to->forw = be32_to_cpu(from->hdr.info.forw); 438 - to->back = be32_to_cpu(from->hdr.info.back); 439 - to->magic = be16_to_cpu(from->hdr.info.magic); 440 - to->count = be16_to_cpu(from->hdr.count); 441 - to->stale = be16_to_cpu(from->hdr.stale); 442 - 443 - ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || 444 - to->magic == XFS_DIR2_LEAFN_MAGIC); 445 - } 446 - 447 - static void 448 - xfs_dir2_leaf_hdr_to_disk( 449 - struct xfs_dir2_leaf *to, 450 - struct xfs_dir3_icleaf_hdr *from) 451 - { 452 - ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || 453 - from->magic == XFS_DIR2_LEAFN_MAGIC); 454 - 455 - to->hdr.info.forw = cpu_to_be32(from->forw); 456 - to->hdr.info.back = cpu_to_be32(from->back); 457 - to->hdr.info.magic = cpu_to_be16(from->magic); 458 - to->hdr.count = cpu_to_be16(from->count); 459 - to->hdr.stale = cpu_to_be16(from->stale); 460 - } 461 - 462 - static void 463 - xfs_dir3_leaf_hdr_from_disk( 464 - struct xfs_dir3_icleaf_hdr *to, 465 - struct xfs_dir2_leaf *from) 466 - { 467 - struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from; 468 - 469 - to->forw = be32_to_cpu(hdr3->info.hdr.forw); 470 - to->back = be32_to_cpu(hdr3->info.hdr.back); 471 - to->magic = be16_to_cpu(hdr3->info.hdr.magic); 472 - to->count = be16_to_cpu(hdr3->count); 473 - to->stale = be16_to_cpu(hdr3->stale); 474 - 475 - ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || 476 - to->magic == XFS_DIR3_LEAFN_MAGIC); 477 - } 478 - 479 - static void 480 - xfs_dir3_leaf_hdr_to_disk( 481 - struct xfs_dir2_leaf *to, 482 - struct xfs_dir3_icleaf_hdr *from) 483 - { 484 - struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to; 485 - 486 - ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC || 487 - from->magic == XFS_DIR3_LEAFN_MAGIC); 488 - 489 - hdr3->info.hdr.forw = cpu_to_be32(from->forw); 490 - hdr3->info.hdr.back = cpu_to_be32(from->back); 491 - hdr3->info.hdr.magic = cpu_to_be16(from->magic); 492 - hdr3->count = cpu_to_be16(from->count); 493 - hdr3->stale = cpu_to_be16(from->stale); 494 - } 495 - 496 - 497 - /* 498 - * Directory/Attribute Node block operations 499 - */ 500 - static struct xfs_da_node_entry * 501 - xfs_da2_node_tree_p(struct xfs_da_intnode *dap) 502 - { 503 - return dap->__btree; 504 - } 505 - 506 - static struct xfs_da_node_entry * 507 - xfs_da3_node_tree_p(struct xfs_da_intnode *dap) 508 - { 509 - return ((struct xfs_da3_intnode *)dap)->__btree; 510 - } 511 - 512 - static void 513 - xfs_da2_node_hdr_from_disk( 514 - struct xfs_da3_icnode_hdr *to, 515 - struct xfs_da_intnode *from) 516 - { 517 - ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)); 518 - to->forw = be32_to_cpu(from->hdr.info.forw); 519 - to->back = be32_to_cpu(from->hdr.info.back); 520 - to->magic = be16_to_cpu(from->hdr.info.magic); 521 - to->count = be16_to_cpu(from->hdr.__count); 522 - to->level = be16_to_cpu(from->hdr.__level); 523 - } 524 - 525 - static void 526 - xfs_da2_node_hdr_to_disk( 527 - struct xfs_da_intnode *to, 528 - struct xfs_da3_icnode_hdr *from) 529 - { 530 - ASSERT(from->magic == XFS_DA_NODE_MAGIC); 531 - to->hdr.info.forw = cpu_to_be32(from->forw); 532 - to->hdr.info.back = cpu_to_be32(from->back); 533 - to->hdr.info.magic = cpu_to_be16(from->magic); 534 - to->hdr.__count = cpu_to_be16(from->count); 535 - to->hdr.__level = cpu_to_be16(from->level); 536 - } 537 - 538 - static void 539 - xfs_da3_node_hdr_from_disk( 540 - struct xfs_da3_icnode_hdr *to, 541 - struct xfs_da_intnode *from) 542 - { 543 - struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)from; 544 - 545 - ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)); 546 - to->forw = be32_to_cpu(hdr3->info.hdr.forw); 547 - to->back = be32_to_cpu(hdr3->info.hdr.back); 548 - to->magic = be16_to_cpu(hdr3->info.hdr.magic); 549 - to->count = be16_to_cpu(hdr3->__count); 550 - to->level = be16_to_cpu(hdr3->__level); 551 - } 552 - 553 - static void 554 - xfs_da3_node_hdr_to_disk( 555 - struct xfs_da_intnode *to, 556 - struct xfs_da3_icnode_hdr *from) 557 - { 558 - struct xfs_da3_node_hdr *hdr3 = (struct xfs_da3_node_hdr *)to; 559 - 560 - ASSERT(from->magic == XFS_DA3_NODE_MAGIC); 561 - hdr3->info.hdr.forw = cpu_to_be32(from->forw); 562 - hdr3->info.hdr.back = cpu_to_be32(from->back); 563 - hdr3->info.hdr.magic = cpu_to_be16(from->magic); 564 - hdr3->__count = cpu_to_be16(from->count); 565 - hdr3->__level = cpu_to_be16(from->level); 566 - } 567 - 568 - 569 - /* 570 - * Directory free space block operations 571 - */ 572 - static int 573 - xfs_dir2_free_max_bests(struct xfs_da_geometry *geo) 574 - { 575 - return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) / 576 - sizeof(xfs_dir2_data_off_t); 577 - } 578 - 579 - static __be16 * 580 - xfs_dir2_free_bests_p(struct xfs_dir2_free *free) 581 - { 582 - return (__be16 *)((char *)free + sizeof(struct xfs_dir2_free_hdr)); 583 - } 584 - 585 - /* 586 - * Convert data space db to the corresponding free db. 587 - */ 588 - static xfs_dir2_db_t 589 - xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 590 - { 591 - return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + 592 - (db / xfs_dir2_free_max_bests(geo)); 593 - } 594 - 595 - /* 596 - * Convert data space db to the corresponding index in a free db. 597 - */ 598 - static int 599 - xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 600 - { 601 - return db % xfs_dir2_free_max_bests(geo); 602 - } 603 - 604 - static int 605 - xfs_dir3_free_max_bests(struct xfs_da_geometry *geo) 606 - { 607 - return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) / 608 - sizeof(xfs_dir2_data_off_t); 609 - } 610 - 611 - static __be16 * 612 - xfs_dir3_free_bests_p(struct xfs_dir2_free *free) 613 - { 614 - return (__be16 *)((char *)free + sizeof(struct xfs_dir3_free_hdr)); 615 - } 616 - 617 - /* 618 - * Convert data space db to the corresponding free db. 619 - */ 620 - static xfs_dir2_db_t 621 - xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 622 - { 623 - return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + 624 - (db / xfs_dir3_free_max_bests(geo)); 625 - } 626 - 627 - /* 628 - * Convert data space db to the corresponding index in a free db. 629 - */ 630 - static int 631 - xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 632 - { 633 - return db % xfs_dir3_free_max_bests(geo); 634 - } 635 - 636 - static void 637 - xfs_dir2_free_hdr_from_disk( 638 - struct xfs_dir3_icfree_hdr *to, 639 - struct xfs_dir2_free *from) 640 - { 641 - to->magic = be32_to_cpu(from->hdr.magic); 642 - to->firstdb = be32_to_cpu(from->hdr.firstdb); 643 - to->nvalid = be32_to_cpu(from->hdr.nvalid); 644 - to->nused = be32_to_cpu(from->hdr.nused); 645 - ASSERT(to->magic == XFS_DIR2_FREE_MAGIC); 646 - } 647 - 648 - static void 649 - xfs_dir2_free_hdr_to_disk( 650 - struct xfs_dir2_free *to, 651 - struct xfs_dir3_icfree_hdr *from) 652 - { 653 - ASSERT(from->magic == XFS_DIR2_FREE_MAGIC); 654 - 655 - to->hdr.magic = cpu_to_be32(from->magic); 656 - to->hdr.firstdb = cpu_to_be32(from->firstdb); 657 - to->hdr.nvalid = cpu_to_be32(from->nvalid); 658 - to->hdr.nused = cpu_to_be32(from->nused); 659 - } 660 - 661 - static void 662 - xfs_dir3_free_hdr_from_disk( 663 - struct xfs_dir3_icfree_hdr *to, 664 - struct xfs_dir2_free *from) 665 - { 666 - struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from; 667 - 668 - to->magic = be32_to_cpu(hdr3->hdr.magic); 669 - to->firstdb = be32_to_cpu(hdr3->firstdb); 670 - to->nvalid = be32_to_cpu(hdr3->nvalid); 671 - to->nused = be32_to_cpu(hdr3->nused); 672 - 673 - ASSERT(to->magic == XFS_DIR3_FREE_MAGIC); 674 - } 675 - 676 - static void 677 - xfs_dir3_free_hdr_to_disk( 678 - struct xfs_dir2_free *to, 679 - struct xfs_dir3_icfree_hdr *from) 680 - { 681 - struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to; 682 - 683 - ASSERT(from->magic == XFS_DIR3_FREE_MAGIC); 684 - 685 - hdr3->hdr.magic = cpu_to_be32(from->magic); 686 - hdr3->firstdb = cpu_to_be32(from->firstdb); 687 - hdr3->nvalid = cpu_to_be32(from->nvalid); 688 - hdr3->nused = cpu_to_be32(from->nused); 689 - } 690 - 691 - static const struct xfs_dir_ops xfs_dir2_ops = { 692 - .sf_entsize = xfs_dir2_sf_entsize, 693 - .sf_nextentry = xfs_dir2_sf_nextentry, 694 - .sf_get_ftype = xfs_dir2_sfe_get_ftype, 695 - .sf_put_ftype = xfs_dir2_sfe_put_ftype, 696 - .sf_get_ino = xfs_dir2_sfe_get_ino, 697 - .sf_put_ino = xfs_dir2_sfe_put_ino, 698 - .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 699 - .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 700 - 701 - .data_entsize = xfs_dir2_data_entsize, 702 - .data_get_ftype = xfs_dir2_data_get_ftype, 703 - .data_put_ftype = xfs_dir2_data_put_ftype, 704 - .data_entry_tag_p = xfs_dir2_data_entry_tag_p, 705 - .data_bestfree_p = xfs_dir2_data_bestfree_p, 706 - 707 - .data_dot_offset = sizeof(struct xfs_dir2_data_hdr), 708 - .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) + 709 - XFS_DIR2_DATA_ENTSIZE(1), 710 - .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + 711 - XFS_DIR2_DATA_ENTSIZE(1) + 712 - XFS_DIR2_DATA_ENTSIZE(2), 713 - .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), 714 - 715 - .data_dot_entry_p = xfs_dir2_data_dot_entry_p, 716 - .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p, 717 - .data_first_entry_p = xfs_dir2_data_first_entry_p, 718 - .data_entry_p = xfs_dir2_data_entry_p, 719 - .data_unused_p = xfs_dir2_data_unused_p, 720 - 721 - .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), 722 - .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, 723 - .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk, 724 - .leaf_max_ents = xfs_dir2_max_leaf_ents, 725 - .leaf_ents_p = xfs_dir2_leaf_ents_p, 726 - 727 - .node_hdr_size = sizeof(struct xfs_da_node_hdr), 728 - .node_hdr_to_disk = xfs_da2_node_hdr_to_disk, 729 - .node_hdr_from_disk = xfs_da2_node_hdr_from_disk, 730 - .node_tree_p = xfs_da2_node_tree_p, 731 - 732 - .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), 733 - .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, 734 - .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, 735 - .free_max_bests = xfs_dir2_free_max_bests, 736 - .free_bests_p = xfs_dir2_free_bests_p, 737 - .db_to_fdb = xfs_dir2_db_to_fdb, 738 - .db_to_fdindex = xfs_dir2_db_to_fdindex, 739 - }; 740 - 741 - static const struct xfs_dir_ops xfs_dir2_ftype_ops = { 742 - .sf_entsize = xfs_dir3_sf_entsize, 743 - .sf_nextentry = xfs_dir3_sf_nextentry, 744 - .sf_get_ftype = xfs_dir3_sfe_get_ftype, 745 - .sf_put_ftype = xfs_dir3_sfe_put_ftype, 746 - .sf_get_ino = xfs_dir3_sfe_get_ino, 747 - .sf_put_ino = xfs_dir3_sfe_put_ino, 748 - .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 749 - .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 750 - 751 - .data_entsize = xfs_dir3_data_entsize, 752 - .data_get_ftype = xfs_dir3_data_get_ftype, 753 - .data_put_ftype = xfs_dir3_data_put_ftype, 754 - .data_entry_tag_p = xfs_dir3_data_entry_tag_p, 755 - .data_bestfree_p = xfs_dir2_data_bestfree_p, 756 - 757 - .data_dot_offset = sizeof(struct xfs_dir2_data_hdr), 758 - .data_dotdot_offset = sizeof(struct xfs_dir2_data_hdr) + 759 - XFS_DIR3_DATA_ENTSIZE(1), 760 - .data_first_offset = sizeof(struct xfs_dir2_data_hdr) + 761 - XFS_DIR3_DATA_ENTSIZE(1) + 762 - XFS_DIR3_DATA_ENTSIZE(2), 763 - .data_entry_offset = sizeof(struct xfs_dir2_data_hdr), 764 - 765 - .data_dot_entry_p = xfs_dir2_data_dot_entry_p, 766 - .data_dotdot_entry_p = xfs_dir2_ftype_data_dotdot_entry_p, 767 - .data_first_entry_p = xfs_dir2_ftype_data_first_entry_p, 768 - .data_entry_p = xfs_dir2_data_entry_p, 769 - .data_unused_p = xfs_dir2_data_unused_p, 770 - 771 - .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), 772 - .leaf_hdr_to_disk = xfs_dir2_leaf_hdr_to_disk, 773 - .leaf_hdr_from_disk = xfs_dir2_leaf_hdr_from_disk, 774 - .leaf_max_ents = xfs_dir2_max_leaf_ents, 775 - .leaf_ents_p = xfs_dir2_leaf_ents_p, 776 - 777 - .node_hdr_size = sizeof(struct xfs_da_node_hdr), 778 - .node_hdr_to_disk = xfs_da2_node_hdr_to_disk, 779 - .node_hdr_from_disk = xfs_da2_node_hdr_from_disk, 780 - .node_tree_p = xfs_da2_node_tree_p, 781 - 782 - .free_hdr_size = sizeof(struct xfs_dir2_free_hdr), 783 - .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, 784 - .free_hdr_from_disk = xfs_dir2_free_hdr_from_disk, 785 - .free_max_bests = xfs_dir2_free_max_bests, 786 - .free_bests_p = xfs_dir2_free_bests_p, 787 - .db_to_fdb = xfs_dir2_db_to_fdb, 788 - .db_to_fdindex = xfs_dir2_db_to_fdindex, 789 - }; 790 - 791 - static const struct xfs_dir_ops xfs_dir3_ops = { 792 - .sf_entsize = xfs_dir3_sf_entsize, 793 - .sf_nextentry = xfs_dir3_sf_nextentry, 794 - .sf_get_ftype = xfs_dir3_sfe_get_ftype, 795 - .sf_put_ftype = xfs_dir3_sfe_put_ftype, 796 - .sf_get_ino = xfs_dir3_sfe_get_ino, 797 - .sf_put_ino = xfs_dir3_sfe_put_ino, 798 - .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 799 - .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 800 - 801 - .data_entsize = xfs_dir3_data_entsize, 802 - .data_get_ftype = xfs_dir3_data_get_ftype, 803 - .data_put_ftype = xfs_dir3_data_put_ftype, 804 - .data_entry_tag_p = xfs_dir3_data_entry_tag_p, 805 - .data_bestfree_p = xfs_dir3_data_bestfree_p, 806 - 807 - .data_dot_offset = sizeof(struct xfs_dir3_data_hdr), 808 - .data_dotdot_offset = sizeof(struct xfs_dir3_data_hdr) + 809 - XFS_DIR3_DATA_ENTSIZE(1), 810 - .data_first_offset = sizeof(struct xfs_dir3_data_hdr) + 811 - XFS_DIR3_DATA_ENTSIZE(1) + 812 - XFS_DIR3_DATA_ENTSIZE(2), 813 - .data_entry_offset = sizeof(struct xfs_dir3_data_hdr), 814 - 815 - .data_dot_entry_p = xfs_dir3_data_dot_entry_p, 816 - .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p, 817 - .data_first_entry_p = xfs_dir3_data_first_entry_p, 818 - .data_entry_p = xfs_dir3_data_entry_p, 819 - .data_unused_p = xfs_dir3_data_unused_p, 820 - 821 - .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr), 822 - .leaf_hdr_to_disk = xfs_dir3_leaf_hdr_to_disk, 823 - .leaf_hdr_from_disk = xfs_dir3_leaf_hdr_from_disk, 824 - .leaf_max_ents = xfs_dir3_max_leaf_ents, 825 - .leaf_ents_p = xfs_dir3_leaf_ents_p, 826 - 827 - .node_hdr_size = sizeof(struct xfs_da3_node_hdr), 828 - .node_hdr_to_disk = xfs_da3_node_hdr_to_disk, 829 - .node_hdr_from_disk = xfs_da3_node_hdr_from_disk, 830 - .node_tree_p = xfs_da3_node_tree_p, 831 - 832 - .free_hdr_size = sizeof(struct xfs_dir3_free_hdr), 833 - .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk, 834 - .free_hdr_from_disk = xfs_dir3_free_hdr_from_disk, 835 - .free_max_bests = xfs_dir3_free_max_bests, 836 - .free_bests_p = xfs_dir3_free_bests_p, 837 - .db_to_fdb = xfs_dir3_db_to_fdb, 838 - .db_to_fdindex = xfs_dir3_db_to_fdindex, 839 - }; 840 - 841 - static const struct xfs_dir_ops xfs_dir2_nondir_ops = { 842 - .node_hdr_size = sizeof(struct xfs_da_node_hdr), 843 - .node_hdr_to_disk = xfs_da2_node_hdr_to_disk, 844 - .node_hdr_from_disk = xfs_da2_node_hdr_from_disk, 845 - .node_tree_p = xfs_da2_node_tree_p, 846 - }; 847 - 848 - static const struct xfs_dir_ops xfs_dir3_nondir_ops = { 849 - .node_hdr_size = sizeof(struct xfs_da3_node_hdr), 850 - .node_hdr_to_disk = xfs_da3_node_hdr_to_disk, 851 - .node_hdr_from_disk = xfs_da3_node_hdr_from_disk, 852 - .node_tree_p = xfs_da3_node_tree_p, 853 - }; 854 - 855 - /* 856 - * Return the ops structure according to the current config. If we are passed 857 - * an inode, then that overrides the default config we use which is based on 858 - * feature bits. 859 - */ 860 - const struct xfs_dir_ops * 861 - xfs_dir_get_ops( 862 - struct xfs_mount *mp, 863 - struct xfs_inode *dp) 864 - { 865 - if (dp) 866 - return dp->d_ops; 867 - if (mp->m_dir_inode_ops) 868 - return mp->m_dir_inode_ops; 869 - if (xfs_sb_version_hascrc(&mp->m_sb)) 870 - return &xfs_dir3_ops; 871 - if (xfs_sb_version_hasftype(&mp->m_sb)) 872 - return &xfs_dir2_ftype_ops; 873 - return &xfs_dir2_ops; 874 - } 875 - 876 - const struct xfs_dir_ops * 877 - xfs_nondir_get_ops( 878 - struct xfs_mount *mp, 879 - struct xfs_inode *dp) 880 - { 881 - if (dp) 882 - return dp->d_ops; 883 - if (mp->m_nondir_inode_ops) 884 - return mp->m_nondir_inode_ops; 885 - if (xfs_sb_version_hascrc(&mp->m_sb)) 886 - return &xfs_dir3_nondir_ops; 887 - return &xfs_dir2_nondir_ops; 888 - }
+1 -58
fs/xfs/libxfs/xfs_da_format.h
··· 94 94 }; 95 95 96 96 /* 97 - * In-core version of the node header to abstract the differences in the v2 and 98 - * v3 disk format of the headers. Callers need to convert to/from disk format as 99 - * appropriate. 100 - */ 101 - struct xfs_da3_icnode_hdr { 102 - uint32_t forw; 103 - uint32_t back; 104 - uint16_t magic; 105 - uint16_t count; 106 - uint16_t level; 107 - }; 108 - 109 - /* 110 97 * Directory version 2. 111 98 * 112 99 * There are 4 possible formats: ··· 421 434 __be32 pad; /* 64 bit alignment */ 422 435 }; 423 436 424 - struct xfs_dir3_icleaf_hdr { 425 - uint32_t forw; 426 - uint32_t back; 427 - uint16_t magic; 428 - uint16_t count; 429 - uint16_t stale; 430 - }; 431 - 432 437 /* 433 438 * Leaf block entry. 434 439 */ ··· 461 482 } 462 483 463 484 /* 464 - * Free space block defintions for the node format. 485 + * Free space block definitions for the node format. 465 486 */ 466 487 467 488 /* ··· 498 519 }; 499 520 500 521 #define XFS_DIR3_FREE_CRC_OFF offsetof(struct xfs_dir3_free, hdr.hdr.crc) 501 - 502 - /* 503 - * In core version of the free block header, abstracted away from on-disk format 504 - * differences. Use this in the code, and convert to/from the disk version using 505 - * xfs_dir3_free_hdr_from_disk/xfs_dir3_free_hdr_to_disk. 506 - */ 507 - struct xfs_dir3_icfree_hdr { 508 - uint32_t magic; 509 - uint32_t firstdb; 510 - uint32_t nvalid; 511 - uint32_t nused; 512 - 513 - }; 514 522 515 523 /* 516 524 * Single block format. ··· 673 707 * struct xfs_attr_leaf_name_local 674 708 * struct xfs_attr_leaf_name_remote 675 709 */ 676 - }; 677 - 678 - /* 679 - * incore, neutral version of the attribute leaf header 680 - */ 681 - struct xfs_attr3_icleaf_hdr { 682 - uint32_t forw; 683 - uint32_t back; 684 - uint16_t magic; 685 - uint16_t count; 686 - uint16_t usedbytes; 687 - /* 688 - * firstused is 32-bit here instead of 16-bit like the on-disk variant 689 - * to support maximum fsb size of 64k without overflow issues throughout 690 - * the attr code. Instead, the overflow condition is handled on 691 - * conversion to/from disk. 692 - */ 693 - uint32_t firstused; 694 - __u8 holes; 695 - struct { 696 - uint16_t base; 697 - uint16_t size; 698 - } freemap[XFS_ATTR_LEAF_MAPSIZE]; 699 710 }; 700 711 701 712 /*
+40 -32
fs/xfs/libxfs/xfs_dir2.c
··· 52 52 * ASCII case-insensitive (ie. A-Z) support for directories that was 53 53 * used in IRIX. 54 54 */ 55 - STATIC xfs_dahash_t 55 + xfs_dahash_t 56 56 xfs_ascii_ci_hashname( 57 57 struct xfs_name *name) 58 58 { ··· 65 65 return hash; 66 66 } 67 67 68 - STATIC enum xfs_dacmp 68 + enum xfs_dacmp 69 69 xfs_ascii_ci_compname( 70 - struct xfs_da_args *args, 71 - const unsigned char *name, 72 - int len) 70 + struct xfs_da_args *args, 71 + const unsigned char *name, 72 + int len) 73 73 { 74 - enum xfs_dacmp result; 75 - int i; 74 + enum xfs_dacmp result; 75 + int i; 76 76 77 77 if (args->namelen != len) 78 78 return XFS_CMP_DIFFERENT; ··· 89 89 return result; 90 90 } 91 91 92 - static const struct xfs_nameops xfs_ascii_ci_nameops = { 93 - .hashname = xfs_ascii_ci_hashname, 94 - .compname = xfs_ascii_ci_compname, 95 - }; 96 - 97 92 int 98 93 xfs_da_mount( 99 94 struct xfs_mount *mp) 100 95 { 101 96 struct xfs_da_geometry *dageo; 102 - int nodehdr_size; 103 97 104 98 105 99 ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT); 106 100 ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE); 107 101 108 - mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL); 109 - mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL); 110 - 111 - nodehdr_size = mp->m_dir_inode_ops->node_hdr_size; 112 102 mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry), 113 103 KM_MAYFAIL); 114 104 mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry), ··· 115 125 dageo->fsblog = mp->m_sb.sb_blocklog; 116 126 dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb); 117 127 dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog; 128 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 129 + dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr); 130 + dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr); 131 + dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr); 132 + dageo->data_entry_offset = 133 + sizeof(struct xfs_dir3_data_hdr); 134 + } else { 135 + dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr); 136 + dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr); 137 + dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr); 138 + dageo->data_entry_offset = 139 + sizeof(struct xfs_dir2_data_hdr); 140 + } 141 + dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) / 142 + sizeof(struct xfs_dir2_leaf_entry); 143 + dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) / 144 + sizeof(xfs_dir2_data_off_t); 145 + 146 + dageo->data_first_offset = dageo->data_entry_offset + 147 + xfs_dir2_data_entsize(mp, 1) + 148 + xfs_dir2_data_entsize(mp, 2); 118 149 119 150 /* 120 151 * Now we've set up the block conversion variables, we can calculate the ··· 144 133 dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET); 145 134 dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET); 146 135 dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET); 147 - dageo->node_ents = (dageo->blksize - nodehdr_size) / 136 + dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) / 148 137 (uint)sizeof(xfs_da_node_entry_t); 149 138 dageo->magicpct = (dageo->blksize * 37) / 100; 150 139 ··· 154 143 dageo->fsblog = mp->m_sb.sb_blocklog; 155 144 dageo->blksize = 1 << dageo->blklog; 156 145 dageo->fsbcount = 1; 157 - dageo->node_ents = (dageo->blksize - nodehdr_size) / 146 + dageo->node_hdr_size = mp->m_dir_geo->node_hdr_size; 147 + dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) / 158 148 (uint)sizeof(xfs_da_node_entry_t); 159 149 dageo->magicpct = (dageo->blksize * 37) / 100; 160 - 161 - if (xfs_sb_version_hasasciici(&mp->m_sb)) 162 - mp->m_dirnameops = &xfs_ascii_ci_nameops; 163 - else 164 - mp->m_dirnameops = &xfs_default_nameops; 165 - 166 150 return 0; 167 151 } 168 152 ··· 197 191 { 198 192 bool ino_ok = xfs_verify_dir_ino(mp, ino); 199 193 200 - if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE))) { 194 + if (XFS_IS_CORRUPT(mp, !ino_ok) || 195 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_DIR_INO_VALIDATE)) { 201 196 xfs_warn(mp, "Invalid inode number 0x%Lx", 202 197 (unsigned long long) ino); 203 - XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); 204 198 return -EFSCORRUPTED; 205 199 } 206 200 return 0; ··· 268 262 args->name = name->name; 269 263 args->namelen = name->len; 270 264 args->filetype = name->type; 271 - args->hashval = dp->i_mount->m_dirnameops->hashname(name); 265 + args->hashval = xfs_dir2_hashname(dp->i_mount, name); 272 266 args->inumber = inum; 273 267 args->dp = dp; 274 268 args->total = total; ··· 364 358 args->name = name->name; 365 359 args->namelen = name->len; 366 360 args->filetype = name->type; 367 - args->hashval = dp->i_mount->m_dirnameops->hashname(name); 361 + args->hashval = xfs_dir2_hashname(dp->i_mount, name); 368 362 args->dp = dp; 369 363 args->whichfork = XFS_DATA_FORK; 370 364 args->trans = tp; ··· 436 430 args->name = name->name; 437 431 args->namelen = name->len; 438 432 args->filetype = name->type; 439 - args->hashval = dp->i_mount->m_dirnameops->hashname(name); 433 + args->hashval = xfs_dir2_hashname(dp->i_mount, name); 440 434 args->inumber = ino; 441 435 args->dp = dp; 442 436 args->total = total; ··· 497 491 args->name = name->name; 498 492 args->namelen = name->len; 499 493 args->filetype = name->type; 500 - args->hashval = dp->i_mount->m_dirnameops->hashname(name); 494 + args->hashval = xfs_dir2_hashname(dp->i_mount, name); 501 495 args->inumber = inum; 502 496 args->dp = dp; 503 497 args->total = total; ··· 606 600 if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK))) 607 601 return rval; 608 602 rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize; 609 - if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize) 603 + if (XFS_IS_CORRUPT(args->dp->i_mount, 604 + rval != 0 && 605 + args->dp->i_d.di_size != args->geo->blksize)) 610 606 return -EFSCORRUPTED; 611 607 *vp = rval; 612 608 return 0;
+6 -84
fs/xfs/libxfs/xfs_dir2.h
··· 18 18 struct xfs_dir2_data_hdr; 19 19 struct xfs_dir2_data_entry; 20 20 struct xfs_dir2_data_unused; 21 + struct xfs_dir3_icfree_hdr; 22 + struct xfs_dir3_icleaf_hdr; 21 23 22 24 extern struct xfs_name xfs_name_dotdot; 23 25 ··· 27 25 * Convert inode mode to directory entry filetype 28 26 */ 29 27 extern unsigned char xfs_mode_to_ftype(int mode); 30 - 31 - /* 32 - * directory operations vector for encode/decode routines 33 - */ 34 - struct xfs_dir_ops { 35 - int (*sf_entsize)(struct xfs_dir2_sf_hdr *hdr, int len); 36 - struct xfs_dir2_sf_entry * 37 - (*sf_nextentry)(struct xfs_dir2_sf_hdr *hdr, 38 - struct xfs_dir2_sf_entry *sfep); 39 - uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep); 40 - void (*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep, 41 - uint8_t ftype); 42 - xfs_ino_t (*sf_get_ino)(struct xfs_dir2_sf_hdr *hdr, 43 - struct xfs_dir2_sf_entry *sfep); 44 - void (*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr, 45 - struct xfs_dir2_sf_entry *sfep, 46 - xfs_ino_t ino); 47 - xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr); 48 - void (*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr, 49 - xfs_ino_t ino); 50 - 51 - int (*data_entsize)(int len); 52 - uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep); 53 - void (*data_put_ftype)(struct xfs_dir2_data_entry *dep, 54 - uint8_t ftype); 55 - __be16 * (*data_entry_tag_p)(struct xfs_dir2_data_entry *dep); 56 - struct xfs_dir2_data_free * 57 - (*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr); 58 - 59 - xfs_dir2_data_aoff_t data_dot_offset; 60 - xfs_dir2_data_aoff_t data_dotdot_offset; 61 - xfs_dir2_data_aoff_t data_first_offset; 62 - size_t data_entry_offset; 63 - 64 - struct xfs_dir2_data_entry * 65 - (*data_dot_entry_p)(struct xfs_dir2_data_hdr *hdr); 66 - struct xfs_dir2_data_entry * 67 - (*data_dotdot_entry_p)(struct xfs_dir2_data_hdr *hdr); 68 - struct xfs_dir2_data_entry * 69 - (*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr); 70 - struct xfs_dir2_data_entry * 71 - (*data_entry_p)(struct xfs_dir2_data_hdr *hdr); 72 - struct xfs_dir2_data_unused * 73 - (*data_unused_p)(struct xfs_dir2_data_hdr *hdr); 74 - 75 - int leaf_hdr_size; 76 - void (*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to, 77 - struct xfs_dir3_icleaf_hdr *from); 78 - void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to, 79 - struct xfs_dir2_leaf *from); 80 - int (*leaf_max_ents)(struct xfs_da_geometry *geo); 81 - struct xfs_dir2_leaf_entry * 82 - (*leaf_ents_p)(struct xfs_dir2_leaf *lp); 83 - 84 - int node_hdr_size; 85 - void (*node_hdr_to_disk)(struct xfs_da_intnode *to, 86 - struct xfs_da3_icnode_hdr *from); 87 - void (*node_hdr_from_disk)(struct xfs_da3_icnode_hdr *to, 88 - struct xfs_da_intnode *from); 89 - struct xfs_da_node_entry * 90 - (*node_tree_p)(struct xfs_da_intnode *dap); 91 - 92 - int free_hdr_size; 93 - void (*free_hdr_to_disk)(struct xfs_dir2_free *to, 94 - struct xfs_dir3_icfree_hdr *from); 95 - void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to, 96 - struct xfs_dir2_free *from); 97 - int (*free_max_bests)(struct xfs_da_geometry *geo); 98 - __be16 * (*free_bests_p)(struct xfs_dir2_free *free); 99 - xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo, 100 - xfs_dir2_db_t db); 101 - int (*db_to_fdindex)(struct xfs_da_geometry *geo, 102 - xfs_dir2_db_t db); 103 - }; 104 - 105 - extern const struct xfs_dir_ops * 106 - xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp); 107 - extern const struct xfs_dir_ops * 108 - xfs_nondir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp); 109 28 110 29 /* 111 30 * Generic directory interface routines ··· 47 124 extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, 48 125 struct xfs_name *name, xfs_ino_t ino, 49 126 xfs_extlen_t tot); 127 + extern bool xfs_dir2_sf_replace_needblock(struct xfs_inode *dp, 128 + xfs_ino_t inum); 50 129 extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, 51 130 struct xfs_name *name, xfs_ino_t inum, 52 131 xfs_extlen_t tot); ··· 68 143 extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, 69 144 struct xfs_buf *bp); 70 145 71 - extern void xfs_dir2_data_freescan_int(struct xfs_da_geometry *geo, 72 - const struct xfs_dir_ops *ops, 73 - struct xfs_dir2_data_hdr *hdr, int *loghead); 74 - extern void xfs_dir2_data_freescan(struct xfs_inode *dp, 146 + extern void xfs_dir2_data_freescan(struct xfs_mount *mp, 75 147 struct xfs_dir2_data_hdr *hdr, int *loghead); 76 148 extern void xfs_dir2_data_log_entry(struct xfs_da_args *args, 77 149 struct xfs_buf *bp, struct xfs_dir2_data_entry *dep); ··· 246 324 #define XFS_READDIR_BUFSIZE (32768) 247 325 248 326 unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp, uint8_t filetype); 249 - void *xfs_dir3_data_endp(struct xfs_da_geometry *geo, 327 + unsigned int xfs_dir3_data_end_offset(struct xfs_da_geometry *geo, 250 328 struct xfs_dir2_data_hdr *hdr); 251 329 bool xfs_dir2_namecheck(const void *name, size_t length); 252 330
+61 -70
fs/xfs/libxfs/xfs_dir2_block.c
··· 123 123 struct xfs_mount *mp = dp->i_mount; 124 124 int err; 125 125 126 - err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, -1, bpp, 126 + err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, 0, bpp, 127 127 XFS_DATA_FORK, &xfs_dir3_block_buf_ops); 128 128 if (!err && tp && *bpp) 129 129 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF); ··· 172 172 struct xfs_dir2_data_unused *enddup = NULL; 173 173 174 174 *compact = 0; 175 - bf = dp->d_ops->data_bestfree_p(hdr); 175 + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 176 176 177 177 /* 178 178 * If there are stale entries we'll use one for the leaf. ··· 311 311 * This needs to happen before the next call to use_free. 312 312 */ 313 313 if (needscan) 314 - xfs_dir2_data_freescan(args->dp, hdr, needlog); 314 + xfs_dir2_data_freescan(args->dp->i_mount, hdr, needlog); 315 315 } 316 316 317 317 /* ··· 355 355 if (error) 356 356 return error; 357 357 358 - len = dp->d_ops->data_entsize(args->namelen); 358 + len = xfs_dir2_data_entsize(dp->i_mount, args->namelen); 359 359 360 360 /* 361 361 * Set up pointers to parts of the block. ··· 458 458 * This needs to happen before the next call to use_free. 459 459 */ 460 460 if (needscan) { 461 - xfs_dir2_data_freescan(dp, hdr, &needlog); 461 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 462 462 needscan = 0; 463 463 } 464 464 /* ··· 541 541 dep->inumber = cpu_to_be64(args->inumber); 542 542 dep->namelen = args->namelen; 543 543 memcpy(dep->name, args->name, args->namelen); 544 - dp->d_ops->data_put_ftype(dep, args->filetype); 545 - tagp = dp->d_ops->data_entry_tag_p(dep); 544 + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); 545 + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); 546 546 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 547 547 /* 548 548 * Clean up the bestfree array and log the header, tail, and entry. 549 549 */ 550 550 if (needscan) 551 - xfs_dir2_data_freescan(dp, hdr, &needlog); 551 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 552 552 if (needlog) 553 553 xfs_dir2_data_log_header(args, bp); 554 554 xfs_dir2_block_log_tail(tp, bp); ··· 633 633 * Fill in inode number, CI name if appropriate, release the block. 634 634 */ 635 635 args->inumber = be64_to_cpu(dep->inumber); 636 - args->filetype = dp->d_ops->data_get_ftype(dep); 636 + args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); 637 637 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); 638 638 xfs_trans_brelse(args->trans, bp); 639 639 return error; ··· 660 660 int high; /* binary search high index */ 661 661 int low; /* binary search low index */ 662 662 int mid; /* binary search current idx */ 663 - xfs_mount_t *mp; /* filesystem mount point */ 664 663 xfs_trans_t *tp; /* transaction pointer */ 665 664 enum xfs_dacmp cmp; /* comparison result */ 666 665 667 666 dp = args->dp; 668 667 tp = args->trans; 669 - mp = dp->i_mount; 670 668 671 669 error = xfs_dir3_block_read(tp, dp, &bp); 672 670 if (error) ··· 716 718 * and buffer. If it's the first case-insensitive match, store 717 719 * the index and buffer and continue looking for an exact match. 718 720 */ 719 - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); 721 + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); 720 722 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 721 723 args->cmpresult = cmp; 722 724 *bpp = bp; ··· 789 791 needlog = needscan = 0; 790 792 xfs_dir2_data_make_free(args, bp, 791 793 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), 792 - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); 794 + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, 795 + &needscan); 793 796 /* 794 797 * Fix up the block tail. 795 798 */ ··· 805 806 * Fix up bestfree, log the header if necessary. 806 807 */ 807 808 if (needscan) 808 - xfs_dir2_data_freescan(dp, hdr, &needlog); 809 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 809 810 if (needlog) 810 811 xfs_dir2_data_log_header(args, bp); 811 812 xfs_dir3_data_check(dp, bp); ··· 863 864 * Change the inode number to the new value. 864 865 */ 865 866 dep->inumber = cpu_to_be64(args->inumber); 866 - dp->d_ops->data_put_ftype(dep, args->filetype); 867 + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); 867 868 xfs_dir2_data_log_entry(args, bp, dep); 868 869 xfs_dir3_data_check(dp, bp); 869 870 return 0; ··· 913 914 __be16 *tagp; /* end of entry (tag) */ 914 915 int to; /* block/leaf to index */ 915 916 xfs_trans_t *tp; /* transaction pointer */ 916 - struct xfs_dir2_leaf_entry *ents; 917 917 struct xfs_dir3_icleaf_hdr leafhdr; 918 918 919 919 trace_xfs_dir2_leaf_to_block(args); ··· 921 923 tp = args->trans; 922 924 mp = dp->i_mount; 923 925 leaf = lbp->b_addr; 924 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 925 - ents = dp->d_ops->leaf_ents_p(leaf); 926 + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); 926 927 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); 927 928 928 929 ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || ··· 935 938 while (dp->i_d.di_size > args->geo->blksize) { 936 939 int hdrsz; 937 940 938 - hdrsz = dp->d_ops->data_entry_offset; 941 + hdrsz = args->geo->data_entry_offset; 939 942 bestsp = xfs_dir2_leaf_bests_p(ltp); 940 943 if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == 941 944 args->geo->blksize - hdrsz) { ··· 950 953 * Read the data block if we don't already have it, give up if it fails. 951 954 */ 952 955 if (!dbp) { 953 - error = xfs_dir3_data_read(tp, dp, args->geo->datablk, -1, &dbp); 956 + error = xfs_dir3_data_read(tp, dp, args->geo->datablk, 0, &dbp); 954 957 if (error) 955 958 return error; 956 959 } ··· 1001 1004 */ 1002 1005 lep = xfs_dir2_block_leaf_p(btp); 1003 1006 for (from = to = 0; from < leafhdr.count; from++) { 1004 - if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 1007 + if (leafhdr.ents[from].address == 1008 + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 1005 1009 continue; 1006 - lep[to++] = ents[from]; 1010 + lep[to++] = leafhdr.ents[from]; 1007 1011 } 1008 1012 ASSERT(to == be32_to_cpu(btp->count)); 1009 1013 xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); ··· 1012 1014 * Scan the bestfree if we need it and log the data block header. 1013 1015 */ 1014 1016 if (needscan) 1015 - xfs_dir2_data_freescan(dp, hdr, &needlog); 1017 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 1016 1018 if (needlog) 1017 1019 xfs_dir2_data_log_header(args, dbp); 1018 1020 /* ··· 1037 1039 */ 1038 1040 int /* error */ 1039 1041 xfs_dir2_sf_to_block( 1040 - xfs_da_args_t *args) /* operation arguments */ 1042 + struct xfs_da_args *args) 1041 1043 { 1044 + struct xfs_trans *tp = args->trans; 1045 + struct xfs_inode *dp = args->dp; 1046 + struct xfs_mount *mp = dp->i_mount; 1047 + struct xfs_ifork *ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); 1048 + struct xfs_da_geometry *geo = args->geo; 1042 1049 xfs_dir2_db_t blkno; /* dir-relative block # (0) */ 1043 1050 xfs_dir2_data_hdr_t *hdr; /* block header */ 1044 1051 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 1045 1052 struct xfs_buf *bp; /* block buffer */ 1046 1053 xfs_dir2_block_tail_t *btp; /* block tail pointer */ 1047 1054 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 1048 - xfs_inode_t *dp; /* incore directory inode */ 1049 1055 int dummy; /* trash */ 1050 1056 xfs_dir2_data_unused_t *dup; /* unused entry pointer */ 1051 1057 int endoffset; /* end of data objects */ 1052 1058 int error; /* error return value */ 1053 1059 int i; /* index */ 1054 - xfs_mount_t *mp; /* filesystem mount point */ 1055 1060 int needlog; /* need to log block header */ 1056 1061 int needscan; /* need to scan block freespc */ 1057 1062 int newoffset; /* offset from current entry */ 1058 - int offset; /* target block offset */ 1063 + unsigned int offset = geo->data_entry_offset; 1059 1064 xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ 1060 1065 xfs_dir2_sf_hdr_t *oldsfp; /* old shortform header */ 1061 1066 xfs_dir2_sf_hdr_t *sfp; /* shortform header */ 1062 1067 __be16 *tagp; /* end of data entry */ 1063 - xfs_trans_t *tp; /* transaction pointer */ 1064 1068 struct xfs_name name; 1065 - struct xfs_ifork *ifp; 1066 1069 1067 1070 trace_xfs_dir2_sf_to_block(args); 1068 1071 1069 - dp = args->dp; 1070 - tp = args->trans; 1071 - mp = dp->i_mount; 1072 - ifp = XFS_IFORK_PTR(dp, XFS_DATA_FORK); 1073 1072 ASSERT(ifp->if_flags & XFS_IFINLINE); 1074 - /* 1075 - * Bomb out if the shortform directory is way too short. 1076 - */ 1077 - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 1078 - ASSERT(XFS_FORCED_SHUTDOWN(mp)); 1079 - return -EIO; 1080 - } 1073 + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); 1081 1074 1082 1075 oldsfp = (xfs_dir2_sf_hdr_t *)ifp->if_u1.if_data; 1083 1076 ··· 1112 1123 * The whole thing is initialized to free by the init routine. 1113 1124 * Say we're using the leaf and tail area. 1114 1125 */ 1115 - dup = dp->d_ops->data_unused_p(hdr); 1126 + dup = bp->b_addr + offset; 1116 1127 needlog = needscan = 0; 1117 1128 error = xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i, 1118 1129 i, &needlog, &needscan); ··· 1135 1146 be16_to_cpu(dup->length), &needlog, &needscan); 1136 1147 if (error) 1137 1148 goto out_free; 1149 + 1138 1150 /* 1139 1151 * Create entry for . 1140 1152 */ 1141 - dep = dp->d_ops->data_dot_entry_p(hdr); 1153 + dep = bp->b_addr + offset; 1142 1154 dep->inumber = cpu_to_be64(dp->i_ino); 1143 1155 dep->namelen = 1; 1144 1156 dep->name[0] = '.'; 1145 - dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); 1146 - tagp = dp->d_ops->data_entry_tag_p(dep); 1147 - *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1157 + xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR); 1158 + tagp = xfs_dir2_data_entry_tag_p(mp, dep); 1159 + *tagp = cpu_to_be16(offset); 1148 1160 xfs_dir2_data_log_entry(args, bp, dep); 1149 1161 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); 1150 - blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( 1151 - (char *)dep - (char *)hdr)); 1162 + blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); 1163 + offset += xfs_dir2_data_entsize(mp, dep->namelen); 1164 + 1152 1165 /* 1153 1166 * Create entry for .. 1154 1167 */ 1155 - dep = dp->d_ops->data_dotdot_entry_p(hdr); 1156 - dep->inumber = cpu_to_be64(dp->d_ops->sf_get_parent_ino(sfp)); 1168 + dep = bp->b_addr + offset; 1169 + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); 1157 1170 dep->namelen = 2; 1158 1171 dep->name[0] = dep->name[1] = '.'; 1159 - dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); 1160 - tagp = dp->d_ops->data_entry_tag_p(dep); 1161 - *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1172 + xfs_dir2_data_put_ftype(mp, dep, XFS_DIR3_FT_DIR); 1173 + tagp = xfs_dir2_data_entry_tag_p(mp, dep); 1174 + *tagp = cpu_to_be16(offset); 1162 1175 xfs_dir2_data_log_entry(args, bp, dep); 1163 1176 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); 1164 - blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( 1165 - (char *)dep - (char *)hdr)); 1166 - offset = dp->d_ops->data_first_offset; 1177 + blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(offset)); 1178 + offset += xfs_dir2_data_entsize(mp, dep->namelen); 1179 + 1167 1180 /* 1168 1181 * Loop over existing entries, stuff them in. 1169 1182 */ ··· 1174 1183 sfep = NULL; 1175 1184 else 1176 1185 sfep = xfs_dir2_sf_firstentry(sfp); 1186 + 1177 1187 /* 1178 1188 * Need to preserve the existing offset values in the sf directory. 1179 1189 * Insert holes (unused entries) where necessary. ··· 1191 1199 * There should be a hole here, make one. 1192 1200 */ 1193 1201 if (offset < newoffset) { 1194 - dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); 1202 + dup = bp->b_addr + offset; 1195 1203 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 1196 1204 dup->length = cpu_to_be16(newoffset - offset); 1197 - *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( 1198 - ((char *)dup - (char *)hdr)); 1205 + *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(offset); 1199 1206 xfs_dir2_data_log_unused(args, bp, dup); 1200 1207 xfs_dir2_data_freeinsert(hdr, 1201 - dp->d_ops->data_bestfree_p(hdr), 1202 - dup, &dummy); 1208 + xfs_dir2_data_bestfree_p(mp, hdr), 1209 + dup, &dummy); 1203 1210 offset += be16_to_cpu(dup->length); 1204 1211 continue; 1205 1212 } 1206 1213 /* 1207 1214 * Copy a real entry. 1208 1215 */ 1209 - dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset); 1210 - dep->inumber = cpu_to_be64(dp->d_ops->sf_get_ino(sfp, sfep)); 1216 + dep = bp->b_addr + newoffset; 1217 + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_ino(mp, sfp, sfep)); 1211 1218 dep->namelen = sfep->namelen; 1212 - dp->d_ops->data_put_ftype(dep, dp->d_ops->sf_get_ftype(sfep)); 1219 + xfs_dir2_data_put_ftype(mp, dep, 1220 + xfs_dir2_sf_get_ftype(mp, sfep)); 1213 1221 memcpy(dep->name, sfep->name, dep->namelen); 1214 - tagp = dp->d_ops->data_entry_tag_p(dep); 1215 - *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1222 + tagp = xfs_dir2_data_entry_tag_p(mp, dep); 1223 + *tagp = cpu_to_be16(newoffset); 1216 1224 xfs_dir2_data_log_entry(args, bp, dep); 1217 1225 name.name = sfep->name; 1218 1226 name.len = sfep->namelen; 1219 - blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> 1220 - hashname(&name)); 1221 - blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( 1222 - (char *)dep - (char *)hdr)); 1227 + blp[2 + i].hashval = cpu_to_be32(xfs_dir2_hashname(mp, &name)); 1228 + blp[2 + i].address = 1229 + cpu_to_be32(xfs_dir2_byte_to_dataptr(newoffset)); 1223 1230 offset = (int)((char *)(tagp + 1) - (char *)hdr); 1224 1231 if (++i == sfp->count) 1225 1232 sfep = NULL; 1226 1233 else 1227 - sfep = dp->d_ops->sf_nextentry(sfp, sfep); 1234 + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 1228 1235 } 1229 1236 /* Done with the temporary buffer */ 1230 1237 kmem_free(sfp);
+154 -126
fs/xfs/libxfs/xfs_dir2_data.c
··· 13 13 #include "xfs_mount.h" 14 14 #include "xfs_inode.h" 15 15 #include "xfs_dir2.h" 16 + #include "xfs_dir2_priv.h" 16 17 #include "xfs_error.h" 17 18 #include "xfs_trans.h" 18 19 #include "xfs_buf_item.h" ··· 23 22 struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf, 24 23 struct xfs_dir2_data_unused *dup, 25 24 struct xfs_dir2_data_free **bf_ent); 25 + 26 + struct xfs_dir2_data_free * 27 + xfs_dir2_data_bestfree_p( 28 + struct xfs_mount *mp, 29 + struct xfs_dir2_data_hdr *hdr) 30 + { 31 + if (xfs_sb_version_hascrc(&mp->m_sb)) 32 + return ((struct xfs_dir3_data_hdr *)hdr)->best_free; 33 + return hdr->bestfree; 34 + } 35 + 36 + /* 37 + * Pointer to an entry's tag word. 38 + */ 39 + __be16 * 40 + xfs_dir2_data_entry_tag_p( 41 + struct xfs_mount *mp, 42 + struct xfs_dir2_data_entry *dep) 43 + { 44 + return (__be16 *)((char *)dep + 45 + xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16)); 46 + } 47 + 48 + uint8_t 49 + xfs_dir2_data_get_ftype( 50 + struct xfs_mount *mp, 51 + struct xfs_dir2_data_entry *dep) 52 + { 53 + if (xfs_sb_version_hasftype(&mp->m_sb)) { 54 + uint8_t ftype = dep->name[dep->namelen]; 55 + 56 + if (likely(ftype < XFS_DIR3_FT_MAX)) 57 + return ftype; 58 + } 59 + 60 + return XFS_DIR3_FT_UNKNOWN; 61 + } 62 + 63 + void 64 + xfs_dir2_data_put_ftype( 65 + struct xfs_mount *mp, 66 + struct xfs_dir2_data_entry *dep, 67 + uint8_t ftype) 68 + { 69 + ASSERT(ftype < XFS_DIR3_FT_MAX); 70 + ASSERT(dep->namelen != 0); 71 + 72 + if (xfs_sb_version_hasftype(&mp->m_sb)) 73 + dep->name[dep->namelen] = ftype; 74 + } 75 + 76 + /* 77 + * The number of leaf entries is limited by the size of the block and the amount 78 + * of space used by the data entries. We don't know how much space is used by 79 + * the data entries yet, so just ensure that the count falls somewhere inside 80 + * the block right now. 81 + */ 82 + static inline unsigned int 83 + xfs_dir2_data_max_leaf_entries( 84 + struct xfs_da_geometry *geo) 85 + { 86 + return (geo->blksize - sizeof(struct xfs_dir2_block_tail) - 87 + geo->data_entry_offset) / 88 + sizeof(struct xfs_dir2_leaf_entry); 89 + } 26 90 27 91 /* 28 92 * Check the consistency of the data block. ··· 104 38 xfs_dir2_block_tail_t *btp=NULL; /* block tail */ 105 39 int count; /* count of entries found */ 106 40 xfs_dir2_data_hdr_t *hdr; /* data block header */ 107 - xfs_dir2_data_entry_t *dep; /* data entry */ 108 41 xfs_dir2_data_free_t *dfp; /* bestfree entry */ 109 - xfs_dir2_data_unused_t *dup; /* unused entry */ 110 - char *endp; /* end of useful data */ 111 42 int freeseen; /* mask of bestfrees seen */ 112 43 xfs_dahash_t hash; /* hash of current name */ 113 44 int i; /* leaf index */ 114 45 int lastfree; /* last entry was unused */ 115 46 xfs_dir2_leaf_entry_t *lep=NULL; /* block leaf entries */ 116 47 struct xfs_mount *mp = bp->b_mount; 117 - char *p; /* current data position */ 118 48 int stale; /* count of stale leaves */ 119 49 struct xfs_name name; 120 - const struct xfs_dir_ops *ops; 121 - struct xfs_da_geometry *geo; 122 - 123 - geo = mp->m_dir_geo; 124 - 125 - /* 126 - * We can be passed a null dp here from a verifier, so we need to go the 127 - * hard way to get them. 128 - */ 129 - ops = xfs_dir_get_ops(mp, dp); 50 + unsigned int offset; 51 + unsigned int end; 52 + struct xfs_da_geometry *geo = mp->m_dir_geo; 130 53 131 54 /* 132 - * If this isn't a directory, or we don't get handed the dir ops, 133 - * something is seriously wrong. Bail out. 55 + * If this isn't a directory, something is seriously wrong. Bail out. 134 56 */ 135 - if ((dp && !S_ISDIR(VFS_I(dp)->i_mode)) || 136 - ops != xfs_dir_get_ops(mp, NULL)) 57 + if (dp && !S_ISDIR(VFS_I(dp)->i_mode)) 137 58 return __this_address; 138 59 139 60 hdr = bp->b_addr; 140 - p = (char *)ops->data_entry_p(hdr); 61 + offset = geo->data_entry_offset; 141 62 142 63 switch (hdr->magic) { 143 64 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): ··· 132 79 btp = xfs_dir2_block_tail_p(geo, hdr); 133 80 lep = xfs_dir2_block_leaf_p(btp); 134 81 135 - /* 136 - * The number of leaf entries is limited by the size of the 137 - * block and the amount of space used by the data entries. 138 - * We don't know how much space is used by the data entries yet, 139 - * so just ensure that the count falls somewhere inside the 140 - * block right now. 141 - */ 142 82 if (be32_to_cpu(btp->count) >= 143 - ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry)) 83 + xfs_dir2_data_max_leaf_entries(geo)) 144 84 return __this_address; 145 85 break; 146 86 case cpu_to_be32(XFS_DIR3_DATA_MAGIC): ··· 142 96 default: 143 97 return __this_address; 144 98 } 145 - endp = xfs_dir3_data_endp(geo, hdr); 146 - if (!endp) 99 + end = xfs_dir3_data_end_offset(geo, hdr); 100 + if (!end) 147 101 return __this_address; 148 102 149 103 /* 150 104 * Account for zero bestfree entries. 151 105 */ 152 - bf = ops->data_bestfree_p(hdr); 106 + bf = xfs_dir2_data_bestfree_p(mp, hdr); 153 107 count = lastfree = freeseen = 0; 154 108 if (!bf[0].length) { 155 109 if (bf[0].offset) ··· 174 128 /* 175 129 * Loop over the data/unused entries. 176 130 */ 177 - while (p < endp) { 178 - dup = (xfs_dir2_data_unused_t *)p; 131 + while (offset < end) { 132 + struct xfs_dir2_data_unused *dup = bp->b_addr + offset; 133 + struct xfs_dir2_data_entry *dep = bp->b_addr + offset; 134 + 179 135 /* 180 136 * If it's unused, look for the space in the bestfree table. 181 137 * If we find it, account for that, else make sure it ··· 188 140 189 141 if (lastfree != 0) 190 142 return __this_address; 191 - if (endp < p + be16_to_cpu(dup->length)) 143 + if (offset + be16_to_cpu(dup->length) > end) 192 144 return __this_address; 193 145 if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) != 194 - (char *)dup - (char *)hdr) 146 + offset) 195 147 return __this_address; 196 148 fa = xfs_dir2_data_freefind_verify(hdr, bf, dup, &dfp); 197 149 if (fa) ··· 206 158 be16_to_cpu(bf[2].length)) 207 159 return __this_address; 208 160 } 209 - p += be16_to_cpu(dup->length); 161 + offset += be16_to_cpu(dup->length); 210 162 lastfree = 1; 211 163 continue; 212 164 } ··· 216 168 * in the leaf section of the block. 217 169 * The linear search is crude but this is DEBUG code. 218 170 */ 219 - dep = (xfs_dir2_data_entry_t *)p; 220 171 if (dep->namelen == 0) 221 172 return __this_address; 222 173 if (xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))) 223 174 return __this_address; 224 - if (endp < p + ops->data_entsize(dep->namelen)) 175 + if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end) 225 176 return __this_address; 226 - if (be16_to_cpu(*ops->data_entry_tag_p(dep)) != 227 - (char *)dep - (char *)hdr) 177 + if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset) 228 178 return __this_address; 229 - if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX) 179 + if (xfs_dir2_data_get_ftype(mp, dep) >= XFS_DIR3_FT_MAX) 230 180 return __this_address; 231 181 count++; 232 182 lastfree = 0; ··· 235 189 ((char *)dep - (char *)hdr)); 236 190 name.name = dep->name; 237 191 name.len = dep->namelen; 238 - hash = mp->m_dirnameops->hashname(&name); 192 + hash = xfs_dir2_hashname(mp, &name); 239 193 for (i = 0; i < be32_to_cpu(btp->count); i++) { 240 194 if (be32_to_cpu(lep[i].address) == addr && 241 195 be32_to_cpu(lep[i].hashval) == hash) ··· 244 198 if (i >= be32_to_cpu(btp->count)) 245 199 return __this_address; 246 200 } 247 - p += ops->data_entsize(dep->namelen); 201 + offset += xfs_dir2_data_entsize(mp, dep->namelen); 248 202 } 249 203 /* 250 204 * Need to have seen all the entries and all the bestfree slots. ··· 400 354 struct xfs_trans *tp, 401 355 struct xfs_inode *dp, 402 356 xfs_dablk_t bno, 403 - xfs_daddr_t mapped_bno, 357 + unsigned int flags, 404 358 struct xfs_buf **bpp) 405 359 { 406 360 int err; 407 361 408 - err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, 409 - XFS_DATA_FORK, &xfs_dir3_data_buf_ops); 362 + err = xfs_da_read_buf(tp, dp, bno, flags, bpp, XFS_DATA_FORK, 363 + &xfs_dir3_data_buf_ops); 410 364 if (!err && tp && *bpp) 411 365 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF); 412 366 return err; ··· 416 370 xfs_dir3_data_readahead( 417 371 struct xfs_inode *dp, 418 372 xfs_dablk_t bno, 419 - xfs_daddr_t mapped_bno) 373 + unsigned int flags) 420 374 { 421 - return xfs_da_reada_buf(dp, bno, mapped_bno, 422 - XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops); 375 + return xfs_da_reada_buf(dp, bno, flags, XFS_DATA_FORK, 376 + &xfs_dir3_data_reada_buf_ops); 423 377 } 424 378 425 379 /* ··· 607 561 * Given a data block, reconstruct its bestfree map. 608 562 */ 609 563 void 610 - xfs_dir2_data_freescan_int( 611 - struct xfs_da_geometry *geo, 612 - const struct xfs_dir_ops *ops, 613 - struct xfs_dir2_data_hdr *hdr, 614 - int *loghead) 564 + xfs_dir2_data_freescan( 565 + struct xfs_mount *mp, 566 + struct xfs_dir2_data_hdr *hdr, 567 + int *loghead) 615 568 { 616 - xfs_dir2_data_entry_t *dep; /* active data entry */ 617 - xfs_dir2_data_unused_t *dup; /* unused data entry */ 618 - struct xfs_dir2_data_free *bf; 619 - char *endp; /* end of block's data */ 620 - char *p; /* current entry pointer */ 569 + struct xfs_da_geometry *geo = mp->m_dir_geo; 570 + struct xfs_dir2_data_free *bf = xfs_dir2_data_bestfree_p(mp, hdr); 571 + void *addr = hdr; 572 + unsigned int offset = geo->data_entry_offset; 573 + unsigned int end; 621 574 622 575 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 623 576 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || ··· 626 581 /* 627 582 * Start by clearing the table. 628 583 */ 629 - bf = ops->data_bestfree_p(hdr); 630 584 memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT); 631 585 *loghead = 1; 632 - /* 633 - * Set up pointers. 634 - */ 635 - p = (char *)ops->data_entry_p(hdr); 636 - endp = xfs_dir3_data_endp(geo, hdr); 637 - /* 638 - * Loop over the block's entries. 639 - */ 640 - while (p < endp) { 641 - dup = (xfs_dir2_data_unused_t *)p; 586 + 587 + end = xfs_dir3_data_end_offset(geo, addr); 588 + while (offset < end) { 589 + struct xfs_dir2_data_unused *dup = addr + offset; 590 + struct xfs_dir2_data_entry *dep = addr + offset; 591 + 642 592 /* 643 593 * If it's a free entry, insert it. 644 594 */ 645 595 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 646 - ASSERT((char *)dup - (char *)hdr == 596 + ASSERT(offset == 647 597 be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); 648 598 xfs_dir2_data_freeinsert(hdr, bf, dup, loghead); 649 - p += be16_to_cpu(dup->length); 599 + offset += be16_to_cpu(dup->length); 600 + continue; 650 601 } 602 + 651 603 /* 652 604 * For active entries, check their tags and skip them. 653 605 */ 654 - else { 655 - dep = (xfs_dir2_data_entry_t *)p; 656 - ASSERT((char *)dep - (char *)hdr == 657 - be16_to_cpu(*ops->data_entry_tag_p(dep))); 658 - p += ops->data_entsize(dep->namelen); 659 - } 606 + ASSERT(offset == 607 + be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep))); 608 + offset += xfs_dir2_data_entsize(mp, dep->namelen); 660 609 } 661 - } 662 - 663 - void 664 - xfs_dir2_data_freescan( 665 - struct xfs_inode *dp, 666 - struct xfs_dir2_data_hdr *hdr, 667 - int *loghead) 668 - { 669 - return xfs_dir2_data_freescan_int(dp->i_mount->m_dir_geo, dp->d_ops, 670 - hdr, loghead); 671 610 } 672 611 673 612 /* ··· 660 631 */ 661 632 int /* error */ 662 633 xfs_dir3_data_init( 663 - xfs_da_args_t *args, /* directory operation args */ 664 - xfs_dir2_db_t blkno, /* logical dir block number */ 665 - struct xfs_buf **bpp) /* output block buffer */ 634 + struct xfs_da_args *args, /* directory operation args */ 635 + xfs_dir2_db_t blkno, /* logical dir block number */ 636 + struct xfs_buf **bpp) /* output block buffer */ 666 637 { 667 - struct xfs_buf *bp; /* block buffer */ 668 - xfs_dir2_data_hdr_t *hdr; /* data block header */ 669 - xfs_inode_t *dp; /* incore directory inode */ 670 - xfs_dir2_data_unused_t *dup; /* unused entry pointer */ 671 - struct xfs_dir2_data_free *bf; 672 - int error; /* error return value */ 673 - int i; /* bestfree index */ 674 - xfs_mount_t *mp; /* filesystem mount point */ 675 - xfs_trans_t *tp; /* transaction pointer */ 676 - int t; /* temp */ 638 + struct xfs_trans *tp = args->trans; 639 + struct xfs_inode *dp = args->dp; 640 + struct xfs_mount *mp = dp->i_mount; 641 + struct xfs_da_geometry *geo = args->geo; 642 + struct xfs_buf *bp; 643 + struct xfs_dir2_data_hdr *hdr; 644 + struct xfs_dir2_data_unused *dup; 645 + struct xfs_dir2_data_free *bf; 646 + int error; 647 + int i; 677 648 678 - dp = args->dp; 679 - mp = dp->i_mount; 680 - tp = args->trans; 681 649 /* 682 650 * Get the buffer set up for the block. 683 651 */ 684 652 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno), 685 - -1, &bp, XFS_DATA_FORK); 653 + &bp, XFS_DATA_FORK); 686 654 if (error) 687 655 return error; 688 656 bp->b_ops = &xfs_dir3_data_buf_ops; ··· 701 675 } else 702 676 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 703 677 704 - bf = dp->d_ops->data_bestfree_p(hdr); 705 - bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset); 678 + bf = xfs_dir2_data_bestfree_p(mp, hdr); 679 + bf[0].offset = cpu_to_be16(geo->data_entry_offset); 680 + bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset); 706 681 for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { 707 682 bf[i].length = 0; 708 683 bf[i].offset = 0; ··· 712 685 /* 713 686 * Set up an unused entry for the block's body. 714 687 */ 715 - dup = dp->d_ops->data_unused_p(hdr); 688 + dup = bp->b_addr + geo->data_entry_offset; 716 689 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 717 - 718 - t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset; 719 - bf[0].length = cpu_to_be16(t); 720 - dup->length = cpu_to_be16(t); 690 + dup->length = bf[0].length; 721 691 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); 692 + 722 693 /* 723 694 * Log it and return it. 724 695 */ ··· 735 710 struct xfs_buf *bp, 736 711 xfs_dir2_data_entry_t *dep) /* data entry pointer */ 737 712 { 713 + struct xfs_mount *mp = bp->b_mount; 738 714 struct xfs_dir2_data_hdr *hdr = bp->b_addr; 739 715 740 716 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || ··· 744 718 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 745 719 746 720 xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr), 747 - (uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) - 721 + (uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) - 748 722 (char *)hdr - 1)); 749 723 } 750 724 ··· 765 739 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 766 740 #endif 767 741 768 - xfs_trans_log_buf(args->trans, bp, 0, 769 - args->dp->d_ops->data_entry_offset - 1); 742 + xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1); 770 743 } 771 744 772 745 /* ··· 814 789 { 815 790 xfs_dir2_data_hdr_t *hdr; /* data block pointer */ 816 791 xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 817 - char *endptr; /* end of data area */ 818 792 int needscan; /* need to regen bestfree */ 819 793 xfs_dir2_data_unused_t *newdup; /* new unused entry */ 820 794 xfs_dir2_data_unused_t *postdup; /* unused entry after us */ 821 795 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ 796 + unsigned int end; 822 797 struct xfs_dir2_data_free *bf; 823 798 824 799 hdr = bp->b_addr; ··· 826 801 /* 827 802 * Figure out where the end of the data area is. 828 803 */ 829 - endptr = xfs_dir3_data_endp(args->geo, hdr); 830 - ASSERT(endptr != NULL); 804 + end = xfs_dir3_data_end_offset(args->geo, hdr); 805 + ASSERT(end != 0); 831 806 832 807 /* 833 808 * If this isn't the start of the block, then back up to 834 809 * the previous entry and see if it's free. 835 810 */ 836 - if (offset > args->dp->d_ops->data_entry_offset) { 811 + if (offset > args->geo->data_entry_offset) { 837 812 __be16 *tagp; /* tag just before us */ 838 813 839 814 tagp = (__be16 *)((char *)hdr + offset) - 1; ··· 846 821 * If this isn't the end of the block, see if the entry after 847 822 * us is free. 848 823 */ 849 - if ((char *)hdr + offset + len < endptr) { 824 + if (offset + len < end) { 850 825 postdup = 851 826 (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); 852 827 if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG) ··· 859 834 * Previous and following entries are both free, 860 835 * merge everything into a single free entry. 861 836 */ 862 - bf = args->dp->d_ops->data_bestfree_p(hdr); 837 + bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr); 863 838 if (prevdup && postdup) { 864 839 xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ 865 840 ··· 1050 1025 * Look up the entry in the bestfree table. 1051 1026 */ 1052 1027 oldlen = be16_to_cpu(dup->length); 1053 - bf = args->dp->d_ops->data_bestfree_p(hdr); 1028 + bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr); 1054 1029 dfp = xfs_dir2_data_freefind(hdr, bf, dup); 1055 1030 ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length)); 1056 1031 /* ··· 1174 1149 } 1175 1150 1176 1151 /* Find the end of the entry data in a data/block format dir block. */ 1177 - void * 1178 - xfs_dir3_data_endp( 1152 + unsigned int 1153 + xfs_dir3_data_end_offset( 1179 1154 struct xfs_da_geometry *geo, 1180 1155 struct xfs_dir2_data_hdr *hdr) 1181 1156 { 1157 + void *p; 1158 + 1182 1159 switch (hdr->magic) { 1183 1160 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): 1184 1161 case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): 1185 - return xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr)); 1162 + p = xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr)); 1163 + return p - (void *)hdr; 1186 1164 case cpu_to_be32(XFS_DIR3_DATA_MAGIC): 1187 1165 case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 1188 - return (char *)hdr + geo->blksize; 1166 + return geo->blksize; 1189 1167 default: 1190 - return NULL; 1168 + return 0; 1191 1169 } 1192 1170 }
+171 -136
fs/xfs/libxfs/xfs_dir2_leaf.c
··· 24 24 * Local function declarations. 25 25 */ 26 26 static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, 27 - int *indexp, struct xfs_buf **dbpp); 27 + int *indexp, struct xfs_buf **dbpp, 28 + struct xfs_dir3_icleaf_hdr *leafhdr); 28 29 static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args, 29 30 struct xfs_buf *bp, int first, int last); 30 31 static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args, 31 32 struct xfs_buf *bp); 33 + 34 + void 35 + xfs_dir2_leaf_hdr_from_disk( 36 + struct xfs_mount *mp, 37 + struct xfs_dir3_icleaf_hdr *to, 38 + struct xfs_dir2_leaf *from) 39 + { 40 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 41 + struct xfs_dir3_leaf *from3 = (struct xfs_dir3_leaf *)from; 42 + 43 + to->forw = be32_to_cpu(from3->hdr.info.hdr.forw); 44 + to->back = be32_to_cpu(from3->hdr.info.hdr.back); 45 + to->magic = be16_to_cpu(from3->hdr.info.hdr.magic); 46 + to->count = be16_to_cpu(from3->hdr.count); 47 + to->stale = be16_to_cpu(from3->hdr.stale); 48 + to->ents = from3->__ents; 49 + 50 + ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || 51 + to->magic == XFS_DIR3_LEAFN_MAGIC); 52 + } else { 53 + to->forw = be32_to_cpu(from->hdr.info.forw); 54 + to->back = be32_to_cpu(from->hdr.info.back); 55 + to->magic = be16_to_cpu(from->hdr.info.magic); 56 + to->count = be16_to_cpu(from->hdr.count); 57 + to->stale = be16_to_cpu(from->hdr.stale); 58 + to->ents = from->__ents; 59 + 60 + ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || 61 + to->magic == XFS_DIR2_LEAFN_MAGIC); 62 + } 63 + } 64 + 65 + void 66 + xfs_dir2_leaf_hdr_to_disk( 67 + struct xfs_mount *mp, 68 + struct xfs_dir2_leaf *to, 69 + struct xfs_dir3_icleaf_hdr *from) 70 + { 71 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 72 + struct xfs_dir3_leaf *to3 = (struct xfs_dir3_leaf *)to; 73 + 74 + ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC || 75 + from->magic == XFS_DIR3_LEAFN_MAGIC); 76 + 77 + to3->hdr.info.hdr.forw = cpu_to_be32(from->forw); 78 + to3->hdr.info.hdr.back = cpu_to_be32(from->back); 79 + to3->hdr.info.hdr.magic = cpu_to_be16(from->magic); 80 + to3->hdr.count = cpu_to_be16(from->count); 81 + to3->hdr.stale = cpu_to_be16(from->stale); 82 + } else { 83 + ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || 84 + from->magic == XFS_DIR2_LEAFN_MAGIC); 85 + 86 + to->hdr.info.forw = cpu_to_be32(from->forw); 87 + to->hdr.info.back = cpu_to_be32(from->back); 88 + to->hdr.info.magic = cpu_to_be16(from->magic); 89 + to->hdr.count = cpu_to_be16(from->count); 90 + to->hdr.stale = cpu_to_be16(from->stale); 91 + } 92 + } 32 93 33 94 /* 34 95 * Check the internal consistency of a leaf1 block. ··· 104 43 struct xfs_dir2_leaf *leaf = bp->b_addr; 105 44 struct xfs_dir3_icleaf_hdr leafhdr; 106 45 107 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 46 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 108 47 109 48 if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) { 110 49 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; ··· 113 52 } else if (leafhdr.magic != XFS_DIR2_LEAF1_MAGIC) 114 53 return __this_address; 115 54 116 - return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf); 55 + return xfs_dir3_leaf_check_int(dp->i_mount, &leafhdr, leaf); 117 56 } 118 57 119 58 static inline void ··· 137 76 138 77 xfs_failaddr_t 139 78 xfs_dir3_leaf_check_int( 140 - struct xfs_mount *mp, 141 - struct xfs_inode *dp, 142 - struct xfs_dir3_icleaf_hdr *hdr, 143 - struct xfs_dir2_leaf *leaf) 79 + struct xfs_mount *mp, 80 + struct xfs_dir3_icleaf_hdr *hdr, 81 + struct xfs_dir2_leaf *leaf) 144 82 { 145 - struct xfs_dir2_leaf_entry *ents; 146 - xfs_dir2_leaf_tail_t *ltp; 147 - int stale; 148 - int i; 149 - const struct xfs_dir_ops *ops; 150 - struct xfs_dir3_icleaf_hdr leafhdr; 151 - struct xfs_da_geometry *geo = mp->m_dir_geo; 83 + struct xfs_da_geometry *geo = mp->m_dir_geo; 84 + xfs_dir2_leaf_tail_t *ltp; 85 + int stale; 86 + int i; 152 87 153 - /* 154 - * we can be passed a null dp here from a verifier, so we need to go the 155 - * hard way to get them. 156 - */ 157 - ops = xfs_dir_get_ops(mp, dp); 158 - 159 - if (!hdr) { 160 - ops->leaf_hdr_from_disk(&leafhdr, leaf); 161 - hdr = &leafhdr; 162 - } 163 - 164 - ents = ops->leaf_ents_p(leaf); 165 88 ltp = xfs_dir2_leaf_tail_p(geo, leaf); 166 89 167 90 /* ··· 153 108 * Should factor in the size of the bests table as well. 154 109 * We can deduce a value for that from di_size. 155 110 */ 156 - if (hdr->count > ops->leaf_max_ents(geo)) 111 + if (hdr->count > geo->leaf_max_ents) 157 112 return __this_address; 158 113 159 114 /* Leaves and bests don't overlap in leaf format. */ 160 115 if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC || 161 116 hdr->magic == XFS_DIR3_LEAF1_MAGIC) && 162 - (char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) 117 + (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) 163 118 return __this_address; 164 119 165 120 /* Check hash value order, count stale entries. */ 166 121 for (i = stale = 0; i < hdr->count; i++) { 167 122 if (i + 1 < hdr->count) { 168 - if (be32_to_cpu(ents[i].hashval) > 169 - be32_to_cpu(ents[i + 1].hashval)) 123 + if (be32_to_cpu(hdr->ents[i].hashval) > 124 + be32_to_cpu(hdr->ents[i + 1].hashval)) 170 125 return __this_address; 171 126 } 172 - if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 127 + if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 173 128 stale++; 174 129 } 175 130 if (hdr->stale != stale) ··· 184 139 */ 185 140 static xfs_failaddr_t 186 141 xfs_dir3_leaf_verify( 187 - struct xfs_buf *bp) 142 + struct xfs_buf *bp) 188 143 { 189 - struct xfs_mount *mp = bp->b_mount; 190 - struct xfs_dir2_leaf *leaf = bp->b_addr; 191 - xfs_failaddr_t fa; 144 + struct xfs_mount *mp = bp->b_mount; 145 + struct xfs_dir3_icleaf_hdr leafhdr; 146 + xfs_failaddr_t fa; 192 147 193 148 fa = xfs_da3_blkinfo_verify(bp, bp->b_addr); 194 149 if (fa) 195 150 return fa; 196 151 197 - return xfs_dir3_leaf_check_int(mp, NULL, NULL, leaf); 152 + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, bp->b_addr); 153 + return xfs_dir3_leaf_check_int(mp, &leafhdr, bp->b_addr); 198 154 } 199 155 200 156 static void ··· 262 216 struct xfs_trans *tp, 263 217 struct xfs_inode *dp, 264 218 xfs_dablk_t fbno, 265 - xfs_daddr_t mappedbno, 266 219 struct xfs_buf **bpp) 267 220 { 268 221 int err; 269 222 270 - err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 271 - XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops); 223 + err = xfs_da_read_buf(tp, dp, fbno, 0, bpp, XFS_DATA_FORK, 224 + &xfs_dir3_leaf1_buf_ops); 272 225 if (!err && tp && *bpp) 273 226 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAF1_BUF); 274 227 return err; ··· 278 233 struct xfs_trans *tp, 279 234 struct xfs_inode *dp, 280 235 xfs_dablk_t fbno, 281 - xfs_daddr_t mappedbno, 282 236 struct xfs_buf **bpp) 283 237 { 284 238 int err; 285 239 286 - err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 287 - XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops); 240 + err = xfs_da_read_buf(tp, dp, fbno, 0, bpp, XFS_DATA_FORK, 241 + &xfs_dir3_leafn_buf_ops); 288 242 if (!err && tp && *bpp) 289 243 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAFN_BUF); 290 244 return err; ··· 355 311 bno < xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET)); 356 312 357 313 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, bno), 358 - -1, &bp, XFS_DATA_FORK); 314 + &bp, XFS_DATA_FORK); 359 315 if (error) 360 316 return error; 361 317 ··· 390 346 int needscan; /* need to rescan bestfree */ 391 347 xfs_trans_t *tp; /* transaction pointer */ 392 348 struct xfs_dir2_data_free *bf; 393 - struct xfs_dir2_leaf_entry *ents; 394 349 struct xfs_dir3_icleaf_hdr leafhdr; 395 350 396 351 trace_xfs_dir2_block_to_leaf(args); ··· 418 375 xfs_dir3_data_check(dp, dbp); 419 376 btp = xfs_dir2_block_tail_p(args->geo, hdr); 420 377 blp = xfs_dir2_block_leaf_p(btp); 421 - bf = dp->d_ops->data_bestfree_p(hdr); 422 - ents = dp->d_ops->leaf_ents_p(leaf); 378 + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 423 379 424 380 /* 425 381 * Set the counts in the leaf header. 426 382 */ 427 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 383 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 428 384 leafhdr.count = be32_to_cpu(btp->count); 429 385 leafhdr.stale = be32_to_cpu(btp->stale); 430 - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 386 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); 431 387 xfs_dir3_leaf_log_header(args, lbp); 432 388 433 389 /* 434 390 * Could compact these but I think we always do the conversion 435 391 * after squeezing out stale entries. 436 392 */ 437 - memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); 438 - xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1); 393 + memcpy(leafhdr.ents, blp, 394 + be32_to_cpu(btp->count) * sizeof(struct xfs_dir2_leaf_entry)); 395 + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, 0, leafhdr.count - 1); 439 396 needscan = 0; 440 397 needlog = 1; 441 398 /* ··· 458 415 hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); 459 416 460 417 if (needscan) 461 - xfs_dir2_data_freescan(dp, hdr, &needlog); 418 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 462 419 /* 463 420 * Set up leaf tail and bests table. 464 421 */ ··· 637 594 638 595 trace_xfs_dir2_leaf_addname(args); 639 596 640 - error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp); 597 + error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, &lbp); 641 598 if (error) 642 599 return error; 643 600 ··· 650 607 index = xfs_dir2_leaf_search_hash(args, lbp); 651 608 leaf = lbp->b_addr; 652 609 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); 653 - ents = dp->d_ops->leaf_ents_p(leaf); 654 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 610 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 611 + ents = leafhdr.ents; 655 612 bestsp = xfs_dir2_leaf_bests_p(ltp); 656 - length = dp->d_ops->data_entsize(args->namelen); 613 + length = xfs_dir2_data_entsize(dp->i_mount, args->namelen); 657 614 658 615 /* 659 616 * See if there are any entries with the same hash value ··· 816 773 else 817 774 xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block); 818 775 hdr = dbp->b_addr; 819 - bf = dp->d_ops->data_bestfree_p(hdr); 776 + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 820 777 bestsp[use_block] = bf[0].length; 821 778 grown = 1; 822 779 } else { ··· 826 783 */ 827 784 error = xfs_dir3_data_read(tp, dp, 828 785 xfs_dir2_db_to_da(args->geo, use_block), 829 - -1, &dbp); 786 + 0, &dbp); 830 787 if (error) { 831 788 xfs_trans_brelse(tp, lbp); 832 789 return error; 833 790 } 834 791 hdr = dbp->b_addr; 835 - bf = dp->d_ops->data_bestfree_p(hdr); 792 + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 836 793 grown = 0; 837 794 } 838 795 /* ··· 858 815 dep->inumber = cpu_to_be64(args->inumber); 859 816 dep->namelen = args->namelen; 860 817 memcpy(dep->name, args->name, dep->namelen); 861 - dp->d_ops->data_put_ftype(dep, args->filetype); 862 - tagp = dp->d_ops->data_entry_tag_p(dep); 818 + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); 819 + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); 863 820 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 864 821 /* 865 822 * Need to scan fix up the bestfree table. 866 823 */ 867 824 if (needscan) 868 - xfs_dir2_data_freescan(dp, hdr, &needlog); 825 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 869 826 /* 870 827 * Need to log the data block's header. 871 828 */ ··· 895 852 /* 896 853 * Log the leaf fields and give up the buffers. 897 854 */ 898 - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 855 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); 899 856 xfs_dir3_leaf_log_header(args, lbp); 900 - xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh); 857 + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, lfloglow, lfloghigh); 901 858 xfs_dir3_leaf_check(dp, lbp); 902 859 xfs_dir3_data_check(dp, dbp); 903 860 return 0; ··· 917 874 xfs_dir2_leaf_t *leaf; /* leaf structure */ 918 875 int loglow; /* first leaf entry to log */ 919 876 int to; /* target leaf index */ 920 - struct xfs_dir2_leaf_entry *ents; 921 877 struct xfs_inode *dp = args->dp; 922 878 923 879 leaf = bp->b_addr; ··· 926 884 /* 927 885 * Compress out the stale entries in place. 928 886 */ 929 - ents = dp->d_ops->leaf_ents_p(leaf); 930 887 for (from = to = 0, loglow = -1; from < leafhdr->count; from++) { 931 - if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 888 + if (leafhdr->ents[from].address == 889 + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 932 890 continue; 933 891 /* 934 892 * Only actually copy the entries that are different. ··· 936 894 if (from > to) { 937 895 if (loglow == -1) 938 896 loglow = to; 939 - ents[to] = ents[from]; 897 + leafhdr->ents[to] = leafhdr->ents[from]; 940 898 } 941 899 to++; 942 900 } ··· 947 905 leafhdr->count -= leafhdr->stale; 948 906 leafhdr->stale = 0; 949 907 950 - dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr); 908 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, leafhdr); 951 909 xfs_dir3_leaf_log_header(args, bp); 952 910 if (loglow != -1) 953 - xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1); 911 + xfs_dir3_leaf_log_ents(args, leafhdr, bp, loglow, to - 1); 954 912 } 955 913 956 914 /* ··· 1079 1037 void 1080 1038 xfs_dir3_leaf_log_ents( 1081 1039 struct xfs_da_args *args, 1040 + struct xfs_dir3_icleaf_hdr *hdr, 1082 1041 struct xfs_buf *bp, 1083 1042 int first, 1084 1043 int last) ··· 1087 1044 xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ 1088 1045 xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ 1089 1046 struct xfs_dir2_leaf *leaf = bp->b_addr; 1090 - struct xfs_dir2_leaf_entry *ents; 1091 1047 1092 1048 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || 1093 1049 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || 1094 1050 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1095 1051 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); 1096 1052 1097 - ents = args->dp->d_ops->leaf_ents_p(leaf); 1098 - firstlep = &ents[first]; 1099 - lastlep = &ents[last]; 1053 + firstlep = &hdr->ents[first]; 1054 + lastlep = &hdr->ents[last]; 1100 1055 xfs_trans_log_buf(args->trans, bp, 1101 1056 (uint)((char *)firstlep - (char *)leaf), 1102 1057 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); ··· 1117 1076 1118 1077 xfs_trans_log_buf(args->trans, bp, 1119 1078 (uint)((char *)&leaf->hdr - (char *)leaf), 1120 - args->dp->d_ops->leaf_hdr_size - 1); 1079 + args->geo->leaf_hdr_size - 1); 1121 1080 } 1122 1081 1123 1082 /* ··· 1156 1115 int error; /* error return code */ 1157 1116 int index; /* found entry index */ 1158 1117 struct xfs_buf *lbp; /* leaf buffer */ 1159 - xfs_dir2_leaf_t *leaf; /* leaf structure */ 1160 1118 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1161 1119 xfs_trans_t *tp; /* transaction pointer */ 1162 - struct xfs_dir2_leaf_entry *ents; 1120 + struct xfs_dir3_icleaf_hdr leafhdr; 1163 1121 1164 1122 trace_xfs_dir2_leaf_lookup(args); 1165 1123 1166 1124 /* 1167 1125 * Look up name in the leaf block, returning both buffers and index. 1168 1126 */ 1169 - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1127 + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); 1128 + if (error) 1170 1129 return error; 1171 - } 1130 + 1172 1131 tp = args->trans; 1173 1132 dp = args->dp; 1174 1133 xfs_dir3_leaf_check(dp, lbp); 1175 - leaf = lbp->b_addr; 1176 - ents = dp->d_ops->leaf_ents_p(leaf); 1134 + 1177 1135 /* 1178 1136 * Get to the leaf entry and contained data entry address. 1179 1137 */ 1180 - lep = &ents[index]; 1138 + lep = &leafhdr.ents[index]; 1181 1139 1182 1140 /* 1183 1141 * Point to the data entry. ··· 1188 1148 * Return the found inode number & CI name if appropriate 1189 1149 */ 1190 1150 args->inumber = be64_to_cpu(dep->inumber); 1191 - args->filetype = dp->d_ops->data_get_ftype(dep); 1151 + args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); 1192 1152 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); 1193 1153 xfs_trans_brelse(tp, dbp); 1194 1154 xfs_trans_brelse(tp, lbp); ··· 1206 1166 xfs_da_args_t *args, /* operation arguments */ 1207 1167 struct xfs_buf **lbpp, /* out: leaf buffer */ 1208 1168 int *indexp, /* out: index in leaf block */ 1209 - struct xfs_buf **dbpp) /* out: data buffer */ 1169 + struct xfs_buf **dbpp, /* out: data buffer */ 1170 + struct xfs_dir3_icleaf_hdr *leafhdr) 1210 1171 { 1211 1172 xfs_dir2_db_t curdb = -1; /* current data block number */ 1212 1173 struct xfs_buf *dbp = NULL; /* data buffer */ ··· 1223 1182 xfs_trans_t *tp; /* transaction pointer */ 1224 1183 xfs_dir2_db_t cidb = -1; /* case match data block no. */ 1225 1184 enum xfs_dacmp cmp; /* name compare result */ 1226 - struct xfs_dir2_leaf_entry *ents; 1227 - struct xfs_dir3_icleaf_hdr leafhdr; 1228 1185 1229 1186 dp = args->dp; 1230 1187 tp = args->trans; 1231 1188 mp = dp->i_mount; 1232 1189 1233 - error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp); 1190 + error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, &lbp); 1234 1191 if (error) 1235 1192 return error; 1236 1193 1237 1194 *lbpp = lbp; 1238 1195 leaf = lbp->b_addr; 1239 1196 xfs_dir3_leaf_check(dp, lbp); 1240 - ents = dp->d_ops->leaf_ents_p(leaf); 1241 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 1197 + xfs_dir2_leaf_hdr_from_disk(mp, leafhdr, leaf); 1242 1198 1243 1199 /* 1244 1200 * Look for the first leaf entry with our hash value. ··· 1245 1207 * Loop over all the entries with the right hash value 1246 1208 * looking to match the name. 1247 1209 */ 1248 - for (lep = &ents[index]; 1249 - index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; 1210 + for (lep = &leafhdr->ents[index]; 1211 + index < leafhdr->count && 1212 + be32_to_cpu(lep->hashval) == args->hashval; 1250 1213 lep++, index++) { 1251 1214 /* 1252 1215 * Skip over stale leaf entries. ··· 1268 1229 xfs_trans_brelse(tp, dbp); 1269 1230 error = xfs_dir3_data_read(tp, dp, 1270 1231 xfs_dir2_db_to_da(args->geo, newdb), 1271 - -1, &dbp); 1232 + 0, &dbp); 1272 1233 if (error) { 1273 1234 xfs_trans_brelse(tp, lbp); 1274 1235 return error; ··· 1286 1247 * and buffer. If it's the first case-insensitive match, store 1287 1248 * the index and buffer and continue looking for an exact match. 1288 1249 */ 1289 - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); 1250 + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); 1290 1251 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 1291 1252 args->cmpresult = cmp; 1292 1253 *indexp = index; ··· 1310 1271 xfs_trans_brelse(tp, dbp); 1311 1272 error = xfs_dir3_data_read(tp, dp, 1312 1273 xfs_dir2_db_to_da(args->geo, cidb), 1313 - -1, &dbp); 1274 + 0, &dbp); 1314 1275 if (error) { 1315 1276 xfs_trans_brelse(tp, lbp); 1316 1277 return error; ··· 1336 1297 xfs_dir2_leaf_removename( 1337 1298 xfs_da_args_t *args) /* operation arguments */ 1338 1299 { 1300 + struct xfs_da_geometry *geo = args->geo; 1339 1301 __be16 *bestsp; /* leaf block best freespace */ 1340 1302 xfs_dir2_data_hdr_t *hdr; /* data block header */ 1341 1303 xfs_dir2_db_t db; /* data block number */ ··· 1354 1314 int needscan; /* need to rescan data frees */ 1355 1315 xfs_dir2_data_off_t oldbest; /* old value of best free */ 1356 1316 struct xfs_dir2_data_free *bf; /* bestfree table */ 1357 - struct xfs_dir2_leaf_entry *ents; 1358 1317 struct xfs_dir3_icleaf_hdr leafhdr; 1359 1318 1360 1319 trace_xfs_dir2_leaf_removename(args); ··· 1361 1322 /* 1362 1323 * Lookup the leaf entry, get the leaf and data blocks read in. 1363 1324 */ 1364 - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1325 + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); 1326 + if (error) 1365 1327 return error; 1366 - } 1328 + 1367 1329 dp = args->dp; 1368 1330 leaf = lbp->b_addr; 1369 1331 hdr = dbp->b_addr; 1370 1332 xfs_dir3_data_check(dp, dbp); 1371 - bf = dp->d_ops->data_bestfree_p(hdr); 1372 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 1373 - ents = dp->d_ops->leaf_ents_p(leaf); 1333 + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 1334 + 1374 1335 /* 1375 1336 * Point to the leaf entry, use that to point to the data entry. 1376 1337 */ 1377 - lep = &ents[index]; 1378 - db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); 1338 + lep = &leafhdr.ents[index]; 1339 + db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address)); 1379 1340 dep = (xfs_dir2_data_entry_t *)((char *)hdr + 1380 - xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); 1341 + xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address))); 1381 1342 needscan = needlog = 0; 1382 1343 oldbest = be16_to_cpu(bf[0].length); 1383 - ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); 1344 + ltp = xfs_dir2_leaf_tail_p(geo, leaf); 1384 1345 bestsp = xfs_dir2_leaf_bests_p(ltp); 1385 - if (be16_to_cpu(bestsp[db]) != oldbest) 1346 + if (be16_to_cpu(bestsp[db]) != oldbest) { 1347 + xfs_buf_corruption_error(lbp); 1386 1348 return -EFSCORRUPTED; 1349 + } 1387 1350 /* 1388 1351 * Mark the former data entry unused. 1389 1352 */ 1390 1353 xfs_dir2_data_make_free(args, dbp, 1391 1354 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), 1392 - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); 1355 + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, 1356 + &needscan); 1393 1357 /* 1394 1358 * We just mark the leaf entry stale by putting a null in it. 1395 1359 */ 1396 1360 leafhdr.stale++; 1397 - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 1361 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); 1398 1362 xfs_dir3_leaf_log_header(args, lbp); 1399 1363 1400 1364 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1401 - xfs_dir3_leaf_log_ents(args, lbp, index, index); 1365 + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, index, index); 1402 1366 1403 1367 /* 1404 1368 * Scan the freespace in the data block again if necessary, 1405 1369 * log the data block header if necessary. 1406 1370 */ 1407 1371 if (needscan) 1408 - xfs_dir2_data_freescan(dp, hdr, &needlog); 1372 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 1409 1373 if (needlog) 1410 1374 xfs_dir2_data_log_header(args, dbp); 1411 1375 /* ··· 1424 1382 * If the data block is now empty then get rid of the data block. 1425 1383 */ 1426 1384 if (be16_to_cpu(bf[0].length) == 1427 - args->geo->blksize - dp->d_ops->data_entry_offset) { 1428 - ASSERT(db != args->geo->datablk); 1385 + geo->blksize - geo->data_entry_offset) { 1386 + ASSERT(db != geo->datablk); 1429 1387 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1430 1388 /* 1431 1389 * Nope, can't get rid of it because it caused ··· 1467 1425 /* 1468 1426 * If the data block was not the first one, drop it. 1469 1427 */ 1470 - else if (db != args->geo->datablk) 1428 + else if (db != geo->datablk) 1471 1429 dbp = NULL; 1472 1430 1473 1431 xfs_dir3_leaf_check(dp, lbp); ··· 1490 1448 int error; /* error return code */ 1491 1449 int index; /* index of leaf entry */ 1492 1450 struct xfs_buf *lbp; /* leaf buffer */ 1493 - xfs_dir2_leaf_t *leaf; /* leaf structure */ 1494 1451 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1495 1452 xfs_trans_t *tp; /* transaction pointer */ 1496 - struct xfs_dir2_leaf_entry *ents; 1453 + struct xfs_dir3_icleaf_hdr leafhdr; 1497 1454 1498 1455 trace_xfs_dir2_leaf_replace(args); 1499 1456 1500 1457 /* 1501 1458 * Look up the entry. 1502 1459 */ 1503 - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { 1460 + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); 1461 + if (error) 1504 1462 return error; 1505 - } 1463 + 1506 1464 dp = args->dp; 1507 - leaf = lbp->b_addr; 1508 - ents = dp->d_ops->leaf_ents_p(leaf); 1509 1465 /* 1510 1466 * Point to the leaf entry, get data address from it. 1511 1467 */ 1512 - lep = &ents[index]; 1468 + lep = &leafhdr.ents[index]; 1513 1469 /* 1514 1470 * Point to the data entry. 1515 1471 */ ··· 1519 1479 * Put the new inode number in, log it. 1520 1480 */ 1521 1481 dep->inumber = cpu_to_be64(args->inumber); 1522 - dp->d_ops->data_put_ftype(dep, args->filetype); 1482 + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); 1523 1483 tp = args->trans; 1524 1484 xfs_dir2_data_log_entry(args, dbp, dep); 1525 1485 xfs_dir3_leaf_check(dp, lbp); ··· 1541 1501 xfs_dahash_t hashwant; /* hash value looking for */ 1542 1502 int high; /* high leaf index */ 1543 1503 int low; /* low leaf index */ 1544 - xfs_dir2_leaf_t *leaf; /* leaf structure */ 1545 1504 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1546 1505 int mid=0; /* current leaf index */ 1547 - struct xfs_dir2_leaf_entry *ents; 1548 1506 struct xfs_dir3_icleaf_hdr leafhdr; 1549 1507 1550 - leaf = lbp->b_addr; 1551 - ents = args->dp->d_ops->leaf_ents_p(leaf); 1552 - args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 1508 + xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, lbp->b_addr); 1553 1509 1554 1510 /* 1555 1511 * Note, the table cannot be empty, so we have to go through the loop. 1556 1512 * Binary search the leaf entries looking for our hash value. 1557 1513 */ 1558 - for (lep = ents, low = 0, high = leafhdr.count - 1, 1514 + for (lep = leafhdr.ents, low = 0, high = leafhdr.count - 1, 1559 1515 hashwant = args->hashval; 1560 1516 low <= high; ) { 1561 1517 mid = (low + high) >> 1; ··· 1588 1552 struct xfs_buf *lbp, /* leaf buffer */ 1589 1553 xfs_dir2_db_t db) /* data block number */ 1590 1554 { 1555 + struct xfs_da_geometry *geo = args->geo; 1591 1556 __be16 *bestsp; /* leaf bests table */ 1592 1557 struct xfs_buf *dbp; /* data block buffer */ 1593 1558 xfs_inode_t *dp; /* incore directory inode */ ··· 1602 1565 /* 1603 1566 * Read the offending data block. We need its buffer. 1604 1567 */ 1605 - error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db), 1606 - -1, &dbp); 1568 + error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), 0, &dbp); 1607 1569 if (error) 1608 1570 return error; 1609 1571 1610 1572 leaf = lbp->b_addr; 1611 - ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); 1573 + ltp = xfs_dir2_leaf_tail_p(geo, leaf); 1612 1574 1613 1575 #ifdef DEBUG 1614 1576 { 1615 1577 struct xfs_dir2_data_hdr *hdr = dbp->b_addr; 1616 - struct xfs_dir2_data_free *bf = dp->d_ops->data_bestfree_p(hdr); 1578 + struct xfs_dir2_data_free *bf = 1579 + xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 1617 1580 1618 1581 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 1619 1582 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); 1620 1583 ASSERT(be16_to_cpu(bf[0].length) == 1621 - args->geo->blksize - dp->d_ops->data_entry_offset); 1584 + geo->blksize - geo->data_entry_offset); 1622 1585 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); 1623 1586 } 1624 1587 #endif ··· 1676 1639 int error; /* error return code */ 1677 1640 struct xfs_buf *fbp; /* buffer for freespace block */ 1678 1641 xfs_fileoff_t fo; /* freespace file offset */ 1679 - xfs_dir2_free_t *free; /* freespace structure */ 1680 1642 struct xfs_buf *lbp; /* buffer for leaf block */ 1681 1643 xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ 1682 1644 xfs_dir2_leaf_t *leaf; /* leaf structure */ ··· 1733 1697 return 0; 1734 1698 lbp = state->path.blk[0].bp; 1735 1699 leaf = lbp->b_addr; 1736 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 1700 + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); 1737 1701 1738 1702 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || 1739 1703 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); ··· 1744 1708 error = xfs_dir2_free_read(tp, dp, args->geo->freeblk, &fbp); 1745 1709 if (error) 1746 1710 return error; 1747 - free = fbp->b_addr; 1748 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 1711 + xfs_dir2_free_hdr_from_disk(mp, &freehdr, fbp->b_addr); 1749 1712 1750 1713 ASSERT(!freehdr.firstdb); 1751 1714 ··· 1778 1743 /* 1779 1744 * Set up the leaf bests table. 1780 1745 */ 1781 - memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free), 1746 + memcpy(xfs_dir2_leaf_bests_p(ltp), freehdr.bests, 1782 1747 freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); 1783 1748 1784 - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 1749 + xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr); 1785 1750 xfs_dir3_leaf_log_header(args, lbp); 1786 1751 xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1787 1752 xfs_dir3_leaf_log_tail(args, lbp);
+235 -196
fs/xfs/libxfs/xfs_dir2_node.c
··· 34 34 int *rval); 35 35 36 36 /* 37 + * Convert data space db to the corresponding free db. 38 + */ 39 + static xfs_dir2_db_t 40 + xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 41 + { 42 + return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) + 43 + (db / geo->free_max_bests); 44 + } 45 + 46 + /* 47 + * Convert data space db to the corresponding index in a free db. 48 + */ 49 + static int 50 + xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db) 51 + { 52 + return db % geo->free_max_bests; 53 + } 54 + 55 + /* 37 56 * Check internal consistency of a leafn block. 38 57 */ 39 58 #ifdef DEBUG ··· 64 45 struct xfs_dir2_leaf *leaf = bp->b_addr; 65 46 struct xfs_dir3_icleaf_hdr leafhdr; 66 47 67 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 48 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 68 49 69 50 if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) { 70 51 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; ··· 73 54 } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC) 74 55 return __this_address; 75 56 76 - return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf); 57 + return xfs_dir3_leaf_check_int(dp->i_mount, &leafhdr, leaf); 77 58 } 78 59 79 60 static inline void ··· 179 160 struct xfs_buf *bp) 180 161 { 181 162 struct xfs_mount *mp = dp->i_mount; 163 + int maxbests = mp->m_dir_geo->free_max_bests; 182 164 unsigned int firstdb; 183 - int maxbests; 184 165 185 - maxbests = dp->d_ops->free_max_bests(mp->m_dir_geo); 186 166 firstdb = (xfs_dir2_da_to_db(mp->m_dir_geo, fbno) - 187 167 xfs_dir2_byte_to_db(mp->m_dir_geo, XFS_DIR2_FREE_OFFSET)) * 188 168 maxbests; ··· 212 194 struct xfs_trans *tp, 213 195 struct xfs_inode *dp, 214 196 xfs_dablk_t fbno, 215 - xfs_daddr_t mappedbno, 197 + unsigned int flags, 216 198 struct xfs_buf **bpp) 217 199 { 218 200 xfs_failaddr_t fa; 219 201 int err; 220 202 221 - err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 222 - XFS_DATA_FORK, &xfs_dir3_free_buf_ops); 203 + err = xfs_da_read_buf(tp, dp, fbno, flags, bpp, XFS_DATA_FORK, 204 + &xfs_dir3_free_buf_ops); 223 205 if (err || !*bpp) 224 206 return err; 225 207 ··· 238 220 return 0; 239 221 } 240 222 223 + void 224 + xfs_dir2_free_hdr_from_disk( 225 + struct xfs_mount *mp, 226 + struct xfs_dir3_icfree_hdr *to, 227 + struct xfs_dir2_free *from) 228 + { 229 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 230 + struct xfs_dir3_free *from3 = (struct xfs_dir3_free *)from; 231 + 232 + to->magic = be32_to_cpu(from3->hdr.hdr.magic); 233 + to->firstdb = be32_to_cpu(from3->hdr.firstdb); 234 + to->nvalid = be32_to_cpu(from3->hdr.nvalid); 235 + to->nused = be32_to_cpu(from3->hdr.nused); 236 + to->bests = from3->bests; 237 + 238 + ASSERT(to->magic == XFS_DIR3_FREE_MAGIC); 239 + } else { 240 + to->magic = be32_to_cpu(from->hdr.magic); 241 + to->firstdb = be32_to_cpu(from->hdr.firstdb); 242 + to->nvalid = be32_to_cpu(from->hdr.nvalid); 243 + to->nused = be32_to_cpu(from->hdr.nused); 244 + to->bests = from->bests; 245 + 246 + ASSERT(to->magic == XFS_DIR2_FREE_MAGIC); 247 + } 248 + } 249 + 250 + static void 251 + xfs_dir2_free_hdr_to_disk( 252 + struct xfs_mount *mp, 253 + struct xfs_dir2_free *to, 254 + struct xfs_dir3_icfree_hdr *from) 255 + { 256 + if (xfs_sb_version_hascrc(&mp->m_sb)) { 257 + struct xfs_dir3_free *to3 = (struct xfs_dir3_free *)to; 258 + 259 + ASSERT(from->magic == XFS_DIR3_FREE_MAGIC); 260 + 261 + to3->hdr.hdr.magic = cpu_to_be32(from->magic); 262 + to3->hdr.firstdb = cpu_to_be32(from->firstdb); 263 + to3->hdr.nvalid = cpu_to_be32(from->nvalid); 264 + to3->hdr.nused = cpu_to_be32(from->nused); 265 + } else { 266 + ASSERT(from->magic == XFS_DIR2_FREE_MAGIC); 267 + 268 + to->hdr.magic = cpu_to_be32(from->magic); 269 + to->hdr.firstdb = cpu_to_be32(from->firstdb); 270 + to->hdr.nvalid = cpu_to_be32(from->nvalid); 271 + to->hdr.nused = cpu_to_be32(from->nused); 272 + } 273 + } 274 + 241 275 int 242 276 xfs_dir2_free_read( 243 277 struct xfs_trans *tp, ··· 297 227 xfs_dablk_t fbno, 298 228 struct xfs_buf **bpp) 299 229 { 300 - return __xfs_dir3_free_read(tp, dp, fbno, -1, bpp); 230 + return __xfs_dir3_free_read(tp, dp, fbno, 0, bpp); 301 231 } 302 232 303 233 static int ··· 307 237 xfs_dablk_t fbno, 308 238 struct xfs_buf **bpp) 309 239 { 310 - return __xfs_dir3_free_read(tp, dp, fbno, -2, bpp); 240 + return __xfs_dir3_free_read(tp, dp, fbno, XFS_DABUF_MAP_HOLE_OK, bpp); 311 241 } 312 242 313 243 static int ··· 324 254 struct xfs_dir3_icfree_hdr hdr; 325 255 326 256 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, fbno), 327 - -1, &bp, XFS_DATA_FORK); 257 + &bp, XFS_DATA_FORK); 328 258 if (error) 329 259 return error; 330 260 ··· 348 278 uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_meta_uuid); 349 279 } else 350 280 hdr.magic = XFS_DIR2_FREE_MAGIC; 351 - dp->d_ops->free_hdr_to_disk(bp->b_addr, &hdr); 281 + xfs_dir2_free_hdr_to_disk(mp, bp->b_addr, &hdr); 352 282 *bpp = bp; 353 283 return 0; 354 284 } ··· 359 289 STATIC void 360 290 xfs_dir2_free_log_bests( 361 291 struct xfs_da_args *args, 292 + struct xfs_dir3_icfree_hdr *hdr, 362 293 struct xfs_buf *bp, 363 294 int first, /* first entry to log */ 364 295 int last) /* last entry to log */ 365 296 { 366 - xfs_dir2_free_t *free; /* freespace structure */ 367 - __be16 *bests; 297 + struct xfs_dir2_free *free = bp->b_addr; 368 298 369 - free = bp->b_addr; 370 - bests = args->dp->d_ops->free_bests_p(free); 371 299 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 372 300 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 373 301 xfs_trans_log_buf(args->trans, bp, 374 - (uint)((char *)&bests[first] - (char *)free), 375 - (uint)((char *)&bests[last] - (char *)free + 376 - sizeof(bests[0]) - 1)); 302 + (char *)&hdr->bests[first] - (char *)free, 303 + (char *)&hdr->bests[last] - (char *)free + 304 + sizeof(hdr->bests[0]) - 1); 377 305 } 378 306 379 307 /* ··· 390 322 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 391 323 #endif 392 324 xfs_trans_log_buf(args->trans, bp, 0, 393 - args->dp->d_ops->free_hdr_size - 1); 325 + args->geo->free_hdr_size - 1); 394 326 } 395 327 396 328 /* ··· 407 339 int error; /* error return value */ 408 340 struct xfs_buf *fbp; /* freespace buffer */ 409 341 xfs_dir2_db_t fdb; /* freespace block number */ 410 - xfs_dir2_free_t *free; /* freespace structure */ 411 342 __be16 *from; /* pointer to freespace entry */ 412 343 int i; /* leaf freespace index */ 413 344 xfs_dir2_leaf_t *leaf; /* leaf structure */ 414 345 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 415 346 int n; /* count of live freespc ents */ 416 347 xfs_dir2_data_off_t off; /* freespace entry value */ 417 - __be16 *to; /* pointer to freespace entry */ 418 348 xfs_trans_t *tp; /* transaction pointer */ 419 349 struct xfs_dir3_icfree_hdr freehdr; 420 350 ··· 434 368 if (error) 435 369 return error; 436 370 437 - free = fbp->b_addr; 438 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 371 + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, fbp->b_addr); 439 372 leaf = lbp->b_addr; 440 373 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); 441 374 if (be32_to_cpu(ltp->bestcount) > 442 - (uint)dp->i_d.di_size / args->geo->blksize) 375 + (uint)dp->i_d.di_size / args->geo->blksize) { 376 + xfs_buf_corruption_error(lbp); 443 377 return -EFSCORRUPTED; 378 + } 444 379 445 380 /* 446 381 * Copy freespace entries from the leaf block to the new block. 447 382 * Count active entries. 448 383 */ 449 384 from = xfs_dir2_leaf_bests_p(ltp); 450 - to = dp->d_ops->free_bests_p(free); 451 - for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { 452 - if ((off = be16_to_cpu(*from)) != NULLDATAOFF) 385 + for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++) { 386 + off = be16_to_cpu(*from); 387 + if (off != NULLDATAOFF) 453 388 n++; 454 - *to = cpu_to_be16(off); 389 + freehdr.bests[i] = cpu_to_be16(off); 455 390 } 456 391 457 392 /* ··· 461 394 freehdr.nused = n; 462 395 freehdr.nvalid = be32_to_cpu(ltp->bestcount); 463 396 464 - dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); 465 - xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1); 397 + xfs_dir2_free_hdr_to_disk(dp->i_mount, fbp->b_addr, &freehdr); 398 + xfs_dir2_free_log_bests(args, &freehdr, fbp, 0, freehdr.nvalid - 1); 466 399 xfs_dir2_free_log_header(args, fbp); 467 400 468 401 /* ··· 505 438 506 439 trace_xfs_dir2_leafn_add(args, index); 507 440 508 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 509 - ents = dp->d_ops->leaf_ents_p(leaf); 441 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 442 + ents = leafhdr.ents; 510 443 511 444 /* 512 445 * Quick check just to make sure we are not going to index 513 446 * into other peoples memory 514 447 */ 515 - if (index < 0) 448 + if (index < 0) { 449 + xfs_buf_corruption_error(bp); 516 450 return -EFSCORRUPTED; 451 + } 517 452 518 453 /* 519 454 * If there are already the maximum number of leaf entries in ··· 524 455 * a compact. 525 456 */ 526 457 527 - if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) { 458 + if (leafhdr.count == args->geo->leaf_max_ents) { 528 459 if (!leafhdr.stale) 529 460 return -ENOSPC; 530 461 compact = leafhdr.stale > 1; ··· 562 493 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo, 563 494 args->blkno, args->index)); 564 495 565 - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 496 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); 566 497 xfs_dir3_leaf_log_header(args, bp); 567 - xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh); 498 + xfs_dir3_leaf_log_ents(args, &leafhdr, bp, lfloglow, lfloghigh); 568 499 xfs_dir3_leaf_check(dp, bp); 569 500 return 0; 570 501 } ··· 578 509 { 579 510 struct xfs_dir3_icfree_hdr hdr; 580 511 581 - dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr); 512 + xfs_dir2_free_hdr_from_disk(dp->i_mount, &hdr, bp->b_addr); 582 513 583 - ASSERT((hdr.firstdb % 584 - dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0); 514 + ASSERT((hdr.firstdb % dp->i_mount->m_dir_geo->free_max_bests) == 0); 585 515 ASSERT(hdr.firstdb <= db); 586 516 ASSERT(db < hdr.firstdb + hdr.nvalid); 587 517 } ··· 598 530 struct xfs_buf *bp, /* leaf buffer */ 599 531 int *count) /* count of entries in leaf */ 600 532 { 601 - struct xfs_dir2_leaf *leaf = bp->b_addr; 602 - struct xfs_dir2_leaf_entry *ents; 603 533 struct xfs_dir3_icleaf_hdr leafhdr; 604 534 605 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 535 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, bp->b_addr); 606 536 607 537 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || 608 538 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC || ··· 611 545 *count = leafhdr.count; 612 546 if (!leafhdr.count) 613 547 return 0; 614 - 615 - ents = dp->d_ops->leaf_ents_p(leaf); 616 - return be32_to_cpu(ents[leafhdr.count - 1].hashval); 548 + return be32_to_cpu(leafhdr.ents[leafhdr.count - 1].hashval); 617 549 } 618 550 619 551 /* ··· 640 576 xfs_dir2_db_t newdb; /* new data block number */ 641 577 xfs_dir2_db_t newfdb; /* new free block number */ 642 578 xfs_trans_t *tp; /* transaction pointer */ 643 - struct xfs_dir2_leaf_entry *ents; 644 579 struct xfs_dir3_icleaf_hdr leafhdr; 645 580 646 581 dp = args->dp; 647 582 tp = args->trans; 648 583 mp = dp->i_mount; 649 584 leaf = bp->b_addr; 650 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 651 - ents = dp->d_ops->leaf_ents_p(leaf); 585 + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); 652 586 653 587 xfs_dir3_leaf_check(dp, bp); 654 588 ASSERT(leafhdr.count > 0); ··· 666 604 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 667 605 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 668 606 } 669 - length = dp->d_ops->data_entsize(args->namelen); 607 + length = xfs_dir2_data_entsize(mp, args->namelen); 670 608 /* 671 609 * Loop over leaf entries with the right hash value. 672 610 */ 673 - for (lep = &ents[index]; 611 + for (lep = &leafhdr.ents[index]; 674 612 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; 675 613 lep++, index++) { 676 614 /* ··· 692 630 * in hand, take a look at it. 693 631 */ 694 632 if (newdb != curdb) { 695 - __be16 *bests; 633 + struct xfs_dir3_icfree_hdr freehdr; 696 634 697 635 curdb = newdb; 698 636 /* 699 637 * Convert the data block to the free block 700 638 * holding its freespace information. 701 639 */ 702 - newfdb = dp->d_ops->db_to_fdb(args->geo, newdb); 640 + newfdb = xfs_dir2_db_to_fdb(args->geo, newdb); 703 641 /* 704 642 * If it's not the one we have in hand, read it in. 705 643 */ ··· 723 661 /* 724 662 * Get the index for our entry. 725 663 */ 726 - fi = dp->d_ops->db_to_fdindex(args->geo, curdb); 664 + fi = xfs_dir2_db_to_fdindex(args->geo, curdb); 727 665 /* 728 666 * If it has room, return it. 729 667 */ 730 - bests = dp->d_ops->free_bests_p(free); 731 - if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) { 732 - XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", 733 - XFS_ERRLEVEL_LOW, mp); 668 + xfs_dir2_free_hdr_from_disk(mp, &freehdr, free); 669 + if (XFS_IS_CORRUPT(mp, 670 + freehdr.bests[fi] == 671 + cpu_to_be16(NULLDATAOFF))) { 734 672 if (curfdb != newfdb) 735 673 xfs_trans_brelse(tp, curbp); 736 674 return -EFSCORRUPTED; 737 675 } 738 676 curfdb = newfdb; 739 - if (be16_to_cpu(bests[fi]) >= length) 677 + if (be16_to_cpu(freehdr.bests[fi]) >= length) 740 678 goto out; 741 679 } 742 680 } ··· 790 728 xfs_dir2_db_t newdb; /* new data block number */ 791 729 xfs_trans_t *tp; /* transaction pointer */ 792 730 enum xfs_dacmp cmp; /* comparison result */ 793 - struct xfs_dir2_leaf_entry *ents; 794 731 struct xfs_dir3_icleaf_hdr leafhdr; 795 732 796 733 dp = args->dp; 797 734 tp = args->trans; 798 735 mp = dp->i_mount; 799 736 leaf = bp->b_addr; 800 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 801 - ents = dp->d_ops->leaf_ents_p(leaf); 737 + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); 802 738 803 739 xfs_dir3_leaf_check(dp, bp); 804 - if (leafhdr.count <= 0) 740 + if (leafhdr.count <= 0) { 741 + xfs_buf_corruption_error(bp); 805 742 return -EFSCORRUPTED; 743 + } 806 744 807 745 /* 808 746 * Look up the hash value in the leaf entries. ··· 818 756 /* 819 757 * Loop over leaf entries with the right hash value. 820 758 */ 821 - for (lep = &ents[index]; 759 + for (lep = &leafhdr.ents[index]; 822 760 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; 823 761 lep++, index++) { 824 762 /* ··· 857 795 error = xfs_dir3_data_read(tp, dp, 858 796 xfs_dir2_db_to_da(args->geo, 859 797 newdb), 860 - -1, &curbp); 798 + 0, &curbp); 861 799 if (error) 862 800 return error; 863 801 } ··· 875 813 * EEXIST immediately. If it's the first case-insensitive 876 814 * match, store the block & inode number and continue looking. 877 815 */ 878 - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); 816 + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); 879 817 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 880 818 /* If there is a CI match block, drop it */ 881 819 if (args->cmpresult != XFS_CMP_DIFFERENT && ··· 883 821 xfs_trans_brelse(tp, state->extrablk.bp); 884 822 args->cmpresult = cmp; 885 823 args->inumber = be64_to_cpu(dep->inumber); 886 - args->filetype = dp->d_ops->data_get_ftype(dep); 824 + args->filetype = xfs_dir2_data_get_ftype(mp, dep); 887 825 *indexp = index; 888 826 state->extravalid = 1; 889 827 state->extrablk.bp = curbp; ··· 973 911 if (start_d < dhdr->count) { 974 912 memmove(&dents[start_d + count], &dents[start_d], 975 913 (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t)); 976 - xfs_dir3_leaf_log_ents(args, bp_d, start_d + count, 914 + xfs_dir3_leaf_log_ents(args, dhdr, bp_d, start_d + count, 977 915 count + dhdr->count - 1); 978 916 } 979 917 /* ··· 995 933 */ 996 934 memcpy(&dents[start_d], &sents[start_s], 997 935 count * sizeof(xfs_dir2_leaf_entry_t)); 998 - xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1); 936 + xfs_dir3_leaf_log_ents(args, dhdr, bp_d, start_d, start_d + count - 1); 999 937 1000 938 /* 1001 939 * If there are source entries after the ones we copied, ··· 1004 942 if (start_s + count < shdr->count) { 1005 943 memmove(&sents[start_s], &sents[start_s + count], 1006 944 count * sizeof(xfs_dir2_leaf_entry_t)); 1007 - xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1); 945 + xfs_dir3_leaf_log_ents(args, shdr, bp_s, start_s, 946 + start_s + count - 1); 1008 947 } 1009 948 1010 949 /* ··· 1034 971 struct xfs_dir3_icleaf_hdr hdr1; 1035 972 struct xfs_dir3_icleaf_hdr hdr2; 1036 973 1037 - dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1); 1038 - dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2); 1039 - ents1 = dp->d_ops->leaf_ents_p(leaf1); 1040 - ents2 = dp->d_ops->leaf_ents_p(leaf2); 974 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); 975 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); 976 + ents1 = hdr1.ents; 977 + ents2 = hdr2.ents; 1041 978 1042 979 if (hdr1.count > 0 && hdr2.count > 0 && 1043 980 (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) || ··· 1087 1024 1088 1025 leaf1 = blk1->bp->b_addr; 1089 1026 leaf2 = blk2->bp->b_addr; 1090 - dp->d_ops->leaf_hdr_from_disk(&hdr1, leaf1); 1091 - dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf2); 1092 - ents1 = dp->d_ops->leaf_ents_p(leaf1); 1093 - ents2 = dp->d_ops->leaf_ents_p(leaf2); 1027 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); 1028 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); 1029 + ents1 = hdr1.ents; 1030 + ents2 = hdr2.ents; 1094 1031 1095 1032 oldsum = hdr1.count + hdr2.count; 1096 1033 #if defined(DEBUG) || defined(XFS_WARN) ··· 1136 1073 ASSERT(hdr1.stale + hdr2.stale == oldstale); 1137 1074 1138 1075 /* log the changes made when moving the entries */ 1139 - dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1); 1140 - dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2); 1076 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf1, &hdr1); 1077 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf2, &hdr2); 1141 1078 xfs_dir3_leaf_log_header(args, blk1->bp); 1142 1079 xfs_dir3_leaf_log_header(args, blk2->bp); 1143 1080 ··· 1183 1120 int longest) 1184 1121 { 1185 1122 int logfree = 0; 1186 - __be16 *bests; 1187 1123 struct xfs_dir3_icfree_hdr freehdr; 1188 1124 struct xfs_inode *dp = args->dp; 1189 1125 1190 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 1191 - bests = dp->d_ops->free_bests_p(free); 1126 + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); 1192 1127 if (hdr) { 1193 1128 /* 1194 1129 * Data block is not empty, just set the free entry to the new 1195 1130 * value. 1196 1131 */ 1197 - bests[findex] = cpu_to_be16(longest); 1198 - xfs_dir2_free_log_bests(args, fbp, findex, findex); 1132 + freehdr.bests[findex] = cpu_to_be16(longest); 1133 + xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex); 1199 1134 return 0; 1200 1135 } 1201 1136 ··· 1209 1148 int i; /* free entry index */ 1210 1149 1211 1150 for (i = findex - 1; i >= 0; i--) { 1212 - if (bests[i] != cpu_to_be16(NULLDATAOFF)) 1151 + if (freehdr.bests[i] != cpu_to_be16(NULLDATAOFF)) 1213 1152 break; 1214 1153 } 1215 1154 freehdr.nvalid = i + 1; 1216 1155 logfree = 0; 1217 1156 } else { 1218 1157 /* Not the last entry, just punch it out. */ 1219 - bests[findex] = cpu_to_be16(NULLDATAOFF); 1158 + freehdr.bests[findex] = cpu_to_be16(NULLDATAOFF); 1220 1159 logfree = 1; 1221 1160 } 1222 1161 1223 - dp->d_ops->free_hdr_to_disk(free, &freehdr); 1162 + xfs_dir2_free_hdr_to_disk(dp->i_mount, free, &freehdr); 1224 1163 xfs_dir2_free_log_header(args, fbp); 1225 1164 1226 1165 /* ··· 1245 1184 1246 1185 /* Log the free entry that changed, unless we got rid of it. */ 1247 1186 if (logfree) 1248 - xfs_dir2_free_log_bests(args, fbp, findex, findex); 1187 + xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex); 1249 1188 return 0; 1250 1189 } 1251 1190 ··· 1262 1201 xfs_da_state_blk_t *dblk, /* data block */ 1263 1202 int *rval) /* resulting block needs join */ 1264 1203 { 1204 + struct xfs_da_geometry *geo = args->geo; 1265 1205 xfs_dir2_data_hdr_t *hdr; /* data block header */ 1266 1206 xfs_dir2_db_t db; /* data block number */ 1267 1207 struct xfs_buf *dbp; /* data block buffer */ ··· 1277 1215 xfs_trans_t *tp; /* transaction pointer */ 1278 1216 struct xfs_dir2_data_free *bf; /* bestfree table */ 1279 1217 struct xfs_dir3_icleaf_hdr leafhdr; 1280 - struct xfs_dir2_leaf_entry *ents; 1281 1218 1282 1219 trace_xfs_dir2_leafn_remove(args, index); 1283 1220 1284 1221 dp = args->dp; 1285 1222 tp = args->trans; 1286 1223 leaf = bp->b_addr; 1287 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 1288 - ents = dp->d_ops->leaf_ents_p(leaf); 1224 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 1289 1225 1290 1226 /* 1291 1227 * Point to the entry we're removing. 1292 1228 */ 1293 - lep = &ents[index]; 1229 + lep = &leafhdr.ents[index]; 1294 1230 1295 1231 /* 1296 1232 * Extract the data block and offset from the entry. 1297 1233 */ 1298 - db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); 1234 + db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address)); 1299 1235 ASSERT(dblk->blkno == db); 1300 - off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)); 1236 + off = xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address)); 1301 1237 ASSERT(dblk->index == off); 1302 1238 1303 1239 /* ··· 1303 1243 * Log the leaf block changes. 1304 1244 */ 1305 1245 leafhdr.stale++; 1306 - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 1246 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); 1307 1247 xfs_dir3_leaf_log_header(args, bp); 1308 1248 1309 1249 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1310 - xfs_dir3_leaf_log_ents(args, bp, index, index); 1250 + xfs_dir3_leaf_log_ents(args, &leafhdr, bp, index, index); 1311 1251 1312 1252 /* 1313 1253 * Make the data entry free. Keep track of the longest freespace ··· 1316 1256 dbp = dblk->bp; 1317 1257 hdr = dbp->b_addr; 1318 1258 dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); 1319 - bf = dp->d_ops->data_bestfree_p(hdr); 1259 + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 1320 1260 longest = be16_to_cpu(bf[0].length); 1321 1261 needlog = needscan = 0; 1322 1262 xfs_dir2_data_make_free(args, dbp, off, 1323 - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); 1263 + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, 1264 + &needscan); 1324 1265 /* 1325 1266 * Rescan the data block freespaces for bestfree. 1326 1267 * Log the data block header if needed. 1327 1268 */ 1328 1269 if (needscan) 1329 - xfs_dir2_data_freescan(dp, hdr, &needlog); 1270 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 1330 1271 if (needlog) 1331 1272 xfs_dir2_data_log_header(args, dbp); 1332 1273 xfs_dir3_data_check(dp, dbp); ··· 1346 1285 * Convert the data block number to a free block, 1347 1286 * read in the free block. 1348 1287 */ 1349 - fdb = dp->d_ops->db_to_fdb(args->geo, db); 1350 - error = xfs_dir2_free_read(tp, dp, 1351 - xfs_dir2_db_to_da(args->geo, fdb), 1288 + fdb = xfs_dir2_db_to_fdb(geo, db); 1289 + error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(geo, fdb), 1352 1290 &fbp); 1353 1291 if (error) 1354 1292 return error; ··· 1355 1295 #ifdef DEBUG 1356 1296 { 1357 1297 struct xfs_dir3_icfree_hdr freehdr; 1358 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 1359 - ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) * 1360 - (fdb - xfs_dir2_byte_to_db(args->geo, 1361 - XFS_DIR2_FREE_OFFSET))); 1298 + 1299 + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); 1300 + ASSERT(freehdr.firstdb == geo->free_max_bests * 1301 + (fdb - xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET))); 1362 1302 } 1363 1303 #endif 1364 1304 /* 1365 1305 * Calculate which entry we need to fix. 1366 1306 */ 1367 - findex = dp->d_ops->db_to_fdindex(args->geo, db); 1307 + findex = xfs_dir2_db_to_fdindex(geo, db); 1368 1308 longest = be16_to_cpu(bf[0].length); 1369 1309 /* 1370 1310 * If the data block is now empty we can get rid of it 1371 1311 * (usually). 1372 1312 */ 1373 - if (longest == args->geo->blksize - 1374 - dp->d_ops->data_entry_offset) { 1313 + if (longest == geo->blksize - geo->data_entry_offset) { 1375 1314 /* 1376 1315 * Try to punch out the data block. 1377 1316 */ ··· 1402 1343 * Return indication of whether this leaf block is empty enough 1403 1344 * to justify trying to join it with a neighbor. 1404 1345 */ 1405 - *rval = (dp->d_ops->leaf_hdr_size + 1406 - (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < 1407 - args->geo->magicpct; 1346 + *rval = (geo->leaf_hdr_size + 1347 + (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) < 1348 + geo->magicpct; 1408 1349 return 0; 1409 1350 } 1410 1351 ··· 1503 1444 */ 1504 1445 blk = &state->path.blk[state->path.active - 1]; 1505 1446 leaf = blk->bp->b_addr; 1506 - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 1507 - ents = dp->d_ops->leaf_ents_p(leaf); 1447 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); 1448 + ents = leafhdr.ents; 1508 1449 xfs_dir3_leaf_check(dp, blk->bp); 1509 1450 1510 1451 count = leafhdr.count - leafhdr.stale; 1511 - bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]); 1452 + bytes = state->args->geo->leaf_hdr_size + count * sizeof(ents[0]); 1512 1453 if (bytes > (state->args->geo->blksize >> 1)) { 1513 1454 /* 1514 1455 * Blk over 50%, don't try to join. ··· 1553 1494 /* 1554 1495 * Read the sibling leaf block. 1555 1496 */ 1556 - error = xfs_dir3_leafn_read(state->args->trans, dp, 1557 - blkno, -1, &bp); 1497 + error = xfs_dir3_leafn_read(state->args->trans, dp, blkno, &bp); 1558 1498 if (error) 1559 1499 return error; 1560 1500 ··· 1565 1507 (state->args->geo->blksize >> 2); 1566 1508 1567 1509 leaf = bp->b_addr; 1568 - dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf); 1569 - ents = dp->d_ops->leaf_ents_p(leaf); 1510 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf); 1511 + ents = hdr2.ents; 1570 1512 count += hdr2.count - hdr2.stale; 1571 1513 bytes -= count * sizeof(ents[0]); 1572 1514 ··· 1628 1570 drop_leaf = drop_blk->bp->b_addr; 1629 1571 save_leaf = save_blk->bp->b_addr; 1630 1572 1631 - dp->d_ops->leaf_hdr_from_disk(&savehdr, save_leaf); 1632 - dp->d_ops->leaf_hdr_from_disk(&drophdr, drop_leaf); 1633 - sents = dp->d_ops->leaf_ents_p(save_leaf); 1634 - dents = dp->d_ops->leaf_ents_p(drop_leaf); 1573 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &savehdr, save_leaf); 1574 + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &drophdr, drop_leaf); 1575 + sents = savehdr.ents; 1576 + dents = drophdr.ents; 1635 1577 1636 1578 /* 1637 1579 * If there are any stale leaf entries, take this opportunity ··· 1657 1599 save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval); 1658 1600 1659 1601 /* log the changes made when moving the entries */ 1660 - dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr); 1661 - dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr); 1602 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, save_leaf, &savehdr); 1603 + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, drop_leaf, &drophdr); 1662 1604 xfs_dir3_leaf_log_header(args, save_blk->bp); 1663 1605 xfs_dir3_leaf_log_header(args, drop_blk->bp); 1664 1606 ··· 1677 1619 xfs_dir2_db_t *dbno, 1678 1620 struct xfs_buf **dbpp, 1679 1621 struct xfs_buf **fbpp, 1622 + struct xfs_dir3_icfree_hdr *hdr, 1680 1623 int *findex) 1681 1624 { 1682 1625 struct xfs_inode *dp = args->dp; 1683 1626 struct xfs_trans *tp = args->trans; 1684 1627 struct xfs_mount *mp = dp->i_mount; 1685 - struct xfs_dir3_icfree_hdr freehdr; 1686 1628 struct xfs_dir2_data_free *bf; 1687 - struct xfs_dir2_data_hdr *hdr; 1688 - struct xfs_dir2_free *free = NULL; 1689 1629 xfs_dir2_db_t fbno; 1690 1630 struct xfs_buf *fbp; 1691 1631 struct xfs_buf *dbp; 1692 - __be16 *bests = NULL; 1693 1632 int error; 1694 1633 1695 1634 /* Not allowed to allocate, return failure. */ ··· 1705 1650 * Get the freespace block corresponding to the data block 1706 1651 * that was just allocated. 1707 1652 */ 1708 - fbno = dp->d_ops->db_to_fdb(args->geo, *dbno); 1653 + fbno = xfs_dir2_db_to_fdb(args->geo, *dbno); 1709 1654 error = xfs_dir2_free_try_read(tp, dp, 1710 1655 xfs_dir2_db_to_da(args->geo, fbno), &fbp); 1711 1656 if (error) ··· 1720 1665 if (error) 1721 1666 return error; 1722 1667 1723 - if (dp->d_ops->db_to_fdb(args->geo, *dbno) != fbno) { 1668 + if (XFS_IS_CORRUPT(mp, 1669 + xfs_dir2_db_to_fdb(args->geo, *dbno) != 1670 + fbno)) { 1724 1671 xfs_alert(mp, 1725 1672 "%s: dir ino %llu needed freesp block %lld for data block %lld, got %lld", 1726 1673 __func__, (unsigned long long)dp->i_ino, 1727 - (long long)dp->d_ops->db_to_fdb(args->geo, *dbno), 1674 + (long long)xfs_dir2_db_to_fdb(args->geo, *dbno), 1728 1675 (long long)*dbno, (long long)fbno); 1729 1676 if (fblk) { 1730 1677 xfs_alert(mp, ··· 1736 1679 } else { 1737 1680 xfs_alert(mp, " ... fblk is NULL"); 1738 1681 } 1739 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 1740 1682 return -EFSCORRUPTED; 1741 1683 } 1742 1684 ··· 1743 1687 error = xfs_dir3_free_get_buf(args, fbno, &fbp); 1744 1688 if (error) 1745 1689 return error; 1746 - free = fbp->b_addr; 1747 - bests = dp->d_ops->free_bests_p(free); 1748 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 1690 + xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr); 1749 1691 1750 1692 /* Remember the first slot as our empty slot. */ 1751 - freehdr.firstdb = (fbno - xfs_dir2_byte_to_db(args->geo, 1693 + hdr->firstdb = (fbno - xfs_dir2_byte_to_db(args->geo, 1752 1694 XFS_DIR2_FREE_OFFSET)) * 1753 - dp->d_ops->free_max_bests(args->geo); 1695 + args->geo->free_max_bests; 1754 1696 } else { 1755 - free = fbp->b_addr; 1756 - bests = dp->d_ops->free_bests_p(free); 1757 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 1697 + xfs_dir2_free_hdr_from_disk(mp, hdr, fbp->b_addr); 1758 1698 } 1759 1699 1760 1700 /* Set the freespace block index from the data block number. */ 1761 - *findex = dp->d_ops->db_to_fdindex(args->geo, *dbno); 1701 + *findex = xfs_dir2_db_to_fdindex(args->geo, *dbno); 1762 1702 1763 1703 /* Extend the freespace table if the new data block is off the end. */ 1764 - if (*findex >= freehdr.nvalid) { 1765 - ASSERT(*findex < dp->d_ops->free_max_bests(args->geo)); 1766 - freehdr.nvalid = *findex + 1; 1767 - bests[*findex] = cpu_to_be16(NULLDATAOFF); 1704 + if (*findex >= hdr->nvalid) { 1705 + ASSERT(*findex < args->geo->free_max_bests); 1706 + hdr->nvalid = *findex + 1; 1707 + hdr->bests[*findex] = cpu_to_be16(NULLDATAOFF); 1768 1708 } 1769 1709 1770 1710 /* 1771 1711 * If this entry was for an empty data block (this should always be 1772 1712 * true) then update the header. 1773 1713 */ 1774 - if (bests[*findex] == cpu_to_be16(NULLDATAOFF)) { 1775 - freehdr.nused++; 1776 - dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); 1714 + if (hdr->bests[*findex] == cpu_to_be16(NULLDATAOFF)) { 1715 + hdr->nused++; 1716 + xfs_dir2_free_hdr_to_disk(mp, fbp->b_addr, hdr); 1777 1717 xfs_dir2_free_log_header(args, fbp); 1778 1718 } 1779 1719 1780 1720 /* Update the freespace value for the new block in the table. */ 1781 - hdr = dbp->b_addr; 1782 - bf = dp->d_ops->data_bestfree_p(hdr); 1783 - bests[*findex] = bf[0].length; 1721 + bf = xfs_dir2_data_bestfree_p(mp, dbp->b_addr); 1722 + hdr->bests[*findex] = bf[0].length; 1784 1723 1785 1724 *dbpp = dbp; 1786 1725 *fbpp = fbp; ··· 1788 1737 struct xfs_da_state_blk *fblk, 1789 1738 xfs_dir2_db_t *dbnop, 1790 1739 struct xfs_buf **fbpp, 1740 + struct xfs_dir3_icfree_hdr *hdr, 1791 1741 int *findexp, 1792 1742 int length) 1793 1743 { 1794 - struct xfs_dir3_icfree_hdr freehdr; 1795 - struct xfs_dir2_free *free = NULL; 1796 1744 struct xfs_inode *dp = args->dp; 1797 1745 struct xfs_trans *tp = args->trans; 1798 1746 struct xfs_buf *fbp = NULL; ··· 1801 1751 xfs_dir2_db_t dbno = -1; 1802 1752 xfs_dir2_db_t fbno; 1803 1753 xfs_fileoff_t fo; 1804 - __be16 *bests = NULL; 1805 1754 int findex = 0; 1806 1755 int error; 1807 1756 ··· 1811 1762 */ 1812 1763 if (fblk) { 1813 1764 fbp = fblk->bp; 1814 - free = fbp->b_addr; 1815 1765 findex = fblk->index; 1766 + xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr); 1816 1767 if (findex >= 0) { 1817 1768 /* caller already found the freespace for us. */ 1818 - bests = dp->d_ops->free_bests_p(free); 1819 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 1820 - 1821 - ASSERT(findex < freehdr.nvalid); 1822 - ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF); 1823 - ASSERT(be16_to_cpu(bests[findex]) >= length); 1824 - dbno = freehdr.firstdb + findex; 1769 + ASSERT(findex < hdr->nvalid); 1770 + ASSERT(be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF); 1771 + ASSERT(be16_to_cpu(hdr->bests[findex]) >= length); 1772 + dbno = hdr->firstdb + findex; 1825 1773 goto found_block; 1826 1774 } 1827 1775 ··· 1860 1814 if (!fbp) 1861 1815 continue; 1862 1816 1863 - free = fbp->b_addr; 1864 - bests = dp->d_ops->free_bests_p(free); 1865 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 1817 + xfs_dir2_free_hdr_from_disk(dp->i_mount, hdr, fbp->b_addr); 1866 1818 1867 1819 /* Scan the free entry array for a large enough free space. */ 1868 - for (findex = freehdr.nvalid - 1; findex >= 0; findex--) { 1869 - if (be16_to_cpu(bests[findex]) != NULLDATAOFF && 1870 - be16_to_cpu(bests[findex]) >= length) { 1871 - dbno = freehdr.firstdb + findex; 1820 + for (findex = hdr->nvalid - 1; findex >= 0; findex--) { 1821 + if (be16_to_cpu(hdr->bests[findex]) != NULLDATAOFF && 1822 + be16_to_cpu(hdr->bests[findex]) >= length) { 1823 + dbno = hdr->firstdb + findex; 1872 1824 goto found_block; 1873 1825 } 1874 1826 } ··· 1882 1838 return 0; 1883 1839 } 1884 1840 1885 - 1886 1841 /* 1887 1842 * Add the data entry for a node-format directory name addition. 1888 1843 * The leaf entry is added in xfs_dir2_leafn_add. ··· 1896 1853 struct xfs_dir2_data_entry *dep; /* data entry pointer */ 1897 1854 struct xfs_dir2_data_hdr *hdr; /* data block header */ 1898 1855 struct xfs_dir2_data_free *bf; 1899 - struct xfs_dir2_free *free = NULL; /* freespace block structure */ 1900 1856 struct xfs_trans *tp = args->trans; 1901 1857 struct xfs_inode *dp = args->dp; 1858 + struct xfs_dir3_icfree_hdr freehdr; 1902 1859 struct xfs_buf *dbp; /* data block buffer */ 1903 1860 struct xfs_buf *fbp; /* freespace buffer */ 1904 1861 xfs_dir2_data_aoff_t aoff; ··· 1910 1867 int needlog = 0; /* need to log data header */ 1911 1868 int needscan = 0; /* need to rescan data frees */ 1912 1869 __be16 *tagp; /* data entry tag pointer */ 1913 - __be16 *bests; 1914 1870 1915 - length = dp->d_ops->data_entsize(args->namelen); 1916 - error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &findex, 1917 - length); 1871 + length = xfs_dir2_data_entsize(dp->i_mount, args->namelen); 1872 + error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &freehdr, 1873 + &findex, length); 1918 1874 if (error) 1919 1875 return error; 1920 1876 ··· 1935 1893 /* we're going to have to log the free block index later */ 1936 1894 logfree = 1; 1937 1895 error = xfs_dir2_node_add_datablk(args, fblk, &dbno, &dbp, &fbp, 1938 - &findex); 1896 + &freehdr, &findex); 1939 1897 } else { 1940 1898 /* Read the data block in. */ 1941 1899 error = xfs_dir3_data_read(tp, dp, 1942 1900 xfs_dir2_db_to_da(args->geo, dbno), 1943 - -1, &dbp); 1901 + 0, &dbp); 1944 1902 } 1945 1903 if (error) 1946 1904 return error; 1947 1905 1948 1906 /* setup for data block up now */ 1949 1907 hdr = dbp->b_addr; 1950 - bf = dp->d_ops->data_bestfree_p(hdr); 1908 + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); 1951 1909 ASSERT(be16_to_cpu(bf[0].length) >= length); 1952 1910 1953 1911 /* Point to the existing unused space. */ ··· 1968 1926 dep->inumber = cpu_to_be64(args->inumber); 1969 1927 dep->namelen = args->namelen; 1970 1928 memcpy(dep->name, args->name, dep->namelen); 1971 - dp->d_ops->data_put_ftype(dep, args->filetype); 1972 - tagp = dp->d_ops->data_entry_tag_p(dep); 1929 + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); 1930 + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); 1973 1931 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1974 1932 xfs_dir2_data_log_entry(args, dbp, dep); 1975 1933 1976 1934 /* Rescan the freespace and log the data block if needed. */ 1977 1935 if (needscan) 1978 - xfs_dir2_data_freescan(dp, hdr, &needlog); 1936 + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); 1979 1937 if (needlog) 1980 1938 xfs_dir2_data_log_header(args, dbp); 1981 1939 1982 1940 /* If the freespace block entry is now wrong, update it. */ 1983 - free = fbp->b_addr; 1984 - bests = dp->d_ops->free_bests_p(free); 1985 - if (bests[findex] != bf[0].length) { 1986 - bests[findex] = bf[0].length; 1941 + if (freehdr.bests[findex] != bf[0].length) { 1942 + freehdr.bests[findex] = bf[0].length; 1987 1943 logfree = 1; 1988 1944 } 1989 1945 1990 1946 /* Log the freespace entry if needed. */ 1991 1947 if (logfree) 1992 - xfs_dir2_free_log_bests(args, fbp, findex, findex); 1948 + xfs_dir2_free_log_bests(args, &freehdr, fbp, findex, findex); 1993 1949 1994 1950 /* Return the data block and offset in args. */ 1995 1951 args->blkno = (xfs_dablk_t)dbno; ··· 2195 2155 int i; /* btree level */ 2196 2156 xfs_ino_t inum; /* new inode number */ 2197 2157 int ftype; /* new file type */ 2198 - xfs_dir2_leaf_t *leaf; /* leaf structure */ 2199 - xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */ 2200 2158 int rval; /* internal return value */ 2201 2159 xfs_da_state_t *state; /* btree cursor */ 2202 2160 ··· 2226 2188 * and locked it. But paranoia is good. 2227 2189 */ 2228 2190 if (rval == -EEXIST) { 2229 - struct xfs_dir2_leaf_entry *ents; 2191 + struct xfs_dir3_icleaf_hdr leafhdr; 2192 + 2230 2193 /* 2231 2194 * Find the leaf entry. 2232 2195 */ 2233 2196 blk = &state->path.blk[state->path.active - 1]; 2234 2197 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 2235 - leaf = blk->bp->b_addr; 2236 - ents = args->dp->d_ops->leaf_ents_p(leaf); 2237 - lep = &ents[blk->index]; 2238 2198 ASSERT(state->extravalid); 2199 + 2200 + xfs_dir2_leaf_hdr_from_disk(state->mp, &leafhdr, 2201 + blk->bp->b_addr); 2239 2202 /* 2240 2203 * Point to the data entry. 2241 2204 */ ··· 2246 2207 dep = (xfs_dir2_data_entry_t *) 2247 2208 ((char *)hdr + 2248 2209 xfs_dir2_dataptr_to_off(args->geo, 2249 - be32_to_cpu(lep->address))); 2210 + be32_to_cpu(leafhdr.ents[blk->index].address))); 2250 2211 ASSERT(inum != be64_to_cpu(dep->inumber)); 2251 2212 /* 2252 2213 * Fill in the new inode number and log the entry. 2253 2214 */ 2254 2215 dep->inumber = cpu_to_be64(inum); 2255 - args->dp->d_ops->data_put_ftype(dep, ftype); 2216 + xfs_dir2_data_put_ftype(state->mp, dep, ftype); 2256 2217 xfs_dir2_data_log_entry(args, state->extrablk.bp, dep); 2257 2218 rval = 0; 2258 2219 } ··· 2309 2270 if (!bp) 2310 2271 return 0; 2311 2272 free = bp->b_addr; 2312 - dp->d_ops->free_hdr_from_disk(&freehdr, free); 2273 + xfs_dir2_free_hdr_from_disk(dp->i_mount, &freehdr, free); 2313 2274 2314 2275 /* 2315 2276 * If there are used entries, there's nothing to do.
+103 -11
fs/xfs/libxfs/xfs_dir2_priv.h
··· 8 8 9 9 struct dir_context; 10 10 11 + /* 12 + * In-core version of the leaf and free block headers to abstract the 13 + * differences in the v2 and v3 disk format of the headers. 14 + */ 15 + struct xfs_dir3_icleaf_hdr { 16 + uint32_t forw; 17 + uint32_t back; 18 + uint16_t magic; 19 + uint16_t count; 20 + uint16_t stale; 21 + 22 + /* 23 + * Pointer to the on-disk format entries, which are behind the 24 + * variable size (v4 vs v5) header in the on-disk block. 25 + */ 26 + struct xfs_dir2_leaf_entry *ents; 27 + }; 28 + 29 + struct xfs_dir3_icfree_hdr { 30 + uint32_t magic; 31 + uint32_t firstdb; 32 + uint32_t nvalid; 33 + uint32_t nused; 34 + 35 + /* 36 + * Pointer to the on-disk format entries, which are behind the 37 + * variable size (v4 vs v5) header in the on-disk block. 38 + */ 39 + __be16 *bests; 40 + }; 41 + 11 42 /* xfs_dir2.c */ 43 + xfs_dahash_t xfs_ascii_ci_hashname(struct xfs_name *name); 44 + enum xfs_dacmp xfs_ascii_ci_compname(struct xfs_da_args *args, 45 + const unsigned char *name, int len); 12 46 extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, 13 47 xfs_dir2_db_t *dbp); 14 48 extern int xfs_dir_cilookup_result(struct xfs_da_args *args, ··· 60 26 struct xfs_buf *lbp, struct xfs_buf *dbp); 61 27 62 28 /* xfs_dir2_data.c */ 29 + struct xfs_dir2_data_free *xfs_dir2_data_bestfree_p(struct xfs_mount *mp, 30 + struct xfs_dir2_data_hdr *hdr); 31 + __be16 *xfs_dir2_data_entry_tag_p(struct xfs_mount *mp, 32 + struct xfs_dir2_data_entry *dep); 33 + uint8_t xfs_dir2_data_get_ftype(struct xfs_mount *mp, 34 + struct xfs_dir2_data_entry *dep); 35 + void xfs_dir2_data_put_ftype(struct xfs_mount *mp, 36 + struct xfs_dir2_data_entry *dep, uint8_t ftype); 37 + 63 38 #ifdef DEBUG 64 39 extern void xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); 65 40 #else ··· 77 34 78 35 extern xfs_failaddr_t __xfs_dir3_data_check(struct xfs_inode *dp, 79 36 struct xfs_buf *bp); 80 - extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, 81 - xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp); 82 - extern int xfs_dir3_data_readahead(struct xfs_inode *dp, xfs_dablk_t bno, 83 - xfs_daddr_t mapped_bno); 37 + int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, 38 + xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp); 39 + int xfs_dir3_data_readahead(struct xfs_inode *dp, xfs_dablk_t bno, 40 + unsigned int flags); 84 41 85 42 extern struct xfs_dir2_data_free * 86 43 xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr, ··· 90 47 struct xfs_buf **bpp); 91 48 92 49 /* xfs_dir2_leaf.c */ 93 - extern int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, 94 - xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); 95 - extern int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, 96 - xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); 50 + void xfs_dir2_leaf_hdr_from_disk(struct xfs_mount *mp, 51 + struct xfs_dir3_icleaf_hdr *to, struct xfs_dir2_leaf *from); 52 + void xfs_dir2_leaf_hdr_to_disk(struct xfs_mount *mp, struct xfs_dir2_leaf *to, 53 + struct xfs_dir3_icleaf_hdr *from); 54 + int xfs_dir3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, 55 + xfs_dablk_t fbno, struct xfs_buf **bpp); 56 + int xfs_dir3_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, 57 + xfs_dablk_t fbno, struct xfs_buf **bpp); 97 58 extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, 98 59 struct xfs_buf *dbp); 99 60 extern int xfs_dir2_leaf_addname(struct xfs_da_args *args); ··· 109 62 extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno, 110 63 struct xfs_buf **bpp, uint16_t magic); 111 64 extern void xfs_dir3_leaf_log_ents(struct xfs_da_args *args, 112 - struct xfs_buf *bp, int first, int last); 65 + struct xfs_dir3_icleaf_hdr *hdr, struct xfs_buf *bp, int first, 66 + int last); 113 67 extern void xfs_dir3_leaf_log_header(struct xfs_da_args *args, 114 68 struct xfs_buf *bp); 115 69 extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); ··· 127 79 extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); 128 80 129 81 extern xfs_failaddr_t xfs_dir3_leaf_check_int(struct xfs_mount *mp, 130 - struct xfs_inode *dp, struct xfs_dir3_icleaf_hdr *hdr, 131 - struct xfs_dir2_leaf *leaf); 82 + struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir2_leaf *leaf); 132 83 133 84 /* xfs_dir2_node.c */ 85 + void xfs_dir2_free_hdr_from_disk(struct xfs_mount *mp, 86 + struct xfs_dir3_icfree_hdr *to, struct xfs_dir2_free *from); 134 87 extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args, 135 88 struct xfs_buf *lbp); 136 89 extern xfs_dahash_t xfs_dir2_leaf_lasthash(struct xfs_inode *dp, ··· 157 108 xfs_dablk_t fbno, struct xfs_buf **bpp); 158 109 159 110 /* xfs_dir2_sf.c */ 111 + xfs_ino_t xfs_dir2_sf_get_ino(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *hdr, 112 + struct xfs_dir2_sf_entry *sfep); 113 + xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *hdr); 114 + void xfs_dir2_sf_put_parent_ino(struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino); 115 + uint8_t xfs_dir2_sf_get_ftype(struct xfs_mount *mp, 116 + struct xfs_dir2_sf_entry *sfep); 117 + struct xfs_dir2_sf_entry *xfs_dir2_sf_nextentry(struct xfs_mount *mp, 118 + struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep); 160 119 extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, 161 120 struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp); 162 121 extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp, ··· 179 122 /* xfs_dir2_readdir.c */ 180 123 extern int xfs_readdir(struct xfs_trans *tp, struct xfs_inode *dp, 181 124 struct dir_context *ctx, size_t bufsize); 125 + 126 + static inline unsigned int 127 + xfs_dir2_data_entsize( 128 + struct xfs_mount *mp, 129 + unsigned int namelen) 130 + { 131 + unsigned int len; 132 + 133 + len = offsetof(struct xfs_dir2_data_entry, name[0]) + namelen + 134 + sizeof(xfs_dir2_data_off_t) /* tag */; 135 + if (xfs_sb_version_hasftype(&mp->m_sb)) 136 + len += sizeof(uint8_t); 137 + return round_up(len, XFS_DIR2_DATA_ALIGN); 138 + } 139 + 140 + static inline xfs_dahash_t 141 + xfs_dir2_hashname( 142 + struct xfs_mount *mp, 143 + struct xfs_name *name) 144 + { 145 + if (unlikely(xfs_sb_version_hasasciici(&mp->m_sb))) 146 + return xfs_ascii_ci_hashname(name); 147 + return xfs_da_hashname(name->name, name->len); 148 + } 149 + 150 + static inline enum xfs_dacmp 151 + xfs_dir2_compname( 152 + struct xfs_da_args *args, 153 + const unsigned char *name, 154 + int len) 155 + { 156 + if (unlikely(xfs_sb_version_hasasciici(&args->dp->i_mount->m_sb))) 157 + return xfs_ascii_ci_compname(args, name, len); 158 + return xfs_da_compname(args, name, len); 159 + } 182 160 183 161 #endif /* __XFS_DIR2_PRIV_H__ */
+254 -170
fs/xfs/libxfs/xfs_dir2_sf.c
··· 37 37 static void xfs_dir2_sf_toino4(xfs_da_args_t *args); 38 38 static void xfs_dir2_sf_toino8(xfs_da_args_t *args); 39 39 40 + static int 41 + xfs_dir2_sf_entsize( 42 + struct xfs_mount *mp, 43 + struct xfs_dir2_sf_hdr *hdr, 44 + int len) 45 + { 46 + int count = len; 47 + 48 + count += sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ 49 + count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */ 50 + 51 + if (xfs_sb_version_hasftype(&mp->m_sb)) 52 + count += sizeof(uint8_t); 53 + return count; 54 + } 55 + 56 + struct xfs_dir2_sf_entry * 57 + xfs_dir2_sf_nextentry( 58 + struct xfs_mount *mp, 59 + struct xfs_dir2_sf_hdr *hdr, 60 + struct xfs_dir2_sf_entry *sfep) 61 + { 62 + return (void *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen); 63 + } 64 + 65 + /* 66 + * In short-form directory entries the inode numbers are stored at variable 67 + * offset behind the entry name. If the entry stores a filetype value, then it 68 + * sits between the name and the inode number. The actual inode numbers can 69 + * come in two formats as well, either 4 bytes or 8 bytes wide. 70 + */ 71 + xfs_ino_t 72 + xfs_dir2_sf_get_ino( 73 + struct xfs_mount *mp, 74 + struct xfs_dir2_sf_hdr *hdr, 75 + struct xfs_dir2_sf_entry *sfep) 76 + { 77 + uint8_t *from = sfep->name + sfep->namelen; 78 + 79 + if (xfs_sb_version_hasftype(&mp->m_sb)) 80 + from++; 81 + 82 + if (!hdr->i8count) 83 + return get_unaligned_be32(from); 84 + return get_unaligned_be64(from) & XFS_MAXINUMBER; 85 + } 86 + 87 + static void 88 + xfs_dir2_sf_put_ino( 89 + struct xfs_mount *mp, 90 + struct xfs_dir2_sf_hdr *hdr, 91 + struct xfs_dir2_sf_entry *sfep, 92 + xfs_ino_t ino) 93 + { 94 + uint8_t *to = sfep->name + sfep->namelen; 95 + 96 + ASSERT(ino <= XFS_MAXINUMBER); 97 + 98 + if (xfs_sb_version_hasftype(&mp->m_sb)) 99 + to++; 100 + 101 + if (hdr->i8count) 102 + put_unaligned_be64(ino, to); 103 + else 104 + put_unaligned_be32(ino, to); 105 + } 106 + 107 + xfs_ino_t 108 + xfs_dir2_sf_get_parent_ino( 109 + struct xfs_dir2_sf_hdr *hdr) 110 + { 111 + if (!hdr->i8count) 112 + return get_unaligned_be32(hdr->parent); 113 + return get_unaligned_be64(hdr->parent) & XFS_MAXINUMBER; 114 + } 115 + 116 + void 117 + xfs_dir2_sf_put_parent_ino( 118 + struct xfs_dir2_sf_hdr *hdr, 119 + xfs_ino_t ino) 120 + { 121 + ASSERT(ino <= XFS_MAXINUMBER); 122 + 123 + if (hdr->i8count) 124 + put_unaligned_be64(ino, hdr->parent); 125 + else 126 + put_unaligned_be32(ino, hdr->parent); 127 + } 128 + 129 + /* 130 + * The file type field is stored at the end of the name for filetype enabled 131 + * shortform directories, or not at all otherwise. 132 + */ 133 + uint8_t 134 + xfs_dir2_sf_get_ftype( 135 + struct xfs_mount *mp, 136 + struct xfs_dir2_sf_entry *sfep) 137 + { 138 + if (xfs_sb_version_hasftype(&mp->m_sb)) { 139 + uint8_t ftype = sfep->name[sfep->namelen]; 140 + 141 + if (ftype < XFS_DIR3_FT_MAX) 142 + return ftype; 143 + } 144 + 145 + return XFS_DIR3_FT_UNKNOWN; 146 + } 147 + 148 + static void 149 + xfs_dir2_sf_put_ftype( 150 + struct xfs_mount *mp, 151 + struct xfs_dir2_sf_entry *sfep, 152 + uint8_t ftype) 153 + { 154 + ASSERT(ftype < XFS_DIR3_FT_MAX); 155 + 156 + if (xfs_sb_version_hasftype(&mp->m_sb)) 157 + sfep->name[sfep->namelen] = ftype; 158 + } 159 + 40 160 /* 41 161 * Given a block directory (dp/block), calculate its size as a shortform (sf) 42 162 * directory and a header for the sf directory, if it will fit it the ··· 245 125 */ 246 126 sfhp->count = count; 247 127 sfhp->i8count = i8count; 248 - dp->d_ops->sf_put_parent_ino(sfhp, parent); 128 + xfs_dir2_sf_put_parent_ino(sfhp, parent); 249 129 return size; 250 130 } 251 131 ··· 255 135 */ 256 136 int /* error */ 257 137 xfs_dir2_block_to_sf( 258 - xfs_da_args_t *args, /* operation arguments */ 138 + struct xfs_da_args *args, /* operation arguments */ 259 139 struct xfs_buf *bp, 260 140 int size, /* shortform directory size */ 261 - xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ 141 + struct xfs_dir2_sf_hdr *sfhp) /* shortform directory hdr */ 262 142 { 263 - xfs_dir2_data_hdr_t *hdr; /* block header */ 264 - xfs_dir2_data_entry_t *dep; /* data entry pointer */ 265 - xfs_inode_t *dp; /* incore directory inode */ 266 - xfs_dir2_data_unused_t *dup; /* unused data pointer */ 267 - char *endptr; /* end of data entries */ 143 + struct xfs_inode *dp = args->dp; 144 + struct xfs_mount *mp = dp->i_mount; 268 145 int error; /* error return value */ 269 146 int logflags; /* inode logging flags */ 270 - xfs_mount_t *mp; /* filesystem mount point */ 271 - char *ptr; /* current data pointer */ 272 - xfs_dir2_sf_entry_t *sfep; /* shortform entry */ 273 - xfs_dir2_sf_hdr_t *sfp; /* shortform directory header */ 274 - xfs_dir2_sf_hdr_t *dst; /* temporary data buffer */ 147 + struct xfs_dir2_sf_entry *sfep; /* shortform entry */ 148 + struct xfs_dir2_sf_hdr *sfp; /* shortform directory header */ 149 + unsigned int offset = args->geo->data_entry_offset; 150 + unsigned int end; 275 151 276 152 trace_xfs_dir2_block_to_sf(args); 277 153 278 - dp = args->dp; 279 - mp = dp->i_mount; 280 - 281 154 /* 282 - * allocate a temporary destination buffer the size of the inode 283 - * to format the data into. Once we have formatted the data, we 284 - * can free the block and copy the formatted data into the inode literal 285 - * area. 155 + * Allocate a temporary destination buffer the size of the inode to 156 + * format the data into. Once we have formatted the data, we can free 157 + * the block and copy the formatted data into the inode literal area. 286 158 */ 287 - dst = kmem_alloc(mp->m_sb.sb_inodesize, 0); 288 - hdr = bp->b_addr; 289 - 290 - /* 291 - * Copy the header into the newly allocate local space. 292 - */ 293 - sfp = (xfs_dir2_sf_hdr_t *)dst; 159 + sfp = kmem_alloc(mp->m_sb.sb_inodesize, 0); 294 160 memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); 295 161 296 162 /* 297 - * Set up to loop over the block's entries. 163 + * Loop over the active and unused entries. Stop when we reach the 164 + * leaf/tail portion of the block. 298 165 */ 299 - ptr = (char *)dp->d_ops->data_entry_p(hdr); 300 - endptr = xfs_dir3_data_endp(args->geo, hdr); 166 + end = xfs_dir3_data_end_offset(args->geo, bp->b_addr); 301 167 sfep = xfs_dir2_sf_firstentry(sfp); 302 - /* 303 - * Loop over the active and unused entries. 304 - * Stop when we reach the leaf/tail portion of the block. 305 - */ 306 - while (ptr < endptr) { 168 + while (offset < end) { 169 + struct xfs_dir2_data_unused *dup = bp->b_addr + offset; 170 + struct xfs_dir2_data_entry *dep = bp->b_addr + offset; 171 + 307 172 /* 308 173 * If it's unused, just skip over it. 309 174 */ 310 - dup = (xfs_dir2_data_unused_t *)ptr; 311 175 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 312 - ptr += be16_to_cpu(dup->length); 176 + offset += be16_to_cpu(dup->length); 313 177 continue; 314 178 } 315 - dep = (xfs_dir2_data_entry_t *)ptr; 179 + 316 180 /* 317 181 * Skip . 318 182 */ ··· 308 204 else if (dep->namelen == 2 && 309 205 dep->name[0] == '.' && dep->name[1] == '.') 310 206 ASSERT(be64_to_cpu(dep->inumber) == 311 - dp->d_ops->sf_get_parent_ino(sfp)); 207 + xfs_dir2_sf_get_parent_ino(sfp)); 312 208 /* 313 209 * Normal entry, copy it into shortform. 314 210 */ 315 211 else { 316 212 sfep->namelen = dep->namelen; 317 - xfs_dir2_sf_put_offset(sfep, 318 - (xfs_dir2_data_aoff_t) 319 - ((char *)dep - (char *)hdr)); 213 + xfs_dir2_sf_put_offset(sfep, offset); 320 214 memcpy(sfep->name, dep->name, dep->namelen); 321 - dp->d_ops->sf_put_ino(sfp, sfep, 215 + xfs_dir2_sf_put_ino(mp, sfp, sfep, 322 216 be64_to_cpu(dep->inumber)); 323 - dp->d_ops->sf_put_ftype(sfep, 324 - dp->d_ops->data_get_ftype(dep)); 217 + xfs_dir2_sf_put_ftype(mp, sfep, 218 + xfs_dir2_data_get_ftype(mp, dep)); 325 219 326 - sfep = dp->d_ops->sf_nextentry(sfp, sfep); 220 + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 327 221 } 328 - ptr += dp->d_ops->data_entsize(dep->namelen); 222 + offset += xfs_dir2_data_entsize(mp, dep->namelen); 329 223 } 330 224 ASSERT((char *)sfep - (char *)sfp == size); 331 225 ··· 342 240 * Convert the inode to local format and copy the data in. 343 241 */ 344 242 ASSERT(dp->i_df.if_bytes == 0); 345 - xfs_init_local_fork(dp, XFS_DATA_FORK, dst, size); 243 + xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size); 346 244 dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; 347 245 dp->i_d.di_size = size; 348 246 ··· 350 248 xfs_dir2_sf_check(args); 351 249 out: 352 250 xfs_trans_log_inode(args->trans, dp, logflags); 353 - kmem_free(dst); 251 + kmem_free(sfp); 354 252 return error; 355 253 } 356 254 ··· 379 277 ASSERT(xfs_dir2_sf_lookup(args) == -ENOENT); 380 278 dp = args->dp; 381 279 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 382 - /* 383 - * Make sure the shortform value has some of its header. 384 - */ 385 - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 386 - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); 387 - return -EIO; 388 - } 280 + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); 389 281 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 390 282 ASSERT(dp->i_df.if_u1.if_data != NULL); 391 283 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; ··· 387 291 /* 388 292 * Compute entry (and change in) size. 389 293 */ 390 - incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen); 294 + incr_isize = xfs_dir2_sf_entsize(dp->i_mount, sfp, args->namelen); 391 295 objchange = 0; 392 296 393 297 /* ··· 460 364 xfs_dir2_data_aoff_t offset, /* offset to use for new ent */ 461 365 int new_isize) /* new directory size */ 462 366 { 367 + struct xfs_inode *dp = args->dp; 368 + struct xfs_mount *mp = dp->i_mount; 463 369 int byteoff; /* byte offset in sf dir */ 464 - xfs_inode_t *dp; /* incore directory inode */ 465 370 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ 466 - 467 - dp = args->dp; 468 371 469 372 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 470 373 byteoff = (int)((char *)sfep - (char *)sfp); 471 374 /* 472 375 * Grow the in-inode space. 473 376 */ 474 - xfs_idata_realloc(dp, dp->d_ops->sf_entsize(sfp, args->namelen), 377 + xfs_idata_realloc(dp, xfs_dir2_sf_entsize(mp, sfp, args->namelen), 475 378 XFS_DATA_FORK); 476 379 /* 477 380 * Need to set up again due to realloc of the inode data. ··· 483 388 sfep->namelen = args->namelen; 484 389 xfs_dir2_sf_put_offset(sfep, offset); 485 390 memcpy(sfep->name, args->name, sfep->namelen); 486 - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); 487 - dp->d_ops->sf_put_ftype(sfep, args->filetype); 391 + xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); 392 + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); 488 393 489 394 /* 490 395 * Update the header and inode. ··· 511 416 int objchange, /* changing inode number size */ 512 417 int new_isize) /* new directory size */ 513 418 { 419 + struct xfs_inode *dp = args->dp; 420 + struct xfs_mount *mp = dp->i_mount; 514 421 int add_datasize; /* data size need for new ent */ 515 422 char *buf; /* buffer for old */ 516 - xfs_inode_t *dp; /* incore directory inode */ 517 423 int eof; /* reached end of old dir */ 518 424 int nbytes; /* temp for byte copies */ 519 425 xfs_dir2_data_aoff_t new_offset; /* next offset value */ ··· 528 432 /* 529 433 * Copy the old directory to the stack buffer. 530 434 */ 531 - dp = args->dp; 532 - 533 435 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 534 436 old_isize = (int)dp->i_d.di_size; 535 437 buf = kmem_alloc(old_isize, 0); ··· 538 444 * to insert the new entry. 539 445 * If it's going to end up at the end then oldsfep will point there. 540 446 */ 541 - for (offset = dp->d_ops->data_first_offset, 447 + for (offset = args->geo->data_first_offset, 542 448 oldsfep = xfs_dir2_sf_firstentry(oldsfp), 543 - add_datasize = dp->d_ops->data_entsize(args->namelen), 449 + add_datasize = xfs_dir2_data_entsize(mp, args->namelen), 544 450 eof = (char *)oldsfep == &buf[old_isize]; 545 451 !eof; 546 - offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen), 547 - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep), 452 + offset = new_offset + xfs_dir2_data_entsize(mp, oldsfep->namelen), 453 + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep), 548 454 eof = (char *)oldsfep == &buf[old_isize]) { 549 455 new_offset = xfs_dir2_sf_get_offset(oldsfep); 550 456 if (offset + add_datasize <= new_offset) ··· 573 479 sfep->namelen = args->namelen; 574 480 xfs_dir2_sf_put_offset(sfep, offset); 575 481 memcpy(sfep->name, args->name, sfep->namelen); 576 - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); 577 - dp->d_ops->sf_put_ftype(sfep, args->filetype); 482 + xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); 483 + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); 578 484 sfp->count++; 579 485 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) 580 486 sfp->i8count++; ··· 582 488 * If there's more left to copy, do that. 583 489 */ 584 490 if (!eof) { 585 - sfep = dp->d_ops->sf_nextentry(sfp, sfep); 491 + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 586 492 memcpy(sfep, oldsfep, old_isize - nbytes); 587 493 } 588 494 kmem_free(buf); ··· 604 510 xfs_dir2_sf_entry_t **sfepp, /* out(1): new entry ptr */ 605 511 xfs_dir2_data_aoff_t *offsetp) /* out(1): new offset */ 606 512 { 607 - xfs_inode_t *dp; /* incore directory inode */ 513 + struct xfs_inode *dp = args->dp; 514 + struct xfs_mount *mp = dp->i_mount; 608 515 int holefit; /* found hole it will fit in */ 609 516 int i; /* entry number */ 610 517 xfs_dir2_data_aoff_t offset; /* data block offset */ ··· 614 519 int size; /* entry's data size */ 615 520 int used; /* data bytes used */ 616 521 617 - dp = args->dp; 618 - 619 522 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 620 - size = dp->d_ops->data_entsize(args->namelen); 621 - offset = dp->d_ops->data_first_offset; 523 + size = xfs_dir2_data_entsize(mp, args->namelen); 524 + offset = args->geo->data_first_offset; 622 525 sfep = xfs_dir2_sf_firstentry(sfp); 623 526 holefit = 0; 624 527 /* ··· 628 535 if (!holefit) 629 536 holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); 630 537 offset = xfs_dir2_sf_get_offset(sfep) + 631 - dp->d_ops->data_entsize(sfep->namelen); 632 - sfep = dp->d_ops->sf_nextentry(sfp, sfep); 538 + xfs_dir2_data_entsize(mp, sfep->namelen); 539 + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 633 540 } 634 541 /* 635 542 * Calculate data bytes used excluding the new entry, if this ··· 671 578 xfs_dir2_sf_check( 672 579 xfs_da_args_t *args) /* operation arguments */ 673 580 { 674 - xfs_inode_t *dp; /* incore directory inode */ 581 + struct xfs_inode *dp = args->dp; 582 + struct xfs_mount *mp = dp->i_mount; 675 583 int i; /* entry number */ 676 584 int i8count; /* number of big inode#s */ 677 585 xfs_ino_t ino; /* entry inode number */ ··· 680 586 xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */ 681 587 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ 682 588 683 - dp = args->dp; 684 - 685 589 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 686 - offset = dp->d_ops->data_first_offset; 687 - ino = dp->d_ops->sf_get_parent_ino(sfp); 590 + offset = args->geo->data_first_offset; 591 + ino = xfs_dir2_sf_get_parent_ino(sfp); 688 592 i8count = ino > XFS_DIR2_MAX_SHORT_INUM; 689 593 690 594 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); 691 595 i < sfp->count; 692 - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { 596 + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { 693 597 ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); 694 - ino = dp->d_ops->sf_get_ino(sfp, sfep); 598 + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); 695 599 i8count += ino > XFS_DIR2_MAX_SHORT_INUM; 696 600 offset = 697 601 xfs_dir2_sf_get_offset(sfep) + 698 - dp->d_ops->data_entsize(sfep->namelen); 699 - ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); 602 + xfs_dir2_data_entsize(mp, sfep->namelen); 603 + ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX); 700 604 } 701 605 ASSERT(i8count == sfp->i8count); 702 606 ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); ··· 714 622 struct xfs_dir2_sf_entry *sfep; 715 623 struct xfs_dir2_sf_entry *next_sfep; 716 624 char *endp; 717 - const struct xfs_dir_ops *dops; 718 625 struct xfs_ifork *ifp; 719 626 xfs_ino_t ino; 720 627 int i; 721 628 int i8count; 722 629 int offset; 723 - int size; 630 + int64_t size; 724 631 int error; 725 632 uint8_t filetype; 726 633 727 634 ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); 728 - /* 729 - * xfs_iread calls us before xfs_setup_inode sets up ip->d_ops, 730 - * so we can only trust the mountpoint to have the right pointer. 731 - */ 732 - dops = xfs_dir_get_ops(mp, NULL); 733 635 734 636 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 735 637 sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; ··· 739 653 endp = (char *)sfp + size; 740 654 741 655 /* Check .. entry */ 742 - ino = dops->sf_get_parent_ino(sfp); 656 + ino = xfs_dir2_sf_get_parent_ino(sfp); 743 657 i8count = ino > XFS_DIR2_MAX_SHORT_INUM; 744 658 error = xfs_dir_ino_validate(mp, ino); 745 659 if (error) 746 660 return __this_address; 747 - offset = dops->data_first_offset; 661 + offset = mp->m_dir_geo->data_first_offset; 748 662 749 663 /* Check all reported entries */ 750 664 sfep = xfs_dir2_sf_firstentry(sfp); ··· 766 680 * within the data buffer. The next entry starts after the 767 681 * name component, so nextentry is an acceptable test. 768 682 */ 769 - next_sfep = dops->sf_nextentry(sfp, sfep); 683 + next_sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 770 684 if (endp < (char *)next_sfep) 771 685 return __this_address; 772 686 ··· 775 689 return __this_address; 776 690 777 691 /* Check the inode number. */ 778 - ino = dops->sf_get_ino(sfp, sfep); 692 + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); 779 693 i8count += ino > XFS_DIR2_MAX_SHORT_INUM; 780 694 error = xfs_dir_ino_validate(mp, ino); 781 695 if (error) 782 696 return __this_address; 783 697 784 698 /* Check the file type. */ 785 - filetype = dops->sf_get_ftype(sfep); 699 + filetype = xfs_dir2_sf_get_ftype(mp, sfep); 786 700 if (filetype >= XFS_DIR3_FT_MAX) 787 701 return __this_address; 788 702 789 703 offset = xfs_dir2_sf_get_offset(sfep) + 790 - dops->data_entsize(sfep->namelen); 704 + xfs_dir2_data_entsize(mp, sfep->namelen); 791 705 792 706 sfep = next_sfep; 793 707 } ··· 849 763 /* 850 764 * Now can put in the inode number, since i8count is set. 851 765 */ 852 - dp->d_ops->sf_put_parent_ino(sfp, pino); 766 + xfs_dir2_sf_put_parent_ino(sfp, pino); 853 767 sfp->count = 0; 854 768 dp->i_d.di_size = size; 855 769 xfs_dir2_sf_check(args); ··· 865 779 xfs_dir2_sf_lookup( 866 780 xfs_da_args_t *args) /* operation arguments */ 867 781 { 868 - xfs_inode_t *dp; /* incore directory inode */ 782 + struct xfs_inode *dp = args->dp; 783 + struct xfs_mount *mp = dp->i_mount; 869 784 int i; /* entry index */ 870 785 int error; 871 786 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ ··· 877 790 trace_xfs_dir2_sf_lookup(args); 878 791 879 792 xfs_dir2_sf_check(args); 880 - dp = args->dp; 881 793 882 794 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 883 - /* 884 - * Bail out if the directory is way too short. 885 - */ 886 - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 887 - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); 888 - return -EIO; 889 - } 795 + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); 890 796 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 891 797 ASSERT(dp->i_df.if_u1.if_data != NULL); 892 798 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; ··· 898 818 */ 899 819 if (args->namelen == 2 && 900 820 args->name[0] == '.' && args->name[1] == '.') { 901 - args->inumber = dp->d_ops->sf_get_parent_ino(sfp); 821 + args->inumber = xfs_dir2_sf_get_parent_ino(sfp); 902 822 args->cmpresult = XFS_CMP_EXACT; 903 823 args->filetype = XFS_DIR3_FT_DIR; 904 824 return -EEXIST; ··· 908 828 */ 909 829 ci_sfep = NULL; 910 830 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; 911 - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { 831 + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { 912 832 /* 913 833 * Compare name and if it's an exact match, return the inode 914 834 * number. If it's the first case-insensitive match, store the 915 835 * inode number and continue looking for an exact match. 916 836 */ 917 - cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, 918 - sfep->namelen); 837 + cmp = xfs_dir2_compname(args, sfep->name, sfep->namelen); 919 838 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 920 839 args->cmpresult = cmp; 921 - args->inumber = dp->d_ops->sf_get_ino(sfp, sfep); 922 - args->filetype = dp->d_ops->sf_get_ftype(sfep); 840 + args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep); 841 + args->filetype = xfs_dir2_sf_get_ftype(mp, sfep); 923 842 if (cmp == XFS_CMP_EXACT) 924 843 return -EEXIST; 925 844 ci_sfep = sfep; ··· 943 864 xfs_dir2_sf_removename( 944 865 xfs_da_args_t *args) 945 866 { 867 + struct xfs_inode *dp = args->dp; 868 + struct xfs_mount *mp = dp->i_mount; 946 869 int byteoff; /* offset of removed entry */ 947 - xfs_inode_t *dp; /* incore directory inode */ 948 870 int entsize; /* this entry's size */ 949 871 int i; /* shortform entry index */ 950 872 int newsize; /* new inode size */ ··· 955 875 956 876 trace_xfs_dir2_sf_removename(args); 957 877 958 - dp = args->dp; 959 - 960 878 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 961 879 oldsize = (int)dp->i_d.di_size; 962 - /* 963 - * Bail out if the directory is way too short. 964 - */ 965 - if (oldsize < offsetof(xfs_dir2_sf_hdr_t, parent)) { 966 - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); 967 - return -EIO; 968 - } 880 + ASSERT(oldsize >= offsetof(struct xfs_dir2_sf_hdr, parent)); 969 881 ASSERT(dp->i_df.if_bytes == oldsize); 970 882 ASSERT(dp->i_df.if_u1.if_data != NULL); 971 883 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; ··· 967 895 * Find the one we're deleting. 968 896 */ 969 897 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; 970 - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { 898 + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { 971 899 if (xfs_da_compname(args, sfep->name, sfep->namelen) == 972 900 XFS_CMP_EXACT) { 973 - ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) == 901 + ASSERT(xfs_dir2_sf_get_ino(mp, sfp, sfep) == 974 902 args->inumber); 975 903 break; 976 904 } ··· 984 912 * Calculate sizes. 985 913 */ 986 914 byteoff = (int)((char *)sfep - (char *)sfp); 987 - entsize = dp->d_ops->sf_entsize(sfp, args->namelen); 915 + entsize = xfs_dir2_sf_entsize(mp, sfp, args->namelen); 988 916 newsize = oldsize - entsize; 989 917 /* 990 918 * Copy the part if any after the removed entry, sliding it down. ··· 1017 945 } 1018 946 1019 947 /* 948 + * Check whether the sf dir replace operation need more blocks. 949 + */ 950 + bool 951 + xfs_dir2_sf_replace_needblock( 952 + struct xfs_inode *dp, 953 + xfs_ino_t inum) 954 + { 955 + int newsize; 956 + struct xfs_dir2_sf_hdr *sfp; 957 + 958 + if (dp->i_d.di_format != XFS_DINODE_FMT_LOCAL) 959 + return false; 960 + 961 + sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data; 962 + newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF; 963 + 964 + return inum > XFS_DIR2_MAX_SHORT_INUM && 965 + sfp->i8count == 0 && newsize > XFS_IFORK_DSIZE(dp); 966 + } 967 + 968 + /* 1020 969 * Replace the inode number of an entry in a shortform directory. 1021 970 */ 1022 971 int /* error */ 1023 972 xfs_dir2_sf_replace( 1024 973 xfs_da_args_t *args) /* operation arguments */ 1025 974 { 1026 - xfs_inode_t *dp; /* incore directory inode */ 975 + struct xfs_inode *dp = args->dp; 976 + struct xfs_mount *mp = dp->i_mount; 1027 977 int i; /* entry index */ 1028 978 xfs_ino_t ino=0; /* entry old inode number */ 1029 979 int i8elevated; /* sf_toino8 set i8count=1 */ ··· 1054 960 1055 961 trace_xfs_dir2_sf_replace(args); 1056 962 1057 - dp = args->dp; 1058 - 1059 963 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 1060 - /* 1061 - * Bail out if the shortform directory is way too small. 1062 - */ 1063 - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 1064 - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); 1065 - return -EIO; 1066 - } 964 + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); 1067 965 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 1068 966 ASSERT(dp->i_df.if_u1.if_data != NULL); 1069 967 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; ··· 1066 980 */ 1067 981 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { 1068 982 int error; /* error return value */ 1069 - int newsize; /* new inode size */ 1070 983 1071 - newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF; 1072 984 /* 1073 985 * Won't fit as shortform, convert to block then do replace. 1074 986 */ 1075 - if (newsize > XFS_IFORK_DSIZE(dp)) { 987 + if (xfs_dir2_sf_replace_needblock(dp, args->inumber)) { 1076 988 error = xfs_dir2_sf_to_block(args); 1077 - if (error) { 989 + if (error) 1078 990 return error; 1079 - } 1080 991 return xfs_dir2_block_replace(args); 1081 992 } 1082 993 /* ··· 1091 1008 */ 1092 1009 if (args->namelen == 2 && 1093 1010 args->name[0] == '.' && args->name[1] == '.') { 1094 - ino = dp->d_ops->sf_get_parent_ino(sfp); 1011 + ino = xfs_dir2_sf_get_parent_ino(sfp); 1095 1012 ASSERT(args->inumber != ino); 1096 - dp->d_ops->sf_put_parent_ino(sfp, args->inumber); 1013 + xfs_dir2_sf_put_parent_ino(sfp, args->inumber); 1097 1014 } 1098 1015 /* 1099 1016 * Normal entry, look for the name. 1100 1017 */ 1101 1018 else { 1102 1019 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; 1103 - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { 1020 + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { 1104 1021 if (xfs_da_compname(args, sfep->name, sfep->namelen) == 1105 1022 XFS_CMP_EXACT) { 1106 - ino = dp->d_ops->sf_get_ino(sfp, sfep); 1023 + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); 1107 1024 ASSERT(args->inumber != ino); 1108 - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); 1109 - dp->d_ops->sf_put_ftype(sfep, args->filetype); 1025 + xfs_dir2_sf_put_ino(mp, sfp, sfep, 1026 + args->inumber); 1027 + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); 1110 1028 break; 1111 1029 } 1112 1030 } ··· 1160 1076 xfs_dir2_sf_toino4( 1161 1077 xfs_da_args_t *args) /* operation arguments */ 1162 1078 { 1079 + struct xfs_inode *dp = args->dp; 1080 + struct xfs_mount *mp = dp->i_mount; 1163 1081 char *buf; /* old dir's buffer */ 1164 - xfs_inode_t *dp; /* incore directory inode */ 1165 1082 int i; /* entry index */ 1166 1083 int newsize; /* new inode size */ 1167 1084 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ ··· 1172 1087 xfs_dir2_sf_hdr_t *sfp; /* new sf directory */ 1173 1088 1174 1089 trace_xfs_dir2_sf_toino4(args); 1175 - 1176 - dp = args->dp; 1177 1090 1178 1091 /* 1179 1092 * Copy the old directory to the buffer. ··· 1199 1116 */ 1200 1117 sfp->count = oldsfp->count; 1201 1118 sfp->i8count = 0; 1202 - dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp)); 1119 + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); 1203 1120 /* 1204 1121 * Copy the entries field by field. 1205 1122 */ 1206 1123 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), 1207 1124 oldsfep = xfs_dir2_sf_firstentry(oldsfp); 1208 1125 i < sfp->count; 1209 - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), 1210 - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { 1126 + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep), 1127 + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) { 1211 1128 sfep->namelen = oldsfep->namelen; 1212 1129 memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); 1213 1130 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1214 - dp->d_ops->sf_put_ino(sfp, sfep, 1215 - dp->d_ops->sf_get_ino(oldsfp, oldsfep)); 1216 - dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); 1131 + xfs_dir2_sf_put_ino(mp, sfp, sfep, 1132 + xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); 1133 + xfs_dir2_sf_put_ftype(mp, sfep, 1134 + xfs_dir2_sf_get_ftype(mp, oldsfep)); 1217 1135 } 1218 1136 /* 1219 1137 * Clean up the inode. ··· 1233 1149 xfs_dir2_sf_toino8( 1234 1150 xfs_da_args_t *args) /* operation arguments */ 1235 1151 { 1152 + struct xfs_inode *dp = args->dp; 1153 + struct xfs_mount *mp = dp->i_mount; 1236 1154 char *buf; /* old dir's buffer */ 1237 - xfs_inode_t *dp; /* incore directory inode */ 1238 1155 int i; /* entry index */ 1239 1156 int newsize; /* new inode size */ 1240 1157 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ ··· 1245 1160 xfs_dir2_sf_hdr_t *sfp; /* new sf directory */ 1246 1161 1247 1162 trace_xfs_dir2_sf_toino8(args); 1248 - 1249 - dp = args->dp; 1250 1163 1251 1164 /* 1252 1165 * Copy the old directory to the buffer. ··· 1272 1189 */ 1273 1190 sfp->count = oldsfp->count; 1274 1191 sfp->i8count = 1; 1275 - dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp)); 1192 + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); 1276 1193 /* 1277 1194 * Copy the entries field by field. 1278 1195 */ 1279 1196 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), 1280 1197 oldsfep = xfs_dir2_sf_firstentry(oldsfp); 1281 1198 i < sfp->count; 1282 - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), 1283 - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { 1199 + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep), 1200 + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) { 1284 1201 sfep->namelen = oldsfep->namelen; 1285 1202 memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); 1286 1203 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1287 - dp->d_ops->sf_put_ino(sfp, sfep, 1288 - dp->d_ops->sf_get_ino(oldsfp, oldsfep)); 1289 - dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); 1204 + xfs_dir2_sf_put_ino(mp, sfp, sfep, 1205 + xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); 1206 + xfs_dir2_sf_put_ftype(mp, sfep, 1207 + xfs_dir2_sf_get_ftype(mp, oldsfep)); 1290 1208 } 1291 1209 /* 1292 1210 * Clean up the inode.
+4 -4
fs/xfs/libxfs/xfs_dquot_buf.c
··· 35 35 36 36 xfs_failaddr_t 37 37 xfs_dquot_verify( 38 - struct xfs_mount *mp, 39 - xfs_disk_dquot_t *ddq, 40 - xfs_dqid_t id, 41 - uint type) /* used only during quotacheck */ 38 + struct xfs_mount *mp, 39 + struct xfs_disk_dquot *ddq, 40 + xfs_dqid_t id, 41 + uint type) /* used only during quotacheck */ 42 42 { 43 43 /* 44 44 * We can encounter an uninitialized dquot buffer for 2 reasons:
+7 -7
fs/xfs/libxfs/xfs_format.h
··· 920 920 * This enum is used in string mapping in xfs_trace.h; please keep the 921 921 * TRACE_DEFINE_ENUMs for it up to date. 922 922 */ 923 - typedef enum xfs_dinode_fmt { 923 + enum xfs_dinode_fmt { 924 924 XFS_DINODE_FMT_DEV, /* xfs_dev_t */ 925 925 XFS_DINODE_FMT_LOCAL, /* bulk data */ 926 926 XFS_DINODE_FMT_EXTENTS, /* struct xfs_bmbt_rec */ 927 927 XFS_DINODE_FMT_BTREE, /* struct xfs_bmdr_block */ 928 928 XFS_DINODE_FMT_UUID /* added long ago, but never used */ 929 - } xfs_dinode_fmt_t; 929 + }; 930 930 931 931 #define XFS_INODE_FORMAT_STR \ 932 932 { XFS_DINODE_FMT_DEV, "dev" }, \ ··· 1144 1144 1145 1145 /* 1146 1146 * This is the main portion of the on-disk representation of quota 1147 - * information for a user. This is the q_core of the xfs_dquot_t that 1147 + * information for a user. This is the q_core of the struct xfs_dquot that 1148 1148 * is kept in kernel memory. We pad this with some more expansion room 1149 1149 * to construct the on disk structure. 1150 1150 */ 1151 - typedef struct xfs_disk_dquot { 1151 + struct xfs_disk_dquot { 1152 1152 __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */ 1153 1153 __u8 d_version; /* dquot version */ 1154 1154 __u8 d_flags; /* XFS_DQ_USER/PROJ/GROUP */ ··· 1171 1171 __be32 d_rtbtimer; /* similar to above; for RT disk blocks */ 1172 1172 __be16 d_rtbwarns; /* warnings issued wrt RT disk blocks */ 1173 1173 __be16 d_pad; 1174 - } xfs_disk_dquot_t; 1174 + }; 1175 1175 1176 1176 /* 1177 1177 * This is what goes on disk. This is separated from the xfs_disk_dquot because 1178 1178 * carrying the unnecessary padding would be a waste of memory. 1179 1179 */ 1180 1180 typedef struct xfs_dqblk { 1181 - xfs_disk_dquot_t dd_diskdq; /* portion that lives incore as well */ 1182 - char dd_fill[4]; /* filling for posterity */ 1181 + struct xfs_disk_dquot dd_diskdq; /* portion living incore as well */ 1182 + char dd_fill[4];/* filling for posterity */ 1183 1183 1184 1184 /* 1185 1185 * These two are only present on filesystems with the CRC bits set.
+2 -2
fs/xfs/libxfs/xfs_fs.h
··· 324 324 * Structures returned from ioctl XFS_IOC_FSBULKSTAT & XFS_IOC_FSBULKSTAT_SINGLE 325 325 */ 326 326 typedef struct xfs_bstime { 327 - time_t tv_sec; /* seconds */ 327 + __kernel_long_t tv_sec; /* seconds */ 328 328 __s32 tv_nsec; /* and nanoseconds */ 329 329 } xfs_bstime_t; 330 330 ··· 416 416 417 417 /* 418 418 * Project quota id helpers (previously projid was 16bit only 419 - * and using two 16bit values to hold new 32bit projid was choosen 419 + * and using two 16bit values to hold new 32bit projid was chosen 420 420 * to retain compatibility with "old" filesystems). 421 421 */ 422 422 static inline uint32_t
+86 -31
fs/xfs/libxfs/xfs_ialloc.c
··· 544 544 nrec->ir_free, &i); 545 545 if (error) 546 546 goto error; 547 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error); 547 + if (XFS_IS_CORRUPT(mp, i != 1)) { 548 + error = -EFSCORRUPTED; 549 + goto error; 550 + } 548 551 549 552 goto out; 550 553 } ··· 560 557 error = xfs_inobt_get_rec(cur, &rec, &i); 561 558 if (error) 562 559 goto error; 563 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error); 564 - XFS_WANT_CORRUPTED_GOTO(mp, 565 - rec.ir_startino == nrec->ir_startino, 566 - error); 560 + if (XFS_IS_CORRUPT(mp, i != 1)) { 561 + error = -EFSCORRUPTED; 562 + goto error; 563 + } 564 + if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) { 565 + error = -EFSCORRUPTED; 566 + goto error; 567 + } 567 568 568 569 /* 569 570 * This should never fail. If we have coexisting records that 570 571 * cannot merge, something is seriously wrong. 571 572 */ 572 - XFS_WANT_CORRUPTED_GOTO(mp, __xfs_inobt_can_merge(nrec, &rec), 573 - error); 573 + if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) { 574 + error = -EFSCORRUPTED; 575 + goto error; 576 + } 574 577 575 578 trace_xfs_irec_merge_pre(mp, agno, rec.ir_startino, 576 579 rec.ir_holemask, nrec->ir_startino, ··· 1066 1057 error = xfs_inobt_get_rec(cur, rec, &i); 1067 1058 if (error) 1068 1059 return error; 1069 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1060 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1061 + return -EFSCORRUPTED; 1070 1062 } 1071 1063 1072 1064 return 0; ··· 1091 1081 error = xfs_inobt_get_rec(cur, rec, &i); 1092 1082 if (error) 1093 1083 return error; 1094 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1084 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1085 + return -EFSCORRUPTED; 1095 1086 } 1096 1087 1097 1088 return 0; ··· 1172 1161 error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); 1173 1162 if (error) 1174 1163 goto error0; 1175 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1164 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1165 + error = -EFSCORRUPTED; 1166 + goto error0; 1167 + } 1176 1168 1177 1169 error = xfs_inobt_get_rec(cur, &rec, &j); 1178 1170 if (error) 1179 1171 goto error0; 1180 - XFS_WANT_CORRUPTED_GOTO(mp, j == 1, error0); 1172 + if (XFS_IS_CORRUPT(mp, j != 1)) { 1173 + error = -EFSCORRUPTED; 1174 + goto error0; 1175 + } 1181 1176 1182 1177 if (rec.ir_freecount > 0) { 1183 1178 /* ··· 1338 1321 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); 1339 1322 if (error) 1340 1323 goto error0; 1341 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1324 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1325 + error = -EFSCORRUPTED; 1326 + goto error0; 1327 + } 1342 1328 1343 1329 for (;;) { 1344 1330 error = xfs_inobt_get_rec(cur, &rec, &i); 1345 1331 if (error) 1346 1332 goto error0; 1347 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1333 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1334 + error = -EFSCORRUPTED; 1335 + goto error0; 1336 + } 1348 1337 if (rec.ir_freecount > 0) 1349 1338 break; 1350 1339 error = xfs_btree_increment(cur, 0, &i); 1351 1340 if (error) 1352 1341 goto error0; 1353 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1342 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1343 + error = -EFSCORRUPTED; 1344 + goto error0; 1345 + } 1354 1346 } 1355 1347 1356 1348 alloc_inode: ··· 1419 1393 error = xfs_inobt_get_rec(lcur, rec, &i); 1420 1394 if (error) 1421 1395 return error; 1422 - XFS_WANT_CORRUPTED_RETURN(lcur->bc_mp, i == 1); 1396 + if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1)) 1397 + return -EFSCORRUPTED; 1423 1398 1424 1399 /* 1425 1400 * See if we've landed in the parent inode record. The finobt ··· 1443 1416 error = xfs_inobt_get_rec(rcur, &rrec, &j); 1444 1417 if (error) 1445 1418 goto error_rcur; 1446 - XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, j == 1, error_rcur); 1419 + if (XFS_IS_CORRUPT(lcur->bc_mp, j != 1)) { 1420 + error = -EFSCORRUPTED; 1421 + goto error_rcur; 1422 + } 1447 1423 } 1448 1424 1449 - XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, i == 1 || j == 1, error_rcur); 1425 + if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1 && j != 1)) { 1426 + error = -EFSCORRUPTED; 1427 + goto error_rcur; 1428 + } 1450 1429 if (i == 1 && j == 1) { 1451 1430 /* 1452 1431 * Both the left and right records are valid. Choose the closer ··· 1505 1472 error = xfs_inobt_get_rec(cur, rec, &i); 1506 1473 if (error) 1507 1474 return error; 1508 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1475 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1476 + return -EFSCORRUPTED; 1509 1477 return 0; 1510 1478 } 1511 1479 } ··· 1517 1483 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); 1518 1484 if (error) 1519 1485 return error; 1520 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1486 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1487 + return -EFSCORRUPTED; 1521 1488 1522 1489 error = xfs_inobt_get_rec(cur, rec, &i); 1523 1490 if (error) 1524 1491 return error; 1525 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1492 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1493 + return -EFSCORRUPTED; 1526 1494 1527 1495 return 0; 1528 1496 } ··· 1546 1510 error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i); 1547 1511 if (error) 1548 1512 return error; 1549 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1513 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1514 + return -EFSCORRUPTED; 1550 1515 1551 1516 error = xfs_inobt_get_rec(cur, &rec, &i); 1552 1517 if (error) 1553 1518 return error; 1554 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); 1519 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) 1520 + return -EFSCORRUPTED; 1555 1521 ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) % 1556 1522 XFS_INODES_PER_CHUNK) == 0); 1557 1523 1558 1524 rec.ir_free &= ~XFS_INOBT_MASK(offset); 1559 1525 rec.ir_freecount--; 1560 1526 1561 - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, (rec.ir_free == frec->ir_free) && 1562 - (rec.ir_freecount == frec->ir_freecount)); 1527 + if (XFS_IS_CORRUPT(cur->bc_mp, 1528 + rec.ir_free != frec->ir_free || 1529 + rec.ir_freecount != frec->ir_freecount)) 1530 + return -EFSCORRUPTED; 1563 1531 1564 1532 return xfs_inobt_update(cur, &rec); 1565 1533 } ··· 1973 1933 __func__, error); 1974 1934 goto error0; 1975 1935 } 1976 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1936 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1937 + error = -EFSCORRUPTED; 1938 + goto error0; 1939 + } 1977 1940 error = xfs_inobt_get_rec(cur, &rec, &i); 1978 1941 if (error) { 1979 1942 xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.", 1980 1943 __func__, error); 1981 1944 goto error0; 1982 1945 } 1983 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); 1946 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1947 + error = -EFSCORRUPTED; 1948 + goto error0; 1949 + } 1984 1950 /* 1985 1951 * Get the offset in the inode chunk. 1986 1952 */ ··· 2098 2052 * freed an inode in a previously fully allocated chunk. If not, 2099 2053 * something is out of sync. 2100 2054 */ 2101 - XFS_WANT_CORRUPTED_GOTO(mp, ibtrec->ir_freecount == 1, error); 2055 + if (XFS_IS_CORRUPT(mp, ibtrec->ir_freecount != 1)) { 2056 + error = -EFSCORRUPTED; 2057 + goto error; 2058 + } 2102 2059 2103 2060 error = xfs_inobt_insert_rec(cur, ibtrec->ir_holemask, 2104 2061 ibtrec->ir_count, ··· 2124 2075 error = xfs_inobt_get_rec(cur, &rec, &i); 2125 2076 if (error) 2126 2077 goto error; 2127 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error); 2078 + if (XFS_IS_CORRUPT(mp, i != 1)) { 2079 + error = -EFSCORRUPTED; 2080 + goto error; 2081 + } 2128 2082 2129 2083 rec.ir_free |= XFS_INOBT_MASK(offset); 2130 2084 rec.ir_freecount++; 2131 2085 2132 - XFS_WANT_CORRUPTED_GOTO(mp, (rec.ir_free == ibtrec->ir_free) && 2133 - (rec.ir_freecount == ibtrec->ir_freecount), 2134 - error); 2086 + if (XFS_IS_CORRUPT(mp, 2087 + rec.ir_free != ibtrec->ir_free || 2088 + rec.ir_freecount != ibtrec->ir_freecount)) { 2089 + error = -EFSCORRUPTED; 2090 + goto error; 2091 + } 2135 2092 2136 2093 /* 2137 2094 * The content of inobt records should always match between the inobt
+1 -1
fs/xfs/libxfs/xfs_iext_tree.c
··· 596 596 struct xfs_ifork *ifp, 597 597 struct xfs_iext_cursor *cur) 598 598 { 599 - size_t new_size = ifp->if_bytes + sizeof(struct xfs_iext_rec); 599 + int64_t new_size = ifp->if_bytes + sizeof(struct xfs_iext_rec); 600 600 void *new; 601 601 602 602 /* account for the prev/next pointers */
+9 -12
fs/xfs/libxfs/xfs_inode_buf.c
··· 213 213 to->di_version = from->di_version; 214 214 if (to->di_version == 1) { 215 215 set_nlink(inode, be16_to_cpu(from->di_onlink)); 216 - to->di_projid_lo = 0; 217 - to->di_projid_hi = 0; 216 + to->di_projid = 0; 218 217 to->di_version = 2; 219 218 } else { 220 219 set_nlink(inode, be32_to_cpu(from->di_nlink)); 221 - to->di_projid_lo = be16_to_cpu(from->di_projid_lo); 222 - to->di_projid_hi = be16_to_cpu(from->di_projid_hi); 220 + to->di_projid = (prid_t)be16_to_cpu(from->di_projid_hi) << 16 | 221 + be16_to_cpu(from->di_projid_lo); 223 222 } 224 223 225 224 to->di_format = from->di_format; ··· 255 256 if (to->di_version == 3) { 256 257 inode_set_iversion_queried(inode, 257 258 be64_to_cpu(from->di_changecount)); 258 - to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); 259 - to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); 259 + to->di_crtime.tv_sec = be32_to_cpu(from->di_crtime.t_sec); 260 + to->di_crtime.tv_nsec = be32_to_cpu(from->di_crtime.t_nsec); 260 261 to->di_flags2 = be64_to_cpu(from->di_flags2); 261 262 to->di_cowextsize = be32_to_cpu(from->di_cowextsize); 262 263 } ··· 278 279 to->di_format = from->di_format; 279 280 to->di_uid = cpu_to_be32(from->di_uid); 280 281 to->di_gid = cpu_to_be32(from->di_gid); 281 - to->di_projid_lo = cpu_to_be16(from->di_projid_lo); 282 - to->di_projid_hi = cpu_to_be16(from->di_projid_hi); 282 + to->di_projid_lo = cpu_to_be16(from->di_projid & 0xffff); 283 + to->di_projid_hi = cpu_to_be16(from->di_projid >> 16); 283 284 284 285 memset(to->di_pad, 0, sizeof(to->di_pad)); 285 286 to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec); ··· 305 306 306 307 if (from->di_version == 3) { 307 308 to->di_changecount = cpu_to_be64(inode_peek_iversion(inode)); 308 - to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec); 309 - to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec); 309 + to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.tv_sec); 310 + to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.tv_nsec); 310 311 to->di_flags2 = cpu_to_be64(from->di_flags2); 311 312 to->di_cowextsize = cpu_to_be32(from->di_cowextsize); 312 313 to->di_ino = cpu_to_be64(ip->i_ino); ··· 631 632 if ((iget_flags & XFS_IGET_CREATE) && 632 633 xfs_sb_version_hascrc(&mp->m_sb) && 633 634 !(mp->m_flags & XFS_MOUNT_IKEEP)) { 634 - /* initialise the on-disk inode core */ 635 - memset(&ip->i_d, 0, sizeof(ip->i_d)); 636 635 VFS_I(ip)->i_generation = prandom_u32(); 637 636 ip->i_d.di_version = 3; 638 637 return 0;
+2 -3
fs/xfs/libxfs/xfs_inode_buf.h
··· 21 21 uint16_t di_flushiter; /* incremented on flush */ 22 22 uint32_t di_uid; /* owner's user id */ 23 23 uint32_t di_gid; /* owner's group id */ 24 - uint16_t di_projid_lo; /* lower part of owner's project id */ 25 - uint16_t di_projid_hi; /* higher part of owner's project id */ 24 + uint32_t di_projid; /* owner's project id */ 26 25 xfs_fsize_t di_size; /* number of bytes in file */ 27 26 xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */ 28 27 xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ ··· 36 37 uint64_t di_flags2; /* more random flags */ 37 38 uint32_t di_cowextsize; /* basic cow extent size for file */ 38 39 39 - xfs_ictimestamp_t di_crtime; /* time created */ 40 + struct timespec64 di_crtime; /* time created */ 40 41 }; 41 42 42 43 /*
+14 -8
fs/xfs/libxfs/xfs_inode_fork.c
··· 75 75 error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK); 76 76 break; 77 77 default: 78 + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, 79 + dip, sizeof(*dip), __this_address); 78 80 return -EFSCORRUPTED; 79 81 } 80 82 break; 81 83 82 84 default: 85 + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, 86 + sizeof(*dip), __this_address); 83 87 return -EFSCORRUPTED; 84 88 } 85 89 if (error) ··· 114 110 error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK); 115 111 break; 116 112 default: 113 + xfs_inode_verifier_error(ip, error, __func__, dip, 114 + sizeof(*dip), __this_address); 117 115 error = -EFSCORRUPTED; 118 116 break; 119 117 } 120 118 if (error) { 121 - kmem_zone_free(xfs_ifork_zone, ip->i_afp); 119 + kmem_cache_free(xfs_ifork_zone, ip->i_afp); 122 120 ip->i_afp = NULL; 123 121 if (ip->i_cowfp) 124 - kmem_zone_free(xfs_ifork_zone, ip->i_cowfp); 122 + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); 125 123 ip->i_cowfp = NULL; 126 124 xfs_idestroy_fork(ip, XFS_DATA_FORK); 127 125 } ··· 135 129 struct xfs_inode *ip, 136 130 int whichfork, 137 131 const void *data, 138 - int size) 132 + int64_t size) 139 133 { 140 134 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 141 135 int mem_size = size, real_size = 0; ··· 473 467 void 474 468 xfs_idata_realloc( 475 469 struct xfs_inode *ip, 476 - int byte_diff, 470 + int64_t byte_diff, 477 471 int whichfork) 478 472 { 479 473 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 480 - int new_size = (int)ifp->if_bytes + byte_diff; 474 + int64_t new_size = ifp->if_bytes + byte_diff; 481 475 482 476 ASSERT(new_size >= 0); 483 477 ASSERT(new_size <= XFS_IFORK_SIZE(ip, whichfork)); ··· 531 525 } 532 526 533 527 if (whichfork == XFS_ATTR_FORK) { 534 - kmem_zone_free(xfs_ifork_zone, ip->i_afp); 528 + kmem_cache_free(xfs_ifork_zone, ip->i_afp); 535 529 ip->i_afp = NULL; 536 530 } else if (whichfork == XFS_COW_FORK) { 537 - kmem_zone_free(xfs_ifork_zone, ip->i_cowfp); 531 + kmem_cache_free(xfs_ifork_zone, ip->i_cowfp); 538 532 ip->i_cowfp = NULL; 539 533 } 540 534 } ··· 558 552 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 559 553 struct xfs_iext_cursor icur; 560 554 struct xfs_bmbt_irec rec; 561 - int copied = 0; 555 + int64_t copied = 0; 562 556 563 557 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED)); 564 558 ASSERT(ifp->if_bytes > 0);
+12 -6
fs/xfs/libxfs/xfs_inode_fork.h
··· 13 13 * File incore extent information, present for each of data & attr forks. 14 14 */ 15 15 struct xfs_ifork { 16 - int if_bytes; /* bytes in if_u1 */ 17 - unsigned int if_seq; /* fork mod counter */ 16 + int64_t if_bytes; /* bytes in if_u1 */ 18 17 struct xfs_btree_block *if_broot; /* file's incore btree root */ 19 - short if_broot_bytes; /* bytes allocated for root */ 20 - unsigned char if_flags; /* per-fork flags */ 18 + unsigned int if_seq; /* fork mod counter */ 21 19 int if_height; /* height of the extent tree */ 22 20 union { 23 21 void *if_root; /* extent tree root */ 24 22 char *if_data; /* inline file data */ 25 23 } if_u1; 24 + short if_broot_bytes; /* bytes allocated for root */ 25 + unsigned char if_flags; /* per-fork flags */ 26 26 }; 27 27 28 28 /* ··· 87 87 #define XFS_IFORK_MAXEXT(ip, w) \ 88 88 (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) 89 89 90 + #define xfs_ifork_has_extents(ip, w) \ 91 + (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ 92 + XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) 93 + 90 94 struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); 91 95 92 96 int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); 93 97 void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, 94 98 struct xfs_inode_log_item *, int); 95 99 void xfs_idestroy_fork(struct xfs_inode *, int); 96 - void xfs_idata_realloc(struct xfs_inode *, int, int); 100 + void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, 101 + int whichfork); 97 102 void xfs_iroot_realloc(struct xfs_inode *, int, int); 98 103 int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); 99 104 int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, 100 105 int); 101 - void xfs_init_local_fork(struct xfs_inode *, int, const void *, int); 106 + void xfs_init_local_fork(struct xfs_inode *ip, int whichfork, 107 + const void *data, int64_t size); 102 108 103 109 xfs_extnum_t xfs_iext_count(struct xfs_ifork *ifp); 104 110 void xfs_iext_insert(struct xfs_inode *, struct xfs_iext_cursor *cur,
+2 -2
fs/xfs/libxfs/xfs_log_format.h
··· 432 432 } 433 433 434 434 /* 435 - * Buffer Log Format defintions 435 + * Buffer Log Format definitions 436 436 * 437 - * These are the physical dirty bitmap defintions for the log format structure. 437 + * These are the physical dirty bitmap definitions for the log format structure. 438 438 */ 439 439 #define XFS_BLF_CHUNK 128 440 440 #define XFS_BLF_SHIFT 7
+2 -2
fs/xfs/libxfs/xfs_log_recover.h
··· 30 30 xfs_log_iovec_t *ri_buf; /* ptr to regions buffer */ 31 31 } xlog_recover_item_t; 32 32 33 - typedef struct xlog_recover { 33 + struct xlog_recover { 34 34 struct hlist_node r_list; 35 35 xlog_tid_t r_log_tid; /* log's transaction id */ 36 36 xfs_trans_header_t r_theader; /* trans header for partial */ 37 37 int r_state; /* not needed */ 38 38 xfs_lsn_t r_lsn; /* xact lsn */ 39 39 struct list_head r_itemq; /* q for items */ 40 - } xlog_recover_t; 40 + }; 41 41 42 42 #define ITEM_TYPE(i) (*(unsigned short *)(i)->ri_buf[0].i_addr) 43 43
+126 -48
fs/xfs/libxfs/xfs_refcount.c
··· 200 200 error = xfs_btree_insert(cur, i); 201 201 if (error) 202 202 goto out_error; 203 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, *i == 1, out_error); 203 + if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) { 204 + error = -EFSCORRUPTED; 205 + goto out_error; 206 + } 204 207 205 208 out_error: 206 209 if (error) ··· 230 227 error = xfs_refcount_get_rec(cur, &irec, &found_rec); 231 228 if (error) 232 229 goto out_error; 233 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 230 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 231 + error = -EFSCORRUPTED; 232 + goto out_error; 233 + } 234 234 trace_xfs_refcount_delete(cur->bc_mp, cur->bc_private.a.agno, &irec); 235 235 error = xfs_btree_delete(cur, i); 236 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, *i == 1, out_error); 236 + if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) { 237 + error = -EFSCORRUPTED; 238 + goto out_error; 239 + } 237 240 if (error) 238 241 goto out_error; 239 242 error = xfs_refcount_lookup_ge(cur, irec.rc_startblock, &found_rec); ··· 358 349 error = xfs_refcount_get_rec(cur, &rcext, &found_rec); 359 350 if (error) 360 351 goto out_error; 361 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 352 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 353 + error = -EFSCORRUPTED; 354 + goto out_error; 355 + } 362 356 if (rcext.rc_startblock == agbno || xfs_refc_next(&rcext) <= agbno) 363 357 return 0; 364 358 ··· 383 371 error = xfs_refcount_insert(cur, &tmp, &found_rec); 384 372 if (error) 385 373 goto out_error; 386 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 374 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 375 + error = -EFSCORRUPTED; 376 + goto out_error; 377 + } 387 378 return error; 388 379 389 380 out_error: ··· 425 410 &found_rec); 426 411 if (error) 427 412 goto out_error; 428 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 413 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 414 + error = -EFSCORRUPTED; 415 + goto out_error; 416 + } 429 417 430 418 error = xfs_refcount_delete(cur, &found_rec); 431 419 if (error) 432 420 goto out_error; 433 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 421 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 422 + error = -EFSCORRUPTED; 423 + goto out_error; 424 + } 434 425 435 426 if (center->rc_refcount > 1) { 436 427 error = xfs_refcount_delete(cur, &found_rec); 437 428 if (error) 438 429 goto out_error; 439 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, 440 - out_error); 430 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 431 + error = -EFSCORRUPTED; 432 + goto out_error; 433 + } 441 434 } 442 435 443 436 /* Enlarge the left extent. */ ··· 453 430 &found_rec); 454 431 if (error) 455 432 goto out_error; 456 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 433 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 434 + error = -EFSCORRUPTED; 435 + goto out_error; 436 + } 457 437 458 438 left->rc_blockcount = extlen; 459 439 error = xfs_refcount_update(cur, left); ··· 495 469 &found_rec); 496 470 if (error) 497 471 goto out_error; 498 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, 499 - out_error); 472 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 473 + error = -EFSCORRUPTED; 474 + goto out_error; 475 + } 500 476 501 477 error = xfs_refcount_delete(cur, &found_rec); 502 478 if (error) 503 479 goto out_error; 504 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, 505 - out_error); 480 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 481 + error = -EFSCORRUPTED; 482 + goto out_error; 483 + } 506 484 } 507 485 508 486 /* Enlarge the left extent. */ ··· 514 484 &found_rec); 515 485 if (error) 516 486 goto out_error; 517 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 487 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 488 + error = -EFSCORRUPTED; 489 + goto out_error; 490 + } 518 491 519 492 left->rc_blockcount += cleft->rc_blockcount; 520 493 error = xfs_refcount_update(cur, left); ··· 559 526 &found_rec); 560 527 if (error) 561 528 goto out_error; 562 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, 563 - out_error); 529 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 530 + error = -EFSCORRUPTED; 531 + goto out_error; 532 + } 564 533 565 534 error = xfs_refcount_delete(cur, &found_rec); 566 535 if (error) 567 536 goto out_error; 568 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, 569 - out_error); 537 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 538 + error = -EFSCORRUPTED; 539 + goto out_error; 540 + } 570 541 } 571 542 572 543 /* Enlarge the right extent. */ ··· 578 541 &found_rec); 579 542 if (error) 580 543 goto out_error; 581 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 544 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 545 + error = -EFSCORRUPTED; 546 + goto out_error; 547 + } 582 548 583 549 right->rc_startblock -= cright->rc_blockcount; 584 550 right->rc_blockcount += cright->rc_blockcount; ··· 627 587 error = xfs_refcount_get_rec(cur, &tmp, &found_rec); 628 588 if (error) 629 589 goto out_error; 630 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 590 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 591 + error = -EFSCORRUPTED; 592 + goto out_error; 593 + } 631 594 632 595 if (xfs_refc_next(&tmp) != agbno) 633 596 return 0; ··· 648 605 error = xfs_refcount_get_rec(cur, &tmp, &found_rec); 649 606 if (error) 650 607 goto out_error; 651 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, 652 - out_error); 608 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 609 + error = -EFSCORRUPTED; 610 + goto out_error; 611 + } 653 612 654 613 /* if tmp starts at the end of our range, just use that */ 655 614 if (tmp.rc_startblock == agbno) ··· 716 671 error = xfs_refcount_get_rec(cur, &tmp, &found_rec); 717 672 if (error) 718 673 goto out_error; 719 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); 674 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 675 + error = -EFSCORRUPTED; 676 + goto out_error; 677 + } 720 678 721 679 if (tmp.rc_startblock != agbno + aglen) 722 680 return 0; ··· 737 689 error = xfs_refcount_get_rec(cur, &tmp, &found_rec); 738 690 if (error) 739 691 goto out_error; 740 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, 741 - out_error); 692 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 693 + error = -EFSCORRUPTED; 694 + goto out_error; 695 + } 742 696 743 697 /* if tmp ends at the end of our range, just use that */ 744 698 if (xfs_refc_next(&tmp) == agbno + aglen) ··· 963 913 &found_tmp); 964 914 if (error) 965 915 goto out_error; 966 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 967 - found_tmp == 1, out_error); 916 + if (XFS_IS_CORRUPT(cur->bc_mp, 917 + found_tmp != 1)) { 918 + error = -EFSCORRUPTED; 919 + goto out_error; 920 + } 968 921 cur->bc_private.a.priv.refc.nr_ops++; 969 922 } else { 970 923 fsbno = XFS_AGB_TO_FSB(cur->bc_mp, ··· 1008 955 error = xfs_refcount_delete(cur, &found_rec); 1009 956 if (error) 1010 957 goto out_error; 1011 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 1012 - found_rec == 1, out_error); 958 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 959 + error = -EFSCORRUPTED; 960 + goto out_error; 961 + } 1013 962 cur->bc_private.a.priv.refc.nr_ops++; 1014 963 goto advloop; 1015 964 } else { ··· 1177 1122 XFS_ALLOC_FLAG_FREEING, &agbp); 1178 1123 if (error) 1179 1124 return error; 1180 - if (!agbp) 1125 + if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) 1181 1126 return -EFSCORRUPTED; 1182 1127 1183 1128 rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno); ··· 1327 1272 error = xfs_refcount_get_rec(cur, &tmp, &i); 1328 1273 if (error) 1329 1274 goto out_error; 1330 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, out_error); 1275 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 1276 + error = -EFSCORRUPTED; 1277 + goto out_error; 1278 + } 1331 1279 1332 1280 /* If the extent ends before the start, look at the next one */ 1333 1281 if (tmp.rc_startblock + tmp.rc_blockcount <= agbno) { ··· 1342 1284 error = xfs_refcount_get_rec(cur, &tmp, &i); 1343 1285 if (error) 1344 1286 goto out_error; 1345 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, out_error); 1287 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 1288 + error = -EFSCORRUPTED; 1289 + goto out_error; 1290 + } 1346 1291 } 1347 1292 1348 1293 /* If the extent starts after the range we want, bail out */ ··· 1373 1312 error = xfs_refcount_get_rec(cur, &tmp, &i); 1374 1313 if (error) 1375 1314 goto out_error; 1376 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, out_error); 1315 + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { 1316 + error = -EFSCORRUPTED; 1317 + goto out_error; 1318 + } 1377 1319 if (tmp.rc_startblock >= agbno + aglen || 1378 1320 tmp.rc_startblock != *fbno + *flen) 1379 1321 break; ··· 1477 1413 switch (adj) { 1478 1414 case XFS_REFCOUNT_ADJUST_COW_ALLOC: 1479 1415 /* Adding a CoW reservation, there should be nothing here. */ 1480 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 1481 - ext.rc_startblock >= agbno + aglen, out_error); 1416 + if (XFS_IS_CORRUPT(cur->bc_mp, 1417 + agbno + aglen > ext.rc_startblock)) { 1418 + error = -EFSCORRUPTED; 1419 + goto out_error; 1420 + } 1482 1421 1483 1422 tmp.rc_startblock = agbno; 1484 1423 tmp.rc_blockcount = aglen; ··· 1493 1426 &found_tmp); 1494 1427 if (error) 1495 1428 goto out_error; 1496 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 1497 - found_tmp == 1, out_error); 1429 + if (XFS_IS_CORRUPT(cur->bc_mp, found_tmp != 1)) { 1430 + error = -EFSCORRUPTED; 1431 + goto out_error; 1432 + } 1498 1433 break; 1499 1434 case XFS_REFCOUNT_ADJUST_COW_FREE: 1500 1435 /* Removing a CoW reservation, there should be one extent. */ 1501 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 1502 - ext.rc_startblock == agbno, out_error); 1503 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 1504 - ext.rc_blockcount == aglen, out_error); 1505 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 1506 - ext.rc_refcount == 1, out_error); 1436 + if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_startblock != agbno)) { 1437 + error = -EFSCORRUPTED; 1438 + goto out_error; 1439 + } 1440 + if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount != aglen)) { 1441 + error = -EFSCORRUPTED; 1442 + goto out_error; 1443 + } 1444 + if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_refcount != 1)) { 1445 + error = -EFSCORRUPTED; 1446 + goto out_error; 1447 + } 1507 1448 1508 1449 ext.rc_refcount = 0; 1509 1450 trace_xfs_refcount_modify_extent(cur->bc_mp, ··· 1519 1444 error = xfs_refcount_delete(cur, &found_rec); 1520 1445 if (error) 1521 1446 goto out_error; 1522 - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, 1523 - found_rec == 1, out_error); 1447 + if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) { 1448 + error = -EFSCORRUPTED; 1449 + goto out_error; 1450 + } 1524 1451 break; 1525 1452 default: 1526 1453 ASSERT(0); ··· 1661 1584 /* Stuff an extent on the recovery list. */ 1662 1585 STATIC int 1663 1586 xfs_refcount_recover_extent( 1664 - struct xfs_btree_cur *cur, 1587 + struct xfs_btree_cur *cur, 1665 1588 union xfs_btree_rec *rec, 1666 1589 void *priv) 1667 1590 { 1668 1591 struct list_head *debris = priv; 1669 1592 struct xfs_refcount_recovery *rr; 1670 1593 1671 - if (be32_to_cpu(rec->refc.rc_refcount) != 1) 1594 + if (XFS_IS_CORRUPT(cur->bc_mp, 1595 + be32_to_cpu(rec->refc.rc_refcount) != 1)) 1672 1596 return -EFSCORRUPTED; 1673 1597 1674 1598 rr = kmem_alloc(sizeof(struct xfs_refcount_recovery), 0);
+289 -88
fs/xfs/libxfs/xfs_rmap.c
··· 113 113 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i); 114 114 if (error) 115 115 goto done; 116 - XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 0, done); 116 + if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) { 117 + error = -EFSCORRUPTED; 118 + goto done; 119 + } 117 120 118 121 rcur->bc_rec.r.rm_startblock = agbno; 119 122 rcur->bc_rec.r.rm_blockcount = len; ··· 126 123 error = xfs_btree_insert(rcur, &i); 127 124 if (error) 128 125 goto done; 129 - XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); 126 + if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) { 127 + error = -EFSCORRUPTED; 128 + goto done; 129 + } 130 130 done: 131 131 if (error) 132 132 trace_xfs_rmap_insert_error(rcur->bc_mp, ··· 155 149 error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, flags, &i); 156 150 if (error) 157 151 goto done; 158 - XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); 152 + if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) { 153 + error = -EFSCORRUPTED; 154 + goto done; 155 + } 159 156 160 157 error = xfs_btree_delete(rcur, &i); 161 158 if (error) 162 159 goto done; 163 - XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); 160 + if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) { 161 + error = -EFSCORRUPTED; 162 + goto done; 163 + } 164 164 done: 165 165 if (error) 166 166 trace_xfs_rmap_delete_error(rcur->bc_mp, ··· 418 406 return 0; 419 407 420 408 /* Make sure the unwritten flag matches. */ 421 - XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) == 422 - (rec->rm_flags & XFS_RMAP_UNWRITTEN), out); 409 + if (XFS_IS_CORRUPT(mp, 410 + (flags & XFS_RMAP_UNWRITTEN) != 411 + (rec->rm_flags & XFS_RMAP_UNWRITTEN))) { 412 + error = -EFSCORRUPTED; 413 + goto out; 414 + } 423 415 424 416 /* Make sure the owner matches what we expect to find in the tree. */ 425 - XFS_WANT_CORRUPTED_GOTO(mp, owner == rec->rm_owner, out); 417 + if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) { 418 + error = -EFSCORRUPTED; 419 + goto out; 420 + } 426 421 427 422 /* Check the offset, if necessary. */ 428 423 if (XFS_RMAP_NON_INODE_OWNER(owner)) 429 424 goto out; 430 425 431 426 if (flags & XFS_RMAP_BMBT_BLOCK) { 432 - XFS_WANT_CORRUPTED_GOTO(mp, rec->rm_flags & XFS_RMAP_BMBT_BLOCK, 433 - out); 427 + if (XFS_IS_CORRUPT(mp, 428 + !(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) { 429 + error = -EFSCORRUPTED; 430 + goto out; 431 + } 434 432 } else { 435 - XFS_WANT_CORRUPTED_GOTO(mp, rec->rm_offset <= offset, out); 436 - XFS_WANT_CORRUPTED_GOTO(mp, 437 - ltoff + rec->rm_blockcount >= offset + len, 438 - out); 433 + if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) { 434 + error = -EFSCORRUPTED; 435 + goto out; 436 + } 437 + if (XFS_IS_CORRUPT(mp, 438 + offset + len > ltoff + rec->rm_blockcount)) { 439 + error = -EFSCORRUPTED; 440 + goto out; 441 + } 439 442 } 440 443 441 444 out: ··· 509 482 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, flags, &i); 510 483 if (error) 511 484 goto out_error; 512 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 485 + if (XFS_IS_CORRUPT(mp, i != 1)) { 486 + error = -EFSCORRUPTED; 487 + goto out_error; 488 + } 513 489 514 490 error = xfs_rmap_get_rec(cur, &ltrec, &i); 515 491 if (error) 516 492 goto out_error; 517 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 493 + if (XFS_IS_CORRUPT(mp, i != 1)) { 494 + error = -EFSCORRUPTED; 495 + goto out_error; 496 + } 518 497 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, 519 498 cur->bc_private.a.agno, ltrec.rm_startblock, 520 499 ltrec.rm_blockcount, ltrec.rm_owner, ··· 535 502 * be the case that the "left" extent goes all the way to EOFS. 536 503 */ 537 504 if (owner == XFS_RMAP_OWN_NULL) { 538 - XFS_WANT_CORRUPTED_GOTO(mp, bno >= ltrec.rm_startblock + 539 - ltrec.rm_blockcount, out_error); 505 + if (XFS_IS_CORRUPT(mp, 506 + bno < 507 + ltrec.rm_startblock + ltrec.rm_blockcount)) { 508 + error = -EFSCORRUPTED; 509 + goto out_error; 510 + } 540 511 goto out_done; 541 512 } 542 513 ··· 563 526 error = xfs_rmap_get_rec(cur, &rtrec, &i); 564 527 if (error) 565 528 goto out_error; 566 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 529 + if (XFS_IS_CORRUPT(mp, i != 1)) { 530 + error = -EFSCORRUPTED; 531 + goto out_error; 532 + } 567 533 if (rtrec.rm_startblock >= bno + len) 568 534 goto out_done; 569 535 } 570 536 571 537 /* Make sure the extent we found covers the entire freeing range. */ 572 - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno && 573 - ltrec.rm_startblock + ltrec.rm_blockcount >= 574 - bno + len, out_error); 538 + if (XFS_IS_CORRUPT(mp, 539 + ltrec.rm_startblock > bno || 540 + ltrec.rm_startblock + ltrec.rm_blockcount < 541 + bno + len)) { 542 + error = -EFSCORRUPTED; 543 + goto out_error; 544 + } 575 545 576 546 /* Check owner information. */ 577 547 error = xfs_rmap_free_check_owner(mp, ltoff, &ltrec, len, owner, ··· 595 551 error = xfs_btree_delete(cur, &i); 596 552 if (error) 597 553 goto out_error; 598 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 554 + if (XFS_IS_CORRUPT(mp, i != 1)) { 555 + error = -EFSCORRUPTED; 556 + goto out_error; 557 + } 599 558 } else if (ltrec.rm_startblock == bno) { 600 559 /* 601 560 * overlap left hand side of extent: move the start, trim the ··· 790 743 error = xfs_rmap_get_rec(cur, &ltrec, &have_lt); 791 744 if (error) 792 745 goto out_error; 793 - XFS_WANT_CORRUPTED_GOTO(mp, have_lt == 1, out_error); 746 + if (XFS_IS_CORRUPT(mp, have_lt != 1)) { 747 + error = -EFSCORRUPTED; 748 + goto out_error; 749 + } 794 750 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, 795 751 cur->bc_private.a.agno, ltrec.rm_startblock, 796 752 ltrec.rm_blockcount, ltrec.rm_owner, ··· 803 753 have_lt = 0; 804 754 } 805 755 806 - XFS_WANT_CORRUPTED_GOTO(mp, 807 - have_lt == 0 || 808 - ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error); 756 + if (XFS_IS_CORRUPT(mp, 757 + have_lt != 0 && 758 + ltrec.rm_startblock + ltrec.rm_blockcount > bno)) { 759 + error = -EFSCORRUPTED; 760 + goto out_error; 761 + } 809 762 810 763 /* 811 764 * Increment the cursor to see if we have a right-adjacent record to our ··· 822 769 error = xfs_rmap_get_rec(cur, &gtrec, &have_gt); 823 770 if (error) 824 771 goto out_error; 825 - XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error); 826 - XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock, 827 - out_error); 772 + if (XFS_IS_CORRUPT(mp, have_gt != 1)) { 773 + error = -EFSCORRUPTED; 774 + goto out_error; 775 + } 776 + if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) { 777 + error = -EFSCORRUPTED; 778 + goto out_error; 779 + } 828 780 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 829 781 cur->bc_private.a.agno, gtrec.rm_startblock, 830 782 gtrec.rm_blockcount, gtrec.rm_owner, ··· 879 821 error = xfs_btree_delete(cur, &i); 880 822 if (error) 881 823 goto out_error; 882 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 824 + if (XFS_IS_CORRUPT(mp, i != 1)) { 825 + error = -EFSCORRUPTED; 826 + goto out_error; 827 + } 883 828 } 884 829 885 830 /* point the cursor back to the left record and update */ ··· 926 865 error = xfs_btree_insert(cur, &i); 927 866 if (error) 928 867 goto out_error; 929 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 868 + if (XFS_IS_CORRUPT(mp, i != 1)) { 869 + error = -EFSCORRUPTED; 870 + goto out_error; 871 + } 930 872 } 931 873 932 874 trace_xfs_rmap_map_done(mp, cur->bc_private.a.agno, bno, len, ··· 1021 957 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i); 1022 958 if (error) 1023 959 goto done; 1024 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 960 + if (XFS_IS_CORRUPT(mp, i != 1)) { 961 + error = -EFSCORRUPTED; 962 + goto done; 963 + } 1025 964 1026 965 error = xfs_rmap_get_rec(cur, &PREV, &i); 1027 966 if (error) 1028 967 goto done; 1029 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 968 + if (XFS_IS_CORRUPT(mp, i != 1)) { 969 + error = -EFSCORRUPTED; 970 + goto done; 971 + } 1030 972 trace_xfs_rmap_lookup_le_range_result(cur->bc_mp, 1031 973 cur->bc_private.a.agno, PREV.rm_startblock, 1032 974 PREV.rm_blockcount, PREV.rm_owner, ··· 1065 995 error = xfs_rmap_get_rec(cur, &LEFT, &i); 1066 996 if (error) 1067 997 goto done; 1068 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1069 - XFS_WANT_CORRUPTED_GOTO(mp, 1070 - LEFT.rm_startblock + LEFT.rm_blockcount <= bno, 1071 - done); 998 + if (XFS_IS_CORRUPT(mp, i != 1)) { 999 + error = -EFSCORRUPTED; 1000 + goto done; 1001 + } 1002 + if (XFS_IS_CORRUPT(mp, 1003 + LEFT.rm_startblock + LEFT.rm_blockcount > 1004 + bno)) { 1005 + error = -EFSCORRUPTED; 1006 + goto done; 1007 + } 1072 1008 trace_xfs_rmap_find_left_neighbor_result(cur->bc_mp, 1073 1009 cur->bc_private.a.agno, LEFT.rm_startblock, 1074 1010 LEFT.rm_blockcount, LEFT.rm_owner, ··· 1093 1017 error = xfs_btree_increment(cur, 0, &i); 1094 1018 if (error) 1095 1019 goto done; 1096 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1020 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1021 + error = -EFSCORRUPTED; 1022 + goto done; 1023 + } 1097 1024 error = xfs_btree_increment(cur, 0, &i); 1098 1025 if (error) 1099 1026 goto done; ··· 1105 1026 error = xfs_rmap_get_rec(cur, &RIGHT, &i); 1106 1027 if (error) 1107 1028 goto done; 1108 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1109 - XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock, 1110 - done); 1029 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1030 + error = -EFSCORRUPTED; 1031 + goto done; 1032 + } 1033 + if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) { 1034 + error = -EFSCORRUPTED; 1035 + goto done; 1036 + } 1111 1037 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 1112 1038 cur->bc_private.a.agno, RIGHT.rm_startblock, 1113 1039 RIGHT.rm_blockcount, RIGHT.rm_owner, ··· 1139 1055 error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, oldext, &i); 1140 1056 if (error) 1141 1057 goto done; 1142 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1058 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1059 + error = -EFSCORRUPTED; 1060 + goto done; 1061 + } 1143 1062 1144 1063 /* 1145 1064 * Switch out based on the FILLING and CONTIG state bits. ··· 1158 1071 error = xfs_btree_increment(cur, 0, &i); 1159 1072 if (error) 1160 1073 goto done; 1161 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1074 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1075 + error = -EFSCORRUPTED; 1076 + goto done; 1077 + } 1162 1078 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno, 1163 1079 RIGHT.rm_startblock, RIGHT.rm_blockcount, 1164 1080 RIGHT.rm_owner, RIGHT.rm_offset, ··· 1169 1079 error = xfs_btree_delete(cur, &i); 1170 1080 if (error) 1171 1081 goto done; 1172 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1082 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1083 + error = -EFSCORRUPTED; 1084 + goto done; 1085 + } 1173 1086 error = xfs_btree_decrement(cur, 0, &i); 1174 1087 if (error) 1175 1088 goto done; 1176 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1089 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1090 + error = -EFSCORRUPTED; 1091 + goto done; 1092 + } 1177 1093 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno, 1178 1094 PREV.rm_startblock, PREV.rm_blockcount, 1179 1095 PREV.rm_owner, PREV.rm_offset, ··· 1187 1091 error = xfs_btree_delete(cur, &i); 1188 1092 if (error) 1189 1093 goto done; 1190 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1094 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1095 + error = -EFSCORRUPTED; 1096 + goto done; 1097 + } 1191 1098 error = xfs_btree_decrement(cur, 0, &i); 1192 1099 if (error) 1193 1100 goto done; 1194 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1101 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1102 + error = -EFSCORRUPTED; 1103 + goto done; 1104 + } 1195 1105 NEW = LEFT; 1196 1106 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount; 1197 1107 error = xfs_rmap_update(cur, &NEW); ··· 1217 1115 error = xfs_btree_delete(cur, &i); 1218 1116 if (error) 1219 1117 goto done; 1220 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1118 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1119 + error = -EFSCORRUPTED; 1120 + goto done; 1121 + } 1221 1122 error = xfs_btree_decrement(cur, 0, &i); 1222 1123 if (error) 1223 1124 goto done; 1224 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1125 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1126 + error = -EFSCORRUPTED; 1127 + goto done; 1128 + } 1225 1129 NEW = LEFT; 1226 1130 NEW.rm_blockcount += PREV.rm_blockcount; 1227 1131 error = xfs_rmap_update(cur, &NEW); ··· 1243 1135 error = xfs_btree_increment(cur, 0, &i); 1244 1136 if (error) 1245 1137 goto done; 1246 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1138 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1139 + error = -EFSCORRUPTED; 1140 + goto done; 1141 + } 1247 1142 trace_xfs_rmap_delete(mp, cur->bc_private.a.agno, 1248 1143 RIGHT.rm_startblock, RIGHT.rm_blockcount, 1249 1144 RIGHT.rm_owner, RIGHT.rm_offset, ··· 1254 1143 error = xfs_btree_delete(cur, &i); 1255 1144 if (error) 1256 1145 goto done; 1257 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1146 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1147 + error = -EFSCORRUPTED; 1148 + goto done; 1149 + } 1258 1150 error = xfs_btree_decrement(cur, 0, &i); 1259 1151 if (error) 1260 1152 goto done; 1261 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1153 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1154 + error = -EFSCORRUPTED; 1155 + goto done; 1156 + } 1262 1157 NEW = PREV; 1263 1158 NEW.rm_blockcount = len + RIGHT.rm_blockcount; 1264 1159 NEW.rm_flags = newext; ··· 1331 1214 error = xfs_btree_insert(cur, &i); 1332 1215 if (error) 1333 1216 goto done; 1334 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1217 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1218 + error = -EFSCORRUPTED; 1219 + goto done; 1220 + } 1335 1221 break; 1336 1222 1337 1223 case RMAP_RIGHT_FILLING | RMAP_RIGHT_CONTIG: ··· 1373 1253 oldext, &i); 1374 1254 if (error) 1375 1255 goto done; 1376 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 1256 + if (XFS_IS_CORRUPT(mp, i != 0)) { 1257 + error = -EFSCORRUPTED; 1258 + goto done; 1259 + } 1377 1260 NEW.rm_startblock = bno; 1378 1261 NEW.rm_owner = owner; 1379 1262 NEW.rm_offset = offset; ··· 1388 1265 error = xfs_btree_insert(cur, &i); 1389 1266 if (error) 1390 1267 goto done; 1391 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1268 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1269 + error = -EFSCORRUPTED; 1270 + goto done; 1271 + } 1392 1272 break; 1393 1273 1394 1274 case 0: ··· 1421 1295 error = xfs_btree_insert(cur, &i); 1422 1296 if (error) 1423 1297 goto done; 1424 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1298 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1299 + error = -EFSCORRUPTED; 1300 + goto done; 1301 + } 1425 1302 /* 1426 1303 * Reset the cursor to the position of the new extent 1427 1304 * we are about to insert as we can't trust it after ··· 1434 1305 oldext, &i); 1435 1306 if (error) 1436 1307 goto done; 1437 - XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); 1308 + if (XFS_IS_CORRUPT(mp, i != 0)) { 1309 + error = -EFSCORRUPTED; 1310 + goto done; 1311 + } 1438 1312 /* new middle extent - newext */ 1439 1313 cur->bc_rec.r.rm_flags &= ~XFS_RMAP_UNWRITTEN; 1440 1314 cur->bc_rec.r.rm_flags |= newext; ··· 1446 1314 error = xfs_btree_insert(cur, &i); 1447 1315 if (error) 1448 1316 goto done; 1449 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1317 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1318 + error = -EFSCORRUPTED; 1319 + goto done; 1320 + } 1450 1321 break; 1451 1322 1452 1323 case RMAP_LEFT_FILLING | RMAP_LEFT_CONTIG | RMAP_RIGHT_CONTIG: ··· 1518 1383 &PREV, &i); 1519 1384 if (error) 1520 1385 goto done; 1521 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1386 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1387 + error = -EFSCORRUPTED; 1388 + goto done; 1389 + } 1522 1390 1523 1391 ASSERT(PREV.rm_offset <= offset); 1524 1392 ASSERT(PREV.rm_offset + PREV.rm_blockcount >= new_endoff); ··· 1544 1406 goto done; 1545 1407 if (i) { 1546 1408 state |= RMAP_LEFT_VALID; 1547 - XFS_WANT_CORRUPTED_GOTO(mp, 1548 - LEFT.rm_startblock + LEFT.rm_blockcount <= bno, 1549 - done); 1409 + if (XFS_IS_CORRUPT(mp, 1410 + LEFT.rm_startblock + LEFT.rm_blockcount > 1411 + bno)) { 1412 + error = -EFSCORRUPTED; 1413 + goto done; 1414 + } 1550 1415 if (xfs_rmap_is_mergeable(&LEFT, owner, newext)) 1551 1416 state |= RMAP_LEFT_CONTIG; 1552 1417 } ··· 1564 1423 error = xfs_rmap_get_rec(cur, &RIGHT, &i); 1565 1424 if (error) 1566 1425 goto done; 1567 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1568 - XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= RIGHT.rm_startblock, 1569 - done); 1426 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1427 + error = -EFSCORRUPTED; 1428 + goto done; 1429 + } 1430 + if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) { 1431 + error = -EFSCORRUPTED; 1432 + goto done; 1433 + } 1570 1434 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 1571 1435 cur->bc_private.a.agno, RIGHT.rm_startblock, 1572 1436 RIGHT.rm_blockcount, RIGHT.rm_owner, ··· 1618 1472 NEW.rm_offset, NEW.rm_flags, &i); 1619 1473 if (error) 1620 1474 goto done; 1621 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1475 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1476 + error = -EFSCORRUPTED; 1477 + goto done; 1478 + } 1622 1479 NEW.rm_blockcount += PREV.rm_blockcount + RIGHT.rm_blockcount; 1623 1480 error = xfs_rmap_update(cur, &NEW); 1624 1481 if (error) ··· 1644 1495 NEW.rm_offset, NEW.rm_flags, &i); 1645 1496 if (error) 1646 1497 goto done; 1647 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1498 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1499 + error = -EFSCORRUPTED; 1500 + goto done; 1501 + } 1648 1502 NEW.rm_blockcount += PREV.rm_blockcount; 1649 1503 error = xfs_rmap_update(cur, &NEW); 1650 1504 if (error) ··· 1670 1518 NEW.rm_offset, NEW.rm_flags, &i); 1671 1519 if (error) 1672 1520 goto done; 1673 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1521 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1522 + error = -EFSCORRUPTED; 1523 + goto done; 1524 + } 1674 1525 NEW.rm_blockcount += RIGHT.rm_blockcount; 1675 1526 NEW.rm_flags = RIGHT.rm_flags; 1676 1527 error = xfs_rmap_update(cur, &NEW); ··· 1693 1538 NEW.rm_offset, NEW.rm_flags, &i); 1694 1539 if (error) 1695 1540 goto done; 1696 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1541 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1542 + error = -EFSCORRUPTED; 1543 + goto done; 1544 + } 1697 1545 NEW.rm_flags = newext; 1698 1546 error = xfs_rmap_update(cur, &NEW); 1699 1547 if (error) ··· 1728 1570 NEW.rm_offset, NEW.rm_flags, &i); 1729 1571 if (error) 1730 1572 goto done; 1731 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1573 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1574 + error = -EFSCORRUPTED; 1575 + goto done; 1576 + } 1732 1577 NEW.rm_blockcount += len; 1733 1578 error = xfs_rmap_update(cur, &NEW); 1734 1579 if (error) ··· 1773 1612 NEW.rm_offset, NEW.rm_flags, &i); 1774 1613 if (error) 1775 1614 goto done; 1776 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1615 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1616 + error = -EFSCORRUPTED; 1617 + goto done; 1618 + } 1777 1619 NEW.rm_blockcount = offset - NEW.rm_offset; 1778 1620 error = xfs_rmap_update(cur, &NEW); 1779 1621 if (error) ··· 1808 1644 NEW.rm_offset, NEW.rm_flags, &i); 1809 1645 if (error) 1810 1646 goto done; 1811 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1647 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1648 + error = -EFSCORRUPTED; 1649 + goto done; 1650 + } 1812 1651 NEW.rm_blockcount -= len; 1813 1652 error = xfs_rmap_update(cur, &NEW); 1814 1653 if (error) ··· 1846 1679 NEW.rm_offset, NEW.rm_flags, &i); 1847 1680 if (error) 1848 1681 goto done; 1849 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); 1682 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1683 + error = -EFSCORRUPTED; 1684 + goto done; 1685 + } 1850 1686 NEW.rm_blockcount = offset - NEW.rm_offset; 1851 1687 error = xfs_rmap_update(cur, &NEW); 1852 1688 if (error) ··· 1935 1765 &ltrec, &i); 1936 1766 if (error) 1937 1767 goto out_error; 1938 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 1768 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1769 + error = -EFSCORRUPTED; 1770 + goto out_error; 1771 + } 1939 1772 ltoff = ltrec.rm_offset; 1940 1773 1941 1774 /* Make sure the extent we found covers the entire freeing range. */ 1942 - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno && 1943 - ltrec.rm_startblock + ltrec.rm_blockcount >= 1944 - bno + len, out_error); 1775 + if (XFS_IS_CORRUPT(mp, 1776 + ltrec.rm_startblock > bno || 1777 + ltrec.rm_startblock + ltrec.rm_blockcount < 1778 + bno + len)) { 1779 + error = -EFSCORRUPTED; 1780 + goto out_error; 1781 + } 1945 1782 1946 1783 /* Make sure the owner matches what we expect to find in the tree. */ 1947 - XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner, out_error); 1784 + if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) { 1785 + error = -EFSCORRUPTED; 1786 + goto out_error; 1787 + } 1948 1788 1949 1789 /* Make sure the unwritten flag matches. */ 1950 - XFS_WANT_CORRUPTED_GOTO(mp, (flags & XFS_RMAP_UNWRITTEN) == 1951 - (ltrec.rm_flags & XFS_RMAP_UNWRITTEN), out_error); 1790 + if (XFS_IS_CORRUPT(mp, 1791 + (flags & XFS_RMAP_UNWRITTEN) != 1792 + (ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) { 1793 + error = -EFSCORRUPTED; 1794 + goto out_error; 1795 + } 1952 1796 1953 1797 /* Check the offset. */ 1954 - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_offset <= offset, out_error); 1955 - XFS_WANT_CORRUPTED_GOTO(mp, offset <= ltoff + ltrec.rm_blockcount, 1956 - out_error); 1798 + if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) { 1799 + error = -EFSCORRUPTED; 1800 + goto out_error; 1801 + } 1802 + if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) { 1803 + error = -EFSCORRUPTED; 1804 + goto out_error; 1805 + } 1957 1806 1958 1807 if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { 1959 1808 /* Exact match, simply remove the record from rmap tree. */ ··· 2025 1836 ltrec.rm_offset, ltrec.rm_flags, &i); 2026 1837 if (error) 2027 1838 goto out_error; 2028 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 1839 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1840 + error = -EFSCORRUPTED; 1841 + goto out_error; 1842 + } 2029 1843 ltrec.rm_blockcount -= len; 2030 1844 error = xfs_rmap_update(cur, &ltrec); 2031 1845 if (error) ··· 2054 1862 ltrec.rm_offset, ltrec.rm_flags, &i); 2055 1863 if (error) 2056 1864 goto out_error; 2057 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 1865 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1866 + error = -EFSCORRUPTED; 1867 + goto out_error; 1868 + } 2058 1869 ltrec.rm_blockcount = bno - ltrec.rm_startblock; 2059 1870 error = xfs_rmap_update(cur, &ltrec); 2060 1871 if (error) ··· 2133 1938 error = xfs_rmap_get_rec(cur, &gtrec, &have_gt); 2134 1939 if (error) 2135 1940 goto out_error; 2136 - XFS_WANT_CORRUPTED_GOTO(mp, have_gt == 1, out_error); 1941 + if (XFS_IS_CORRUPT(mp, have_gt != 1)) { 1942 + error = -EFSCORRUPTED; 1943 + goto out_error; 1944 + } 2137 1945 trace_xfs_rmap_find_right_neighbor_result(cur->bc_mp, 2138 1946 cur->bc_private.a.agno, gtrec.rm_startblock, 2139 1947 gtrec.rm_blockcount, gtrec.rm_owner, ··· 2185 1987 ltrec.rm_offset, ltrec.rm_flags, &i); 2186 1988 if (error) 2187 1989 goto out_error; 2188 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); 1990 + if (XFS_IS_CORRUPT(mp, i != 1)) { 1991 + error = -EFSCORRUPTED; 1992 + goto out_error; 1993 + } 2189 1994 2190 1995 error = xfs_rmap_update(cur, &ltrec); 2191 1996 if (error) ··· 2400 2199 error = xfs_free_extent_fix_freelist(tp, agno, &agbp); 2401 2200 if (error) 2402 2201 return error; 2403 - if (!agbp) 2202 + if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) 2404 2203 return -EFSCORRUPTED; 2405 2204 2406 2205 rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno);
+2 -2
fs/xfs/libxfs/xfs_rtbitmap.c
··· 15 15 #include "xfs_bmap.h" 16 16 #include "xfs_trans.h" 17 17 #include "xfs_rtalloc.h" 18 - 18 + #include "xfs_error.h" 19 19 20 20 /* 21 21 * Realtime allocator bitmap functions shared with userspace. ··· 70 70 if (error) 71 71 return error; 72 72 73 - if (nmap == 0 || !xfs_bmap_is_real_extent(&map)) 73 + if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_real_extent(&map))) 74 74 return -EFSCORRUPTED; 75 75 76 76 ASSERT(map.br_startblock != NULLFSBLOCK);
+1
fs/xfs/libxfs/xfs_sb.c
··· 10 10 #include "xfs_log_format.h" 11 11 #include "xfs_trans_resv.h" 12 12 #include "xfs_bit.h" 13 + #include "xfs_sb.h" 13 14 #include "xfs_mount.h" 14 15 #include "xfs_ialloc.h" 15 16 #include "xfs_alloc.h"
+3 -5
fs/xfs/libxfs/xfs_trans_inode.c
··· 55 55 int flags) 56 56 { 57 57 struct inode *inode = VFS_I(ip); 58 - struct timespec64 tv; 58 + struct timespec64 tv; 59 59 60 60 ASSERT(tp); 61 61 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ··· 66 66 inode->i_mtime = tv; 67 67 if (flags & XFS_ICHGTIME_CHG) 68 68 inode->i_ctime = tv; 69 - if (flags & XFS_ICHGTIME_CREATE) { 70 - ip->i_d.di_crtime.t_sec = (int32_t)tv.tv_sec; 71 - ip->i_d.di_crtime.t_nsec = (int32_t)tv.tv_nsec; 72 - } 69 + if (flags & XFS_ICHGTIME_CREATE) 70 + ip->i_d.di_crtime = tv; 73 71 } 74 72 75 73 /*
+3 -3
fs/xfs/libxfs/xfs_trans_resv.c
··· 718 718 719 719 /* 720 720 * Adjusting quota limits. 721 - * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) 721 + * the disk quota buffer: sizeof(struct xfs_disk_dquot) 722 722 */ 723 723 STATIC uint 724 724 xfs_calc_qm_setqlim_reservation(void) ··· 742 742 743 743 /* 744 744 * Turning off quotas. 745 - * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2 745 + * the quota off logitems: sizeof(struct xfs_qoff_logitem) * 2 746 746 * the superblock for the quota flags: sector size 747 747 */ 748 748 STATIC uint ··· 755 755 756 756 /* 757 757 * End of turning off quotas. 758 - * the xfs_qoff_logitem_t: sizeof(struct xfs_qoff_logitem) * 2 758 + * the quota off logitems: sizeof(struct xfs_qoff_logitem) * 2 759 759 */ 760 760 STATIC uint 761 761 xfs_calc_qm_quotaoff_end_reservation(void)
-2
fs/xfs/libxfs/xfs_types.h
··· 21 21 typedef uint32_t xfs_rtword_t; /* word type for bitmap manipulations */ 22 22 23 23 typedef int64_t xfs_lsn_t; /* log sequence number */ 24 - typedef int32_t xfs_tid_t; /* transaction identifier */ 25 24 26 25 typedef uint32_t xfs_dablk_t; /* dir/attr block number (in file) */ 27 26 typedef uint32_t xfs_dahash_t; /* dir/attr hash value */ ··· 32 33 typedef uint64_t xfs_filblks_t; /* number of blocks in a file */ 33 34 34 35 typedef int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */ 35 - typedef int64_t xfs_sfiloff_t; /* signed block number in a file */ 36 36 37 37 /* 38 38 * New verifiers will return the instruction address of the failing check.
+6 -5
fs/xfs/scrub/attr.c
··· 398 398 STATIC int 399 399 xchk_xattr_rec( 400 400 struct xchk_da_btree *ds, 401 - int level, 402 - void *rec) 401 + int level) 403 402 { 404 403 struct xfs_mount *mp = ds->state->mp; 405 - struct xfs_attr_leaf_entry *ent = rec; 406 - struct xfs_da_state_blk *blk; 404 + struct xfs_da_state_blk *blk = &ds->state->path.blk[level]; 407 405 struct xfs_attr_leaf_name_local *lentry; 408 406 struct xfs_attr_leaf_name_remote *rentry; 409 407 struct xfs_buf *bp; 408 + struct xfs_attr_leaf_entry *ent; 410 409 xfs_dahash_t calc_hash; 411 410 xfs_dahash_t hash; 412 411 int nameidx; ··· 413 414 unsigned int badflags; 414 415 int error; 415 416 416 - blk = &ds->state->path.blk[level]; 417 + ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC); 418 + 419 + ent = xfs_attr3_leaf_entryp(blk->bp->b_addr) + blk->index; 417 420 418 421 /* Check the whole block, if necessary. */ 419 422 error = xchk_xattr_block(ds, level);
+2 -1
fs/xfs/scrub/bitmap.c
··· 294 294 struct xfs_bitmap *bitmap, 295 295 struct xfs_btree_cur *cur) 296 296 { 297 - return xfs_btree_visit_blocks(cur, xfs_bitmap_collect_btblock, bitmap); 297 + return xfs_btree_visit_blocks(cur, xfs_bitmap_collect_btblock, 298 + XFS_BTREE_VISIT_ALL, bitmap); 298 299 }
+8 -1
fs/xfs/scrub/common.h
··· 14 14 static inline bool 15 15 xchk_should_terminate( 16 16 struct xfs_scrub *sc, 17 - int *error) 17 + int *error) 18 18 { 19 + /* 20 + * If preemption is disabled, we need to yield to the scheduler every 21 + * few seconds so that we don't run afoul of the soft lockup watchdog 22 + * or RCU stall detector. 23 + */ 24 + cond_resched(); 25 + 19 26 if (fatal_signal_pending(current)) { 20 27 if (*error == 0) 21 28 *error = -EAGAIN;
+17 -45
fs/xfs/scrub/dabtree.c
··· 77 77 __return_address); 78 78 } 79 79 80 - /* Find an entry at a certain level in a da btree. */ 81 - STATIC void * 82 - xchk_da_btree_entry( 83 - struct xchk_da_btree *ds, 84 - int level, 85 - int rec) 80 + static struct xfs_da_node_entry * 81 + xchk_da_btree_node_entry( 82 + struct xchk_da_btree *ds, 83 + int level) 86 84 { 87 - char *ents; 88 - struct xfs_da_state_blk *blk; 89 - void *baddr; 85 + struct xfs_da_state_blk *blk = &ds->state->path.blk[level]; 86 + struct xfs_da3_icnode_hdr hdr; 90 87 91 - /* Dispatch the entry finding function. */ 92 - blk = &ds->state->path.blk[level]; 93 - baddr = blk->bp->b_addr; 94 - switch (blk->magic) { 95 - case XFS_ATTR_LEAF_MAGIC: 96 - case XFS_ATTR3_LEAF_MAGIC: 97 - ents = (char *)xfs_attr3_leaf_entryp(baddr); 98 - return ents + (rec * sizeof(struct xfs_attr_leaf_entry)); 99 - case XFS_DIR2_LEAFN_MAGIC: 100 - case XFS_DIR3_LEAFN_MAGIC: 101 - ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr); 102 - return ents + (rec * sizeof(struct xfs_dir2_leaf_entry)); 103 - case XFS_DIR2_LEAF1_MAGIC: 104 - case XFS_DIR3_LEAF1_MAGIC: 105 - ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr); 106 - return ents + (rec * sizeof(struct xfs_dir2_leaf_entry)); 107 - case XFS_DA_NODE_MAGIC: 108 - case XFS_DA3_NODE_MAGIC: 109 - ents = (char *)ds->dargs.dp->d_ops->node_tree_p(baddr); 110 - return ents + (rec * sizeof(struct xfs_da_node_entry)); 111 - } 88 + ASSERT(blk->magic == XFS_DA_NODE_MAGIC); 112 89 113 - return NULL; 90 + xfs_da3_node_hdr_from_disk(ds->sc->mp, &hdr, blk->bp->b_addr); 91 + return hdr.btree + blk->index; 114 92 } 115 93 116 94 /* Scrub a da btree hash (key). */ ··· 98 120 int level, 99 121 __be32 *hashp) 100 122 { 101 - struct xfs_da_state_blk *blks; 102 123 struct xfs_da_node_entry *entry; 103 124 xfs_dahash_t hash; 104 125 xfs_dahash_t parent_hash; ··· 112 135 return 0; 113 136 114 137 /* Is this hash no larger than the parent hash? */ 115 - blks = ds->state->path.blk; 116 - entry = xchk_da_btree_entry(ds, level - 1, blks[level - 1].index); 138 + entry = xchk_da_btree_node_entry(ds, level - 1); 117 139 parent_hash = be32_to_cpu(entry->hashval); 118 140 if (parent_hash < hash) 119 141 xchk_da_set_corrupt(ds, level); ··· 331 355 goto out_nobuf; 332 356 333 357 /* Read the buffer. */ 334 - error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno, -2, 335 - &blk->bp, dargs->whichfork, 358 + error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno, 359 + XFS_DABUF_MAP_HOLE_OK, &blk->bp, dargs->whichfork, 336 360 &xchk_da_btree_buf_ops); 337 361 if (!xchk_da_process_error(ds, level, &error)) 338 362 goto out_nobuf; ··· 409 433 XFS_BLFT_DA_NODE_BUF); 410 434 blk->magic = XFS_DA_NODE_MAGIC; 411 435 node = blk->bp->b_addr; 412 - ip->d_ops->node_hdr_from_disk(&nodehdr, node); 413 - btree = ip->d_ops->node_tree_p(node); 436 + xfs_da3_node_hdr_from_disk(ip->i_mount, &nodehdr, node); 437 + btree = nodehdr.btree; 414 438 *pmaxrecs = nodehdr.count; 415 439 blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval); 416 440 if (level == 0) { ··· 455 479 struct xfs_mount *mp = sc->mp; 456 480 struct xfs_da_state_blk *blks; 457 481 struct xfs_da_node_entry *key; 458 - void *rec; 459 482 xfs_dablk_t blkno; 460 483 int level; 461 484 int error; 462 485 463 486 /* Skip short format data structures; no btree to scan. */ 464 - if (XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 465 - XFS_IFORK_FORMAT(sc->ip, whichfork) != XFS_DINODE_FMT_BTREE) 487 + if (!xfs_ifork_has_extents(sc->ip, whichfork)) 466 488 return 0; 467 489 468 490 /* Set up initial da state. */ ··· 512 538 } 513 539 514 540 /* Dispatch record scrubbing. */ 515 - rec = xchk_da_btree_entry(&ds, level, 516 - blks[level].index); 517 - error = scrub_fn(&ds, level, rec); 541 + error = scrub_fn(&ds, level); 518 542 if (error) 519 543 break; 520 544 if (xchk_should_terminate(sc, &error) || ··· 534 562 } 535 563 536 564 /* Hashes in order for scrub? */ 537 - key = xchk_da_btree_entry(&ds, level, blks[level].index); 565 + key = xchk_da_btree_node_entry(&ds, level); 538 566 error = xchk_da_btree_hash(&ds, level, &key->hashval); 539 567 if (error) 540 568 goto out;
+1 -2
fs/xfs/scrub/dabtree.h
··· 28 28 int tree_level; 29 29 }; 30 30 31 - typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds, 32 - int level, void *rec); 31 + typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds, int level); 33 32 34 33 /* Check for da btree operation errors. */ 35 34 bool xchk_da_process_error(struct xchk_da_btree *ds, int level, int *error);
+68 -64
fs/xfs/scrub/dir.c
··· 113 113 offset = xfs_dir2_db_to_da(mp->m_dir_geo, 114 114 xfs_dir2_dataptr_to_db(mp->m_dir_geo, pos)); 115 115 116 + if (xchk_should_terminate(sdc->sc, &error)) 117 + return error; 118 + 116 119 /* Does this inode number make sense? */ 117 120 if (!xfs_verify_dir_ino(mp, ino)) { 118 121 xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, offset); ··· 182 179 STATIC int 183 180 xchk_dir_rec( 184 181 struct xchk_da_btree *ds, 185 - int level, 186 - void *rec) 182 + int level) 187 183 { 184 + struct xfs_da_state_blk *blk = &ds->state->path.blk[level]; 188 185 struct xfs_mount *mp = ds->state->mp; 189 - struct xfs_dir2_leaf_entry *ent = rec; 190 186 struct xfs_inode *dp = ds->dargs.dp; 187 + struct xfs_da_geometry *geo = mp->m_dir_geo; 191 188 struct xfs_dir2_data_entry *dent; 192 189 struct xfs_buf *bp; 193 - char *p, *endp; 190 + struct xfs_dir2_leaf_entry *ent; 191 + unsigned int end; 192 + unsigned int iter_off; 194 193 xfs_ino_t ino; 195 194 xfs_dablk_t rec_bno; 196 195 xfs_dir2_db_t db; ··· 200 195 xfs_dir2_dataptr_t ptr; 201 196 xfs_dahash_t calc_hash; 202 197 xfs_dahash_t hash; 198 + struct xfs_dir3_icleaf_hdr hdr; 203 199 unsigned int tag; 204 200 int error; 201 + 202 + ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC || 203 + blk->magic == XFS_DIR2_LEAFN_MAGIC); 204 + 205 + xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr); 206 + ent = hdr.ents + blk->index; 205 207 206 208 /* Check the hash of the entry. */ 207 209 error = xchk_da_btree_hash(ds, level, &ent->hashval); ··· 221 209 return 0; 222 210 223 211 /* Find the directory entry's location. */ 224 - db = xfs_dir2_dataptr_to_db(mp->m_dir_geo, ptr); 225 - off = xfs_dir2_dataptr_to_off(mp->m_dir_geo, ptr); 226 - rec_bno = xfs_dir2_db_to_da(mp->m_dir_geo, db); 212 + db = xfs_dir2_dataptr_to_db(geo, ptr); 213 + off = xfs_dir2_dataptr_to_off(geo, ptr); 214 + rec_bno = xfs_dir2_db_to_da(geo, db); 227 215 228 - if (rec_bno >= mp->m_dir_geo->leafblk) { 216 + if (rec_bno >= geo->leafblk) { 229 217 xchk_da_set_corrupt(ds, level); 230 218 goto out; 231 219 } 232 - error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno, -2, &bp); 220 + error = xfs_dir3_data_read(ds->dargs.trans, dp, rec_bno, 221 + XFS_DABUF_MAP_HOLE_OK, &bp); 233 222 if (!xchk_fblock_process_error(ds->sc, XFS_DATA_FORK, rec_bno, 234 223 &error)) 235 224 goto out; ··· 243 230 if (ds->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 244 231 goto out_relse; 245 232 246 - dent = (struct xfs_dir2_data_entry *)(((char *)bp->b_addr) + off); 233 + dent = bp->b_addr + off; 247 234 248 235 /* Make sure we got a real directory entry. */ 249 - p = (char *)mp->m_dir_inode_ops->data_entry_p(bp->b_addr); 250 - endp = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr); 251 - if (!endp) { 236 + iter_off = geo->data_entry_offset; 237 + end = xfs_dir3_data_end_offset(geo, bp->b_addr); 238 + if (!end) { 252 239 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 253 240 goto out_relse; 254 241 } 255 - while (p < endp) { 256 - struct xfs_dir2_data_entry *dep; 257 - struct xfs_dir2_data_unused *dup; 242 + for (;;) { 243 + struct xfs_dir2_data_entry *dep = bp->b_addr + iter_off; 244 + struct xfs_dir2_data_unused *dup = bp->b_addr + iter_off; 258 245 259 - dup = (struct xfs_dir2_data_unused *)p; 246 + if (iter_off >= end) { 247 + xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 248 + goto out_relse; 249 + } 250 + 260 251 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 261 - p += be16_to_cpu(dup->length); 252 + iter_off += be16_to_cpu(dup->length); 262 253 continue; 263 254 } 264 - dep = (struct xfs_dir2_data_entry *)p; 265 255 if (dep == dent) 266 256 break; 267 - p += mp->m_dir_inode_ops->data_entsize(dep->namelen); 268 - } 269 - if (p >= endp) { 270 - xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 271 - goto out_relse; 257 + iter_off += xfs_dir2_data_entsize(mp, dep->namelen); 272 258 } 273 259 274 260 /* Retrieve the entry, sanity check it, and compare hashes. */ 275 261 ino = be64_to_cpu(dent->inumber); 276 262 hash = be32_to_cpu(ent->hashval); 277 - tag = be16_to_cpup(dp->d_ops->data_entry_tag_p(dent)); 263 + tag = be16_to_cpup(xfs_dir2_data_entry_tag_p(mp, dent)); 278 264 if (!xfs_verify_dir_ino(mp, ino) || tag != off) 279 265 xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno); 280 266 if (dent->namelen == 0) { ··· 331 319 struct xfs_buf *bp; 332 320 struct xfs_dir2_data_free *bf; 333 321 struct xfs_mount *mp = sc->mp; 334 - const struct xfs_dir_ops *d_ops; 335 - char *ptr; 336 - char *endptr; 337 322 u16 tag; 338 323 unsigned int nr_bestfrees = 0; 339 324 unsigned int nr_frees = 0; 340 325 unsigned int smallest_bestfree; 341 326 int newlen; 342 - int offset; 327 + unsigned int offset; 328 + unsigned int end; 343 329 int error; 344 - 345 - d_ops = sc->ip->d_ops; 346 330 347 331 if (is_block) { 348 332 /* dir block format */ ··· 347 339 error = xfs_dir3_block_read(sc->tp, sc->ip, &bp); 348 340 } else { 349 341 /* dir data format */ 350 - error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, -1, &bp); 342 + error = xfs_dir3_data_read(sc->tp, sc->ip, lblk, 0, &bp); 351 343 } 352 344 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) 353 345 goto out; ··· 359 351 goto out_buf; 360 352 361 353 /* Do the bestfrees correspond to actual free space? */ 362 - bf = d_ops->data_bestfree_p(bp->b_addr); 354 + bf = xfs_dir2_data_bestfree_p(mp, bp->b_addr); 363 355 smallest_bestfree = UINT_MAX; 364 356 for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { 365 357 offset = be16_to_cpu(dfp->offset); ··· 369 361 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 370 362 goto out_buf; 371 363 } 372 - dup = (struct xfs_dir2_data_unused *)(bp->b_addr + offset); 364 + dup = bp->b_addr + offset; 373 365 tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)); 374 366 375 367 /* bestfree doesn't match the entry it points at? */ 376 368 if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG) || 377 369 be16_to_cpu(dup->length) != be16_to_cpu(dfp->length) || 378 - tag != ((char *)dup - (char *)bp->b_addr)) { 370 + tag != offset) { 379 371 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 380 372 goto out_buf; 381 373 } ··· 391 383 } 392 384 393 385 /* Make sure the bestfrees are actually the best free spaces. */ 394 - ptr = (char *)d_ops->data_entry_p(bp->b_addr); 395 - endptr = xfs_dir3_data_endp(mp->m_dir_geo, bp->b_addr); 386 + offset = mp->m_dir_geo->data_entry_offset; 387 + end = xfs_dir3_data_end_offset(mp->m_dir_geo, bp->b_addr); 396 388 397 389 /* Iterate the entries, stopping when we hit or go past the end. */ 398 - while (ptr < endptr) { 399 - dup = (struct xfs_dir2_data_unused *)ptr; 390 + while (offset < end) { 391 + dup = bp->b_addr + offset; 392 + 400 393 /* Skip real entries */ 401 394 if (dup->freetag != cpu_to_be16(XFS_DIR2_DATA_FREE_TAG)) { 402 - struct xfs_dir2_data_entry *dep; 395 + struct xfs_dir2_data_entry *dep = bp->b_addr + offset; 403 396 404 - dep = (struct xfs_dir2_data_entry *)ptr; 405 - newlen = d_ops->data_entsize(dep->namelen); 397 + newlen = xfs_dir2_data_entsize(mp, dep->namelen); 406 398 if (newlen <= 0) { 407 399 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 408 400 lblk); 409 401 goto out_buf; 410 402 } 411 - ptr += newlen; 403 + offset += newlen; 412 404 continue; 413 405 } 414 406 415 407 /* Spot check this free entry */ 416 408 tag = be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)); 417 - if (tag != ((char *)dup - (char *)bp->b_addr)) { 409 + if (tag != offset) { 418 410 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 419 411 goto out_buf; 420 412 } ··· 433 425 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 434 426 goto out_buf; 435 427 } 436 - ptr += newlen; 437 - if (ptr <= endptr) 428 + offset += newlen; 429 + if (offset <= end) 438 430 nr_frees++; 439 431 } 440 432 441 433 /* We're required to fill all the space. */ 442 - if (ptr != endptr) 434 + if (offset != end) 443 435 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 444 436 445 437 /* Did we see at least as many free slots as there are bestfrees? */ ··· 466 458 { 467 459 struct xfs_dir2_data_free *dfp; 468 460 469 - dfp = sc->ip->d_ops->data_bestfree_p(dbp->b_addr); 461 + dfp = xfs_dir2_data_bestfree_p(sc->mp, dbp->b_addr); 470 462 471 463 if (len != be16_to_cpu(dfp->length)) 472 464 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); ··· 483 475 xfs_dablk_t lblk) 484 476 { 485 477 struct xfs_dir3_icleaf_hdr leafhdr; 486 - struct xfs_dir2_leaf_entry *ents; 487 478 struct xfs_dir2_leaf_tail *ltp; 488 479 struct xfs_dir2_leaf *leaf; 489 480 struct xfs_buf *dbp; 490 481 struct xfs_buf *bp; 491 - const struct xfs_dir_ops *d_ops = sc->ip->d_ops; 492 482 struct xfs_da_geometry *geo = sc->mp->m_dir_geo; 493 483 __be16 *bestp; 494 484 __u16 best; ··· 498 492 int error; 499 493 500 494 /* Read the free space block. */ 501 - error = xfs_dir3_leaf_read(sc->tp, sc->ip, lblk, -1, &bp); 495 + error = xfs_dir3_leaf_read(sc->tp, sc->ip, lblk, &bp); 502 496 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, &error)) 503 497 goto out; 504 498 xchk_buffer_recheck(sc, bp); 505 499 506 500 leaf = bp->b_addr; 507 - d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 508 - ents = d_ops->leaf_ents_p(leaf); 501 + xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf); 509 502 ltp = xfs_dir2_leaf_tail_p(geo, leaf); 510 503 bestcount = be32_to_cpu(ltp->bestcount); 511 504 bestp = xfs_dir2_leaf_bests_p(ltp); ··· 526 521 } 527 522 528 523 /* Is the leaf count even remotely sane? */ 529 - if (leafhdr.count > d_ops->leaf_max_ents(geo)) { 524 + if (leafhdr.count > geo->leaf_max_ents) { 530 525 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 531 526 goto out; 532 527 } 533 528 534 529 /* Leaves and bests don't overlap in leaf format. */ 535 - if ((char *)&ents[leafhdr.count] > (char *)bestp) { 530 + if ((char *)&leafhdr.ents[leafhdr.count] > (char *)bestp) { 536 531 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 537 532 goto out; 538 533 } 539 534 540 535 /* Check hash value order, count stale entries. */ 541 536 for (i = 0; i < leafhdr.count; i++) { 542 - hash = be32_to_cpu(ents[i].hashval); 537 + hash = be32_to_cpu(leafhdr.ents[i].hashval); 543 538 if (i > 0 && lasthash > hash) 544 539 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); 545 540 lasthash = hash; 546 - if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 541 + if (leafhdr.ents[i].address == 542 + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 547 543 stale++; 548 544 } 549 545 if (leafhdr.stale != stale) ··· 558 552 if (best == NULLDATAOFF) 559 553 continue; 560 554 error = xfs_dir3_data_read(sc->tp, sc->ip, 561 - i * args->geo->fsbcount, -1, &dbp); 555 + i * args->geo->fsbcount, 0, &dbp); 562 556 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, 563 557 &error)) 564 558 break; ··· 581 575 struct xfs_dir3_icfree_hdr freehdr; 582 576 struct xfs_buf *dbp; 583 577 struct xfs_buf *bp; 584 - __be16 *bestp; 585 578 __u16 best; 586 579 unsigned int stale = 0; 587 580 int i; ··· 600 595 } 601 596 602 597 /* Check all the entries. */ 603 - sc->ip->d_ops->free_hdr_from_disk(&freehdr, bp->b_addr); 604 - bestp = sc->ip->d_ops->free_bests_p(bp->b_addr); 605 - for (i = 0; i < freehdr.nvalid; i++, bestp++) { 606 - best = be16_to_cpu(*bestp); 598 + xfs_dir2_free_hdr_from_disk(sc->ip->i_mount, &freehdr, bp->b_addr); 599 + for (i = 0; i < freehdr.nvalid; i++) { 600 + best = be16_to_cpu(freehdr.bests[i]); 607 601 if (best == NULLDATAOFF) { 608 602 stale++; 609 603 continue; 610 604 } 611 605 error = xfs_dir3_data_read(sc->tp, sc->ip, 612 606 (freehdr.firstdb + i) * args->geo->fsbcount, 613 - -1, &dbp); 607 + 0, &dbp); 614 608 if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, lblk, 615 609 &error)) 616 610 break;
+6 -2
fs/xfs/scrub/fscounters.c
··· 104 104 pag = NULL; 105 105 error = 0; 106 106 107 - if (fatal_signal_pending(current)) 107 + if (xchk_should_terminate(sc, &error)) 108 108 break; 109 109 } 110 110 ··· 163 163 uint64_t delayed; 164 164 xfs_agnumber_t agno; 165 165 int tries = 8; 166 + int error = 0; 166 167 167 168 retry: 168 169 fsc->icount = 0; ··· 197 196 198 197 xfs_perag_put(pag); 199 198 200 - if (fatal_signal_pending(current)) 199 + if (xchk_should_terminate(sc, &error)) 201 200 break; 202 201 } 202 + 203 + if (error) 204 + return error; 203 205 204 206 /* 205 207 * The global incore space reservation is taken from the incore
+1
fs/xfs/scrub/health.c
··· 11 11 #include "xfs_sb.h" 12 12 #include "xfs_health.h" 13 13 #include "scrub/scrub.h" 14 + #include "scrub/health.h" 14 15 15 16 /* 16 17 * Scrub and In-Core Filesystem Health Assessments
+21 -6
fs/xfs/scrub/parent.c
··· 32 32 33 33 struct xchk_parent_ctx { 34 34 struct dir_context dc; 35 + struct xfs_scrub *sc; 35 36 xfs_ino_t ino; 36 37 xfs_nlink_t nlink; 38 + bool cancelled; 37 39 }; 38 40 39 41 /* Look for a single entry in a directory pointing to an inode. */ ··· 49 47 unsigned type) 50 48 { 51 49 struct xchk_parent_ctx *spc; 50 + int error = 0; 52 51 53 52 spc = container_of(dc, struct xchk_parent_ctx, dc); 54 53 if (spc->ino == ino) 55 54 spc->nlink++; 56 - return 0; 55 + 56 + /* 57 + * If we're facing a fatal signal, bail out. Store the cancellation 58 + * status separately because the VFS readdir code squashes error codes 59 + * into short directory reads. 60 + */ 61 + if (xchk_should_terminate(spc->sc, &error)) 62 + spc->cancelled = true; 63 + 64 + return error; 57 65 } 58 66 59 67 /* Count the number of dentries in the parent dir that point to this inode. */ ··· 74 62 xfs_nlink_t *nlink) 75 63 { 76 64 struct xchk_parent_ctx spc = { 77 - .dc.actor = xchk_parent_actor, 78 - .dc.pos = 0, 79 - .ino = sc->ip->i_ino, 80 - .nlink = 0, 65 + .dc.actor = xchk_parent_actor, 66 + .ino = sc->ip->i_ino, 67 + .sc = sc, 81 68 }; 82 69 size_t bufsize; 83 70 loff_t oldpos; ··· 91 80 */ 92 81 lock_mode = xfs_ilock_data_map_shared(parent); 93 82 if (parent->i_d.di_nextents > 0) 94 - error = xfs_dir3_data_readahead(parent, 0, -1); 83 + error = xfs_dir3_data_readahead(parent, 0, 0); 95 84 xfs_iunlock(parent, lock_mode); 96 85 if (error) 97 86 return error; ··· 108 97 error = xfs_readdir(sc->tp, parent, &spc.dc, bufsize); 109 98 if (error) 110 99 goto out; 100 + if (spc.cancelled) { 101 + error = -EAGAIN; 102 + goto out; 103 + } 111 104 if (oldpos == spc.dc.pos) 112 105 break; 113 106 oldpos = spc.dc.pos;
+7
fs/xfs/scrub/quota.c
··· 93 93 unsigned long long rcount; 94 94 xfs_ino_t fs_icount; 95 95 xfs_dqid_t id = be32_to_cpu(d->d_id); 96 + int error = 0; 97 + 98 + if (xchk_should_terminate(sc, &error)) 99 + return error; 96 100 97 101 /* 98 102 * Except for the root dquot, the actual dquot we got must either have ··· 181 177 xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); 182 178 if (id != 0 && rhard != 0 && rcount > rhard) 183 179 xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset); 180 + 181 + if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) 182 + return -EFSCORRUPTED; 184 183 185 184 return 0; 186 185 }
+1
fs/xfs/scrub/scrub.c
··· 16 16 #include "xfs_qm.h" 17 17 #include "xfs_errortag.h" 18 18 #include "xfs_error.h" 19 + #include "xfs_scrub.h" 19 20 #include "scrub/scrub.h" 20 21 #include "scrub/common.h" 21 22 #include "scrub/trace.h"
+14 -4
fs/xfs/xfs_acl.c
··· 12 12 #include "xfs_inode.h" 13 13 #include "xfs_attr.h" 14 14 #include "xfs_trace.h" 15 - #include <linux/posix_acl_xattr.h> 15 + #include "xfs_error.h" 16 + #include "xfs_acl.h" 16 17 18 + #include <linux/posix_acl_xattr.h> 17 19 18 20 /* 19 21 * Locking scheme: ··· 25 23 26 24 STATIC struct posix_acl * 27 25 xfs_acl_from_disk( 26 + struct xfs_mount *mp, 28 27 const struct xfs_acl *aclp, 29 28 int len, 30 29 int max_entries) ··· 35 32 const struct xfs_acl_entry *ace; 36 33 unsigned int count, i; 37 34 38 - if (len < sizeof(*aclp)) 35 + if (len < sizeof(*aclp)) { 36 + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp, 37 + len); 39 38 return ERR_PTR(-EFSCORRUPTED); 39 + } 40 + 40 41 count = be32_to_cpu(aclp->acl_cnt); 41 - if (count > max_entries || XFS_ACL_SIZE(count) != len) 42 + if (count > max_entries || XFS_ACL_SIZE(count) != len) { 43 + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp, 44 + len); 42 45 return ERR_PTR(-EFSCORRUPTED); 46 + } 43 47 44 48 acl = posix_acl_alloc(count, GFP_KERNEL); 45 49 if (!acl) ··· 155 145 if (error != -ENOATTR) 156 146 acl = ERR_PTR(error); 157 147 } else { 158 - acl = xfs_acl_from_disk(xfs_acl, len, 148 + acl = xfs_acl_from_disk(ip->i_mount, xfs_acl, len, 159 149 XFS_ACL_MAX_ENTRIES(ip->i_mount)); 160 150 kmem_free(xfs_acl); 161 151 }
+10 -33
fs/xfs/xfs_aops.c
··· 30 30 return container_of(ctx, struct xfs_writepage_ctx, ctx); 31 31 } 32 32 33 - struct block_device * 34 - xfs_find_bdev_for_inode( 35 - struct inode *inode) 36 - { 37 - struct xfs_inode *ip = XFS_I(inode); 38 - struct xfs_mount *mp = ip->i_mount; 39 - 40 - if (XFS_IS_REALTIME_INODE(ip)) 41 - return mp->m_rtdev_targp->bt_bdev; 42 - else 43 - return mp->m_ddev_targp->bt_bdev; 44 - } 45 - 46 - struct dax_device * 47 - xfs_find_daxdev_for_inode( 48 - struct inode *inode) 49 - { 50 - struct xfs_inode *ip = XFS_I(inode); 51 - struct xfs_mount *mp = ip->i_mount; 52 - 53 - if (XFS_IS_REALTIME_INODE(ip)) 54 - return mp->m_rtdev_targp->bt_daxdev; 55 - else 56 - return mp->m_ddev_targp->bt_daxdev; 57 - } 58 - 59 33 /* 60 34 * Fast and loose check if this write could update the on-disk inode size. 61 35 */ ··· 583 609 struct address_space *mapping, 584 610 struct writeback_control *wbc) 585 611 { 586 - xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED); 612 + struct xfs_inode *ip = XFS_I(mapping->host); 613 + 614 + xfs_iflags_clear(ip, XFS_ITRUNCATED); 587 615 return dax_writeback_mapping_range(mapping, 588 - xfs_find_bdev_for_inode(mapping->host), wbc); 616 + xfs_inode_buftarg(ip)->bt_bdev, wbc); 589 617 } 590 618 591 619 STATIC sector_t ··· 610 634 */ 611 635 if (xfs_is_cow_inode(ip) || XFS_IS_REALTIME_INODE(ip)) 612 636 return 0; 613 - return iomap_bmap(mapping, block, &xfs_iomap_ops); 637 + return iomap_bmap(mapping, block, &xfs_read_iomap_ops); 614 638 } 615 639 616 640 STATIC int ··· 618 642 struct file *unused, 619 643 struct page *page) 620 644 { 621 - return iomap_readpage(page, &xfs_iomap_ops); 645 + return iomap_readpage(page, &xfs_read_iomap_ops); 622 646 } 623 647 624 648 STATIC int ··· 628 652 struct list_head *pages, 629 653 unsigned nr_pages) 630 654 { 631 - return iomap_readpages(mapping, pages, nr_pages, &xfs_iomap_ops); 655 + return iomap_readpages(mapping, pages, nr_pages, &xfs_read_iomap_ops); 632 656 } 633 657 634 658 static int ··· 637 661 struct file *swap_file, 638 662 sector_t *span) 639 663 { 640 - sis->bdev = xfs_find_bdev_for_inode(file_inode(swap_file)); 641 - return iomap_swapfile_activate(sis, swap_file, span, &xfs_iomap_ops); 664 + sis->bdev = xfs_inode_buftarg(XFS_I(file_inode(swap_file)))->bt_bdev; 665 + return iomap_swapfile_activate(sis, swap_file, span, 666 + &xfs_read_iomap_ops); 642 667 } 643 668 644 669 const struct address_space_operations xfs_address_space_operations = {
-3
fs/xfs/xfs_aops.h
··· 11 11 12 12 int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size); 13 13 14 - extern struct block_device *xfs_find_bdev_for_inode(struct inode *); 15 - extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *); 16 - 17 14 #endif /* __XFS_AOPS_H__ */
+46 -30
fs/xfs/xfs_attr_inactive.c
··· 22 22 #include "xfs_attr_leaf.h" 23 23 #include "xfs_quota.h" 24 24 #include "xfs_dir2.h" 25 + #include "xfs_error.h" 25 26 26 27 /* 27 28 * Look at all the extents for this logical region, ··· 191 190 */ 192 191 STATIC int 193 192 xfs_attr3_node_inactive( 194 - struct xfs_trans **trans, 195 - struct xfs_inode *dp, 196 - struct xfs_buf *bp, 197 - int level) 193 + struct xfs_trans **trans, 194 + struct xfs_inode *dp, 195 + struct xfs_buf *bp, 196 + int level) 198 197 { 199 - xfs_da_blkinfo_t *info; 200 - xfs_da_intnode_t *node; 201 - xfs_dablk_t child_fsb; 202 - xfs_daddr_t parent_blkno, child_blkno; 203 - int error, i; 204 - struct xfs_buf *child_bp; 205 - struct xfs_da_node_entry *btree; 198 + struct xfs_mount *mp = dp->i_mount; 199 + struct xfs_da_blkinfo *info; 200 + xfs_dablk_t child_fsb; 201 + xfs_daddr_t parent_blkno, child_blkno; 202 + struct xfs_buf *child_bp; 206 203 struct xfs_da3_icnode_hdr ichdr; 204 + int error, i; 207 205 208 206 /* 209 207 * Since this code is recursive (gasp!) we must protect ourselves. 210 208 */ 211 209 if (level > XFS_DA_NODE_MAXDEPTH) { 212 210 xfs_trans_brelse(*trans, bp); /* no locks for later trans */ 213 - return -EIO; 211 + xfs_buf_corruption_error(bp); 212 + return -EFSCORRUPTED; 214 213 } 215 214 216 - node = bp->b_addr; 217 - dp->d_ops->node_hdr_from_disk(&ichdr, node); 215 + xfs_da3_node_hdr_from_disk(dp->i_mount, &ichdr, bp->b_addr); 218 216 parent_blkno = bp->b_bn; 219 217 if (!ichdr.count) { 220 218 xfs_trans_brelse(*trans, bp); 221 219 return 0; 222 220 } 223 - btree = dp->d_ops->node_tree_p(node); 224 - child_fsb = be32_to_cpu(btree[0].before); 221 + child_fsb = be32_to_cpu(ichdr.btree[0].before); 225 222 xfs_trans_brelse(*trans, bp); /* no locks for later trans */ 226 223 227 224 /* ··· 234 235 * traversal of the tree so we may deal with many blocks 235 236 * before we come back to this one. 236 237 */ 237 - error = xfs_da3_node_read(*trans, dp, child_fsb, -1, &child_bp, 238 + error = xfs_da3_node_read(*trans, dp, child_fsb, &child_bp, 238 239 XFS_ATTR_FORK); 239 240 if (error) 240 241 return error; ··· 257 258 error = xfs_attr3_leaf_inactive(trans, dp, child_bp); 258 259 break; 259 260 default: 260 - error = -EIO; 261 + xfs_buf_corruption_error(child_bp); 261 262 xfs_trans_brelse(*trans, child_bp); 263 + error = -EFSCORRUPTED; 262 264 break; 263 265 } 264 266 if (error) ··· 268 268 /* 269 269 * Remove the subsidiary block from the cache and from the log. 270 270 */ 271 - error = xfs_da_get_buf(*trans, dp, 0, child_blkno, &child_bp, 272 - XFS_ATTR_FORK); 273 - if (error) 271 + child_bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp, 272 + child_blkno, 273 + XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0); 274 + if (!child_bp) 275 + return -EIO; 276 + error = bp->b_error; 277 + if (error) { 278 + xfs_trans_brelse(*trans, child_bp); 274 279 return error; 280 + } 275 281 xfs_trans_binval(*trans, child_bp); 276 282 277 283 /* ··· 285 279 * child block number. 286 280 */ 287 281 if (i + 1 < ichdr.count) { 288 - error = xfs_da3_node_read(*trans, dp, 0, parent_blkno, 289 - &bp, XFS_ATTR_FORK); 282 + struct xfs_da3_icnode_hdr phdr; 283 + 284 + error = xfs_da3_node_read_mapped(*trans, dp, 285 + parent_blkno, &bp, XFS_ATTR_FORK); 290 286 if (error) 291 287 return error; 292 - node = bp->b_addr; 293 - btree = dp->d_ops->node_tree_p(node); 294 - child_fsb = be32_to_cpu(btree[i + 1].before); 288 + xfs_da3_node_hdr_from_disk(dp->i_mount, &phdr, 289 + bp->b_addr); 290 + child_fsb = be32_to_cpu(phdr.btree[i + 1].before); 295 291 xfs_trans_brelse(*trans, bp); 296 292 } 297 293 /* ··· 318 310 struct xfs_trans **trans, 319 311 struct xfs_inode *dp) 320 312 { 313 + struct xfs_mount *mp = dp->i_mount; 321 314 struct xfs_da_blkinfo *info; 322 315 struct xfs_buf *bp; 323 316 xfs_daddr_t blkno; ··· 330 321 * the extents in reverse order the extent containing 331 322 * block 0 must still be there. 332 323 */ 333 - error = xfs_da3_node_read(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK); 324 + error = xfs_da3_node_read(*trans, dp, 0, &bp, XFS_ATTR_FORK); 334 325 if (error) 335 326 return error; 336 327 blkno = bp->b_bn; ··· 350 341 error = xfs_attr3_leaf_inactive(trans, dp, bp); 351 342 break; 352 343 default: 353 - error = -EIO; 344 + error = -EFSCORRUPTED; 345 + xfs_buf_corruption_error(bp); 354 346 xfs_trans_brelse(*trans, bp); 355 347 break; 356 348 } ··· 361 351 /* 362 352 * Invalidate the incore copy of the root block. 363 353 */ 364 - error = xfs_da_get_buf(*trans, dp, 0, blkno, &bp, XFS_ATTR_FORK); 365 - if (error) 354 + bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno, 355 + XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0); 356 + if (!bp) 357 + return -EIO; 358 + error = bp->b_error; 359 + if (error) { 360 + xfs_trans_brelse(*trans, bp); 366 361 return error; 362 + } 367 363 xfs_trans_binval(*trans, bp); /* remove from cache */ 368 364 /* 369 365 * Commit the invalidate and start the next transaction.
+46 -29
fs/xfs/xfs_attr_list.c
··· 49 49 * we can begin returning them to the user. 50 50 */ 51 51 static int 52 - xfs_attr_shortform_list(xfs_attr_list_context_t *context) 52 + xfs_attr_shortform_list( 53 + struct xfs_attr_list_context *context) 53 54 { 54 - attrlist_cursor_kern_t *cursor; 55 - xfs_attr_sf_sort_t *sbuf, *sbp; 56 - xfs_attr_shortform_t *sf; 57 - xfs_attr_sf_entry_t *sfe; 58 - xfs_inode_t *dp; 59 - int sbsize, nsbuf, count, i; 55 + struct attrlist_cursor_kern *cursor; 56 + struct xfs_attr_sf_sort *sbuf, *sbp; 57 + struct xfs_attr_shortform *sf; 58 + struct xfs_attr_sf_entry *sfe; 59 + struct xfs_inode *dp; 60 + int sbsize, nsbuf, count, i; 61 + int error = 0; 60 62 61 63 ASSERT(context != NULL); 62 64 dp = context->dp; ··· 86 84 (XFS_ISRESET_CURSOR(cursor) && 87 85 (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { 88 86 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { 87 + if (XFS_IS_CORRUPT(context->dp->i_mount, 88 + !xfs_attr_namecheck(sfe->nameval, 89 + sfe->namelen))) 90 + return -EFSCORRUPTED; 89 91 context->put_listent(context, 90 92 sfe->flags, 91 93 sfe->nameval, ··· 167 161 break; 168 162 } 169 163 } 170 - if (i == nsbuf) { 171 - kmem_free(sbuf); 172 - return 0; 173 - } 164 + if (i == nsbuf) 165 + goto out; 174 166 175 167 /* 176 168 * Loop putting entries into the user buffer. ··· 177 173 if (cursor->hashval != sbp->hash) { 178 174 cursor->hashval = sbp->hash; 179 175 cursor->offset = 0; 176 + } 177 + if (XFS_IS_CORRUPT(context->dp->i_mount, 178 + !xfs_attr_namecheck(sbp->name, 179 + sbp->namelen))) { 180 + error = -EFSCORRUPTED; 181 + goto out; 180 182 } 181 183 context->put_listent(context, 182 184 sbp->flags, ··· 193 183 break; 194 184 cursor->offset++; 195 185 } 196 - 186 + out: 197 187 kmem_free(sbuf); 198 - return 0; 188 + return error; 199 189 } 200 190 201 191 /* ··· 223 213 ASSERT(*pbp == NULL); 224 214 cursor->blkno = 0; 225 215 for (;;) { 226 - error = xfs_da3_node_read(tp, dp, cursor->blkno, -1, &bp, 216 + error = xfs_da3_node_read(tp, dp, cursor->blkno, &bp, 227 217 XFS_ATTR_FORK); 228 218 if (error) 229 219 return error; ··· 239 229 goto out_corruptbuf; 240 230 } 241 231 242 - dp->d_ops->node_hdr_from_disk(&nodehdr, node); 232 + xfs_da3_node_hdr_from_disk(mp, &nodehdr, node); 243 233 244 234 /* Tree taller than we can handle; bail out! */ 245 235 if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) ··· 253 243 else 254 244 expected_level--; 255 245 256 - btree = dp->d_ops->node_tree_p(node); 246 + btree = nodehdr.btree; 257 247 for (i = 0; i < nodehdr.count; btree++, i++) { 258 248 if (cursor->hashval <= be32_to_cpu(btree->hashval)) { 259 249 cursor->blkno = be32_to_cpu(btree->before); ··· 268 258 return 0; 269 259 270 260 /* We can't point back to the root. */ 271 - if (cursor->blkno == 0) 261 + if (XFS_IS_CORRUPT(mp, cursor->blkno == 0)) 272 262 return -EFSCORRUPTED; 273 263 } 274 264 ··· 279 269 return 0; 280 270 281 271 out_corruptbuf: 272 + xfs_buf_corruption_error(bp); 282 273 xfs_trans_brelse(tp, bp); 283 274 return -EFSCORRUPTED; 284 275 } ··· 295 284 struct xfs_buf *bp; 296 285 struct xfs_inode *dp = context->dp; 297 286 struct xfs_mount *mp = dp->i_mount; 298 - int error; 287 + int error = 0; 299 288 300 289 trace_xfs_attr_node_list(context); 301 290 ··· 309 298 */ 310 299 bp = NULL; 311 300 if (cursor->blkno > 0) { 312 - error = xfs_da3_node_read(context->tp, dp, cursor->blkno, -1, 313 - &bp, XFS_ATTR_FORK); 301 + error = xfs_da3_node_read(context->tp, dp, cursor->blkno, &bp, 302 + XFS_ATTR_FORK); 314 303 if ((error != 0) && (error != -EFSCORRUPTED)) 315 304 return error; 316 305 if (bp) { ··· 369 358 */ 370 359 for (;;) { 371 360 leaf = bp->b_addr; 372 - xfs_attr3_leaf_list_int(bp, context); 361 + error = xfs_attr3_leaf_list_int(bp, context); 362 + if (error) 363 + break; 373 364 xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); 374 365 if (context->seen_enough || leafhdr.forw == 0) 375 366 break; 376 367 cursor->blkno = leafhdr.forw; 377 368 xfs_trans_brelse(context->tp, bp); 378 - error = xfs_attr3_leaf_read(context->tp, dp, cursor->blkno, -1, &bp); 369 + error = xfs_attr3_leaf_read(context->tp, dp, cursor->blkno, 370 + &bp); 379 371 if (error) 380 372 return error; 381 373 } 382 374 xfs_trans_brelse(context->tp, bp); 383 - return 0; 375 + return error; 384 376 } 385 377 386 378 /* 387 379 * Copy out attribute list entries for attr_list(), for leaf attribute lists. 388 380 */ 389 - void 381 + int 390 382 xfs_attr3_leaf_list_int( 391 383 struct xfs_buf *bp, 392 384 struct xfs_attr_list_context *context) ··· 431 417 } 432 418 if (i == ichdr.count) { 433 419 trace_xfs_attr_list_notfound(context); 434 - return; 420 + return 0; 435 421 } 436 422 } else { 437 423 entry = &entries[0]; ··· 471 457 valuelen = be32_to_cpu(name_rmt->valuelen); 472 458 } 473 459 460 + if (XFS_IS_CORRUPT(context->dp->i_mount, 461 + !xfs_attr_namecheck(name, namelen))) 462 + return -EFSCORRUPTED; 474 463 context->put_listent(context, entry->flags, 475 464 name, namelen, valuelen); 476 465 if (context->seen_enough) ··· 481 464 cursor->offset++; 482 465 } 483 466 trace_xfs_attr_list_leaf_end(context); 484 - return; 467 + return 0; 485 468 } 486 469 487 470 /* ··· 496 479 trace_xfs_attr_leaf_list(context); 497 480 498 481 context->cursor->blkno = 0; 499 - error = xfs_attr3_leaf_read(context->tp, context->dp, 0, -1, &bp); 482 + error = xfs_attr3_leaf_read(context->tp, context->dp, 0, &bp); 500 483 if (error) 501 484 return error; 502 485 503 - xfs_attr3_leaf_list_int(bp, context); 486 + error = xfs_attr3_leaf_list_int(bp, context); 504 487 xfs_trans_brelse(context->tp, bp); 505 - return 0; 488 + return error; 506 489 } 507 490 508 491 int
+6 -5
fs/xfs/xfs_bmap_item.c
··· 21 21 #include "xfs_icache.h" 22 22 #include "xfs_bmap_btree.h" 23 23 #include "xfs_trans_space.h" 24 - 24 + #include "xfs_error.h" 25 25 26 26 kmem_zone_t *xfs_bui_zone; 27 27 kmem_zone_t *xfs_bud_zone; ··· 35 35 xfs_bui_item_free( 36 36 struct xfs_bui_log_item *buip) 37 37 { 38 - kmem_zone_free(xfs_bui_zone, buip); 38 + kmem_cache_free(xfs_bui_zone, buip); 39 39 } 40 40 41 41 /* ··· 201 201 struct xfs_bud_log_item *budp = BUD_ITEM(lip); 202 202 203 203 xfs_bui_release(budp->bud_buip); 204 - kmem_zone_free(xfs_bud_zone, budp); 204 + kmem_cache_free(xfs_bud_zone, budp); 205 205 } 206 206 207 207 static const struct xfs_item_ops xfs_bud_item_ops = { ··· 456 456 if (buip->bui_format.bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) { 457 457 set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); 458 458 xfs_bui_release(buip); 459 - return -EIO; 459 + return -EFSCORRUPTED; 460 460 } 461 461 462 462 /* ··· 490 490 */ 491 491 set_bit(XFS_BUI_RECOVERED, &buip->bui_flags); 492 492 xfs_bui_release(buip); 493 - return -EIO; 493 + return -EFSCORRUPTED; 494 494 } 495 495 496 496 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, ··· 525 525 type = bui_type; 526 526 break; 527 527 default: 528 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 528 529 error = -EFSCORRUPTED; 529 530 goto err_inode; 530 531 }
+42 -215
fs/xfs/xfs_bmap_util.c
··· 53 53 */ 54 54 int 55 55 xfs_zero_extent( 56 - struct xfs_inode *ip, 57 - xfs_fsblock_t start_fsb, 58 - xfs_off_t count_fsb) 56 + struct xfs_inode *ip, 57 + xfs_fsblock_t start_fsb, 58 + xfs_off_t count_fsb) 59 59 { 60 - struct xfs_mount *mp = ip->i_mount; 61 - xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); 62 - sector_t block = XFS_BB_TO_FSBT(mp, sector); 60 + struct xfs_mount *mp = ip->i_mount; 61 + struct xfs_buftarg *target = xfs_inode_buftarg(ip); 62 + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); 63 + sector_t block = XFS_BB_TO_FSBT(mp, sector); 63 64 64 - return blkdev_issue_zeroout(xfs_find_bdev_for_inode(VFS_I(ip)), 65 + return blkdev_issue_zeroout(target->bt_bdev, 65 66 block << (mp->m_super->s_blocksize_bits - 9), 66 67 count_fsb << (mp->m_super->s_blocksize_bits - 9), 67 68 GFP_NOFS, 0); ··· 165 164 xfs_trans_mod_dquot_byino(ap->tp, ap->ip, 166 165 ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : 167 166 XFS_TRANS_DQ_RTBCOUNT, (long) ralen); 168 - 169 - /* Zero the extent if we were asked to do so */ 170 - if (ap->datatype & XFS_ALLOC_USERDATA_ZERO) { 171 - error = xfs_zero_extent(ap->ip, ap->blkno, ap->length); 172 - if (error) 173 - return error; 174 - } 175 167 } else { 176 168 ap->length = 0; 177 169 } 178 170 return 0; 179 171 } 180 172 #endif /* CONFIG_XFS_RT */ 181 - 182 - /* 183 - * Check if the endoff is outside the last extent. If so the caller will grow 184 - * the allocation to a stripe unit boundary. All offsets are considered outside 185 - * the end of file for an empty fork, so 1 is returned in *eof in that case. 186 - */ 187 - int 188 - xfs_bmap_eof( 189 - struct xfs_inode *ip, 190 - xfs_fileoff_t endoff, 191 - int whichfork, 192 - int *eof) 193 - { 194 - struct xfs_bmbt_irec rec; 195 - int error; 196 - 197 - error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, eof); 198 - if (error || *eof) 199 - return error; 200 - 201 - *eof = endoff >= rec.br_startoff + rec.br_blockcount; 202 - return 0; 203 - } 204 173 205 174 /* 206 175 * Extent tree block counting routines. ··· 200 229 } 201 230 202 231 /* 203 - * Count leaf blocks given a range of extent records originally 204 - * in btree format. 205 - */ 206 - STATIC void 207 - xfs_bmap_disk_count_leaves( 208 - struct xfs_mount *mp, 209 - struct xfs_btree_block *block, 210 - int numrecs, 211 - xfs_filblks_t *count) 212 - { 213 - int b; 214 - xfs_bmbt_rec_t *frp; 215 - 216 - for (b = 1; b <= numrecs; b++) { 217 - frp = XFS_BMBT_REC_ADDR(mp, block, b); 218 - *count += xfs_bmbt_disk_get_blockcount(frp); 219 - } 220 - } 221 - 222 - /* 223 - * Recursively walks each level of a btree 224 - * to count total fsblocks in use. 225 - */ 226 - STATIC int 227 - xfs_bmap_count_tree( 228 - struct xfs_mount *mp, 229 - struct xfs_trans *tp, 230 - struct xfs_ifork *ifp, 231 - xfs_fsblock_t blockno, 232 - int levelin, 233 - xfs_extnum_t *nextents, 234 - xfs_filblks_t *count) 235 - { 236 - int error; 237 - struct xfs_buf *bp, *nbp; 238 - int level = levelin; 239 - __be64 *pp; 240 - xfs_fsblock_t bno = blockno; 241 - xfs_fsblock_t nextbno; 242 - struct xfs_btree_block *block, *nextblock; 243 - int numrecs; 244 - 245 - error = xfs_btree_read_bufl(mp, tp, bno, &bp, XFS_BMAP_BTREE_REF, 246 - &xfs_bmbt_buf_ops); 247 - if (error) 248 - return error; 249 - *count += 1; 250 - block = XFS_BUF_TO_BLOCK(bp); 251 - 252 - if (--level) { 253 - /* Not at node above leaves, count this level of nodes */ 254 - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); 255 - while (nextbno != NULLFSBLOCK) { 256 - error = xfs_btree_read_bufl(mp, tp, nextbno, &nbp, 257 - XFS_BMAP_BTREE_REF, 258 - &xfs_bmbt_buf_ops); 259 - if (error) 260 - return error; 261 - *count += 1; 262 - nextblock = XFS_BUF_TO_BLOCK(nbp); 263 - nextbno = be64_to_cpu(nextblock->bb_u.l.bb_rightsib); 264 - xfs_trans_brelse(tp, nbp); 265 - } 266 - 267 - /* Dive to the next level */ 268 - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); 269 - bno = be64_to_cpu(*pp); 270 - error = xfs_bmap_count_tree(mp, tp, ifp, bno, level, nextents, 271 - count); 272 - if (error) { 273 - xfs_trans_brelse(tp, bp); 274 - XFS_ERROR_REPORT("xfs_bmap_count_tree(1)", 275 - XFS_ERRLEVEL_LOW, mp); 276 - return -EFSCORRUPTED; 277 - } 278 - xfs_trans_brelse(tp, bp); 279 - } else { 280 - /* count all level 1 nodes and their leaves */ 281 - for (;;) { 282 - nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); 283 - numrecs = be16_to_cpu(block->bb_numrecs); 284 - (*nextents) += numrecs; 285 - xfs_bmap_disk_count_leaves(mp, block, numrecs, count); 286 - xfs_trans_brelse(tp, bp); 287 - if (nextbno == NULLFSBLOCK) 288 - break; 289 - bno = nextbno; 290 - error = xfs_btree_read_bufl(mp, tp, bno, &bp, 291 - XFS_BMAP_BTREE_REF, 292 - &xfs_bmbt_buf_ops); 293 - if (error) 294 - return error; 295 - *count += 1; 296 - block = XFS_BUF_TO_BLOCK(bp); 297 - } 298 - } 299 - return 0; 300 - } 301 - 302 - /* 303 232 * Count fsblocks of the given fork. Delayed allocation extents are 304 233 * not counted towards the totals. 305 234 */ ··· 211 340 xfs_extnum_t *nextents, 212 341 xfs_filblks_t *count) 213 342 { 214 - struct xfs_mount *mp; /* file system mount structure */ 215 - __be64 *pp; /* pointer to block address */ 216 - struct xfs_btree_block *block; /* current btree block */ 217 - struct xfs_ifork *ifp; /* fork structure */ 218 - xfs_fsblock_t bno; /* block # of "block" */ 219 - int level; /* btree level, for checking */ 343 + struct xfs_mount *mp = ip->i_mount; 344 + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 345 + struct xfs_btree_cur *cur; 346 + xfs_extlen_t btblocks = 0; 220 347 int error; 221 348 222 - bno = NULLFSBLOCK; 223 - mp = ip->i_mount; 224 349 *nextents = 0; 225 350 *count = 0; 226 - ifp = XFS_IFORK_PTR(ip, whichfork); 351 + 227 352 if (!ifp) 228 353 return 0; 229 354 230 355 switch (XFS_IFORK_FORMAT(ip, whichfork)) { 231 - case XFS_DINODE_FMT_EXTENTS: 232 - *nextents = xfs_bmap_count_leaves(ifp, count); 233 - return 0; 234 356 case XFS_DINODE_FMT_BTREE: 235 357 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 236 358 error = xfs_iread_extents(tp, ip, whichfork); ··· 231 367 return error; 232 368 } 233 369 234 - /* 235 - * Root level must use BMAP_BROOT_PTR_ADDR macro to get ptr out. 236 - */ 237 - block = ifp->if_broot; 238 - level = be16_to_cpu(block->bb_level); 239 - ASSERT(level > 0); 240 - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); 241 - bno = be64_to_cpu(*pp); 242 - ASSERT(bno != NULLFSBLOCK); 243 - ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); 244 - ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); 370 + cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); 371 + error = xfs_btree_count_blocks(cur, &btblocks); 372 + xfs_btree_del_cursor(cur, error); 373 + if (error) 374 + return error; 245 375 246 - error = xfs_bmap_count_tree(mp, tp, ifp, bno, level, 247 - nextents, count); 248 - if (error) { 249 - XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", 250 - XFS_ERRLEVEL_LOW, mp); 251 - return -EFSCORRUPTED; 252 - } 253 - return 0; 376 + /* 377 + * xfs_btree_count_blocks includes the root block contained in 378 + * the inode fork in @btblocks, so subtract one because we're 379 + * only interested in allocated disk blocks. 380 + */ 381 + *count += btblocks - 1; 382 + 383 + /* fall through */ 384 + case XFS_DINODE_FMT_EXTENTS: 385 + *nextents = xfs_bmap_count_leaves(ifp, count); 386 + break; 254 387 } 255 388 256 389 return 0; ··· 825 964 xfs_trans_ijoin(tp, ip, 0); 826 965 827 966 error = xfs_bmapi_write(tp, ip, startoffset_fsb, 828 - allocatesize_fsb, alloc_type, resblks, 829 - imapp, &nimaps); 967 + allocatesize_fsb, alloc_type, 0, imapp, 968 + &nimaps); 830 969 if (error) 831 970 goto error0; 832 971 ··· 900 1039 goto out_unlock; 901 1040 } 902 1041 1042 + /* Caller must first wait for the completion of any pending DIOs if required. */ 903 1043 int 904 1044 xfs_flush_unmap_range( 905 1045 struct xfs_inode *ip, ··· 911 1049 struct inode *inode = VFS_I(ip); 912 1050 xfs_off_t rounding, start, end; 913 1051 int error; 914 - 915 - /* wait for the completion of any pending DIOs */ 916 - inode_dio_wait(inode); 917 1052 918 1053 rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_SIZE); 919 1054 start = round_down(offset, rounding); ··· 943 1084 if (len <= 0) /* if nothing being freed */ 944 1085 return 0; 945 1086 946 - error = xfs_flush_unmap_range(ip, offset, len); 947 - if (error) 948 - return error; 949 - 950 1087 startoffset_fsb = XFS_B_TO_FSB(mp, offset); 951 1088 endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len); 952 1089 ··· 968 1113 return 0; 969 1114 if (offset + len > XFS_ISIZE(ip)) 970 1115 len = XFS_ISIZE(ip) - offset; 971 - error = iomap_zero_range(VFS_I(ip), offset, len, NULL, &xfs_iomap_ops); 1116 + error = iomap_zero_range(VFS_I(ip), offset, len, NULL, 1117 + &xfs_buffered_write_iomap_ops); 972 1118 if (error) 973 1119 return error; 974 1120 ··· 985 1129 } 986 1130 987 1131 return error; 988 - } 989 - 990 - /* 991 - * Preallocate and zero a range of a file. This mechanism has the allocation 992 - * semantics of fallocate and in addition converts data in the range to zeroes. 993 - */ 994 - int 995 - xfs_zero_file_space( 996 - struct xfs_inode *ip, 997 - xfs_off_t offset, 998 - xfs_off_t len) 999 - { 1000 - struct xfs_mount *mp = ip->i_mount; 1001 - uint blksize; 1002 - int error; 1003 - 1004 - trace_xfs_zero_file_space(ip); 1005 - 1006 - blksize = 1 << mp->m_sb.sb_blocklog; 1007 - 1008 - /* 1009 - * Punch a hole and prealloc the range. We use hole punch rather than 1010 - * unwritten extent conversion for two reasons: 1011 - * 1012 - * 1.) Hole punch handles partial block zeroing for us. 1013 - * 1014 - * 2.) If prealloc returns ENOSPC, the file range is still zero-valued 1015 - * by virtue of the hole punch. 1016 - */ 1017 - error = xfs_free_file_space(ip, offset, len); 1018 - if (error || xfs_is_always_cow_inode(ip)) 1019 - return error; 1020 - 1021 - return xfs_alloc_file_space(ip, round_down(offset, blksize), 1022 - round_up(offset + len, blksize) - 1023 - round_down(offset, blksize), 1024 - XFS_BMAPI_PREALLOC); 1025 1132 } 1026 1133 1027 1134 static int ··· 1568 1749 error = -EINVAL; 1569 1750 goto out_unlock; 1570 1751 } 1752 + 1753 + error = xfs_qm_dqattach(ip); 1754 + if (error) 1755 + goto out_unlock; 1756 + 1757 + error = xfs_qm_dqattach(tip); 1758 + if (error) 1759 + goto out_unlock; 1571 1760 1572 1761 error = xfs_swap_extent_flush(ip); 1573 1762 if (error)
-4
fs/xfs/xfs_bmap_util.h
··· 30 30 } 31 31 #endif /* CONFIG_XFS_RT */ 32 32 33 - int xfs_bmap_eof(struct xfs_inode *ip, xfs_fileoff_t endoff, 34 - int whichfork, int *eof); 35 33 int xfs_bmap_punch_delalloc_range(struct xfs_inode *ip, 36 34 xfs_fileoff_t start_fsb, xfs_fileoff_t length); 37 35 ··· 56 58 int xfs_alloc_file_space(struct xfs_inode *ip, xfs_off_t offset, 57 59 xfs_off_t len, int alloc_type); 58 60 int xfs_free_file_space(struct xfs_inode *ip, xfs_off_t offset, 59 - xfs_off_t len); 60 - int xfs_zero_file_space(struct xfs_inode *ip, xfs_off_t offset, 61 61 xfs_off_t len); 62 62 int xfs_collapse_file_space(struct xfs_inode *, xfs_off_t offset, 63 63 xfs_off_t len);
+15 -17
fs/xfs/xfs_buf.c
··· 238 238 */ 239 239 error = xfs_buf_get_maps(bp, nmaps); 240 240 if (error) { 241 - kmem_zone_free(xfs_buf_zone, bp); 241 + kmem_cache_free(xfs_buf_zone, bp); 242 242 return NULL; 243 243 } 244 244 ··· 304 304 * The buffer must not be on any hash - use xfs_buf_rele instead for 305 305 * hashed and refcounted buffers 306 306 */ 307 - void 307 + static void 308 308 xfs_buf_free( 309 309 xfs_buf_t *bp) 310 310 { ··· 328 328 kmem_free(bp->b_addr); 329 329 _xfs_buf_free_pages(bp); 330 330 xfs_buf_free_maps(bp); 331 - kmem_zone_free(xfs_buf_zone, bp); 331 + kmem_cache_free(xfs_buf_zone, bp); 332 332 } 333 333 334 334 /* ··· 461 461 unsigned nofs_flag; 462 462 463 463 /* 464 - * vm_map_ram() will allocate auxillary structures (e.g. 464 + * vm_map_ram() will allocate auxiliary structures (e.g. 465 465 * pagetables) with GFP_KERNEL, yet we are likely to be under 466 466 * GFP_NOFS context here. Hence we need to tell memory reclaim 467 467 * that we are in such a context via PF_MEMALLOC_NOFS to prevent ··· 949 949 _xfs_buf_free_pages(bp); 950 950 fail_free_buf: 951 951 xfs_buf_free_maps(bp); 952 - kmem_zone_free(xfs_buf_zone, bp); 952 + kmem_cache_free(xfs_buf_zone, bp); 953 953 fail: 954 954 return NULL; 955 955 } ··· 1261 1261 int map, 1262 1262 int *buf_offset, 1263 1263 int *count, 1264 - int op, 1265 - int op_flags) 1264 + int op) 1266 1265 { 1267 1266 int page_index; 1268 1267 int total_nr_pages = bp->b_page_count; ··· 1296 1297 bio->bi_iter.bi_sector = sector; 1297 1298 bio->bi_end_io = xfs_buf_bio_end_io; 1298 1299 bio->bi_private = bp; 1299 - bio_set_op_attrs(bio, op, op_flags); 1300 + bio->bi_opf = op; 1300 1301 1301 1302 for (; size && nr_pages; nr_pages--, page_index++) { 1302 1303 int rbytes, nbytes = PAGE_SIZE - offset; ··· 1341 1342 { 1342 1343 struct blk_plug plug; 1343 1344 int op; 1344 - int op_flags = 0; 1345 1345 int offset; 1346 1346 int size; 1347 1347 int i; ··· 1382 1384 dump_stack(); 1383 1385 } 1384 1386 } 1385 - } else if (bp->b_flags & XBF_READ_AHEAD) { 1386 - op = REQ_OP_READ; 1387 - op_flags = REQ_RAHEAD; 1388 1387 } else { 1389 1388 op = REQ_OP_READ; 1389 + if (bp->b_flags & XBF_READ_AHEAD) 1390 + op |= REQ_RAHEAD; 1390 1391 } 1391 1392 1392 1393 /* we only use the buffer cache for meta-data */ 1393 - op_flags |= REQ_META; 1394 + op |= REQ_META; 1394 1395 1395 1396 /* 1396 1397 * Walk all the vectors issuing IO on them. Set up the initial offset ··· 1401 1404 size = BBTOB(bp->b_length); 1402 1405 blk_start_plug(&plug); 1403 1406 for (i = 0; i < bp->b_map_count; i++) { 1404 - xfs_buf_ioapply_map(bp, i, &offset, &size, op, op_flags); 1407 + xfs_buf_ioapply_map(bp, i, &offset, &size, op); 1405 1408 if (bp->b_error) 1406 1409 break; 1407 1410 if (size <= 0) ··· 2060 2063 int __init 2061 2064 xfs_buf_init(void) 2062 2065 { 2063 - xfs_buf_zone = kmem_zone_init_flags(sizeof(xfs_buf_t), "xfs_buf", 2064 - KM_ZONE_HWALIGN, NULL); 2066 + xfs_buf_zone = kmem_cache_create("xfs_buf", 2067 + sizeof(struct xfs_buf), 0, 2068 + SLAB_HWCACHE_ALIGN, NULL); 2065 2069 if (!xfs_buf_zone) 2066 2070 goto out; 2067 2071 ··· 2075 2077 void 2076 2078 xfs_buf_terminate(void) 2077 2079 { 2078 - kmem_zone_destroy(xfs_buf_zone); 2080 + kmem_cache_destroy(xfs_buf_zone); 2079 2081 } 2080 2082 2081 2083 void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref)
-1
fs/xfs/xfs_buf.h
··· 244 244 void xfs_buf_hold(struct xfs_buf *bp); 245 245 246 246 /* Releasing Buffers */ 247 - extern void xfs_buf_free(xfs_buf_t *); 248 247 extern void xfs_buf_rele(xfs_buf_t *); 249 248 250 249 /* Locking and Unlocking Buffers */
+3 -3
fs/xfs/xfs_buf_item.c
··· 763 763 error = xfs_buf_item_get_format(bip, bp->b_map_count); 764 764 ASSERT(error == 0); 765 765 if (error) { /* to stop gcc throwing set-but-unused warnings */ 766 - kmem_zone_free(xfs_buf_item_zone, bip); 766 + kmem_cache_free(xfs_buf_item_zone, bip); 767 767 return error; 768 768 } 769 769 ··· 851 851 * first_bit and last_bit. 852 852 */ 853 853 while ((bits_to_set - bits_set) >= NBWORD) { 854 - *wordp |= 0xffffffff; 854 + *wordp = 0xffffffff; 855 855 bits_set += NBWORD; 856 856 wordp++; 857 857 } ··· 939 939 { 940 940 xfs_buf_item_free_format(bip); 941 941 kmem_free(bip->bli_item.li_lv_shadow); 942 - kmem_zone_free(xfs_buf_item_zone, bip); 942 + kmem_cache_free(xfs_buf_item_zone, bip); 943 943 } 944 944 945 945 /*
+73 -64
fs/xfs/xfs_dir2_readdir.c
··· 17 17 #include "xfs_trace.h" 18 18 #include "xfs_bmap.h" 19 19 #include "xfs_trans.h" 20 + #include "xfs_error.h" 20 21 21 22 /* 22 23 * Directory file type support functions ··· 48 47 { 49 48 int i; /* shortform entry number */ 50 49 struct xfs_inode *dp = args->dp; /* incore directory inode */ 50 + struct xfs_mount *mp = dp->i_mount; 51 51 xfs_dir2_dataptr_t off; /* current entry's offset */ 52 52 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 53 53 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ ··· 70 68 return 0; 71 69 72 70 /* 73 - * Precalculate offsets for . and .. as we will always need them. 74 - * 75 - * XXX(hch): the second argument is sometimes 0 and sometimes 76 - * geo->datablk 71 + * Precalculate offsets for "." and ".." as we will always need them. 72 + * This relies on the fact that directories always start with the 73 + * entries for "." and "..". 77 74 */ 78 75 dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, 79 - dp->d_ops->data_dot_offset); 76 + geo->data_entry_offset); 80 77 dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, 81 - dp->d_ops->data_dotdot_offset); 78 + geo->data_entry_offset + 79 + xfs_dir2_data_entsize(mp, sizeof(".") - 1)); 82 80 83 81 /* 84 82 * Put . entry unless we're starting past it. ··· 93 91 * Put .. entry unless we're starting past it. 94 92 */ 95 93 if (ctx->pos <= dotdot_offset) { 96 - ino = dp->d_ops->sf_get_parent_ino(sfp); 94 + ino = xfs_dir2_sf_get_parent_ino(sfp); 97 95 ctx->pos = dotdot_offset & 0x7fffffff; 98 96 if (!dir_emit(ctx, "..", 2, ino, DT_DIR)) 99 97 return 0; ··· 110 108 xfs_dir2_sf_get_offset(sfep)); 111 109 112 110 if (ctx->pos > off) { 113 - sfep = dp->d_ops->sf_nextentry(sfp, sfep); 111 + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 114 112 continue; 115 113 } 116 114 117 - ino = dp->d_ops->sf_get_ino(sfp, sfep); 118 - filetype = dp->d_ops->sf_get_ftype(sfep); 115 + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); 116 + filetype = xfs_dir2_sf_get_ftype(mp, sfep); 119 117 ctx->pos = off & 0x7fffffff; 118 + if (XFS_IS_CORRUPT(dp->i_mount, 119 + !xfs_dir2_namecheck(sfep->name, 120 + sfep->namelen))) 121 + return -EFSCORRUPTED; 120 122 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, 121 - xfs_dir3_get_dtype(dp->i_mount, filetype))) 123 + xfs_dir3_get_dtype(mp, filetype))) 122 124 return 0; 123 - sfep = dp->d_ops->sf_nextentry(sfp, sfep); 125 + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); 124 126 } 125 127 126 128 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & ··· 141 135 struct dir_context *ctx) 142 136 { 143 137 struct xfs_inode *dp = args->dp; /* incore directory inode */ 144 - xfs_dir2_data_hdr_t *hdr; /* block header */ 145 138 struct xfs_buf *bp; /* buffer for block */ 146 - xfs_dir2_data_entry_t *dep; /* block data entry */ 147 - xfs_dir2_data_unused_t *dup; /* block unused entry */ 148 - char *endptr; /* end of the data entries */ 149 139 int error; /* error return value */ 150 - char *ptr; /* current data entry */ 151 140 int wantoff; /* starting block offset */ 152 141 xfs_off_t cook; 153 142 struct xfs_da_geometry *geo = args->geo; 154 143 int lock_mode; 144 + unsigned int offset; 145 + unsigned int end; 155 146 156 147 /* 157 148 * If the block number in the offset is out of range, we're done. ··· 167 164 * We'll skip entries before this. 168 165 */ 169 166 wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos); 170 - hdr = bp->b_addr; 171 167 xfs_dir3_data_check(dp, bp); 172 - /* 173 - * Set up values for the loop. 174 - */ 175 - ptr = (char *)dp->d_ops->data_entry_p(hdr); 176 - endptr = xfs_dir3_data_endp(geo, hdr); 177 168 178 169 /* 179 170 * Loop over the data portion of the block. 180 171 * Each object is a real entry (dep) or an unused one (dup). 181 172 */ 182 - while (ptr < endptr) { 173 + offset = geo->data_entry_offset; 174 + end = xfs_dir3_data_end_offset(geo, bp->b_addr); 175 + while (offset < end) { 176 + struct xfs_dir2_data_unused *dup = bp->b_addr + offset; 177 + struct xfs_dir2_data_entry *dep = bp->b_addr + offset; 183 178 uint8_t filetype; 184 179 185 - dup = (xfs_dir2_data_unused_t *)ptr; 186 180 /* 187 181 * Unused, skip it. 188 182 */ 189 183 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 190 - ptr += be16_to_cpu(dup->length); 184 + offset += be16_to_cpu(dup->length); 191 185 continue; 192 186 } 193 - 194 - dep = (xfs_dir2_data_entry_t *)ptr; 195 187 196 188 /* 197 189 * Bump pointer for the next iteration. 198 190 */ 199 - ptr += dp->d_ops->data_entsize(dep->namelen); 191 + offset += xfs_dir2_data_entsize(dp->i_mount, dep->namelen); 192 + 200 193 /* 201 194 * The entry is before the desired starting point, skip it. 202 195 */ 203 - if ((char *)dep - (char *)hdr < wantoff) 196 + if (offset < wantoff) 204 197 continue; 205 198 206 - cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, 207 - (char *)dep - (char *)hdr); 199 + cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset); 208 200 209 201 ctx->pos = cook & 0x7fffffff; 210 - filetype = dp->d_ops->data_get_ftype(dep); 202 + filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); 211 203 /* 212 204 * If it didn't fit, set the final offset to here & return. 213 205 */ 206 + if (XFS_IS_CORRUPT(dp->i_mount, 207 + !xfs_dir2_namecheck(dep->name, 208 + dep->namelen))) { 209 + error = -EFSCORRUPTED; 210 + goto out_rele; 211 + } 214 212 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 215 213 be64_to_cpu(dep->inumber), 216 - xfs_dir3_get_dtype(dp->i_mount, filetype))) { 217 - xfs_trans_brelse(args->trans, bp); 218 - return 0; 219 - } 214 + xfs_dir3_get_dtype(dp->i_mount, filetype))) 215 + goto out_rele; 220 216 } 221 217 222 218 /* ··· 224 222 */ 225 223 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & 226 224 0x7fffffff; 225 + out_rele: 227 226 xfs_trans_brelse(args->trans, bp); 228 - return 0; 227 + return error; 229 228 } 230 229 231 230 /* ··· 279 276 new_off = xfs_dir2_da_to_byte(geo, map.br_startoff); 280 277 if (new_off > *cur_off) 281 278 *cur_off = new_off; 282 - error = xfs_dir3_data_read(args->trans, dp, map.br_startoff, -1, &bp); 279 + error = xfs_dir3_data_read(args->trans, dp, map.br_startoff, 0, &bp); 283 280 if (error) 284 281 goto out; 285 282 ··· 314 311 break; 315 312 } 316 313 if (next_ra > *ra_blk) { 317 - xfs_dir3_data_readahead(dp, next_ra, -2); 314 + xfs_dir3_data_readahead(dp, next_ra, 315 + XFS_DABUF_MAP_HOLE_OK); 318 316 *ra_blk = next_ra; 319 317 } 320 318 ra_want -= geo->fsbcount; ··· 347 343 size_t bufsize) 348 344 { 349 345 struct xfs_inode *dp = args->dp; 346 + struct xfs_mount *mp = dp->i_mount; 350 347 struct xfs_buf *bp = NULL; /* data block buffer */ 351 - xfs_dir2_data_hdr_t *hdr; /* data block header */ 352 348 xfs_dir2_data_entry_t *dep; /* data entry */ 353 349 xfs_dir2_data_unused_t *dup; /* unused entry */ 354 - char *ptr = NULL; /* pointer to current data */ 355 350 struct xfs_da_geometry *geo = args->geo; 356 351 xfs_dablk_t rablk = 0; /* current readahead block */ 357 352 xfs_dir2_off_t curoff; /* current overall offset */ 358 353 int length; /* temporary length value */ 359 354 int byteoff; /* offset in current block */ 360 355 int lock_mode; 356 + unsigned int offset = 0; 361 357 int error = 0; /* error return value */ 362 358 363 359 /* ··· 384 380 * If we have no buffer, or we're off the end of the 385 381 * current buffer, need to get another one. 386 382 */ 387 - if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) { 383 + if (!bp || offset >= geo->blksize) { 388 384 if (bp) { 389 385 xfs_trans_brelse(args->trans, bp); 390 386 bp = NULL; ··· 397 393 if (error || !bp) 398 394 break; 399 395 400 - hdr = bp->b_addr; 401 396 xfs_dir3_data_check(dp, bp); 402 397 /* 403 398 * Find our position in the block. 404 399 */ 405 - ptr = (char *)dp->d_ops->data_entry_p(hdr); 400 + offset = geo->data_entry_offset; 406 401 byteoff = xfs_dir2_byte_to_off(geo, curoff); 407 402 /* 408 403 * Skip past the header. 409 404 */ 410 405 if (byteoff == 0) 411 - curoff += dp->d_ops->data_entry_offset; 406 + curoff += geo->data_entry_offset; 412 407 /* 413 408 * Skip past entries until we reach our offset. 414 409 */ 415 410 else { 416 - while ((char *)ptr - (char *)hdr < byteoff) { 417 - dup = (xfs_dir2_data_unused_t *)ptr; 411 + while (offset < byteoff) { 412 + dup = bp->b_addr + offset; 418 413 419 414 if (be16_to_cpu(dup->freetag) 420 415 == XFS_DIR2_DATA_FREE_TAG) { 421 416 422 417 length = be16_to_cpu(dup->length); 423 - ptr += length; 418 + offset += length; 424 419 continue; 425 420 } 426 - dep = (xfs_dir2_data_entry_t *)ptr; 427 - length = 428 - dp->d_ops->data_entsize(dep->namelen); 429 - ptr += length; 421 + dep = bp->b_addr + offset; 422 + length = xfs_dir2_data_entsize(mp, 423 + dep->namelen); 424 + offset += length; 430 425 } 431 426 /* 432 427 * Now set our real offset. ··· 433 430 curoff = 434 431 xfs_dir2_db_off_to_byte(geo, 435 432 xfs_dir2_byte_to_db(geo, curoff), 436 - (char *)ptr - (char *)hdr); 437 - if (ptr >= (char *)hdr + geo->blksize) { 433 + offset); 434 + if (offset >= geo->blksize) 438 435 continue; 439 - } 440 436 } 441 437 } 438 + 442 439 /* 443 - * We have a pointer to an entry. 444 - * Is it a live one? 440 + * We have a pointer to an entry. Is it a live one? 445 441 */ 446 - dup = (xfs_dir2_data_unused_t *)ptr; 442 + dup = bp->b_addr + offset; 443 + 447 444 /* 448 445 * No, it's unused, skip over it. 449 446 */ 450 447 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 451 448 length = be16_to_cpu(dup->length); 452 - ptr += length; 449 + offset += length; 453 450 curoff += length; 454 451 continue; 455 452 } 456 453 457 - dep = (xfs_dir2_data_entry_t *)ptr; 458 - length = dp->d_ops->data_entsize(dep->namelen); 459 - filetype = dp->d_ops->data_get_ftype(dep); 454 + dep = bp->b_addr + offset; 455 + length = xfs_dir2_data_entsize(mp, dep->namelen); 456 + filetype = xfs_dir2_data_get_ftype(mp, dep); 460 457 461 458 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; 459 + if (XFS_IS_CORRUPT(dp->i_mount, 460 + !xfs_dir2_namecheck(dep->name, 461 + dep->namelen))) { 462 + error = -EFSCORRUPTED; 463 + break; 464 + } 462 465 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 463 466 be64_to_cpu(dep->inumber), 464 467 xfs_dir3_get_dtype(dp->i_mount, filetype))) ··· 473 464 /* 474 465 * Advance to next entry in the block. 475 466 */ 476 - ptr += length; 467 + offset += length; 477 468 curoff += length; 478 469 /* bufsize may have just been a guess; don't go negative */ 479 470 bufsize = bufsize > length ? bufsize - length : 0;
+5 -1
fs/xfs/xfs_discard.c
··· 13 13 #include "xfs_btree.h" 14 14 #include "xfs_alloc_btree.h" 15 15 #include "xfs_alloc.h" 16 + #include "xfs_discard.h" 16 17 #include "xfs_error.h" 17 18 #include "xfs_extent_busy.h" 18 19 #include "xfs_trace.h" ··· 71 70 error = xfs_alloc_get_rec(cur, &fbno, &flen, &i); 72 71 if (error) 73 72 goto out_del_cursor; 74 - XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_del_cursor); 73 + if (XFS_IS_CORRUPT(mp, i != 1)) { 74 + error = -EFSCORRUPTED; 75 + goto out_del_cursor; 76 + } 75 77 ASSERT(flen <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_longest)); 76 78 77 79 /*
+24 -22
fs/xfs/xfs_dquot.c
··· 48 48 */ 49 49 void 50 50 xfs_qm_dqdestroy( 51 - xfs_dquot_t *dqp) 51 + struct xfs_dquot *dqp) 52 52 { 53 53 ASSERT(list_empty(&dqp->q_lru)); 54 54 ··· 56 56 mutex_destroy(&dqp->q_qlock); 57 57 58 58 XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot); 59 - kmem_zone_free(xfs_qm_dqzone, dqp); 59 + kmem_cache_free(xfs_qm_dqzone, dqp); 60 60 } 61 61 62 62 /* ··· 113 113 */ 114 114 void 115 115 xfs_qm_adjust_dqtimers( 116 - xfs_mount_t *mp, 117 - xfs_disk_dquot_t *d) 116 + struct xfs_mount *mp, 117 + struct xfs_disk_dquot *d) 118 118 { 119 119 ASSERT(d->d_id); 120 120 ··· 305 305 /* Create the block mapping. */ 306 306 xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL); 307 307 error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset, 308 - XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 309 - XFS_QM_DQALLOC_SPACE_RES(mp), &map, &nmaps); 308 + XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, 0, &map, 309 + &nmaps); 310 310 if (error) 311 311 return error; 312 312 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); ··· 497 497 struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; 498 498 499 499 /* copy everything from disk dquot to the incore dquot */ 500 - memcpy(&dqp->q_core, ddqp, sizeof(xfs_disk_dquot_t)); 500 + memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot)); 501 501 502 502 /* 503 503 * Reservation counters are defined as reservation plus current usage ··· 833 833 case XFS_DQ_GROUP: 834 834 return ip->i_d.di_gid; 835 835 case XFS_DQ_PROJ: 836 - return xfs_get_projid(ip); 836 + return ip->i_d.di_projid; 837 837 } 838 838 ASSERT(0); 839 839 return 0; ··· 989 989 */ 990 990 void 991 991 xfs_qm_dqrele( 992 - xfs_dquot_t *dqp) 992 + struct xfs_dquot *dqp) 993 993 { 994 994 if (!dqp) 995 995 return; ··· 1018 1018 struct xfs_buf *bp, 1019 1019 struct xfs_log_item *lip) 1020 1020 { 1021 - xfs_dq_logitem_t *qip = (struct xfs_dq_logitem *)lip; 1022 - xfs_dquot_t *dqp = qip->qli_dquot; 1021 + struct xfs_dq_logitem *qip = (struct xfs_dq_logitem *)lip; 1022 + struct xfs_dquot *dqp = qip->qli_dquot; 1023 1023 struct xfs_ail *ailp = lip->li_ailp; 1024 1024 1025 1025 /* ··· 1126 1126 xfs_buf_relse(bp); 1127 1127 xfs_dqfunlock(dqp); 1128 1128 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1129 - return -EIO; 1129 + return -EFSCORRUPTED; 1130 1130 } 1131 1131 1132 1132 /* This is the only portion of data that needs to persist */ 1133 - memcpy(ddqp, &dqp->q_core, sizeof(xfs_disk_dquot_t)); 1133 + memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot)); 1134 1134 1135 1135 /* 1136 1136 * Clear the dirty field and remember the flush lsn for later use. ··· 1188 1188 */ 1189 1189 void 1190 1190 xfs_dqlock2( 1191 - xfs_dquot_t *d1, 1192 - xfs_dquot_t *d2) 1191 + struct xfs_dquot *d1, 1192 + struct xfs_dquot *d2) 1193 1193 { 1194 1194 if (d1 && d2) { 1195 1195 ASSERT(d1 != d2); ··· 1211 1211 int __init 1212 1212 xfs_qm_init(void) 1213 1213 { 1214 - xfs_qm_dqzone = 1215 - kmem_zone_init(sizeof(struct xfs_dquot), "xfs_dquot"); 1214 + xfs_qm_dqzone = kmem_cache_create("xfs_dquot", 1215 + sizeof(struct xfs_dquot), 1216 + 0, 0, NULL); 1216 1217 if (!xfs_qm_dqzone) 1217 1218 goto out; 1218 1219 1219 - xfs_qm_dqtrxzone = 1220 - kmem_zone_init(sizeof(struct xfs_dquot_acct), "xfs_dqtrx"); 1220 + xfs_qm_dqtrxzone = kmem_cache_create("xfs_dqtrx", 1221 + sizeof(struct xfs_dquot_acct), 1222 + 0, 0, NULL); 1221 1223 if (!xfs_qm_dqtrxzone) 1222 1224 goto out_free_dqzone; 1223 1225 1224 1226 return 0; 1225 1227 1226 1228 out_free_dqzone: 1227 - kmem_zone_destroy(xfs_qm_dqzone); 1229 + kmem_cache_destroy(xfs_qm_dqzone); 1228 1230 out: 1229 1231 return -ENOMEM; 1230 1232 } ··· 1234 1232 void 1235 1233 xfs_qm_exit(void) 1236 1234 { 1237 - kmem_zone_destroy(xfs_qm_dqtrxzone); 1238 - kmem_zone_destroy(xfs_qm_dqzone); 1235 + kmem_cache_destroy(xfs_qm_dqtrxzone); 1236 + kmem_cache_destroy(xfs_qm_dqzone); 1239 1237 } 1240 1238 1241 1239 /*
+49 -47
fs/xfs/xfs_dquot.h
··· 30 30 /* 31 31 * The incore dquot structure 32 32 */ 33 - typedef struct xfs_dquot { 34 - uint dq_flags; /* various flags (XFS_DQ_*) */ 35 - struct list_head q_lru; /* global free list of dquots */ 36 - struct xfs_mount*q_mount; /* filesystem this relates to */ 37 - uint q_nrefs; /* # active refs from inodes */ 38 - xfs_daddr_t q_blkno; /* blkno of dquot buffer */ 39 - int q_bufoffset; /* off of dq in buffer (# dquots) */ 40 - xfs_fileoff_t q_fileoffset; /* offset in quotas file */ 33 + struct xfs_dquot { 34 + uint dq_flags; 35 + struct list_head q_lru; 36 + struct xfs_mount *q_mount; 37 + uint q_nrefs; 38 + xfs_daddr_t q_blkno; 39 + int q_bufoffset; 40 + xfs_fileoff_t q_fileoffset; 41 41 42 - xfs_disk_dquot_t q_core; /* actual usage & quotas */ 43 - xfs_dq_logitem_t q_logitem; /* dquot log item */ 44 - xfs_qcnt_t q_res_bcount; /* total regular nblks used+reserved */ 45 - xfs_qcnt_t q_res_icount; /* total inos allocd+reserved */ 46 - xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */ 47 - xfs_qcnt_t q_prealloc_lo_wmark;/* prealloc throttle wmark */ 48 - xfs_qcnt_t q_prealloc_hi_wmark;/* prealloc disabled wmark */ 49 - int64_t q_low_space[XFS_QLOWSP_MAX]; 50 - struct mutex q_qlock; /* quota lock */ 51 - struct completion q_flush; /* flush completion queue */ 52 - atomic_t q_pincount; /* dquot pin count */ 53 - wait_queue_head_t q_pinwait; /* dquot pinning wait queue */ 54 - } xfs_dquot_t; 42 + struct xfs_disk_dquot q_core; 43 + struct xfs_dq_logitem q_logitem; 44 + /* total regular nblks used+reserved */ 45 + xfs_qcnt_t q_res_bcount; 46 + /* total inos allocd+reserved */ 47 + xfs_qcnt_t q_res_icount; 48 + /* total realtime blks used+reserved */ 49 + xfs_qcnt_t q_res_rtbcount; 50 + xfs_qcnt_t q_prealloc_lo_wmark; 51 + xfs_qcnt_t q_prealloc_hi_wmark; 52 + int64_t q_low_space[XFS_QLOWSP_MAX]; 53 + struct mutex q_qlock; 54 + struct completion q_flush; 55 + atomic_t q_pincount; 56 + struct wait_queue_head q_pinwait; 57 + }; 55 58 56 59 /* 57 60 * Lock hierarchy for q_qlock: 58 61 * XFS_QLOCK_NORMAL is the implicit default, 59 - * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2 62 + * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2 60 63 */ 61 64 enum { 62 65 XFS_QLOCK_NORMAL = 0, ··· 67 64 }; 68 65 69 66 /* 70 - * Manage the q_flush completion queue embedded in the dquot. This completion 67 + * Manage the q_flush completion queue embedded in the dquot. This completion 71 68 * queue synchronizes processes attempting to flush the in-core dquot back to 72 69 * disk. 73 70 */ 74 - static inline void xfs_dqflock(xfs_dquot_t *dqp) 71 + static inline void xfs_dqflock(struct xfs_dquot *dqp) 75 72 { 76 73 wait_for_completion(&dqp->q_flush); 77 74 } 78 75 79 - static inline bool xfs_dqflock_nowait(xfs_dquot_t *dqp) 76 + static inline bool xfs_dqflock_nowait(struct xfs_dquot *dqp) 80 77 { 81 78 return try_wait_for_completion(&dqp->q_flush); 82 79 } 83 80 84 - static inline void xfs_dqfunlock(xfs_dquot_t *dqp) 81 + static inline void xfs_dqfunlock(struct xfs_dquot *dqp) 85 82 { 86 83 complete(&dqp->q_flush); 87 84 } ··· 115 112 } 116 113 } 117 114 118 - static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type) 115 + static inline struct xfs_dquot *xfs_inode_dquot(struct xfs_inode *ip, int type) 119 116 { 120 117 switch (type & XFS_DQ_ALLTYPES) { 121 118 case XFS_DQ_USER: ··· 150 147 #define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ) 151 148 #define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP) 152 149 153 - extern void xfs_qm_dqdestroy(xfs_dquot_t *); 154 - extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **); 155 - extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); 156 - extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, 157 - xfs_disk_dquot_t *); 158 - extern void xfs_qm_adjust_dqlimits(struct xfs_mount *, 159 - struct xfs_dquot *); 160 - extern xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip, 161 - uint type); 162 - extern int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id, 150 + void xfs_qm_dqdestroy(struct xfs_dquot *dqp); 151 + int xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp); 152 + void xfs_qm_dqunpin_wait(struct xfs_dquot *dqp); 153 + void xfs_qm_adjust_dqtimers(struct xfs_mount *mp, 154 + struct xfs_disk_dquot *d); 155 + void xfs_qm_adjust_dqlimits(struct xfs_mount *mp, 156 + struct xfs_dquot *d); 157 + xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type); 158 + int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id, 163 159 uint type, bool can_alloc, 164 160 struct xfs_dquot **dqpp); 165 - extern int xfs_qm_dqget_inode(struct xfs_inode *ip, uint type, 166 - bool can_alloc, 167 - struct xfs_dquot **dqpp); 168 - extern int xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id, 161 + int xfs_qm_dqget_inode(struct xfs_inode *ip, uint type, 162 + bool can_alloc, 163 + struct xfs_dquot **dqpp); 164 + int xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id, 169 165 uint type, struct xfs_dquot **dqpp); 170 - extern int xfs_qm_dqget_uncached(struct xfs_mount *mp, 171 - xfs_dqid_t id, uint type, 172 - struct xfs_dquot **dqpp); 173 - extern void xfs_qm_dqput(xfs_dquot_t *); 166 + int xfs_qm_dqget_uncached(struct xfs_mount *mp, 167 + xfs_dqid_t id, uint type, 168 + struct xfs_dquot **dqpp); 169 + void xfs_qm_dqput(struct xfs_dquot *dqp); 174 170 175 - extern void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *); 171 + void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *); 176 172 177 - extern void xfs_dquot_set_prealloc_limits(struct xfs_dquot *); 173 + void xfs_dquot_set_prealloc_limits(struct xfs_dquot *); 178 174 179 175 static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp) 180 176 {
+18 -16
fs/xfs/xfs_dquot_item.h
··· 11 11 struct xfs_mount; 12 12 struct xfs_qoff_logitem; 13 13 14 - typedef struct xfs_dq_logitem { 15 - struct xfs_log_item qli_item; /* common portion */ 16 - struct xfs_dquot *qli_dquot; /* dquot ptr */ 17 - xfs_lsn_t qli_flush_lsn; /* lsn at last flush */ 18 - } xfs_dq_logitem_t; 14 + struct xfs_dq_logitem { 15 + struct xfs_log_item qli_item; /* common portion */ 16 + struct xfs_dquot *qli_dquot; /* dquot ptr */ 17 + xfs_lsn_t qli_flush_lsn; /* lsn at last flush */ 18 + }; 19 19 20 - typedef struct xfs_qoff_logitem { 21 - struct xfs_log_item qql_item; /* common portion */ 22 - struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */ 20 + struct xfs_qoff_logitem { 21 + struct xfs_log_item qql_item; /* common portion */ 22 + struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */ 23 23 unsigned int qql_flags; 24 - } xfs_qoff_logitem_t; 24 + }; 25 25 26 26 27 - extern void xfs_qm_dquot_logitem_init(struct xfs_dquot *); 28 - extern xfs_qoff_logitem_t *xfs_qm_qoff_logitem_init(struct xfs_mount *, 29 - struct xfs_qoff_logitem *, uint); 30 - extern xfs_qoff_logitem_t *xfs_trans_get_qoff_item(struct xfs_trans *, 31 - struct xfs_qoff_logitem *, uint); 32 - extern void xfs_trans_log_quotaoff_item(struct xfs_trans *, 33 - struct xfs_qoff_logitem *); 27 + void xfs_qm_dquot_logitem_init(struct xfs_dquot *dqp); 28 + struct xfs_qoff_logitem *xfs_qm_qoff_logitem_init(struct xfs_mount *mp, 29 + struct xfs_qoff_logitem *start, 30 + uint flags); 31 + struct xfs_qoff_logitem *xfs_trans_get_qoff_item(struct xfs_trans *tp, 32 + struct xfs_qoff_logitem *startqoff, 33 + uint flags); 34 + void xfs_trans_log_quotaoff_item(struct xfs_trans *tp, 35 + struct xfs_qoff_logitem *qlp); 34 36 35 37 #endif /* __XFS_DQUOT_ITEM_H__ */
+26 -5
fs/xfs/xfs_error.c
··· 257 257 258 258 xfs_warn_ratelimited(mp, 259 259 "Injecting error (%s) at file %s, line %d, on filesystem \"%s\"", 260 - expression, file, line, mp->m_fsname); 260 + expression, file, line, mp->m_super->s_id); 261 261 return true; 262 262 } 263 263 ··· 329 329 const char *tag, 330 330 int level, 331 331 struct xfs_mount *mp, 332 - void *buf, 332 + const void *buf, 333 333 size_t bufsize, 334 334 const char *filename, 335 335 int linenum, 336 336 xfs_failaddr_t failaddr) 337 337 { 338 - if (level <= xfs_error_level) 338 + if (buf && level <= xfs_error_level) 339 339 xfs_hex_dump(buf, bufsize); 340 340 xfs_error_report(tag, level, mp, filename, linenum, failaddr); 341 341 xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair"); 342 + } 343 + 344 + /* 345 + * Complain about the kinds of metadata corruption that we can't detect from a 346 + * verifier, such as incorrect inter-block relationship data. Does not set 347 + * bp->b_error. 348 + */ 349 + void 350 + xfs_buf_corruption_error( 351 + struct xfs_buf *bp) 352 + { 353 + struct xfs_mount *mp = bp->b_mount; 354 + 355 + xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR, 356 + "Metadata corruption detected at %pS, %s block 0x%llx", 357 + __return_address, bp->b_ops->name, bp->b_bn); 358 + 359 + xfs_alert(mp, "Unmount and run xfs_repair"); 360 + 361 + if (xfs_error_level >= XFS_ERRLEVEL_HIGH) 362 + xfs_stack_trace(); 342 363 } 343 364 344 365 /* ··· 371 350 struct xfs_buf *bp, 372 351 int error, 373 352 const char *name, 374 - void *buf, 353 + const void *buf, 375 354 size_t bufsz, 376 355 xfs_failaddr_t failaddr) 377 356 { ··· 423 402 struct xfs_inode *ip, 424 403 int error, 425 404 const char *name, 426 - void *buf, 405 + const void *buf, 427 406 size_t bufsz, 428 407 xfs_failaddr_t failaddr) 429 408 {
+4 -29
fs/xfs/xfs_error.h
··· 12 12 const char *filename, int linenum, 13 13 xfs_failaddr_t failaddr); 14 14 extern void xfs_corruption_error(const char *tag, int level, 15 - struct xfs_mount *mp, void *buf, size_t bufsize, 15 + struct xfs_mount *mp, const void *buf, size_t bufsize, 16 16 const char *filename, int linenum, 17 17 xfs_failaddr_t failaddr); 18 + void xfs_buf_corruption_error(struct xfs_buf *bp); 18 19 extern void xfs_buf_verifier_error(struct xfs_buf *bp, int error, 19 - const char *name, void *buf, size_t bufsz, 20 + const char *name, const void *buf, size_t bufsz, 20 21 xfs_failaddr_t failaddr); 21 22 extern void xfs_verifier_error(struct xfs_buf *bp, int error, 22 23 xfs_failaddr_t failaddr); 23 24 extern void xfs_inode_verifier_error(struct xfs_inode *ip, int error, 24 - const char *name, void *buf, size_t bufsz, 25 + const char *name, const void *buf, size_t bufsz, 25 26 xfs_failaddr_t failaddr); 26 27 27 28 #define XFS_ERROR_REPORT(e, lvl, mp) \ ··· 37 36 38 37 /* Dump 128 bytes of any corrupt buffer */ 39 38 #define XFS_CORRUPTION_DUMP_LEN (128) 40 - 41 - /* 42 - * Macros to set EFSCORRUPTED & return/branch. 43 - */ 44 - #define XFS_WANT_CORRUPTED_GOTO(mp, x, l) \ 45 - { \ 46 - int fs_is_ok = (x); \ 47 - ASSERT(fs_is_ok); \ 48 - if (unlikely(!fs_is_ok)) { \ 49 - XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \ 50 - XFS_ERRLEVEL_LOW, mp); \ 51 - error = -EFSCORRUPTED; \ 52 - goto l; \ 53 - } \ 54 - } 55 - 56 - #define XFS_WANT_CORRUPTED_RETURN(mp, x) \ 57 - { \ 58 - int fs_is_ok = (x); \ 59 - ASSERT(fs_is_ok); \ 60 - if (unlikely(!fs_is_ok)) { \ 61 - XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \ 62 - XFS_ERRLEVEL_LOW, mp); \ 63 - return -EFSCORRUPTED; \ 64 - } \ 65 - } 66 39 67 40 #ifdef DEBUG 68 41 extern int xfs_errortag_init(struct xfs_mount *mp);
+1 -1
fs/xfs/xfs_extent_busy.c
··· 367 367 * If this is a metadata allocation, try to reuse the busy 368 368 * extent instead of trimming the allocation. 369 369 */ 370 - if (!xfs_alloc_is_userdata(args->datatype) && 370 + if (!(args->datatype & XFS_ALLOC_USERDATA) && 371 371 !(busyp->flags & XFS_EXTENT_BUSY_DISCARDED)) { 372 372 if (!xfs_extent_busy_update_extent(args->mp, args->pag, 373 373 busyp, fbno, flen,
+5 -4
fs/xfs/xfs_extfree_item.c
··· 21 21 #include "xfs_alloc.h" 22 22 #include "xfs_bmap.h" 23 23 #include "xfs_trace.h" 24 - 24 + #include "xfs_error.h" 25 25 26 26 kmem_zone_t *xfs_efi_zone; 27 27 kmem_zone_t *xfs_efd_zone; ··· 39 39 if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS) 40 40 kmem_free(efip); 41 41 else 42 - kmem_zone_free(xfs_efi_zone, efip); 42 + kmem_cache_free(xfs_efi_zone, efip); 43 43 } 44 44 45 45 /* ··· 228 228 } 229 229 return 0; 230 230 } 231 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); 231 232 return -EFSCORRUPTED; 232 233 } 233 234 ··· 244 243 if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS) 245 244 kmem_free(efdp); 246 245 else 247 - kmem_zone_free(xfs_efd_zone, efdp); 246 + kmem_cache_free(xfs_efd_zone, efdp); 248 247 } 249 248 250 249 /* ··· 625 624 */ 626 625 set_bit(XFS_EFI_RECOVERED, &efip->efi_flags); 627 626 xfs_efi_release(efip); 628 - return -EIO; 627 + return -EFSCORRUPTED; 629 628 } 630 629 } 631 630
+78 -26
fs/xfs/xfs_file.c
··· 188 188 file_accessed(iocb->ki_filp); 189 189 190 190 xfs_ilock(ip, XFS_IOLOCK_SHARED); 191 - ret = iomap_dio_rw(iocb, to, &xfs_iomap_ops, NULL, is_sync_kiocb(iocb)); 191 + ret = iomap_dio_rw(iocb, to, &xfs_read_iomap_ops, NULL, 192 + is_sync_kiocb(iocb)); 192 193 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 193 194 194 195 return ret; ··· 216 215 xfs_ilock(ip, XFS_IOLOCK_SHARED); 217 216 } 218 217 219 - ret = dax_iomap_rw(iocb, to, &xfs_iomap_ops); 218 + ret = dax_iomap_rw(iocb, to, &xfs_read_iomap_ops); 220 219 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 221 220 222 221 file_accessed(iocb->ki_filp); ··· 352 351 353 352 trace_xfs_zero_eof(ip, isize, iocb->ki_pos - isize); 354 353 error = iomap_zero_range(inode, isize, iocb->ki_pos - isize, 355 - NULL, &xfs_iomap_ops); 354 + NULL, &xfs_buffered_write_iomap_ops); 356 355 if (error) 357 356 return error; 358 357 } else ··· 487 486 int unaligned_io = 0; 488 487 int iolock; 489 488 size_t count = iov_iter_count(from); 490 - struct xfs_buftarg *target = XFS_IS_REALTIME_INODE(ip) ? 491 - mp->m_rtdev_targp : mp->m_ddev_targp; 489 + struct xfs_buftarg *target = xfs_inode_buftarg(ip); 492 490 493 491 /* DIO must be aligned to device logical sector size */ 494 492 if ((iocb->ki_pos | count) & target->bt_logical_sectormask) ··· 551 551 * If unaligned, this is the only IO in-flight. Wait on it before we 552 552 * release the iolock to prevent subsequent overlapping IO. 553 553 */ 554 - ret = iomap_dio_rw(iocb, from, &xfs_iomap_ops, &xfs_dio_write_ops, 554 + ret = iomap_dio_rw(iocb, from, &xfs_direct_write_iomap_ops, 555 + &xfs_dio_write_ops, 555 556 is_sync_kiocb(iocb) || unaligned_io); 556 557 out: 557 558 xfs_iunlock(ip, iolock); ··· 592 591 count = iov_iter_count(from); 593 592 594 593 trace_xfs_file_dax_write(ip, count, pos); 595 - ret = dax_iomap_rw(iocb, from, &xfs_iomap_ops); 594 + ret = dax_iomap_rw(iocb, from, &xfs_direct_write_iomap_ops); 596 595 if (ret > 0 && iocb->ki_pos > i_size_read(inode)) { 597 596 i_size_write(inode, iocb->ki_pos); 598 597 error = xfs_setfilesize(ip, pos, ret); ··· 639 638 current->backing_dev_info = inode_to_bdi(inode); 640 639 641 640 trace_xfs_file_buffered_write(ip, iov_iter_count(from), iocb->ki_pos); 642 - ret = iomap_file_buffered_write(iocb, from, &xfs_iomap_ops); 641 + ret = iomap_file_buffered_write(iocb, from, 642 + &xfs_buffered_write_iomap_ops); 643 643 if (likely(ret >= 0)) 644 644 iocb->ki_pos += ret; 645 645 ··· 817 815 if (error) 818 816 goto out_unlock; 819 817 818 + /* 819 + * Must wait for all AIO to complete before we continue as AIO can 820 + * change the file size on completion without holding any locks we 821 + * currently hold. We must do this first because AIO can update both 822 + * the on disk and in memory inode sizes, and the operations that follow 823 + * require the in-memory size to be fully up-to-date. 824 + */ 825 + inode_dio_wait(inode); 826 + 827 + /* 828 + * Now AIO and DIO has drained we flush and (if necessary) invalidate 829 + * the cached range over the first operation we are about to run. 830 + * 831 + * We care about zero and collapse here because they both run a hole 832 + * punch over the range first. Because that can zero data, and the range 833 + * of invalidation for the shift operations is much larger, we still do 834 + * the required flush for collapse in xfs_prepare_shift(). 835 + * 836 + * Insert has the same range requirements as collapse, and we extend the 837 + * file first which can zero data. Hence insert has the same 838 + * flush/invalidate requirements as collapse and so they are both 839 + * handled at the right time by xfs_prepare_shift(). 840 + */ 841 + if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE | 842 + FALLOC_FL_COLLAPSE_RANGE)) { 843 + error = xfs_flush_unmap_range(ip, offset, len); 844 + if (error) 845 + goto out_unlock; 846 + } 847 + 820 848 if (mode & FALLOC_FL_PUNCH_HOLE) { 821 849 error = xfs_free_file_space(ip, offset, len); 822 850 if (error) ··· 910 878 } 911 879 912 880 if (mode & FALLOC_FL_ZERO_RANGE) { 913 - error = xfs_zero_file_space(ip, offset, len); 881 + /* 882 + * Punch a hole and prealloc the range. We use a hole 883 + * punch rather than unwritten extent conversion for two 884 + * reasons: 885 + * 886 + * 1.) Hole punch handles partial block zeroing for us. 887 + * 2.) If prealloc returns ENOSPC, the file range is 888 + * still zero-valued by virtue of the hole punch. 889 + */ 890 + unsigned int blksize = i_blocksize(inode); 891 + 892 + trace_xfs_zero_file_space(ip); 893 + 894 + error = xfs_free_file_space(ip, offset, len); 895 + if (error) 896 + goto out_unlock; 897 + 898 + len = round_up(offset + len, blksize) - 899 + round_down(offset, blksize); 900 + offset = round_down(offset, blksize); 914 901 } else if (mode & FALLOC_FL_UNSHARE_RANGE) { 915 902 error = xfs_reflink_unshare(ip, offset, len); 916 903 if (error) 917 904 goto out_unlock; 918 - 919 - if (!xfs_is_always_cow_inode(ip)) { 920 - error = xfs_alloc_file_space(ip, offset, len, 921 - XFS_BMAPI_PREALLOC); 922 - } 923 905 } else { 924 906 /* 925 907 * If always_cow mode we can't use preallocations and ··· 943 897 error = -EOPNOTSUPP; 944 898 goto out_unlock; 945 899 } 900 + } 946 901 902 + if (!xfs_is_always_cow_inode(ip)) { 947 903 error = xfs_alloc_file_space(ip, offset, len, 948 904 XFS_BMAPI_PREALLOC); 905 + if (error) 906 + goto out_unlock; 949 907 } 950 - if (error) 951 - goto out_unlock; 952 908 } 953 909 954 910 if (file->f_flags & O_DSYNC) ··· 1104 1056 */ 1105 1057 mode = xfs_ilock_data_map_shared(ip); 1106 1058 if (ip->i_d.di_nextents > 0) 1107 - error = xfs_dir3_data_readahead(ip, 0, -1); 1059 + error = xfs_dir3_data_readahead(ip, 0, 0); 1108 1060 xfs_iunlock(ip, mode); 1109 1061 return error; 1110 1062 } ··· 1201 1153 if (IS_DAX(inode)) { 1202 1154 pfn_t pfn; 1203 1155 1204 - ret = dax_iomap_fault(vmf, pe_size, &pfn, NULL, &xfs_iomap_ops); 1156 + ret = dax_iomap_fault(vmf, pe_size, &pfn, NULL, 1157 + (write_fault && !vmf->cow_page) ? 1158 + &xfs_direct_write_iomap_ops : 1159 + &xfs_read_iomap_ops); 1205 1160 if (ret & VM_FAULT_NEEDDSYNC) 1206 1161 ret = dax_finish_sync_fault(vmf, pe_size, pfn); 1207 1162 } else { 1208 1163 if (write_fault) 1209 - ret = iomap_page_mkwrite(vmf, &xfs_iomap_ops); 1164 + ret = iomap_page_mkwrite(vmf, 1165 + &xfs_buffered_write_iomap_ops); 1210 1166 else 1211 1167 ret = filemap_fault(vmf); 1212 1168 } ··· 1274 1222 1275 1223 STATIC int 1276 1224 xfs_file_mmap( 1277 - struct file *filp, 1278 - struct vm_area_struct *vma) 1225 + struct file *file, 1226 + struct vm_area_struct *vma) 1279 1227 { 1280 - struct dax_device *dax_dev; 1228 + struct inode *inode = file_inode(file); 1229 + struct xfs_buftarg *target = xfs_inode_buftarg(XFS_I(inode)); 1281 1230 1282 - dax_dev = xfs_find_daxdev_for_inode(file_inode(filp)); 1283 1231 /* 1284 1232 * We don't support synchronous mappings for non-DAX files and 1285 1233 * for DAX files if underneath dax_device is not synchronous. 1286 1234 */ 1287 - if (!daxdev_mapping_supported(vma, dax_dev)) 1235 + if (!daxdev_mapping_supported(vma, target->bt_daxdev)) 1288 1236 return -EOPNOTSUPP; 1289 1237 1290 - file_accessed(filp); 1238 + file_accessed(file); 1291 1239 vma->vm_ops = &xfs_file_vm_ops; 1292 - if (IS_DAX(file_inode(filp))) 1240 + if (IS_DAX(inode)) 1293 1241 vma->vm_flags |= VM_HUGEPAGE; 1294 1242 return 0; 1295 1243 }
+2 -1
fs/xfs/xfs_filestream.c
··· 18 18 #include "xfs_trace.h" 19 19 #include "xfs_ag_resv.h" 20 20 #include "xfs_trans.h" 21 + #include "xfs_filestream.h" 21 22 22 23 struct xfs_fstrm_item { 23 24 struct xfs_mru_cache_elem mru; ··· 375 374 startag = (item->ag + 1) % mp->m_sb.sb_agcount; 376 375 } 377 376 378 - if (xfs_alloc_is_userdata(ap->datatype)) 377 + if (ap->datatype & XFS_ALLOC_USERDATA) 379 378 flags |= XFS_PICK_USERDATA; 380 379 if (ap->tp->t_flags & XFS_TRANS_LOWMODE) 381 380 flags |= XFS_PICK_LOWSPACE;
+1
fs/xfs/xfs_fsmap.c
··· 146 146 dest->fmr_owner = XFS_FMR_OWN_FREE; 147 147 break; 148 148 default: 149 + ASSERT(0); 149 150 return -EFSCORRUPTED; 150 151 } 151 152 return 0;
+4 -4
fs/xfs/xfs_icache.c
··· 44 44 if (!ip) 45 45 return NULL; 46 46 if (inode_init_always(mp->m_super, VFS_I(ip))) { 47 - kmem_zone_free(xfs_inode_zone, ip); 47 + kmem_cache_free(xfs_inode_zone, ip); 48 48 return NULL; 49 49 } 50 50 ··· 104 104 ip->i_itemp = NULL; 105 105 } 106 106 107 - kmem_zone_free(xfs_inode_zone, ip); 107 + kmem_cache_free(xfs_inode_zone, ip); 108 108 } 109 109 110 110 static void ··· 1419 1419 return 0; 1420 1420 1421 1421 if ((eofb->eof_flags & XFS_EOF_FLAGS_PRID) && 1422 - xfs_get_projid(ip) != eofb->eof_prid) 1422 + ip->i_d.di_projid != eofb->eof_prid) 1423 1423 return 0; 1424 1424 1425 1425 return 1; ··· 1443 1443 return 1; 1444 1444 1445 1445 if ((eofb->eof_flags & XFS_EOF_FLAGS_PRID) && 1446 - xfs_get_projid(ip) == eofb->eof_prid) 1446 + ip->i_d.di_projid == eofb->eof_prid) 1447 1447 return 1; 1448 1448 1449 1449 return 0;
+1 -1
fs/xfs/xfs_icreate_item.c
··· 55 55 xfs_icreate_item_release( 56 56 struct xfs_log_item *lip) 57 57 { 58 - kmem_zone_free(xfs_icreate_zone, ICR_ITEM(lip)); 58 + kmem_cache_free(xfs_icreate_zone, ICR_ITEM(lip)); 59 59 } 60 60 61 61 static const struct xfs_item_ops xfs_icreate_item_ops = {
+39 -9
fs/xfs/xfs_inode.c
··· 55 55 xfs_get_extsz_hint( 56 56 struct xfs_inode *ip) 57 57 { 58 + /* 59 + * No point in aligning allocations if we need to COW to actually 60 + * write to them. 61 + */ 62 + if (xfs_is_always_cow_inode(ip)) 63 + return 0; 58 64 if ((ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) && ip->i_d.di_extsize) 59 65 return ip->i_d.di_extsize; 60 66 if (XFS_IS_REALTIME_INODE(ip)) ··· 815 809 ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); 816 810 ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); 817 811 inode->i_rdev = rdev; 818 - xfs_set_projid(ip, prid); 812 + ip->i_d.di_projid = prid; 819 813 820 814 if (pip && XFS_INHERIT_GID(pip)) { 821 815 ip->i_d.di_gid = pip->i_d.di_gid; ··· 851 845 inode_set_iversion(inode, 1); 852 846 ip->i_d.di_flags2 = 0; 853 847 ip->i_d.di_cowextsize = 0; 854 - ip->i_d.di_crtime.t_sec = (int32_t)tv.tv_sec; 855 - ip->i_d.di_crtime.t_nsec = (int32_t)tv.tv_nsec; 848 + ip->i_d.di_crtime = tv; 856 849 } 857 850 858 851 ··· 1423 1418 * the tree quota mechanism could be circumvented. 1424 1419 */ 1425 1420 if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && 1426 - (xfs_get_projid(tdp) != xfs_get_projid(sip)))) { 1421 + tdp->i_d.di_projid != sip->i_d.di_projid)) { 1427 1422 error = -EXDEV; 1428 1423 goto error_return; 1429 1424 } ··· 2135 2130 * passed in because either we're adding or removing ourselves from the 2136 2131 * head of the list. 2137 2132 */ 2138 - if (old_value == new_agino) 2133 + if (old_value == new_agino) { 2134 + xfs_buf_corruption_error(agibp); 2139 2135 return -EFSCORRUPTED; 2136 + } 2140 2137 2141 2138 agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino); 2142 2139 offset = offsetof(struct xfs_agi, agi_unlinked) + ··· 2201 2194 /* Make sure the old pointer isn't garbage. */ 2202 2195 old_value = be32_to_cpu(dip->di_next_unlinked); 2203 2196 if (!xfs_verify_agino_or_null(mp, agno, old_value)) { 2197 + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, 2198 + sizeof(*dip), __this_address); 2204 2199 error = -EFSCORRUPTED; 2205 2200 goto out; 2206 2201 } ··· 2214 2205 */ 2215 2206 *old_next_agino = old_value; 2216 2207 if (old_value == next_agino) { 2217 - if (next_agino != NULLAGINO) 2208 + if (next_agino != NULLAGINO) { 2209 + xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, 2210 + dip, sizeof(*dip), __this_address); 2218 2211 error = -EFSCORRUPTED; 2212 + } 2219 2213 goto out; 2220 2214 } 2221 2215 ··· 2269 2257 */ 2270 2258 next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); 2271 2259 if (next_agino == agino || 2272 - !xfs_verify_agino_or_null(mp, agno, next_agino)) 2260 + !xfs_verify_agino_or_null(mp, agno, next_agino)) { 2261 + xfs_buf_corruption_error(agibp); 2273 2262 return -EFSCORRUPTED; 2263 + } 2274 2264 2275 2265 if (next_agino != NULLAGINO) { 2276 2266 struct xfs_perag *pag; ··· 3210 3196 struct xfs_trans *tp; 3211 3197 struct xfs_inode *wip = NULL; /* whiteout inode */ 3212 3198 struct xfs_inode *inodes[__XFS_SORT_INODES]; 3199 + struct xfs_buf *agibp; 3213 3200 int num_inodes = __XFS_SORT_INODES; 3214 3201 bool new_parent = (src_dp != target_dp); 3215 3202 bool src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode); ··· 3285 3270 * tree quota mechanism would be circumvented. 3286 3271 */ 3287 3272 if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && 3288 - (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) { 3273 + target_dp->i_d.di_projid != src_ip->i_d.di_projid)) { 3289 3274 error = -EXDEV; 3290 3275 goto out_trans_cancel; 3291 3276 } ··· 3342 3327 goto out_trans_cancel; 3343 3328 3344 3329 xfs_bumplink(tp, wip); 3345 - xfs_trans_log_inode(tp, wip, XFS_ILOG_CORE); 3346 3330 VFS_I(wip)->i_state &= ~I_LINKABLE; 3347 3331 } 3348 3332 ··· 3375 3361 * In case there is already an entry with the same 3376 3362 * name at the destination directory, remove it first. 3377 3363 */ 3364 + 3365 + /* 3366 + * Check whether the replace operation will need to allocate 3367 + * blocks. This happens when the shortform directory lacks 3368 + * space and we have to convert it to a block format directory. 3369 + * When more blocks are necessary, we must lock the AGI first 3370 + * to preserve locking order (AGI -> AGF). 3371 + */ 3372 + if (xfs_dir2_sf_replace_needblock(target_dp, src_ip->i_ino)) { 3373 + error = xfs_read_agi(mp, tp, 3374 + XFS_INO_TO_AGNO(mp, target_ip->i_ino), 3375 + &agibp); 3376 + if (error) 3377 + goto out_trans_cancel; 3378 + } 3379 + 3378 3380 error = xfs_dir_replace(tp, target_dp, target_name, 3379 3381 src_ip->i_ino, spaceres); 3380 3382 if (error)
+8 -23
fs/xfs/xfs_inode.h
··· 37 37 struct xfs_ifork *i_cowfp; /* copy on write extents */ 38 38 struct xfs_ifork i_df; /* data fork */ 39 39 40 - /* operations vectors */ 41 - const struct xfs_dir_ops *d_ops; /* directory ops vector */ 42 - 43 40 /* Transaction and locking information. */ 44 41 struct xfs_inode_log_item *i_itemp; /* logging information */ 45 42 mrlock_t i_lock; /* inode lock */ ··· 174 177 return ret; 175 178 } 176 179 177 - /* 178 - * Project quota id helpers (previously projid was 16bit only 179 - * and using two 16bit values to hold new 32bit projid was chosen 180 - * to retain compatibility with "old" filesystems). 181 - */ 182 - static inline prid_t 183 - xfs_get_projid(struct xfs_inode *ip) 184 - { 185 - return (prid_t)ip->i_d.di_projid_hi << 16 | ip->i_d.di_projid_lo; 186 - } 187 - 188 - static inline void 189 - xfs_set_projid(struct xfs_inode *ip, 190 - prid_t projid) 191 - { 192 - ip->i_d.di_projid_hi = (uint16_t) (projid >> 16); 193 - ip->i_d.di_projid_lo = (uint16_t) (projid & 0xffff); 194 - } 195 - 196 180 static inline prid_t 197 181 xfs_get_initial_prid(struct xfs_inode *dp) 198 182 { 199 183 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 200 - return xfs_get_projid(dp); 184 + return dp->i_d.di_projid; 201 185 202 186 return XFS_PROJID_DEFAULT; 203 187 } ··· 196 218 { 197 219 return ip->i_cowfp && ip->i_cowfp->if_bytes; 198 220 } 221 + 222 + /* 223 + * Return the buftarg used for data allocations on a given inode. 224 + */ 225 + #define xfs_inode_buftarg(ip) \ 226 + (XFS_IS_REALTIME_INODE(ip) ? \ 227 + (ip)->i_mount->m_rtdev_targp : (ip)->i_mount->m_ddev_targp) 199 228 200 229 /* 201 230 * In-core inode flags.
+9 -6
fs/xfs/xfs_inode_item.c
··· 17 17 #include "xfs_trans_priv.h" 18 18 #include "xfs_buf_item.h" 19 19 #include "xfs_log.h" 20 + #include "xfs_error.h" 20 21 21 22 #include <linux/iversion.h> 22 23 ··· 310 309 to->di_format = from->di_format; 311 310 to->di_uid = from->di_uid; 312 311 to->di_gid = from->di_gid; 313 - to->di_projid_lo = from->di_projid_lo; 314 - to->di_projid_hi = from->di_projid_hi; 312 + to->di_projid_lo = from->di_projid & 0xffff; 313 + to->di_projid_hi = from->di_projid >> 16; 315 314 316 315 memset(to->di_pad, 0, sizeof(to->di_pad)); 317 316 memset(to->di_pad3, 0, sizeof(to->di_pad3)); ··· 341 340 342 341 if (from->di_version == 3) { 343 342 to->di_changecount = inode_peek_iversion(inode); 344 - to->di_crtime.t_sec = from->di_crtime.t_sec; 345 - to->di_crtime.t_nsec = from->di_crtime.t_nsec; 343 + to->di_crtime.t_sec = from->di_crtime.tv_sec; 344 + to->di_crtime.t_nsec = from->di_crtime.tv_nsec; 346 345 to->di_flags2 = from->di_flags2; 347 346 to->di_cowextsize = from->di_cowextsize; 348 347 to->di_ino = ip->i_ino; ··· 667 666 xfs_inode_t *ip) 668 667 { 669 668 kmem_free(ip->i_itemp->ili_item.li_lv_shadow); 670 - kmem_zone_free(xfs_ili_zone, ip->i_itemp); 669 + kmem_cache_free(xfs_ili_zone, ip->i_itemp); 671 670 } 672 671 673 672 ··· 829 828 { 830 829 struct xfs_inode_log_format_32 *in_f32 = buf->i_addr; 831 830 832 - if (buf->i_len != sizeof(*in_f32)) 831 + if (buf->i_len != sizeof(*in_f32)) { 832 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); 833 833 return -EFSCORRUPTED; 834 + } 834 835 835 836 in_f->ilf_type = in_f32->ilf_type; 836 837 in_f->ilf_size = in_f32->ilf_size;
+27 -176
fs/xfs/xfs_ioctl.c
··· 33 33 #include "xfs_sb.h" 34 34 #include "xfs_ag.h" 35 35 #include "xfs_health.h" 36 + #include "xfs_reflink.h" 37 + #include "xfs_ioctl.h" 36 38 37 39 #include <linux/mount.h> 38 40 #include <linux/namei.h> ··· 292 290 return error; 293 291 } 294 292 295 - int 296 - xfs_set_dmattrs( 297 - xfs_inode_t *ip, 298 - uint evmask, 299 - uint16_t state) 300 - { 301 - xfs_mount_t *mp = ip->i_mount; 302 - xfs_trans_t *tp; 303 - int error; 304 - 305 - if (!capable(CAP_SYS_ADMIN)) 306 - return -EPERM; 307 - 308 - if (XFS_FORCED_SHUTDOWN(mp)) 309 - return -EIO; 310 - 311 - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp); 312 - if (error) 313 - return error; 314 - 315 - xfs_ilock(ip, XFS_ILOCK_EXCL); 316 - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 317 - 318 - ip->i_d.di_dmevmask = evmask; 319 - ip->i_d.di_dmstate = state; 320 - 321 - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 322 - error = xfs_trans_commit(tp); 323 - 324 - return error; 325 - } 326 - 327 - STATIC int 328 - xfs_fssetdm_by_handle( 329 - struct file *parfilp, 330 - void __user *arg) 331 - { 332 - int error; 333 - struct fsdmidata fsd; 334 - xfs_fsop_setdm_handlereq_t dmhreq; 335 - struct dentry *dentry; 336 - 337 - if (!capable(CAP_MKNOD)) 338 - return -EPERM; 339 - if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) 340 - return -EFAULT; 341 - 342 - error = mnt_want_write_file(parfilp); 343 - if (error) 344 - return error; 345 - 346 - dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq); 347 - if (IS_ERR(dentry)) { 348 - mnt_drop_write_file(parfilp); 349 - return PTR_ERR(dentry); 350 - } 351 - 352 - if (IS_IMMUTABLE(d_inode(dentry)) || IS_APPEND(d_inode(dentry))) { 353 - error = -EPERM; 354 - goto out; 355 - } 356 - 357 - if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) { 358 - error = -EFAULT; 359 - goto out; 360 - } 361 - 362 - error = xfs_set_dmattrs(XFS_I(d_inode(dentry)), fsd.fsd_dmevmask, 363 - fsd.fsd_dmstate); 364 - 365 - out: 366 - mnt_drop_write_file(parfilp); 367 - dput(dentry); 368 - return error; 369 - } 370 - 371 293 STATIC int 372 294 xfs_attrlist_by_handle( 373 295 struct file *parfilp, ··· 514 588 int 515 589 xfs_ioc_space( 516 590 struct file *filp, 517 - unsigned int cmd, 518 591 xfs_flock64_t *bf) 519 592 { 520 593 struct inode *inode = file_inode(filp); 521 594 struct xfs_inode *ip = XFS_I(inode); 522 595 struct iattr iattr; 523 - enum xfs_prealloc_flags flags = 0; 596 + enum xfs_prealloc_flags flags = XFS_PREALLOC_CLEAR; 524 597 uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; 525 598 int error; 526 599 ··· 531 606 532 607 if (!S_ISREG(inode->i_mode)) 533 608 return -EINVAL; 609 + 610 + if (xfs_is_always_cow_inode(ip)) 611 + return -EOPNOTSUPP; 534 612 535 613 if (filp->f_flags & O_DSYNC) 536 614 flags |= XFS_PREALLOC_SYNC; ··· 548 620 error = xfs_break_layouts(inode, &iolock, BREAK_UNMAP); 549 621 if (error) 550 622 goto out_unlock; 623 + inode_dio_wait(inode); 551 624 552 625 switch (bf->l_whence) { 553 626 case 0: /*SEEK_SET*/ ··· 564 635 goto out_unlock; 565 636 } 566 637 567 - /* 568 - * length of <= 0 for resv/unresv/zero is invalid. length for 569 - * alloc/free is ignored completely and we have no idea what userspace 570 - * might have set it to, so set it to zero to allow range 571 - * checks to pass. 572 - */ 573 - switch (cmd) { 574 - case XFS_IOC_ZERO_RANGE: 575 - case XFS_IOC_RESVSP: 576 - case XFS_IOC_RESVSP64: 577 - case XFS_IOC_UNRESVSP: 578 - case XFS_IOC_UNRESVSP64: 579 - if (bf->l_len <= 0) { 580 - error = -EINVAL; 581 - goto out_unlock; 582 - } 583 - break; 584 - default: 585 - bf->l_len = 0; 586 - break; 587 - } 588 - 589 - if (bf->l_start < 0 || 590 - bf->l_start > inode->i_sb->s_maxbytes || 591 - bf->l_start + bf->l_len < 0 || 592 - bf->l_start + bf->l_len >= inode->i_sb->s_maxbytes) { 638 + if (bf->l_start < 0 || bf->l_start > inode->i_sb->s_maxbytes) { 593 639 error = -EINVAL; 594 640 goto out_unlock; 595 641 } 596 642 597 - switch (cmd) { 598 - case XFS_IOC_ZERO_RANGE: 599 - flags |= XFS_PREALLOC_SET; 600 - error = xfs_zero_file_space(ip, bf->l_start, bf->l_len); 601 - break; 602 - case XFS_IOC_RESVSP: 603 - case XFS_IOC_RESVSP64: 604 - flags |= XFS_PREALLOC_SET; 605 - error = xfs_alloc_file_space(ip, bf->l_start, bf->l_len, 606 - XFS_BMAPI_PREALLOC); 607 - break; 608 - case XFS_IOC_UNRESVSP: 609 - case XFS_IOC_UNRESVSP64: 610 - error = xfs_free_file_space(ip, bf->l_start, bf->l_len); 611 - break; 612 - case XFS_IOC_ALLOCSP: 613 - case XFS_IOC_ALLOCSP64: 614 - case XFS_IOC_FREESP: 615 - case XFS_IOC_FREESP64: 616 - flags |= XFS_PREALLOC_CLEAR; 617 - if (bf->l_start > XFS_ISIZE(ip)) { 618 - error = xfs_alloc_file_space(ip, XFS_ISIZE(ip), 619 - bf->l_start - XFS_ISIZE(ip), 0); 620 - if (error) 621 - goto out_unlock; 622 - } 623 - 624 - iattr.ia_valid = ATTR_SIZE; 625 - iattr.ia_size = bf->l_start; 626 - 627 - error = xfs_vn_setattr_size(file_dentry(filp), &iattr); 628 - break; 629 - default: 630 - ASSERT(0); 631 - error = -EINVAL; 643 + if (bf->l_start > XFS_ISIZE(ip)) { 644 + error = xfs_alloc_file_space(ip, XFS_ISIZE(ip), 645 + bf->l_start - XFS_ISIZE(ip), 0); 646 + if (error) 647 + goto out_unlock; 632 648 } 633 649 650 + iattr.ia_valid = ATTR_SIZE; 651 + iattr.ia_size = bf->l_start; 652 + error = xfs_vn_setattr_size(file_dentry(filp), &iattr); 634 653 if (error) 635 654 goto out_unlock; 636 655 ··· 993 1116 fa->fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; 994 1117 fa->fsx_cowextsize = ip->i_d.di_cowextsize << 995 1118 ip->i_mount->m_sb.sb_blocklog; 996 - fa->fsx_projid = xfs_get_projid(ip); 1119 + fa->fsx_projid = ip->i_d.di_projid; 997 1120 998 1121 if (attr) { 999 1122 if (ip->i_afp) { ··· 1188 1311 * have to check the device for dax support or flush pagecache. 1189 1312 */ 1190 1313 if (fa->fsx_xflags & FS_XFLAG_DAX) { 1191 - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) 1192 - return -EINVAL; 1193 - if (!bdev_dax_supported(xfs_find_bdev_for_inode(VFS_I(ip)), 1194 - sb->s_blocksize)) 1314 + struct xfs_buftarg *target = xfs_inode_buftarg(ip); 1315 + 1316 + if (!bdev_dax_supported(target->bt_bdev, sb->s_blocksize)) 1195 1317 return -EINVAL; 1196 1318 } 1197 1319 ··· 1445 1569 } 1446 1570 1447 1571 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp) && 1448 - xfs_get_projid(ip) != fa->fsx_projid) { 1572 + ip->i_d.di_projid != fa->fsx_projid) { 1449 1573 code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL, pdqp, 1450 1574 capable(CAP_FOWNER) ? XFS_QMOPT_FORCE_RES : 0); 1451 1575 if (code) /* out of quota */ ··· 1482 1606 VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID); 1483 1607 1484 1608 /* Change the ownerships and register project quota modifications */ 1485 - if (xfs_get_projid(ip) != fa->fsx_projid) { 1609 + if (ip->i_d.di_projid != fa->fsx_projid) { 1486 1610 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) { 1487 1611 olddquot = xfs_qm_vop_chown(tp, ip, 1488 1612 &ip->i_pdquot, pdqp); 1489 1613 } 1490 1614 ASSERT(ip->i_d.di_version > 1); 1491 - xfs_set_projid(ip, fa->fsx_projid); 1615 + ip->i_d.di_projid = fa->fsx_projid; 1492 1616 } 1493 1617 1494 1618 /* ··· 1998 2122 return xfs_ioc_setlabel(filp, mp, arg); 1999 2123 case XFS_IOC_ALLOCSP: 2000 2124 case XFS_IOC_FREESP: 2001 - case XFS_IOC_RESVSP: 2002 - case XFS_IOC_UNRESVSP: 2003 2125 case XFS_IOC_ALLOCSP64: 2004 - case XFS_IOC_FREESP64: 2005 - case XFS_IOC_RESVSP64: 2006 - case XFS_IOC_UNRESVSP64: 2007 - case XFS_IOC_ZERO_RANGE: { 2126 + case XFS_IOC_FREESP64: { 2008 2127 xfs_flock64_t bf; 2009 2128 2010 2129 if (copy_from_user(&bf, arg, sizeof(bf))) 2011 2130 return -EFAULT; 2012 - return xfs_ioc_space(filp, cmd, &bf); 2131 + return xfs_ioc_space(filp, &bf); 2013 2132 } 2014 2133 case XFS_IOC_DIOINFO: { 2015 - struct dioattr da; 2016 - xfs_buftarg_t *target = 2017 - XFS_IS_REALTIME_INODE(ip) ? 2018 - mp->m_rtdev_targp : mp->m_ddev_targp; 2134 + struct xfs_buftarg *target = xfs_inode_buftarg(ip); 2135 + struct dioattr da; 2019 2136 2020 2137 da.d_mem = da.d_miniosz = target->bt_logical_sectorsize; 2021 2138 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); ··· 2052 2183 case XFS_IOC_SETXFLAGS: 2053 2184 return xfs_ioc_setxflags(ip, filp, arg); 2054 2185 2055 - case XFS_IOC_FSSETDM: { 2056 - struct fsdmidata dmi; 2057 - 2058 - if (copy_from_user(&dmi, arg, sizeof(dmi))) 2059 - return -EFAULT; 2060 - 2061 - error = mnt_want_write_file(filp); 2062 - if (error) 2063 - return error; 2064 - 2065 - error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask, 2066 - dmi.fsd_dmstate); 2067 - mnt_drop_write_file(filp); 2068 - return error; 2069 - } 2070 - 2071 2186 case XFS_IOC_GETBMAP: 2072 2187 case XFS_IOC_GETBMAPA: 2073 2188 case XFS_IOC_GETBMAPX: ··· 2079 2226 return -EFAULT; 2080 2227 return xfs_open_by_handle(filp, &hreq); 2081 2228 } 2082 - case XFS_IOC_FSSETDM_BY_HANDLE: 2083 - return xfs_fssetdm_by_handle(filp, arg); 2084 2229 2085 2230 case XFS_IOC_READLINK_BY_HANDLE: { 2086 2231 xfs_fsop_handlereq_t hreq;
-7
fs/xfs/xfs_ioctl.h
··· 9 9 extern int 10 10 xfs_ioc_space( 11 11 struct file *filp, 12 - unsigned int cmd, 13 12 xfs_flock64_t *bf); 14 13 15 14 int ··· 69 70 struct file *file, 70 71 unsigned int cmd, 71 72 unsigned long arg); 72 - 73 - extern int 74 - xfs_set_dmattrs( 75 - struct xfs_inode *ip, 76 - uint evmask, 77 - uint16_t state); 78 73 79 74 struct xfs_ibulk; 80 75 struct xfs_bstat;
+2 -47
fs/xfs/xfs_ioctl32.c
··· 500 500 return error; 501 501 } 502 502 503 - STATIC int 504 - xfs_compat_fssetdm_by_handle( 505 - struct file *parfilp, 506 - void __user *arg) 507 - { 508 - int error; 509 - struct fsdmidata fsd; 510 - compat_xfs_fsop_setdm_handlereq_t dmhreq; 511 - struct dentry *dentry; 512 - 513 - if (!capable(CAP_MKNOD)) 514 - return -EPERM; 515 - if (copy_from_user(&dmhreq, arg, 516 - sizeof(compat_xfs_fsop_setdm_handlereq_t))) 517 - return -EFAULT; 518 - 519 - dentry = xfs_compat_handlereq_to_dentry(parfilp, &dmhreq.hreq); 520 - if (IS_ERR(dentry)) 521 - return PTR_ERR(dentry); 522 - 523 - if (IS_IMMUTABLE(d_inode(dentry)) || IS_APPEND(d_inode(dentry))) { 524 - error = -EPERM; 525 - goto out; 526 - } 527 - 528 - if (copy_from_user(&fsd, compat_ptr(dmhreq.data), sizeof(fsd))) { 529 - error = -EFAULT; 530 - goto out; 531 - } 532 - 533 - error = xfs_set_dmattrs(XFS_I(d_inode(dentry)), fsd.fsd_dmevmask, 534 - fsd.fsd_dmstate); 535 - 536 - out: 537 - dput(dentry); 538 - return error; 539 - } 540 - 541 503 long 542 504 xfs_file_compat_ioctl( 543 505 struct file *filp, ··· 519 557 case XFS_IOC_ALLOCSP_32: 520 558 case XFS_IOC_FREESP_32: 521 559 case XFS_IOC_ALLOCSP64_32: 522 - case XFS_IOC_FREESP64_32: 523 - case XFS_IOC_RESVSP_32: 524 - case XFS_IOC_UNRESVSP_32: 525 - case XFS_IOC_RESVSP64_32: 526 - case XFS_IOC_UNRESVSP64_32: 527 - case XFS_IOC_ZERO_RANGE_32: { 560 + case XFS_IOC_FREESP64_32: { 528 561 struct xfs_flock64 bf; 529 562 530 563 if (xfs_compat_flock64_copyin(&bf, arg)) 531 564 return -EFAULT; 532 565 cmd = _NATIVE_IOC(cmd, struct xfs_flock64); 533 - return xfs_ioc_space(filp, cmd, &bf); 566 + return xfs_ioc_space(filp, &bf); 534 567 } 535 568 case XFS_IOC_FSGEOMETRY_V1_32: 536 569 return xfs_compat_ioc_fsgeometry_v1(mp, arg); ··· 608 651 return xfs_compat_attrlist_by_handle(filp, arg); 609 652 case XFS_IOC_ATTRMULTI_BY_HANDLE_32: 610 653 return xfs_compat_attrmulti_by_handle(filp, arg); 611 - case XFS_IOC_FSSETDM_BY_HANDLE_32: 612 - return xfs_compat_fssetdm_by_handle(filp, arg); 613 654 default: 614 655 /* try the native version */ 615 656 return xfs_file_ioctl(filp, cmd, (unsigned long)arg);
+2 -11
fs/xfs/xfs_ioctl32.h
··· 99 99 _IOWR('X', 108, struct compat_xfs_fsop_handlereq) 100 100 101 101 /* The bstat field in the swapext struct needs translation */ 102 - typedef struct compat_xfs_swapext { 102 + struct compat_xfs_swapext { 103 103 int64_t sx_version; /* version */ 104 104 int64_t sx_fdtarget; /* fd of target file */ 105 105 int64_t sx_fdtmp; /* fd of tmp file */ ··· 107 107 xfs_off_t sx_length; /* leng from offset */ 108 108 char sx_pad[16]; /* pad space, unused */ 109 109 struct compat_xfs_bstat sx_stat; /* stat of target b4 copy */ 110 - } __compat_packed compat_xfs_swapext_t; 110 + } __compat_packed; 111 111 112 112 #define XFS_IOC_SWAPEXT_32 _IOWR('X', 109, struct compat_xfs_swapext) 113 113 ··· 142 142 143 143 #define XFS_IOC_ATTRMULTI_BY_HANDLE_32 \ 144 144 _IOW('X', 123, struct compat_xfs_fsop_attrmulti_handlereq) 145 - 146 - typedef struct compat_xfs_fsop_setdm_handlereq { 147 - struct compat_xfs_fsop_handlereq hreq; /* handle information */ 148 - /* ptr to struct fsdmidata */ 149 - compat_uptr_t data; /* DMAPI data */ 150 - } compat_xfs_fsop_setdm_handlereq_t; 151 - 152 - #define XFS_IOC_FSSETDM_BY_HANDLE_32 \ 153 - _IOW('X', 121, struct compat_xfs_fsop_setdm_handlereq) 154 145 155 146 #ifdef BROKEN_X86_ALIGNMENT 156 147 /* on ia32 l_start is on a 32-bit boundary */
+426 -434
fs/xfs/xfs_iomap.c
··· 29 29 #include "xfs_reflink.h" 30 30 31 31 32 - #define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \ 33 - << mp->m_writeio_log) 32 + #define XFS_ALLOC_ALIGN(mp, off) \ 33 + (((off) >> mp->m_allocsize_log) << mp->m_allocsize_log) 34 34 35 35 static int 36 36 xfs_alert_fsblock_zero( ··· 57 57 u16 flags) 58 58 { 59 59 struct xfs_mount *mp = ip->i_mount; 60 + struct xfs_buftarg *target = xfs_inode_buftarg(ip); 60 61 61 62 if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) 62 63 return xfs_alert_fsblock_zero(ip, imap); ··· 78 77 } 79 78 iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff); 80 79 iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount); 81 - iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip)); 82 - iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip)); 80 + iomap->bdev = target->bt_bdev; 81 + iomap->dax_dev = target->bt_daxdev; 83 82 iomap->flags = flags; 84 83 85 84 if (xfs_ipincount(ip) && ··· 95 94 xfs_fileoff_t offset_fsb, 96 95 xfs_fileoff_t end_fsb) 97 96 { 97 + struct xfs_buftarg *target = xfs_inode_buftarg(ip); 98 + 98 99 iomap->addr = IOMAP_NULL_ADDR; 99 100 iomap->type = IOMAP_HOLE; 100 101 iomap->offset = XFS_FSB_TO_B(ip->i_mount, offset_fsb); 101 102 iomap->length = XFS_FSB_TO_B(ip->i_mount, end_fsb - offset_fsb); 102 - iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip)); 103 - iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip)); 103 + iomap->bdev = target->bt_bdev; 104 + iomap->dax_dev = target->bt_daxdev; 104 105 } 105 106 106 - xfs_extlen_t 107 + static inline xfs_fileoff_t 108 + xfs_iomap_end_fsb( 109 + struct xfs_mount *mp, 110 + loff_t offset, 111 + loff_t count) 112 + { 113 + ASSERT(offset <= mp->m_super->s_maxbytes); 114 + return min(XFS_B_TO_FSB(mp, offset + count), 115 + XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes)); 116 + } 117 + 118 + static xfs_extlen_t 107 119 xfs_eof_alignment( 108 - struct xfs_inode *ip, 109 - xfs_extlen_t extsize) 120 + struct xfs_inode *ip) 110 121 { 111 122 struct xfs_mount *mp = ip->i_mount; 112 123 xfs_extlen_t align = 0; ··· 141 128 align = 0; 142 129 } 143 130 144 - /* 145 - * Always round up the allocation request to an extent boundary 146 - * (when file on a real-time subvolume or has di_extsize hint). 147 - */ 148 - if (extsize) { 149 - if (align) 150 - align = roundup_64(align, extsize); 151 - else 152 - align = extsize; 153 - } 154 - 155 131 return align; 156 132 } 157 133 158 - STATIC int 134 + /* 135 + * Check if last_fsb is outside the last extent, and if so grow it to the next 136 + * stripe unit boundary. 137 + */ 138 + xfs_fileoff_t 159 139 xfs_iomap_eof_align_last_fsb( 160 140 struct xfs_inode *ip, 161 - xfs_extlen_t extsize, 162 - xfs_fileoff_t *last_fsb) 141 + xfs_fileoff_t end_fsb) 163 142 { 164 - xfs_extlen_t align = xfs_eof_alignment(ip, extsize); 143 + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); 144 + xfs_extlen_t extsz = xfs_get_extsz_hint(ip); 145 + xfs_extlen_t align = xfs_eof_alignment(ip); 146 + struct xfs_bmbt_irec irec; 147 + struct xfs_iext_cursor icur; 148 + 149 + ASSERT(ifp->if_flags & XFS_IFEXTENTS); 150 + 151 + /* 152 + * Always round up the allocation request to the extent hint boundary. 153 + */ 154 + if (extsz) { 155 + if (align) 156 + align = roundup_64(align, extsz); 157 + else 158 + align = extsz; 159 + } 165 160 166 161 if (align) { 167 - xfs_fileoff_t new_last_fsb = roundup_64(*last_fsb, align); 168 - int eof, error; 162 + xfs_fileoff_t aligned_end_fsb = roundup_64(end_fsb, align); 169 163 170 - error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof); 171 - if (error) 172 - return error; 173 - if (eof) 174 - *last_fsb = new_last_fsb; 164 + xfs_iext_last(ifp, &icur); 165 + if (!xfs_iext_get_extent(ifp, &icur, &irec) || 166 + aligned_end_fsb >= irec.br_startoff + irec.br_blockcount) 167 + return aligned_end_fsb; 175 168 } 176 - return 0; 169 + 170 + return end_fsb; 177 171 } 178 172 179 173 int 180 174 xfs_iomap_write_direct( 181 - xfs_inode_t *ip, 182 - xfs_off_t offset, 183 - size_t count, 184 - xfs_bmbt_irec_t *imap, 185 - int nmaps) 175 + struct xfs_inode *ip, 176 + xfs_fileoff_t offset_fsb, 177 + xfs_fileoff_t count_fsb, 178 + struct xfs_bmbt_irec *imap) 186 179 { 187 - xfs_mount_t *mp = ip->i_mount; 188 - xfs_fileoff_t offset_fsb; 189 - xfs_fileoff_t last_fsb; 190 - xfs_filblks_t count_fsb, resaligned; 191 - xfs_extlen_t extsz; 192 - int nimaps; 193 - int quota_flag; 194 - int rt; 195 - xfs_trans_t *tp; 196 - uint qblocks, resblks, resrtextents; 197 - int error; 198 - int lockmode; 199 - int bmapi_flags = XFS_BMAPI_PREALLOC; 200 - uint tflags = 0; 180 + struct xfs_mount *mp = ip->i_mount; 181 + struct xfs_trans *tp; 182 + xfs_filblks_t resaligned; 183 + int nimaps; 184 + int quota_flag; 185 + uint qblocks, resblks; 186 + unsigned int resrtextents = 0; 187 + int error; 188 + int bmapi_flags = XFS_BMAPI_PREALLOC; 189 + uint tflags = 0; 201 190 202 - rt = XFS_IS_REALTIME_INODE(ip); 203 - extsz = xfs_get_extsz_hint(ip); 204 - lockmode = XFS_ILOCK_SHARED; /* locked by caller */ 205 - 206 - ASSERT(xfs_isilocked(ip, lockmode)); 207 - 208 - offset_fsb = XFS_B_TO_FSBT(mp, offset); 209 - last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); 210 - if ((offset + count) > XFS_ISIZE(ip)) { 211 - /* 212 - * Assert that the in-core extent list is present since this can 213 - * call xfs_iread_extents() and we only have the ilock shared. 214 - * This should be safe because the lock was held around a bmapi 215 - * call in the caller and we only need it to access the in-core 216 - * list. 217 - */ 218 - ASSERT(XFS_IFORK_PTR(ip, XFS_DATA_FORK)->if_flags & 219 - XFS_IFEXTENTS); 220 - error = xfs_iomap_eof_align_last_fsb(ip, extsz, &last_fsb); 221 - if (error) 222 - goto out_unlock; 223 - } else { 224 - if (nmaps && (imap->br_startblock == HOLESTARTBLOCK)) 225 - last_fsb = min(last_fsb, (xfs_fileoff_t) 226 - imap->br_blockcount + 227 - imap->br_startoff); 228 - } 229 - count_fsb = last_fsb - offset_fsb; 230 191 ASSERT(count_fsb > 0); 231 - resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb, extsz); 232 192 233 - if (unlikely(rt)) { 193 + resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb, 194 + xfs_get_extsz_hint(ip)); 195 + if (unlikely(XFS_IS_REALTIME_INODE(ip))) { 234 196 resrtextents = qblocks = resaligned; 235 197 resrtextents /= mp->m_sb.sb_rextsize; 236 198 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); 237 199 quota_flag = XFS_QMOPT_RES_RTBLKS; 238 200 } else { 239 - resrtextents = 0; 240 201 resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned); 241 202 quota_flag = XFS_QMOPT_RES_REGBLKS; 242 203 } 243 204 244 - /* 245 - * Drop the shared lock acquired by the caller, attach the dquot if 246 - * necessary and move on to transaction setup. 247 - */ 248 - xfs_iunlock(ip, lockmode); 249 205 error = xfs_qm_dqattach(ip); 250 206 if (error) 251 207 return error; ··· 244 262 if (error) 245 263 return error; 246 264 247 - lockmode = XFS_ILOCK_EXCL; 248 - xfs_ilock(ip, lockmode); 265 + xfs_ilock(ip, XFS_ILOCK_EXCL); 249 266 250 267 error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks, 0, quota_flag); 251 268 if (error) ··· 257 276 * caller gave to us. 258 277 */ 259 278 nimaps = 1; 260 - error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, 261 - bmapi_flags, resblks, imap, &nimaps); 279 + error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, 0, 280 + imap, &nimaps); 262 281 if (error) 263 282 goto out_res_cancel; 264 283 ··· 281 300 error = xfs_alert_fsblock_zero(ip, imap); 282 301 283 302 out_unlock: 284 - xfs_iunlock(ip, lockmode); 303 + xfs_iunlock(ip, XFS_ILOCK_EXCL); 285 304 return error; 286 305 287 306 out_res_cancel: ··· 390 409 if (offset + count <= XFS_ISIZE(ip)) 391 410 return 0; 392 411 393 - if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) && 394 - (XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_writeio_blocks))) 412 + if (!(mp->m_flags & XFS_MOUNT_ALLOCSIZE) && 413 + (XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_allocsize_blocks))) 395 414 return 0; 396 415 397 416 /* 398 417 * If an explicit allocsize is set, the file is small, or we 399 418 * are writing behind a hole, then use the minimum prealloc: 400 419 */ 401 - if ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) || 420 + if ((mp->m_flags & XFS_MOUNT_ALLOCSIZE) || 402 421 XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, mp->m_dalign) || 403 422 !xfs_iext_peek_prev_extent(ifp, icur, &prev) || 404 423 prev.br_startoff + prev.br_blockcount < offset_fsb) 405 - return mp->m_writeio_blocks; 424 + return mp->m_allocsize_blocks; 406 425 407 426 /* 408 427 * Determine the initial size of the preallocation. We are beyond the ··· 495 514 while (alloc_blocks && alloc_blocks >= freesp) 496 515 alloc_blocks >>= 4; 497 516 check_writeio: 498 - if (alloc_blocks < mp->m_writeio_blocks) 499 - alloc_blocks = mp->m_writeio_blocks; 517 + if (alloc_blocks < mp->m_allocsize_blocks) 518 + alloc_blocks = mp->m_allocsize_blocks; 500 519 trace_xfs_iomap_prealloc_size(ip, alloc_blocks, shift, 501 - mp->m_writeio_blocks); 520 + mp->m_allocsize_blocks); 502 521 return alloc_blocks; 503 - } 504 - 505 - static int 506 - xfs_file_iomap_begin_delay( 507 - struct inode *inode, 508 - loff_t offset, 509 - loff_t count, 510 - unsigned flags, 511 - struct iomap *iomap) 512 - { 513 - struct xfs_inode *ip = XFS_I(inode); 514 - struct xfs_mount *mp = ip->i_mount; 515 - xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); 516 - xfs_fileoff_t maxbytes_fsb = 517 - XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); 518 - xfs_fileoff_t end_fsb; 519 - struct xfs_bmbt_irec imap, cmap; 520 - struct xfs_iext_cursor icur, ccur; 521 - xfs_fsblock_t prealloc_blocks = 0; 522 - bool eof = false, cow_eof = false, shared = false; 523 - u16 iomap_flags = 0; 524 - int whichfork = XFS_DATA_FORK; 525 - int error = 0; 526 - 527 - ASSERT(!XFS_IS_REALTIME_INODE(ip)); 528 - ASSERT(!xfs_get_extsz_hint(ip)); 529 - 530 - xfs_ilock(ip, XFS_ILOCK_EXCL); 531 - 532 - if (unlikely(XFS_TEST_ERROR( 533 - (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS && 534 - XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE), 535 - mp, XFS_ERRTAG_BMAPIFORMAT))) { 536 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 537 - error = -EFSCORRUPTED; 538 - goto out_unlock; 539 - } 540 - 541 - XFS_STATS_INC(mp, xs_blk_mapw); 542 - 543 - if (!(ip->i_df.if_flags & XFS_IFEXTENTS)) { 544 - error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); 545 - if (error) 546 - goto out_unlock; 547 - } 548 - 549 - end_fsb = min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb); 550 - 551 - /* 552 - * Search the data fork fork first to look up our source mapping. We 553 - * always need the data fork map, as we have to return it to the 554 - * iomap code so that the higher level write code can read data in to 555 - * perform read-modify-write cycles for unaligned writes. 556 - */ 557 - eof = !xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &icur, &imap); 558 - if (eof) 559 - imap.br_startoff = end_fsb; /* fake hole until the end */ 560 - 561 - /* We never need to allocate blocks for zeroing a hole. */ 562 - if ((flags & IOMAP_ZERO) && imap.br_startoff > offset_fsb) { 563 - xfs_hole_to_iomap(ip, iomap, offset_fsb, imap.br_startoff); 564 - goto out_unlock; 565 - } 566 - 567 - /* 568 - * Search the COW fork extent list even if we did not find a data fork 569 - * extent. This serves two purposes: first this implements the 570 - * speculative preallocation using cowextsize, so that we also unshare 571 - * block adjacent to shared blocks instead of just the shared blocks 572 - * themselves. Second the lookup in the extent list is generally faster 573 - * than going out to the shared extent tree. 574 - */ 575 - if (xfs_is_cow_inode(ip)) { 576 - if (!ip->i_cowfp) { 577 - ASSERT(!xfs_is_reflink_inode(ip)); 578 - xfs_ifork_init_cow(ip); 579 - } 580 - cow_eof = !xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, 581 - &ccur, &cmap); 582 - if (!cow_eof && cmap.br_startoff <= offset_fsb) { 583 - trace_xfs_reflink_cow_found(ip, &cmap); 584 - whichfork = XFS_COW_FORK; 585 - goto done; 586 - } 587 - } 588 - 589 - if (imap.br_startoff <= offset_fsb) { 590 - /* 591 - * For reflink files we may need a delalloc reservation when 592 - * overwriting shared extents. This includes zeroing of 593 - * existing extents that contain data. 594 - */ 595 - if (!xfs_is_cow_inode(ip) || 596 - ((flags & IOMAP_ZERO) && imap.br_state != XFS_EXT_NORM)) { 597 - trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK, 598 - &imap); 599 - goto done; 600 - } 601 - 602 - xfs_trim_extent(&imap, offset_fsb, end_fsb - offset_fsb); 603 - 604 - /* Trim the mapping to the nearest shared extent boundary. */ 605 - error = xfs_inode_need_cow(ip, &imap, &shared); 606 - if (error) 607 - goto out_unlock; 608 - 609 - /* Not shared? Just report the (potentially capped) extent. */ 610 - if (!shared) { 611 - trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK, 612 - &imap); 613 - goto done; 614 - } 615 - 616 - /* 617 - * Fork all the shared blocks from our write offset until the 618 - * end of the extent. 619 - */ 620 - whichfork = XFS_COW_FORK; 621 - end_fsb = imap.br_startoff + imap.br_blockcount; 622 - } else { 623 - /* 624 - * We cap the maximum length we map here to MAX_WRITEBACK_PAGES 625 - * pages to keep the chunks of work done where somewhat 626 - * symmetric with the work writeback does. This is a completely 627 - * arbitrary number pulled out of thin air. 628 - * 629 - * Note that the values needs to be less than 32-bits wide until 630 - * the lower level functions are updated. 631 - */ 632 - count = min_t(loff_t, count, 1024 * PAGE_SIZE); 633 - end_fsb = min(XFS_B_TO_FSB(mp, offset + count), maxbytes_fsb); 634 - 635 - if (xfs_is_always_cow_inode(ip)) 636 - whichfork = XFS_COW_FORK; 637 - } 638 - 639 - error = xfs_qm_dqattach_locked(ip, false); 640 - if (error) 641 - goto out_unlock; 642 - 643 - if (eof) { 644 - prealloc_blocks = xfs_iomap_prealloc_size(ip, whichfork, offset, 645 - count, &icur); 646 - if (prealloc_blocks) { 647 - xfs_extlen_t align; 648 - xfs_off_t end_offset; 649 - xfs_fileoff_t p_end_fsb; 650 - 651 - end_offset = XFS_WRITEIO_ALIGN(mp, offset + count - 1); 652 - p_end_fsb = XFS_B_TO_FSBT(mp, end_offset) + 653 - prealloc_blocks; 654 - 655 - align = xfs_eof_alignment(ip, 0); 656 - if (align) 657 - p_end_fsb = roundup_64(p_end_fsb, align); 658 - 659 - p_end_fsb = min(p_end_fsb, maxbytes_fsb); 660 - ASSERT(p_end_fsb > offset_fsb); 661 - prealloc_blocks = p_end_fsb - end_fsb; 662 - } 663 - } 664 - 665 - retry: 666 - error = xfs_bmapi_reserve_delalloc(ip, whichfork, offset_fsb, 667 - end_fsb - offset_fsb, prealloc_blocks, 668 - whichfork == XFS_DATA_FORK ? &imap : &cmap, 669 - whichfork == XFS_DATA_FORK ? &icur : &ccur, 670 - whichfork == XFS_DATA_FORK ? eof : cow_eof); 671 - switch (error) { 672 - case 0: 673 - break; 674 - case -ENOSPC: 675 - case -EDQUOT: 676 - /* retry without any preallocation */ 677 - trace_xfs_delalloc_enospc(ip, offset, count); 678 - if (prealloc_blocks) { 679 - prealloc_blocks = 0; 680 - goto retry; 681 - } 682 - /*FALLTHRU*/ 683 - default: 684 - goto out_unlock; 685 - } 686 - 687 - /* 688 - * Flag newly allocated delalloc blocks with IOMAP_F_NEW so we punch 689 - * them out if the write happens to fail. 690 - */ 691 - if (whichfork == XFS_DATA_FORK) { 692 - iomap_flags |= IOMAP_F_NEW; 693 - trace_xfs_iomap_alloc(ip, offset, count, whichfork, &imap); 694 - } else { 695 - trace_xfs_iomap_alloc(ip, offset, count, whichfork, &cmap); 696 - } 697 - done: 698 - if (whichfork == XFS_COW_FORK) { 699 - if (imap.br_startoff > offset_fsb) { 700 - xfs_trim_extent(&cmap, offset_fsb, 701 - imap.br_startoff - offset_fsb); 702 - error = xfs_bmbt_to_iomap(ip, iomap, &cmap, 703 - IOMAP_F_SHARED); 704 - goto out_unlock; 705 - } 706 - /* ensure we only report blocks we have a reservation for */ 707 - xfs_trim_extent(&imap, cmap.br_startoff, cmap.br_blockcount); 708 - shared = true; 709 - } 710 - if (shared) 711 - iomap_flags |= IOMAP_F_SHARED; 712 - error = xfs_bmbt_to_iomap(ip, iomap, &imap, iomap_flags); 713 - out_unlock: 714 - xfs_iunlock(ip, XFS_ILOCK_EXCL); 715 - return error; 716 522 } 717 523 718 524 int ··· 539 771 */ 540 772 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1; 541 773 774 + /* Attach dquots so that bmbt splits are accounted correctly. */ 775 + error = xfs_qm_dqattach(ip); 776 + if (error) 777 + return error; 778 + 542 779 do { 543 780 /* 544 781 * Set up a transaction to convert the range of extents ··· 561 788 562 789 xfs_ilock(ip, XFS_ILOCK_EXCL); 563 790 xfs_trans_ijoin(tp, ip, 0); 791 + 792 + error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0, 793 + XFS_QMOPT_RES_REGBLKS); 794 + if (error) 795 + goto error_on_bmapi_transaction; 564 796 565 797 /* 566 798 * Modify the unwritten extent state of the buffer. ··· 624 846 static inline bool 625 847 imap_needs_alloc( 626 848 struct inode *inode, 849 + unsigned flags, 627 850 struct xfs_bmbt_irec *imap, 628 851 int nimaps) 629 852 { 630 - return !nimaps || 631 - imap->br_startblock == HOLESTARTBLOCK || 632 - imap->br_startblock == DELAYSTARTBLOCK || 633 - (IS_DAX(inode) && imap->br_state == XFS_EXT_UNWRITTEN); 853 + /* don't allocate blocks when just zeroing */ 854 + if (flags & IOMAP_ZERO) 855 + return false; 856 + if (!nimaps || 857 + imap->br_startblock == HOLESTARTBLOCK || 858 + imap->br_startblock == DELAYSTARTBLOCK) 859 + return true; 860 + /* we convert unwritten extents before copying the data for DAX */ 861 + if (IS_DAX(inode) && imap->br_state == XFS_EXT_UNWRITTEN) 862 + return true; 863 + return false; 634 864 } 635 865 636 866 static inline bool 637 - needs_cow_for_zeroing( 867 + imap_needs_cow( 868 + struct xfs_inode *ip, 869 + unsigned int flags, 638 870 struct xfs_bmbt_irec *imap, 639 871 int nimaps) 640 872 { 641 - return nimaps && 642 - imap->br_startblock != HOLESTARTBLOCK && 643 - imap->br_state != XFS_EXT_UNWRITTEN; 873 + if (!xfs_is_cow_inode(ip)) 874 + return false; 875 + 876 + /* when zeroing we don't have to COW holes or unwritten extents */ 877 + if (flags & IOMAP_ZERO) { 878 + if (!nimaps || 879 + imap->br_startblock == HOLESTARTBLOCK || 880 + imap->br_state == XFS_EXT_UNWRITTEN) 881 + return false; 882 + } 883 + 884 + return true; 644 885 } 645 886 646 887 static int ··· 675 878 * COW writes may allocate delalloc space or convert unwritten COW 676 879 * extents, so we need to make sure to take the lock exclusively here. 677 880 */ 678 - if (xfs_is_cow_inode(ip) && is_write) { 679 - /* 680 - * FIXME: It could still overwrite on unshared extents and not 681 - * need allocation. 682 - */ 683 - if (flags & IOMAP_NOWAIT) 684 - return -EAGAIN; 881 + if (xfs_is_cow_inode(ip) && is_write) 685 882 mode = XFS_ILOCK_EXCL; 686 - } 687 883 688 884 /* 689 885 * Extents not yet cached requires exclusive access, don't block. This ··· 713 923 } 714 924 715 925 static int 716 - xfs_file_iomap_begin( 926 + xfs_direct_write_iomap_begin( 717 927 struct inode *inode, 718 928 loff_t offset, 719 929 loff_t length, ··· 723 933 { 724 934 struct xfs_inode *ip = XFS_I(inode); 725 935 struct xfs_mount *mp = ip->i_mount; 726 - struct xfs_bmbt_irec imap; 727 - xfs_fileoff_t offset_fsb, end_fsb; 936 + struct xfs_bmbt_irec imap, cmap; 937 + xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); 938 + xfs_fileoff_t end_fsb = xfs_iomap_end_fsb(mp, offset, length); 728 939 int nimaps = 1, error = 0; 729 940 bool shared = false; 730 941 u16 iomap_flags = 0; 731 942 unsigned lockmode; 732 943 944 + ASSERT(flags & (IOMAP_WRITE | IOMAP_ZERO)); 945 + 733 946 if (XFS_FORCED_SHUTDOWN(mp)) 734 947 return -EIO; 735 948 736 - if ((flags & (IOMAP_WRITE | IOMAP_ZERO)) && !(flags & IOMAP_DIRECT) && 737 - !IS_DAX(inode) && !xfs_get_extsz_hint(ip)) { 738 - /* Reserve delalloc blocks for regular writeback. */ 739 - return xfs_file_iomap_begin_delay(inode, offset, length, flags, 740 - iomap); 741 - } 742 - 743 949 /* 744 - * Lock the inode in the manner required for the specified operation and 745 - * check for as many conditions that would result in blocking as 746 - * possible. This removes most of the non-blocking checks from the 747 - * mapping code below. 950 + * Writes that span EOF might trigger an IO size update on completion, 951 + * so consider them to be dirty for the purposes of O_DSYNC even if 952 + * there is no other metadata changes pending or have been made here. 748 953 */ 954 + if (offset + length > i_size_read(inode)) 955 + iomap_flags |= IOMAP_F_DIRTY; 956 + 749 957 error = xfs_ilock_for_iomap(ip, flags, &lockmode); 750 958 if (error) 751 959 return error; 752 - 753 - ASSERT(offset <= mp->m_super->s_maxbytes); 754 - if (offset > mp->m_super->s_maxbytes - length) 755 - length = mp->m_super->s_maxbytes - offset; 756 - offset_fsb = XFS_B_TO_FSBT(mp, offset); 757 - end_fsb = XFS_B_TO_FSB(mp, offset + length); 758 960 759 961 error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, 760 962 &nimaps, 0); 761 963 if (error) 762 964 goto out_unlock; 763 965 764 - if (flags & IOMAP_REPORT) { 765 - /* Trim the mapping to the nearest shared extent boundary. */ 766 - error = xfs_reflink_trim_around_shared(ip, &imap, &shared); 767 - if (error) 966 + if (imap_needs_cow(ip, flags, &imap, nimaps)) { 967 + error = -EAGAIN; 968 + if (flags & IOMAP_NOWAIT) 768 969 goto out_unlock; 769 - } 770 - 771 - /* Non-modifying mapping requested, so we are done */ 772 - if (!(flags & (IOMAP_WRITE | IOMAP_ZERO))) 773 - goto out_found; 774 - 775 - /* 776 - * Break shared extents if necessary. Checks for non-blocking IO have 777 - * been done up front, so we don't need to do them here. 778 - */ 779 - if (xfs_is_cow_inode(ip)) { 780 - struct xfs_bmbt_irec cmap; 781 - bool directio = (flags & IOMAP_DIRECT); 782 - 783 - /* if zeroing doesn't need COW allocation, then we are done. */ 784 - if ((flags & IOMAP_ZERO) && 785 - !needs_cow_for_zeroing(&imap, nimaps)) 786 - goto out_found; 787 970 788 971 /* may drop and re-acquire the ilock */ 789 - cmap = imap; 790 - error = xfs_reflink_allocate_cow(ip, &cmap, &shared, &lockmode, 791 - directio); 972 + error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared, 973 + &lockmode, flags & IOMAP_DIRECT); 792 974 if (error) 793 975 goto out_unlock; 794 - 795 - /* 796 - * For buffered writes we need to report the address of the 797 - * previous block (if there was any) so that the higher level 798 - * write code can perform read-modify-write operations; we 799 - * won't need the CoW fork mapping until writeback. For direct 800 - * I/O, which must be block aligned, we need to report the 801 - * newly allocated address. If the data fork has a hole, copy 802 - * the COW fork mapping to avoid allocating to the data fork. 803 - */ 804 - if (directio || imap.br_startblock == HOLESTARTBLOCK) 805 - imap = cmap; 806 - 976 + if (shared) 977 + goto out_found_cow; 807 978 end_fsb = imap.br_startoff + imap.br_blockcount; 808 979 length = XFS_FSB_TO_B(mp, end_fsb) - offset; 809 980 } 810 981 811 - /* Don't need to allocate over holes when doing zeroing operations. */ 812 - if (flags & IOMAP_ZERO) 813 - goto out_found; 982 + if (imap_needs_alloc(inode, flags, &imap, nimaps)) 983 + goto allocate_blocks; 814 984 815 - if (!imap_needs_alloc(inode, &imap, nimaps)) 816 - goto out_found; 985 + xfs_iunlock(ip, lockmode); 986 + trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap); 987 + return xfs_bmbt_to_iomap(ip, iomap, &imap, iomap_flags); 817 988 818 - /* If nowait is set bail since we are going to make allocations. */ 819 - if (flags & IOMAP_NOWAIT) { 820 - error = -EAGAIN; 989 + allocate_blocks: 990 + error = -EAGAIN; 991 + if (flags & IOMAP_NOWAIT) 821 992 goto out_unlock; 822 - } 823 993 824 994 /* 825 995 * We cap the maximum length we map to a sane size to keep the chunks ··· 791 1041 * lower level functions are updated. 792 1042 */ 793 1043 length = min_t(loff_t, length, 1024 * PAGE_SIZE); 1044 + end_fsb = xfs_iomap_end_fsb(mp, offset, length); 794 1045 795 - /* 796 - * xfs_iomap_write_direct() expects the shared lock. It is unlocked on 797 - * return. 798 - */ 799 - if (lockmode == XFS_ILOCK_EXCL) 800 - xfs_ilock_demote(ip, lockmode); 801 - error = xfs_iomap_write_direct(ip, offset, length, &imap, 802 - nimaps); 1046 + if (offset + length > XFS_ISIZE(ip)) 1047 + end_fsb = xfs_iomap_eof_align_last_fsb(ip, end_fsb); 1048 + else if (nimaps && imap.br_startblock == HOLESTARTBLOCK) 1049 + end_fsb = min(end_fsb, imap.br_startoff + imap.br_blockcount); 1050 + xfs_iunlock(ip, lockmode); 1051 + 1052 + error = xfs_iomap_write_direct(ip, offset_fsb, end_fsb - offset_fsb, 1053 + &imap); 803 1054 if (error) 804 1055 return error; 805 1056 806 - iomap_flags |= IOMAP_F_NEW; 807 1057 trace_xfs_iomap_alloc(ip, offset, length, XFS_DATA_FORK, &imap); 1058 + return xfs_bmbt_to_iomap(ip, iomap, &imap, iomap_flags | IOMAP_F_NEW); 808 1059 809 - out_finish: 810 - /* 811 - * Writes that span EOF might trigger an IO size update on completion, 812 - * so consider them to be dirty for the purposes of O_DSYNC even if 813 - * there is no other metadata changes pending or have been made here. 814 - */ 815 - if ((flags & IOMAP_WRITE) && offset + length > i_size_read(inode)) 816 - iomap_flags |= IOMAP_F_DIRTY; 817 - if (shared) 818 - iomap_flags |= IOMAP_F_SHARED; 819 - return xfs_bmbt_to_iomap(ip, iomap, &imap, iomap_flags); 820 - 821 - out_found: 822 - ASSERT(nimaps); 1060 + out_found_cow: 823 1061 xfs_iunlock(ip, lockmode); 824 - trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap); 825 - goto out_finish; 1062 + length = XFS_FSB_TO_B(mp, cmap.br_startoff + cmap.br_blockcount); 1063 + trace_xfs_iomap_found(ip, offset, length - offset, XFS_COW_FORK, &cmap); 1064 + if (imap.br_startblock != HOLESTARTBLOCK) { 1065 + error = xfs_bmbt_to_iomap(ip, srcmap, &imap, 0); 1066 + if (error) 1067 + return error; 1068 + } 1069 + return xfs_bmbt_to_iomap(ip, iomap, &cmap, IOMAP_F_SHARED); 826 1070 827 1071 out_unlock: 828 1072 xfs_iunlock(ip, lockmode); 829 1073 return error; 830 1074 } 831 1075 1076 + const struct iomap_ops xfs_direct_write_iomap_ops = { 1077 + .iomap_begin = xfs_direct_write_iomap_begin, 1078 + }; 1079 + 832 1080 static int 833 - xfs_file_iomap_end_delalloc( 834 - struct xfs_inode *ip, 1081 + xfs_buffered_write_iomap_begin( 1082 + struct inode *inode, 1083 + loff_t offset, 1084 + loff_t count, 1085 + unsigned flags, 1086 + struct iomap *iomap, 1087 + struct iomap *srcmap) 1088 + { 1089 + struct xfs_inode *ip = XFS_I(inode); 1090 + struct xfs_mount *mp = ip->i_mount; 1091 + xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); 1092 + xfs_fileoff_t end_fsb = xfs_iomap_end_fsb(mp, offset, count); 1093 + struct xfs_bmbt_irec imap, cmap; 1094 + struct xfs_iext_cursor icur, ccur; 1095 + xfs_fsblock_t prealloc_blocks = 0; 1096 + bool eof = false, cow_eof = false, shared = false; 1097 + int allocfork = XFS_DATA_FORK; 1098 + int error = 0; 1099 + 1100 + /* we can't use delayed allocations when using extent size hints */ 1101 + if (xfs_get_extsz_hint(ip)) 1102 + return xfs_direct_write_iomap_begin(inode, offset, count, 1103 + flags, iomap, srcmap); 1104 + 1105 + ASSERT(!XFS_IS_REALTIME_INODE(ip)); 1106 + 1107 + xfs_ilock(ip, XFS_ILOCK_EXCL); 1108 + 1109 + if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ip, XFS_DATA_FORK)) || 1110 + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) { 1111 + error = -EFSCORRUPTED; 1112 + goto out_unlock; 1113 + } 1114 + 1115 + XFS_STATS_INC(mp, xs_blk_mapw); 1116 + 1117 + if (!(ip->i_df.if_flags & XFS_IFEXTENTS)) { 1118 + error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); 1119 + if (error) 1120 + goto out_unlock; 1121 + } 1122 + 1123 + /* 1124 + * Search the data fork fork first to look up our source mapping. We 1125 + * always need the data fork map, as we have to return it to the 1126 + * iomap code so that the higher level write code can read data in to 1127 + * perform read-modify-write cycles for unaligned writes. 1128 + */ 1129 + eof = !xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &icur, &imap); 1130 + if (eof) 1131 + imap.br_startoff = end_fsb; /* fake hole until the end */ 1132 + 1133 + /* We never need to allocate blocks for zeroing a hole. */ 1134 + if ((flags & IOMAP_ZERO) && imap.br_startoff > offset_fsb) { 1135 + xfs_hole_to_iomap(ip, iomap, offset_fsb, imap.br_startoff); 1136 + goto out_unlock; 1137 + } 1138 + 1139 + /* 1140 + * Search the COW fork extent list even if we did not find a data fork 1141 + * extent. This serves two purposes: first this implements the 1142 + * speculative preallocation using cowextsize, so that we also unshare 1143 + * block adjacent to shared blocks instead of just the shared blocks 1144 + * themselves. Second the lookup in the extent list is generally faster 1145 + * than going out to the shared extent tree. 1146 + */ 1147 + if (xfs_is_cow_inode(ip)) { 1148 + if (!ip->i_cowfp) { 1149 + ASSERT(!xfs_is_reflink_inode(ip)); 1150 + xfs_ifork_init_cow(ip); 1151 + } 1152 + cow_eof = !xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, 1153 + &ccur, &cmap); 1154 + if (!cow_eof && cmap.br_startoff <= offset_fsb) { 1155 + trace_xfs_reflink_cow_found(ip, &cmap); 1156 + goto found_cow; 1157 + } 1158 + } 1159 + 1160 + if (imap.br_startoff <= offset_fsb) { 1161 + /* 1162 + * For reflink files we may need a delalloc reservation when 1163 + * overwriting shared extents. This includes zeroing of 1164 + * existing extents that contain data. 1165 + */ 1166 + if (!xfs_is_cow_inode(ip) || 1167 + ((flags & IOMAP_ZERO) && imap.br_state != XFS_EXT_NORM)) { 1168 + trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK, 1169 + &imap); 1170 + goto found_imap; 1171 + } 1172 + 1173 + xfs_trim_extent(&imap, offset_fsb, end_fsb - offset_fsb); 1174 + 1175 + /* Trim the mapping to the nearest shared extent boundary. */ 1176 + error = xfs_inode_need_cow(ip, &imap, &shared); 1177 + if (error) 1178 + goto out_unlock; 1179 + 1180 + /* Not shared? Just report the (potentially capped) extent. */ 1181 + if (!shared) { 1182 + trace_xfs_iomap_found(ip, offset, count, XFS_DATA_FORK, 1183 + &imap); 1184 + goto found_imap; 1185 + } 1186 + 1187 + /* 1188 + * Fork all the shared blocks from our write offset until the 1189 + * end of the extent. 1190 + */ 1191 + allocfork = XFS_COW_FORK; 1192 + end_fsb = imap.br_startoff + imap.br_blockcount; 1193 + } else { 1194 + /* 1195 + * We cap the maximum length we map here to MAX_WRITEBACK_PAGES 1196 + * pages to keep the chunks of work done where somewhat 1197 + * symmetric with the work writeback does. This is a completely 1198 + * arbitrary number pulled out of thin air. 1199 + * 1200 + * Note that the values needs to be less than 32-bits wide until 1201 + * the lower level functions are updated. 1202 + */ 1203 + count = min_t(loff_t, count, 1024 * PAGE_SIZE); 1204 + end_fsb = xfs_iomap_end_fsb(mp, offset, count); 1205 + 1206 + if (xfs_is_always_cow_inode(ip)) 1207 + allocfork = XFS_COW_FORK; 1208 + } 1209 + 1210 + error = xfs_qm_dqattach_locked(ip, false); 1211 + if (error) 1212 + goto out_unlock; 1213 + 1214 + if (eof) { 1215 + prealloc_blocks = xfs_iomap_prealloc_size(ip, allocfork, offset, 1216 + count, &icur); 1217 + if (prealloc_blocks) { 1218 + xfs_extlen_t align; 1219 + xfs_off_t end_offset; 1220 + xfs_fileoff_t p_end_fsb; 1221 + 1222 + end_offset = XFS_ALLOC_ALIGN(mp, offset + count - 1); 1223 + p_end_fsb = XFS_B_TO_FSBT(mp, end_offset) + 1224 + prealloc_blocks; 1225 + 1226 + align = xfs_eof_alignment(ip); 1227 + if (align) 1228 + p_end_fsb = roundup_64(p_end_fsb, align); 1229 + 1230 + p_end_fsb = min(p_end_fsb, 1231 + XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes)); 1232 + ASSERT(p_end_fsb > offset_fsb); 1233 + prealloc_blocks = p_end_fsb - end_fsb; 1234 + } 1235 + } 1236 + 1237 + retry: 1238 + error = xfs_bmapi_reserve_delalloc(ip, allocfork, offset_fsb, 1239 + end_fsb - offset_fsb, prealloc_blocks, 1240 + allocfork == XFS_DATA_FORK ? &imap : &cmap, 1241 + allocfork == XFS_DATA_FORK ? &icur : &ccur, 1242 + allocfork == XFS_DATA_FORK ? eof : cow_eof); 1243 + switch (error) { 1244 + case 0: 1245 + break; 1246 + case -ENOSPC: 1247 + case -EDQUOT: 1248 + /* retry without any preallocation */ 1249 + trace_xfs_delalloc_enospc(ip, offset, count); 1250 + if (prealloc_blocks) { 1251 + prealloc_blocks = 0; 1252 + goto retry; 1253 + } 1254 + /*FALLTHRU*/ 1255 + default: 1256 + goto out_unlock; 1257 + } 1258 + 1259 + if (allocfork == XFS_COW_FORK) { 1260 + trace_xfs_iomap_alloc(ip, offset, count, allocfork, &cmap); 1261 + goto found_cow; 1262 + } 1263 + 1264 + /* 1265 + * Flag newly allocated delalloc blocks with IOMAP_F_NEW so we punch 1266 + * them out if the write happens to fail. 1267 + */ 1268 + xfs_iunlock(ip, XFS_ILOCK_EXCL); 1269 + trace_xfs_iomap_alloc(ip, offset, count, allocfork, &imap); 1270 + return xfs_bmbt_to_iomap(ip, iomap, &imap, IOMAP_F_NEW); 1271 + 1272 + found_imap: 1273 + xfs_iunlock(ip, XFS_ILOCK_EXCL); 1274 + return xfs_bmbt_to_iomap(ip, iomap, &imap, 0); 1275 + 1276 + found_cow: 1277 + xfs_iunlock(ip, XFS_ILOCK_EXCL); 1278 + if (imap.br_startoff <= offset_fsb) { 1279 + error = xfs_bmbt_to_iomap(ip, srcmap, &imap, 0); 1280 + if (error) 1281 + return error; 1282 + } else { 1283 + xfs_trim_extent(&cmap, offset_fsb, 1284 + imap.br_startoff - offset_fsb); 1285 + } 1286 + return xfs_bmbt_to_iomap(ip, iomap, &cmap, IOMAP_F_SHARED); 1287 + 1288 + out_unlock: 1289 + xfs_iunlock(ip, XFS_ILOCK_EXCL); 1290 + return error; 1291 + } 1292 + 1293 + static int 1294 + xfs_buffered_write_iomap_end( 1295 + struct inode *inode, 835 1296 loff_t offset, 836 1297 loff_t length, 837 1298 ssize_t written, 1299 + unsigned flags, 838 1300 struct iomap *iomap) 839 1301 { 1302 + struct xfs_inode *ip = XFS_I(inode); 840 1303 struct xfs_mount *mp = ip->i_mount; 841 1304 xfs_fileoff_t start_fsb; 842 1305 xfs_fileoff_t end_fsb; 843 1306 int error = 0; 1307 + 1308 + if (iomap->type != IOMAP_DELALLOC) 1309 + return 0; 844 1310 845 1311 /* 846 1312 * Behave as if the write failed if drop writes is enabled. Set the NEW ··· 1102 1136 return 0; 1103 1137 } 1104 1138 1139 + const struct iomap_ops xfs_buffered_write_iomap_ops = { 1140 + .iomap_begin = xfs_buffered_write_iomap_begin, 1141 + .iomap_end = xfs_buffered_write_iomap_end, 1142 + }; 1143 + 1105 1144 static int 1106 - xfs_file_iomap_end( 1145 + xfs_read_iomap_begin( 1107 1146 struct inode *inode, 1108 1147 loff_t offset, 1109 1148 loff_t length, 1110 - ssize_t written, 1111 1149 unsigned flags, 1112 - struct iomap *iomap) 1150 + struct iomap *iomap, 1151 + struct iomap *srcmap) 1113 1152 { 1114 - if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC) 1115 - return xfs_file_iomap_end_delalloc(XFS_I(inode), offset, 1116 - length, written, iomap); 1117 - return 0; 1153 + struct xfs_inode *ip = XFS_I(inode); 1154 + struct xfs_mount *mp = ip->i_mount; 1155 + struct xfs_bmbt_irec imap; 1156 + xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); 1157 + xfs_fileoff_t end_fsb = xfs_iomap_end_fsb(mp, offset, length); 1158 + int nimaps = 1, error = 0; 1159 + bool shared = false; 1160 + unsigned lockmode; 1161 + 1162 + ASSERT(!(flags & (IOMAP_WRITE | IOMAP_ZERO))); 1163 + 1164 + if (XFS_FORCED_SHUTDOWN(mp)) 1165 + return -EIO; 1166 + 1167 + error = xfs_ilock_for_iomap(ip, flags, &lockmode); 1168 + if (error) 1169 + return error; 1170 + error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap, 1171 + &nimaps, 0); 1172 + if (!error && (flags & IOMAP_REPORT)) 1173 + error = xfs_reflink_trim_around_shared(ip, &imap, &shared); 1174 + xfs_iunlock(ip, lockmode); 1175 + 1176 + if (error) 1177 + return error; 1178 + trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap); 1179 + return xfs_bmbt_to_iomap(ip, iomap, &imap, shared ? IOMAP_F_SHARED : 0); 1118 1180 } 1119 1181 1120 - const struct iomap_ops xfs_iomap_ops = { 1121 - .iomap_begin = xfs_file_iomap_begin, 1122 - .iomap_end = xfs_file_iomap_end, 1182 + const struct iomap_ops xfs_read_iomap_ops = { 1183 + .iomap_begin = xfs_read_iomap_begin, 1123 1184 }; 1124 1185 1125 1186 static int ··· 1189 1196 /* 1190 1197 * Fake a hole until the end of the file. 1191 1198 */ 1192 - data_fsb = min(XFS_B_TO_FSB(mp, offset + length), 1193 - XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes)); 1199 + data_fsb = xfs_iomap_end_fsb(mp, offset, length); 1194 1200 } 1195 1201 1196 1202 /*
+7 -4
fs/xfs/xfs_iomap.h
··· 11 11 struct xfs_inode; 12 12 struct xfs_bmbt_irec; 13 13 14 - int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, 15 - struct xfs_bmbt_irec *, int); 14 + int xfs_iomap_write_direct(struct xfs_inode *ip, xfs_fileoff_t offset_fsb, 15 + xfs_fileoff_t count_fsb, struct xfs_bmbt_irec *imap); 16 16 int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool); 17 + xfs_fileoff_t xfs_iomap_eof_align_last_fsb(struct xfs_inode *ip, 18 + xfs_fileoff_t end_fsb); 17 19 18 20 int xfs_bmbt_to_iomap(struct xfs_inode *, struct iomap *, 19 21 struct xfs_bmbt_irec *, u16); 20 - xfs_extlen_t xfs_eof_alignment(struct xfs_inode *ip, xfs_extlen_t extsize); 21 22 22 23 static inline xfs_filblks_t 23 24 xfs_aligned_fsb_count( ··· 40 39 return count_fsb; 41 40 } 42 41 43 - extern const struct iomap_ops xfs_iomap_ops; 42 + extern const struct iomap_ops xfs_buffered_write_iomap_ops; 43 + extern const struct iomap_ops xfs_direct_write_iomap_ops; 44 + extern const struct iomap_ops xfs_read_iomap_ops; 44 45 extern const struct iomap_ops xfs_seek_iomap_ops; 45 46 extern const struct iomap_ops xfs_xattr_iomap_ops; 46 47
+48 -22
fs/xfs/xfs_iops.c
··· 20 20 #include "xfs_symlink.h" 21 21 #include "xfs_dir2.h" 22 22 #include "xfs_iomap.h" 23 + #include "xfs_error.h" 23 24 24 25 #include <linux/xattr.h> 25 26 #include <linux/posix_acl.h> ··· 471 470 struct inode *inode, 472 471 struct delayed_call *done) 473 472 { 473 + struct xfs_inode *ip = XFS_I(inode); 474 474 char *link; 475 475 476 - ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE); 476 + ASSERT(ip->i_df.if_flags & XFS_IFINLINE); 477 477 478 478 /* 479 479 * The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if 480 480 * if_data is junk. 481 481 */ 482 - link = XFS_I(inode)->i_df.if_u1.if_data; 483 - if (!link) 482 + link = ip->i_df.if_u1.if_data; 483 + if (XFS_IS_CORRUPT(ip->i_mount, !link)) 484 484 return ERR_PTR(-EFSCORRUPTED); 485 485 return link; 486 + } 487 + 488 + static uint32_t 489 + xfs_stat_blksize( 490 + struct xfs_inode *ip) 491 + { 492 + struct xfs_mount *mp = ip->i_mount; 493 + 494 + /* 495 + * If the file blocks are being allocated from a realtime volume, then 496 + * always return the realtime extent size. 497 + */ 498 + if (XFS_IS_REALTIME_INODE(ip)) 499 + return xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; 500 + 501 + /* 502 + * Allow large block sizes to be reported to userspace programs if the 503 + * "largeio" mount option is used. 504 + * 505 + * If compatibility mode is specified, simply return the basic unit of 506 + * caching so that we don't get inefficient read/modify/write I/O from 507 + * user apps. Otherwise.... 508 + * 509 + * If the underlying volume is a stripe, then return the stripe width in 510 + * bytes as the recommended I/O size. It is not a stripe and we've set a 511 + * default buffered I/O size, return that, otherwise return the compat 512 + * default. 513 + */ 514 + if (mp->m_flags & XFS_MOUNT_LARGEIO) { 515 + if (mp->m_swidth) 516 + return mp->m_swidth << mp->m_sb.sb_blocklog; 517 + if (mp->m_flags & XFS_MOUNT_ALLOCSIZE) 518 + return 1U << mp->m_allocsize_log; 519 + } 520 + 521 + return PAGE_SIZE; 486 522 } 487 523 488 524 STATIC int ··· 554 516 if (ip->i_d.di_version == 3) { 555 517 if (request_mask & STATX_BTIME) { 556 518 stat->result_mask |= STATX_BTIME; 557 - stat->btime.tv_sec = ip->i_d.di_crtime.t_sec; 558 - stat->btime.tv_nsec = ip->i_d.di_crtime.t_nsec; 519 + stat->btime = ip->i_d.di_crtime; 559 520 } 560 521 } 561 522 ··· 580 543 stat->rdev = inode->i_rdev; 581 544 break; 582 545 default: 583 - if (XFS_IS_REALTIME_INODE(ip)) { 584 - /* 585 - * If the file blocks are being allocated from a 586 - * realtime volume, then return the inode's realtime 587 - * extent size or the realtime volume's extent size. 588 - */ 589 - stat->blksize = 590 - xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; 591 - } else 592 - stat->blksize = xfs_preferred_iosize(mp); 546 + stat->blksize = xfs_stat_blksize(ip); 593 547 stat->rdev = 0; 594 548 break; 595 549 } ··· 692 664 ASSERT(gdqp == NULL); 693 665 error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid), 694 666 xfs_kgid_to_gid(gid), 695 - xfs_get_projid(ip), 667 + ip->i_d.di_projid, 696 668 qflags, &udqp, &gdqp, NULL); 697 669 if (error) 698 670 return error; ··· 911 883 if (newsize > oldsize) { 912 884 trace_xfs_zero_eof(ip, oldsize, newsize - oldsize); 913 885 error = iomap_zero_range(inode, oldsize, newsize - oldsize, 914 - &did_zeroing, &xfs_iomap_ops); 886 + &did_zeroing, &xfs_buffered_write_iomap_ops); 915 887 } else { 916 888 error = iomap_truncate_page(inode, newsize, &did_zeroing, 917 - &xfs_iomap_ops); 889 + &xfs_buffered_write_iomap_ops); 918 890 } 919 891 920 892 if (error) ··· 1142 1114 &xfs_xattr_iomap_ops); 1143 1115 } else { 1144 1116 error = iomap_fiemap(inode, fieinfo, start, length, 1145 - &xfs_iomap_ops); 1117 + &xfs_read_iomap_ops); 1146 1118 } 1147 1119 xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED); 1148 1120 ··· 1255 1227 return false; 1256 1228 1257 1229 /* Device has to support DAX too. */ 1258 - return xfs_find_daxdev_for_inode(VFS_I(ip)) != NULL; 1230 + return xfs_inode_buftarg(ip)->bt_daxdev != NULL; 1259 1231 } 1260 1232 1261 1233 STATIC void ··· 1318 1290 lockdep_set_class(&inode->i_rwsem, 1319 1291 &inode->i_sb->s_type->i_mutex_dir_key); 1320 1292 lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class); 1321 - ip->d_ops = ip->i_mount->m_dir_inode_ops; 1322 1293 } else { 1323 - ip->d_ops = ip->i_mount->m_nondir_inode_ops; 1324 1294 lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class); 1325 1295 } 1326 1296
+3 -3
fs/xfs/xfs_itable.c
··· 84 84 /* xfs_iget returns the following without needing 85 85 * further change. 86 86 */ 87 - buf->bs_projectid = xfs_get_projid(ip); 87 + buf->bs_projectid = ip->i_d.di_projid; 88 88 buf->bs_ino = ino; 89 89 buf->bs_uid = dic->di_uid; 90 90 buf->bs_gid = dic->di_gid; ··· 97 97 buf->bs_mtime_nsec = inode->i_mtime.tv_nsec; 98 98 buf->bs_ctime = inode->i_ctime.tv_sec; 99 99 buf->bs_ctime_nsec = inode->i_ctime.tv_nsec; 100 - buf->bs_btime = dic->di_crtime.t_sec; 101 - buf->bs_btime_nsec = dic->di_crtime.t_nsec; 100 + buf->bs_btime = dic->di_crtime.tv_sec; 101 + buf->bs_btime_nsec = dic->di_crtime.tv_nsec; 102 102 buf->bs_gen = inode->i_generation; 103 103 buf->bs_mode = inode->i_mode; 104 104
+2 -1
fs/xfs/xfs_iwalk.c
··· 298 298 error = xfs_inobt_get_rec(*curpp, irec, has_more); 299 299 if (error) 300 300 return error; 301 - XFS_WANT_CORRUPTED_RETURN(mp, *has_more == 1); 301 + if (XFS_IS_CORRUPT(mp, *has_more != 1)) 302 + return -EFSCORRUPTED; 302 303 303 304 /* 304 305 * If the LE lookup yielded an inobt record before the cursor position,
+10 -4
fs/xfs/xfs_linux.h
··· 223 223 char *data, unsigned int op); 224 224 225 225 #define ASSERT_ALWAYS(expr) \ 226 - (likely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 226 + (likely(expr) ? (void)0 : assfail(NULL, #expr, __FILE__, __LINE__)) 227 227 228 228 #ifdef DEBUG 229 229 #define ASSERT(expr) \ 230 - (likely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 230 + (likely(expr) ? (void)0 : assfail(NULL, #expr, __FILE__, __LINE__)) 231 231 232 232 #else /* !DEBUG */ 233 233 234 234 #ifdef XFS_WARN 235 235 236 236 #define ASSERT(expr) \ 237 - (likely(expr) ? (void)0 : asswarn(#expr, __FILE__, __LINE__)) 237 + (likely(expr) ? (void)0 : asswarn(NULL, #expr, __FILE__, __LINE__)) 238 238 239 239 #else /* !DEBUG && !XFS_WARN */ 240 240 241 - #define ASSERT(expr) ((void)0) 241 + #define ASSERT(expr) ((void)0) 242 242 243 243 #endif /* XFS_WARN */ 244 244 #endif /* DEBUG */ 245 + 246 + #define XFS_IS_CORRUPT(mp, expr) \ 247 + (unlikely(expr) ? xfs_corruption_error(#expr, XFS_ERRLEVEL_LOW, (mp), \ 248 + NULL, 0, __FILE__, __LINE__, \ 249 + __this_address), \ 250 + true : false) 245 251 246 252 #define STATIC static noinline 247 253
+177 -261
fs/xfs/xfs_log.c
··· 57 57 struct xlog_ticket *ticket, 58 58 int *continued_write, 59 59 int *logoffsetp); 60 - STATIC int 61 - xlog_state_release_iclog( 62 - struct xlog *log, 63 - struct xlog_in_core *iclog); 64 60 STATIC void 65 61 xlog_state_switch_iclogs( 66 62 struct xlog *log, ··· 79 83 xlog_ungrant_log_space( 80 84 struct xlog *log, 81 85 struct xlog_ticket *ticket); 82 - 86 + STATIC void 87 + xlog_sync( 88 + struct xlog *log, 89 + struct xlog_in_core *iclog); 83 90 #if defined(DEBUG) 84 91 STATIC void 85 92 xlog_verify_dest_ptr( ··· 551 552 return lsn; 552 553 } 553 554 554 - int 555 - xfs_log_release_iclog( 556 - struct xfs_mount *mp, 555 + static bool 556 + __xlog_state_release_iclog( 557 + struct xlog *log, 557 558 struct xlog_in_core *iclog) 558 559 { 559 - if (xlog_state_release_iclog(mp->m_log, iclog)) { 560 + lockdep_assert_held(&log->l_icloglock); 561 + 562 + if (iclog->ic_state == XLOG_STATE_WANT_SYNC) { 563 + /* update tail before writing to iclog */ 564 + xfs_lsn_t tail_lsn = xlog_assign_tail_lsn(log->l_mp); 565 + 566 + iclog->ic_state = XLOG_STATE_SYNCING; 567 + iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); 568 + xlog_verify_tail_lsn(log, iclog, tail_lsn); 569 + /* cycle incremented when incrementing curr_block */ 570 + return true; 571 + } 572 + 573 + ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); 574 + return false; 575 + } 576 + 577 + /* 578 + * Flush iclog to disk if this is the last reference to the given iclog and the 579 + * it is in the WANT_SYNC state. 580 + */ 581 + static int 582 + xlog_state_release_iclog( 583 + struct xlog *log, 584 + struct xlog_in_core *iclog) 585 + { 586 + lockdep_assert_held(&log->l_icloglock); 587 + 588 + if (iclog->ic_state == XLOG_STATE_IOERROR) 589 + return -EIO; 590 + 591 + if (atomic_dec_and_test(&iclog->ic_refcnt) && 592 + __xlog_state_release_iclog(log, iclog)) { 593 + spin_unlock(&log->l_icloglock); 594 + xlog_sync(log, iclog); 595 + spin_lock(&log->l_icloglock); 596 + } 597 + 598 + return 0; 599 + } 600 + 601 + int 602 + xfs_log_release_iclog( 603 + struct xfs_mount *mp, 604 + struct xlog_in_core *iclog) 605 + { 606 + struct xlog *log = mp->m_log; 607 + bool sync; 608 + 609 + if (iclog->ic_state == XLOG_STATE_IOERROR) { 560 610 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); 561 611 return -EIO; 562 612 } 563 613 614 + if (atomic_dec_and_lock(&iclog->ic_refcnt, &log->l_icloglock)) { 615 + sync = __xlog_state_release_iclog(log, iclog); 616 + spin_unlock(&log->l_icloglock); 617 + if (sync) 618 + xlog_sync(log, iclog); 619 + } 564 620 return 0; 565 621 } 566 622 ··· 920 866 iclog = log->l_iclog; 921 867 atomic_inc(&iclog->ic_refcnt); 922 868 xlog_state_want_sync(log, iclog); 923 - spin_unlock(&log->l_icloglock); 924 869 error = xlog_state_release_iclog(log, iclog); 925 - 926 - spin_lock(&log->l_icloglock); 927 870 switch (iclog->ic_state) { 928 871 default: 929 872 if (!XLOG_FORCED_SHUTDOWN(log)) { ··· 975 924 #ifdef DEBUG 976 925 first_iclog = iclog = log->l_iclog; 977 926 do { 978 - if (!(iclog->ic_state & XLOG_STATE_IOERROR)) { 979 - ASSERT(iclog->ic_state & XLOG_STATE_ACTIVE); 927 + if (iclog->ic_state != XLOG_STATE_IOERROR) { 928 + ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE); 980 929 ASSERT(iclog->ic_offset == 0); 981 930 } 982 931 iclog = iclog->ic_next; ··· 1001 950 spin_lock(&log->l_icloglock); 1002 951 iclog = log->l_iclog; 1003 952 atomic_inc(&iclog->ic_refcnt); 1004 - 1005 953 xlog_state_want_sync(log, iclog); 1006 - spin_unlock(&log->l_icloglock); 1007 954 error = xlog_state_release_iclog(log, iclog); 1008 - 1009 - spin_lock(&log->l_icloglock); 1010 - 1011 - if ( ! ( iclog->ic_state == XLOG_STATE_ACTIVE 1012 - || iclog->ic_state == XLOG_STATE_DIRTY 1013 - || iclog->ic_state == XLOG_STATE_IOERROR) ) { 1014 - 1015 - xlog_wait(&iclog->ic_force_wait, 1016 - &log->l_icloglock); 1017 - } else { 955 + switch (iclog->ic_state) { 956 + case XLOG_STATE_ACTIVE: 957 + case XLOG_STATE_DIRTY: 958 + case XLOG_STATE_IOERROR: 1018 959 spin_unlock(&log->l_icloglock); 960 + break; 961 + default: 962 + xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); 963 + break; 1019 964 } 1020 965 } 1021 966 ··· 1301 1254 * didn't succeed. 1302 1255 */ 1303 1256 aborted = true; 1304 - } else if (iclog->ic_state & XLOG_STATE_IOERROR) { 1257 + } else if (iclog->ic_state == XLOG_STATE_IOERROR) { 1305 1258 aborted = true; 1306 1259 } 1307 1260 ··· 1526 1479 1527 1480 log->l_ioend_workqueue = alloc_workqueue("xfs-log/%s", 1528 1481 WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_HIGHPRI, 0, 1529 - mp->m_fsname); 1482 + mp->m_super->s_id); 1530 1483 if (!log->l_ioend_workqueue) 1531 1484 goto out_free_iclog; 1532 1485 ··· 1774 1727 * across the log IO to archieve that. 1775 1728 */ 1776 1729 down(&iclog->ic_sema); 1777 - if (unlikely(iclog->ic_state & XLOG_STATE_IOERROR)) { 1730 + if (unlikely(iclog->ic_state == XLOG_STATE_IOERROR)) { 1778 1731 /* 1779 1732 * It would seem logical to return EIO here, but we rely on 1780 1733 * the log state machine to propagate I/O errors instead of ··· 1782 1735 * the buffer manually, the code needs to be kept in sync 1783 1736 * with the I/O completion path. 1784 1737 */ 1785 - xlog_state_done_syncing(iclog, XFS_LI_ABORTED); 1738 + xlog_state_done_syncing(iclog, true); 1786 1739 up(&iclog->ic_sema); 1787 1740 return; 1788 1741 } 1789 - 1790 - iclog->ic_io_size = count; 1791 1742 1792 1743 bio_init(&iclog->ic_bio, iclog->ic_bvec, howmany(count, PAGE_SIZE)); 1793 1744 bio_set_dev(&iclog->ic_bio, log->l_targ->bt_bdev); ··· 1796 1751 if (need_flush) 1797 1752 iclog->ic_bio.bi_opf |= REQ_PREFLUSH; 1798 1753 1799 - xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, iclog->ic_io_size); 1754 + xlog_map_iclog_data(&iclog->ic_bio, iclog->ic_data, count); 1800 1755 if (is_vmalloc_addr(iclog->ic_data)) 1801 - flush_kernel_vmap_range(iclog->ic_data, iclog->ic_io_size); 1756 + flush_kernel_vmap_range(iclog->ic_data, count); 1802 1757 1803 1758 /* 1804 1759 * If this log buffer would straddle the end of the log we will have ··· 2014 1969 /* 2015 1970 * Update counters atomically now that memcpy is done. 2016 1971 */ 2017 - /* ARGSUSED */ 2018 1972 static inline void 2019 1973 xlog_state_finish_copy( 2020 1974 struct xlog *log, ··· 2021 1977 int record_cnt, 2022 1978 int copy_bytes) 2023 1979 { 2024 - spin_lock(&log->l_icloglock); 1980 + lockdep_assert_held(&log->l_icloglock); 2025 1981 2026 1982 be32_add_cpu(&iclog->ic_header.h_num_logops, record_cnt); 2027 1983 iclog->ic_offset += copy_bytes; 2028 - 2029 - spin_unlock(&log->l_icloglock); 2030 - } /* xlog_state_finish_copy */ 2031 - 2032 - 2033 - 1984 + } 2034 1985 2035 1986 /* 2036 1987 * print out info relating to regions written which consume ··· 2302 2263 int log_offset, 2303 2264 struct xlog_in_core **commit_iclog) 2304 2265 { 2266 + int error; 2267 + 2305 2268 if (*partial_copy) { 2306 2269 /* 2307 2270 * This iclog has already been marked WANT_SYNC by 2308 2271 * xlog_state_get_iclog_space. 2309 2272 */ 2273 + spin_lock(&log->l_icloglock); 2310 2274 xlog_state_finish_copy(log, iclog, *record_cnt, *data_cnt); 2311 2275 *record_cnt = 0; 2312 2276 *data_cnt = 0; 2313 - return xlog_state_release_iclog(log, iclog); 2277 + goto release_iclog; 2314 2278 } 2315 2279 2316 2280 *partial_copy = 0; ··· 2321 2279 2322 2280 if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) { 2323 2281 /* no more space in this iclog - push it. */ 2282 + spin_lock(&log->l_icloglock); 2324 2283 xlog_state_finish_copy(log, iclog, *record_cnt, *data_cnt); 2325 2284 *record_cnt = 0; 2326 2285 *data_cnt = 0; 2327 2286 2328 - spin_lock(&log->l_icloglock); 2329 2287 xlog_state_want_sync(log, iclog); 2330 - spin_unlock(&log->l_icloglock); 2331 - 2332 2288 if (!commit_iclog) 2333 - return xlog_state_release_iclog(log, iclog); 2289 + goto release_iclog; 2290 + spin_unlock(&log->l_icloglock); 2334 2291 ASSERT(flags & XLOG_COMMIT_TRANS); 2335 2292 *commit_iclog = iclog; 2336 2293 } 2337 2294 2338 2295 return 0; 2296 + 2297 + release_iclog: 2298 + error = xlog_state_release_iclog(log, iclog); 2299 + spin_unlock(&log->l_icloglock); 2300 + return error; 2339 2301 } 2340 2302 2341 2303 /* ··· 2401 2355 int contwr = 0; 2402 2356 int record_cnt = 0; 2403 2357 int data_cnt = 0; 2404 - int error; 2358 + int error = 0; 2405 2359 2406 2360 *start_lsn = 0; 2407 2361 ··· 2552 2506 2553 2507 ASSERT(len == 0); 2554 2508 2509 + spin_lock(&log->l_icloglock); 2555 2510 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt); 2556 - if (!commit_iclog) 2557 - return xlog_state_release_iclog(log, iclog); 2511 + if (commit_iclog) { 2512 + ASSERT(flags & XLOG_COMMIT_TRANS); 2513 + *commit_iclog = iclog; 2514 + } else { 2515 + error = xlog_state_release_iclog(log, iclog); 2516 + } 2517 + spin_unlock(&log->l_icloglock); 2558 2518 2559 - ASSERT(flags & XLOG_COMMIT_TRANS); 2560 - *commit_iclog = iclog; 2561 - return 0; 2519 + return error; 2562 2520 } 2563 2521 2564 2522 ··· 2598 2548 int changed = 0; 2599 2549 2600 2550 /* Prepare the completed iclog. */ 2601 - if (!(dirty_iclog->ic_state & XLOG_STATE_IOERROR)) 2551 + if (dirty_iclog->ic_state != XLOG_STATE_IOERROR) 2602 2552 dirty_iclog->ic_state = XLOG_STATE_DIRTY; 2603 2553 2604 2554 /* Walk all the iclogs to update the ordered active state. */ ··· 2689 2639 xfs_lsn_t lowest_lsn = 0, lsn; 2690 2640 2691 2641 do { 2692 - if (iclog->ic_state & (XLOG_STATE_ACTIVE | XLOG_STATE_DIRTY)) 2642 + if (iclog->ic_state == XLOG_STATE_ACTIVE || 2643 + iclog->ic_state == XLOG_STATE_DIRTY) 2693 2644 continue; 2694 2645 2695 2646 lsn = be64_to_cpu(iclog->ic_header.h_lsn); ··· 2750 2699 xlog_state_iodone_process_iclog( 2751 2700 struct xlog *log, 2752 2701 struct xlog_in_core *iclog, 2753 - struct xlog_in_core *completed_iclog, 2754 2702 bool *ioerror) 2755 2703 { 2756 2704 xfs_lsn_t lowest_lsn; 2757 2705 xfs_lsn_t header_lsn; 2758 2706 2759 - /* Skip all iclogs in the ACTIVE & DIRTY states */ 2760 - if (iclog->ic_state & (XLOG_STATE_ACTIVE | XLOG_STATE_DIRTY)) 2707 + switch (iclog->ic_state) { 2708 + case XLOG_STATE_ACTIVE: 2709 + case XLOG_STATE_DIRTY: 2710 + /* 2711 + * Skip all iclogs in the ACTIVE & DIRTY states: 2712 + */ 2761 2713 return false; 2762 - 2763 - /* 2764 - * Between marking a filesystem SHUTDOWN and stopping the log, we do 2765 - * flush all iclogs to disk (if there wasn't a log I/O error). So, we do 2766 - * want things to go smoothly in case of just a SHUTDOWN w/o a 2767 - * LOG_IO_ERROR. 2768 - */ 2769 - if (iclog->ic_state & XLOG_STATE_IOERROR) { 2714 + case XLOG_STATE_IOERROR: 2715 + /* 2716 + * Between marking a filesystem SHUTDOWN and stopping the log, 2717 + * we do flush all iclogs to disk (if there wasn't a log I/O 2718 + * error). So, we do want things to go smoothly in case of just 2719 + * a SHUTDOWN w/o a LOG_IO_ERROR. 2720 + */ 2770 2721 *ioerror = true; 2771 2722 return false; 2772 - } 2773 - 2774 - /* 2775 - * Can only perform callbacks in order. Since this iclog is not in the 2776 - * DONE_SYNC/ DO_CALLBACK state, we skip the rest and just try to clean 2777 - * up. If we set our iclog to DO_CALLBACK, we will not process it when 2778 - * we retry since a previous iclog is in the CALLBACK and the state 2779 - * cannot change since we are holding the l_icloglock. 2780 - */ 2781 - if (!(iclog->ic_state & 2782 - (XLOG_STATE_DONE_SYNC | XLOG_STATE_DO_CALLBACK))) { 2783 - if (completed_iclog && 2784 - (completed_iclog->ic_state == XLOG_STATE_DONE_SYNC)) { 2785 - completed_iclog->ic_state = XLOG_STATE_DO_CALLBACK; 2786 - } 2723 + case XLOG_STATE_DONE_SYNC: 2724 + /* 2725 + * Now that we have an iclog that is in the DONE_SYNC state, do 2726 + * one more check here to see if we have chased our tail around. 2727 + * If this is not the lowest lsn iclog, then we will leave it 2728 + * for another completion to process. 2729 + */ 2730 + header_lsn = be64_to_cpu(iclog->ic_header.h_lsn); 2731 + lowest_lsn = xlog_get_lowest_lsn(log); 2732 + if (lowest_lsn && XFS_LSN_CMP(lowest_lsn, header_lsn) < 0) 2733 + return false; 2734 + xlog_state_set_callback(log, iclog, header_lsn); 2735 + return false; 2736 + default: 2737 + /* 2738 + * Can only perform callbacks in order. Since this iclog is not 2739 + * in the DONE_SYNC state, we skip the rest and just try to 2740 + * clean up. 2741 + */ 2787 2742 return true; 2788 2743 } 2789 - 2790 - /* 2791 - * We now have an iclog that is in either the DO_CALLBACK or DONE_SYNC 2792 - * states. The other states (WANT_SYNC, SYNCING, or CALLBACK were caught 2793 - * by the above if and are going to clean (i.e. we aren't doing their 2794 - * callbacks) see the above if. 2795 - * 2796 - * We will do one more check here to see if we have chased our tail 2797 - * around. If this is not the lowest lsn iclog, then we will leave it 2798 - * for another completion to process. 2799 - */ 2800 - header_lsn = be64_to_cpu(iclog->ic_header.h_lsn); 2801 - lowest_lsn = xlog_get_lowest_lsn(log); 2802 - if (lowest_lsn && XFS_LSN_CMP(lowest_lsn, header_lsn) < 0) 2803 - return false; 2804 - 2805 - xlog_state_set_callback(log, iclog, header_lsn); 2806 - return false; 2807 - 2808 2744 } 2809 2745 2810 2746 /* ··· 2808 2770 struct xlog *log, 2809 2771 struct xlog_in_core *iclog, 2810 2772 bool aborted) 2773 + __releases(&log->l_icloglock) 2774 + __acquires(&log->l_icloglock) 2811 2775 { 2812 2776 spin_unlock(&log->l_icloglock); 2813 2777 spin_lock(&iclog->ic_callback_lock); ··· 2832 2792 spin_unlock(&iclog->ic_callback_lock); 2833 2793 } 2834 2794 2835 - #ifdef DEBUG 2836 - /* 2837 - * Make one last gasp attempt to see if iclogs are being left in limbo. If the 2838 - * above loop finds an iclog earlier than the current iclog and in one of the 2839 - * syncing states, the current iclog is put into DO_CALLBACK and the callbacks 2840 - * are deferred to the completion of the earlier iclog. Walk the iclogs in order 2841 - * and make sure that no iclog is in DO_CALLBACK unless an earlier iclog is in 2842 - * one of the syncing states. 2843 - * 2844 - * Note that SYNCING|IOERROR is a valid state so we cannot just check for 2845 - * ic_state == SYNCING. 2846 - */ 2847 - static void 2848 - xlog_state_callback_check_state( 2849 - struct xlog *log) 2850 - { 2851 - struct xlog_in_core *first_iclog = log->l_iclog; 2852 - struct xlog_in_core *iclog = first_iclog; 2853 - 2854 - do { 2855 - ASSERT(iclog->ic_state != XLOG_STATE_DO_CALLBACK); 2856 - /* 2857 - * Terminate the loop if iclogs are found in states 2858 - * which will cause other threads to clean up iclogs. 2859 - * 2860 - * SYNCING - i/o completion will go through logs 2861 - * DONE_SYNC - interrupt thread should be waiting for 2862 - * l_icloglock 2863 - * IOERROR - give up hope all ye who enter here 2864 - */ 2865 - if (iclog->ic_state == XLOG_STATE_WANT_SYNC || 2866 - iclog->ic_state & XLOG_STATE_SYNCING || 2867 - iclog->ic_state == XLOG_STATE_DONE_SYNC || 2868 - iclog->ic_state == XLOG_STATE_IOERROR ) 2869 - break; 2870 - iclog = iclog->ic_next; 2871 - } while (first_iclog != iclog); 2872 - } 2873 - #else 2874 - #define xlog_state_callback_check_state(l) ((void)0) 2875 - #endif 2876 - 2877 2795 STATIC void 2878 2796 xlog_state_do_callback( 2879 2797 struct xlog *log, 2880 - bool aborted, 2881 - struct xlog_in_core *ciclog) 2798 + bool aborted) 2882 2799 { 2883 2800 struct xlog_in_core *iclog; 2884 2801 struct xlog_in_core *first_iclog; 2885 - bool did_callbacks = false; 2886 2802 bool cycled_icloglock; 2887 2803 bool ioerror; 2888 2804 int flushcnt = 0; ··· 2862 2866 2863 2867 do { 2864 2868 if (xlog_state_iodone_process_iclog(log, iclog, 2865 - ciclog, &ioerror)) 2869 + &ioerror)) 2866 2870 break; 2867 2871 2868 - if (!(iclog->ic_state & 2869 - (XLOG_STATE_CALLBACK | XLOG_STATE_IOERROR))) { 2872 + if (iclog->ic_state != XLOG_STATE_CALLBACK && 2873 + iclog->ic_state != XLOG_STATE_IOERROR) { 2870 2874 iclog = iclog->ic_next; 2871 2875 continue; 2872 2876 } ··· 2882 2886 iclog = iclog->ic_next; 2883 2887 } while (first_iclog != iclog); 2884 2888 2885 - did_callbacks |= cycled_icloglock; 2886 - 2887 2889 if (repeats > 5000) { 2888 2890 flushcnt += repeats; 2889 2891 repeats = 0; ··· 2891 2897 } 2892 2898 } while (!ioerror && cycled_icloglock); 2893 2899 2894 - if (did_callbacks) 2895 - xlog_state_callback_check_state(log); 2896 - 2897 - if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) 2900 + if (log->l_iclog->ic_state == XLOG_STATE_ACTIVE || 2901 + log->l_iclog->ic_state == XLOG_STATE_IOERROR) 2898 2902 wake_up_all(&log->l_flush_wait); 2899 2903 2900 2904 spin_unlock(&log->l_icloglock); ··· 2921 2929 2922 2930 spin_lock(&log->l_icloglock); 2923 2931 2924 - ASSERT(iclog->ic_state == XLOG_STATE_SYNCING || 2925 - iclog->ic_state == XLOG_STATE_IOERROR); 2926 2932 ASSERT(atomic_read(&iclog->ic_refcnt) == 0); 2927 2933 2928 2934 /* ··· 2929 2939 * and none should ever be attempted to be written to disk 2930 2940 * again. 2931 2941 */ 2932 - if (iclog->ic_state != XLOG_STATE_IOERROR) 2942 + if (iclog->ic_state == XLOG_STATE_SYNCING) 2933 2943 iclog->ic_state = XLOG_STATE_DONE_SYNC; 2944 + else 2945 + ASSERT(iclog->ic_state == XLOG_STATE_IOERROR); 2934 2946 2935 2947 /* 2936 2948 * Someone could be sleeping prior to writing out the next ··· 2941 2949 */ 2942 2950 wake_up_all(&iclog->ic_write_wait); 2943 2951 spin_unlock(&log->l_icloglock); 2944 - xlog_state_do_callback(log, aborted, iclog); /* also cleans log */ 2952 + xlog_state_do_callback(log, aborted); /* also cleans log */ 2945 2953 } /* xlog_state_done_syncing */ 2946 2954 2947 2955 ··· 2975 2983 int log_offset; 2976 2984 xlog_rec_header_t *head; 2977 2985 xlog_in_core_t *iclog; 2978 - int error; 2979 2986 2980 2987 restart: 2981 2988 spin_lock(&log->l_icloglock); ··· 3023 3032 * can fit into remaining data section. 3024 3033 */ 3025 3034 if (iclog->ic_size - iclog->ic_offset < 2*sizeof(xlog_op_header_t)) { 3035 + int error = 0; 3036 + 3026 3037 xlog_state_switch_iclogs(log, iclog, iclog->ic_size); 3027 3038 3028 3039 /* 3029 - * If I'm the only one writing to this iclog, sync it to disk. 3030 - * We need to do an atomic compare and decrement here to avoid 3031 - * racing with concurrent atomic_dec_and_lock() calls in 3040 + * If we are the only one writing to this iclog, sync it to 3041 + * disk. We need to do an atomic compare and decrement here to 3042 + * avoid racing with concurrent atomic_dec_and_lock() calls in 3032 3043 * xlog_state_release_iclog() when there is more than one 3033 3044 * reference to the iclog. 3034 3045 */ 3035 - if (!atomic_add_unless(&iclog->ic_refcnt, -1, 1)) { 3036 - /* we are the only one */ 3037 - spin_unlock(&log->l_icloglock); 3046 + if (!atomic_add_unless(&iclog->ic_refcnt, -1, 1)) 3038 3047 error = xlog_state_release_iclog(log, iclog); 3039 - if (error) 3040 - return error; 3041 - } else { 3042 - spin_unlock(&log->l_icloglock); 3043 - } 3048 + spin_unlock(&log->l_icloglock); 3049 + if (error) 3050 + return error; 3044 3051 goto restart; 3045 3052 } 3046 3053 ··· 3150 3161 } 3151 3162 3152 3163 /* 3153 - * Flush iclog to disk if this is the last reference to the given iclog and 3154 - * the WANT_SYNC bit is set. 3155 - * 3156 - * When this function is entered, the iclog is not necessarily in the 3157 - * WANT_SYNC state. It may be sitting around waiting to get filled. 3158 - * 3159 - * 3160 - */ 3161 - STATIC int 3162 - xlog_state_release_iclog( 3163 - struct xlog *log, 3164 - struct xlog_in_core *iclog) 3165 - { 3166 - int sync = 0; /* do we sync? */ 3167 - 3168 - if (iclog->ic_state & XLOG_STATE_IOERROR) 3169 - return -EIO; 3170 - 3171 - ASSERT(atomic_read(&iclog->ic_refcnt) > 0); 3172 - if (!atomic_dec_and_lock(&iclog->ic_refcnt, &log->l_icloglock)) 3173 - return 0; 3174 - 3175 - if (iclog->ic_state & XLOG_STATE_IOERROR) { 3176 - spin_unlock(&log->l_icloglock); 3177 - return -EIO; 3178 - } 3179 - ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE || 3180 - iclog->ic_state == XLOG_STATE_WANT_SYNC); 3181 - 3182 - if (iclog->ic_state == XLOG_STATE_WANT_SYNC) { 3183 - /* update tail before writing to iclog */ 3184 - xfs_lsn_t tail_lsn = xlog_assign_tail_lsn(log->l_mp); 3185 - sync++; 3186 - iclog->ic_state = XLOG_STATE_SYNCING; 3187 - iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); 3188 - xlog_verify_tail_lsn(log, iclog, tail_lsn); 3189 - /* cycle incremented when incrementing curr_block */ 3190 - } 3191 - spin_unlock(&log->l_icloglock); 3192 - 3193 - /* 3194 - * We let the log lock go, so it's possible that we hit a log I/O 3195 - * error or some other SHUTDOWN condition that marks the iclog 3196 - * as XLOG_STATE_IOERROR before the bwrite. However, we know that 3197 - * this iclog has consistent data, so we ignore IOERROR 3198 - * flags after this point. 3199 - */ 3200 - if (sync) 3201 - xlog_sync(log, iclog); 3202 - return 0; 3203 - } /* xlog_state_release_iclog */ 3204 - 3205 - 3206 - /* 3207 3164 * This routine will mark the current iclog in the ring as WANT_SYNC 3208 3165 * and move the current iclog pointer to the next iclog in the ring. 3209 3166 * When this routine is called from xlog_state_get_iclog_space(), the ··· 3242 3307 3243 3308 spin_lock(&log->l_icloglock); 3244 3309 iclog = log->l_iclog; 3245 - if (iclog->ic_state & XLOG_STATE_IOERROR) 3310 + if (iclog->ic_state == XLOG_STATE_IOERROR) 3246 3311 goto out_error; 3247 3312 3248 3313 if (iclog->ic_state == XLOG_STATE_DIRTY || ··· 3272 3337 atomic_inc(&iclog->ic_refcnt); 3273 3338 lsn = be64_to_cpu(iclog->ic_header.h_lsn); 3274 3339 xlog_state_switch_iclogs(log, iclog, 0); 3275 - spin_unlock(&log->l_icloglock); 3276 - 3277 3340 if (xlog_state_release_iclog(log, iclog)) 3278 - return -EIO; 3341 + goto out_error; 3279 3342 3280 - spin_lock(&log->l_icloglock); 3281 3343 if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn || 3282 3344 iclog->ic_state == XLOG_STATE_DIRTY) 3283 3345 goto out_unlock; ··· 3299 3367 if (!(flags & XFS_LOG_SYNC)) 3300 3368 goto out_unlock; 3301 3369 3302 - if (iclog->ic_state & XLOG_STATE_IOERROR) 3370 + if (iclog->ic_state == XLOG_STATE_IOERROR) 3303 3371 goto out_error; 3304 3372 XFS_STATS_INC(mp, xs_log_force_sleep); 3305 3373 xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); 3306 - if (iclog->ic_state & XLOG_STATE_IOERROR) 3374 + if (iclog->ic_state == XLOG_STATE_IOERROR) 3307 3375 return -EIO; 3308 3376 return 0; 3309 3377 ··· 3328 3396 3329 3397 spin_lock(&log->l_icloglock); 3330 3398 iclog = log->l_iclog; 3331 - if (iclog->ic_state & XLOG_STATE_IOERROR) 3399 + if (iclog->ic_state == XLOG_STATE_IOERROR) 3332 3400 goto out_error; 3333 3401 3334 3402 while (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) { ··· 3357 3425 * will go out then. 3358 3426 */ 3359 3427 if (!already_slept && 3360 - (iclog->ic_prev->ic_state & 3361 - (XLOG_STATE_WANT_SYNC | XLOG_STATE_SYNCING))) { 3362 - ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR)); 3363 - 3428 + (iclog->ic_prev->ic_state == XLOG_STATE_WANT_SYNC || 3429 + iclog->ic_prev->ic_state == XLOG_STATE_SYNCING)) { 3364 3430 XFS_STATS_INC(mp, xs_log_force_sleep); 3365 3431 3366 3432 xlog_wait(&iclog->ic_prev->ic_write_wait, ··· 3367 3437 } 3368 3438 atomic_inc(&iclog->ic_refcnt); 3369 3439 xlog_state_switch_iclogs(log, iclog, 0); 3370 - spin_unlock(&log->l_icloglock); 3371 3440 if (xlog_state_release_iclog(log, iclog)) 3372 - return -EIO; 3441 + goto out_error; 3373 3442 if (log_flushed) 3374 3443 *log_flushed = 1; 3375 - spin_lock(&log->l_icloglock); 3376 3444 } 3377 3445 3378 3446 if (!(flags & XFS_LOG_SYNC) || 3379 - (iclog->ic_state & (XLOG_STATE_ACTIVE | XLOG_STATE_DIRTY))) 3447 + (iclog->ic_state == XLOG_STATE_ACTIVE || 3448 + iclog->ic_state == XLOG_STATE_DIRTY)) 3380 3449 goto out_unlock; 3381 3450 3382 - if (iclog->ic_state & XLOG_STATE_IOERROR) 3451 + if (iclog->ic_state == XLOG_STATE_IOERROR) 3383 3452 goto out_error; 3384 3453 3385 3454 XFS_STATS_INC(mp, xs_log_force_sleep); 3386 3455 xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); 3387 - if (iclog->ic_state & XLOG_STATE_IOERROR) 3456 + if (iclog->ic_state == XLOG_STATE_IOERROR) 3388 3457 return -EIO; 3389 3458 return 0; 3390 3459 ··· 3446 3517 if (iclog->ic_state == XLOG_STATE_ACTIVE) { 3447 3518 xlog_state_switch_iclogs(log, iclog, 0); 3448 3519 } else { 3449 - ASSERT(iclog->ic_state & 3450 - (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR)); 3520 + ASSERT(iclog->ic_state == XLOG_STATE_WANT_SYNC || 3521 + iclog->ic_state == XLOG_STATE_IOERROR); 3451 3522 } 3452 3523 } 3453 3524 ··· 3468 3539 { 3469 3540 ASSERT(atomic_read(&ticket->t_ref) > 0); 3470 3541 if (atomic_dec_and_test(&ticket->t_ref)) 3471 - kmem_zone_free(xfs_log_ticket_zone, ticket); 3542 + kmem_cache_free(xfs_log_ticket_zone, ticket); 3472 3543 } 3473 3544 3474 3545 xlog_ticket_t * ··· 3824 3895 xlog_in_core_t *iclog, *ic; 3825 3896 3826 3897 iclog = log->l_iclog; 3827 - if (! (iclog->ic_state & XLOG_STATE_IOERROR)) { 3898 + if (iclog->ic_state != XLOG_STATE_IOERROR) { 3828 3899 /* 3829 3900 * Mark all the incore logs IOERROR. 3830 3901 * From now on, no log flushes will result. ··· 3884 3955 * Somebody could've already done the hard work for us. 3885 3956 * No need to get locks for this. 3886 3957 */ 3887 - if (logerror && log->l_iclog->ic_state & XLOG_STATE_IOERROR) { 3958 + if (logerror && log->l_iclog->ic_state == XLOG_STATE_IOERROR) { 3888 3959 ASSERT(XLOG_FORCED_SHUTDOWN(log)); 3889 3960 return 1; 3890 3961 } ··· 3935 4006 spin_lock(&log->l_cilp->xc_push_lock); 3936 4007 wake_up_all(&log->l_cilp->xc_commit_wait); 3937 4008 spin_unlock(&log->l_cilp->xc_push_lock); 3938 - xlog_state_do_callback(log, true, NULL); 4009 + xlog_state_do_callback(log, true); 3939 4010 3940 - #ifdef XFSERRORDEBUG 3941 - { 3942 - xlog_in_core_t *iclog; 3943 - 3944 - spin_lock(&log->l_icloglock); 3945 - iclog = log->l_iclog; 3946 - do { 3947 - ASSERT(iclog->ic_callback == 0); 3948 - iclog = iclog->ic_next; 3949 - } while (iclog != log->l_iclog); 3950 - spin_unlock(&log->l_icloglock); 3951 - } 3952 - #endif 3953 4011 /* return non-zero if log IOERROR transition had already happened */ 3954 4012 return retval; 3955 4013 }
+3 -3
fs/xfs/xfs_log_cil.c
··· 179 179 180 180 /* 181 181 * We free and allocate here as a realloc would copy 182 - * unecessary data. We don't use kmem_zalloc() for the 182 + * unnecessary data. We don't use kmem_zalloc() for the 183 183 * same reason - we don't need to zero the data area in 184 184 * the buffer, only the log vector header and the iovec 185 185 * storage. ··· 682 682 } 683 683 684 684 685 - /* check for a previously pushed seqeunce */ 685 + /* check for a previously pushed sequence */ 686 686 if (push_seq < cil->xc_ctx->sequence) { 687 687 spin_unlock(&cil->xc_push_lock); 688 688 goto out_skip; ··· 847 847 goto out_abort; 848 848 849 849 spin_lock(&commit_iclog->ic_callback_lock); 850 - if (commit_iclog->ic_state & XLOG_STATE_IOERROR) { 850 + if (commit_iclog->ic_state == XLOG_STATE_IOERROR) { 851 851 spin_unlock(&commit_iclog->ic_callback_lock); 852 852 goto out_abort; 853 853 }
+15 -18
fs/xfs/xfs_log_priv.h
··· 40 40 /* 41 41 * In core log state 42 42 */ 43 - #define XLOG_STATE_ACTIVE 0x0001 /* Current IC log being written to */ 44 - #define XLOG_STATE_WANT_SYNC 0x0002 /* Want to sync this iclog; no more writes */ 45 - #define XLOG_STATE_SYNCING 0x0004 /* This IC log is syncing */ 46 - #define XLOG_STATE_DONE_SYNC 0x0008 /* Done syncing to disk */ 47 - #define XLOG_STATE_DO_CALLBACK \ 48 - 0x0010 /* Process callback functions */ 49 - #define XLOG_STATE_CALLBACK 0x0020 /* Callback functions now */ 50 - #define XLOG_STATE_DIRTY 0x0040 /* Dirty IC log, not ready for ACTIVE status*/ 51 - #define XLOG_STATE_IOERROR 0x0080 /* IO error happened in sync'ing log */ 52 - #define XLOG_STATE_ALL 0x7FFF /* All possible valid flags */ 53 - #define XLOG_STATE_NOTUSED 0x8000 /* This IC log not being used */ 43 + enum xlog_iclog_state { 44 + XLOG_STATE_ACTIVE, /* Current IC log being written to */ 45 + XLOG_STATE_WANT_SYNC, /* Want to sync this iclog; no more writes */ 46 + XLOG_STATE_SYNCING, /* This IC log is syncing */ 47 + XLOG_STATE_DONE_SYNC, /* Done syncing to disk */ 48 + XLOG_STATE_CALLBACK, /* Callback functions now */ 49 + XLOG_STATE_DIRTY, /* Dirty IC log, not ready for ACTIVE status */ 50 + XLOG_STATE_IOERROR, /* IO error happened in sync'ing log */ 51 + }; 54 52 55 53 /* 56 54 * Flags to log ticket ··· 177 179 * - ic_next is the pointer to the next iclog in the ring. 178 180 * - ic_log is a pointer back to the global log structure. 179 181 * - ic_size is the full size of the log buffer, minus the cycle headers. 180 - * - ic_io_size is the size of the currently pending log buffer write, which 181 - * might be smaller than ic_size 182 182 * - ic_offset is the current number of bytes written to in this iclog. 183 183 * - ic_refcnt is bumped when someone is writing to the log. 184 184 * - ic_state is the state of the iclog. ··· 201 205 struct xlog_in_core *ic_prev; 202 206 struct xlog *ic_log; 203 207 u32 ic_size; 204 - u32 ic_io_size; 205 208 u32 ic_offset; 206 - unsigned short ic_state; 209 + enum xlog_iclog_state ic_state; 207 210 char *ic_datap; /* pointer to iclog data */ 208 211 209 212 /* Callback structures need their own cacheline */ ··· 394 399 /* The following field are used for debugging; need to hold icloglock */ 395 400 #ifdef DEBUG 396 401 void *l_iclog_bak[XLOG_MAX_ICLOGS]; 397 - /* log record crc error injection factor */ 398 - uint32_t l_badcrc_factor; 399 402 #endif 400 403 /* log recovery lsn tracking (for buffer submission */ 401 404 xfs_lsn_t l_recovery_lsn; ··· 535 542 * by a spinlock. This matches the semantics of all the wait queues used in the 536 543 * log code. 537 544 */ 538 - static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock) 545 + static inline void 546 + xlog_wait( 547 + struct wait_queue_head *wq, 548 + struct spinlock *lock) 549 + __releases(lock) 539 550 { 540 551 DECLARE_WAITQUEUE(wait, current); 541 552
+77 -71
fs/xfs/xfs_log_recover.c
··· 103 103 * Pass log block 0 since we don't have an addr yet, buffer will be 104 104 * verified on read. 105 105 */ 106 - if (!xlog_verify_bno(log, 0, nbblks)) { 106 + if (XFS_IS_CORRUPT(log->l_mp, !xlog_verify_bno(log, 0, nbblks))) { 107 107 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", 108 108 nbblks); 109 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); 110 109 return NULL; 111 110 } 112 111 ··· 151 152 { 152 153 int error; 153 154 154 - if (!xlog_verify_bno(log, blk_no, nbblks)) { 155 + if (XFS_IS_CORRUPT(log->l_mp, !xlog_verify_bno(log, blk_no, nbblks))) { 155 156 xfs_warn(log->l_mp, 156 157 "Invalid log block/length (0x%llx, 0x%x) for buffer", 157 158 blk_no, nbblks); 158 - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); 159 159 return -EFSCORRUPTED; 160 160 } 161 161 ··· 242 244 * (XLOG_FMT_UNKNOWN). This stops us from trying to recover 243 245 * a dirty log created in IRIX. 244 246 */ 245 - if (unlikely(head->h_fmt != cpu_to_be32(XLOG_FMT))) { 247 + if (XFS_IS_CORRUPT(mp, head->h_fmt != cpu_to_be32(XLOG_FMT))) { 246 248 xfs_warn(mp, 247 249 "dirty log written in incompatible format - can't recover"); 248 250 xlog_header_check_dump(mp, head); 249 - XFS_ERROR_REPORT("xlog_header_check_recover(1)", 250 - XFS_ERRLEVEL_HIGH, mp); 251 251 return -EFSCORRUPTED; 252 - } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { 252 + } 253 + if (XFS_IS_CORRUPT(mp, !uuid_equal(&mp->m_sb.sb_uuid, 254 + &head->h_fs_uuid))) { 253 255 xfs_warn(mp, 254 256 "dirty log entry has mismatched uuid - can't recover"); 255 257 xlog_header_check_dump(mp, head); 256 - XFS_ERROR_REPORT("xlog_header_check_recover(2)", 257 - XFS_ERRLEVEL_HIGH, mp); 258 258 return -EFSCORRUPTED; 259 259 } 260 260 return 0; ··· 275 279 * by IRIX and continue. 276 280 */ 277 281 xfs_warn(mp, "null uuid in log - IRIX style log"); 278 - } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) { 282 + } else if (XFS_IS_CORRUPT(mp, !uuid_equal(&mp->m_sb.sb_uuid, 283 + &head->h_fs_uuid))) { 279 284 xfs_warn(mp, "log has mismatched uuid - can't recover"); 280 285 xlog_header_check_dump(mp, head); 281 - XFS_ERROR_REPORT("xlog_header_check_mount", 282 - XFS_ERRLEVEL_HIGH, mp); 283 286 return -EFSCORRUPTED; 284 287 } 285 288 return 0; ··· 466 471 xfs_warn(log->l_mp, 467 472 "Log inconsistent (didn't find previous header)"); 468 473 ASSERT(0); 469 - error = -EIO; 474 + error = -EFSCORRUPTED; 470 475 goto out; 471 476 } 472 477 ··· 1342 1347 error = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, buffer, 1343 1348 &rhead_blk, &rhead, &wrapped); 1344 1349 if (error < 0) 1345 - return error; 1350 + goto done; 1346 1351 if (!error) { 1347 1352 xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); 1348 - return -EIO; 1353 + error = -EFSCORRUPTED; 1354 + goto done; 1349 1355 } 1350 1356 *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); 1351 1357 ··· 1695 1699 * the distance from the beginning of the log to the 1696 1700 * tail. 1697 1701 */ 1698 - if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) { 1699 - XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)", 1700 - XFS_ERRLEVEL_LOW, log->l_mp); 1702 + if (XFS_IS_CORRUPT(log->l_mp, 1703 + head_block < tail_block || 1704 + head_block >= log->l_logBBsize)) 1701 1705 return -EFSCORRUPTED; 1702 - } 1703 1706 tail_distance = tail_block + (log->l_logBBsize - head_block); 1704 1707 } else { 1705 1708 /* ··· 1706 1711 * so the distance from the head to the tail is just 1707 1712 * the tail block minus the head block. 1708 1713 */ 1709 - if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){ 1710 - XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)", 1711 - XFS_ERRLEVEL_LOW, log->l_mp); 1714 + if (XFS_IS_CORRUPT(log->l_mp, 1715 + head_block >= tail_block || 1716 + head_cycle != tail_cycle + 1)) 1712 1717 return -EFSCORRUPTED; 1713 - } 1714 1718 tail_distance = tail_block - head_block; 1715 1719 } 1716 1720 ··· 2129 2135 */ 2130 2136 logged_nextp = item->ri_buf[item_index].i_addr + 2131 2137 next_unlinked_offset - reg_buf_offset; 2132 - if (unlikely(*logged_nextp == 0)) { 2138 + if (XFS_IS_CORRUPT(mp, *logged_nextp == 0)) { 2133 2139 xfs_alert(mp, 2134 2140 "Bad inode buffer log record (ptr = "PTR_FMT", bp = "PTR_FMT"). " 2135 2141 "Trying to replay bad (0) inode di_next_unlinked field.", 2136 2142 item, bp); 2137 - XFS_ERROR_REPORT("xlog_recover_do_inode_buf", 2138 - XFS_ERRLEVEL_LOW, mp); 2139 2143 return -EFSCORRUPTED; 2140 2144 } 2141 2145 ··· 2568 2576 int bit; 2569 2577 int nbits; 2570 2578 xfs_failaddr_t fa; 2579 + const size_t size_disk_dquot = sizeof(struct xfs_disk_dquot); 2571 2580 2572 2581 trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f); 2573 2582 ··· 2611 2618 "XFS: NULL dquot in %s.", __func__); 2612 2619 goto next; 2613 2620 } 2614 - if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) { 2621 + if (item->ri_buf[i].i_len < size_disk_dquot) { 2615 2622 xfs_alert(mp, 2616 2623 "XFS: dquot too small (%d) in %s.", 2617 2624 item->ri_buf[i].i_len, __func__); ··· 2962 2969 * Make sure the place we're flushing out to really looks 2963 2970 * like an inode! 2964 2971 */ 2965 - if (unlikely(!xfs_verify_magic16(bp, dip->di_magic))) { 2972 + if (XFS_IS_CORRUPT(mp, !xfs_verify_magic16(bp, dip->di_magic))) { 2966 2973 xfs_alert(mp, 2967 2974 "%s: Bad inode magic number, dip = "PTR_FMT", dino bp = "PTR_FMT", ino = %Ld", 2968 2975 __func__, dip, bp, in_f->ilf_ino); 2969 - XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)", 2970 - XFS_ERRLEVEL_LOW, mp); 2971 2976 error = -EFSCORRUPTED; 2972 2977 goto out_release; 2973 2978 } 2974 2979 ldip = item->ri_buf[1].i_addr; 2975 - if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) { 2980 + if (XFS_IS_CORRUPT(mp, ldip->di_magic != XFS_DINODE_MAGIC)) { 2976 2981 xfs_alert(mp, 2977 2982 "%s: Bad inode log record, rec ptr "PTR_FMT", ino %Ld", 2978 2983 __func__, item, in_f->ilf_ino); 2979 - XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)", 2980 - XFS_ERRLEVEL_LOW, mp); 2981 2984 error = -EFSCORRUPTED; 2982 2985 goto out_release; 2983 2986 } ··· 3155 3166 default: 3156 3167 xfs_warn(log->l_mp, "%s: Invalid flag", __func__); 3157 3168 ASSERT(0); 3158 - error = -EIO; 3169 + error = -EFSCORRUPTED; 3159 3170 goto out_release; 3160 3171 } 3161 3172 } ··· 3236 3247 recddq = item->ri_buf[1].i_addr; 3237 3248 if (recddq == NULL) { 3238 3249 xfs_alert(log->l_mp, "NULL dquot in %s.", __func__); 3239 - return -EIO; 3250 + return -EFSCORRUPTED; 3240 3251 } 3241 - if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) { 3252 + if (item->ri_buf[1].i_len < sizeof(struct xfs_disk_dquot)) { 3242 3253 xfs_alert(log->l_mp, "dquot too small (%d) in %s.", 3243 3254 item->ri_buf[1].i_len, __func__); 3244 - return -EIO; 3255 + return -EFSCORRUPTED; 3245 3256 } 3246 3257 3247 3258 /* ··· 3268 3279 if (fa) { 3269 3280 xfs_alert(mp, "corrupt dquot ID 0x%x in log at %pS", 3270 3281 dq_f->qlf_id, fa); 3271 - return -EIO; 3282 + return -EFSCORRUPTED; 3272 3283 } 3273 3284 ASSERT(dq_f->qlf_len == 1); 3274 3285 ··· 3526 3537 memcpy(dst_cui_fmt, src_cui_fmt, len); 3527 3538 return 0; 3528 3539 } 3540 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); 3529 3541 return -EFSCORRUPTED; 3530 3542 } 3531 3543 ··· 3591 3601 struct xfs_ail *ailp = log->l_ailp; 3592 3602 3593 3603 cud_formatp = item->ri_buf[0].i_addr; 3594 - if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) 3604 + if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) { 3605 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); 3595 3606 return -EFSCORRUPTED; 3607 + } 3596 3608 cui_id = cud_formatp->cud_cui_id; 3597 3609 3598 3610 /* ··· 3646 3654 memcpy(dst_bui_fmt, src_bui_fmt, len); 3647 3655 return 0; 3648 3656 } 3657 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); 3649 3658 return -EFSCORRUPTED; 3650 3659 } 3651 3660 ··· 3670 3677 3671 3678 bui_formatp = item->ri_buf[0].i_addr; 3672 3679 3673 - if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) 3680 + if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) { 3681 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); 3674 3682 return -EFSCORRUPTED; 3683 + } 3675 3684 buip = xfs_bui_init(mp); 3676 3685 error = xfs_bui_copy_format(&item->ri_buf[0], &buip->bui_format); 3677 3686 if (error) { ··· 3715 3720 struct xfs_ail *ailp = log->l_ailp; 3716 3721 3717 3722 bud_formatp = item->ri_buf[0].i_addr; 3718 - if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format)) 3723 + if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format)) { 3724 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); 3719 3725 return -EFSCORRUPTED; 3726 + } 3720 3727 bui_id = bud_formatp->bud_bui_id; 3721 3728 3722 3729 /* ··· 4015 4018 xfs_warn(log->l_mp, "%s: invalid item type (%d)", 4016 4019 __func__, ITEM_TYPE(item)); 4017 4020 ASSERT(0); 4018 - return -EIO; 4021 + return -EFSCORRUPTED; 4019 4022 } 4020 4023 } 4021 4024 ··· 4063 4066 xfs_warn(log->l_mp, "%s: invalid item type (%d)", 4064 4067 __func__, ITEM_TYPE(item)); 4065 4068 ASSERT(0); 4066 - return -EIO; 4069 + return -EFSCORRUPTED; 4067 4070 } 4068 4071 } 4069 4072 ··· 4184 4187 ASSERT(len <= sizeof(struct xfs_trans_header)); 4185 4188 if (len > sizeof(struct xfs_trans_header)) { 4186 4189 xfs_warn(log->l_mp, "%s: bad header length", __func__); 4187 - return -EIO; 4190 + return -EFSCORRUPTED; 4188 4191 } 4189 4192 4190 4193 xlog_recover_add_item(&trans->r_itemq); ··· 4240 4243 xfs_warn(log->l_mp, "%s: bad header magic number", 4241 4244 __func__); 4242 4245 ASSERT(0); 4243 - return -EIO; 4246 + return -EFSCORRUPTED; 4244 4247 } 4245 4248 4246 4249 if (len > sizeof(struct xfs_trans_header)) { 4247 4250 xfs_warn(log->l_mp, "%s: bad header length", __func__); 4248 4251 ASSERT(0); 4249 - return -EIO; 4252 + return -EFSCORRUPTED; 4250 4253 } 4251 4254 4252 4255 /* ··· 4282 4285 in_f->ilf_size); 4283 4286 ASSERT(0); 4284 4287 kmem_free(ptr); 4285 - return -EIO; 4288 + return -EFSCORRUPTED; 4286 4289 } 4287 4290 4288 4291 item->ri_total = in_f->ilf_size; ··· 4290 4293 kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), 4291 4294 0); 4292 4295 } 4293 - ASSERT(item->ri_total > item->ri_cnt); 4296 + 4297 + if (item->ri_total <= item->ri_cnt) { 4298 + xfs_warn(log->l_mp, 4299 + "log item region count (%d) overflowed size (%d)", 4300 + item->ri_cnt, item->ri_total); 4301 + ASSERT(0); 4302 + kmem_free(ptr); 4303 + return -EFSCORRUPTED; 4304 + } 4305 + 4294 4306 /* Description region is ri_buf[0] */ 4295 4307 item->ri_buf[item->ri_cnt].i_addr = ptr; 4296 4308 item->ri_buf[item->ri_cnt].i_len = len; ··· 4386 4380 default: 4387 4381 xfs_warn(log->l_mp, "%s: bad flag 0x%x", __func__, flags); 4388 4382 ASSERT(0); 4389 - error = -EIO; 4383 + error = -EFSCORRUPTED; 4390 4384 break; 4391 4385 } 4392 4386 if (error || freeit) ··· 4466 4460 xfs_warn(log->l_mp, "%s: bad clientid 0x%x", 4467 4461 __func__, ohead->oh_clientid); 4468 4462 ASSERT(0); 4469 - return -EIO; 4463 + return -EFSCORRUPTED; 4470 4464 } 4471 4465 4472 4466 /* ··· 4476 4470 if (dp + len > end) { 4477 4471 xfs_warn(log->l_mp, "%s: bad length 0x%x", __func__, len); 4478 4472 WARN_ON(1); 4479 - return -EIO; 4473 + return -EFSCORRUPTED; 4480 4474 } 4481 4475 4482 4476 trans = xlog_recover_ophdr_to_trans(rhash, rhead, ohead); ··· 5178 5172 * If the filesystem is CRC enabled, this mismatch becomes a 5179 5173 * fatal log corruption failure. 5180 5174 */ 5181 - if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) 5175 + if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) { 5176 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp); 5182 5177 return -EFSCORRUPTED; 5178 + } 5183 5179 } 5184 5180 5185 5181 xlog_unpack_data(rhead, dp, log); ··· 5198 5190 { 5199 5191 int hlen; 5200 5192 5201 - if (unlikely(rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) { 5202 - XFS_ERROR_REPORT("xlog_valid_rec_header(1)", 5203 - XFS_ERRLEVEL_LOW, log->l_mp); 5193 + if (XFS_IS_CORRUPT(log->l_mp, 5194 + rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) 5204 5195 return -EFSCORRUPTED; 5205 - } 5206 - if (unlikely( 5207 - (!rhead->h_version || 5208 - (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { 5196 + if (XFS_IS_CORRUPT(log->l_mp, 5197 + (!rhead->h_version || 5198 + (be32_to_cpu(rhead->h_version) & 5199 + (~XLOG_VERSION_OKBITS))))) { 5209 5200 xfs_warn(log->l_mp, "%s: unrecognised log version (%d).", 5210 5201 __func__, be32_to_cpu(rhead->h_version)); 5211 - return -EIO; 5202 + return -EFSCORRUPTED; 5212 5203 } 5213 5204 5214 5205 /* LR body must have data or it wouldn't have been written */ 5215 5206 hlen = be32_to_cpu(rhead->h_len); 5216 - if (unlikely( hlen <= 0 || hlen > INT_MAX )) { 5217 - XFS_ERROR_REPORT("xlog_valid_rec_header(2)", 5218 - XFS_ERRLEVEL_LOW, log->l_mp); 5207 + if (XFS_IS_CORRUPT(log->l_mp, hlen <= 0 || hlen > INT_MAX)) 5219 5208 return -EFSCORRUPTED; 5220 - } 5221 - if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) { 5222 - XFS_ERROR_REPORT("xlog_valid_rec_header(3)", 5223 - XFS_ERRLEVEL_LOW, log->l_mp); 5209 + if (XFS_IS_CORRUPT(log->l_mp, 5210 + blkno > log->l_logBBsize || blkno > INT_MAX)) 5224 5211 return -EFSCORRUPTED; 5225 - } 5226 5212 return 0; 5227 5213 } 5228 5214 ··· 5298 5296 "invalid iclog size (%d bytes), using lsunit (%d bytes)", 5299 5297 h_size, log->l_mp->m_logbsize); 5300 5298 h_size = log->l_mp->m_logbsize; 5301 - } else 5302 - return -EFSCORRUPTED; 5299 + } else { 5300 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, 5301 + log->l_mp); 5302 + error = -EFSCORRUPTED; 5303 + goto bread_err1; 5304 + } 5303 5305 } 5304 5306 5305 5307 if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&
+15 -7
fs/xfs/xfs_message.c
··· 20 20 const struct xfs_mount *mp, 21 21 struct va_format *vaf) 22 22 { 23 - if (mp && mp->m_fsname) { 24 - printk("%sXFS (%s): %pV\n", level, mp->m_fsname, vaf); 23 + if (mp && mp->m_super) { 24 + printk("%sXFS (%s): %pV\n", level, mp->m_super->s_id, vaf); 25 25 return; 26 26 } 27 27 printk("%sXFS: %pV\n", level, vaf); ··· 86 86 } 87 87 88 88 void 89 - asswarn(char *expr, char *file, int line) 89 + asswarn( 90 + struct xfs_mount *mp, 91 + char *expr, 92 + char *file, 93 + int line) 90 94 { 91 - xfs_warn(NULL, "Assertion failed: %s, file: %s, line: %d", 95 + xfs_warn(mp, "Assertion failed: %s, file: %s, line: %d", 92 96 expr, file, line); 93 97 WARN_ON(1); 94 98 } 95 99 96 100 void 97 - assfail(char *expr, char *file, int line) 101 + assfail( 102 + struct xfs_mount *mp, 103 + char *expr, 104 + char *file, 105 + int line) 98 106 { 99 - xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d", 107 + xfs_emerg(mp, "Assertion failed: %s, file: %s, line: %d", 100 108 expr, file, line); 101 109 if (xfs_globals.bug_on_assert) 102 110 BUG(); ··· 113 105 } 114 106 115 107 void 116 - xfs_hex_dump(void *p, int length) 108 + xfs_hex_dump(const void *p, int length) 117 109 { 118 110 print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_OFFSET, 16, 1, p, length, 1); 119 111 }
+3 -3
fs/xfs/xfs_message.h
··· 57 57 #define xfs_debug_ratelimited(dev, fmt, ...) \ 58 58 xfs_printk_ratelimited(xfs_debug, dev, fmt, ##__VA_ARGS__) 59 59 60 - extern void assfail(char *expr, char *f, int l); 61 - extern void asswarn(char *expr, char *f, int l); 60 + void assfail(struct xfs_mount *mp, char *expr, char *f, int l); 61 + void asswarn(struct xfs_mount *mp, char *expr, char *f, int l); 62 62 63 - extern void xfs_hex_dump(void *p, int length); 63 + extern void xfs_hex_dump(const void *p, int length); 64 64 65 65 #endif /* __XFS_MESSAGE_H */
+10 -48
fs/xfs/xfs_mount.c
··· 426 426 } 427 427 428 428 /* 429 - * Set the default minimum read and write sizes unless 430 - * already specified in a mount option. 431 - * We use smaller I/O sizes when the file system 432 - * is being used for NFS service (wsync mount option). 433 - */ 434 - STATIC void 435 - xfs_set_rw_sizes(xfs_mount_t *mp) 436 - { 437 - xfs_sb_t *sbp = &(mp->m_sb); 438 - int readio_log, writeio_log; 439 - 440 - if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) { 441 - if (mp->m_flags & XFS_MOUNT_WSYNC) { 442 - readio_log = XFS_WSYNC_READIO_LOG; 443 - writeio_log = XFS_WSYNC_WRITEIO_LOG; 444 - } else { 445 - readio_log = XFS_READIO_LOG_LARGE; 446 - writeio_log = XFS_WRITEIO_LOG_LARGE; 447 - } 448 - } else { 449 - readio_log = mp->m_readio_log; 450 - writeio_log = mp->m_writeio_log; 451 - } 452 - 453 - if (sbp->sb_blocklog > readio_log) { 454 - mp->m_readio_log = sbp->sb_blocklog; 455 - } else { 456 - mp->m_readio_log = readio_log; 457 - } 458 - mp->m_readio_blocks = 1 << (mp->m_readio_log - sbp->sb_blocklog); 459 - if (sbp->sb_blocklog > writeio_log) { 460 - mp->m_writeio_log = sbp->sb_blocklog; 461 - } else { 462 - mp->m_writeio_log = writeio_log; 463 - } 464 - mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); 465 - } 466 - 467 - /* 468 429 * precalculate the low space thresholds for dynamic speculative preallocation. 469 430 */ 470 431 void ··· 667 706 /* enable fail_at_unmount as default */ 668 707 mp->m_fail_unmount = true; 669 708 670 - error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, NULL, mp->m_fsname); 709 + error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, 710 + NULL, mp->m_super->s_id); 671 711 if (error) 672 712 goto out; 673 713 ··· 690 728 goto out_remove_errortag; 691 729 692 730 /* 693 - * Set the minimum read and write sizes 731 + * Update the preferred write size based on the information from the 732 + * on-disk superblock. 694 733 */ 695 - xfs_set_rw_sizes(mp); 734 + mp->m_allocsize_log = 735 + max_t(uint32_t, sbp->sb_blocklog, mp->m_allocsize_log); 736 + mp->m_allocsize_blocks = 1U << (mp->m_allocsize_log - sbp->sb_blocklog); 696 737 697 738 /* set the low space thresholds for dynamic preallocation */ 698 739 xfs_set_low_space_thresholds(mp); ··· 761 796 goto out_free_dir; 762 797 } 763 798 764 - if (!sbp->sb_logblocks) { 799 + if (XFS_IS_CORRUPT(mp, !sbp->sb_logblocks)) { 765 800 xfs_warn(mp, "no log defined"); 766 - XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp); 767 801 error = -EFSCORRUPTED; 768 802 goto out_free_perag; 769 803 } ··· 800 836 801 837 ASSERT(rip != NULL); 802 838 803 - if (unlikely(!S_ISDIR(VFS_I(rip)->i_mode))) { 839 + if (XFS_IS_CORRUPT(mp, !S_ISDIR(VFS_I(rip)->i_mode))) { 804 840 xfs_warn(mp, "corrupted root inode %llu: not a directory", 805 841 (unsigned long long)rip->i_ino); 806 842 xfs_iunlock(rip, XFS_ILOCK_EXCL); 807 - XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, 808 - mp); 809 843 error = -EFSCORRUPTED; 810 844 goto out_rele_rip; 811 845 } ··· 1239 1277 printk_once(KERN_WARNING 1240 1278 "Filesystem \"%s\": reserve blocks depleted! " 1241 1279 "Consider increasing reserve pool size.", 1242 - mp->m_fsname); 1280 + mp->m_super->s_id); 1243 1281 fdblocks_enospc: 1244 1282 spin_unlock(&mp->m_sb_lock); 1245 1283 return -ENOSPC;
+4 -53
fs/xfs/xfs_mount.h
··· 9 9 struct xlog; 10 10 struct xfs_inode; 11 11 struct xfs_mru_cache; 12 - struct xfs_nameops; 13 12 struct xfs_ail; 14 13 struct xfs_quotainfo; 15 - struct xfs_dir_ops; 16 14 struct xfs_da_geometry; 17 15 18 16 /* dynamic preallocation free space thresholds, 5% down to 1% */ ··· 57 59 58 60 typedef struct xfs_mount { 59 61 struct super_block *m_super; 60 - xfs_tid_t m_tid; /* next unused tid for fs */ 61 62 62 63 /* 63 64 * Bitsets of per-fs metadata that have been checked and/or are sick. ··· 86 89 struct percpu_counter m_delalloc_blks; 87 90 88 91 struct xfs_buf *m_sb_bp; /* buffer for superblock */ 89 - char *m_fsname; /* filesystem name */ 90 - int m_fsname_len; /* strlen of fs name */ 91 92 char *m_rtname; /* realtime device name */ 92 93 char *m_logname; /* external log device name */ 93 94 int m_bsize; /* fs logical block size */ ··· 93 98 xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ 94 99 spinlock_t m_agirotor_lock;/* .. and lock protecting it */ 95 100 xfs_agnumber_t m_maxagi; /* highest inode alloc group */ 96 - uint m_readio_log; /* min read size log bytes */ 97 - uint m_readio_blocks; /* min read size blocks */ 98 - uint m_writeio_log; /* min write size log bytes */ 99 - uint m_writeio_blocks; /* min write size blocks */ 101 + uint m_allocsize_log;/* min write size log bytes */ 102 + uint m_allocsize_blocks; /* min write size blocks */ 100 103 struct xfs_da_geometry *m_dir_geo; /* directory block geometry */ 101 104 struct xfs_da_geometry *m_attr_geo; /* attribute block geometry */ 102 105 struct xlog *m_log; /* log specific stuff */ ··· 152 159 int m_dalign; /* stripe unit */ 153 160 int m_swidth; /* stripe width */ 154 161 uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ 155 - const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ 156 - const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */ 157 - const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */ 158 - uint m_chsize; /* size of next field */ 159 162 atomic_t m_active_trans; /* number trans frozen */ 160 163 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ 161 164 struct delayed_work m_reclaim_work; /* background inode reclaim */ ··· 218 229 #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ 219 230 #define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ 220 231 #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ 221 - #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ 232 + #define XFS_MOUNT_ALLOCSIZE (1ULL << 12) /* specified allocation size */ 222 233 #define XFS_MOUNT_SMALL_INUMS (1ULL << 14) /* user wants 32bit inodes */ 223 234 #define XFS_MOUNT_32BITINODES (1ULL << 15) /* inode32 allocator active */ 224 235 #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ ··· 227 238 * allocation */ 228 239 #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ 229 240 #define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ 230 - #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred 241 + #define XFS_MOUNT_LARGEIO (1ULL << 22) /* report large preferred 231 242 * I/O size in stat() */ 232 243 #define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams 233 244 allocator */ ··· 235 246 236 247 #define XFS_MOUNT_DAX (1ULL << 62) /* TEST ONLY! */ 237 248 238 - 239 - /* 240 - * Default minimum read and write sizes. 241 - */ 242 - #define XFS_READIO_LOG_LARGE 16 243 - #define XFS_WRITEIO_LOG_LARGE 16 244 - 245 249 /* 246 250 * Max and min values for mount-option defined I/O 247 251 * preallocation sizes. 248 252 */ 249 253 #define XFS_MAX_IO_LOG 30 /* 1G */ 250 254 #define XFS_MIN_IO_LOG PAGE_SHIFT 251 - 252 - /* 253 - * Synchronous read and write sizes. This should be 254 - * better for NFSv2 wsync filesystems. 255 - */ 256 - #define XFS_WSYNC_READIO_LOG 15 /* 32k */ 257 - #define XFS_WSYNC_WRITEIO_LOG 14 /* 16k */ 258 - 259 - /* 260 - * Allow large block sizes to be reported to userspace programs if the 261 - * "largeio" mount option is used. 262 - * 263 - * If compatibility mode is specified, simply return the basic unit of caching 264 - * so that we don't get inefficient read/modify/write I/O from user apps. 265 - * Otherwise.... 266 - * 267 - * If the underlying volume is a stripe, then return the stripe width in bytes 268 - * as the recommended I/O size. It is not a stripe and we've set a default 269 - * buffered I/O size, return that, otherwise return the compat default. 270 - */ 271 - static inline unsigned long 272 - xfs_preferred_iosize(xfs_mount_t *mp) 273 - { 274 - if (mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE) 275 - return PAGE_SIZE; 276 - return (mp->m_swidth ? 277 - (mp->m_swidth << mp->m_sb.sb_blocklog) : 278 - ((mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) ? 279 - (1 << (int)max(mp->m_readio_log, mp->m_writeio_log)) : 280 - PAGE_SIZE)); 281 - } 282 255 283 256 #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ 284 257 ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN)
+25 -29
fs/xfs/xfs_pnfs.c
··· 12 12 #include "xfs_trans.h" 13 13 #include "xfs_bmap.h" 14 14 #include "xfs_iomap.h" 15 + #include "xfs_pnfs.h" 15 16 16 17 /* 17 18 * Ensure that we do not have any outstanding pNFS layouts that can be used by ··· 60 59 61 60 printk_once(KERN_NOTICE 62 61 "XFS (%s): using experimental pNFS feature, use at your own risk!\n", 63 - mp->m_fsname); 62 + mp->m_super->s_id); 64 63 65 64 if (*len < sizeof(uuid_t)) 66 65 return -EINVAL; ··· 143 142 lock_flags = xfs_ilock_data_map_shared(ip); 144 143 error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, 145 144 &imap, &nimaps, bmapi_flags); 146 - xfs_iunlock(ip, lock_flags); 147 145 148 - if (error) 149 - goto out_unlock; 146 + ASSERT(!nimaps || imap.br_startblock != DELAYSTARTBLOCK); 150 147 151 - if (write) { 152 - enum xfs_prealloc_flags flags = 0; 148 + if (!error && write && 149 + (!nimaps || imap.br_startblock == HOLESTARTBLOCK)) { 150 + if (offset + length > XFS_ISIZE(ip)) 151 + end_fsb = xfs_iomap_eof_align_last_fsb(ip, end_fsb); 152 + else if (nimaps && imap.br_startblock == HOLESTARTBLOCK) 153 + end_fsb = min(end_fsb, imap.br_startoff + 154 + imap.br_blockcount); 155 + xfs_iunlock(ip, lock_flags); 153 156 154 - ASSERT(imap.br_startblock != DELAYSTARTBLOCK); 155 - 156 - if (!nimaps || imap.br_startblock == HOLESTARTBLOCK) { 157 - /* 158 - * xfs_iomap_write_direct() expects to take ownership of 159 - * the shared ilock. 160 - */ 161 - xfs_ilock(ip, XFS_ILOCK_SHARED); 162 - error = xfs_iomap_write_direct(ip, offset, length, 163 - &imap, nimaps); 164 - if (error) 165 - goto out_unlock; 166 - 167 - /* 168 - * Ensure the next transaction is committed 169 - * synchronously so that the blocks allocated and 170 - * handed out to the client are guaranteed to be 171 - * present even after a server crash. 172 - */ 173 - flags |= XFS_PREALLOC_SET | XFS_PREALLOC_SYNC; 174 - } 175 - 176 - error = xfs_update_prealloc_flags(ip, flags); 157 + error = xfs_iomap_write_direct(ip, offset_fsb, 158 + end_fsb - offset_fsb, &imap); 177 159 if (error) 178 160 goto out_unlock; 161 + 162 + /* 163 + * Ensure the next transaction is committed synchronously so 164 + * that the blocks allocated and handed out to the client are 165 + * guaranteed to be present even after a server crash. 166 + */ 167 + error = xfs_update_prealloc_flags(ip, 168 + XFS_PREALLOC_SET | XFS_PREALLOC_SYNC); 169 + if (error) 170 + goto out_unlock; 171 + } else { 172 + xfs_iunlock(ip, lock_flags); 179 173 } 180 174 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 181 175
+36 -31
fs/xfs/xfs_qm.c
··· 22 22 #include "xfs_qm.h" 23 23 #include "xfs_trace.h" 24 24 #include "xfs_icache.h" 25 + #include "xfs_error.h" 25 26 26 27 /* 27 28 * The global quota manager. There is only one of these for the entire ··· 30 29 * quota functionality, including maintaining the freelist and hash 31 30 * tables of dquots. 32 31 */ 33 - STATIC int xfs_qm_init_quotainos(xfs_mount_t *); 34 - STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); 32 + STATIC int xfs_qm_init_quotainos(struct xfs_mount *mp); 33 + STATIC int xfs_qm_init_quotainfo(struct xfs_mount *mp); 35 34 36 - STATIC void xfs_qm_destroy_quotainos(xfs_quotainfo_t *qi); 35 + STATIC void xfs_qm_destroy_quotainos(struct xfs_quotainfo *qi); 37 36 STATIC void xfs_qm_dqfree_one(struct xfs_dquot *dqp); 38 37 /* 39 38 * We use the batch lookup interface to iterate over the dquots as it ··· 244 243 245 244 STATIC int 246 245 xfs_qm_dqattach_one( 247 - xfs_inode_t *ip, 248 - xfs_dqid_t id, 249 - uint type, 250 - bool doalloc, 251 - xfs_dquot_t **IO_idqpp) 246 + struct xfs_inode *ip, 247 + xfs_dqid_t id, 248 + uint type, 249 + bool doalloc, 250 + struct xfs_dquot **IO_idqpp) 252 251 { 253 - xfs_dquot_t *dqp; 254 - int error; 252 + struct xfs_dquot *dqp; 253 + int error; 255 254 256 255 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 257 256 error = 0; ··· 342 341 } 343 342 344 343 if (XFS_IS_PQUOTA_ON(mp) && !ip->i_pdquot) { 345 - error = xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ, 344 + error = xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, 346 345 doalloc, &ip->i_pdquot); 347 346 if (error) 348 347 goto done; ··· 540 539 541 540 STATIC void 542 541 xfs_qm_set_defquota( 543 - xfs_mount_t *mp, 544 - uint type, 545 - xfs_quotainfo_t *qinf) 542 + struct xfs_mount *mp, 543 + uint type, 544 + struct xfs_quotainfo *qinf) 546 545 { 547 - xfs_dquot_t *dqp; 548 - struct xfs_def_quota *defq; 546 + struct xfs_dquot *dqp; 547 + struct xfs_def_quota *defq; 549 548 struct xfs_disk_dquot *ddqp; 550 549 int error; 551 550 ··· 643 642 644 643 ASSERT(XFS_IS_QUOTA_RUNNING(mp)); 645 644 646 - qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), 0); 645 + qinf = mp->m_quotainfo = kmem_zalloc(sizeof(struct xfs_quotainfo), 0); 647 646 648 647 error = list_lru_init(&qinf->qi_lru); 649 648 if (error) ··· 710 709 */ 711 710 void 712 711 xfs_qm_destroy_quotainfo( 713 - xfs_mount_t *mp) 712 + struct xfs_mount *mp) 714 713 { 715 - xfs_quotainfo_t *qi; 714 + struct xfs_quotainfo *qi; 716 715 717 716 qi = mp->m_quotainfo; 718 717 ASSERT(qi != NULL); ··· 755 754 if ((flags & XFS_QMOPT_PQUOTA) && 756 755 (mp->m_sb.sb_gquotino != NULLFSINO)) { 757 756 ino = mp->m_sb.sb_gquotino; 758 - ASSERT(mp->m_sb.sb_pquotino == NULLFSINO); 757 + if (XFS_IS_CORRUPT(mp, 758 + mp->m_sb.sb_pquotino != NULLFSINO)) 759 + return -EFSCORRUPTED; 759 760 } else if ((flags & XFS_QMOPT_GQUOTA) && 760 761 (mp->m_sb.sb_pquotino != NULLFSINO)) { 761 762 ino = mp->m_sb.sb_pquotino; 762 - ASSERT(mp->m_sb.sb_gquotino == NULLFSINO); 763 + if (XFS_IS_CORRUPT(mp, 764 + mp->m_sb.sb_gquotino != NULLFSINO)) 765 + return -EFSCORRUPTED; 763 766 } 764 767 if (ino != NULLFSINO) { 765 768 error = xfs_iget(mp, NULL, ino, 0, 0, ip); ··· 1564 1559 1565 1560 STATIC void 1566 1561 xfs_qm_destroy_quotainos( 1567 - xfs_quotainfo_t *qi) 1562 + struct xfs_quotainfo *qi) 1568 1563 { 1569 1564 if (qi->qi_uquotaip) { 1570 1565 xfs_irele(qi->qi_uquotaip); ··· 1698 1693 } 1699 1694 } 1700 1695 if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) { 1701 - if (xfs_get_projid(ip) != prid) { 1696 + if (ip->i_d.di_projid != prid) { 1702 1697 xfs_iunlock(ip, lockflags); 1703 1698 error = xfs_qm_dqget(mp, (xfs_dqid_t)prid, XFS_DQ_PROJ, 1704 1699 true, &pq); ··· 1742 1737 * Actually transfer ownership, and do dquot modifications. 1743 1738 * These were already reserved. 1744 1739 */ 1745 - xfs_dquot_t * 1740 + struct xfs_dquot * 1746 1741 xfs_qm_vop_chown( 1747 - xfs_trans_t *tp, 1748 - xfs_inode_t *ip, 1749 - xfs_dquot_t **IO_olddq, 1750 - xfs_dquot_t *newdq) 1742 + struct xfs_trans *tp, 1743 + struct xfs_inode *ip, 1744 + struct xfs_dquot **IO_olddq, 1745 + struct xfs_dquot *newdq) 1751 1746 { 1752 - xfs_dquot_t *prevdq; 1747 + struct xfs_dquot *prevdq; 1753 1748 uint bfield = XFS_IS_REALTIME_INODE(ip) ? 1754 1749 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; 1755 1750 ··· 1832 1827 } 1833 1828 1834 1829 if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp && 1835 - xfs_get_projid(ip) != be32_to_cpu(pdqp->q_core.d_id)) { 1830 + ip->i_d.di_projid != be32_to_cpu(pdqp->q_core.d_id)) { 1836 1831 prjflags = XFS_QMOPT_ENOSPC; 1837 1832 pdq_delblks = pdqp; 1838 1833 if (delblks) { ··· 1933 1928 } 1934 1929 if (pdqp && XFS_IS_PQUOTA_ON(mp)) { 1935 1930 ASSERT(ip->i_pdquot == NULL); 1936 - ASSERT(xfs_get_projid(ip) == be32_to_cpu(pdqp->q_core.d_id)); 1931 + ASSERT(ip->i_d.di_projid == be32_to_cpu(pdqp->q_core.d_id)); 1937 1932 1938 1933 ip->i_pdquot = xfs_qm_dqhold(pdqp); 1939 1934 xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1);
+3 -3
fs/xfs/xfs_qm.h
··· 54 54 * Various quota information for individual filesystems. 55 55 * The mount structure keeps a pointer to this. 56 56 */ 57 - typedef struct xfs_quotainfo { 57 + struct xfs_quotainfo { 58 58 struct radix_tree_root qi_uquota_tree; 59 59 struct radix_tree_root qi_gquota_tree; 60 60 struct radix_tree_root qi_pquota_tree; ··· 76 76 struct xfs_def_quota qi_usr_default; 77 77 struct xfs_def_quota qi_grp_default; 78 78 struct xfs_def_quota qi_prj_default; 79 - struct shrinker qi_shrinker; 80 - } xfs_quotainfo_t; 79 + struct shrinker qi_shrinker; 80 + }; 81 81 82 82 static inline struct radix_tree_root * 83 83 xfs_dquot_tree(
+4 -4
fs/xfs/xfs_qm_bhv.c
··· 54 54 */ 55 55 void 56 56 xfs_qm_statvfs( 57 - xfs_inode_t *ip, 57 + struct xfs_inode *ip, 58 58 struct kstatfs *statp) 59 59 { 60 - xfs_mount_t *mp = ip->i_mount; 61 - xfs_dquot_t *dqp; 60 + struct xfs_mount *mp = ip->i_mount; 61 + struct xfs_dquot *dqp; 62 62 63 - if (!xfs_qm_dqget(mp, xfs_get_projid(ip), XFS_DQ_PROJ, false, &dqp)) { 63 + if (!xfs_qm_dqget(mp, ip->i_d.di_projid, XFS_DQ_PROJ, false, &dqp)) { 64 64 xfs_fill_statvfs_from_dquot(statp, dqp); 65 65 xfs_qm_dqput(dqp); 66 66 }
+67 -72
fs/xfs/xfs_qm_syscalls.c
··· 19 19 #include "xfs_qm.h" 20 20 #include "xfs_icache.h" 21 21 22 - STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); 23 - STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, 24 - uint); 22 + STATIC int 23 + xfs_qm_log_quotaoff( 24 + struct xfs_mount *mp, 25 + struct xfs_qoff_logitem **qoffstartp, 26 + uint flags) 27 + { 28 + struct xfs_trans *tp; 29 + int error; 30 + struct xfs_qoff_logitem *qoffi; 31 + 32 + *qoffstartp = NULL; 33 + 34 + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp); 35 + if (error) 36 + goto out; 37 + 38 + qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); 39 + xfs_trans_log_quotaoff_item(tp, qoffi); 40 + 41 + spin_lock(&mp->m_sb_lock); 42 + mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 43 + spin_unlock(&mp->m_sb_lock); 44 + 45 + xfs_log_sb(tp); 46 + 47 + /* 48 + * We have to make sure that the transaction is secure on disk before we 49 + * return and actually stop quota accounting. So, make it synchronous. 50 + * We don't care about quotoff's performance. 51 + */ 52 + xfs_trans_set_sync(tp); 53 + error = xfs_trans_commit(tp); 54 + if (error) 55 + goto out; 56 + 57 + *qoffstartp = qoffi; 58 + out: 59 + return error; 60 + } 61 + 62 + STATIC int 63 + xfs_qm_log_quotaoff_end( 64 + struct xfs_mount *mp, 65 + struct xfs_qoff_logitem *startqoff, 66 + uint flags) 67 + { 68 + struct xfs_trans *tp; 69 + int error; 70 + struct xfs_qoff_logitem *qoffi; 71 + 72 + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp); 73 + if (error) 74 + return error; 75 + 76 + qoffi = xfs_trans_get_qoff_item(tp, startqoff, 77 + flags & XFS_ALL_QUOTA_ACCT); 78 + xfs_trans_log_quotaoff_item(tp, qoffi); 79 + 80 + /* 81 + * We have to make sure that the transaction is secure on disk before we 82 + * return and actually stop quota accounting. So, make it synchronous. 83 + * We don't care about quotoff's performance. 84 + */ 85 + xfs_trans_set_sync(tp); 86 + return xfs_trans_commit(tp); 87 + } 25 88 26 89 /* 27 90 * Turn off quota accounting and/or enforcement for all udquots and/or ··· 103 40 uint dqtype; 104 41 int error; 105 42 uint inactivate_flags; 106 - xfs_qoff_logitem_t *qoffstart; 43 + struct xfs_qoff_logitem *qoffstart; 107 44 108 45 /* 109 46 * No file system can have quotas enabled on disk but not in core. ··· 598 535 xfs_qm_dqrele(dqp); 599 536 out_unlock: 600 537 mutex_unlock(&q->qi_quotaofflock); 601 - return error; 602 - } 603 - 604 - STATIC int 605 - xfs_qm_log_quotaoff_end( 606 - xfs_mount_t *mp, 607 - xfs_qoff_logitem_t *startqoff, 608 - uint flags) 609 - { 610 - xfs_trans_t *tp; 611 - int error; 612 - xfs_qoff_logitem_t *qoffi; 613 - 614 - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp); 615 - if (error) 616 - return error; 617 - 618 - qoffi = xfs_trans_get_qoff_item(tp, startqoff, 619 - flags & XFS_ALL_QUOTA_ACCT); 620 - xfs_trans_log_quotaoff_item(tp, qoffi); 621 - 622 - /* 623 - * We have to make sure that the transaction is secure on disk before we 624 - * return and actually stop quota accounting. So, make it synchronous. 625 - * We don't care about quotoff's performance. 626 - */ 627 - xfs_trans_set_sync(tp); 628 - return xfs_trans_commit(tp); 629 - } 630 - 631 - 632 - STATIC int 633 - xfs_qm_log_quotaoff( 634 - xfs_mount_t *mp, 635 - xfs_qoff_logitem_t **qoffstartp, 636 - uint flags) 637 - { 638 - xfs_trans_t *tp; 639 - int error; 640 - xfs_qoff_logitem_t *qoffi; 641 - 642 - *qoffstartp = NULL; 643 - 644 - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp); 645 - if (error) 646 - goto out; 647 - 648 - qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); 649 - xfs_trans_log_quotaoff_item(tp, qoffi); 650 - 651 - spin_lock(&mp->m_sb_lock); 652 - mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 653 - spin_unlock(&mp->m_sb_lock); 654 - 655 - xfs_log_sb(tp); 656 - 657 - /* 658 - * We have to make sure that the transaction is secure on disk before we 659 - * return and actually stop quota accounting. So, make it synchronous. 660 - * We don't care about quotoff's performance. 661 - */ 662 - xfs_trans_set_sync(tp); 663 - error = xfs_trans_commit(tp); 664 - if (error) 665 - goto out; 666 - 667 - *qoffstartp = qoffi; 668 - out: 669 538 return error; 670 539 } 671 540
+3
fs/xfs/xfs_quotaops.c
··· 201 201 if (XFS_IS_QUOTA_ON(mp)) 202 202 return -EINVAL; 203 203 204 + if (uflags & ~(FS_USER_QUOTA | FS_GROUP_QUOTA | FS_PROJ_QUOTA)) 205 + return -EINVAL; 206 + 204 207 if (uflags & FS_USER_QUOTA) 205 208 flags |= XFS_DQ_USER; 206 209 if (uflags & FS_GROUP_QUOTA)
+5 -4
fs/xfs/xfs_refcount_item.c
··· 17 17 #include "xfs_refcount_item.h" 18 18 #include "xfs_log.h" 19 19 #include "xfs_refcount.h" 20 - 20 + #include "xfs_error.h" 21 21 22 22 kmem_zone_t *xfs_cui_zone; 23 23 kmem_zone_t *xfs_cud_zone; ··· 34 34 if (cuip->cui_format.cui_nextents > XFS_CUI_MAX_FAST_EXTENTS) 35 35 kmem_free(cuip); 36 36 else 37 - kmem_zone_free(xfs_cui_zone, cuip); 37 + kmem_cache_free(xfs_cui_zone, cuip); 38 38 } 39 39 40 40 /* ··· 206 206 struct xfs_cud_log_item *cudp = CUD_ITEM(lip); 207 207 208 208 xfs_cui_release(cudp->cud_cuip); 209 - kmem_zone_free(xfs_cud_zone, cudp); 209 + kmem_cache_free(xfs_cud_zone, cudp); 210 210 } 211 211 212 212 static const struct xfs_item_ops xfs_cud_item_ops = { ··· 497 497 */ 498 498 set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags); 499 499 xfs_cui_release(cuip); 500 - return -EIO; 500 + return -EFSCORRUPTED; 501 501 } 502 502 } 503 503 ··· 536 536 type = refc_type; 537 537 break; 538 538 default: 539 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); 539 540 error = -EFSCORRUPTED; 540 541 goto abort_error; 541 542 }
+23 -115
fs/xfs/xfs_reflink.c
··· 308 308 xfs_find_trim_cow_extent( 309 309 struct xfs_inode *ip, 310 310 struct xfs_bmbt_irec *imap, 311 + struct xfs_bmbt_irec *cmap, 311 312 bool *shared, 312 313 bool *found) 313 314 { 314 315 xfs_fileoff_t offset_fsb = imap->br_startoff; 315 316 xfs_filblks_t count_fsb = imap->br_blockcount; 316 317 struct xfs_iext_cursor icur; 317 - struct xfs_bmbt_irec got; 318 318 319 319 *found = false; 320 320 ··· 322 322 * If we don't find an overlapping extent, trim the range we need to 323 323 * allocate to fit the hole we found. 324 324 */ 325 - if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &got)) 326 - got.br_startoff = offset_fsb + count_fsb; 327 - if (got.br_startoff > offset_fsb) { 325 + if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, cmap)) 326 + cmap->br_startoff = offset_fsb + count_fsb; 327 + if (cmap->br_startoff > offset_fsb) { 328 328 xfs_trim_extent(imap, imap->br_startoff, 329 - got.br_startoff - imap->br_startoff); 329 + cmap->br_startoff - imap->br_startoff); 330 330 return xfs_inode_need_cow(ip, imap, shared); 331 331 } 332 332 333 333 *shared = true; 334 - if (isnullstartblock(got.br_startblock)) { 335 - xfs_trim_extent(imap, got.br_startoff, got.br_blockcount); 334 + if (isnullstartblock(cmap->br_startblock)) { 335 + xfs_trim_extent(imap, cmap->br_startoff, cmap->br_blockcount); 336 336 return 0; 337 337 } 338 338 339 339 /* real extent found - no need to allocate */ 340 - xfs_trim_extent(&got, offset_fsb, count_fsb); 341 - *imap = got; 340 + xfs_trim_extent(cmap, offset_fsb, count_fsb); 342 341 *found = true; 343 342 return 0; 344 343 } ··· 347 348 xfs_reflink_allocate_cow( 348 349 struct xfs_inode *ip, 349 350 struct xfs_bmbt_irec *imap, 351 + struct xfs_bmbt_irec *cmap, 350 352 bool *shared, 351 353 uint *lockmode, 352 354 bool convert_now) ··· 367 367 xfs_ifork_init_cow(ip); 368 368 } 369 369 370 - error = xfs_find_trim_cow_extent(ip, imap, shared, &found); 370 + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); 371 371 if (error || !*shared) 372 372 return error; 373 373 if (found) ··· 392 392 /* 393 393 * Check for an overlapping extent again now that we dropped the ilock. 394 394 */ 395 - error = xfs_find_trim_cow_extent(ip, imap, shared, &found); 395 + error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found); 396 396 if (error || !*shared) 397 397 goto out_trans_cancel; 398 398 if (found) { ··· 410 410 /* Allocate the entire reservation as unwritten blocks. */ 411 411 nimaps = 1; 412 412 error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, 413 - XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, 414 - resblks, imap, &nimaps); 413 + XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, 0, cmap, 414 + &nimaps); 415 415 if (error) 416 416 goto out_unreserve; 417 417 ··· 427 427 if (nimaps == 0) 428 428 return -ENOSPC; 429 429 convert: 430 - xfs_trim_extent(imap, offset_fsb, count_fsb); 430 + xfs_trim_extent(cmap, offset_fsb, count_fsb); 431 431 /* 432 432 * COW fork extents are supposed to remain unwritten until we're ready 433 433 * to initiate a disk write. For direct I/O we are going to write the 434 434 * data and need the conversion, but for buffered writes we're done. 435 435 */ 436 - if (!convert_now || imap->br_state == XFS_EXT_NORM) 436 + if (!convert_now || cmap->br_state == XFS_EXT_NORM) 437 437 return 0; 438 - trace_xfs_reflink_convert_cow(ip, imap); 438 + trace_xfs_reflink_convert_cow(ip, cmap); 439 439 return xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb); 440 440 441 441 out_unreserve: ··· 1270 1270 1271 1271 trace_xfs_zero_eof(ip, isize, pos - isize); 1272 1272 return iomap_zero_range(VFS_I(ip), isize, pos - isize, NULL, 1273 - &xfs_iomap_ops); 1273 + &xfs_buffered_write_iomap_ops); 1274 1274 } 1275 1275 1276 1276 /* ··· 1379 1379 out_unlock: 1380 1380 xfs_reflink_remap_unlock(file_in, file_out); 1381 1381 return ret; 1382 - } 1383 - 1384 - /* 1385 - * The user wants to preemptively CoW all shared blocks in this file, 1386 - * which enables us to turn off the reflink flag. Iterate all 1387 - * extents which are not prealloc/delalloc to see which ranges are 1388 - * mentioned in the refcount tree, then read those blocks into the 1389 - * pagecache, dirty them, fsync them back out, and then we can update 1390 - * the inode flag. What happens if we run out of memory? :) 1391 - */ 1392 - STATIC int 1393 - xfs_reflink_dirty_extents( 1394 - struct xfs_inode *ip, 1395 - xfs_fileoff_t fbno, 1396 - xfs_filblks_t end, 1397 - xfs_off_t isize) 1398 - { 1399 - struct xfs_mount *mp = ip->i_mount; 1400 - xfs_agnumber_t agno; 1401 - xfs_agblock_t agbno; 1402 - xfs_extlen_t aglen; 1403 - xfs_agblock_t rbno; 1404 - xfs_extlen_t rlen; 1405 - xfs_off_t fpos; 1406 - xfs_off_t flen; 1407 - struct xfs_bmbt_irec map[2]; 1408 - int nmaps; 1409 - int error = 0; 1410 - 1411 - while (end - fbno > 0) { 1412 - nmaps = 1; 1413 - /* 1414 - * Look for extents in the file. Skip holes, delalloc, or 1415 - * unwritten extents; they can't be reflinked. 1416 - */ 1417 - error = xfs_bmapi_read(ip, fbno, end - fbno, map, &nmaps, 0); 1418 - if (error) 1419 - goto out; 1420 - if (nmaps == 0) 1421 - break; 1422 - if (!xfs_bmap_is_real_extent(&map[0])) 1423 - goto next; 1424 - 1425 - map[1] = map[0]; 1426 - while (map[1].br_blockcount) { 1427 - agno = XFS_FSB_TO_AGNO(mp, map[1].br_startblock); 1428 - agbno = XFS_FSB_TO_AGBNO(mp, map[1].br_startblock); 1429 - aglen = map[1].br_blockcount; 1430 - 1431 - error = xfs_reflink_find_shared(mp, NULL, agno, agbno, 1432 - aglen, &rbno, &rlen, true); 1433 - if (error) 1434 - goto out; 1435 - if (rbno == NULLAGBLOCK) 1436 - break; 1437 - 1438 - /* Dirty the pages */ 1439 - xfs_iunlock(ip, XFS_ILOCK_EXCL); 1440 - fpos = XFS_FSB_TO_B(mp, map[1].br_startoff + 1441 - (rbno - agbno)); 1442 - flen = XFS_FSB_TO_B(mp, rlen); 1443 - if (fpos + flen > isize) 1444 - flen = isize - fpos; 1445 - error = iomap_file_unshare(VFS_I(ip), fpos, flen, 1446 - &xfs_iomap_ops); 1447 - xfs_ilock(ip, XFS_ILOCK_EXCL); 1448 - if (error) 1449 - goto out; 1450 - 1451 - map[1].br_blockcount -= (rbno - agbno + rlen); 1452 - map[1].br_startoff += (rbno - agbno + rlen); 1453 - map[1].br_startblock += (rbno - agbno + rlen); 1454 - } 1455 - 1456 - next: 1457 - fbno = map[0].br_startoff + map[0].br_blockcount; 1458 - } 1459 - out: 1460 - return error; 1461 1382 } 1462 1383 1463 1384 /* Does this inode need the reflink flag? */ ··· 1517 1596 xfs_off_t offset, 1518 1597 xfs_off_t len) 1519 1598 { 1520 - struct xfs_mount *mp = ip->i_mount; 1521 - xfs_fileoff_t fbno; 1522 - xfs_filblks_t end; 1523 - xfs_off_t isize; 1599 + struct inode *inode = VFS_I(ip); 1524 1600 int error; 1525 1601 1526 1602 if (!xfs_is_reflink_inode(ip)) ··· 1525 1607 1526 1608 trace_xfs_reflink_unshare(ip, offset, len); 1527 1609 1528 - inode_dio_wait(VFS_I(ip)); 1610 + inode_dio_wait(inode); 1529 1611 1530 - /* Try to CoW the selected ranges */ 1531 - xfs_ilock(ip, XFS_ILOCK_EXCL); 1532 - fbno = XFS_B_TO_FSBT(mp, offset); 1533 - isize = i_size_read(VFS_I(ip)); 1534 - end = XFS_B_TO_FSB(mp, offset + len); 1535 - error = xfs_reflink_dirty_extents(ip, fbno, end, isize); 1612 + error = iomap_file_unshare(inode, offset, len, 1613 + &xfs_buffered_write_iomap_ops); 1536 1614 if (error) 1537 - goto out_unlock; 1538 - xfs_iunlock(ip, XFS_ILOCK_EXCL); 1539 - 1540 - /* Wait for the IO to finish */ 1541 - error = filemap_write_and_wait(VFS_I(ip)->i_mapping); 1615 + goto out; 1616 + error = filemap_write_and_wait(inode->i_mapping); 1542 1617 if (error) 1543 1618 goto out; 1544 1619 ··· 1539 1628 error = xfs_reflink_try_clear_inode_flag(ip); 1540 1629 if (error) 1541 1630 goto out; 1542 - 1543 1631 return 0; 1544 1632 1545 - out_unlock: 1546 - xfs_iunlock(ip, XFS_ILOCK_EXCL); 1547 1633 out: 1548 1634 trace_xfs_reflink_unshare_error(ip, error, _RET_IP_); 1549 1635 return error;
+2 -2
fs/xfs/xfs_reflink.h
··· 25 25 bool xfs_inode_need_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, 26 26 bool *shared); 27 27 28 - extern int xfs_reflink_allocate_cow(struct xfs_inode *ip, 29 - struct xfs_bmbt_irec *imap, bool *shared, uint *lockmode, 28 + int xfs_reflink_allocate_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, 29 + struct xfs_bmbt_irec *cmap, bool *shared, uint *lockmode, 30 30 bool convert_now); 31 31 extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset, 32 32 xfs_off_t count);
+8 -5
fs/xfs/xfs_rmap_item.c
··· 17 17 #include "xfs_rmap_item.h" 18 18 #include "xfs_log.h" 19 19 #include "xfs_rmap.h" 20 - 20 + #include "xfs_error.h" 21 21 22 22 kmem_zone_t *xfs_rui_zone; 23 23 kmem_zone_t *xfs_rud_zone; ··· 34 34 if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS) 35 35 kmem_free(ruip); 36 36 else 37 - kmem_zone_free(xfs_rui_zone, ruip); 37 + kmem_cache_free(xfs_rui_zone, ruip); 38 38 } 39 39 40 40 /* ··· 171 171 src_rui_fmt = buf->i_addr; 172 172 len = xfs_rui_log_format_sizeof(src_rui_fmt->rui_nextents); 173 173 174 - if (buf->i_len != len) 174 + if (buf->i_len != len) { 175 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); 175 176 return -EFSCORRUPTED; 177 + } 176 178 177 179 memcpy(dst_rui_fmt, src_rui_fmt, len); 178 180 return 0; ··· 229 227 struct xfs_rud_log_item *rudp = RUD_ITEM(lip); 230 228 231 229 xfs_rui_release(rudp->rud_ruip); 232 - kmem_zone_free(xfs_rud_zone, rudp); 230 + kmem_cache_free(xfs_rud_zone, rudp); 233 231 } 234 232 235 233 static const struct xfs_item_ops xfs_rud_item_ops = { ··· 541 539 */ 542 540 set_bit(XFS_RUI_RECOVERED, &ruip->rui_flags); 543 541 xfs_rui_release(ruip); 544 - return -EIO; 542 + return -EFSCORRUPTED; 545 543 } 546 544 } 547 545 ··· 583 581 type = XFS_RMAP_FREE; 584 582 break; 585 583 default: 584 + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL); 586 585 error = -EFSCORRUPTED; 587 586 goto abort_error; 588 587 }
+1 -2
fs/xfs/xfs_rtalloc.c
··· 792 792 */ 793 793 nmap = 1; 794 794 error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, 795 - XFS_BMAPI_METADATA, resblks, &map, 796 - &nmap); 795 + XFS_BMAPI_METADATA, 0, &map, &nmap); 797 796 if (!error && nmap < 1) 798 797 error = -ENOSPC; 799 798 if (error)
+717 -753
fs/xfs/xfs_super.c
··· 37 37 #include "xfs_reflink.h" 38 38 39 39 #include <linux/magic.h> 40 - #include <linux/parser.h> 40 + #include <linux/fs_context.h> 41 + #include <linux/fs_parser.h> 41 42 42 43 static const struct super_operations xfs_super_operations; 43 44 ··· 51 50 * Table driven mount option parser. 52 51 */ 53 52 enum { 54 - Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize, 53 + Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, 55 54 Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid, 56 55 Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups, 57 56 Opt_allocsize, Opt_norecovery, Opt_inode64, Opt_inode32, Opt_ikeep, ··· 59 58 Opt_filestreams, Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, 60 59 Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota, 61 60 Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, 62 - Opt_discard, Opt_nodiscard, Opt_dax, Opt_err, 61 + Opt_discard, Opt_nodiscard, Opt_dax, 63 62 }; 64 63 65 - static const match_table_t tokens = { 66 - {Opt_logbufs, "logbufs=%u"}, /* number of XFS log buffers */ 67 - {Opt_logbsize, "logbsize=%s"}, /* size of XFS log buffers */ 68 - {Opt_logdev, "logdev=%s"}, /* log device */ 69 - {Opt_rtdev, "rtdev=%s"}, /* realtime I/O device */ 70 - {Opt_biosize, "biosize=%u"}, /* log2 of preferred buffered io size */ 71 - {Opt_wsync, "wsync"}, /* safe-mode nfs compatible mount */ 72 - {Opt_noalign, "noalign"}, /* turn off stripe alignment */ 73 - {Opt_swalloc, "swalloc"}, /* turn on stripe width allocation */ 74 - {Opt_sunit, "sunit=%u"}, /* data volume stripe unit */ 75 - {Opt_swidth, "swidth=%u"}, /* data volume stripe width */ 76 - {Opt_nouuid, "nouuid"}, /* ignore filesystem UUID */ 77 - {Opt_grpid, "grpid"}, /* group-ID from parent directory */ 78 - {Opt_nogrpid, "nogrpid"}, /* group-ID from current process */ 79 - {Opt_bsdgroups, "bsdgroups"}, /* group-ID from parent directory */ 80 - {Opt_sysvgroups,"sysvgroups"}, /* group-ID from current process */ 81 - {Opt_allocsize, "allocsize=%s"},/* preferred allocation size */ 82 - {Opt_norecovery,"norecovery"}, /* don't run XFS recovery */ 83 - {Opt_inode64, "inode64"}, /* inodes can be allocated anywhere */ 84 - {Opt_inode32, "inode32"}, /* inode allocation limited to 85 - * XFS_MAXINUMBER_32 */ 86 - {Opt_ikeep, "ikeep"}, /* do not free empty inode clusters */ 87 - {Opt_noikeep, "noikeep"}, /* free empty inode clusters */ 88 - {Opt_largeio, "largeio"}, /* report large I/O sizes in stat() */ 89 - {Opt_nolargeio, "nolargeio"}, /* do not report large I/O sizes 90 - * in stat(). */ 91 - {Opt_attr2, "attr2"}, /* do use attr2 attribute format */ 92 - {Opt_noattr2, "noattr2"}, /* do not use attr2 attribute format */ 93 - {Opt_filestreams,"filestreams"},/* use filestreams allocator */ 94 - {Opt_quota, "quota"}, /* disk quotas (user) */ 95 - {Opt_noquota, "noquota"}, /* no quotas */ 96 - {Opt_usrquota, "usrquota"}, /* user quota enabled */ 97 - {Opt_grpquota, "grpquota"}, /* group quota enabled */ 98 - {Opt_prjquota, "prjquota"}, /* project quota enabled */ 99 - {Opt_uquota, "uquota"}, /* user quota (IRIX variant) */ 100 - {Opt_gquota, "gquota"}, /* group quota (IRIX variant) */ 101 - {Opt_pquota, "pquota"}, /* project quota (IRIX variant) */ 102 - {Opt_uqnoenforce,"uqnoenforce"},/* user quota limit enforcement */ 103 - {Opt_gqnoenforce,"gqnoenforce"},/* group quota limit enforcement */ 104 - {Opt_pqnoenforce,"pqnoenforce"},/* project quota limit enforcement */ 105 - {Opt_qnoenforce, "qnoenforce"}, /* same as uqnoenforce */ 106 - {Opt_discard, "discard"}, /* Discard unused blocks */ 107 - {Opt_nodiscard, "nodiscard"}, /* Do not discard unused blocks */ 108 - {Opt_dax, "dax"}, /* Enable direct access to bdev pages */ 109 - {Opt_err, NULL}, 64 + static const struct fs_parameter_spec xfs_param_specs[] = { 65 + fsparam_u32("logbufs", Opt_logbufs), 66 + fsparam_string("logbsize", Opt_logbsize), 67 + fsparam_string("logdev", Opt_logdev), 68 + fsparam_string("rtdev", Opt_rtdev), 69 + fsparam_flag("wsync", Opt_wsync), 70 + fsparam_flag("noalign", Opt_noalign), 71 + fsparam_flag("swalloc", Opt_swalloc), 72 + fsparam_u32("sunit", Opt_sunit), 73 + fsparam_u32("swidth", Opt_swidth), 74 + fsparam_flag("nouuid", Opt_nouuid), 75 + fsparam_flag("grpid", Opt_grpid), 76 + fsparam_flag("nogrpid", Opt_nogrpid), 77 + fsparam_flag("bsdgroups", Opt_bsdgroups), 78 + fsparam_flag("sysvgroups", Opt_sysvgroups), 79 + fsparam_string("allocsize", Opt_allocsize), 80 + fsparam_flag("norecovery", Opt_norecovery), 81 + fsparam_flag("inode64", Opt_inode64), 82 + fsparam_flag("inode32", Opt_inode32), 83 + fsparam_flag("ikeep", Opt_ikeep), 84 + fsparam_flag("noikeep", Opt_noikeep), 85 + fsparam_flag("largeio", Opt_largeio), 86 + fsparam_flag("nolargeio", Opt_nolargeio), 87 + fsparam_flag("attr2", Opt_attr2), 88 + fsparam_flag("noattr2", Opt_noattr2), 89 + fsparam_flag("filestreams", Opt_filestreams), 90 + fsparam_flag("quota", Opt_quota), 91 + fsparam_flag("noquota", Opt_noquota), 92 + fsparam_flag("usrquota", Opt_usrquota), 93 + fsparam_flag("grpquota", Opt_grpquota), 94 + fsparam_flag("prjquota", Opt_prjquota), 95 + fsparam_flag("uquota", Opt_uquota), 96 + fsparam_flag("gquota", Opt_gquota), 97 + fsparam_flag("pquota", Opt_pquota), 98 + fsparam_flag("uqnoenforce", Opt_uqnoenforce), 99 + fsparam_flag("gqnoenforce", Opt_gqnoenforce), 100 + fsparam_flag("pqnoenforce", Opt_pqnoenforce), 101 + fsparam_flag("qnoenforce", Opt_qnoenforce), 102 + fsparam_flag("discard", Opt_discard), 103 + fsparam_flag("nodiscard", Opt_nodiscard), 104 + fsparam_flag("dax", Opt_dax), 105 + {} 110 106 }; 111 107 112 - 113 - STATIC int 114 - suffix_kstrtoint(const substring_t *s, unsigned int base, int *res) 115 - { 116 - int last, shift_left_factor = 0, _res; 117 - char *value; 118 - int ret = 0; 119 - 120 - value = match_strdup(s); 121 - if (!value) 122 - return -ENOMEM; 123 - 124 - last = strlen(value) - 1; 125 - if (value[last] == 'K' || value[last] == 'k') { 126 - shift_left_factor = 10; 127 - value[last] = '\0'; 128 - } 129 - if (value[last] == 'M' || value[last] == 'm') { 130 - shift_left_factor = 20; 131 - value[last] = '\0'; 132 - } 133 - if (value[last] == 'G' || value[last] == 'g') { 134 - shift_left_factor = 30; 135 - value[last] = '\0'; 136 - } 137 - 138 - if (kstrtoint(value, base, &_res)) 139 - ret = -EINVAL; 140 - kfree(value); 141 - *res = _res << shift_left_factor; 142 - return ret; 143 - } 144 - 145 - /* 146 - * This function fills in xfs_mount_t fields based on mount args. 147 - * Note: the superblock has _not_ yet been read in. 148 - * 149 - * Note that this function leaks the various device name allocations on 150 - * failure. The caller takes care of them. 151 - * 152 - * *sb is const because this is also used to test options on the remount 153 - * path, and we don't want this to have any side effects at remount time. 154 - * Today this function does not change *sb, but just to future-proof... 155 - */ 156 - STATIC int 157 - xfs_parseargs( 158 - struct xfs_mount *mp, 159 - char *options) 160 - { 161 - const struct super_block *sb = mp->m_super; 162 - char *p; 163 - substring_t args[MAX_OPT_ARGS]; 164 - int dsunit = 0; 165 - int dswidth = 0; 166 - int iosize = 0; 167 - uint8_t iosizelog = 0; 168 - 169 - /* 170 - * set up the mount name first so all the errors will refer to the 171 - * correct device. 172 - */ 173 - mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL); 174 - if (!mp->m_fsname) 175 - return -ENOMEM; 176 - mp->m_fsname_len = strlen(mp->m_fsname) + 1; 177 - 178 - /* 179 - * Copy binary VFS mount flags we are interested in. 180 - */ 181 - if (sb_rdonly(sb)) 182 - mp->m_flags |= XFS_MOUNT_RDONLY; 183 - if (sb->s_flags & SB_DIRSYNC) 184 - mp->m_flags |= XFS_MOUNT_DIRSYNC; 185 - if (sb->s_flags & SB_SYNCHRONOUS) 186 - mp->m_flags |= XFS_MOUNT_WSYNC; 187 - 188 - /* 189 - * Set some default flags that could be cleared by the mount option 190 - * parsing. 191 - */ 192 - mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; 193 - 194 - /* 195 - * These can be overridden by the mount option parsing. 196 - */ 197 - mp->m_logbufs = -1; 198 - mp->m_logbsize = -1; 199 - 200 - if (!options) 201 - goto done; 202 - 203 - while ((p = strsep(&options, ",")) != NULL) { 204 - int token; 205 - 206 - if (!*p) 207 - continue; 208 - 209 - token = match_token(p, tokens, args); 210 - switch (token) { 211 - case Opt_logbufs: 212 - if (match_int(args, &mp->m_logbufs)) 213 - return -EINVAL; 214 - break; 215 - case Opt_logbsize: 216 - if (suffix_kstrtoint(args, 10, &mp->m_logbsize)) 217 - return -EINVAL; 218 - break; 219 - case Opt_logdev: 220 - kfree(mp->m_logname); 221 - mp->m_logname = match_strdup(args); 222 - if (!mp->m_logname) 223 - return -ENOMEM; 224 - break; 225 - case Opt_rtdev: 226 - kfree(mp->m_rtname); 227 - mp->m_rtname = match_strdup(args); 228 - if (!mp->m_rtname) 229 - return -ENOMEM; 230 - break; 231 - case Opt_allocsize: 232 - case Opt_biosize: 233 - if (suffix_kstrtoint(args, 10, &iosize)) 234 - return -EINVAL; 235 - iosizelog = ffs(iosize) - 1; 236 - break; 237 - case Opt_grpid: 238 - case Opt_bsdgroups: 239 - mp->m_flags |= XFS_MOUNT_GRPID; 240 - break; 241 - case Opt_nogrpid: 242 - case Opt_sysvgroups: 243 - mp->m_flags &= ~XFS_MOUNT_GRPID; 244 - break; 245 - case Opt_wsync: 246 - mp->m_flags |= XFS_MOUNT_WSYNC; 247 - break; 248 - case Opt_norecovery: 249 - mp->m_flags |= XFS_MOUNT_NORECOVERY; 250 - break; 251 - case Opt_noalign: 252 - mp->m_flags |= XFS_MOUNT_NOALIGN; 253 - break; 254 - case Opt_swalloc: 255 - mp->m_flags |= XFS_MOUNT_SWALLOC; 256 - break; 257 - case Opt_sunit: 258 - if (match_int(args, &dsunit)) 259 - return -EINVAL; 260 - break; 261 - case Opt_swidth: 262 - if (match_int(args, &dswidth)) 263 - return -EINVAL; 264 - break; 265 - case Opt_inode32: 266 - mp->m_flags |= XFS_MOUNT_SMALL_INUMS; 267 - break; 268 - case Opt_inode64: 269 - mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; 270 - break; 271 - case Opt_nouuid: 272 - mp->m_flags |= XFS_MOUNT_NOUUID; 273 - break; 274 - case Opt_ikeep: 275 - mp->m_flags |= XFS_MOUNT_IKEEP; 276 - break; 277 - case Opt_noikeep: 278 - mp->m_flags &= ~XFS_MOUNT_IKEEP; 279 - break; 280 - case Opt_largeio: 281 - mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; 282 - break; 283 - case Opt_nolargeio: 284 - mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; 285 - break; 286 - case Opt_attr2: 287 - mp->m_flags |= XFS_MOUNT_ATTR2; 288 - break; 289 - case Opt_noattr2: 290 - mp->m_flags &= ~XFS_MOUNT_ATTR2; 291 - mp->m_flags |= XFS_MOUNT_NOATTR2; 292 - break; 293 - case Opt_filestreams: 294 - mp->m_flags |= XFS_MOUNT_FILESTREAMS; 295 - break; 296 - case Opt_noquota: 297 - mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; 298 - mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; 299 - mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; 300 - break; 301 - case Opt_quota: 302 - case Opt_uquota: 303 - case Opt_usrquota: 304 - mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | 305 - XFS_UQUOTA_ENFD); 306 - break; 307 - case Opt_qnoenforce: 308 - case Opt_uqnoenforce: 309 - mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); 310 - mp->m_qflags &= ~XFS_UQUOTA_ENFD; 311 - break; 312 - case Opt_pquota: 313 - case Opt_prjquota: 314 - mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | 315 - XFS_PQUOTA_ENFD); 316 - break; 317 - case Opt_pqnoenforce: 318 - mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); 319 - mp->m_qflags &= ~XFS_PQUOTA_ENFD; 320 - break; 321 - case Opt_gquota: 322 - case Opt_grpquota: 323 - mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | 324 - XFS_GQUOTA_ENFD); 325 - break; 326 - case Opt_gqnoenforce: 327 - mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); 328 - mp->m_qflags &= ~XFS_GQUOTA_ENFD; 329 - break; 330 - case Opt_discard: 331 - mp->m_flags |= XFS_MOUNT_DISCARD; 332 - break; 333 - case Opt_nodiscard: 334 - mp->m_flags &= ~XFS_MOUNT_DISCARD; 335 - break; 336 - #ifdef CONFIG_FS_DAX 337 - case Opt_dax: 338 - mp->m_flags |= XFS_MOUNT_DAX; 339 - break; 340 - #endif 341 - default: 342 - xfs_warn(mp, "unknown mount option [%s].", p); 343 - return -EINVAL; 344 - } 345 - } 346 - 347 - /* 348 - * no recovery flag requires a read-only mount 349 - */ 350 - if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && 351 - !(mp->m_flags & XFS_MOUNT_RDONLY)) { 352 - xfs_warn(mp, "no-recovery mounts must be read-only."); 353 - return -EINVAL; 354 - } 355 - 356 - if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { 357 - xfs_warn(mp, 358 - "sunit and swidth options incompatible with the noalign option"); 359 - return -EINVAL; 360 - } 361 - 362 - #ifndef CONFIG_XFS_QUOTA 363 - if (XFS_IS_QUOTA_RUNNING(mp)) { 364 - xfs_warn(mp, "quota support not available in this kernel."); 365 - return -EINVAL; 366 - } 367 - #endif 368 - 369 - if ((dsunit && !dswidth) || (!dsunit && dswidth)) { 370 - xfs_warn(mp, "sunit and swidth must be specified together"); 371 - return -EINVAL; 372 - } 373 - 374 - if (dsunit && (dswidth % dsunit != 0)) { 375 - xfs_warn(mp, 376 - "stripe width (%d) must be a multiple of the stripe unit (%d)", 377 - dswidth, dsunit); 378 - return -EINVAL; 379 - } 380 - 381 - done: 382 - if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) { 383 - /* 384 - * At this point the superblock has not been read 385 - * in, therefore we do not know the block size. 386 - * Before the mount call ends we will convert 387 - * these to FSBs. 388 - */ 389 - mp->m_dalign = dsunit; 390 - mp->m_swidth = dswidth; 391 - } 392 - 393 - if (mp->m_logbufs != -1 && 394 - mp->m_logbufs != 0 && 395 - (mp->m_logbufs < XLOG_MIN_ICLOGS || 396 - mp->m_logbufs > XLOG_MAX_ICLOGS)) { 397 - xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", 398 - mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); 399 - return -EINVAL; 400 - } 401 - if (mp->m_logbsize != -1 && 402 - mp->m_logbsize != 0 && 403 - (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || 404 - mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || 405 - !is_power_of_2(mp->m_logbsize))) { 406 - xfs_warn(mp, 407 - "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", 408 - mp->m_logbsize); 409 - return -EINVAL; 410 - } 411 - 412 - if (iosizelog) { 413 - if (iosizelog > XFS_MAX_IO_LOG || 414 - iosizelog < XFS_MIN_IO_LOG) { 415 - xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", 416 - iosizelog, XFS_MIN_IO_LOG, 417 - XFS_MAX_IO_LOG); 418 - return -EINVAL; 419 - } 420 - 421 - mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; 422 - mp->m_readio_log = iosizelog; 423 - mp->m_writeio_log = iosizelog; 424 - } 425 - 426 - return 0; 427 - } 108 + static const struct fs_parameter_description xfs_fs_parameters = { 109 + .name = "xfs", 110 + .specs = xfs_param_specs, 111 + }; 428 112 429 113 struct proc_xfs_info { 430 114 uint64_t flag; 431 115 char *str; 432 116 }; 433 117 434 - STATIC void 435 - xfs_showargs( 436 - struct xfs_mount *mp, 437 - struct seq_file *m) 118 + static int 119 + xfs_fs_show_options( 120 + struct seq_file *m, 121 + struct dentry *root) 438 122 { 439 123 static struct proc_xfs_info xfs_info_set[] = { 440 124 /* the few simple ones we can get from the mount struct */ ··· 133 447 { XFS_MOUNT_FILESTREAMS, ",filestreams" }, 134 448 { XFS_MOUNT_GRPID, ",grpid" }, 135 449 { XFS_MOUNT_DISCARD, ",discard" }, 136 - { XFS_MOUNT_SMALL_INUMS, ",inode32" }, 450 + { XFS_MOUNT_LARGEIO, ",largeio" }, 137 451 { XFS_MOUNT_DAX, ",dax" }, 138 452 { 0, NULL } 139 453 }; 140 - static struct proc_xfs_info xfs_info_unset[] = { 141 - /* the few simple ones we can get from the mount struct */ 142 - { XFS_MOUNT_COMPAT_IOSIZE, ",largeio" }, 143 - { XFS_MOUNT_SMALL_INUMS, ",inode64" }, 144 - { 0, NULL } 145 - }; 454 + struct xfs_mount *mp = XFS_M(root->d_sb); 146 455 struct proc_xfs_info *xfs_infop; 147 456 148 457 for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { 149 458 if (mp->m_flags & xfs_infop->flag) 150 459 seq_puts(m, xfs_infop->str); 151 460 } 152 - for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) { 153 - if (!(mp->m_flags & xfs_infop->flag)) 154 - seq_puts(m, xfs_infop->str); 155 - } 156 461 157 - if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) 462 + seq_printf(m, ",inode%d", 463 + (mp->m_flags & XFS_MOUNT_SMALL_INUMS) ? 32 : 64); 464 + 465 + if (mp->m_flags & XFS_MOUNT_ALLOCSIZE) 158 466 seq_printf(m, ",allocsize=%dk", 159 - (int)(1 << mp->m_writeio_log) >> 10); 467 + (1 << mp->m_allocsize_log) >> 10); 160 468 161 469 if (mp->m_logbufs > 0) 162 470 seq_printf(m, ",logbufs=%d", mp->m_logbufs); ··· 189 509 190 510 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) 191 511 seq_puts(m, ",noquota"); 512 + 513 + return 0; 192 514 } 193 515 194 516 static uint64_t ··· 489 807 struct xfs_mount *mp) 490 808 { 491 809 mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s", 492 - WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_fsname); 810 + WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_super->s_id); 493 811 if (!mp->m_buf_workqueue) 494 812 goto out; 495 813 496 814 mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", 497 - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); 815 + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id); 498 816 if (!mp->m_unwritten_workqueue) 499 817 goto out_destroy_buf; 500 818 501 819 mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s", 502 820 WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND, 503 - 0, mp->m_fsname); 821 + 0, mp->m_super->s_id); 504 822 if (!mp->m_cil_workqueue) 505 823 goto out_destroy_unwritten; 506 824 507 825 mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s", 508 - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); 826 + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id); 509 827 if (!mp->m_reclaim_workqueue) 510 828 goto out_destroy_cil; 511 829 512 830 mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", 513 - WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); 831 + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_super->s_id); 514 832 if (!mp->m_eofblocks_workqueue) 515 833 goto out_destroy_reclaim; 516 834 517 835 mp->m_sync_workqueue = alloc_workqueue("xfs-sync/%s", WQ_FREEZABLE, 0, 518 - mp->m_fsname); 836 + mp->m_super->s_id); 519 837 if (!mp->m_sync_workqueue) 520 838 goto out_destroy_eofb; 521 839 ··· 719 1037 return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE); 720 1038 } 721 1039 722 - STATIC void 723 - xfs_free_fsname( 1040 + static void 1041 + xfs_mount_free( 724 1042 struct xfs_mount *mp) 725 1043 { 726 - kfree(mp->m_fsname); 727 1044 kfree(mp->m_rtname); 728 1045 kfree(mp->m_logname); 1046 + kmem_free(mp); 729 1047 } 730 1048 731 1049 STATIC int ··· 886 1204 xfs_log_quiesce(mp); 887 1205 } 888 1206 889 - STATIC int 890 - xfs_test_remount_options( 891 - struct super_block *sb, 892 - char *options) 893 - { 894 - int error = 0; 895 - struct xfs_mount *tmp_mp; 896 - 897 - tmp_mp = kmem_zalloc(sizeof(*tmp_mp), KM_MAYFAIL); 898 - if (!tmp_mp) 899 - return -ENOMEM; 900 - 901 - tmp_mp->m_super = sb; 902 - error = xfs_parseargs(tmp_mp, options); 903 - xfs_free_fsname(tmp_mp); 904 - kmem_free(tmp_mp); 905 - 906 - return error; 907 - } 908 - 909 - STATIC int 910 - xfs_fs_remount( 911 - struct super_block *sb, 912 - int *flags, 913 - char *options) 914 - { 915 - struct xfs_mount *mp = XFS_M(sb); 916 - xfs_sb_t *sbp = &mp->m_sb; 917 - substring_t args[MAX_OPT_ARGS]; 918 - char *p; 919 - int error; 920 - 921 - /* First, check for complete junk; i.e. invalid options */ 922 - error = xfs_test_remount_options(sb, options); 923 - if (error) 924 - return error; 925 - 926 - sync_filesystem(sb); 927 - while ((p = strsep(&options, ",")) != NULL) { 928 - int token; 929 - 930 - if (!*p) 931 - continue; 932 - 933 - token = match_token(p, tokens, args); 934 - switch (token) { 935 - case Opt_inode64: 936 - mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; 937 - mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); 938 - break; 939 - case Opt_inode32: 940 - mp->m_flags |= XFS_MOUNT_SMALL_INUMS; 941 - mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); 942 - break; 943 - default: 944 - /* 945 - * Logically we would return an error here to prevent 946 - * users from believing they might have changed 947 - * mount options using remount which can't be changed. 948 - * 949 - * But unfortunately mount(8) adds all options from 950 - * mtab and fstab to the mount arguments in some cases 951 - * so we can't blindly reject options, but have to 952 - * check for each specified option if it actually 953 - * differs from the currently set option and only 954 - * reject it if that's the case. 955 - * 956 - * Until that is implemented we return success for 957 - * every remount request, and silently ignore all 958 - * options that we can't actually change. 959 - */ 960 - #if 0 961 - xfs_info(mp, 962 - "mount option \"%s\" not supported for remount", p); 963 - return -EINVAL; 964 - #else 965 - break; 966 - #endif 967 - } 968 - } 969 - 970 - /* ro -> rw */ 971 - if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) { 972 - if (mp->m_flags & XFS_MOUNT_NORECOVERY) { 973 - xfs_warn(mp, 974 - "ro->rw transition prohibited on norecovery mount"); 975 - return -EINVAL; 976 - } 977 - 978 - if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && 979 - xfs_sb_has_ro_compat_feature(sbp, 980 - XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { 981 - xfs_warn(mp, 982 - "ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem", 983 - (sbp->sb_features_ro_compat & 984 - XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); 985 - return -EINVAL; 986 - } 987 - 988 - mp->m_flags &= ~XFS_MOUNT_RDONLY; 989 - 990 - /* 991 - * If this is the first remount to writeable state we 992 - * might have some superblock changes to update. 993 - */ 994 - if (mp->m_update_sb) { 995 - error = xfs_sync_sb(mp, false); 996 - if (error) { 997 - xfs_warn(mp, "failed to write sb changes"); 998 - return error; 999 - } 1000 - mp->m_update_sb = false; 1001 - } 1002 - 1003 - /* 1004 - * Fill out the reserve pool if it is empty. Use the stashed 1005 - * value if it is non-zero, otherwise go with the default. 1006 - */ 1007 - xfs_restore_resvblks(mp); 1008 - xfs_log_work_queue(mp); 1009 - 1010 - /* Recover any CoW blocks that never got remapped. */ 1011 - error = xfs_reflink_recover_cow(mp); 1012 - if (error) { 1013 - xfs_err(mp, 1014 - "Error %d recovering leftover CoW allocations.", error); 1015 - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1016 - return error; 1017 - } 1018 - xfs_start_block_reaping(mp); 1019 - 1020 - /* Create the per-AG metadata reservation pool .*/ 1021 - error = xfs_fs_reserve_ag_blocks(mp); 1022 - if (error && error != -ENOSPC) 1023 - return error; 1024 - } 1025 - 1026 - /* rw -> ro */ 1027 - if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) { 1028 - /* 1029 - * Cancel background eofb scanning so it cannot race with the 1030 - * final log force+buftarg wait and deadlock the remount. 1031 - */ 1032 - xfs_stop_block_reaping(mp); 1033 - 1034 - /* Get rid of any leftover CoW reservations... */ 1035 - error = xfs_icache_free_cowblocks(mp, NULL); 1036 - if (error) { 1037 - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1038 - return error; 1039 - } 1040 - 1041 - /* Free the per-AG metadata reservation pool. */ 1042 - error = xfs_fs_unreserve_ag_blocks(mp); 1043 - if (error) { 1044 - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1045 - return error; 1046 - } 1047 - 1048 - /* 1049 - * Before we sync the metadata, we need to free up the reserve 1050 - * block pool so that the used block count in the superblock on 1051 - * disk is correct at the end of the remount. Stash the current 1052 - * reserve pool size so that if we get remounted rw, we can 1053 - * return it to the same size. 1054 - */ 1055 - xfs_save_resvblks(mp); 1056 - 1057 - xfs_quiesce_attr(mp); 1058 - mp->m_flags |= XFS_MOUNT_RDONLY; 1059 - } 1060 - 1061 - return 0; 1062 - } 1063 - 1064 1207 /* 1065 1208 * Second stage of a freeze. The data is already frozen so we only 1066 1209 * need to take care of the metadata. Once that's done sync the superblock ··· 913 1406 xfs_restore_resvblks(mp); 914 1407 xfs_log_work_queue(mp); 915 1408 xfs_start_block_reaping(mp); 916 - return 0; 917 - } 918 - 919 - STATIC int 920 - xfs_fs_show_options( 921 - struct seq_file *m, 922 - struct dentry *root) 923 - { 924 - xfs_showargs(XFS_M(root->d_sb), m); 925 1409 return 0; 926 1410 } 927 1411 ··· 1038 1540 percpu_counter_destroy(&mp->m_delalloc_blks); 1039 1541 } 1040 1542 1041 - static struct xfs_mount * 1042 - xfs_mount_alloc( 1543 + static void 1544 + xfs_fs_put_super( 1043 1545 struct super_block *sb) 1044 1546 { 1045 - struct xfs_mount *mp; 1547 + struct xfs_mount *mp = XFS_M(sb); 1046 1548 1047 - mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); 1048 - if (!mp) 1049 - return NULL; 1549 + /* if ->fill_super failed, we have no mount to tear down */ 1550 + if (!sb->s_fs_info) 1551 + return; 1050 1552 1051 - mp->m_super = sb; 1052 - spin_lock_init(&mp->m_sb_lock); 1053 - spin_lock_init(&mp->m_agirotor_lock); 1054 - INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); 1055 - spin_lock_init(&mp->m_perag_lock); 1056 - mutex_init(&mp->m_growlock); 1057 - atomic_set(&mp->m_active_trans, 0); 1058 - INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); 1059 - INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); 1060 - INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker); 1061 - mp->m_kobj.kobject.kset = xfs_kset; 1062 - /* 1063 - * We don't create the finobt per-ag space reservation until after log 1064 - * recovery, so we must set this to true so that an ifree transaction 1065 - * started during log recovery will not depend on space reservations 1066 - * for finobt expansion. 1067 - */ 1068 - mp->m_finobt_nores = true; 1069 - return mp; 1553 + xfs_notice(mp, "Unmounting Filesystem"); 1554 + xfs_filestream_unmount(mp); 1555 + xfs_unmountfs(mp); 1556 + 1557 + xfs_freesb(mp); 1558 + free_percpu(mp->m_stats.xs_stats); 1559 + xfs_destroy_percpu_counters(mp); 1560 + xfs_destroy_mount_workqueues(mp); 1561 + xfs_close_devices(mp); 1562 + 1563 + sb->s_fs_info = NULL; 1564 + xfs_mount_free(mp); 1070 1565 } 1071 1566 1072 - 1073 - STATIC int 1074 - xfs_fs_fill_super( 1567 + static long 1568 + xfs_fs_nr_cached_objects( 1075 1569 struct super_block *sb, 1076 - void *data, 1077 - int silent) 1570 + struct shrink_control *sc) 1078 1571 { 1079 - struct inode *root; 1080 - struct xfs_mount *mp = NULL; 1081 - int flags = 0, error = -ENOMEM; 1572 + /* Paranoia: catch incorrect calls during mount setup or teardown */ 1573 + if (WARN_ON_ONCE(!sb->s_fs_info)) 1574 + return 0; 1575 + return xfs_reclaim_inodes_count(XFS_M(sb)); 1576 + } 1082 1577 1578 + static long 1579 + xfs_fs_free_cached_objects( 1580 + struct super_block *sb, 1581 + struct shrink_control *sc) 1582 + { 1583 + return xfs_reclaim_inodes_nr(XFS_M(sb), sc->nr_to_scan); 1584 + } 1585 + 1586 + static const struct super_operations xfs_super_operations = { 1587 + .alloc_inode = xfs_fs_alloc_inode, 1588 + .destroy_inode = xfs_fs_destroy_inode, 1589 + .dirty_inode = xfs_fs_dirty_inode, 1590 + .drop_inode = xfs_fs_drop_inode, 1591 + .put_super = xfs_fs_put_super, 1592 + .sync_fs = xfs_fs_sync_fs, 1593 + .freeze_fs = xfs_fs_freeze, 1594 + .unfreeze_fs = xfs_fs_unfreeze, 1595 + .statfs = xfs_fs_statfs, 1596 + .show_options = xfs_fs_show_options, 1597 + .nr_cached_objects = xfs_fs_nr_cached_objects, 1598 + .free_cached_objects = xfs_fs_free_cached_objects, 1599 + }; 1600 + 1601 + static int 1602 + suffix_kstrtoint( 1603 + const char *s, 1604 + unsigned int base, 1605 + int *res) 1606 + { 1607 + int last, shift_left_factor = 0, _res; 1608 + char *value; 1609 + int ret = 0; 1610 + 1611 + value = kstrdup(s, GFP_KERNEL); 1612 + if (!value) 1613 + return -ENOMEM; 1614 + 1615 + last = strlen(value) - 1; 1616 + if (value[last] == 'K' || value[last] == 'k') { 1617 + shift_left_factor = 10; 1618 + value[last] = '\0'; 1619 + } 1620 + if (value[last] == 'M' || value[last] == 'm') { 1621 + shift_left_factor = 20; 1622 + value[last] = '\0'; 1623 + } 1624 + if (value[last] == 'G' || value[last] == 'g') { 1625 + shift_left_factor = 30; 1626 + value[last] = '\0'; 1627 + } 1628 + 1629 + if (kstrtoint(value, base, &_res)) 1630 + ret = -EINVAL; 1631 + kfree(value); 1632 + *res = _res << shift_left_factor; 1633 + return ret; 1634 + } 1635 + 1636 + /* 1637 + * Set mount state from a mount option. 1638 + * 1639 + * NOTE: mp->m_super is NULL here! 1640 + */ 1641 + static int 1642 + xfs_fc_parse_param( 1643 + struct fs_context *fc, 1644 + struct fs_parameter *param) 1645 + { 1646 + struct xfs_mount *mp = fc->s_fs_info; 1647 + struct fs_parse_result result; 1648 + int size = 0; 1649 + int opt; 1650 + 1651 + opt = fs_parse(fc, &xfs_fs_parameters, param, &result); 1652 + if (opt < 0) 1653 + return opt; 1654 + 1655 + switch (opt) { 1656 + case Opt_logbufs: 1657 + mp->m_logbufs = result.uint_32; 1658 + return 0; 1659 + case Opt_logbsize: 1660 + if (suffix_kstrtoint(param->string, 10, &mp->m_logbsize)) 1661 + return -EINVAL; 1662 + return 0; 1663 + case Opt_logdev: 1664 + kfree(mp->m_logname); 1665 + mp->m_logname = kstrdup(param->string, GFP_KERNEL); 1666 + if (!mp->m_logname) 1667 + return -ENOMEM; 1668 + return 0; 1669 + case Opt_rtdev: 1670 + kfree(mp->m_rtname); 1671 + mp->m_rtname = kstrdup(param->string, GFP_KERNEL); 1672 + if (!mp->m_rtname) 1673 + return -ENOMEM; 1674 + return 0; 1675 + case Opt_allocsize: 1676 + if (suffix_kstrtoint(param->string, 10, &size)) 1677 + return -EINVAL; 1678 + mp->m_allocsize_log = ffs(size) - 1; 1679 + mp->m_flags |= XFS_MOUNT_ALLOCSIZE; 1680 + return 0; 1681 + case Opt_grpid: 1682 + case Opt_bsdgroups: 1683 + mp->m_flags |= XFS_MOUNT_GRPID; 1684 + return 0; 1685 + case Opt_nogrpid: 1686 + case Opt_sysvgroups: 1687 + mp->m_flags &= ~XFS_MOUNT_GRPID; 1688 + return 0; 1689 + case Opt_wsync: 1690 + mp->m_flags |= XFS_MOUNT_WSYNC; 1691 + return 0; 1692 + case Opt_norecovery: 1693 + mp->m_flags |= XFS_MOUNT_NORECOVERY; 1694 + return 0; 1695 + case Opt_noalign: 1696 + mp->m_flags |= XFS_MOUNT_NOALIGN; 1697 + return 0; 1698 + case Opt_swalloc: 1699 + mp->m_flags |= XFS_MOUNT_SWALLOC; 1700 + return 0; 1701 + case Opt_sunit: 1702 + mp->m_dalign = result.uint_32; 1703 + return 0; 1704 + case Opt_swidth: 1705 + mp->m_swidth = result.uint_32; 1706 + return 0; 1707 + case Opt_inode32: 1708 + mp->m_flags |= XFS_MOUNT_SMALL_INUMS; 1709 + return 0; 1710 + case Opt_inode64: 1711 + mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; 1712 + return 0; 1713 + case Opt_nouuid: 1714 + mp->m_flags |= XFS_MOUNT_NOUUID; 1715 + return 0; 1716 + case Opt_ikeep: 1717 + mp->m_flags |= XFS_MOUNT_IKEEP; 1718 + return 0; 1719 + case Opt_noikeep: 1720 + mp->m_flags &= ~XFS_MOUNT_IKEEP; 1721 + return 0; 1722 + case Opt_largeio: 1723 + mp->m_flags |= XFS_MOUNT_LARGEIO; 1724 + return 0; 1725 + case Opt_nolargeio: 1726 + mp->m_flags &= ~XFS_MOUNT_LARGEIO; 1727 + return 0; 1728 + case Opt_attr2: 1729 + mp->m_flags |= XFS_MOUNT_ATTR2; 1730 + return 0; 1731 + case Opt_noattr2: 1732 + mp->m_flags &= ~XFS_MOUNT_ATTR2; 1733 + mp->m_flags |= XFS_MOUNT_NOATTR2; 1734 + return 0; 1735 + case Opt_filestreams: 1736 + mp->m_flags |= XFS_MOUNT_FILESTREAMS; 1737 + return 0; 1738 + case Opt_noquota: 1739 + mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; 1740 + mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; 1741 + mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; 1742 + return 0; 1743 + case Opt_quota: 1744 + case Opt_uquota: 1745 + case Opt_usrquota: 1746 + mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | 1747 + XFS_UQUOTA_ENFD); 1748 + return 0; 1749 + case Opt_qnoenforce: 1750 + case Opt_uqnoenforce: 1751 + mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); 1752 + mp->m_qflags &= ~XFS_UQUOTA_ENFD; 1753 + return 0; 1754 + case Opt_pquota: 1755 + case Opt_prjquota: 1756 + mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | 1757 + XFS_PQUOTA_ENFD); 1758 + return 0; 1759 + case Opt_pqnoenforce: 1760 + mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); 1761 + mp->m_qflags &= ~XFS_PQUOTA_ENFD; 1762 + return 0; 1763 + case Opt_gquota: 1764 + case Opt_grpquota: 1765 + mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | 1766 + XFS_GQUOTA_ENFD); 1767 + return 0; 1768 + case Opt_gqnoenforce: 1769 + mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); 1770 + mp->m_qflags &= ~XFS_GQUOTA_ENFD; 1771 + return 0; 1772 + case Opt_discard: 1773 + mp->m_flags |= XFS_MOUNT_DISCARD; 1774 + return 0; 1775 + case Opt_nodiscard: 1776 + mp->m_flags &= ~XFS_MOUNT_DISCARD; 1777 + return 0; 1778 + #ifdef CONFIG_FS_DAX 1779 + case Opt_dax: 1780 + mp->m_flags |= XFS_MOUNT_DAX; 1781 + return 0; 1782 + #endif 1783 + default: 1784 + xfs_warn(mp, "unknown mount option [%s].", param->key); 1785 + return -EINVAL; 1786 + } 1787 + 1788 + return 0; 1789 + } 1790 + 1791 + static int 1792 + xfs_fc_validate_params( 1793 + struct xfs_mount *mp) 1794 + { 1083 1795 /* 1084 - * allocate mp and do all low-level struct initializations before we 1085 - * attach it to the super 1796 + * no recovery flag requires a read-only mount 1086 1797 */ 1087 - mp = xfs_mount_alloc(sb); 1088 - if (!mp) 1089 - goto out; 1090 - sb->s_fs_info = mp; 1798 + if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && 1799 + !(mp->m_flags & XFS_MOUNT_RDONLY)) { 1800 + xfs_warn(mp, "no-recovery mounts must be read-only."); 1801 + return -EINVAL; 1802 + } 1091 1803 1092 - error = xfs_parseargs(mp, (char *)data); 1804 + if ((mp->m_flags & XFS_MOUNT_NOALIGN) && 1805 + (mp->m_dalign || mp->m_swidth)) { 1806 + xfs_warn(mp, 1807 + "sunit and swidth options incompatible with the noalign option"); 1808 + return -EINVAL; 1809 + } 1810 + 1811 + if (!IS_ENABLED(CONFIG_XFS_QUOTA) && mp->m_qflags != 0) { 1812 + xfs_warn(mp, "quota support not available in this kernel."); 1813 + return -EINVAL; 1814 + } 1815 + 1816 + if ((mp->m_dalign && !mp->m_swidth) || 1817 + (!mp->m_dalign && mp->m_swidth)) { 1818 + xfs_warn(mp, "sunit and swidth must be specified together"); 1819 + return -EINVAL; 1820 + } 1821 + 1822 + if (mp->m_dalign && (mp->m_swidth % mp->m_dalign != 0)) { 1823 + xfs_warn(mp, 1824 + "stripe width (%d) must be a multiple of the stripe unit (%d)", 1825 + mp->m_swidth, mp->m_dalign); 1826 + return -EINVAL; 1827 + } 1828 + 1829 + if (mp->m_logbufs != -1 && 1830 + mp->m_logbufs != 0 && 1831 + (mp->m_logbufs < XLOG_MIN_ICLOGS || 1832 + mp->m_logbufs > XLOG_MAX_ICLOGS)) { 1833 + xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", 1834 + mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); 1835 + return -EINVAL; 1836 + } 1837 + 1838 + if (mp->m_logbsize != -1 && 1839 + mp->m_logbsize != 0 && 1840 + (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || 1841 + mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || 1842 + !is_power_of_2(mp->m_logbsize))) { 1843 + xfs_warn(mp, 1844 + "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", 1845 + mp->m_logbsize); 1846 + return -EINVAL; 1847 + } 1848 + 1849 + if ((mp->m_flags & XFS_MOUNT_ALLOCSIZE) && 1850 + (mp->m_allocsize_log > XFS_MAX_IO_LOG || 1851 + mp->m_allocsize_log < XFS_MIN_IO_LOG)) { 1852 + xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", 1853 + mp->m_allocsize_log, XFS_MIN_IO_LOG, XFS_MAX_IO_LOG); 1854 + return -EINVAL; 1855 + } 1856 + 1857 + return 0; 1858 + } 1859 + 1860 + static int 1861 + xfs_fc_fill_super( 1862 + struct super_block *sb, 1863 + struct fs_context *fc) 1864 + { 1865 + struct xfs_mount *mp = sb->s_fs_info; 1866 + struct inode *root; 1867 + int flags = 0, error; 1868 + 1869 + mp->m_super = sb; 1870 + 1871 + error = xfs_fc_validate_params(mp); 1093 1872 if (error) 1094 - goto out_free_fsname; 1873 + goto out_free_names; 1095 1874 1096 1875 sb_min_blocksize(sb, BBSIZE); 1097 1876 sb->s_xattr = xfs_xattr_handlers; ··· 1390 1615 msleep(xfs_globals.mount_delay * 1000); 1391 1616 } 1392 1617 1393 - if (silent) 1618 + if (fc->sb_flags & SB_SILENT) 1394 1619 flags |= XFS_MFSI_QUIET; 1395 1620 1396 1621 error = xfs_open_devices(mp); 1397 1622 if (error) 1398 - goto out_free_fsname; 1623 + goto out_free_names; 1399 1624 1400 1625 error = xfs_init_mount_workqueues(mp); 1401 1626 if (error) ··· 1532 1757 xfs_destroy_mount_workqueues(mp); 1533 1758 out_close_devices: 1534 1759 xfs_close_devices(mp); 1535 - out_free_fsname: 1760 + out_free_names: 1536 1761 sb->s_fs_info = NULL; 1537 - xfs_free_fsname(mp); 1538 - kfree(mp); 1539 - out: 1762 + xfs_mount_free(mp); 1540 1763 return error; 1541 1764 1542 1765 out_unmount: ··· 1543 1770 goto out_free_sb; 1544 1771 } 1545 1772 1546 - STATIC void 1547 - xfs_fs_put_super( 1548 - struct super_block *sb) 1773 + static int 1774 + xfs_fc_get_tree( 1775 + struct fs_context *fc) 1549 1776 { 1550 - struct xfs_mount *mp = XFS_M(sb); 1551 - 1552 - /* if ->fill_super failed, we have no mount to tear down */ 1553 - if (!sb->s_fs_info) 1554 - return; 1555 - 1556 - xfs_notice(mp, "Unmounting Filesystem"); 1557 - xfs_filestream_unmount(mp); 1558 - xfs_unmountfs(mp); 1559 - 1560 - xfs_freesb(mp); 1561 - free_percpu(mp->m_stats.xs_stats); 1562 - xfs_destroy_percpu_counters(mp); 1563 - xfs_destroy_mount_workqueues(mp); 1564 - xfs_close_devices(mp); 1565 - 1566 - sb->s_fs_info = NULL; 1567 - xfs_free_fsname(mp); 1568 - kfree(mp); 1777 + return get_tree_bdev(fc, xfs_fc_fill_super); 1569 1778 } 1570 1779 1571 - STATIC struct dentry * 1572 - xfs_fs_mount( 1573 - struct file_system_type *fs_type, 1574 - int flags, 1575 - const char *dev_name, 1576 - void *data) 1780 + static int 1781 + xfs_remount_rw( 1782 + struct xfs_mount *mp) 1577 1783 { 1578 - return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); 1784 + struct xfs_sb *sbp = &mp->m_sb; 1785 + int error; 1786 + 1787 + if (mp->m_flags & XFS_MOUNT_NORECOVERY) { 1788 + xfs_warn(mp, 1789 + "ro->rw transition prohibited on norecovery mount"); 1790 + return -EINVAL; 1791 + } 1792 + 1793 + if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && 1794 + xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { 1795 + xfs_warn(mp, 1796 + "ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem", 1797 + (sbp->sb_features_ro_compat & 1798 + XFS_SB_FEAT_RO_COMPAT_UNKNOWN)); 1799 + return -EINVAL; 1800 + } 1801 + 1802 + mp->m_flags &= ~XFS_MOUNT_RDONLY; 1803 + 1804 + /* 1805 + * If this is the first remount to writeable state we might have some 1806 + * superblock changes to update. 1807 + */ 1808 + if (mp->m_update_sb) { 1809 + error = xfs_sync_sb(mp, false); 1810 + if (error) { 1811 + xfs_warn(mp, "failed to write sb changes"); 1812 + return error; 1813 + } 1814 + mp->m_update_sb = false; 1815 + } 1816 + 1817 + /* 1818 + * Fill out the reserve pool if it is empty. Use the stashed value if 1819 + * it is non-zero, otherwise go with the default. 1820 + */ 1821 + xfs_restore_resvblks(mp); 1822 + xfs_log_work_queue(mp); 1823 + 1824 + /* Recover any CoW blocks that never got remapped. */ 1825 + error = xfs_reflink_recover_cow(mp); 1826 + if (error) { 1827 + xfs_err(mp, 1828 + "Error %d recovering leftover CoW allocations.", error); 1829 + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1830 + return error; 1831 + } 1832 + xfs_start_block_reaping(mp); 1833 + 1834 + /* Create the per-AG metadata reservation pool .*/ 1835 + error = xfs_fs_reserve_ag_blocks(mp); 1836 + if (error && error != -ENOSPC) 1837 + return error; 1838 + 1839 + return 0; 1579 1840 } 1580 1841 1581 - static long 1582 - xfs_fs_nr_cached_objects( 1583 - struct super_block *sb, 1584 - struct shrink_control *sc) 1842 + static int 1843 + xfs_remount_ro( 1844 + struct xfs_mount *mp) 1585 1845 { 1586 - /* Paranoia: catch incorrect calls during mount setup or teardown */ 1587 - if (WARN_ON_ONCE(!sb->s_fs_info)) 1588 - return 0; 1589 - return xfs_reclaim_inodes_count(XFS_M(sb)); 1846 + int error; 1847 + 1848 + /* 1849 + * Cancel background eofb scanning so it cannot race with the final 1850 + * log force+buftarg wait and deadlock the remount. 1851 + */ 1852 + xfs_stop_block_reaping(mp); 1853 + 1854 + /* Get rid of any leftover CoW reservations... */ 1855 + error = xfs_icache_free_cowblocks(mp, NULL); 1856 + if (error) { 1857 + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1858 + return error; 1859 + } 1860 + 1861 + /* Free the per-AG metadata reservation pool. */ 1862 + error = xfs_fs_unreserve_ag_blocks(mp); 1863 + if (error) { 1864 + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 1865 + return error; 1866 + } 1867 + 1868 + /* 1869 + * Before we sync the metadata, we need to free up the reserve block 1870 + * pool so that the used block count in the superblock on disk is 1871 + * correct at the end of the remount. Stash the current* reserve pool 1872 + * size so that if we get remounted rw, we can return it to the same 1873 + * size. 1874 + */ 1875 + xfs_save_resvblks(mp); 1876 + 1877 + xfs_quiesce_attr(mp); 1878 + mp->m_flags |= XFS_MOUNT_RDONLY; 1879 + 1880 + return 0; 1590 1881 } 1591 1882 1592 - static long 1593 - xfs_fs_free_cached_objects( 1594 - struct super_block *sb, 1595 - struct shrink_control *sc) 1883 + /* 1884 + * Logically we would return an error here to prevent users from believing 1885 + * they might have changed mount options using remount which can't be changed. 1886 + * 1887 + * But unfortunately mount(8) adds all options from mtab and fstab to the mount 1888 + * arguments in some cases so we can't blindly reject options, but have to 1889 + * check for each specified option if it actually differs from the currently 1890 + * set option and only reject it if that's the case. 1891 + * 1892 + * Until that is implemented we return success for every remount request, and 1893 + * silently ignore all options that we can't actually change. 1894 + */ 1895 + static int 1896 + xfs_fc_reconfigure( 1897 + struct fs_context *fc) 1596 1898 { 1597 - return xfs_reclaim_inodes_nr(XFS_M(sb), sc->nr_to_scan); 1899 + struct xfs_mount *mp = XFS_M(fc->root->d_sb); 1900 + struct xfs_mount *new_mp = fc->s_fs_info; 1901 + xfs_sb_t *sbp = &mp->m_sb; 1902 + int flags = fc->sb_flags; 1903 + int error; 1904 + 1905 + error = xfs_fc_validate_params(new_mp); 1906 + if (error) 1907 + return error; 1908 + 1909 + sync_filesystem(mp->m_super); 1910 + 1911 + /* inode32 -> inode64 */ 1912 + if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && 1913 + !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) { 1914 + mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; 1915 + mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); 1916 + } 1917 + 1918 + /* inode64 -> inode32 */ 1919 + if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) && 1920 + (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) { 1921 + mp->m_flags |= XFS_MOUNT_SMALL_INUMS; 1922 + mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); 1923 + } 1924 + 1925 + /* ro -> rw */ 1926 + if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) { 1927 + error = xfs_remount_rw(mp); 1928 + if (error) 1929 + return error; 1930 + } 1931 + 1932 + /* rw -> ro */ 1933 + if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) { 1934 + error = xfs_remount_ro(mp); 1935 + if (error) 1936 + return error; 1937 + } 1938 + 1939 + return 0; 1598 1940 } 1599 1941 1600 - static const struct super_operations xfs_super_operations = { 1601 - .alloc_inode = xfs_fs_alloc_inode, 1602 - .destroy_inode = xfs_fs_destroy_inode, 1603 - .dirty_inode = xfs_fs_dirty_inode, 1604 - .drop_inode = xfs_fs_drop_inode, 1605 - .put_super = xfs_fs_put_super, 1606 - .sync_fs = xfs_fs_sync_fs, 1607 - .freeze_fs = xfs_fs_freeze, 1608 - .unfreeze_fs = xfs_fs_unfreeze, 1609 - .statfs = xfs_fs_statfs, 1610 - .remount_fs = xfs_fs_remount, 1611 - .show_options = xfs_fs_show_options, 1612 - .nr_cached_objects = xfs_fs_nr_cached_objects, 1613 - .free_cached_objects = xfs_fs_free_cached_objects, 1942 + static void xfs_fc_free( 1943 + struct fs_context *fc) 1944 + { 1945 + struct xfs_mount *mp = fc->s_fs_info; 1946 + 1947 + /* 1948 + * mp is stored in the fs_context when it is initialized. 1949 + * mp is transferred to the superblock on a successful mount, 1950 + * but if an error occurs before the transfer we have to free 1951 + * it here. 1952 + */ 1953 + if (mp) 1954 + xfs_mount_free(mp); 1955 + } 1956 + 1957 + static const struct fs_context_operations xfs_context_ops = { 1958 + .parse_param = xfs_fc_parse_param, 1959 + .get_tree = xfs_fc_get_tree, 1960 + .reconfigure = xfs_fc_reconfigure, 1961 + .free = xfs_fc_free, 1614 1962 }; 1963 + 1964 + static int xfs_init_fs_context( 1965 + struct fs_context *fc) 1966 + { 1967 + struct xfs_mount *mp; 1968 + 1969 + mp = kmem_alloc(sizeof(struct xfs_mount), KM_ZERO); 1970 + if (!mp) 1971 + return -ENOMEM; 1972 + 1973 + spin_lock_init(&mp->m_sb_lock); 1974 + spin_lock_init(&mp->m_agirotor_lock); 1975 + INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); 1976 + spin_lock_init(&mp->m_perag_lock); 1977 + mutex_init(&mp->m_growlock); 1978 + atomic_set(&mp->m_active_trans, 0); 1979 + INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); 1980 + INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); 1981 + INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker); 1982 + mp->m_kobj.kobject.kset = xfs_kset; 1983 + /* 1984 + * We don't create the finobt per-ag space reservation until after log 1985 + * recovery, so we must set this to true so that an ifree transaction 1986 + * started during log recovery will not depend on space reservations 1987 + * for finobt expansion. 1988 + */ 1989 + mp->m_finobt_nores = true; 1990 + 1991 + /* 1992 + * These can be overridden by the mount option parsing. 1993 + */ 1994 + mp->m_logbufs = -1; 1995 + mp->m_logbsize = -1; 1996 + mp->m_allocsize_log = 16; /* 64k */ 1997 + 1998 + /* 1999 + * Copy binary VFS mount flags we are interested in. 2000 + */ 2001 + if (fc->sb_flags & SB_RDONLY) 2002 + mp->m_flags |= XFS_MOUNT_RDONLY; 2003 + if (fc->sb_flags & SB_DIRSYNC) 2004 + mp->m_flags |= XFS_MOUNT_DIRSYNC; 2005 + if (fc->sb_flags & SB_SYNCHRONOUS) 2006 + mp->m_flags |= XFS_MOUNT_WSYNC; 2007 + 2008 + fc->s_fs_info = mp; 2009 + fc->ops = &xfs_context_ops; 2010 + 2011 + return 0; 2012 + } 1615 2013 1616 2014 static struct file_system_type xfs_fs_type = { 1617 2015 .owner = THIS_MODULE, 1618 2016 .name = "xfs", 1619 - .mount = xfs_fs_mount, 2017 + .init_fs_context = xfs_init_fs_context, 2018 + .parameters = &xfs_fs_parameters, 1620 2019 .kill_sb = kill_block_super, 1621 2020 .fs_flags = FS_REQUIRES_DEV, 1622 2021 }; ··· 1797 1852 STATIC int __init 1798 1853 xfs_init_zones(void) 1799 1854 { 1800 - xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t), 1801 - "xfs_log_ticket"); 1855 + xfs_log_ticket_zone = kmem_cache_create("xfs_log_ticket", 1856 + sizeof(struct xlog_ticket), 1857 + 0, 0, NULL); 1802 1858 if (!xfs_log_ticket_zone) 1803 1859 goto out; 1804 1860 1805 - xfs_bmap_free_item_zone = kmem_zone_init( 1806 - sizeof(struct xfs_extent_free_item), 1807 - "xfs_bmap_free_item"); 1861 + xfs_bmap_free_item_zone = kmem_cache_create("xfs_bmap_free_item", 1862 + sizeof(struct xfs_extent_free_item), 1863 + 0, 0, NULL); 1808 1864 if (!xfs_bmap_free_item_zone) 1809 1865 goto out_destroy_log_ticket_zone; 1810 1866 1811 - xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), 1812 - "xfs_btree_cur"); 1867 + xfs_btree_cur_zone = kmem_cache_create("xfs_btree_cur", 1868 + sizeof(struct xfs_btree_cur), 1869 + 0, 0, NULL); 1813 1870 if (!xfs_btree_cur_zone) 1814 1871 goto out_destroy_bmap_free_item_zone; 1815 1872 1816 - xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t), 1817 - "xfs_da_state"); 1873 + xfs_da_state_zone = kmem_cache_create("xfs_da_state", 1874 + sizeof(struct xfs_da_state), 1875 + 0, 0, NULL); 1818 1876 if (!xfs_da_state_zone) 1819 1877 goto out_destroy_btree_cur_zone; 1820 1878 1821 - xfs_ifork_zone = kmem_zone_init(sizeof(struct xfs_ifork), "xfs_ifork"); 1879 + xfs_ifork_zone = kmem_cache_create("xfs_ifork", 1880 + sizeof(struct xfs_ifork), 1881 + 0, 0, NULL); 1822 1882 if (!xfs_ifork_zone) 1823 1883 goto out_destroy_da_state_zone; 1824 1884 1825 - xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); 1885 + xfs_trans_zone = kmem_cache_create("xf_trans", 1886 + sizeof(struct xfs_trans), 1887 + 0, 0, NULL); 1826 1888 if (!xfs_trans_zone) 1827 1889 goto out_destroy_ifork_zone; 1828 1890 ··· 1839 1887 * size possible under XFS. This wastes a little bit of memory, 1840 1888 * but it is much faster. 1841 1889 */ 1842 - xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item), 1843 - "xfs_buf_item"); 1890 + xfs_buf_item_zone = kmem_cache_create("xfs_buf_item", 1891 + sizeof(struct xfs_buf_log_item), 1892 + 0, 0, NULL); 1844 1893 if (!xfs_buf_item_zone) 1845 1894 goto out_destroy_trans_zone; 1846 1895 1847 - xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + 1848 - ((XFS_EFD_MAX_FAST_EXTENTS - 1) * 1849 - sizeof(xfs_extent_t))), "xfs_efd_item"); 1896 + xfs_efd_zone = kmem_cache_create("xfs_efd_item", 1897 + (sizeof(struct xfs_efd_log_item) + 1898 + (XFS_EFD_MAX_FAST_EXTENTS - 1) * 1899 + sizeof(struct xfs_extent)), 1900 + 0, 0, NULL); 1850 1901 if (!xfs_efd_zone) 1851 1902 goto out_destroy_buf_item_zone; 1852 1903 1853 - xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) + 1854 - ((XFS_EFI_MAX_FAST_EXTENTS - 1) * 1855 - sizeof(xfs_extent_t))), "xfs_efi_item"); 1904 + xfs_efi_zone = kmem_cache_create("xfs_efi_item", 1905 + (sizeof(struct xfs_efi_log_item) + 1906 + (XFS_EFI_MAX_FAST_EXTENTS - 1) * 1907 + sizeof(struct xfs_extent)), 1908 + 0, 0, NULL); 1856 1909 if (!xfs_efi_zone) 1857 1910 goto out_destroy_efd_zone; 1858 1911 1859 - xfs_inode_zone = 1860 - kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", 1861 - KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD | 1862 - KM_ZONE_ACCOUNT, xfs_fs_inode_init_once); 1912 + xfs_inode_zone = kmem_cache_create("xfs_inode", 1913 + sizeof(struct xfs_inode), 0, 1914 + (SLAB_HWCACHE_ALIGN | 1915 + SLAB_RECLAIM_ACCOUNT | 1916 + SLAB_MEM_SPREAD | SLAB_ACCOUNT), 1917 + xfs_fs_inode_init_once); 1863 1918 if (!xfs_inode_zone) 1864 1919 goto out_destroy_efi_zone; 1865 1920 1866 - xfs_ili_zone = 1867 - kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", 1868 - KM_ZONE_SPREAD, NULL); 1921 + xfs_ili_zone = kmem_cache_create("xfs_ili", 1922 + sizeof(struct xfs_inode_log_item), 0, 1923 + SLAB_MEM_SPREAD, NULL); 1869 1924 if (!xfs_ili_zone) 1870 1925 goto out_destroy_inode_zone; 1871 - xfs_icreate_zone = kmem_zone_init(sizeof(struct xfs_icreate_item), 1872 - "xfs_icr"); 1926 + 1927 + xfs_icreate_zone = kmem_cache_create("xfs_icr", 1928 + sizeof(struct xfs_icreate_item), 1929 + 0, 0, NULL); 1873 1930 if (!xfs_icreate_zone) 1874 1931 goto out_destroy_ili_zone; 1875 1932 1876 - xfs_rud_zone = kmem_zone_init(sizeof(struct xfs_rud_log_item), 1877 - "xfs_rud_item"); 1933 + xfs_rud_zone = kmem_cache_create("xfs_rud_item", 1934 + sizeof(struct xfs_rud_log_item), 1935 + 0, 0, NULL); 1878 1936 if (!xfs_rud_zone) 1879 1937 goto out_destroy_icreate_zone; 1880 1938 1881 - xfs_rui_zone = kmem_zone_init( 1939 + xfs_rui_zone = kmem_cache_create("xfs_rui_item", 1882 1940 xfs_rui_log_item_sizeof(XFS_RUI_MAX_FAST_EXTENTS), 1883 - "xfs_rui_item"); 1941 + 0, 0, NULL); 1884 1942 if (!xfs_rui_zone) 1885 1943 goto out_destroy_rud_zone; 1886 1944 1887 - xfs_cud_zone = kmem_zone_init(sizeof(struct xfs_cud_log_item), 1888 - "xfs_cud_item"); 1945 + xfs_cud_zone = kmem_cache_create("xfs_cud_item", 1946 + sizeof(struct xfs_cud_log_item), 1947 + 0, 0, NULL); 1889 1948 if (!xfs_cud_zone) 1890 1949 goto out_destroy_rui_zone; 1891 1950 1892 - xfs_cui_zone = kmem_zone_init( 1951 + xfs_cui_zone = kmem_cache_create("xfs_cui_item", 1893 1952 xfs_cui_log_item_sizeof(XFS_CUI_MAX_FAST_EXTENTS), 1894 - "xfs_cui_item"); 1953 + 0, 0, NULL); 1895 1954 if (!xfs_cui_zone) 1896 1955 goto out_destroy_cud_zone; 1897 1956 1898 - xfs_bud_zone = kmem_zone_init(sizeof(struct xfs_bud_log_item), 1899 - "xfs_bud_item"); 1957 + xfs_bud_zone = kmem_cache_create("xfs_bud_item", 1958 + sizeof(struct xfs_bud_log_item), 1959 + 0, 0, NULL); 1900 1960 if (!xfs_bud_zone) 1901 1961 goto out_destroy_cui_zone; 1902 1962 1903 - xfs_bui_zone = kmem_zone_init( 1963 + xfs_bui_zone = kmem_cache_create("xfs_bui_item", 1904 1964 xfs_bui_log_item_sizeof(XFS_BUI_MAX_FAST_EXTENTS), 1905 - "xfs_bui_item"); 1965 + 0, 0, NULL); 1906 1966 if (!xfs_bui_zone) 1907 1967 goto out_destroy_bud_zone; 1908 1968 1909 1969 return 0; 1910 1970 1911 1971 out_destroy_bud_zone: 1912 - kmem_zone_destroy(xfs_bud_zone); 1972 + kmem_cache_destroy(xfs_bud_zone); 1913 1973 out_destroy_cui_zone: 1914 - kmem_zone_destroy(xfs_cui_zone); 1974 + kmem_cache_destroy(xfs_cui_zone); 1915 1975 out_destroy_cud_zone: 1916 - kmem_zone_destroy(xfs_cud_zone); 1976 + kmem_cache_destroy(xfs_cud_zone); 1917 1977 out_destroy_rui_zone: 1918 - kmem_zone_destroy(xfs_rui_zone); 1978 + kmem_cache_destroy(xfs_rui_zone); 1919 1979 out_destroy_rud_zone: 1920 - kmem_zone_destroy(xfs_rud_zone); 1980 + kmem_cache_destroy(xfs_rud_zone); 1921 1981 out_destroy_icreate_zone: 1922 - kmem_zone_destroy(xfs_icreate_zone); 1982 + kmem_cache_destroy(xfs_icreate_zone); 1923 1983 out_destroy_ili_zone: 1924 - kmem_zone_destroy(xfs_ili_zone); 1984 + kmem_cache_destroy(xfs_ili_zone); 1925 1985 out_destroy_inode_zone: 1926 - kmem_zone_destroy(xfs_inode_zone); 1986 + kmem_cache_destroy(xfs_inode_zone); 1927 1987 out_destroy_efi_zone: 1928 - kmem_zone_destroy(xfs_efi_zone); 1988 + kmem_cache_destroy(xfs_efi_zone); 1929 1989 out_destroy_efd_zone: 1930 - kmem_zone_destroy(xfs_efd_zone); 1990 + kmem_cache_destroy(xfs_efd_zone); 1931 1991 out_destroy_buf_item_zone: 1932 - kmem_zone_destroy(xfs_buf_item_zone); 1992 + kmem_cache_destroy(xfs_buf_item_zone); 1933 1993 out_destroy_trans_zone: 1934 - kmem_zone_destroy(xfs_trans_zone); 1994 + kmem_cache_destroy(xfs_trans_zone); 1935 1995 out_destroy_ifork_zone: 1936 - kmem_zone_destroy(xfs_ifork_zone); 1996 + kmem_cache_destroy(xfs_ifork_zone); 1937 1997 out_destroy_da_state_zone: 1938 - kmem_zone_destroy(xfs_da_state_zone); 1998 + kmem_cache_destroy(xfs_da_state_zone); 1939 1999 out_destroy_btree_cur_zone: 1940 - kmem_zone_destroy(xfs_btree_cur_zone); 2000 + kmem_cache_destroy(xfs_btree_cur_zone); 1941 2001 out_destroy_bmap_free_item_zone: 1942 - kmem_zone_destroy(xfs_bmap_free_item_zone); 2002 + kmem_cache_destroy(xfs_bmap_free_item_zone); 1943 2003 out_destroy_log_ticket_zone: 1944 - kmem_zone_destroy(xfs_log_ticket_zone); 2004 + kmem_cache_destroy(xfs_log_ticket_zone); 1945 2005 out: 1946 2006 return -ENOMEM; 1947 2007 } ··· 1966 2002 * destroy caches. 1967 2003 */ 1968 2004 rcu_barrier(); 1969 - kmem_zone_destroy(xfs_bui_zone); 1970 - kmem_zone_destroy(xfs_bud_zone); 1971 - kmem_zone_destroy(xfs_cui_zone); 1972 - kmem_zone_destroy(xfs_cud_zone); 1973 - kmem_zone_destroy(xfs_rui_zone); 1974 - kmem_zone_destroy(xfs_rud_zone); 1975 - kmem_zone_destroy(xfs_icreate_zone); 1976 - kmem_zone_destroy(xfs_ili_zone); 1977 - kmem_zone_destroy(xfs_inode_zone); 1978 - kmem_zone_destroy(xfs_efi_zone); 1979 - kmem_zone_destroy(xfs_efd_zone); 1980 - kmem_zone_destroy(xfs_buf_item_zone); 1981 - kmem_zone_destroy(xfs_trans_zone); 1982 - kmem_zone_destroy(xfs_ifork_zone); 1983 - kmem_zone_destroy(xfs_da_state_zone); 1984 - kmem_zone_destroy(xfs_btree_cur_zone); 1985 - kmem_zone_destroy(xfs_bmap_free_item_zone); 1986 - kmem_zone_destroy(xfs_log_ticket_zone); 2005 + kmem_cache_destroy(xfs_bui_zone); 2006 + kmem_cache_destroy(xfs_bud_zone); 2007 + kmem_cache_destroy(xfs_cui_zone); 2008 + kmem_cache_destroy(xfs_cud_zone); 2009 + kmem_cache_destroy(xfs_rui_zone); 2010 + kmem_cache_destroy(xfs_rud_zone); 2011 + kmem_cache_destroy(xfs_icreate_zone); 2012 + kmem_cache_destroy(xfs_ili_zone); 2013 + kmem_cache_destroy(xfs_inode_zone); 2014 + kmem_cache_destroy(xfs_efi_zone); 2015 + kmem_cache_destroy(xfs_efd_zone); 2016 + kmem_cache_destroy(xfs_buf_item_zone); 2017 + kmem_cache_destroy(xfs_trans_zone); 2018 + kmem_cache_destroy(xfs_ifork_zone); 2019 + kmem_cache_destroy(xfs_da_state_zone); 2020 + kmem_cache_destroy(xfs_btree_cur_zone); 2021 + kmem_cache_destroy(xfs_bmap_free_item_zone); 2022 + kmem_cache_destroy(xfs_log_ticket_zone); 1987 2023 } 1988 2024 1989 2025 STATIC int __init
+10
fs/xfs/xfs_super.h
··· 11 11 #ifdef CONFIG_XFS_QUOTA 12 12 extern int xfs_qm_init(void); 13 13 extern void xfs_qm_exit(void); 14 + # define XFS_QUOTA_STRING "quota, " 14 15 #else 15 16 # define xfs_qm_init() (0) 16 17 # define xfs_qm_exit() do { } while (0) 18 + # define XFS_QUOTA_STRING 17 19 #endif 18 20 19 21 #ifdef CONFIG_XFS_POSIX_ACL ··· 52 50 # define XFS_WARN_STRING 53 51 #endif 54 52 53 + #ifdef CONFIG_XFS_ASSERT_FATAL 54 + # define XFS_ASSERT_FATAL_STRING "fatal assert, " 55 + #else 56 + # define XFS_ASSERT_FATAL_STRING 57 + #endif 58 + 55 59 #ifdef DEBUG 56 60 # define XFS_DBG_STRING "debug" 57 61 #else ··· 71 63 XFS_SCRUB_STRING \ 72 64 XFS_REPAIR_STRING \ 73 65 XFS_WARN_STRING \ 66 + XFS_QUOTA_STRING \ 67 + XFS_ASSERT_FATAL_STRING \ 74 68 XFS_DBG_STRING /* DBG must be last */ 75 69 76 70 struct xfs_inode;
+1
fs/xfs/xfs_symlink.c
··· 17 17 #include "xfs_bmap.h" 18 18 #include "xfs_bmap_btree.h" 19 19 #include "xfs_quota.h" 20 + #include "xfs_symlink.h" 20 21 #include "xfs_trans_space.h" 21 22 #include "xfs_trace.h" 22 23 #include "xfs_trans.h"
+1 -1
fs/xfs/xfs_symlink.h
··· 5 5 #ifndef __XFS_SYMLINK_H 6 6 #define __XFS_SYMLINK_H 1 7 7 8 - /* Kernel only symlink defintions */ 8 + /* Kernel only symlink definitions */ 9 9 10 10 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, 11 11 const char *target_path, umode_t mode, struct xfs_inode **ipp);
+32 -3
fs/xfs/xfs_trace.h
··· 725 725 __entry->writeio_blocks = writeio_blocks; 726 726 ), 727 727 TP_printk("dev %d:%d ino 0x%llx prealloc blocks %llu shift %d " 728 - "m_writeio_blocks %u", 728 + "m_allocsize_blocks %u", 729 729 MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, 730 730 __entry->blocks, __entry->shift, __entry->writeio_blocks) 731 731 ) ··· 1577 1577 DEFINE_ALLOC_EVENT(xfs_alloc_exact_error); 1578 1578 DEFINE_ALLOC_EVENT(xfs_alloc_near_nominleft); 1579 1579 DEFINE_ALLOC_EVENT(xfs_alloc_near_first); 1580 - DEFINE_ALLOC_EVENT(xfs_alloc_near_greater); 1581 - DEFINE_ALLOC_EVENT(xfs_alloc_near_lesser); 1580 + DEFINE_ALLOC_EVENT(xfs_alloc_cur); 1581 + DEFINE_ALLOC_EVENT(xfs_alloc_cur_right); 1582 + DEFINE_ALLOC_EVENT(xfs_alloc_cur_left); 1583 + DEFINE_ALLOC_EVENT(xfs_alloc_cur_lookup); 1584 + DEFINE_ALLOC_EVENT(xfs_alloc_cur_lookup_done); 1582 1585 DEFINE_ALLOC_EVENT(xfs_alloc_near_error); 1583 1586 DEFINE_ALLOC_EVENT(xfs_alloc_near_noentry); 1584 1587 DEFINE_ALLOC_EVENT(xfs_alloc_near_busy); ··· 1600 1597 DEFINE_ALLOC_EVENT(xfs_alloc_vextent_noagbp); 1601 1598 DEFINE_ALLOC_EVENT(xfs_alloc_vextent_loopfailed); 1602 1599 DEFINE_ALLOC_EVENT(xfs_alloc_vextent_allfailed); 1600 + 1601 + TRACE_EVENT(xfs_alloc_cur_check, 1602 + TP_PROTO(struct xfs_mount *mp, xfs_btnum_t btnum, xfs_agblock_t bno, 1603 + xfs_extlen_t len, xfs_extlen_t diff, bool new), 1604 + TP_ARGS(mp, btnum, bno, len, diff, new), 1605 + TP_STRUCT__entry( 1606 + __field(dev_t, dev) 1607 + __field(xfs_btnum_t, btnum) 1608 + __field(xfs_agblock_t, bno) 1609 + __field(xfs_extlen_t, len) 1610 + __field(xfs_extlen_t, diff) 1611 + __field(bool, new) 1612 + ), 1613 + TP_fast_assign( 1614 + __entry->dev = mp->m_super->s_dev; 1615 + __entry->btnum = btnum; 1616 + __entry->bno = bno; 1617 + __entry->len = len; 1618 + __entry->diff = diff; 1619 + __entry->new = new; 1620 + ), 1621 + TP_printk("dev %d:%d btree %s bno 0x%x len 0x%x diff 0x%x new %d", 1622 + MAJOR(__entry->dev), MINOR(__entry->dev), 1623 + __print_symbolic(__entry->btnum, XFS_BTNUM_STRINGS), 1624 + __entry->bno, __entry->len, __entry->diff, __entry->new) 1625 + ) 1603 1626 1604 1627 DECLARE_EVENT_CLASS(xfs_da_class, 1605 1628 TP_PROTO(struct xfs_da_args *args),
+1 -1
fs/xfs/xfs_trans.c
··· 71 71 if (!(tp->t_flags & XFS_TRANS_NO_WRITECOUNT)) 72 72 sb_end_intwrite(tp->t_mountp->m_super); 73 73 xfs_trans_free_dqinfo(tp); 74 - kmem_zone_free(xfs_trans_zone, tp); 74 + kmem_cache_free(xfs_trans_zone, tp); 75 75 } 76 76 77 77 /*
+5 -5
fs/xfs/xfs_trans_ail.c
··· 427 427 428 428 case XFS_ITEM_FLUSHING: 429 429 /* 430 - * The item or its backing buffer is already beeing 430 + * The item or its backing buffer is already being 431 431 * flushed. The typical reason for that is that an 432 432 * inode buffer is locked because we already pushed the 433 433 * updates to it as part of inode clustering. 434 434 * 435 435 * We do not want to to stop flushing just because lots 436 - * of items are already beeing flushed, but we need to 436 + * of items are already being flushed, but we need to 437 437 * re-try the flushing relatively soon if most of the 438 - * AIL is beeing flushed. 438 + * AIL is being flushed. 439 439 */ 440 440 XFS_STATS_INC(mp, xs_push_ail_flushing); 441 441 trace_xfs_ail_flushing(lip); ··· 612 612 * The push is run asynchronously in a workqueue, which means the caller needs 613 613 * to handle waiting on the async flush for space to become available. 614 614 * We don't want to interrupt any push that is in progress, hence we only queue 615 - * work if we set the pushing bit approriately. 615 + * work if we set the pushing bit appropriately. 616 616 * 617 617 * We do this unlocked - we only need to know whether there is anything in the 618 618 * AIL at the time we are called. We don't need to access the contents of ··· 836 836 init_waitqueue_head(&ailp->ail_empty); 837 837 838 838 ailp->ail_task = kthread_run(xfsaild, ailp, "xfsaild/%s", 839 - ailp->ail_mount->m_fsname); 839 + ailp->ail_mount->m_super->s_id); 840 840 if (IS_ERR(ailp->ail_task)) 841 841 goto out_free_ailp; 842 842
+28 -28
fs/xfs/xfs_trans_dquot.c
··· 25 25 */ 26 26 void 27 27 xfs_trans_dqjoin( 28 - xfs_trans_t *tp, 29 - xfs_dquot_t *dqp) 28 + struct xfs_trans *tp, 29 + struct xfs_dquot *dqp) 30 30 { 31 31 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 32 32 ASSERT(dqp->q_logitem.qli_dquot == dqp); ··· 49 49 */ 50 50 void 51 51 xfs_trans_log_dquot( 52 - xfs_trans_t *tp, 53 - xfs_dquot_t *dqp) 52 + struct xfs_trans *tp, 53 + struct xfs_dquot *dqp) 54 54 { 55 55 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 56 56 ··· 486 486 */ 487 487 void 488 488 xfs_trans_unreserve_and_mod_dquots( 489 - xfs_trans_t *tp) 489 + struct xfs_trans *tp) 490 490 { 491 491 int i, j; 492 - xfs_dquot_t *dqp; 492 + struct xfs_dquot *dqp; 493 493 struct xfs_dqtrx *qtrx, *qa; 494 - bool locked; 494 + bool locked; 495 495 496 496 if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY)) 497 497 return; ··· 571 571 */ 572 572 STATIC int 573 573 xfs_trans_dqresv( 574 - xfs_trans_t *tp, 575 - xfs_mount_t *mp, 576 - xfs_dquot_t *dqp, 577 - int64_t nblks, 578 - long ninos, 579 - uint flags) 574 + struct xfs_trans *tp, 575 + struct xfs_mount *mp, 576 + struct xfs_dquot *dqp, 577 + int64_t nblks, 578 + long ninos, 579 + uint flags) 580 580 { 581 - xfs_qcnt_t hardlimit; 582 - xfs_qcnt_t softlimit; 583 - time_t timer; 584 - xfs_qwarncnt_t warns; 585 - xfs_qwarncnt_t warnlimit; 586 - xfs_qcnt_t total_count; 587 - xfs_qcnt_t *resbcountp; 588 - xfs_quotainfo_t *q = mp->m_quotainfo; 581 + xfs_qcnt_t hardlimit; 582 + xfs_qcnt_t softlimit; 583 + time_t timer; 584 + xfs_qwarncnt_t warns; 585 + xfs_qwarncnt_t warnlimit; 586 + xfs_qcnt_t total_count; 587 + xfs_qcnt_t *resbcountp; 588 + struct xfs_quotainfo *q = mp->m_quotainfo; 589 589 struct xfs_def_quota *defq; 590 590 591 591 ··· 824 824 /* 825 825 * This routine is called to allocate a quotaoff log item. 826 826 */ 827 - xfs_qoff_logitem_t * 827 + struct xfs_qoff_logitem * 828 828 xfs_trans_get_qoff_item( 829 - xfs_trans_t *tp, 830 - xfs_qoff_logitem_t *startqoff, 829 + struct xfs_trans *tp, 830 + struct xfs_qoff_logitem *startqoff, 831 831 uint flags) 832 832 { 833 - xfs_qoff_logitem_t *q; 833 + struct xfs_qoff_logitem *q; 834 834 835 835 ASSERT(tp != NULL); 836 836 ··· 852 852 */ 853 853 void 854 854 xfs_trans_log_quotaoff_item( 855 - xfs_trans_t *tp, 856 - xfs_qoff_logitem_t *qlp) 855 + struct xfs_trans *tp, 856 + struct xfs_qoff_logitem *qlp) 857 857 { 858 858 tp->t_flags |= XFS_TRANS_DIRTY; 859 859 set_bit(XFS_LI_DIRTY, &qlp->qql_item.li_flags); ··· 872 872 { 873 873 if (!tp->t_dqinfo) 874 874 return; 875 - kmem_zone_free(xfs_qm_dqtrxzone, tp->t_dqinfo); 875 + kmem_cache_free(xfs_qm_dqtrxzone, tp->t_dqinfo); 876 876 tp->t_dqinfo = NULL; 877 877 }
+1
fs/xfs/xfs_xattr.c
··· 11 11 #include "xfs_da_format.h" 12 12 #include "xfs_inode.h" 13 13 #include "xfs_attr.h" 14 + #include "xfs_acl.h" 14 15 15 16 #include <linux/posix_acl_xattr.h> 16 17 #include <linux/xattr.h>
+8 -2
include/linux/falloc.h
··· 20 20 }; 21 21 22 22 #define FS_IOC_RESVSP _IOW('X', 40, struct space_resv) 23 + #define FS_IOC_UNRESVSP _IOW('X', 41, struct space_resv) 23 24 #define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv) 25 + #define FS_IOC_UNRESVSP64 _IOW('X', 43, struct space_resv) 26 + #define FS_IOC_ZERO_RANGE _IOW('X', 57, struct space_resv) 24 27 25 28 #define FALLOC_FL_SUPPORTED_MASK (FALLOC_FL_KEEP_SIZE | \ 26 29 FALLOC_FL_PUNCH_HOLE | \ ··· 45 42 __s32 l_pad[4]; /* reserve area */ 46 43 }; 47 44 48 - #define FS_IOC_RESVSP_32 _IOW ('X', 40, struct space_resv_32) 45 + #define FS_IOC_RESVSP_32 _IOW ('X', 40, struct space_resv_32) 46 + #define FS_IOC_UNRESVSP_32 _IOW ('X', 41, struct space_resv_32) 49 47 #define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32) 48 + #define FS_IOC_UNRESVSP64_32 _IOW ('X', 43, struct space_resv_32) 49 + #define FS_IOC_ZERO_RANGE_32 _IOW ('X', 57, struct space_resv_32) 50 50 51 - int compat_ioctl_preallocate(struct file *, struct space_resv_32 __user *); 51 + int compat_ioctl_preallocate(struct file *, int, struct space_resv_32 __user *); 52 52 53 53 #endif 54 54
+1 -1
include/linux/fs.h
··· 2554 2554 2555 2555 /* fs/ioctl.c */ 2556 2556 2557 - extern int ioctl_preallocate(struct file *filp, void __user *argp); 2557 + extern int ioctl_preallocate(struct file *filp, int mode, void __user *argp); 2558 2558 2559 2559 /* fs/dcache.c */ 2560 2560 extern void __init vfs_caches_init_early(void);