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

Configure Feed

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

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

Pull xfs updates from Chandan Babu:
"New code:

- Introduce new ioctls to exchange contents of two files.

The first ioctl does the preparation work to exchange the contents
of two files while the second ioctl performs the actual exchange if
the target file has not been changed since a given sampling point.

Fixes:

- Fix bugs associated with calculating the maximum range of realtime
extents to scan for free space.

- Copy keys instead of records when resizing the incore BMBT root
block.

- Do not report FITRIMming more bytes than possibly exist in the
filesystem.

- Modify xfs_fs.h to prevent C++ compilation errors.

- Do not over eagerly free post-EOF speculative preallocation.

- Ensure st_blocks never goes to zero during COW writes

Cleanups/refactors:

- Use Xarray to hold per-AG data instead of a Radix tree.

- Cleanups to:
- realtime bitmap
- inode allocator
- quota
- inode rooted btree code"

* tag 'xfs-6.12-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (61 commits)
xfs: ensure st_blocks never goes to zero during COW writes
xfs: use xas_for_each_marked in xfs_reclaim_inodes_count
xfs: convert perag lookup to xarray
xfs: simplify tagged perag iteration
xfs: move the tagged perag lookup helpers to xfs_icache.c
xfs: use kfree_rcu_mightsleep to free the perag structures
xfs: use LIST_HEAD() to simplify code
xfs: Remove duplicate xfs_trans_priv.h header
xfs: remove unnecessary check
xfs: Use xfs set and clear mp state helpers
xfs: reclaim speculative preallocations for append only files
xfs: simplify extent lookup in xfs_can_free_eofblocks
xfs: check XFS_EOFBLOCKS_RELEASED earlier in xfs_release_eofblocks
xfs: only free posteof blocks on first close
xfs: don't free post-EOF blocks on read close
xfs: skip all of xfs_file_release when shut down
xfs: don't bother returning errors from xfs_file_release
xfs: refactor f_op->release handling
xfs: remove the i_mode check in xfs_release
xfs: standardize the btree maxrecs function parameters
...

+1772 -1454
+9 -85
fs/xfs/libxfs/xfs_ag.c
··· 46 46 struct xfs_perag *pag; 47 47 48 48 rcu_read_lock(); 49 - pag = radix_tree_lookup(&mp->m_perag_tree, agno); 49 + pag = xa_load(&mp->m_perags, agno); 50 50 if (pag) { 51 51 trace_xfs_perag_get(pag, _RET_IP_); 52 52 ASSERT(atomic_read(&pag->pag_ref) >= 0); 53 53 atomic_inc(&pag->pag_ref); 54 54 } 55 - rcu_read_unlock(); 56 - return pag; 57 - } 58 - 59 - /* 60 - * search from @first to find the next perag with the given tag set. 61 - */ 62 - struct xfs_perag * 63 - xfs_perag_get_tag( 64 - struct xfs_mount *mp, 65 - xfs_agnumber_t first, 66 - unsigned int tag) 67 - { 68 - struct xfs_perag *pag; 69 - int found; 70 - 71 - rcu_read_lock(); 72 - found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, 73 - (void **)&pag, first, 1, tag); 74 - if (found <= 0) { 75 - rcu_read_unlock(); 76 - return NULL; 77 - } 78 - trace_xfs_perag_get_tag(pag, _RET_IP_); 79 - atomic_inc(&pag->pag_ref); 80 55 rcu_read_unlock(); 81 56 return pag; 82 57 } ··· 92 117 struct xfs_perag *pag; 93 118 94 119 rcu_read_lock(); 95 - pag = radix_tree_lookup(&mp->m_perag_tree, agno); 120 + pag = xa_load(&mp->m_perags, agno); 96 121 if (pag) { 97 122 trace_xfs_perag_grab(pag, _RET_IP_); 98 123 if (!atomic_inc_not_zero(&pag->pag_active_ref)) 99 124 pag = NULL; 100 125 } 101 - rcu_read_unlock(); 102 - return pag; 103 - } 104 - 105 - /* 106 - * search from @first to find the next perag with the given tag set. 107 - */ 108 - struct xfs_perag * 109 - xfs_perag_grab_tag( 110 - struct xfs_mount *mp, 111 - xfs_agnumber_t first, 112 - int tag) 113 - { 114 - struct xfs_perag *pag; 115 - int found; 116 - 117 - rcu_read_lock(); 118 - found = radix_tree_gang_lookup_tag(&mp->m_perag_tree, 119 - (void **)&pag, first, 1, tag); 120 - if (found <= 0) { 121 - rcu_read_unlock(); 122 - return NULL; 123 - } 124 - trace_xfs_perag_grab_tag(pag, _RET_IP_); 125 - if (!atomic_inc_not_zero(&pag->pag_active_ref)) 126 - pag = NULL; 127 126 rcu_read_unlock(); 128 127 return pag; 129 128 } ··· 184 235 return error; 185 236 } 186 237 187 - STATIC void 188 - __xfs_free_perag( 189 - struct rcu_head *head) 190 - { 191 - struct xfs_perag *pag = container_of(head, struct xfs_perag, rcu_head); 192 - 193 - ASSERT(!delayed_work_pending(&pag->pag_blockgc_work)); 194 - kfree(pag); 195 - } 196 - 197 238 /* 198 239 * Free up the per-ag resources associated with the mount structure. 199 240 */ ··· 195 256 xfs_agnumber_t agno; 196 257 197 258 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { 198 - spin_lock(&mp->m_perag_lock); 199 - pag = radix_tree_delete(&mp->m_perag_tree, agno); 200 - spin_unlock(&mp->m_perag_lock); 259 + pag = xa_erase(&mp->m_perags, agno); 201 260 ASSERT(pag); 202 261 XFS_IS_CORRUPT(pag->pag_mount, atomic_read(&pag->pag_ref) != 0); 203 262 xfs_defer_drain_free(&pag->pag_intents_drain); ··· 207 270 xfs_perag_rele(pag); 208 271 XFS_IS_CORRUPT(pag->pag_mount, 209 272 atomic_read(&pag->pag_active_ref) != 0); 210 - call_rcu(&pag->rcu_head, __xfs_free_perag); 273 + kfree_rcu_mightsleep(pag); 211 274 } 212 275 } 213 276 ··· 284 347 xfs_agnumber_t index; 285 348 286 349 for (index = agstart; index < agend; index++) { 287 - spin_lock(&mp->m_perag_lock); 288 - pag = radix_tree_delete(&mp->m_perag_tree, index); 289 - spin_unlock(&mp->m_perag_lock); 350 + pag = xa_erase(&mp->m_perags, index); 290 351 if (!pag) 291 352 break; 292 353 xfs_buf_cache_destroy(&pag->pag_bcache); ··· 325 390 pag->pag_agno = index; 326 391 pag->pag_mount = mp; 327 392 328 - error = radix_tree_preload(GFP_KERNEL | __GFP_RETRY_MAYFAIL); 329 - if (error) 330 - goto out_free_pag; 331 - 332 - spin_lock(&mp->m_perag_lock); 333 - if (radix_tree_insert(&mp->m_perag_tree, index, pag)) { 334 - WARN_ON_ONCE(1); 335 - spin_unlock(&mp->m_perag_lock); 336 - radix_tree_preload_end(); 337 - error = -EEXIST; 393 + error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL); 394 + if (error) { 395 + WARN_ON_ONCE(error == -EBUSY); 338 396 goto out_free_pag; 339 397 } 340 - spin_unlock(&mp->m_perag_lock); 341 - radix_tree_preload_end(); 342 398 343 399 #ifdef __KERNEL__ 344 400 /* Place kernel structure only init below this point. */ ··· 377 451 378 452 out_remove_pag: 379 453 xfs_defer_drain_free(&pag->pag_intents_drain); 380 - spin_lock(&mp->m_perag_lock); 381 - radix_tree_delete(&mp->m_perag_tree, index); 382 - spin_unlock(&mp->m_perag_lock); 454 + pag = xa_erase(&mp->m_perags, index); 383 455 out_free_pag: 384 456 kfree(pag); 385 457 out_unwind_new_pags:
-14
fs/xfs/libxfs/xfs_ag.h
··· 63 63 /* Blocks reserved for the reverse mapping btree. */ 64 64 struct xfs_ag_resv pag_rmapbt_resv; 65 65 66 - /* for rcu-safe freeing */ 67 - struct rcu_head rcu_head; 68 - 69 66 /* Precalculated geometry info */ 70 67 xfs_agblock_t block_count; 71 68 xfs_agblock_t min_block; ··· 153 156 154 157 /* Passive AG references */ 155 158 struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno); 156 - struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno, 157 - unsigned int tag); 158 159 struct xfs_perag *xfs_perag_hold(struct xfs_perag *pag); 159 160 void xfs_perag_put(struct xfs_perag *pag); 160 161 161 162 /* Active AG references */ 162 163 struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t); 163 - struct xfs_perag *xfs_perag_grab_tag(struct xfs_mount *, xfs_agnumber_t, 164 - int tag); 165 164 void xfs_perag_rele(struct xfs_perag *pag); 166 165 167 166 /* ··· 258 265 #define for_each_perag(mp, agno, pag) \ 259 266 (agno) = 0; \ 260 267 for_each_perag_from((mp), (agno), (pag)) 261 - 262 - #define for_each_perag_tag(mp, agno, pag, tag) \ 263 - for ((agno) = 0, (pag) = xfs_perag_grab_tag((mp), 0, (tag)); \ 264 - (pag) != NULL; \ 265 - (agno) = (pag)->pag_agno + 1, \ 266 - xfs_perag_rele(pag), \ 267 - (pag) = xfs_perag_grab_tag((mp), (agno), (tag))) 268 268 269 269 static inline struct xfs_perag * 270 270 xfs_perag_next_wrap(
+3 -3
fs/xfs/libxfs/xfs_alloc_btree.c
··· 569 569 /* 570 570 * Calculate number of records in an alloc btree block. 571 571 */ 572 - int 572 + unsigned int 573 573 xfs_allocbt_maxrecs( 574 574 struct xfs_mount *mp, 575 - int blocklen, 576 - int leaf) 575 + unsigned int blocklen, 576 + bool leaf) 577 577 { 578 578 blocklen -= XFS_ALLOC_BLOCK_LEN(mp); 579 579 return xfs_allocbt_block_maxrecs(blocklen, leaf);
+2 -1
fs/xfs/libxfs/xfs_alloc_btree.h
··· 53 53 struct xfs_btree_cur *xfs_cntbt_init_cursor(struct xfs_mount *mp, 54 54 struct xfs_trans *tp, struct xfs_buf *bp, 55 55 struct xfs_perag *pag); 56 - extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int); 56 + unsigned int xfs_allocbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, 57 + bool leaf); 57 58 extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp, 58 59 unsigned long long len); 59 60
+4 -4
fs/xfs/libxfs/xfs_attr_leaf.c
··· 686 686 */ 687 687 if (!dp->i_forkoff && dp->i_df.if_bytes > 688 688 xfs_default_attroffset(dp)) 689 - dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); 689 + dsize = xfs_bmdr_space_calc(MINDBTPTRS); 690 690 break; 691 691 case XFS_DINODE_FMT_BTREE: 692 692 /* ··· 700 700 return 0; 701 701 return dp->i_forkoff; 702 702 } 703 - dsize = XFS_BMAP_BROOT_SPACE(mp, dp->i_df.if_broot); 703 + dsize = xfs_bmap_bmdr_space(dp->i_df.if_broot); 704 704 break; 705 705 } 706 706 ··· 708 708 * A data fork btree root must have space for at least 709 709 * MINDBTPTRS key/ptr pairs if the data fork is small or empty. 710 710 */ 711 - minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); 711 + minforkoff = max_t(int64_t, dsize, xfs_bmdr_space_calc(MINDBTPTRS)); 712 712 minforkoff = roundup(minforkoff, 8) >> 3; 713 713 714 714 /* attr fork btree root can have at least this many key/ptr pairs */ 715 - maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); 715 + maxforkoff = XFS_LITINO(mp) - xfs_bmdr_space_calc(MINABTPTRS); 716 716 maxforkoff = maxforkoff >> 3; /* rounded down */ 717 717 718 718 if (offset >= maxforkoff)
+56 -45
fs/xfs/libxfs/xfs_bmap.c
··· 79 79 maxleafents = xfs_iext_max_nextents(xfs_has_large_extent_counts(mp), 80 80 whichfork); 81 81 if (whichfork == XFS_DATA_FORK) 82 - sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS); 82 + sz = xfs_bmdr_space_calc(MINDBTPTRS); 83 83 else 84 - sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); 84 + sz = xfs_bmdr_space_calc(MINABTPTRS); 85 85 86 86 maxrootrecs = xfs_bmdr_maxrecs(sz, 0); 87 87 minleafrecs = mp->m_bmap_dmnr[0]; ··· 102 102 struct xfs_mount *mp) 103 103 { 104 104 if (mp->m_sb.sb_inodesize == 256) 105 - return XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); 106 - return XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); 105 + return XFS_LITINO(mp) - xfs_bmdr_space_calc(MINABTPTRS); 106 + return xfs_bmdr_space_calc(6 * MINABTPTRS); 107 107 } 108 108 109 109 STATIC int /* error */ ··· 298 298 prevp = NULL; 299 299 for( i = 1; i <= xfs_btree_get_numrecs(block); i++) { 300 300 dmxr = mp->m_bmap_dmxr[0]; 301 - keyp = XFS_BMBT_KEY_ADDR(mp, block, i); 301 + keyp = xfs_bmbt_key_addr(mp, block, i); 302 302 303 303 if (prevp) { 304 304 ASSERT(be64_to_cpu(prevp->br_startoff) < ··· 310 310 * Compare the block numbers to see if there are dups. 311 311 */ 312 312 if (root) 313 - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, i, sz); 313 + pp = xfs_bmap_broot_ptr_addr(mp, block, i, sz); 314 314 else 315 - pp = XFS_BMBT_PTR_ADDR(mp, block, i, dmxr); 315 + pp = xfs_bmbt_ptr_addr(mp, block, i, dmxr); 316 316 317 317 for (j = i+1; j <= be16_to_cpu(block->bb_numrecs); j++) { 318 318 if (root) 319 - thispa = XFS_BMAP_BROOT_PTR_ADDR(mp, block, j, sz); 319 + thispa = xfs_bmap_broot_ptr_addr(mp, block, j, sz); 320 320 else 321 - thispa = XFS_BMBT_PTR_ADDR(mp, block, j, dmxr); 321 + thispa = xfs_bmbt_ptr_addr(mp, block, j, dmxr); 322 322 if (*thispa == *pp) { 323 323 xfs_warn(mp, "%s: thispa(%d) == pp(%d) %lld", 324 324 __func__, j, i, ··· 373 373 level = be16_to_cpu(block->bb_level); 374 374 ASSERT(level > 0); 375 375 xfs_check_block(block, mp, 1, ifp->if_broot_bytes); 376 - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes); 376 + pp = xfs_bmap_broot_ptr_addr(mp, block, 1, ifp->if_broot_bytes); 377 377 bno = be64_to_cpu(*pp); 378 378 379 379 ASSERT(bno != NULLFSBLOCK); ··· 406 406 */ 407 407 408 408 xfs_check_block(block, mp, 0, 0); 409 - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); 409 + pp = xfs_bmbt_ptr_addr(mp, block, 1, mp->m_bmap_dmxr[1]); 410 410 bno = be64_to_cpu(*pp); 411 411 if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, bno))) { 412 412 xfs_btree_mark_sick(cur); ··· 446 446 * conform with the first entry in this one. 447 447 */ 448 448 449 - ep = XFS_BMBT_REC_ADDR(mp, block, 1); 449 + ep = xfs_bmbt_rec_addr(mp, block, 1); 450 450 if (i) { 451 451 ASSERT(xfs_bmbt_disk_get_startoff(&last) + 452 452 xfs_bmbt_disk_get_blockcount(&last) <= 453 453 xfs_bmbt_disk_get_startoff(ep)); 454 454 } 455 455 for (j = 1; j < num_recs; j++) { 456 - nextp = XFS_BMBT_REC_ADDR(mp, block, j + 1); 456 + nextp = xfs_bmbt_rec_addr(mp, block, j + 1); 457 457 ASSERT(xfs_bmbt_disk_get_startoff(ep) + 458 458 xfs_bmbt_disk_get_blockcount(ep) <= 459 459 xfs_bmbt_disk_get_startoff(nextp)); ··· 584 584 ASSERT(ifp->if_format == XFS_DINODE_FMT_BTREE); 585 585 ASSERT(be16_to_cpu(rblock->bb_level) == 1); 586 586 ASSERT(be16_to_cpu(rblock->bb_numrecs) == 1); 587 - ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0) == 1); 587 + ASSERT(xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, false) == 1); 588 588 589 - pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); 589 + pp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, ifp->if_broot_bytes); 590 590 cbno = be64_to_cpu(*pp); 591 591 #ifdef DEBUG 592 592 if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_verify_fsbno(mp, cbno))) { ··· 714 714 for_each_xfs_iext(ifp, &icur, &rec) { 715 715 if (isnullstartblock(rec.br_startblock)) 716 716 continue; 717 - arp = XFS_BMBT_REC_ADDR(mp, ablock, 1 + cnt); 717 + arp = xfs_bmbt_rec_addr(mp, ablock, 1 + cnt); 718 718 xfs_bmbt_disk_set_all(arp, &rec); 719 719 cnt++; 720 720 } ··· 724 724 /* 725 725 * Fill in the root key and pointer. 726 726 */ 727 - kp = XFS_BMBT_KEY_ADDR(mp, block, 1); 728 - arp = XFS_BMBT_REC_ADDR(mp, ablock, 1); 727 + kp = xfs_bmbt_key_addr(mp, block, 1); 728 + arp = xfs_bmbt_rec_addr(mp, ablock, 1); 729 729 kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); 730 - pp = XFS_BMBT_PTR_ADDR(mp, block, 1, xfs_bmbt_get_maxrecs(cur, 730 + pp = xfs_bmbt_ptr_addr(mp, block, 1, xfs_bmbt_get_maxrecs(cur, 731 731 be16_to_cpu(block->bb_level))); 732 732 *pp = cpu_to_be64(args.fsbno); 733 733 ··· 896 896 897 897 mp = ip->i_mount; 898 898 899 - if (XFS_BMAP_BMDR_SPACE(block) <= xfs_inode_data_fork_size(ip)) 899 + if (xfs_bmap_bmdr_space(block) <= xfs_inode_data_fork_size(ip)) 900 900 *flags |= XFS_ILOG_DBROOT; 901 901 else { 902 902 cur = xfs_bmbt_init_cursor(mp, tp, ip, XFS_DATA_FORK); ··· 1160 1160 } 1161 1161 1162 1162 /* Copy records into the incore cache. */ 1163 - frp = XFS_BMBT_REC_ADDR(mp, block, 1); 1163 + frp = xfs_bmbt_rec_addr(mp, block, 1); 1164 1164 for (j = 0; j < num_recs; j++, frp++, ir->loaded++) { 1165 1165 struct xfs_bmbt_irec new; 1166 1166 xfs_failaddr_t fa; ··· 3112 3112 return 0; 3113 3113 } 3114 3114 3115 + static inline bool 3116 + xfs_bmap_adjacent_valid( 3117 + struct xfs_bmalloca *ap, 3118 + xfs_fsblock_t x, 3119 + xfs_fsblock_t y) 3120 + { 3121 + struct xfs_mount *mp = ap->ip->i_mount; 3122 + 3123 + if (XFS_IS_REALTIME_INODE(ap->ip) && 3124 + (ap->datatype & XFS_ALLOC_USERDATA)) 3125 + return x < mp->m_sb.sb_rblocks; 3126 + 3127 + return XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && 3128 + XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && 3129 + XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks; 3130 + } 3131 + 3115 3132 #define XFS_ALLOC_GAP_UNITS 4 3116 3133 3117 3134 /* returns true if ap->blkno was modified */ ··· 3136 3119 xfs_bmap_adjacent( 3137 3120 struct xfs_bmalloca *ap) /* bmap alloc argument struct */ 3138 3121 { 3139 - xfs_fsblock_t adjust; /* adjustment to block numbers */ 3140 - xfs_mount_t *mp; /* mount point structure */ 3141 - int rt; /* true if inode is realtime */ 3122 + xfs_fsblock_t adjust; /* adjustment to block numbers */ 3142 3123 3143 - #define ISVALID(x,y) \ 3144 - (rt ? \ 3145 - (x) < mp->m_sb.sb_rblocks : \ 3146 - XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) && \ 3147 - XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount && \ 3148 - XFS_FSB_TO_AGBNO(mp, x) < mp->m_sb.sb_agblocks) 3149 - 3150 - mp = ap->ip->i_mount; 3151 - rt = XFS_IS_REALTIME_INODE(ap->ip) && 3152 - (ap->datatype & XFS_ALLOC_USERDATA); 3153 3124 /* 3154 3125 * If allocating at eof, and there's a previous real block, 3155 3126 * try to use its last block as our starting point. 3156 3127 */ 3157 3128 if (ap->eof && ap->prev.br_startoff != NULLFILEOFF && 3158 3129 !isnullstartblock(ap->prev.br_startblock) && 3159 - ISVALID(ap->prev.br_startblock + ap->prev.br_blockcount, 3160 - ap->prev.br_startblock)) { 3130 + xfs_bmap_adjacent_valid(ap, 3131 + ap->prev.br_startblock + ap->prev.br_blockcount, 3132 + ap->prev.br_startblock)) { 3161 3133 ap->blkno = ap->prev.br_startblock + ap->prev.br_blockcount; 3162 3134 /* 3163 3135 * Adjust for the gap between prevp and us. 3164 3136 */ 3165 3137 adjust = ap->offset - 3166 3138 (ap->prev.br_startoff + ap->prev.br_blockcount); 3167 - if (adjust && 3168 - ISVALID(ap->blkno + adjust, ap->prev.br_startblock)) 3139 + if (adjust && xfs_bmap_adjacent_valid(ap, ap->blkno + adjust, 3140 + ap->prev.br_startblock)) 3169 3141 ap->blkno += adjust; 3170 3142 return true; 3171 3143 } ··· 3177 3171 !isnullstartblock(ap->prev.br_startblock) && 3178 3172 (prevbno = ap->prev.br_startblock + 3179 3173 ap->prev.br_blockcount) && 3180 - ISVALID(prevbno, ap->prev.br_startblock)) { 3174 + xfs_bmap_adjacent_valid(ap, prevbno, 3175 + ap->prev.br_startblock)) { 3181 3176 /* 3182 3177 * Calculate gap to end of previous block. 3183 3178 */ ··· 3194 3187 * number, then just use the end of the previous block. 3195 3188 */ 3196 3189 if (prevdiff <= XFS_ALLOC_GAP_UNITS * ap->length && 3197 - ISVALID(prevbno + prevdiff, 3198 - ap->prev.br_startblock)) 3190 + xfs_bmap_adjacent_valid(ap, prevbno + prevdiff, 3191 + ap->prev.br_startblock)) 3199 3192 prevbno += adjust; 3200 3193 else 3201 3194 prevdiff += adjust; ··· 3227 3220 * offset by our length. 3228 3221 */ 3229 3222 if (gotdiff <= XFS_ALLOC_GAP_UNITS * ap->length && 3230 - ISVALID(gotbno - gotdiff, gotbno)) 3223 + xfs_bmap_adjacent_valid(ap, gotbno - gotdiff, 3224 + gotbno)) 3231 3225 gotbno -= adjust; 3232 - else if (ISVALID(gotbno - ap->length, gotbno)) { 3226 + else if (xfs_bmap_adjacent_valid(ap, gotbno - ap->length, 3227 + gotbno)) { 3233 3228 gotbno -= ap->length; 3234 3229 gotdiff += adjust - ap->length; 3235 3230 } else ··· 3259 3250 return true; 3260 3251 } 3261 3252 } 3262 - #undef ISVALID 3253 + 3263 3254 return false; 3264 3255 } 3265 3256 ··· 4856 4847 } 4857 4848 4858 4849 ip->i_nblocks += len; 4850 + ip->i_delayed_blks -= len; /* see xfs_bmap_defer_add */ 4859 4851 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 4860 4852 4861 4853 if (ifp->if_format == XFS_DINODE_FMT_BTREE) ··· 5386 5376 */ 5387 5377 if (!(tp->t_flags & XFS_TRANS_RTBITMAP_LOCKED)) { 5388 5378 tp->t_flags |= XFS_TRANS_RTBITMAP_LOCKED; 5389 - xfs_rtbitmap_lock(tp, mp); 5379 + xfs_rtbitmap_lock(mp); 5380 + xfs_rtbitmap_trans_join(tp); 5390 5381 } 5391 5382 error = xfs_rtfree_blocks(tp, del->br_startblock, 5392 5383 del->br_blockcount);
+12 -12
fs/xfs/libxfs/xfs_bmap_btree.c
··· 65 65 ASSERT(be16_to_cpu(rblock->bb_level) > 0); 66 66 rblock->bb_numrecs = dblock->bb_numrecs; 67 67 dmxr = xfs_bmdr_maxrecs(dblocklen, 0); 68 - fkp = XFS_BMDR_KEY_ADDR(dblock, 1); 69 - tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); 70 - fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); 71 - tpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); 68 + fkp = xfs_bmdr_key_addr(dblock, 1); 69 + tkp = xfs_bmbt_key_addr(mp, rblock, 1); 70 + fpp = xfs_bmdr_ptr_addr(dblock, 1, dmxr); 71 + tpp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, rblocklen); 72 72 dmxr = be16_to_cpu(dblock->bb_numrecs); 73 73 memcpy(tkp, fkp, sizeof(*fkp) * dmxr); 74 74 memcpy(tpp, fpp, sizeof(*fpp) * dmxr); ··· 168 168 dblock->bb_level = rblock->bb_level; 169 169 dblock->bb_numrecs = rblock->bb_numrecs; 170 170 dmxr = xfs_bmdr_maxrecs(dblocklen, 0); 171 - fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); 172 - tkp = XFS_BMDR_KEY_ADDR(dblock, 1); 173 - fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); 174 - tpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); 171 + fkp = xfs_bmbt_key_addr(mp, rblock, 1); 172 + tkp = xfs_bmdr_key_addr(dblock, 1); 173 + fpp = xfs_bmap_broot_ptr_addr(mp, rblock, 1, rblocklen); 174 + tpp = xfs_bmdr_ptr_addr(dblock, 1, dmxr); 175 175 dmxr = be16_to_cpu(dblock->bb_numrecs); 176 176 memcpy(tkp, fkp, sizeof(*fkp) * dmxr); 177 177 memcpy(tpp, fpp, sizeof(*fpp) * dmxr); ··· 645 645 /* 646 646 * Calculate number of records in a bmap btree block. 647 647 */ 648 - int 648 + unsigned int 649 649 xfs_bmbt_maxrecs( 650 650 struct xfs_mount *mp, 651 - int blocklen, 652 - int leaf) 651 + unsigned int blocklen, 652 + bool leaf) 653 653 { 654 - blocklen -= XFS_BMBT_BLOCK_LEN(mp); 654 + blocklen -= xfs_bmbt_block_len(mp); 655 655 return xfs_bmbt_block_maxrecs(blocklen, leaf); 656 656 } 657 657
+142 -65
fs/xfs/libxfs/xfs_bmap_btree.h
··· 14 14 struct xbtree_ifakeroot; 15 15 16 16 /* 17 - * Btree block header size depends on a superblock flag. 18 - */ 19 - #define XFS_BMBT_BLOCK_LEN(mp) \ 20 - (xfs_has_crc(((mp))) ? \ 21 - XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN) 22 - 23 - #define XFS_BMBT_REC_ADDR(mp, block, index) \ 24 - ((xfs_bmbt_rec_t *) \ 25 - ((char *)(block) + \ 26 - XFS_BMBT_BLOCK_LEN(mp) + \ 27 - ((index) - 1) * sizeof(xfs_bmbt_rec_t))) 28 - 29 - #define XFS_BMBT_KEY_ADDR(mp, block, index) \ 30 - ((xfs_bmbt_key_t *) \ 31 - ((char *)(block) + \ 32 - XFS_BMBT_BLOCK_LEN(mp) + \ 33 - ((index) - 1) * sizeof(xfs_bmbt_key_t))) 34 - 35 - #define XFS_BMBT_PTR_ADDR(mp, block, index, maxrecs) \ 36 - ((xfs_bmbt_ptr_t *) \ 37 - ((char *)(block) + \ 38 - XFS_BMBT_BLOCK_LEN(mp) + \ 39 - (maxrecs) * sizeof(xfs_bmbt_key_t) + \ 40 - ((index) - 1) * sizeof(xfs_bmbt_ptr_t))) 41 - 42 - #define XFS_BMDR_REC_ADDR(block, index) \ 43 - ((xfs_bmdr_rec_t *) \ 44 - ((char *)(block) + \ 45 - sizeof(struct xfs_bmdr_block) + \ 46 - ((index) - 1) * sizeof(xfs_bmdr_rec_t))) 47 - 48 - #define XFS_BMDR_KEY_ADDR(block, index) \ 49 - ((xfs_bmdr_key_t *) \ 50 - ((char *)(block) + \ 51 - sizeof(struct xfs_bmdr_block) + \ 52 - ((index) - 1) * sizeof(xfs_bmdr_key_t))) 53 - 54 - #define XFS_BMDR_PTR_ADDR(block, index, maxrecs) \ 55 - ((xfs_bmdr_ptr_t *) \ 56 - ((char *)(block) + \ 57 - sizeof(struct xfs_bmdr_block) + \ 58 - (maxrecs) * sizeof(xfs_bmdr_key_t) + \ 59 - ((index) - 1) * sizeof(xfs_bmdr_ptr_t))) 60 - 61 - /* 62 - * These are to be used when we know the size of the block and 63 - * we don't have a cursor. 64 - */ 65 - #define XFS_BMAP_BROOT_PTR_ADDR(mp, bb, i, sz) \ 66 - XFS_BMBT_PTR_ADDR(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0)) 67 - 68 - #define XFS_BMAP_BROOT_SPACE_CALC(mp, nrecs) \ 69 - (int)(XFS_BMBT_BLOCK_LEN(mp) + \ 70 - ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) 71 - 72 - #define XFS_BMAP_BROOT_SPACE(mp, bb) \ 73 - (XFS_BMAP_BROOT_SPACE_CALC(mp, be16_to_cpu((bb)->bb_numrecs))) 74 - #define XFS_BMDR_SPACE_CALC(nrecs) \ 75 - (int)(sizeof(xfs_bmdr_block_t) + \ 76 - ((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)))) 77 - #define XFS_BMAP_BMDR_SPACE(bb) \ 78 - (XFS_BMDR_SPACE_CALC(be16_to_cpu((bb)->bb_numrecs))) 79 - 80 - /* 81 17 * Maximum number of bmap btree levels. 82 18 */ 83 19 #define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[(w)]) ··· 35 99 36 100 extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level); 37 101 extern int xfs_bmdr_maxrecs(int blocklen, int leaf); 38 - extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf); 102 + unsigned int xfs_bmbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, 103 + bool leaf); 39 104 40 105 extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip, 41 106 int whichfork, xfs_ino_t new_owner, ··· 57 120 58 121 void xfs_bmbt_init_block(struct xfs_inode *ip, struct xfs_btree_block *buf, 59 122 struct xfs_buf *bp, __u16 level, __u16 numrecs); 123 + 124 + /* 125 + * Btree block header size depends on a superblock flag. 126 + */ 127 + static inline size_t 128 + xfs_bmbt_block_len(struct xfs_mount *mp) 129 + { 130 + return xfs_has_crc(mp) ? 131 + XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN; 132 + } 133 + 134 + /* Addresses of key, pointers, and records within an incore bmbt block. */ 135 + 136 + static inline struct xfs_bmbt_rec * 137 + xfs_bmbt_rec_addr( 138 + struct xfs_mount *mp, 139 + struct xfs_btree_block *block, 140 + unsigned int index) 141 + { 142 + return (struct xfs_bmbt_rec *) 143 + ((char *)block + xfs_bmbt_block_len(mp) + 144 + (index - 1) * sizeof(struct xfs_bmbt_rec)); 145 + } 146 + 147 + static inline struct xfs_bmbt_key * 148 + xfs_bmbt_key_addr( 149 + struct xfs_mount *mp, 150 + struct xfs_btree_block *block, 151 + unsigned int index) 152 + { 153 + return (struct xfs_bmbt_key *) 154 + ((char *)block + xfs_bmbt_block_len(mp) + 155 + (index - 1) * sizeof(struct xfs_bmbt_key *)); 156 + } 157 + 158 + static inline xfs_bmbt_ptr_t * 159 + xfs_bmbt_ptr_addr( 160 + struct xfs_mount *mp, 161 + struct xfs_btree_block *block, 162 + unsigned int index, 163 + unsigned int maxrecs) 164 + { 165 + return (xfs_bmbt_ptr_t *) 166 + ((char *)block + xfs_bmbt_block_len(mp) + 167 + maxrecs * sizeof(struct xfs_bmbt_key) + 168 + (index - 1) * sizeof(xfs_bmbt_ptr_t)); 169 + } 170 + 171 + /* Addresses of key, pointers, and records within an ondisk bmbt block. */ 172 + 173 + static inline struct xfs_bmbt_rec * 174 + xfs_bmdr_rec_addr( 175 + struct xfs_bmdr_block *block, 176 + unsigned int index) 177 + { 178 + return (struct xfs_bmbt_rec *) 179 + ((char *)(block + 1) + 180 + (index - 1) * sizeof(struct xfs_bmbt_rec)); 181 + } 182 + 183 + static inline struct xfs_bmbt_key * 184 + xfs_bmdr_key_addr( 185 + struct xfs_bmdr_block *block, 186 + unsigned int index) 187 + { 188 + return (struct xfs_bmbt_key *) 189 + ((char *)(block + 1) + 190 + (index - 1) * sizeof(struct xfs_bmbt_key)); 191 + } 192 + 193 + static inline xfs_bmbt_ptr_t * 194 + xfs_bmdr_ptr_addr( 195 + struct xfs_bmdr_block *block, 196 + unsigned int index, 197 + unsigned int maxrecs) 198 + { 199 + return (xfs_bmbt_ptr_t *) 200 + ((char *)(block + 1) + 201 + maxrecs * sizeof(struct xfs_bmbt_key) + 202 + (index - 1) * sizeof(xfs_bmbt_ptr_t)); 203 + } 204 + 205 + /* 206 + * Address of pointers within the incore btree root. 207 + * 208 + * These are to be used when we know the size of the block and 209 + * we don't have a cursor. 210 + */ 211 + static inline xfs_bmbt_ptr_t * 212 + xfs_bmap_broot_ptr_addr( 213 + struct xfs_mount *mp, 214 + struct xfs_btree_block *bb, 215 + unsigned int i, 216 + unsigned int sz) 217 + { 218 + return xfs_bmbt_ptr_addr(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, false)); 219 + } 220 + 221 + /* 222 + * Compute the space required for the incore btree root containing the given 223 + * number of records. 224 + */ 225 + static inline size_t 226 + xfs_bmap_broot_space_calc( 227 + struct xfs_mount *mp, 228 + unsigned int nrecs) 229 + { 230 + return xfs_bmbt_block_len(mp) + 231 + (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t))); 232 + } 233 + 234 + /* 235 + * Compute the space required for the incore btree root given the ondisk 236 + * btree root block. 237 + */ 238 + static inline size_t 239 + xfs_bmap_broot_space( 240 + struct xfs_mount *mp, 241 + struct xfs_bmdr_block *bb) 242 + { 243 + return xfs_bmap_broot_space_calc(mp, be16_to_cpu(bb->bb_numrecs)); 244 + } 245 + 246 + /* Compute the space required for the ondisk root block. */ 247 + static inline size_t 248 + xfs_bmdr_space_calc(unsigned int nrecs) 249 + { 250 + return sizeof(struct xfs_bmdr_block) + 251 + (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t))); 252 + } 253 + 254 + /* 255 + * Compute the space required for the ondisk root block given an incore root 256 + * block. 257 + */ 258 + static inline size_t 259 + xfs_bmap_bmdr_space(struct xfs_btree_block *bb) 260 + { 261 + return xfs_bmdr_space_calc(be16_to_cpu(bb->bb_numrecs)); 262 + } 60 263 61 264 #endif /* __XFS_BMAP_BTREE_H__ */
-1
fs/xfs/libxfs/xfs_defer.c
··· 28 28 #include "xfs_da_format.h" 29 29 #include "xfs_da_btree.h" 30 30 #include "xfs_attr.h" 31 - #include "xfs_trans_priv.h" 32 31 #include "xfs_exchmaps.h" 33 32 34 33 static struct kmem_cache *xfs_defer_pending_cache;
+29 -2
fs/xfs/libxfs/xfs_fs.h
··· 8 8 9 9 /* 10 10 * SGI's XFS filesystem's major stuff (constants, structures) 11 + * NOTE: This file must be compile-able with C++ compilers. 11 12 */ 12 13 13 14 /* ··· 827 826 }; 828 827 829 828 /* 829 + * Using the same definition of file2 as struct xfs_exchange_range, commit the 830 + * contents of file1 into file2 if file2 has the same inode number, mtime, and 831 + * ctime as the arguments provided to the call. The old contents of file2 will 832 + * be moved to file1. 833 + * 834 + * Returns -EBUSY if there isn't an exact match for the file2 fields. 835 + * 836 + * Filesystems must be able to restart and complete the operation even after 837 + * the system goes down. 838 + */ 839 + struct xfs_commit_range { 840 + __s32 file1_fd; 841 + __u32 pad; /* must be zeroes */ 842 + __u64 file1_offset; /* file1 offset, bytes */ 843 + __u64 file2_offset; /* file2 offset, bytes */ 844 + __u64 length; /* bytes to exchange */ 845 + 846 + __u64 flags; /* see XFS_EXCHANGE_RANGE_* below */ 847 + 848 + /* opaque file2 metadata for freshness checks */ 849 + __u64 file2_freshness[6]; 850 + }; 851 + 852 + /* 830 853 * Exchange file data all the way to the ends of both files, and then exchange 831 854 * the file sizes. This flag can be used to replace a file's contents with a 832 855 * different amount of data. length will be ignored. ··· 931 906 xfs_getparents_next_rec(struct xfs_getparents *gp, 932 907 struct xfs_getparents_rec *gpr) 933 908 { 934 - void *next = ((void *)gpr + gpr->gpr_reclen); 909 + void *next = ((char *)gpr + gpr->gpr_reclen); 935 910 void *end = (void *)(uintptr_t)(gp->gp_buffer + gp->gp_bufsize); 936 911 937 912 if (next >= end) 938 913 return NULL; 939 914 940 - return next; 915 + return (struct xfs_getparents_rec *)next; 941 916 } 942 917 943 918 /* Iterate through this file handle's directory parent pointers. */ ··· 1022 997 #define XFS_IOC_BULKSTAT _IOR ('X', 127, struct xfs_bulkstat_req) 1023 998 #define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req) 1024 999 #define XFS_IOC_EXCHANGE_RANGE _IOW ('X', 129, struct xfs_exchange_range) 1000 + #define XFS_IOC_START_COMMIT _IOR ('X', 130, struct xfs_commit_range) 1001 + #define XFS_IOC_COMMIT_RANGE _IOW ('X', 131, struct xfs_commit_range) 1025 1002 /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ 1026 1003 1027 1004
+5 -4
fs/xfs/libxfs/xfs_ialloc.c
··· 1855 1855 int 1856 1856 xfs_dialloc( 1857 1857 struct xfs_trans **tpp, 1858 - xfs_ino_t parent, 1859 - umode_t mode, 1858 + const struct xfs_icreate_args *args, 1860 1859 xfs_ino_t *new_ino) 1861 1860 { 1862 1861 struct xfs_mount *mp = (*tpp)->t_mountp; 1862 + xfs_ino_t parent = args->pip ? args->pip->i_ino : 0; 1863 + umode_t mode = args->mode & S_IFMT; 1863 1864 xfs_agnumber_t agno; 1864 1865 int error = 0; 1865 1866 xfs_agnumber_t start_agno; ··· 2948 2947 2949 2948 /* Compute inode btree geometry. */ 2950 2949 igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog; 2951 - igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1); 2952 - igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 0); 2950 + igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, true); 2951 + igeo->inobt_mxr[1] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, false); 2953 2952 igeo->inobt_mnr[0] = igeo->inobt_mxr[0] / 2; 2954 2953 igeo->inobt_mnr[1] = igeo->inobt_mxr[1] / 2; 2955 2954
+3 -1
fs/xfs/libxfs/xfs_ialloc.h
··· 33 33 return xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog); 34 34 } 35 35 36 + struct xfs_icreate_args; 37 + 36 38 /* 37 39 * Allocate an inode on disk. Mode is used to tell whether the new inode will 38 40 * need space, and whether it is a directory. 39 41 */ 40 - int xfs_dialloc(struct xfs_trans **tpp, xfs_ino_t parent, umode_t mode, 42 + int xfs_dialloc(struct xfs_trans **tpp, const struct xfs_icreate_args *args, 41 43 xfs_ino_t *new_ino); 42 44 43 45 int xfs_difree(struct xfs_trans *tp, struct xfs_perag *pag,
+3 -3
fs/xfs/libxfs/xfs_ialloc_btree.c
··· 572 572 /* 573 573 * Calculate number of records in an inobt btree block. 574 574 */ 575 - int 575 + unsigned int 576 576 xfs_inobt_maxrecs( 577 577 struct xfs_mount *mp, 578 - int blocklen, 579 - int leaf) 578 + unsigned int blocklen, 579 + bool leaf) 580 580 { 581 581 blocklen -= XFS_INOBT_BLOCK_LEN(mp); 582 582 return xfs_inobt_block_maxrecs(blocklen, leaf);
+2 -1
fs/xfs/libxfs/xfs_ialloc_btree.h
··· 50 50 struct xfs_trans *tp, struct xfs_buf *agbp); 51 51 struct xfs_btree_cur *xfs_finobt_init_cursor(struct xfs_perag *pag, 52 52 struct xfs_trans *tp, struct xfs_buf *agbp); 53 - extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); 53 + unsigned int xfs_inobt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, 54 + bool leaf); 54 55 55 56 /* ir_holemask to inode allocation bitmap conversion */ 56 57 uint64_t xfs_inobt_irec_to_allocmask(const struct xfs_inobt_rec_incore *irec);
+20 -20
fs/xfs/libxfs/xfs_inode_fork.c
··· 185 185 186 186 ifp = xfs_ifork_ptr(ip, whichfork); 187 187 dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); 188 - size = XFS_BMAP_BROOT_SPACE(mp, dfp); 188 + size = xfs_bmap_broot_space(mp, dfp); 189 189 nrecs = be16_to_cpu(dfp->bb_numrecs); 190 190 level = be16_to_cpu(dfp->bb_level); 191 191 ··· 198 198 */ 199 199 if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) || 200 200 nrecs == 0 || 201 - XFS_BMDR_SPACE_CALC(nrecs) > 201 + xfs_bmdr_space_calc(nrecs) > 202 202 XFS_DFORK_SIZE(dip, mp, whichfork) || 203 203 ifp->if_nextents > ip->i_nblocks) || 204 204 level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) { ··· 409 409 * allocate it now and get out. 410 410 */ 411 411 if (ifp->if_broot_bytes == 0) { 412 - new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff); 412 + new_size = xfs_bmap_broot_space_calc(mp, rec_diff); 413 413 ifp->if_broot = kmalloc(new_size, 414 414 GFP_KERNEL | __GFP_NOFAIL); 415 415 ifp->if_broot_bytes = (int)new_size; ··· 422 422 * location. The records don't change location because 423 423 * they are kept butted up against the btree block header. 424 424 */ 425 - cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); 425 + cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, false); 426 426 new_max = cur_max + rec_diff; 427 - new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); 427 + new_size = xfs_bmap_broot_space_calc(mp, new_max); 428 428 ifp->if_broot = krealloc(ifp->if_broot, new_size, 429 429 GFP_KERNEL | __GFP_NOFAIL); 430 - op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, 430 + op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, 431 431 ifp->if_broot_bytes); 432 - np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, 432 + np = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, 433 433 (int)new_size); 434 434 ifp->if_broot_bytes = (int)new_size; 435 - ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= 435 + ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= 436 436 xfs_inode_fork_size(ip, whichfork)); 437 437 memmove(np, op, cur_max * (uint)sizeof(xfs_fsblock_t)); 438 438 return; ··· 444 444 * records, just get rid of the root and clear the status bit. 445 445 */ 446 446 ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); 447 - cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); 447 + cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, false); 448 448 new_max = cur_max + rec_diff; 449 449 ASSERT(new_max >= 0); 450 450 if (new_max > 0) 451 - new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); 451 + new_size = xfs_bmap_broot_space_calc(mp, new_max); 452 452 else 453 453 new_size = 0; 454 454 if (new_size > 0) { ··· 457 457 * First copy over the btree block header. 458 458 */ 459 459 memcpy(new_broot, ifp->if_broot, 460 - XFS_BMBT_BLOCK_LEN(ip->i_mount)); 460 + xfs_bmbt_block_len(ip->i_mount)); 461 461 } else { 462 462 new_broot = NULL; 463 463 } 464 464 465 465 /* 466 - * Only copy the records and pointers if there are any. 466 + * Only copy the keys and pointers if there are any. 467 467 */ 468 468 if (new_max > 0) { 469 469 /* 470 - * First copy the records. 470 + * First copy the keys. 471 471 */ 472 - op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); 473 - np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); 474 - memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); 472 + op = (char *)xfs_bmbt_key_addr(mp, ifp->if_broot, 1); 473 + np = (char *)xfs_bmbt_key_addr(mp, new_broot, 1); 474 + memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_key_t)); 475 475 476 476 /* 477 477 * Then copy the pointers. 478 478 */ 479 - op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, 479 + op = (char *)xfs_bmap_broot_ptr_addr(mp, ifp->if_broot, 1, 480 480 ifp->if_broot_bytes); 481 - np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, 481 + np = (char *)xfs_bmap_broot_ptr_addr(mp, new_broot, 1, 482 482 (int)new_size); 483 483 memcpy(np, op, new_max * (uint)sizeof(xfs_fsblock_t)); 484 484 } ··· 486 486 ifp->if_broot = new_broot; 487 487 ifp->if_broot_bytes = (int)new_size; 488 488 if (ifp->if_broot) 489 - ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= 489 + ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= 490 490 xfs_inode_fork_size(ip, whichfork)); 491 491 return; 492 492 } ··· 655 655 if ((iip->ili_fields & brootflag[whichfork]) && 656 656 (ifp->if_broot_bytes > 0)) { 657 657 ASSERT(ifp->if_broot != NULL); 658 - ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= 658 + ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <= 659 659 xfs_inode_fork_size(ip, whichfork)); 660 660 xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, 661 661 (xfs_bmdr_block_t *)cp,
+1 -1
fs/xfs/libxfs/xfs_inode_util.c
··· 308 308 !vfsgid_in_group_p(i_gid_into_vfsgid(args->idmap, inode))) 309 309 inode->i_mode &= ~S_ISGID; 310 310 311 - ip->i_projid = pip ? xfs_get_initial_prid(pip) : 0; 311 + ip->i_projid = xfs_get_initial_prid(pip); 312 312 } 313 313 314 314 ip->i_disk_size = 0;
+3 -2
fs/xfs/libxfs/xfs_refcount_btree.c
··· 417 417 /* 418 418 * Calculate the number of records in a refcount btree block. 419 419 */ 420 - int 420 + unsigned int 421 421 xfs_refcountbt_maxrecs( 422 - int blocklen, 422 + struct xfs_mount *mp, 423 + unsigned int blocklen, 423 424 bool leaf) 424 425 { 425 426 blocklen -= XFS_REFCOUNT_BLOCK_LEN;
+2 -1
fs/xfs/libxfs/xfs_refcount_btree.h
··· 48 48 extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp, 49 49 struct xfs_trans *tp, struct xfs_buf *agbp, 50 50 struct xfs_perag *pag); 51 - extern int xfs_refcountbt_maxrecs(int blocklen, bool leaf); 51 + unsigned int xfs_refcountbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, 52 + bool leaf); 52 53 extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp); 53 54 54 55 extern xfs_extlen_t xfs_refcountbt_calc_size(struct xfs_mount *mp,
+4 -3
fs/xfs/libxfs/xfs_rmap_btree.c
··· 731 731 /* 732 732 * Calculate number of records in an rmap btree block. 733 733 */ 734 - int 734 + unsigned int 735 735 xfs_rmapbt_maxrecs( 736 - int blocklen, 737 - int leaf) 736 + struct xfs_mount *mp, 737 + unsigned int blocklen, 738 + bool leaf) 738 739 { 739 740 blocklen -= XFS_RMAP_BLOCK_LEN; 740 741 return xfs_rmapbt_block_maxrecs(blocklen, leaf);
+2 -1
fs/xfs/libxfs/xfs_rmap_btree.h
··· 47 47 struct xfs_perag *pag); 48 48 void xfs_rmapbt_commit_staged_btree(struct xfs_btree_cur *cur, 49 49 struct xfs_trans *tp, struct xfs_buf *agbp); 50 - int xfs_rmapbt_maxrecs(int blocklen, int leaf); 50 + unsigned int xfs_rmapbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen, 51 + bool leaf); 51 52 extern void xfs_rmapbt_compute_maxlevels(struct xfs_mount *mp); 52 53 53 54 extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp,
+196 -78
fs/xfs/libxfs/xfs_rtbitmap.c
··· 13 13 #include "xfs_mount.h" 14 14 #include "xfs_inode.h" 15 15 #include "xfs_bmap.h" 16 + #include "xfs_bmap_btree.h" 17 + #include "xfs_trans_space.h" 16 18 #include "xfs_trans.h" 17 19 #include "xfs_rtalloc.h" 18 20 #include "xfs_error.h" ··· 71 69 * Get a buffer for the bitmap or summary file block specified. 72 70 * The buffer is returned read and locked. 73 71 */ 74 - int 72 + static int 75 73 xfs_rtbuf_get( 76 74 struct xfs_rtalloc_args *args, 77 75 xfs_fileoff_t block, /* block number in bitmap or summary */ ··· 140 138 return 0; 141 139 } 142 140 141 + int 142 + xfs_rtbitmap_read_buf( 143 + struct xfs_rtalloc_args *args, 144 + xfs_fileoff_t block) 145 + { 146 + struct xfs_mount *mp = args->mp; 147 + 148 + if (XFS_IS_CORRUPT(mp, block >= mp->m_sb.sb_rbmblocks)) { 149 + xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP); 150 + return -EFSCORRUPTED; 151 + } 152 + 153 + return xfs_rtbuf_get(args, block, 0); 154 + } 155 + 156 + int 157 + xfs_rtsummary_read_buf( 158 + struct xfs_rtalloc_args *args, 159 + xfs_fileoff_t block) 160 + { 161 + struct xfs_mount *mp = args->mp; 162 + 163 + if (XFS_IS_CORRUPT(mp, block >= mp->m_rsumblocks)) { 164 + xfs_rt_mark_sick(args->mp, XFS_SICK_RT_SUMMARY); 165 + return -EFSCORRUPTED; 166 + } 167 + return xfs_rtbuf_get(args, block, 1); 168 + } 169 + 143 170 /* 144 - * Searching backward from start to limit, find the first block whose 145 - * allocated/free state is different from start's. 171 + * Searching backward from start find the first block whose allocated/free state 172 + * is different from start's. 146 173 */ 147 174 int 148 175 xfs_rtfind_back( 149 176 struct xfs_rtalloc_args *args, 150 177 xfs_rtxnum_t start, /* starting rtext to look at */ 151 - xfs_rtxnum_t limit, /* last rtext to look at */ 152 178 xfs_rtxnum_t *rtx) /* out: start rtext found */ 153 179 { 154 180 struct xfs_mount *mp = args->mp; ··· 205 175 */ 206 176 word = xfs_rtx_to_rbmword(mp, start); 207 177 bit = (int)(start & (XFS_NBWORD - 1)); 208 - len = start - limit + 1; 178 + len = start + 1; 209 179 /* 210 180 * Compute match value, based on the bit at start: if 1 (free) 211 181 * then all-ones, else all-zeroes. ··· 345 315 xfs_rtword_t wdiff; /* difference from wanted value */ 346 316 xfs_rtword_t incore; 347 317 unsigned int word; /* word number in the buffer */ 318 + 319 + ASSERT(start <= limit); 348 320 349 321 /* 350 322 * Compute and read in starting bitmap block for starting block. ··· 730 698 * We need to find the beginning and end of the extent so we can 731 699 * properly update the summary. 732 700 */ 733 - error = xfs_rtfind_back(args, start, 0, &preblock); 701 + error = xfs_rtfind_back(args, start, &preblock); 734 702 if (error) { 735 703 return error; 736 704 } ··· 1022 990 xfs_filblks_t rtlen) 1023 991 { 1024 992 struct xfs_mount *mp = tp->t_mountp; 1025 - xfs_rtxnum_t start; 1026 - xfs_filblks_t len; 1027 993 xfs_extlen_t mod; 1028 994 1029 995 ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN); 1030 996 1031 - len = xfs_rtb_to_rtxrem(mp, rtlen, &mod); 997 + mod = xfs_rtb_to_rtxoff(mp, rtlen); 1032 998 if (mod) { 1033 999 ASSERT(mod == 0); 1034 1000 return -EIO; 1035 1001 } 1036 1002 1037 - start = xfs_rtb_to_rtxrem(mp, rtbno, &mod); 1003 + mod = xfs_rtb_to_rtxoff(mp, rtbno); 1038 1004 if (mod) { 1039 1005 ASSERT(mod == 0); 1040 1006 return -EIO; 1041 1007 } 1042 1008 1043 - return xfs_rtfree_extent(tp, start, len); 1009 + return xfs_rtfree_extent(tp, xfs_rtb_to_rtx(mp, rtbno), 1010 + xfs_rtb_to_rtx(mp, rtlen)); 1044 1011 } 1045 1012 1046 1013 /* Find all the free records within a given range. */ ··· 1047 1016 xfs_rtalloc_query_range( 1048 1017 struct xfs_mount *mp, 1049 1018 struct xfs_trans *tp, 1050 - const struct xfs_rtalloc_rec *low_rec, 1051 - const struct xfs_rtalloc_rec *high_rec, 1019 + xfs_rtxnum_t start, 1020 + xfs_rtxnum_t end, 1052 1021 xfs_rtalloc_query_range_fn fn, 1053 1022 void *priv) 1054 1023 { ··· 1056 1025 .mp = mp, 1057 1026 .tp = tp, 1058 1027 }; 1059 - struct xfs_rtalloc_rec rec; 1060 - xfs_rtxnum_t rtstart; 1061 - xfs_rtxnum_t rtend; 1062 - xfs_rtxnum_t high_key; 1063 - int is_free; 1064 1028 int error = 0; 1065 1029 1066 - if (low_rec->ar_startext > high_rec->ar_startext) 1030 + if (start > end) 1067 1031 return -EINVAL; 1068 - if (low_rec->ar_startext >= mp->m_sb.sb_rextents || 1069 - low_rec->ar_startext == high_rec->ar_startext) 1032 + if (start == end || start >= mp->m_sb.sb_rextents) 1070 1033 return 0; 1071 1034 1072 - high_key = min(high_rec->ar_startext, mp->m_sb.sb_rextents - 1); 1035 + end = min(end, mp->m_sb.sb_rextents - 1); 1073 1036 1074 1037 /* Iterate the bitmap, looking for discrepancies. */ 1075 - rtstart = low_rec->ar_startext; 1076 - while (rtstart <= high_key) { 1038 + while (start <= end) { 1039 + struct xfs_rtalloc_rec rec; 1040 + int is_free; 1041 + xfs_rtxnum_t rtend; 1042 + 1077 1043 /* Is the first block free? */ 1078 - error = xfs_rtcheck_range(&args, rtstart, 1, 1, &rtend, 1044 + error = xfs_rtcheck_range(&args, start, 1, 1, &rtend, 1079 1045 &is_free); 1080 1046 if (error) 1081 1047 break; 1082 1048 1083 1049 /* How long does the extent go for? */ 1084 - error = xfs_rtfind_forw(&args, rtstart, high_key, &rtend); 1050 + error = xfs_rtfind_forw(&args, start, end, &rtend); 1085 1051 if (error) 1086 1052 break; 1087 1053 1088 1054 if (is_free) { 1089 - rec.ar_startext = rtstart; 1090 - rec.ar_extcount = rtend - rtstart + 1; 1055 + rec.ar_startext = start; 1056 + rec.ar_extcount = rtend - start + 1; 1091 1057 1092 1058 error = fn(mp, tp, &rec, priv); 1093 1059 if (error) 1094 1060 break; 1095 1061 } 1096 1062 1097 - rtstart = rtend + 1; 1063 + start = rtend + 1; 1098 1064 } 1099 1065 1100 1066 xfs_rtbuf_cache_relse(&args); ··· 1106 1078 xfs_rtalloc_query_range_fn fn, 1107 1079 void *priv) 1108 1080 { 1109 - struct xfs_rtalloc_rec keys[2]; 1110 - 1111 - keys[0].ar_startext = 0; 1112 - keys[1].ar_startext = mp->m_sb.sb_rextents - 1; 1113 - keys[0].ar_extcount = keys[1].ar_extcount = 0; 1114 - 1115 - return xfs_rtalloc_query_range(mp, tp, &keys[0], &keys[1], fn, priv); 1081 + return xfs_rtalloc_query_range(mp, tp, 0, mp->m_sb.sb_rextents - 1, fn, 1082 + priv); 1116 1083 } 1117 1084 1118 1085 /* Is the given extent all free? */ ··· 1148 1125 return howmany_64(rtextents, NBBY * mp->m_sb.sb_blocksize); 1149 1126 } 1150 1127 1151 - /* 1152 - * Compute the number of rtbitmap words needed to populate every block of a 1153 - * bitmap that is large enough to track the given number of rt extents. 1154 - */ 1155 - unsigned long long 1156 - xfs_rtbitmap_wordcount( 1157 - struct xfs_mount *mp, 1158 - xfs_rtbxlen_t rtextents) 1159 - { 1160 - xfs_filblks_t blocks; 1161 - 1162 - blocks = xfs_rtbitmap_blockcount(mp, rtextents); 1163 - return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; 1164 - } 1165 - 1166 1128 /* Compute the number of rtsummary blocks needed to track the given rt space. */ 1167 1129 xfs_filblks_t 1168 1130 xfs_rtsummary_blockcount( ··· 1161 1153 return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG); 1162 1154 } 1163 1155 1164 - /* 1165 - * Compute the number of rtsummary info words needed to populate every block of 1166 - * a summary file that is large enough to track the given rt space. 1167 - */ 1168 - unsigned long long 1169 - xfs_rtsummary_wordcount( 1170 - struct xfs_mount *mp, 1171 - unsigned int rsumlevels, 1172 - xfs_extlen_t rbmblocks) 1173 - { 1174 - xfs_filblks_t blocks; 1175 - 1176 - blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks); 1177 - return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG; 1178 - } 1179 - 1180 - /* 1181 - * Lock both realtime free space metadata inodes for a freespace update. If a 1182 - * transaction is given, the inodes will be joined to the transaction and the 1183 - * ILOCKs will be released on transaction commit. 1184 - */ 1156 + /* Lock both realtime free space metadata inodes for a freespace update. */ 1185 1157 void 1186 1158 xfs_rtbitmap_lock( 1187 - struct xfs_trans *tp, 1188 1159 struct xfs_mount *mp) 1189 1160 { 1190 1161 xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP); 1191 - if (tp) 1192 - xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL); 1193 - 1194 1162 xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM); 1195 - if (tp) 1196 - xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL); 1163 + } 1164 + 1165 + /* 1166 + * Join both realtime free space metadata inodes to the transaction. The 1167 + * ILOCKs will be released on transaction commit. 1168 + */ 1169 + void 1170 + xfs_rtbitmap_trans_join( 1171 + struct xfs_trans *tp) 1172 + { 1173 + xfs_trans_ijoin(tp, tp->t_mountp->m_rbmip, XFS_ILOCK_EXCL); 1174 + xfs_trans_ijoin(tp, tp->t_mountp->m_rsumip, XFS_ILOCK_EXCL); 1197 1175 } 1198 1176 1199 1177 /* Unlock both realtime free space metadata inodes after a freespace update. */ ··· 1218 1224 1219 1225 if (rbmlock_flags & XFS_RBMLOCK_BITMAP) 1220 1226 xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP); 1227 + } 1228 + 1229 + static int 1230 + xfs_rtfile_alloc_blocks( 1231 + struct xfs_inode *ip, 1232 + xfs_fileoff_t offset_fsb, 1233 + xfs_filblks_t count_fsb, 1234 + struct xfs_bmbt_irec *map) 1235 + { 1236 + struct xfs_mount *mp = ip->i_mount; 1237 + struct xfs_trans *tp; 1238 + int nmap = 1; 1239 + int error; 1240 + 1241 + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc, 1242 + XFS_GROWFSRT_SPACE_RES(mp, count_fsb), 0, 0, &tp); 1243 + if (error) 1244 + return error; 1245 + 1246 + xfs_ilock(ip, XFS_ILOCK_EXCL); 1247 + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 1248 + 1249 + error = xfs_iext_count_extend(tp, ip, XFS_DATA_FORK, 1250 + XFS_IEXT_ADD_NOSPLIT_CNT); 1251 + if (error) 1252 + goto out_trans_cancel; 1253 + 1254 + error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, 1255 + XFS_BMAPI_METADATA, 0, map, &nmap); 1256 + if (error) 1257 + goto out_trans_cancel; 1258 + 1259 + return xfs_trans_commit(tp); 1260 + 1261 + out_trans_cancel: 1262 + xfs_trans_cancel(tp); 1263 + return error; 1264 + } 1265 + 1266 + /* Get a buffer for the block. */ 1267 + static int 1268 + xfs_rtfile_initialize_block( 1269 + struct xfs_inode *ip, 1270 + xfs_fsblock_t fsbno, 1271 + void *data) 1272 + { 1273 + struct xfs_mount *mp = ip->i_mount; 1274 + struct xfs_trans *tp; 1275 + struct xfs_buf *bp; 1276 + const size_t copylen = mp->m_blockwsize << XFS_WORDLOG; 1277 + enum xfs_blft buf_type; 1278 + int error; 1279 + 1280 + if (ip == mp->m_rsumip) 1281 + buf_type = XFS_BLFT_RTSUMMARY_BUF; 1282 + else 1283 + buf_type = XFS_BLFT_RTBITMAP_BUF; 1284 + 1285 + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 0, 0, 0, &tp); 1286 + if (error) 1287 + return error; 1288 + xfs_ilock(ip, XFS_ILOCK_EXCL); 1289 + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 1290 + 1291 + error = xfs_trans_get_buf(tp, mp->m_ddev_targp, 1292 + XFS_FSB_TO_DADDR(mp, fsbno), mp->m_bsize, 0, &bp); 1293 + if (error) { 1294 + xfs_trans_cancel(tp); 1295 + return error; 1296 + } 1297 + 1298 + xfs_trans_buf_set_type(tp, bp, buf_type); 1299 + bp->b_ops = &xfs_rtbuf_ops; 1300 + if (data) 1301 + memcpy(bp->b_addr, data, copylen); 1302 + else 1303 + memset(bp->b_addr, 0, copylen); 1304 + xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); 1305 + return xfs_trans_commit(tp); 1306 + } 1307 + 1308 + /* 1309 + * Allocate space to the bitmap or summary file, and zero it, for growfs. 1310 + * @data must be a contiguous buffer large enough to fill all blocks in the 1311 + * file; or NULL to initialize the contents to zeroes. 1312 + */ 1313 + int 1314 + xfs_rtfile_initialize_blocks( 1315 + struct xfs_inode *ip, /* inode (bitmap/summary) */ 1316 + xfs_fileoff_t offset_fsb, /* offset to start from */ 1317 + xfs_fileoff_t end_fsb, /* offset to allocate to */ 1318 + void *data) /* data to fill the blocks */ 1319 + { 1320 + struct xfs_mount *mp = ip->i_mount; 1321 + const size_t copylen = mp->m_blockwsize << XFS_WORDLOG; 1322 + 1323 + while (offset_fsb < end_fsb) { 1324 + struct xfs_bmbt_irec map; 1325 + xfs_filblks_t i; 1326 + int error; 1327 + 1328 + error = xfs_rtfile_alloc_blocks(ip, offset_fsb, 1329 + end_fsb - offset_fsb, &map); 1330 + if (error) 1331 + return error; 1332 + 1333 + /* 1334 + * Now we need to clear the allocated blocks. 1335 + * 1336 + * Do this one block per transaction, to keep it simple. 1337 + */ 1338 + for (i = 0; i < map.br_blockcount; i++) { 1339 + error = xfs_rtfile_initialize_block(ip, 1340 + map.br_startblock + i, data); 1341 + if (error) 1342 + return error; 1343 + if (data) 1344 + data += copylen; 1345 + } 1346 + 1347 + offset_fsb = map.br_startoff + map.br_blockcount; 1348 + } 1349 + 1350 + return 0; 1221 1351 }
+11 -50
fs/xfs/libxfs/xfs_rtbitmap.h
··· 87 87 } 88 88 89 89 /* 90 - * Crack an rt block number into an rt extent number and an offset within that 91 - * rt extent. Returns the rt extent number directly and the offset in @off. 92 - */ 93 - static inline xfs_rtxnum_t 94 - xfs_rtb_to_rtxrem( 95 - struct xfs_mount *mp, 96 - xfs_rtblock_t rtbno, 97 - xfs_extlen_t *off) 98 - { 99 - if (likely(mp->m_rtxblklog >= 0)) { 100 - *off = rtbno & mp->m_rtxblkmask; 101 - return rtbno >> mp->m_rtxblklog; 102 - } 103 - 104 - return div_u64_rem(rtbno, mp->m_sb.sb_rextsize, off); 105 - } 106 - 107 - /* 108 90 * Convert an rt block number into an rt extent number, rounding up to the next 109 91 * rt extent if the rt block is not aligned to an rt extent boundary. 110 92 */ ··· 275 293 276 294 #ifdef CONFIG_XFS_RT 277 295 void xfs_rtbuf_cache_relse(struct xfs_rtalloc_args *args); 278 - 279 - int xfs_rtbuf_get(struct xfs_rtalloc_args *args, xfs_fileoff_t block, 280 - int issum); 281 - 282 - static inline int 283 - xfs_rtbitmap_read_buf( 284 - struct xfs_rtalloc_args *args, 285 - xfs_fileoff_t block) 286 - { 287 - return xfs_rtbuf_get(args, block, 0); 288 - } 289 - 290 - static inline int 291 - xfs_rtsummary_read_buf( 292 - struct xfs_rtalloc_args *args, 293 - xfs_fileoff_t block) 294 - { 295 - return xfs_rtbuf_get(args, block, 1); 296 - } 297 - 296 + int xfs_rtbitmap_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block); 297 + int xfs_rtsummary_read_buf(struct xfs_rtalloc_args *args, xfs_fileoff_t block); 298 298 int xfs_rtcheck_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 299 299 xfs_rtxlen_t len, int val, xfs_rtxnum_t *new, int *stat); 300 300 int xfs_rtfind_back(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 301 - xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 301 + xfs_rtxnum_t *rtblock); 302 302 int xfs_rtfind_forw(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 303 303 xfs_rtxnum_t limit, xfs_rtxnum_t *rtblock); 304 304 int xfs_rtmodify_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, ··· 292 328 int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start, 293 329 xfs_rtxlen_t len); 294 330 int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, 295 - const struct xfs_rtalloc_rec *low_rec, 296 - const struct xfs_rtalloc_rec *high_rec, 331 + xfs_rtxnum_t start, xfs_rtxnum_t end, 297 332 xfs_rtalloc_query_range_fn fn, void *priv); 298 333 int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp, 299 334 xfs_rtalloc_query_range_fn fn, ··· 316 353 317 354 xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t 318 355 rtextents); 319 - unsigned long long xfs_rtbitmap_wordcount(struct xfs_mount *mp, 320 - xfs_rtbxlen_t rtextents); 321 - 322 356 xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp, 323 357 unsigned int rsumlevels, xfs_extlen_t rbmblocks); 324 - unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp, 325 - unsigned int rsumlevels, xfs_extlen_t rbmblocks); 326 358 327 - void xfs_rtbitmap_lock(struct xfs_trans *tp, struct xfs_mount *mp); 359 + int xfs_rtfile_initialize_blocks(struct xfs_inode *ip, 360 + xfs_fileoff_t offset_fsb, xfs_fileoff_t end_fsb, void *data); 361 + 362 + void xfs_rtbitmap_lock(struct xfs_mount *mp); 328 363 void xfs_rtbitmap_unlock(struct xfs_mount *mp); 364 + void xfs_rtbitmap_trans_join(struct xfs_trans *tp); 329 365 330 366 /* Lock the rt bitmap inode in shared mode */ 331 367 #define XFS_RBMLOCK_BITMAP (1U << 0) ··· 350 388 /* shut up gcc */ 351 389 return 0; 352 390 } 353 - # define xfs_rtbitmap_wordcount(mp, r) (0) 354 391 # define xfs_rtsummary_blockcount(mp, l, b) (0) 355 - # define xfs_rtsummary_wordcount(mp, l, b) (0) 356 - # define xfs_rtbitmap_lock(tp, mp) do { } while (0) 392 + # define xfs_rtbitmap_lock(mp) do { } while (0) 393 + # define xfs_rtbitmap_trans_join(tp) do { } while (0) 357 394 # define xfs_rtbitmap_unlock(mp) do { } while (0) 358 395 # define xfs_rtbitmap_lock_shared(mp, lf) do { } while (0) 359 396 # define xfs_rtbitmap_unlock_shared(mp, lf) do { } while (0)
+53 -39
fs/xfs/libxfs/xfs_sb.c
··· 232 232 return 0; 233 233 } 234 234 235 + static uint64_t 236 + xfs_sb_calc_rbmblocks( 237 + struct xfs_sb *sbp) 238 + { 239 + return howmany_64(sbp->sb_rextents, NBBY * sbp->sb_blocksize); 240 + } 241 + 242 + /* Validate the realtime geometry */ 243 + bool 244 + xfs_validate_rt_geometry( 245 + struct xfs_sb *sbp) 246 + { 247 + if (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE || 248 + sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) 249 + return false; 250 + 251 + if (sbp->sb_rblocks == 0) { 252 + if (sbp->sb_rextents != 0 || sbp->sb_rbmblocks != 0 || 253 + sbp->sb_rextslog != 0 || sbp->sb_frextents != 0) 254 + return false; 255 + return true; 256 + } 257 + 258 + if (sbp->sb_rextents == 0 || 259 + sbp->sb_rextents != div_u64(sbp->sb_rblocks, sbp->sb_rextsize) || 260 + sbp->sb_rextslog != xfs_compute_rextslog(sbp->sb_rextents) || 261 + sbp->sb_rbmblocks != xfs_sb_calc_rbmblocks(sbp)) 262 + return false; 263 + 264 + return true; 265 + } 266 + 235 267 /* Check all the superblock fields we care about when writing one out. */ 236 268 STATIC int 237 269 xfs_validate_sb_write( ··· 523 491 } 524 492 } 525 493 526 - /* Validate the realtime geometry; stolen from xfs_repair */ 527 - if (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE || 528 - sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) { 494 + if (!xfs_validate_rt_geometry(sbp)) { 529 495 xfs_notice(mp, 530 - "realtime extent sanity check failed"); 496 + "realtime %sgeometry check failed", 497 + sbp->sb_rblocks ? "" : "zeroed "); 531 498 return -EFSCORRUPTED; 532 - } 533 - 534 - if (sbp->sb_rblocks == 0) { 535 - if (sbp->sb_rextents != 0 || sbp->sb_rbmblocks != 0 || 536 - sbp->sb_rextslog != 0 || sbp->sb_frextents != 0) { 537 - xfs_notice(mp, 538 - "realtime zeroed geometry check failed"); 539 - return -EFSCORRUPTED; 540 - } 541 - } else { 542 - uint64_t rexts; 543 - uint64_t rbmblocks; 544 - 545 - rexts = div_u64(sbp->sb_rblocks, sbp->sb_rextsize); 546 - rbmblocks = howmany_64(sbp->sb_rextents, 547 - NBBY * sbp->sb_blocksize); 548 - 549 - if (!xfs_validate_rtextents(rexts) || 550 - sbp->sb_rextents != rexts || 551 - sbp->sb_rextslog != xfs_compute_rextslog(rexts) || 552 - sbp->sb_rbmblocks != rbmblocks) { 553 - xfs_notice(mp, 554 - "realtime geometry sanity check failed"); 555 - return -EFSCORRUPTED; 556 - } 557 499 } 558 500 559 501 /* ··· 965 959 .verify_write = xfs_sb_write_verify, 966 960 }; 967 961 962 + void 963 + xfs_mount_sb_set_rextsize( 964 + struct xfs_mount *mp, 965 + struct xfs_sb *sbp) 966 + { 967 + mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); 968 + mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); 969 + } 970 + 968 971 /* 969 972 * xfs_mount_common 970 973 * ··· 998 983 mp->m_blockmask = sbp->sb_blocksize - 1; 999 984 mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; 1000 985 mp->m_blockwmask = mp->m_blockwsize - 1; 1001 - mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize); 1002 - mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize); 986 + xfs_mount_sb_set_rextsize(mp, sbp); 1003 987 1004 - mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); 1005 - mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); 988 + mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, true); 989 + mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, false); 1006 990 mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; 1007 991 mp->m_alloc_mnr[1] = mp->m_alloc_mxr[1] / 2; 1008 992 1009 - mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 1); 1010 - mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, 0); 993 + mp->m_bmap_dmxr[0] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, true); 994 + mp->m_bmap_dmxr[1] = xfs_bmbt_maxrecs(mp, sbp->sb_blocksize, false); 1011 995 mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; 1012 996 mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2; 1013 997 1014 - mp->m_rmap_mxr[0] = xfs_rmapbt_maxrecs(sbp->sb_blocksize, 1); 1015 - mp->m_rmap_mxr[1] = xfs_rmapbt_maxrecs(sbp->sb_blocksize, 0); 998 + mp->m_rmap_mxr[0] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, true); 999 + mp->m_rmap_mxr[1] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, false); 1016 1000 mp->m_rmap_mnr[0] = mp->m_rmap_mxr[0] / 2; 1017 1001 mp->m_rmap_mnr[1] = mp->m_rmap_mxr[1] / 2; 1018 1002 1019 - mp->m_refc_mxr[0] = xfs_refcountbt_maxrecs(sbp->sb_blocksize, true); 1020 - mp->m_refc_mxr[1] = xfs_refcountbt_maxrecs(sbp->sb_blocksize, false); 1003 + mp->m_refc_mxr[0] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, true); 1004 + mp->m_refc_mxr[1] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, false); 1021 1005 mp->m_refc_mnr[0] = mp->m_refc_mxr[0] / 2; 1022 1006 mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2; 1023 1007
+3
fs/xfs/libxfs/xfs_sb.h
··· 17 17 extern int xfs_sync_sb(struct xfs_mount *mp, bool wait); 18 18 extern int xfs_sync_sb_buf(struct xfs_mount *mp); 19 19 extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); 20 + void xfs_mount_sb_set_rextsize(struct xfs_mount *mp, 21 + struct xfs_sb *sbp); 20 22 extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from); 21 23 extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from); 22 24 extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp); ··· 40 38 bool xfs_validate_stripe_geometry(struct xfs_mount *mp, 41 39 __s64 sunit, __s64 swidth, int sectorsize, bool may_repair, 42 40 bool silent); 41 + bool xfs_validate_rt_geometry(struct xfs_sb *sbp); 43 42 44 43 uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents); 45 44
+2 -2
fs/xfs/libxfs/xfs_trans_resv.c
··· 130 130 (4 * sizeof(struct xlog_op_header) + 131 131 sizeof(struct xfs_inode_log_format) + 132 132 mp->m_sb.sb_inodesize + 133 - 2 * XFS_BMBT_BLOCK_LEN(mp)); 133 + 2 * xfs_bmbt_block_len(mp)); 134 134 } 135 135 136 136 /* ··· 918 918 return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 919 919 xfs_calc_inode_res(mp, 2) + 920 920 xfs_calc_buf_res(1, mp->m_sb.sb_blocksize) + 921 - xfs_calc_buf_res(1, mp->m_rsumsize); 921 + xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, mp->m_rsumblocks)); 922 922 } 923 923 924 924 /*
-12
fs/xfs/libxfs/xfs_types.h
··· 235 235 bool xfs_verify_fileext(struct xfs_mount *mp, xfs_fileoff_t off, 236 236 xfs_fileoff_t len); 237 237 238 - /* Do we support an rt volume having this number of rtextents? */ 239 - static inline bool 240 - xfs_validate_rtextents( 241 - xfs_rtbxlen_t rtextents) 242 - { 243 - /* No runt rt volumes */ 244 - if (rtextents == 0) 245 - return false; 246 - 247 - return true; 248 - } 249 - 250 238 #endif /* __XFS_TYPES_H__ */
+1 -1
fs/xfs/scrub/bmap_repair.c
··· 480 480 { 481 481 ASSERT(level > 0); 482 482 483 - return XFS_BMAP_BROOT_SPACE_CALC(cur->bc_mp, nr_this_level); 483 + return xfs_bmap_broot_space_calc(cur->bc_mp, nr_this_level); 484 484 } 485 485 486 486 /* Update the inode counters. */
+9 -20
fs/xfs/scrub/common.h
··· 53 53 bool xchk_should_check_xref(struct xfs_scrub *sc, int *error, 54 54 struct xfs_btree_cur **curpp); 55 55 56 + static inline int xchk_setup_nothing(struct xfs_scrub *sc) 57 + { 58 + return -ENOENT; 59 + } 60 + 56 61 /* Setup functions */ 57 62 int xchk_setup_agheader(struct xfs_scrub *sc); 58 63 int xchk_setup_fs(struct xfs_scrub *sc); ··· 77 72 int xchk_setup_rtbitmap(struct xfs_scrub *sc); 78 73 int xchk_setup_rtsummary(struct xfs_scrub *sc); 79 74 #else 80 - static inline int 81 - xchk_setup_rtbitmap(struct xfs_scrub *sc) 82 - { 83 - return -ENOENT; 84 - } 85 - static inline int 86 - xchk_setup_rtsummary(struct xfs_scrub *sc) 87 - { 88 - return -ENOENT; 89 - } 75 + # define xchk_setup_rtbitmap xchk_setup_nothing 76 + # define xchk_setup_rtsummary xchk_setup_nothing 90 77 #endif 91 78 #ifdef CONFIG_XFS_QUOTA 92 79 int xchk_ino_dqattach(struct xfs_scrub *sc); ··· 90 93 { 91 94 return 0; 92 95 } 93 - static inline int 94 - xchk_setup_quota(struct xfs_scrub *sc) 95 - { 96 - return -ENOENT; 97 - } 98 - static inline int 99 - xchk_setup_quotacheck(struct xfs_scrub *sc) 100 - { 101 - return -ENOENT; 102 - } 96 + # define xchk_setup_quota xchk_setup_nothing 97 + # define xchk_setup_quotacheck xchk_setup_nothing 103 98 #endif 104 99 int xchk_setup_fscounters(struct xfs_scrub *sc); 105 100 int xchk_setup_nlinks(struct xfs_scrub *sc);
+6 -6
fs/xfs/scrub/inode_repair.c
··· 846 846 nrecs = be16_to_cpu(dfp->bb_numrecs); 847 847 level = be16_to_cpu(dfp->bb_level); 848 848 849 - if (nrecs == 0 || XFS_BMDR_SPACE_CALC(nrecs) > dfork_size) 849 + if (nrecs == 0 || xfs_bmdr_space_calc(nrecs) > dfork_size) 850 850 return true; 851 851 if (level == 0 || level >= XFS_BM_MAXLEVELS(sc->mp, whichfork)) 852 852 return true; ··· 858 858 xfs_fileoff_t fileoff; 859 859 xfs_fsblock_t fsbno; 860 860 861 - fkp = XFS_BMDR_KEY_ADDR(dfp, i); 861 + fkp = xfs_bmdr_key_addr(dfp, i); 862 862 fileoff = be64_to_cpu(fkp->br_startoff); 863 863 if (!xfs_verify_fileoff(sc->mp, fileoff)) 864 864 return true; 865 865 866 - fpp = XFS_BMDR_PTR_ADDR(dfp, i, dmxr); 866 + fpp = xfs_bmdr_ptr_addr(dfp, i, dmxr); 867 867 fsbno = be64_to_cpu(*fpp); 868 868 if (!xfs_verify_fsbno(sc->mp, fsbno)) 869 869 return true; ··· 1121 1121 struct xfs_bmdr_block *bmdr; 1122 1122 struct xfs_scrub *sc = ri->sc; 1123 1123 xfs_extnum_t attr_extents, data_extents; 1124 - size_t bmdr_minsz = XFS_BMDR_SPACE_CALC(1); 1124 + size_t bmdr_minsz = xfs_bmdr_space_calc(1); 1125 1125 unsigned int lit_sz = XFS_LITINO(sc->mp); 1126 1126 unsigned int afork_min, dfork_min; 1127 1127 ··· 1173 1173 case XFS_DINODE_FMT_BTREE: 1174 1174 /* Must have space for btree header and key/pointers. */ 1175 1175 bmdr = XFS_DFORK_PTR(dip, XFS_ATTR_FORK); 1176 - afork_min = XFS_BMAP_BROOT_SPACE(sc->mp, bmdr); 1176 + afork_min = xfs_bmap_broot_space(sc->mp, bmdr); 1177 1177 break; 1178 1178 default: 1179 1179 /* We should never see any other formats. */ ··· 1223 1223 case XFS_DINODE_FMT_BTREE: 1224 1224 /* Must have space for btree header and key/pointers. */ 1225 1225 bmdr = XFS_DFORK_PTR(dip, XFS_DATA_FORK); 1226 - dfork_min = XFS_BMAP_BROOT_SPACE(sc->mp, bmdr); 1226 + dfork_min = xfs_bmap_broot_space(sc->mp, bmdr); 1227 1227 break; 1228 1228 default: 1229 1229 dfork_min = 0;
+5 -6
fs/xfs/scrub/rtsummary.c
··· 63 63 * us to avoid pinning kernel memory for this purpose. 64 64 */ 65 65 descr = xchk_xfile_descr(sc, "realtime summary file"); 66 - error = xfile_create(descr, mp->m_rsumsize, &sc->xfile); 66 + error = xfile_create(descr, XFS_FSB_TO_B(mp, mp->m_rsumblocks), 67 + &sc->xfile); 67 68 kfree(descr); 68 69 if (error) 69 70 return error; ··· 96 95 * volume. Hence it is safe to compute and check the geometry values. 97 96 */ 98 97 if (mp->m_sb.sb_rblocks) { 99 - xfs_filblks_t rsumblocks; 100 98 int rextslog; 101 99 102 100 rts->rextents = xfs_rtb_to_rtx(mp, mp->m_sb.sb_rblocks); 103 101 rextslog = xfs_compute_rextslog(rts->rextents); 104 102 rts->rsumlevels = rextslog + 1; 105 103 rts->rbmblocks = xfs_rtbitmap_blockcount(mp, rts->rextents); 106 - rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, 104 + rts->rsumblocks = xfs_rtsummary_blockcount(mp, rts->rsumlevels, 107 105 rts->rbmblocks); 108 - rts->rsumsize = XFS_FSB_TO_B(mp, rsumblocks); 109 106 } 110 107 return 0; 111 108 } ··· 315 316 } 316 317 317 318 /* Is m_rsumsize correct? */ 318 - if (mp->m_rsumsize != rts->rsumsize) { 319 + if (mp->m_rsumblocks != rts->rsumblocks) { 319 320 xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); 320 321 goto out_rbm; 321 322 } ··· 331 332 * growfsrt expands the summary file before updating sb_rextents, so 332 333 * the file can be larger than rsumsize. 333 334 */ 334 - if (mp->m_rsumip->i_disk_size < rts->rsumsize) { 335 + if (mp->m_rsumip->i_disk_size < XFS_FSB_TO_B(mp, rts->rsumblocks)) { 335 336 xchk_ino_set_corrupt(sc, mp->m_rsumip->i_ino); 336 337 goto out_rbm; 337 338 }
+1 -1
fs/xfs/scrub/rtsummary.h
··· 14 14 15 15 uint64_t rextents; 16 16 uint64_t rbmblocks; 17 - uint64_t rsumsize; 17 + xfs_filblks_t rsumblocks; 18 18 unsigned int rsumlevels; 19 19 unsigned int resblks; 20 20
+5 -7
fs/xfs/scrub/rtsummary_repair.c
··· 56 56 * transaction (which we cannot drop because we cannot drop the 57 57 * rtsummary ILOCK) and cannot ask for more reservation. 58 58 */ 59 - blocks = XFS_B_TO_FSB(mp, mp->m_rsumsize); 59 + blocks = mp->m_rsumblocks; 60 60 blocks += xfs_bmbt_calc_size(mp, blocks) * 2; 61 61 if (blocks > UINT_MAX) 62 62 return -EOPNOTSUPP; ··· 100 100 { 101 101 struct xchk_rtsummary *rts = sc->buf; 102 102 struct xfs_mount *mp = sc->mp; 103 - xfs_filblks_t rsumblocks; 104 103 int error; 105 104 106 105 /* We require the rmapbt to rebuild anything. */ ··· 130 131 } 131 132 132 133 /* Make sure we have space allocated for the entire summary file. */ 133 - rsumblocks = XFS_B_TO_FSB(mp, rts->rsumsize); 134 134 xfs_trans_ijoin(sc->tp, sc->ip, 0); 135 135 xfs_trans_ijoin(sc->tp, sc->tempip, 0); 136 - error = xrep_tempfile_prealloc(sc, 0, rsumblocks); 136 + error = xrep_tempfile_prealloc(sc, 0, rts->rsumblocks); 137 137 if (error) 138 138 return error; 139 139 ··· 141 143 return error; 142 144 143 145 /* Copy the rtsummary file that we generated. */ 144 - error = xrep_tempfile_copyin(sc, 0, rsumblocks, 146 + error = xrep_tempfile_copyin(sc, 0, rts->rsumblocks, 145 147 xrep_rtsummary_prep_buf, rts); 146 148 if (error) 147 149 return error; 148 - error = xrep_tempfile_set_isize(sc, rts->rsumsize); 150 + error = xrep_tempfile_set_isize(sc, XFS_FSB_TO_B(mp, rts->rsumblocks)); 149 151 if (error) 150 152 return error; 151 153 ··· 166 168 memset(mp->m_rsum_cache, 0xFF, mp->m_sb.sb_rbmblocks); 167 169 168 170 mp->m_rsumlevels = rts->rsumlevels; 169 - mp->m_rsumsize = rts->rsumsize; 171 + mp->m_rsumblocks = rts->rsumblocks; 170 172 171 173 /* Free the old rtsummary blocks if they're not in use. */ 172 174 return xrep_reap_ifork(sc, sc->tempip, XFS_DATA_FORK);
+9 -20
fs/xfs/scrub/scrub.h
··· 231 231 return false; 232 232 } 233 233 234 + static inline int xchk_nothing(struct xfs_scrub *sc) 235 + { 236 + return -ENOENT; 237 + } 238 + 234 239 /* Metadata scrubbers */ 235 240 int xchk_tester(struct xfs_scrub *sc); 236 241 int xchk_superblock(struct xfs_scrub *sc); ··· 259 254 int xchk_rtbitmap(struct xfs_scrub *sc); 260 255 int xchk_rtsummary(struct xfs_scrub *sc); 261 256 #else 262 - static inline int 263 - xchk_rtbitmap(struct xfs_scrub *sc) 264 - { 265 - return -ENOENT; 266 - } 267 - static inline int 268 - xchk_rtsummary(struct xfs_scrub *sc) 269 - { 270 - return -ENOENT; 271 - } 257 + # define xchk_rtbitmap xchk_nothing 258 + # define xchk_rtsummary xchk_nothing 272 259 #endif 273 260 #ifdef CONFIG_XFS_QUOTA 274 261 int xchk_quota(struct xfs_scrub *sc); 275 262 int xchk_quotacheck(struct xfs_scrub *sc); 276 263 #else 277 - static inline int 278 - xchk_quota(struct xfs_scrub *sc) 279 - { 280 - return -ENOENT; 281 - } 282 - static inline int 283 - xchk_quotacheck(struct xfs_scrub *sc) 284 - { 285 - return -ENOENT; 286 - } 264 + # define xchk_quota xchk_nothing 265 + # define xchk_quotacheck xchk_nothing 287 266 #endif 288 267 int xchk_fscounters(struct xfs_scrub *sc); 289 268 int xchk_nlinks(struct xfs_scrub *sc);
+1 -1
fs/xfs/scrub/tempfile.c
··· 88 88 goto out_release_dquots; 89 89 90 90 /* Allocate inode, set up directory. */ 91 - error = xfs_dialloc(&tp, dp->i_ino, mode, &ino); 91 + error = xfs_dialloc(&tp, &args, &ino); 92 92 if (error) 93 93 goto out_trans_cancel; 94 94 error = xfs_icreate(tp, ino, &args, &sc->tempip);
+17
fs/xfs/xfs_bmap_item.c
··· 346 346 trace_xfs_bmap_defer(bi); 347 347 348 348 xfs_bmap_update_get_group(tp->t_mountp, bi); 349 + 350 + /* 351 + * Ensure the deferred mapping is pre-recorded in i_delayed_blks. 352 + * 353 + * Otherwise stat can report zero blocks for an inode that actually has 354 + * data when the entire mapping is in the process of being overwritten 355 + * using the out of place write path. This is undone in xfs_bmapi_remap 356 + * after it has incremented di_nblocks for a successful operation. 357 + */ 358 + if (bi->bi_type == XFS_BMAP_MAP) 359 + bi->bi_owner->i_delayed_blks += bi->bi_bmap.br_blockcount; 349 360 xfs_defer_add(tp, &bi->bi_list, &xfs_bmap_update_defer_type); 350 361 } 351 362 ··· 377 366 struct list_head *item) 378 367 { 379 368 struct xfs_bmap_intent *bi = bi_entry(item); 369 + 370 + if (bi->bi_type == XFS_BMAP_MAP) 371 + bi->bi_owner->i_delayed_blks -= bi->bi_bmap.br_blockcount; 380 372 381 373 xfs_bmap_update_put_group(bi); 382 374 kmem_cache_free(xfs_bmap_intent_cache, bi); ··· 478 464 bi->bi_owner = *ipp; 479 465 xfs_bmap_update_get_group(mp, bi); 480 466 467 + /* see xfs_bmap_defer_add for details */ 468 + if (bi->bi_type == XFS_BMAP_MAP) 469 + bi->bi_owner->i_delayed_blks += bi->bi_bmap.br_blockcount; 481 470 xfs_defer_add_item(dfp, &bi->bi_list); 482 471 return bi; 483 472 }
+14 -24
fs/xfs/xfs_bmap_util.c
··· 331 331 } 332 332 333 333 if (xfs_get_extsz_hint(ip) || 334 - (ip->i_diflags & 335 - (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND))) 334 + (ip->i_diflags & XFS_DIFLAG_PREALLOC)) 336 335 max_len = mp->m_super->s_maxbytes; 337 336 else 338 337 max_len = XFS_ISIZE(ip); ··· 491 492 xfs_can_free_eofblocks( 492 493 struct xfs_inode *ip) 493 494 { 494 - struct xfs_bmbt_irec imap; 495 495 struct xfs_mount *mp = ip->i_mount; 496 + bool found_blocks = false; 496 497 xfs_fileoff_t end_fsb; 497 498 xfs_fileoff_t last_fsb; 498 - int nimaps = 1; 499 - int error; 499 + struct xfs_bmbt_irec imap; 500 + struct xfs_iext_cursor icur; 500 501 501 502 /* 502 503 * Caller must either hold the exclusive io lock; or be inactivating ··· 523 524 return false; 524 525 525 526 /* 526 - * Only free real extents for inodes with persistent preallocations or 527 - * the append-only flag. 527 + * Do not free real extents in preallocated files unless the file has 528 + * delalloc blocks and we are forced to remove them. 528 529 */ 529 - if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) 530 - if (ip->i_delayed_blks == 0) 531 - return false; 530 + if ((ip->i_diflags & XFS_DIFLAG_PREALLOC) && !ip->i_delayed_blks) 531 + return false; 532 532 533 533 /* 534 534 * Do not try to free post-EOF blocks if EOF is beyond the end of the ··· 542 544 return false; 543 545 544 546 /* 545 - * Look up the mapping for the first block past EOF. If we can't find 546 - * it, there's nothing to free. 547 + * Check if there is an post-EOF extent to free. 547 548 */ 548 549 xfs_ilock(ip, XFS_ILOCK_SHARED); 549 - error = xfs_bmapi_read(ip, end_fsb, last_fsb - end_fsb, &imap, &nimaps, 550 - 0); 550 + if (xfs_iext_lookup_extent(ip, &ip->i_df, end_fsb, &icur, &imap)) 551 + found_blocks = true; 551 552 xfs_iunlock(ip, XFS_ILOCK_SHARED); 552 - if (error || nimaps == 0) 553 - return false; 554 - 555 - /* 556 - * If there's a real mapping there or there are delayed allocation 557 - * reservations, then we have post-EOF blocks to try to free. 558 - */ 559 - return imap.br_startblock != HOLESTARTBLOCK || ip->i_delayed_blks; 553 + return found_blocks; 560 554 } 561 555 562 556 /* ··· 1185 1195 */ 1186 1196 if (tifp->if_format == XFS_DINODE_FMT_BTREE) { 1187 1197 if (xfs_inode_has_attr_fork(ip) && 1188 - XFS_BMAP_BMDR_SPACE(tifp->if_broot) > xfs_inode_fork_boff(ip)) 1198 + xfs_bmap_bmdr_space(tifp->if_broot) > xfs_inode_fork_boff(ip)) 1189 1199 return -EINVAL; 1190 1200 if (tifp->if_nextents <= XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)) 1191 1201 return -EINVAL; ··· 1194 1204 /* Reciprocal target->temp btree format checks */ 1195 1205 if (ifp->if_format == XFS_DINODE_FMT_BTREE) { 1196 1206 if (xfs_inode_has_attr_fork(tip) && 1197 - XFS_BMAP_BMDR_SPACE(ip->i_df.if_broot) > xfs_inode_fork_boff(tip)) 1207 + xfs_bmap_bmdr_space(ip->i_df.if_broot) > xfs_inode_fork_boff(tip)) 1198 1208 return -EINVAL; 1199 1209 if (ifp->if_nextents <= XFS_IFORK_MAXEXT(tip, XFS_DATA_FORK)) 1200 1210 return -EINVAL;
+8 -9
fs/xfs/xfs_discard.c
··· 554 554 xfs_daddr_t end, 555 555 xfs_daddr_t minlen) 556 556 { 557 - struct xfs_rtalloc_rec low = { }; 558 - struct xfs_rtalloc_rec high = { }; 559 557 struct xfs_trim_rtdev tr = { 560 558 .minlen_fsb = XFS_BB_TO_FSB(mp, minlen), 561 559 }; 560 + xfs_rtxnum_t low, high; 562 561 struct xfs_trans *tp; 563 562 xfs_daddr_t rtdev_daddr; 564 563 int error; ··· 583 584 XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks) - 1); 584 585 585 586 /* Convert the rt blocks to rt extents */ 586 - low.ar_startext = xfs_rtb_to_rtxup(mp, XFS_BB_TO_FSB(mp, start)); 587 - high.ar_startext = xfs_rtb_to_rtx(mp, XFS_BB_TO_FSBT(mp, end)); 587 + low = xfs_rtb_to_rtxup(mp, XFS_BB_TO_FSB(mp, start)); 588 + high = xfs_rtb_to_rtx(mp, XFS_BB_TO_FSBT(mp, end)); 588 589 589 590 /* 590 591 * Walk the free ranges between low and high. The query_range function 591 592 * trims the extents returned. 592 593 */ 593 594 do { 594 - tr.stop_rtx = low.ar_startext + (mp->m_sb.sb_blocksize * NBBY); 595 + tr.stop_rtx = low + (mp->m_sb.sb_blocksize * NBBY); 595 596 xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); 596 - error = xfs_rtalloc_query_range(mp, tp, &low, &high, 597 + error = xfs_rtalloc_query_range(mp, tp, low, high, 597 598 xfs_trim_gather_rtextent, &tr); 598 599 599 600 if (error == -ECANCELED) ··· 614 615 if (error) 615 616 break; 616 617 617 - low.ar_startext = tr.restart_rtx; 618 - } while (!xfs_trim_should_stop() && low.ar_startext <= high.ar_startext); 618 + low = tr.restart_rtx; 619 + } while (!xfs_trim_should_stop() && low <= high); 619 620 620 621 xfs_trans_cancel(tp); 621 622 return error; ··· 707 708 return last_error; 708 709 709 710 range.len = min_t(unsigned long long, range.len, 710 - XFS_FSB_TO_B(mp, max_blocks)); 711 + XFS_FSB_TO_B(mp, max_blocks) - range.start); 711 712 if (copy_to_user(urange, &range, sizeof(range))) 712 713 return -EFAULT; 713 714 return 0;
+142 -1
fs/xfs/xfs_exchrange.c
··· 72 72 return error; 73 73 } 74 74 75 + /* 76 + * Check that file2's metadata agree with the snapshot that we took for the 77 + * range commit request. 78 + * 79 + * This should be called after the filesystem has locked /all/ inode metadata 80 + * against modification. 81 + */ 82 + STATIC int 83 + xfs_exchrange_check_freshness( 84 + const struct xfs_exchrange *fxr, 85 + struct xfs_inode *ip2) 86 + { 87 + struct inode *inode2 = VFS_I(ip2); 88 + struct timespec64 ctime = inode_get_ctime(inode2); 89 + struct timespec64 mtime = inode_get_mtime(inode2); 90 + 91 + trace_xfs_exchrange_freshness(fxr, ip2); 92 + 93 + /* Check that file2 hasn't otherwise been modified. */ 94 + if (fxr->file2_ino != ip2->i_ino || 95 + fxr->file2_gen != inode2->i_generation || 96 + !timespec64_equal(&fxr->file2_ctime, &ctime) || 97 + !timespec64_equal(&fxr->file2_mtime, &mtime)) 98 + return -EBUSY; 99 + 100 + return 0; 101 + } 102 + 75 103 #define QRETRY_IP1 (0x1) 76 104 #define QRETRY_IP2 (0x2) 77 105 ··· 635 607 if (error || fxr->length == 0) 636 608 return error; 637 609 610 + if (fxr->flags & __XFS_EXCHANGE_RANGE_CHECK_FRESH2) { 611 + error = xfs_exchrange_check_freshness(fxr, ip2); 612 + if (error) 613 + return error; 614 + } 615 + 638 616 /* Attach dquots to both inodes before changing block maps. */ 639 617 error = xfs_qm_dqattach(ip2); 640 618 if (error) ··· 753 719 if (fxr->file1->f_path.mnt != fxr->file2->f_path.mnt) 754 720 return -EXDEV; 755 721 756 - if (fxr->flags & ~XFS_EXCHANGE_RANGE_ALL_FLAGS) 722 + if (fxr->flags & ~(XFS_EXCHANGE_RANGE_ALL_FLAGS | 723 + __XFS_EXCHANGE_RANGE_CHECK_FRESH2)) 757 724 return -EINVAL; 758 725 759 726 /* Userspace requests only honored for regular files. */ ··· 827 792 fxr.file2_offset = args.file2_offset; 828 793 fxr.length = args.length; 829 794 fxr.flags = args.flags; 795 + 796 + file1 = fdget(args.file1_fd); 797 + if (!file1.file) 798 + return -EBADF; 799 + fxr.file1 = file1.file; 800 + 801 + error = xfs_exchange_range(&fxr); 802 + fdput(file1); 803 + return error; 804 + } 805 + 806 + /* Opaque freshness blob for XFS_IOC_COMMIT_RANGE */ 807 + struct xfs_commit_range_fresh { 808 + xfs_fsid_t fsid; /* m_fixedfsid */ 809 + __u64 file2_ino; /* inode number */ 810 + __s64 file2_mtime; /* modification time */ 811 + __s64 file2_ctime; /* change time */ 812 + __s32 file2_mtime_nsec; /* mod time, nsec */ 813 + __s32 file2_ctime_nsec; /* change time, nsec */ 814 + __u32 file2_gen; /* inode generation */ 815 + __u32 magic; /* zero */ 816 + }; 817 + #define XCR_FRESH_MAGIC 0x444F524B /* DORK */ 818 + 819 + /* Set up a commitrange operation by sampling file2's write-related attrs */ 820 + long 821 + xfs_ioc_start_commit( 822 + struct file *file, 823 + struct xfs_commit_range __user *argp) 824 + { 825 + struct xfs_commit_range args = { }; 826 + struct timespec64 ts; 827 + struct xfs_commit_range_fresh *kern_f; 828 + struct xfs_commit_range_fresh __user *user_f; 829 + struct inode *inode2 = file_inode(file); 830 + struct xfs_inode *ip2 = XFS_I(inode2); 831 + const unsigned int lockflags = XFS_IOLOCK_SHARED | 832 + XFS_MMAPLOCK_SHARED | 833 + XFS_ILOCK_SHARED; 834 + 835 + BUILD_BUG_ON(sizeof(struct xfs_commit_range_fresh) != 836 + sizeof(args.file2_freshness)); 837 + 838 + kern_f = (struct xfs_commit_range_fresh *)&args.file2_freshness; 839 + 840 + memcpy(&kern_f->fsid, ip2->i_mount->m_fixedfsid, sizeof(xfs_fsid_t)); 841 + 842 + xfs_ilock(ip2, lockflags); 843 + ts = inode_get_ctime(inode2); 844 + kern_f->file2_ctime = ts.tv_sec; 845 + kern_f->file2_ctime_nsec = ts.tv_nsec; 846 + ts = inode_get_mtime(inode2); 847 + kern_f->file2_mtime = ts.tv_sec; 848 + kern_f->file2_mtime_nsec = ts.tv_nsec; 849 + kern_f->file2_ino = ip2->i_ino; 850 + kern_f->file2_gen = inode2->i_generation; 851 + kern_f->magic = XCR_FRESH_MAGIC; 852 + xfs_iunlock(ip2, lockflags); 853 + 854 + user_f = (struct xfs_commit_range_fresh __user *)&argp->file2_freshness; 855 + if (copy_to_user(user_f, kern_f, sizeof(*kern_f))) 856 + return -EFAULT; 857 + 858 + return 0; 859 + } 860 + 861 + /* 862 + * Exchange file1 and file2 contents if file2 has not been written since the 863 + * start commit operation. 864 + */ 865 + long 866 + xfs_ioc_commit_range( 867 + struct file *file, 868 + struct xfs_commit_range __user *argp) 869 + { 870 + struct xfs_exchrange fxr = { 871 + .file2 = file, 872 + }; 873 + struct xfs_commit_range args; 874 + struct xfs_commit_range_fresh *kern_f; 875 + struct xfs_inode *ip2 = XFS_I(file_inode(file)); 876 + struct xfs_mount *mp = ip2->i_mount; 877 + struct fd file1; 878 + int error; 879 + 880 + kern_f = (struct xfs_commit_range_fresh *)&args.file2_freshness; 881 + 882 + if (copy_from_user(&args, argp, sizeof(args))) 883 + return -EFAULT; 884 + if (args.flags & ~XFS_EXCHANGE_RANGE_ALL_FLAGS) 885 + return -EINVAL; 886 + if (kern_f->magic != XCR_FRESH_MAGIC) 887 + return -EBUSY; 888 + if (memcmp(&kern_f->fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t))) 889 + return -EBUSY; 890 + 891 + fxr.file1_offset = args.file1_offset; 892 + fxr.file2_offset = args.file2_offset; 893 + fxr.length = args.length; 894 + fxr.flags = args.flags | __XFS_EXCHANGE_RANGE_CHECK_FRESH2; 895 + fxr.file2_ino = kern_f->file2_ino; 896 + fxr.file2_gen = kern_f->file2_gen; 897 + fxr.file2_mtime.tv_sec = kern_f->file2_mtime; 898 + fxr.file2_mtime.tv_nsec = kern_f->file2_mtime_nsec; 899 + fxr.file2_ctime.tv_sec = kern_f->file2_ctime; 900 + fxr.file2_ctime.tv_nsec = kern_f->file2_ctime_nsec; 830 901 831 902 file1 = fdget(args.file1_fd); 832 903 if (!file1.file)
+15 -1
fs/xfs/xfs_exchrange.h
··· 10 10 #define __XFS_EXCHANGE_RANGE_UPD_CMTIME1 (1ULL << 63) 11 11 #define __XFS_EXCHANGE_RANGE_UPD_CMTIME2 (1ULL << 62) 12 12 13 + /* Freshness check required */ 14 + #define __XFS_EXCHANGE_RANGE_CHECK_FRESH2 (1ULL << 61) 15 + 13 16 #define XFS_EXCHANGE_RANGE_PRIV_FLAGS (__XFS_EXCHANGE_RANGE_UPD_CMTIME1 | \ 14 - __XFS_EXCHANGE_RANGE_UPD_CMTIME2) 17 + __XFS_EXCHANGE_RANGE_UPD_CMTIME2 | \ 18 + __XFS_EXCHANGE_RANGE_CHECK_FRESH2) 15 19 16 20 struct xfs_exchrange { 17 21 struct file *file1; ··· 26 22 u64 length; 27 23 28 24 u64 flags; /* XFS_EXCHANGE_RANGE flags */ 25 + 26 + /* file2 metadata for freshness checks */ 27 + u64 file2_ino; 28 + struct timespec64 file2_mtime; 29 + struct timespec64 file2_ctime; 30 + u32 file2_gen; 29 31 }; 30 32 31 33 long xfs_ioc_exchange_range(struct file *file, 32 34 struct xfs_exchange_range __user *argp); 35 + long xfs_ioc_start_commit(struct file *file, 36 + struct xfs_commit_range __user *argp); 37 + long xfs_ioc_commit_range(struct file *file, 38 + struct xfs_commit_range __user *argp); 33 39 34 40 struct xfs_exchmaps_req; 35 41
+69 -3
fs/xfs/xfs_file.c
··· 1238 1238 return error; 1239 1239 } 1240 1240 1241 + /* 1242 + * Don't bother propagating errors. We're just doing cleanup, and the caller 1243 + * ignores the return value anyway. 1244 + */ 1241 1245 STATIC int 1242 1246 xfs_file_release( 1243 - struct inode *inode, 1244 - struct file *filp) 1247 + struct inode *inode, 1248 + struct file *file) 1245 1249 { 1246 - return xfs_release(XFS_I(inode)); 1250 + struct xfs_inode *ip = XFS_I(inode); 1251 + struct xfs_mount *mp = ip->i_mount; 1252 + 1253 + /* 1254 + * If this is a read-only mount or the file system has been shut down, 1255 + * don't generate I/O. 1256 + */ 1257 + if (xfs_is_readonly(mp) || xfs_is_shutdown(mp)) 1258 + return 0; 1259 + 1260 + /* 1261 + * If we previously truncated this file and removed old data in the 1262 + * process, we want to initiate "early" writeout on the last close. 1263 + * This is an attempt to combat the notorious NULL files problem which 1264 + * is particularly noticeable from a truncate down, buffered (re-)write 1265 + * (delalloc), followed by a crash. What we are effectively doing here 1266 + * is significantly reducing the time window where we'd otherwise be 1267 + * exposed to that problem. 1268 + */ 1269 + if (xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED)) { 1270 + xfs_iflags_clear(ip, XFS_EOFBLOCKS_RELEASED); 1271 + if (ip->i_delayed_blks > 0) 1272 + filemap_flush(inode->i_mapping); 1273 + } 1274 + 1275 + /* 1276 + * XFS aggressively preallocates post-EOF space to generate contiguous 1277 + * allocations for writers that append to the end of the file. 1278 + * 1279 + * To support workloads that close and reopen the file frequently, these 1280 + * preallocations usually persist after a close unless it is the first 1281 + * close for the inode. This is a tradeoff to generate tightly packed 1282 + * data layouts for unpacking tarballs or similar archives that write 1283 + * one file after another without going back to it while keeping the 1284 + * preallocation for files that have recurring open/write/close cycles. 1285 + * 1286 + * This heuristic is skipped for inodes with the append-only flag as 1287 + * that flag is rather pointless for inodes written only once. 1288 + * 1289 + * There is no point in freeing blocks here for open but unlinked files 1290 + * as they will be taken care of by the inactivation path soon. 1291 + * 1292 + * When releasing a read-only context, don't flush data or trim post-EOF 1293 + * blocks. This avoids open/read/close workloads from removing EOF 1294 + * blocks that other writers depend upon to reduce fragmentation. 1295 + * 1296 + * If we can't get the iolock just skip truncating the blocks past EOF 1297 + * because we could deadlock with the mmap_lock otherwise. We'll get 1298 + * another chance to drop them once the last reference to the inode is 1299 + * dropped, so we'll never leak blocks permanently. 1300 + */ 1301 + if (inode->i_nlink && 1302 + (file->f_mode & FMODE_WRITE) && 1303 + !(ip->i_diflags & XFS_DIFLAG_APPEND) && 1304 + !xfs_iflags_test(ip, XFS_EOFBLOCKS_RELEASED) && 1305 + xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { 1306 + if (xfs_can_free_eofblocks(ip) && 1307 + !xfs_iflags_test_and_set(ip, XFS_EOFBLOCKS_RELEASED)) 1308 + xfs_free_eofblocks(ip); 1309 + xfs_iunlock(ip, XFS_IOLOCK_EXCL); 1310 + } 1311 + 1312 + return 0; 1247 1313 } 1248 1314 1249 1315 STATIC int
+266 -137
fs/xfs/xfs_fsmap.c
··· 44 44 } 45 45 46 46 /* Convert an fsmap to an xfs_fsmap. */ 47 - void 47 + static void 48 48 xfs_fsmap_to_internal( 49 49 struct xfs_fsmap *dest, 50 50 struct fsmap *src) ··· 441 441 irec->rm_flags |= XFS_RMAP_UNWRITTEN; 442 442 } 443 443 444 - /* Execute a getfsmap query against the log device. */ 445 - STATIC int 446 - xfs_getfsmap_logdev( 447 - struct xfs_trans *tp, 448 - const struct xfs_fsmap *keys, 449 - struct xfs_getfsmap_info *info) 450 - { 451 - struct xfs_mount *mp = tp->t_mountp; 452 - struct xfs_rmap_irec rmap; 453 - xfs_daddr_t rec_daddr, len_daddr; 454 - xfs_fsblock_t start_fsb, end_fsb; 455 - uint64_t eofs; 456 - 457 - eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); 458 - if (keys[0].fmr_physical >= eofs) 459 - return 0; 460 - start_fsb = XFS_BB_TO_FSBT(mp, 461 - keys[0].fmr_physical + keys[0].fmr_length); 462 - end_fsb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); 463 - 464 - /* Adjust the low key if we are continuing from where we left off. */ 465 - if (keys[0].fmr_length > 0) 466 - info->low_daddr = XFS_FSB_TO_BB(mp, start_fsb); 467 - 468 - trace_xfs_fsmap_low_key_linear(mp, info->dev, start_fsb); 469 - trace_xfs_fsmap_high_key_linear(mp, info->dev, end_fsb); 470 - 471 - if (start_fsb > 0) 472 - return 0; 473 - 474 - /* Fabricate an rmap entry for the external log device. */ 475 - rmap.rm_startblock = 0; 476 - rmap.rm_blockcount = mp->m_sb.sb_logblocks; 477 - rmap.rm_owner = XFS_RMAP_OWN_LOG; 478 - rmap.rm_offset = 0; 479 - rmap.rm_flags = 0; 480 - 481 - rec_daddr = XFS_FSB_TO_BB(mp, rmap.rm_startblock); 482 - len_daddr = XFS_FSB_TO_BB(mp, rmap.rm_blockcount); 483 - return xfs_getfsmap_helper(tp, info, &rmap, rec_daddr, len_daddr); 484 - } 485 - 486 - #ifdef CONFIG_XFS_RT 487 - /* Transform a rtbitmap "record" into a fsmap */ 488 - STATIC int 489 - xfs_getfsmap_rtdev_rtbitmap_helper( 490 - struct xfs_mount *mp, 491 - struct xfs_trans *tp, 492 - const struct xfs_rtalloc_rec *rec, 493 - void *priv) 494 - { 495 - struct xfs_getfsmap_info *info = priv; 496 - struct xfs_rmap_irec irec; 497 - xfs_rtblock_t rtbno; 498 - xfs_daddr_t rec_daddr, len_daddr; 499 - 500 - rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); 501 - rec_daddr = XFS_FSB_TO_BB(mp, rtbno); 502 - irec.rm_startblock = rtbno; 503 - 504 - rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount); 505 - len_daddr = XFS_FSB_TO_BB(mp, rtbno); 506 - irec.rm_blockcount = rtbno; 507 - 508 - irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ 509 - irec.rm_offset = 0; 510 - irec.rm_flags = 0; 511 - 512 - return xfs_getfsmap_helper(tp, info, &irec, rec_daddr, len_daddr); 513 - } 514 - 515 - /* Execute a getfsmap query against the realtime device rtbitmap. */ 516 - STATIC int 517 - xfs_getfsmap_rtdev_rtbitmap( 518 - struct xfs_trans *tp, 519 - const struct xfs_fsmap *keys, 520 - struct xfs_getfsmap_info *info) 521 - { 522 - 523 - struct xfs_rtalloc_rec alow = { 0 }; 524 - struct xfs_rtalloc_rec ahigh = { 0 }; 525 - struct xfs_mount *mp = tp->t_mountp; 526 - xfs_rtblock_t start_rtb; 527 - xfs_rtblock_t end_rtb; 528 - uint64_t eofs; 529 - int error; 530 - 531 - eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents)); 532 - if (keys[0].fmr_physical >= eofs) 533 - return 0; 534 - start_rtb = XFS_BB_TO_FSBT(mp, 535 - keys[0].fmr_physical + keys[0].fmr_length); 536 - end_rtb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); 537 - 538 - info->missing_owner = XFS_FMR_OWN_UNKNOWN; 539 - 540 - /* Adjust the low key if we are continuing from where we left off. */ 541 - if (keys[0].fmr_length > 0) { 542 - info->low_daddr = XFS_FSB_TO_BB(mp, start_rtb); 543 - if (info->low_daddr >= eofs) 544 - return 0; 545 - } 546 - 547 - trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtb); 548 - trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtb); 549 - 550 - xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); 551 - 552 - /* 553 - * Set up query parameters to return free rtextents covering the range 554 - * we want. 555 - */ 556 - alow.ar_startext = xfs_rtb_to_rtx(mp, start_rtb); 557 - ahigh.ar_startext = xfs_rtb_to_rtxup(mp, end_rtb); 558 - error = xfs_rtalloc_query_range(mp, tp, &alow, &ahigh, 559 - xfs_getfsmap_rtdev_rtbitmap_helper, info); 560 - if (error) 561 - goto err; 562 - 563 - /* 564 - * Report any gaps at the end of the rtbitmap by simulating a null 565 - * rmap starting at the block after the end of the query range. 566 - */ 567 - info->last = true; 568 - ahigh.ar_startext = min(mp->m_sb.sb_rextents, ahigh.ar_startext); 569 - 570 - error = xfs_getfsmap_rtdev_rtbitmap_helper(mp, tp, &ahigh, info); 571 - if (error) 572 - goto err; 573 - err: 574 - xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); 575 - return error; 576 - } 577 - #endif /* CONFIG_XFS_RT */ 578 - 579 444 static inline bool 580 445 rmap_not_shareable(struct xfs_mount *mp, const struct xfs_rmap_irec *r) 581 446 { ··· 665 800 xfs_getfsmap_datadev_bnobt_query, &akeys[0]); 666 801 } 667 802 803 + /* Execute a getfsmap query against the log device. */ 804 + STATIC int 805 + xfs_getfsmap_logdev( 806 + struct xfs_trans *tp, 807 + const struct xfs_fsmap *keys, 808 + struct xfs_getfsmap_info *info) 809 + { 810 + struct xfs_mount *mp = tp->t_mountp; 811 + struct xfs_rmap_irec rmap; 812 + xfs_daddr_t rec_daddr, len_daddr; 813 + xfs_fsblock_t start_fsb, end_fsb; 814 + uint64_t eofs; 815 + 816 + eofs = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); 817 + if (keys[0].fmr_physical >= eofs) 818 + return 0; 819 + start_fsb = XFS_BB_TO_FSBT(mp, 820 + keys[0].fmr_physical + keys[0].fmr_length); 821 + end_fsb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); 822 + 823 + /* Adjust the low key if we are continuing from where we left off. */ 824 + if (keys[0].fmr_length > 0) 825 + info->low_daddr = XFS_FSB_TO_BB(mp, start_fsb); 826 + 827 + trace_xfs_fsmap_low_key_linear(mp, info->dev, start_fsb); 828 + trace_xfs_fsmap_high_key_linear(mp, info->dev, end_fsb); 829 + 830 + if (start_fsb > 0) 831 + return 0; 832 + 833 + /* Fabricate an rmap entry for the external log device. */ 834 + rmap.rm_startblock = 0; 835 + rmap.rm_blockcount = mp->m_sb.sb_logblocks; 836 + rmap.rm_owner = XFS_RMAP_OWN_LOG; 837 + rmap.rm_offset = 0; 838 + rmap.rm_flags = 0; 839 + 840 + rec_daddr = XFS_FSB_TO_BB(mp, rmap.rm_startblock); 841 + len_daddr = XFS_FSB_TO_BB(mp, rmap.rm_blockcount); 842 + return xfs_getfsmap_helper(tp, info, &rmap, rec_daddr, len_daddr); 843 + } 844 + 845 + #ifdef CONFIG_XFS_RT 846 + /* Transform a rtbitmap "record" into a fsmap */ 847 + STATIC int 848 + xfs_getfsmap_rtdev_rtbitmap_helper( 849 + struct xfs_mount *mp, 850 + struct xfs_trans *tp, 851 + const struct xfs_rtalloc_rec *rec, 852 + void *priv) 853 + { 854 + struct xfs_getfsmap_info *info = priv; 855 + struct xfs_rmap_irec irec; 856 + xfs_rtblock_t rtbno; 857 + xfs_daddr_t rec_daddr, len_daddr; 858 + 859 + rtbno = xfs_rtx_to_rtb(mp, rec->ar_startext); 860 + rec_daddr = XFS_FSB_TO_BB(mp, rtbno); 861 + irec.rm_startblock = rtbno; 862 + 863 + rtbno = xfs_rtx_to_rtb(mp, rec->ar_extcount); 864 + len_daddr = XFS_FSB_TO_BB(mp, rtbno); 865 + irec.rm_blockcount = rtbno; 866 + 867 + irec.rm_owner = XFS_RMAP_OWN_NULL; /* "free" */ 868 + irec.rm_offset = 0; 869 + irec.rm_flags = 0; 870 + 871 + return xfs_getfsmap_helper(tp, info, &irec, rec_daddr, len_daddr); 872 + } 873 + 874 + /* Execute a getfsmap query against the realtime device rtbitmap. */ 875 + STATIC int 876 + xfs_getfsmap_rtdev_rtbitmap( 877 + struct xfs_trans *tp, 878 + const struct xfs_fsmap *keys, 879 + struct xfs_getfsmap_info *info) 880 + { 881 + 882 + struct xfs_rtalloc_rec ahigh = { 0 }; 883 + struct xfs_mount *mp = tp->t_mountp; 884 + xfs_rtblock_t start_rtb; 885 + xfs_rtblock_t end_rtb; 886 + xfs_rtxnum_t high; 887 + uint64_t eofs; 888 + int error; 889 + 890 + eofs = XFS_FSB_TO_BB(mp, xfs_rtx_to_rtb(mp, mp->m_sb.sb_rextents)); 891 + if (keys[0].fmr_physical >= eofs) 892 + return 0; 893 + start_rtb = XFS_BB_TO_FSBT(mp, 894 + keys[0].fmr_physical + keys[0].fmr_length); 895 + end_rtb = XFS_BB_TO_FSB(mp, min(eofs - 1, keys[1].fmr_physical)); 896 + 897 + info->missing_owner = XFS_FMR_OWN_UNKNOWN; 898 + 899 + /* Adjust the low key if we are continuing from where we left off. */ 900 + if (keys[0].fmr_length > 0) { 901 + info->low_daddr = XFS_FSB_TO_BB(mp, start_rtb); 902 + if (info->low_daddr >= eofs) 903 + return 0; 904 + } 905 + 906 + trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtb); 907 + trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtb); 908 + 909 + xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP); 910 + 911 + /* 912 + * Set up query parameters to return free rtextents covering the range 913 + * we want. 914 + */ 915 + high = xfs_rtb_to_rtxup(mp, end_rtb); 916 + error = xfs_rtalloc_query_range(mp, tp, xfs_rtb_to_rtx(mp, start_rtb), 917 + high, xfs_getfsmap_rtdev_rtbitmap_helper, info); 918 + if (error) 919 + goto err; 920 + 921 + /* 922 + * Report any gaps at the end of the rtbitmap by simulating a null 923 + * rmap starting at the block after the end of the query range. 924 + */ 925 + info->last = true; 926 + ahigh.ar_startext = min(mp->m_sb.sb_rextents, high); 927 + 928 + error = xfs_getfsmap_rtdev_rtbitmap_helper(mp, tp, &ahigh, info); 929 + if (error) 930 + goto err; 931 + err: 932 + xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP); 933 + return error; 934 + } 935 + #endif /* CONFIG_XFS_RT */ 936 + 668 937 /* Do we recognize the device? */ 669 938 STATIC bool 670 939 xfs_getfsmap_is_valid_device( ··· 889 890 * xfs_getfsmap_info.low/high -- per-AG low/high keys computed from 890 891 * dkeys; used to query the metadata. 891 892 */ 892 - int 893 + STATIC int 893 894 xfs_getfsmap( 894 895 struct xfs_mount *mp, 895 896 struct xfs_fsmap_head *head, ··· 1017 1018 if (tp) 1018 1019 xfs_trans_cancel(tp); 1019 1020 head->fmh_oflags = FMH_OF_DEV_T; 1021 + return error; 1022 + } 1023 + 1024 + int 1025 + xfs_ioc_getfsmap( 1026 + struct xfs_inode *ip, 1027 + struct fsmap_head __user *arg) 1028 + { 1029 + struct xfs_fsmap_head xhead = {0}; 1030 + struct fsmap_head head; 1031 + struct fsmap *recs; 1032 + unsigned int count; 1033 + __u32 last_flags = 0; 1034 + bool done = false; 1035 + int error; 1036 + 1037 + if (copy_from_user(&head, arg, sizeof(struct fsmap_head))) 1038 + return -EFAULT; 1039 + if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) || 1040 + memchr_inv(head.fmh_keys[0].fmr_reserved, 0, 1041 + sizeof(head.fmh_keys[0].fmr_reserved)) || 1042 + memchr_inv(head.fmh_keys[1].fmr_reserved, 0, 1043 + sizeof(head.fmh_keys[1].fmr_reserved))) 1044 + return -EINVAL; 1045 + 1046 + /* 1047 + * Use an internal memory buffer so that we don't have to copy fsmap 1048 + * data to userspace while holding locks. Start by trying to allocate 1049 + * up to 128k for the buffer, but fall back to a single page if needed. 1050 + */ 1051 + count = min_t(unsigned int, head.fmh_count, 1052 + 131072 / sizeof(struct fsmap)); 1053 + recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); 1054 + if (!recs) { 1055 + count = min_t(unsigned int, head.fmh_count, 1056 + PAGE_SIZE / sizeof(struct fsmap)); 1057 + recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); 1058 + if (!recs) 1059 + return -ENOMEM; 1060 + } 1061 + 1062 + xhead.fmh_iflags = head.fmh_iflags; 1063 + xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]); 1064 + xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]); 1065 + 1066 + trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); 1067 + trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]); 1068 + 1069 + head.fmh_entries = 0; 1070 + do { 1071 + struct fsmap __user *user_recs; 1072 + struct fsmap *last_rec; 1073 + 1074 + user_recs = &arg->fmh_recs[head.fmh_entries]; 1075 + xhead.fmh_entries = 0; 1076 + xhead.fmh_count = min_t(unsigned int, count, 1077 + head.fmh_count - head.fmh_entries); 1078 + 1079 + /* Run query, record how many entries we got. */ 1080 + error = xfs_getfsmap(ip->i_mount, &xhead, recs); 1081 + switch (error) { 1082 + case 0: 1083 + /* 1084 + * There are no more records in the result set. Copy 1085 + * whatever we got to userspace and break out. 1086 + */ 1087 + done = true; 1088 + break; 1089 + case -ECANCELED: 1090 + /* 1091 + * The internal memory buffer is full. Copy whatever 1092 + * records we got to userspace and go again if we have 1093 + * not yet filled the userspace buffer. 1094 + */ 1095 + error = 0; 1096 + break; 1097 + default: 1098 + goto out_free; 1099 + } 1100 + head.fmh_entries += xhead.fmh_entries; 1101 + head.fmh_oflags = xhead.fmh_oflags; 1102 + 1103 + /* 1104 + * If the caller wanted a record count or there aren't any 1105 + * new records to return, we're done. 1106 + */ 1107 + if (head.fmh_count == 0 || xhead.fmh_entries == 0) 1108 + break; 1109 + 1110 + /* Copy all the records we got out to userspace. */ 1111 + if (copy_to_user(user_recs, recs, 1112 + xhead.fmh_entries * sizeof(struct fsmap))) { 1113 + error = -EFAULT; 1114 + goto out_free; 1115 + } 1116 + 1117 + /* Remember the last record flags we copied to userspace. */ 1118 + last_rec = &recs[xhead.fmh_entries - 1]; 1119 + last_flags = last_rec->fmr_flags; 1120 + 1121 + /* Set up the low key for the next iteration. */ 1122 + xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec); 1123 + trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); 1124 + } while (!done && head.fmh_entries < head.fmh_count); 1125 + 1126 + /* 1127 + * If there are no more records in the query result set and we're not 1128 + * in counting mode, mark the last record returned with the LAST flag. 1129 + */ 1130 + if (done && head.fmh_count > 0 && head.fmh_entries > 0) { 1131 + struct fsmap __user *user_rec; 1132 + 1133 + last_flags |= FMR_OF_LAST; 1134 + user_rec = &arg->fmh_recs[head.fmh_entries - 1]; 1135 + 1136 + if (copy_to_user(&user_rec->fmr_flags, &last_flags, 1137 + sizeof(last_flags))) { 1138 + error = -EFAULT; 1139 + goto out_free; 1140 + } 1141 + } 1142 + 1143 + /* copy back header */ 1144 + if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) { 1145 + error = -EFAULT; 1146 + goto out_free; 1147 + } 1148 + 1149 + out_free: 1150 + kvfree(recs); 1020 1151 return error; 1021 1152 }
+2 -4
fs/xfs/xfs_fsmap.h
··· 7 7 #define __XFS_FSMAP_H__ 8 8 9 9 struct fsmap; 10 + struct fsmap_head; 10 11 11 12 /* internal fsmap representation */ 12 13 struct xfs_fsmap { ··· 28 27 struct xfs_fsmap fmh_keys[2]; /* low and high keys */ 29 28 }; 30 29 31 - void xfs_fsmap_to_internal(struct xfs_fsmap *dest, struct fsmap *src); 32 - 33 - int xfs_getfsmap(struct xfs_mount *mp, struct xfs_fsmap_head *head, 34 - struct fsmap *out_recs); 30 + int xfs_ioc_getfsmap(struct xfs_inode *ip, struct fsmap_head __user *arg); 35 31 36 32 #endif /* __XFS_FSMAP_H__ */
+1 -1
fs/xfs/xfs_fsops.c
··· 485 485 const char *why; 486 486 487 487 488 - if (test_and_set_bit(XFS_OPSTATE_SHUTDOWN, &mp->m_opstate)) { 488 + if (xfs_set_shutdown(mp)) { 489 489 xlog_shutdown_wait(mp->m_log); 490 490 return; 491 491 }
+61 -28
fs/xfs/xfs_icache.c
··· 65 65 XFS_ICWALK_FLAG_RECLAIM_SICK | \ 66 66 XFS_ICWALK_FLAG_UNION) 67 67 68 + /* Marks for the perag xarray */ 69 + #define XFS_PERAG_RECLAIM_MARK XA_MARK_0 70 + #define XFS_PERAG_BLOCKGC_MARK XA_MARK_1 71 + 72 + static inline xa_mark_t ici_tag_to_mark(unsigned int tag) 73 + { 74 + if (tag == XFS_ICI_RECLAIM_TAG) 75 + return XFS_PERAG_RECLAIM_MARK; 76 + ASSERT(tag == XFS_ICI_BLOCKGC_TAG); 77 + return XFS_PERAG_BLOCKGC_MARK; 78 + } 79 + 68 80 /* 69 81 * Allocate and initialise an xfs_inode. 70 82 */ ··· 203 191 { 204 192 205 193 rcu_read_lock(); 206 - if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_RECLAIM_TAG)) { 194 + if (xa_marked(&mp->m_perags, XFS_PERAG_RECLAIM_MARK)) { 207 195 queue_delayed_work(mp->m_reclaim_workqueue, &mp->m_reclaim_work, 208 196 msecs_to_jiffies(xfs_syncd_centisecs / 6 * 10)); 209 197 } ··· 253 241 return; 254 242 255 243 /* propagate the tag up into the perag radix tree */ 256 - spin_lock(&mp->m_perag_lock); 257 - radix_tree_tag_set(&mp->m_perag_tree, pag->pag_agno, tag); 258 - spin_unlock(&mp->m_perag_lock); 244 + xa_set_mark(&mp->m_perags, pag->pag_agno, ici_tag_to_mark(tag)); 259 245 260 246 /* start background work */ 261 247 switch (tag) { ··· 295 285 return; 296 286 297 287 /* clear the tag from the perag radix tree */ 298 - spin_lock(&mp->m_perag_lock); 299 - radix_tree_tag_clear(&mp->m_perag_tree, pag->pag_agno, tag); 300 - spin_unlock(&mp->m_perag_lock); 288 + xa_clear_mark(&mp->m_perags, pag->pag_agno, ici_tag_to_mark(tag)); 301 289 302 290 trace_xfs_perag_clear_inode_tag(pag, _RET_IP_); 291 + } 292 + 293 + /* 294 + * Find the next AG after @pag, or the first AG if @pag is NULL. 295 + */ 296 + static struct xfs_perag * 297 + xfs_perag_grab_next_tag( 298 + struct xfs_mount *mp, 299 + struct xfs_perag *pag, 300 + int tag) 301 + { 302 + unsigned long index = 0; 303 + 304 + if (pag) { 305 + index = pag->pag_agno + 1; 306 + xfs_perag_rele(pag); 307 + } 308 + 309 + rcu_read_lock(); 310 + pag = xa_find(&mp->m_perags, &index, ULONG_MAX, ici_tag_to_mark(tag)); 311 + if (pag) { 312 + trace_xfs_perag_grab_next_tag(pag, _RET_IP_); 313 + if (!atomic_inc_not_zero(&pag->pag_active_ref)) 314 + pag = NULL; 315 + } 316 + rcu_read_unlock(); 317 + return pag; 303 318 } 304 319 305 320 /* ··· 790 755 ASSERT((lock_flags & (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED)) == 0); 791 756 792 757 /* reject inode numbers outside existing AGs */ 793 - if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount) 758 + if (!xfs_verify_ino(mp, ino)) 794 759 return -EINVAL; 795 760 796 761 XFS_STATS_INC(mp, xs_ig_attempts); ··· 1012 977 if (xfs_want_reclaim_sick(mp)) 1013 978 icw.icw_flags |= XFS_ICWALK_FLAG_RECLAIM_SICK; 1014 979 1015 - while (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_RECLAIM_TAG)) { 980 + while (xa_marked(&mp->m_perags, XFS_PERAG_RECLAIM_MARK)) { 1016 981 xfs_ail_push_all_sync(mp->m_ail); 1017 982 xfs_icwalk(mp, XFS_ICWALK_RECLAIM, &icw); 1018 983 } ··· 1054 1019 xfs_reclaim_inodes_count( 1055 1020 struct xfs_mount *mp) 1056 1021 { 1057 - struct xfs_perag *pag; 1058 - xfs_agnumber_t ag = 0; 1022 + XA_STATE (xas, &mp->m_perags, 0); 1059 1023 long reclaimable = 0; 1024 + struct xfs_perag *pag; 1060 1025 1061 - while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { 1062 - ag = pag->pag_agno + 1; 1026 + rcu_read_lock(); 1027 + xas_for_each_marked(&xas, pag, ULONG_MAX, XFS_PERAG_RECLAIM_MARK) { 1028 + trace_xfs_reclaim_inodes_count(pag, _THIS_IP_); 1063 1029 reclaimable += pag->pag_ici_reclaimable; 1064 - xfs_perag_put(pag); 1065 1030 } 1031 + rcu_read_unlock(); 1032 + 1066 1033 return reclaimable; 1067 1034 } 1068 1035 ··· 1196 1159 if (xfs_can_free_eofblocks(ip)) 1197 1160 return xfs_free_eofblocks(ip); 1198 1161 1199 - /* inode could be preallocated or append-only */ 1162 + /* inode could be preallocated */ 1200 1163 trace_xfs_inode_free_eofblocks_invalid(ip); 1201 1164 xfs_inode_clear_eofblocks_tag(ip); 1202 1165 return 0; ··· 1406 1369 xfs_blockgc_start( 1407 1370 struct xfs_mount *mp) 1408 1371 { 1409 - struct xfs_perag *pag; 1410 - xfs_agnumber_t agno; 1372 + struct xfs_perag *pag = NULL; 1411 1373 1412 1374 if (xfs_set_blockgc_enabled(mp)) 1413 1375 return; 1414 1376 1415 1377 trace_xfs_blockgc_start(mp, __return_address); 1416 - for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG) 1378 + while ((pag = xfs_perag_grab_next_tag(mp, pag, XFS_ICI_BLOCKGC_TAG))) 1417 1379 xfs_blockgc_queue(pag); 1418 1380 } 1419 1381 ··· 1528 1492 xfs_blockgc_flush_all( 1529 1493 struct xfs_mount *mp) 1530 1494 { 1531 - struct xfs_perag *pag; 1532 - xfs_agnumber_t agno; 1495 + struct xfs_perag *pag = NULL; 1533 1496 1534 1497 trace_xfs_blockgc_flush_all(mp, __return_address); 1535 1498 1536 1499 /* 1537 - * For each blockgc worker, move its queue time up to now. If it 1538 - * wasn't queued, it will not be requeued. Then flush whatever's 1539 - * left. 1500 + * For each blockgc worker, move its queue time up to now. If it wasn't 1501 + * queued, it will not be requeued. Then flush whatever is left. 1540 1502 */ 1541 - for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG) 1503 + while ((pag = xfs_perag_grab_next_tag(mp, pag, XFS_ICI_BLOCKGC_TAG))) 1542 1504 mod_delayed_work(pag->pag_mount->m_blockgc_wq, 1543 1505 &pag->pag_blockgc_work, 0); 1544 1506 1545 - for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG) 1507 + while ((pag = xfs_perag_grab_next_tag(mp, pag, XFS_ICI_BLOCKGC_TAG))) 1546 1508 flush_delayed_work(&pag->pag_blockgc_work); 1547 1509 1548 1510 return xfs_inodegc_flush(mp); ··· 1786 1752 enum xfs_icwalk_goal goal, 1787 1753 struct xfs_icwalk *icw) 1788 1754 { 1789 - struct xfs_perag *pag; 1755 + struct xfs_perag *pag = NULL; 1790 1756 int error = 0; 1791 1757 int last_error = 0; 1792 - xfs_agnumber_t agno; 1793 1758 1794 - for_each_perag_tag(mp, agno, pag, goal) { 1759 + while ((pag = xfs_perag_grab_next_tag(mp, pag, goal))) { 1795 1760 error = xfs_icwalk_ag(pag, goal, icw); 1796 1761 if (error) { 1797 1762 last_error = error;
+2 -84
fs/xfs/xfs_inode.c
··· 704 704 * entry pointing to them, but a directory also the "." entry 705 705 * pointing to itself. 706 706 */ 707 - error = xfs_dialloc(&tp, dp->i_ino, args->mode, &ino); 707 + error = xfs_dialloc(&tp, args, &ino); 708 708 if (!error) 709 709 error = xfs_icreate(tp, ino, args, &du.ip); 710 710 if (error) ··· 812 812 if (error) 813 813 goto out_release_dquots; 814 814 815 - error = xfs_dialloc(&tp, dp->i_ino, args->mode, &ino); 815 + error = xfs_dialloc(&tp, args, &ino); 816 816 if (!error) 817 817 error = xfs_icreate(tp, ino, args, &ip); 818 818 if (error) ··· 1076 1076 1077 1077 out: 1078 1078 *tpp = tp; 1079 - return error; 1080 - } 1081 - 1082 - int 1083 - xfs_release( 1084 - xfs_inode_t *ip) 1085 - { 1086 - xfs_mount_t *mp = ip->i_mount; 1087 - int error = 0; 1088 - 1089 - if (!S_ISREG(VFS_I(ip)->i_mode) || (VFS_I(ip)->i_mode == 0)) 1090 - return 0; 1091 - 1092 - /* If this is a read-only mount, don't do this (would generate I/O) */ 1093 - if (xfs_is_readonly(mp)) 1094 - return 0; 1095 - 1096 - if (!xfs_is_shutdown(mp)) { 1097 - int truncated; 1098 - 1099 - /* 1100 - * If we previously truncated this file and removed old data 1101 - * in the process, we want to initiate "early" writeout on 1102 - * the last close. This is an attempt to combat the notorious 1103 - * NULL files problem which is particularly noticeable from a 1104 - * truncate down, buffered (re-)write (delalloc), followed by 1105 - * a crash. What we are effectively doing here is 1106 - * significantly reducing the time window where we'd otherwise 1107 - * be exposed to that problem. 1108 - */ 1109 - truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); 1110 - if (truncated) { 1111 - xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE); 1112 - if (ip->i_delayed_blks > 0) { 1113 - error = filemap_flush(VFS_I(ip)->i_mapping); 1114 - if (error) 1115 - return error; 1116 - } 1117 - } 1118 - } 1119 - 1120 - if (VFS_I(ip)->i_nlink == 0) 1121 - return 0; 1122 - 1123 - /* 1124 - * If we can't get the iolock just skip truncating the blocks past EOF 1125 - * because we could deadlock with the mmap_lock otherwise. We'll get 1126 - * another chance to drop them once the last reference to the inode is 1127 - * dropped, so we'll never leak blocks permanently. 1128 - */ 1129 - if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) 1130 - return 0; 1131 - 1132 - if (xfs_can_free_eofblocks(ip)) { 1133 - /* 1134 - * Check if the inode is being opened, written and closed 1135 - * frequently and we have delayed allocation blocks outstanding 1136 - * (e.g. streaming writes from the NFS server), truncating the 1137 - * blocks past EOF will cause fragmentation to occur. 1138 - * 1139 - * In this case don't do the truncation, but we have to be 1140 - * careful how we detect this case. Blocks beyond EOF show up as 1141 - * i_delayed_blks even when the inode is clean, so we need to 1142 - * truncate them away first before checking for a dirty release. 1143 - * Hence on the first dirty close we will still remove the 1144 - * speculative allocation, but after that we will leave it in 1145 - * place. 1146 - */ 1147 - if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) 1148 - goto out_unlock; 1149 - 1150 - error = xfs_free_eofblocks(ip); 1151 - if (error) 1152 - goto out_unlock; 1153 - 1154 - /* delalloc blocks after truncation means it really is dirty */ 1155 - if (ip->i_delayed_blks) 1156 - xfs_iflags_set(ip, XFS_IDIRTY_RELEASE); 1157 - } 1158 - 1159 - out_unlock: 1160 - xfs_iunlock(ip, XFS_IOLOCK_EXCL); 1161 1079 return error; 1162 1080 } 1163 1081
+6 -6
fs/xfs/xfs_inode.h
··· 276 276 return ip->i_diflags2 & XFS_DIFLAG2_REFLINK; 277 277 } 278 278 279 - static inline bool xfs_is_metadata_inode(struct xfs_inode *ip) 279 + static inline bool xfs_is_metadata_inode(const struct xfs_inode *ip) 280 280 { 281 281 struct xfs_mount *mp = ip->i_mount; 282 282 283 - return ip == mp->m_rbmip || ip == mp->m_rsumip || 284 - xfs_is_quota_inode(&mp->m_sb, ip->i_ino); 283 + return ip->i_ino == mp->m_sb.sb_rbmino || 284 + ip->i_ino == mp->m_sb.sb_rsumino || 285 + xfs_is_quota_inode(&mp->m_sb, ip->i_ino); 285 286 } 286 287 287 288 bool xfs_is_always_cow_inode(struct xfs_inode *ip); ··· 336 335 #define XFS_INEW (1 << 3) /* inode has just been allocated */ 337 336 #define XFS_IPRESERVE_DM_FIELDS (1 << 4) /* has legacy DMAPI fields set */ 338 337 #define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */ 339 - #define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ 338 + #define XFS_EOFBLOCKS_RELEASED (1 << 6) /* eofblocks were freed in ->release */ 340 339 #define XFS_IFLUSHING (1 << 7) /* inode is being flushed */ 341 340 #define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */ 342 341 #define XFS_IPINNED (1 << __XFS_IPINNED_BIT) ··· 383 382 */ 384 383 #define XFS_IRECLAIM_RESET_FLAGS \ 385 384 (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ 386 - XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | XFS_NEED_INACTIVE | \ 385 + XFS_EOFBLOCKS_RELEASED | XFS_ITRUNCATED | XFS_NEED_INACTIVE | \ 387 386 XFS_INACTIVATING | XFS_IQUOTAUNCHECKED) 388 387 389 388 /* ··· 513 512 #define XFS_INHERIT_GID(pip) \ 514 513 (xfs_has_grpid((pip)->i_mount) || (VFS_I(pip)->i_mode & S_ISGID)) 515 514 516 - int xfs_release(struct xfs_inode *ip); 517 515 int xfs_inactive(struct xfs_inode *ip); 518 516 int xfs_lookup(struct xfs_inode *dp, const struct xfs_name *name, 519 517 struct xfs_inode **ipp, struct xfs_name *ci_name);
+4 -130
fs/xfs/xfs_ioctl.c
··· 876 876 return error; 877 877 } 878 878 879 - STATIC int 880 - xfs_ioc_getfsmap( 881 - struct xfs_inode *ip, 882 - struct fsmap_head __user *arg) 883 - { 884 - struct xfs_fsmap_head xhead = {0}; 885 - struct fsmap_head head; 886 - struct fsmap *recs; 887 - unsigned int count; 888 - __u32 last_flags = 0; 889 - bool done = false; 890 - int error; 891 - 892 - if (copy_from_user(&head, arg, sizeof(struct fsmap_head))) 893 - return -EFAULT; 894 - if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) || 895 - memchr_inv(head.fmh_keys[0].fmr_reserved, 0, 896 - sizeof(head.fmh_keys[0].fmr_reserved)) || 897 - memchr_inv(head.fmh_keys[1].fmr_reserved, 0, 898 - sizeof(head.fmh_keys[1].fmr_reserved))) 899 - return -EINVAL; 900 - 901 - /* 902 - * Use an internal memory buffer so that we don't have to copy fsmap 903 - * data to userspace while holding locks. Start by trying to allocate 904 - * up to 128k for the buffer, but fall back to a single page if needed. 905 - */ 906 - count = min_t(unsigned int, head.fmh_count, 907 - 131072 / sizeof(struct fsmap)); 908 - recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); 909 - if (!recs) { 910 - count = min_t(unsigned int, head.fmh_count, 911 - PAGE_SIZE / sizeof(struct fsmap)); 912 - recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); 913 - if (!recs) 914 - return -ENOMEM; 915 - } 916 - 917 - xhead.fmh_iflags = head.fmh_iflags; 918 - xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]); 919 - xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]); 920 - 921 - trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); 922 - trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]); 923 - 924 - head.fmh_entries = 0; 925 - do { 926 - struct fsmap __user *user_recs; 927 - struct fsmap *last_rec; 928 - 929 - user_recs = &arg->fmh_recs[head.fmh_entries]; 930 - xhead.fmh_entries = 0; 931 - xhead.fmh_count = min_t(unsigned int, count, 932 - head.fmh_count - head.fmh_entries); 933 - 934 - /* Run query, record how many entries we got. */ 935 - error = xfs_getfsmap(ip->i_mount, &xhead, recs); 936 - switch (error) { 937 - case 0: 938 - /* 939 - * There are no more records in the result set. Copy 940 - * whatever we got to userspace and break out. 941 - */ 942 - done = true; 943 - break; 944 - case -ECANCELED: 945 - /* 946 - * The internal memory buffer is full. Copy whatever 947 - * records we got to userspace and go again if we have 948 - * not yet filled the userspace buffer. 949 - */ 950 - error = 0; 951 - break; 952 - default: 953 - goto out_free; 954 - } 955 - head.fmh_entries += xhead.fmh_entries; 956 - head.fmh_oflags = xhead.fmh_oflags; 957 - 958 - /* 959 - * If the caller wanted a record count or there aren't any 960 - * new records to return, we're done. 961 - */ 962 - if (head.fmh_count == 0 || xhead.fmh_entries == 0) 963 - break; 964 - 965 - /* Copy all the records we got out to userspace. */ 966 - if (copy_to_user(user_recs, recs, 967 - xhead.fmh_entries * sizeof(struct fsmap))) { 968 - error = -EFAULT; 969 - goto out_free; 970 - } 971 - 972 - /* Remember the last record flags we copied to userspace. */ 973 - last_rec = &recs[xhead.fmh_entries - 1]; 974 - last_flags = last_rec->fmr_flags; 975 - 976 - /* Set up the low key for the next iteration. */ 977 - xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec); 978 - trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]); 979 - } while (!done && head.fmh_entries < head.fmh_count); 980 - 981 - /* 982 - * If there are no more records in the query result set and we're not 983 - * in counting mode, mark the last record returned with the LAST flag. 984 - */ 985 - if (done && head.fmh_count > 0 && head.fmh_entries > 0) { 986 - struct fsmap __user *user_rec; 987 - 988 - last_flags |= FMR_OF_LAST; 989 - user_rec = &arg->fmh_recs[head.fmh_entries - 1]; 990 - 991 - if (copy_to_user(&user_rec->fmr_flags, &last_flags, 992 - sizeof(last_flags))) { 993 - error = -EFAULT; 994 - goto out_free; 995 - } 996 - } 997 - 998 - /* copy back header */ 999 - if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) { 1000 - error = -EFAULT; 1001 - goto out_free; 1002 - } 1003 - 1004 - out_free: 1005 - kvfree(recs); 1006 - return error; 1007 - } 1008 - 1009 879 int 1010 880 xfs_ioc_swapext( 1011 881 xfs_swapext_t *sxp) ··· 1388 1518 1389 1519 case XFS_IOC_EXCHANGE_RANGE: 1390 1520 return xfs_ioc_exchange_range(filp, arg); 1521 + case XFS_IOC_START_COMMIT: 1522 + return xfs_ioc_start_commit(filp, arg); 1523 + case XFS_IOC_COMMIT_RANGE: 1524 + return xfs_ioc_commit_range(filp, arg); 1391 1525 1392 1526 default: 1393 1527 return -ENOTTY;
+1 -1
fs/xfs/xfs_log.c
··· 3495 3495 * If this log shutdown also sets the mount shutdown state, issue a 3496 3496 * shutdown warning message. 3497 3497 */ 3498 - if (!test_and_set_bit(XFS_OPSTATE_SHUTDOWN, &log->l_mp->m_opstate)) { 3498 + if (!xfs_set_shutdown(log->l_mp)) { 3499 3499 xfs_alert_tag(log->l_mp, XFS_PTAG_SHUTDOWN_LOGERROR, 3500 3500 "Filesystem has been shut down due to log error (0x%x).", 3501 3501 shutdown_flags);
+1 -1
fs/xfs/xfs_log_recover.c
··· 1336 1336 * headers if we have a filesystem using non-persistent counters. 1337 1337 */ 1338 1338 if (clean) 1339 - set_bit(XFS_OPSTATE_CLEAN, &log->l_mp->m_opstate); 1339 + xfs_set_clean(log->l_mp); 1340 1340 1341 1341 /* 1342 1342 * Make sure that there are no blocks in front of the head
+1 -1
fs/xfs/xfs_mount.c
··· 595 595 xfs_extent_busy_wait_all(mp); 596 596 flush_workqueue(xfs_discard_wq); 597 597 598 - set_bit(XFS_OPSTATE_UNMOUNTING, &mp->m_opstate); 598 + xfs_set_unmounting(mp); 599 599 600 600 xfs_ail_push_all_sync(mp->m_ail); 601 601 xfs_inodegc_stop(mp);
+2 -3
fs/xfs/xfs_mount.h
··· 147 147 int m_logbufs; /* number of log buffers */ 148 148 int m_logbsize; /* size of each log buffer */ 149 149 uint m_rsumlevels; /* rt summary levels */ 150 - uint m_rsumsize; /* size of rt summary, bytes */ 150 + xfs_filblks_t m_rsumblocks; /* size of rt summary, FSBs */ 151 151 int m_fixedfsid[2]; /* unchanged for life of FS */ 152 152 uint m_qflags; /* quota status flags */ 153 153 uint64_t m_features; /* active filesystem features */ ··· 208 208 */ 209 209 atomic64_t m_allocbt_blks; 210 210 211 - struct radix_tree_root m_perag_tree; /* per-ag accounting info */ 212 - spinlock_t m_perag_lock; /* lock for m_perag_tree */ 211 + struct xarray m_perags; /* per-ag accounting info */ 213 212 uint64_t m_resblks; /* total reserved blocks */ 214 213 uint64_t m_resblks_avail;/* available reserved blocks */ 215 214 uint64_t m_resblks_save; /* reserved blks @ remount,ro */
+1 -2
fs/xfs/xfs_mru_cache.c
··· 230 230 __releases(mru->lock) __acquires(mru->lock) 231 231 { 232 232 struct xfs_mru_cache_elem *elem, *next; 233 - struct list_head tmp; 233 + LIST_HEAD(tmp); 234 234 235 - INIT_LIST_HEAD(&tmp); 236 235 list_for_each_entry_safe(elem, next, &mru->reap_list, list_node) { 237 236 238 237 /* Remove the element from the data store. */
+41 -7
fs/xfs/xfs_qm.c
··· 799 799 }; 800 800 xfs_ino_t ino; 801 801 802 - error = xfs_dialloc(&tp, 0, S_IFREG, &ino); 802 + error = xfs_dialloc(&tp, &args, &ino); 803 803 if (!error) 804 804 error = xfs_icreate(tp, ino, &args, ipp); 805 805 if (error) { ··· 1539 1539 } 1540 1540 1541 1541 /* 1542 + * Load the inode for a given type of quota, assuming that the sb fields have 1543 + * been sorted out. This is not true when switching quota types on a V4 1544 + * filesystem, so do not use this function for that. 1545 + * 1546 + * Returns -ENOENT if the quota inode field is NULLFSINO; 0 and an inode on 1547 + * success; or a negative errno. 1548 + */ 1549 + int 1550 + xfs_qm_qino_load( 1551 + struct xfs_mount *mp, 1552 + xfs_dqtype_t type, 1553 + struct xfs_inode **ipp) 1554 + { 1555 + xfs_ino_t ino = NULLFSINO; 1556 + 1557 + switch (type) { 1558 + case XFS_DQTYPE_USER: 1559 + ino = mp->m_sb.sb_uquotino; 1560 + break; 1561 + case XFS_DQTYPE_GROUP: 1562 + ino = mp->m_sb.sb_gquotino; 1563 + break; 1564 + case XFS_DQTYPE_PROJ: 1565 + ino = mp->m_sb.sb_pquotino; 1566 + break; 1567 + default: 1568 + ASSERT(0); 1569 + return -EFSCORRUPTED; 1570 + } 1571 + 1572 + if (ino == NULLFSINO) 1573 + return -ENOENT; 1574 + 1575 + return xfs_iget(mp, NULL, ino, 0, 0, ipp); 1576 + } 1577 + 1578 + /* 1542 1579 * This is called after the superblock has been read in and we're ready to 1543 1580 * iget the quota inodes. 1544 1581 */ ··· 1598 1561 if (XFS_IS_UQUOTA_ON(mp) && 1599 1562 mp->m_sb.sb_uquotino != NULLFSINO) { 1600 1563 ASSERT(mp->m_sb.sb_uquotino > 0); 1601 - error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 1602 - 0, 0, &uip); 1564 + error = xfs_qm_qino_load(mp, XFS_DQTYPE_USER, &uip); 1603 1565 if (error) 1604 1566 return error; 1605 1567 } 1606 1568 if (XFS_IS_GQUOTA_ON(mp) && 1607 1569 mp->m_sb.sb_gquotino != NULLFSINO) { 1608 1570 ASSERT(mp->m_sb.sb_gquotino > 0); 1609 - error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 1610 - 0, 0, &gip); 1571 + error = xfs_qm_qino_load(mp, XFS_DQTYPE_GROUP, &gip); 1611 1572 if (error) 1612 1573 goto error_rele; 1613 1574 } 1614 1575 if (XFS_IS_PQUOTA_ON(mp) && 1615 1576 mp->m_sb.sb_pquotino != NULLFSINO) { 1616 1577 ASSERT(mp->m_sb.sb_pquotino > 0); 1617 - error = xfs_iget(mp, NULL, mp->m_sb.sb_pquotino, 1618 - 0, 0, &pip); 1578 + error = xfs_qm_qino_load(mp, XFS_DQTYPE_PROJ, &pip); 1619 1579 if (error) 1620 1580 goto error_rele; 1621 1581 }
+3
fs/xfs/xfs_qm.h
··· 184 184 } 185 185 } 186 186 187 + int xfs_qm_qino_load(struct xfs_mount *mp, xfs_dqtype_t type, 188 + struct xfs_inode **ipp); 189 + 187 190 #endif /* __XFS_QM_H__ */
+6 -7
fs/xfs/xfs_qm_syscalls.c
··· 53 53 STATIC int 54 54 xfs_qm_scall_trunc_qfile( 55 55 struct xfs_mount *mp, 56 - xfs_ino_t ino) 56 + xfs_dqtype_t type) 57 57 { 58 58 struct xfs_inode *ip; 59 59 struct xfs_trans *tp; 60 60 int error; 61 61 62 - if (ino == NULLFSINO) 62 + error = xfs_qm_qino_load(mp, type, &ip); 63 + if (error == -ENOENT) 63 64 return 0; 64 - 65 - error = xfs_iget(mp, NULL, ino, 0, 0, &ip); 66 65 if (error) 67 66 return error; 68 67 ··· 112 113 } 113 114 114 115 if (flags & XFS_QMOPT_UQUOTA) { 115 - error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino); 116 + error = xfs_qm_scall_trunc_qfile(mp, XFS_DQTYPE_USER); 116 117 if (error) 117 118 return error; 118 119 } 119 120 if (flags & XFS_QMOPT_GQUOTA) { 120 - error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino); 121 + error = xfs_qm_scall_trunc_qfile(mp, XFS_DQTYPE_GROUP); 121 122 if (error) 122 123 return error; 123 124 } 124 125 if (flags & XFS_QMOPT_PQUOTA) 125 - error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino); 126 + error = xfs_qm_scall_trunc_qfile(mp, XFS_DQTYPE_PROJ); 126 127 127 128 return error; 128 129 }
+31 -22
fs/xfs/xfs_quotaops.c
··· 16 16 #include "xfs_qm.h" 17 17 18 18 19 - static void 19 + static int 20 20 xfs_qm_fill_state( 21 21 struct qc_type_state *tstate, 22 22 struct xfs_mount *mp, 23 - struct xfs_inode *ip, 24 - xfs_ino_t ino, 25 - struct xfs_def_quota *defq) 23 + xfs_dqtype_t type) 26 24 { 27 - bool tempqip = false; 25 + struct xfs_inode *ip; 26 + struct xfs_def_quota *defq; 27 + int error; 28 28 29 - tstate->ino = ino; 30 - if (!ip && ino == NULLFSINO) 31 - return; 32 - if (!ip) { 33 - if (xfs_iget(mp, NULL, ino, 0, 0, &ip)) 34 - return; 35 - tempqip = true; 29 + error = xfs_qm_qino_load(mp, type, &ip); 30 + if (error) { 31 + tstate->ino = NULLFSINO; 32 + return error != -ENOENT ? error : 0; 36 33 } 34 + 35 + defq = xfs_get_defquota(mp->m_quotainfo, type); 36 + 37 + tstate->ino = ip->i_ino; 37 38 tstate->flags |= QCI_SYSFILE; 38 39 tstate->blocks = ip->i_nblocks; 39 40 tstate->nextents = ip->i_df.if_nextents; ··· 44 43 tstate->spc_warnlimit = 0; 45 44 tstate->ino_warnlimit = 0; 46 45 tstate->rt_spc_warnlimit = 0; 47 - if (tempqip) 48 - xfs_irele(ip); 46 + xfs_irele(ip); 47 + 48 + return 0; 49 49 } 50 50 51 51 /* ··· 58 56 struct super_block *sb, 59 57 struct qc_state *state) 60 58 { 61 - struct xfs_mount *mp = XFS_M(sb); 62 - struct xfs_quotainfo *q = mp->m_quotainfo; 59 + struct xfs_mount *mp = XFS_M(sb); 60 + struct xfs_quotainfo *q = mp->m_quotainfo; 61 + int error; 63 62 64 63 memset(state, 0, sizeof(*state)); 65 64 if (!XFS_IS_QUOTA_ON(mp)) ··· 79 76 if (XFS_IS_PQUOTA_ENFORCED(mp)) 80 77 state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED; 81 78 82 - xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip, 83 - mp->m_sb.sb_uquotino, &q->qi_usr_default); 84 - xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip, 85 - mp->m_sb.sb_gquotino, &q->qi_grp_default); 86 - xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip, 87 - mp->m_sb.sb_pquotino, &q->qi_prj_default); 79 + error = xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, 80 + XFS_DQTYPE_USER); 81 + if (error) 82 + return error; 83 + error = xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, 84 + XFS_DQTYPE_GROUP); 85 + if (error) 86 + return error; 87 + error = xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, 88 + XFS_DQTYPE_PROJ); 89 + if (error) 90 + return error; 88 91 return 0; 89 92 } 90 93
+409 -459
fs/xfs/xfs_rtalloc.c
··· 142 142 * We need to find the beginning and end of the extent so we can 143 143 * properly update the summary. 144 144 */ 145 - error = xfs_rtfind_back(args, start, 0, &preblock); 145 + error = xfs_rtfind_back(args, start, &preblock); 146 146 if (error) 147 147 return error; 148 148 ··· 194 194 return xfs_rtmodify_range(args, start, len, 0); 195 195 } 196 196 197 + /* Reduce @rtxlen until it is a multiple of @prod. */ 198 + static inline xfs_rtxlen_t 199 + xfs_rtalloc_align_len( 200 + xfs_rtxlen_t rtxlen, 201 + xfs_rtxlen_t prod) 202 + { 203 + if (unlikely(prod > 1)) 204 + return rounddown(rtxlen, prod); 205 + return rtxlen; 206 + } 207 + 197 208 /* 198 209 * Make sure we don't run off the end of the rt volume. Be careful that 199 210 * adjusting maxlen downwards doesn't cause us to fail the alignment checks. ··· 219 208 xfs_rtxlen_t ret; 220 209 221 210 ret = min(mp->m_sb.sb_rextents, startrtx + rtxlen) - startrtx; 222 - return rounddown(ret, prod); 211 + return xfs_rtalloc_align_len(ret, prod); 223 212 } 224 213 225 214 /* ··· 240 229 xfs_rtxnum_t *rtx) /* out: start rtext allocated */ 241 230 { 242 231 struct xfs_mount *mp = args->mp; 243 - xfs_rtxnum_t besti; /* best rtext found so far */ 244 - xfs_rtxnum_t bestlen;/* best length found so far */ 232 + xfs_rtxnum_t besti = -1; /* best rtext found so far */ 245 233 xfs_rtxnum_t end; /* last rtext in chunk */ 246 - int error; 247 234 xfs_rtxnum_t i; /* current rtext trying */ 248 235 xfs_rtxnum_t next; /* next rtext to try */ 236 + xfs_rtxlen_t scanlen; /* number of free rtx to look for */ 237 + xfs_rtxlen_t bestlen = 0; /* best length found so far */ 249 238 int stat; /* status from internal calls */ 239 + int error; 250 240 251 241 /* 252 - * Loop over all the extents starting in this bitmap block, 253 - * looking for one that's long enough. 242 + * Loop over all the extents starting in this bitmap block up to the 243 + * end of the rt volume, looking for one that's long enough. 254 244 */ 255 - for (i = xfs_rbmblock_to_rtx(mp, bbno), besti = -1, bestlen = 0, 256 - end = xfs_rbmblock_to_rtx(mp, bbno + 1) - 1; 257 - i <= end; 258 - i++) { 245 + end = min(mp->m_sb.sb_rextents, xfs_rbmblock_to_rtx(mp, bbno + 1)) - 1; 246 + for (i = xfs_rbmblock_to_rtx(mp, bbno); i <= end; i++) { 259 247 /* Make sure we don't scan off the end of the rt volume. */ 260 - maxlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod); 248 + scanlen = xfs_rtallocate_clamp_len(mp, i, maxlen, prod); 249 + if (scanlen < minlen) 250 + break; 261 251 262 252 /* 263 - * See if there's a free extent of maxlen starting at i. 253 + * See if there's a free extent of scanlen starting at i. 264 254 * If it's not so then next will contain the first non-free. 265 255 */ 266 - error = xfs_rtcheck_range(args, i, maxlen, 1, &next, &stat); 256 + error = xfs_rtcheck_range(args, i, scanlen, 1, &next, &stat); 267 257 if (error) 268 258 return error; 269 259 if (stat) { 270 260 /* 271 - * i for maxlen is all free, allocate and return that. 261 + * i to scanlen is all free, allocate and return that. 272 262 */ 273 - bestlen = maxlen; 274 - besti = i; 275 - goto allocate; 263 + *len = scanlen; 264 + *rtx = i; 265 + return 0; 276 266 } 277 267 278 268 /* ··· 301 289 return error; 302 290 } 303 291 304 - /* 305 - * Searched the whole thing & didn't find a maxlen free extent. 306 - */ 307 - if (minlen > maxlen || besti == -1) { 308 - /* 309 - * Allocation failed. Set *nextp to the next block to try. 310 - */ 311 - *nextp = next; 312 - return -ENOSPC; 313 - } 292 + /* Searched the whole thing & didn't find a maxlen free extent. */ 293 + if (besti == -1) 294 + goto nospace; 314 295 315 296 /* 316 - * If size should be a multiple of prod, make that so. 297 + * Ensure bestlen is a multiple of prod, but don't return a too-short 298 + * extent. 317 299 */ 318 - if (prod > 1) { 319 - xfs_rtxlen_t p; /* amount to trim length by */ 320 - 321 - div_u64_rem(bestlen, prod, &p); 322 - if (p) 323 - bestlen -= p; 324 - } 300 + bestlen = xfs_rtalloc_align_len(bestlen, prod); 301 + if (bestlen < minlen) 302 + goto nospace; 325 303 326 304 /* 327 - * Allocate besti for bestlen & return that. 305 + * Pick besti for bestlen & return that. 328 306 */ 329 - allocate: 330 - error = xfs_rtallocate_range(args, besti, bestlen); 331 - if (error) 332 - return error; 333 307 *len = bestlen; 334 308 *rtx = besti; 335 309 return 0; 310 + nospace: 311 + /* Allocation failed. Set *nextp to the next block to try. */ 312 + *nextp = next; 313 + return -ENOSPC; 336 314 } 337 315 338 316 /* ··· 341 339 xfs_rtxlen_t prod, /* extent product factor */ 342 340 xfs_rtxnum_t *rtx) /* out: start rtext allocated */ 343 341 { 344 - int error; 345 - xfs_rtxlen_t i; /* extent length trimmed due to prod */ 346 - int isfree; /* extent is free */ 342 + struct xfs_mount *mp = args->mp; 347 343 xfs_rtxnum_t next; /* next rtext to try (dummy) */ 344 + xfs_rtxlen_t alloclen; /* candidate length */ 345 + xfs_rtxlen_t scanlen; /* number of free rtx to look for */ 346 + int isfree; /* extent is free */ 347 + int error; 348 348 349 349 ASSERT(minlen % prod == 0); 350 350 ASSERT(maxlen % prod == 0); 351 - /* 352 - * Check if the range in question (for maxlen) is free. 353 - */ 354 - error = xfs_rtcheck_range(args, start, maxlen, 1, &next, &isfree); 351 + 352 + /* Make sure we don't run off the end of the rt volume. */ 353 + scanlen = xfs_rtallocate_clamp_len(mp, start, maxlen, prod); 354 + if (scanlen < minlen) 355 + return -ENOSPC; 356 + 357 + /* Check if the range in question (for scanlen) is free. */ 358 + error = xfs_rtcheck_range(args, start, scanlen, 1, &next, &isfree); 355 359 if (error) 356 360 return error; 357 361 358 - if (!isfree) { 359 - /* 360 - * If not, allocate what there is, if it's at least minlen. 361 - */ 362 - maxlen = next - start; 363 - if (maxlen < minlen) 364 - return -ENOSPC; 365 - 366 - /* 367 - * Trim off tail of extent, if prod is specified. 368 - */ 369 - if (prod > 1 && (i = maxlen % prod)) { 370 - maxlen -= i; 371 - if (maxlen < minlen) 372 - return -ENOSPC; 373 - } 362 + if (isfree) { 363 + /* start to scanlen is all free; allocate it. */ 364 + *len = scanlen; 365 + *rtx = start; 366 + return 0; 374 367 } 375 368 376 369 /* 377 - * Allocate what we can and return it. 370 + * If not, allocate what there is, if it's at least minlen. 378 371 */ 379 - error = xfs_rtallocate_range(args, start, maxlen); 380 - if (error) 381 - return error; 382 - *len = maxlen; 372 + alloclen = next - start; 373 + if (alloclen < minlen) 374 + return -ENOSPC; 375 + 376 + /* Ensure alloclen is a multiple of prod. */ 377 + alloclen = xfs_rtalloc_align_len(alloclen, prod); 378 + if (alloclen < minlen) 379 + return -ENOSPC; 380 + 381 + *len = alloclen; 383 382 *rtx = start; 384 383 return 0; 385 384 } ··· 419 416 if (start >= mp->m_sb.sb_rextents) 420 417 start = mp->m_sb.sb_rextents - 1; 421 418 422 - /* Make sure we don't run off the end of the rt volume. */ 423 - maxlen = xfs_rtallocate_clamp_len(mp, start, maxlen, prod); 424 - if (maxlen < minlen) 425 - return -ENOSPC; 426 - 427 419 /* 428 420 * Try the exact allocation first. 429 421 */ ··· 426 428 prod, rtx); 427 429 if (error != -ENOSPC) 428 430 return error; 429 - 430 431 431 432 bbno = xfs_rtx_to_rbmblock(mp, start); 432 433 i = 0; ··· 549 552 xfs_rtxnum_t *rtx) /* out: start rtext allocated */ 550 553 { 551 554 xfs_fileoff_t i; /* bitmap block number */ 555 + int error; 552 556 553 557 for (i = 0; i < args->mp->m_sb.sb_rbmblocks; i++) { 554 558 xfs_suminfo_t sum; /* summary information for extents */ 555 559 xfs_rtxnum_t n; /* next rtext to be tried */ 556 - int error; 557 560 558 561 error = xfs_rtget_summary(args, l, i, &sum); 559 562 if (error) ··· 649 652 return -ENOSPC; 650 653 } 651 654 652 - /* 653 - * Allocate space to the bitmap or summary file, and zero it, for growfs. 654 - */ 655 - STATIC int 656 - xfs_growfs_rt_alloc( 657 - struct xfs_mount *mp, /* file system mount point */ 658 - xfs_extlen_t oblocks, /* old count of blocks */ 659 - xfs_extlen_t nblocks, /* new count of blocks */ 660 - struct xfs_inode *ip) /* inode (bitmap/summary) */ 661 - { 662 - xfs_fileoff_t bno; /* block number in file */ 663 - struct xfs_buf *bp; /* temporary buffer for zeroing */ 664 - xfs_daddr_t d; /* disk block address */ 665 - int error; /* error return value */ 666 - xfs_fsblock_t fsbno; /* filesystem block for bno */ 667 - struct xfs_bmbt_irec map; /* block map output */ 668 - int nmap; /* number of block maps */ 669 - int resblks; /* space reservation */ 670 - enum xfs_blft buf_type; 671 - struct xfs_trans *tp; 672 - 673 - if (ip == mp->m_rsumip) 674 - buf_type = XFS_BLFT_RTSUMMARY_BUF; 675 - else 676 - buf_type = XFS_BLFT_RTBITMAP_BUF; 677 - 678 - /* 679 - * Allocate space to the file, as necessary. 680 - */ 681 - while (oblocks < nblocks) { 682 - resblks = XFS_GROWFSRT_SPACE_RES(mp, nblocks - oblocks); 683 - /* 684 - * Reserve space & log for one extent added to the file. 685 - */ 686 - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtalloc, resblks, 687 - 0, 0, &tp); 688 - if (error) 689 - return error; 690 - /* 691 - * Lock the inode. 692 - */ 693 - xfs_ilock(ip, XFS_ILOCK_EXCL); 694 - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 695 - 696 - error = xfs_iext_count_extend(tp, ip, XFS_DATA_FORK, 697 - XFS_IEXT_ADD_NOSPLIT_CNT); 698 - if (error) 699 - goto out_trans_cancel; 700 - 701 - /* 702 - * Allocate blocks to the bitmap file. 703 - */ 704 - nmap = 1; 705 - error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, 706 - XFS_BMAPI_METADATA, 0, &map, &nmap); 707 - if (error) 708 - goto out_trans_cancel; 709 - /* 710 - * Free any blocks freed up in the transaction, then commit. 711 - */ 712 - error = xfs_trans_commit(tp); 713 - if (error) 714 - return error; 715 - /* 716 - * Now we need to clear the allocated blocks. 717 - * Do this one block per transaction, to keep it simple. 718 - */ 719 - for (bno = map.br_startoff, fsbno = map.br_startblock; 720 - bno < map.br_startoff + map.br_blockcount; 721 - bno++, fsbno++) { 722 - /* 723 - * Reserve log for one block zeroing. 724 - */ 725 - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 726 - 0, 0, 0, &tp); 727 - if (error) 728 - return error; 729 - /* 730 - * Lock the bitmap inode. 731 - */ 732 - xfs_ilock(ip, XFS_ILOCK_EXCL); 733 - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 734 - /* 735 - * Get a buffer for the block. 736 - */ 737 - d = XFS_FSB_TO_DADDR(mp, fsbno); 738 - error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, 739 - mp->m_bsize, 0, &bp); 740 - if (error) 741 - goto out_trans_cancel; 742 - 743 - xfs_trans_buf_set_type(tp, bp, buf_type); 744 - bp->b_ops = &xfs_rtbuf_ops; 745 - memset(bp->b_addr, 0, mp->m_sb.sb_blocksize); 746 - xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); 747 - /* 748 - * Commit the transaction. 749 - */ 750 - error = xfs_trans_commit(tp); 751 - if (error) 752 - return error; 753 - } 754 - /* 755 - * Go on to the next extent, if any. 756 - */ 757 - oblocks = map.br_startoff + map.br_blockcount; 758 - } 759 - 760 - return 0; 761 - 762 - out_trans_cancel: 763 - xfs_trans_cancel(tp); 764 - return error; 765 - } 766 - 767 - static void 655 + static int 768 656 xfs_alloc_rsum_cache( 769 - xfs_mount_t *mp, /* file system mount structure */ 770 - xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */ 657 + struct xfs_mount *mp, 658 + xfs_extlen_t rbmblocks) 771 659 { 772 660 /* 773 661 * The rsum cache is initialized to the maximum value, which is 774 662 * trivially an upper bound on the maximum level with any free extents. 775 - * We can continue without the cache if it couldn't be allocated. 776 663 */ 777 664 mp->m_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL); 778 - if (mp->m_rsum_cache) 779 - memset(mp->m_rsum_cache, -1, rbmblocks); 780 - else 781 - xfs_warn(mp, "could not allocate realtime summary cache"); 665 + if (!mp->m_rsum_cache) 666 + return -ENOMEM; 667 + memset(mp->m_rsum_cache, -1, rbmblocks); 668 + return 0; 782 669 } 783 670 784 671 /* ··· 698 817 return error; 699 818 } 700 819 820 + static int 821 + xfs_growfs_rt_bmblock( 822 + struct xfs_mount *mp, 823 + xfs_rfsblock_t nrblocks, 824 + xfs_agblock_t rextsize, 825 + xfs_fileoff_t bmbno) 826 + { 827 + struct xfs_inode *rbmip = mp->m_rbmip; 828 + struct xfs_inode *rsumip = mp->m_rsumip; 829 + struct xfs_rtalloc_args args = { 830 + .mp = mp, 831 + }; 832 + struct xfs_rtalloc_args nargs = { 833 + }; 834 + struct xfs_mount *nmp; 835 + xfs_rfsblock_t nrblocks_step; 836 + xfs_rtbxlen_t freed_rtx; 837 + int error; 838 + 839 + 840 + nrblocks_step = (bmbno + 1) * NBBY * mp->m_sb.sb_blocksize * rextsize; 841 + 842 + nmp = nargs.mp = kmemdup(mp, sizeof(*mp), GFP_KERNEL); 843 + if (!nmp) 844 + return -ENOMEM; 845 + 846 + /* 847 + * Calculate new sb and mount fields for this round. 848 + */ 849 + nmp->m_sb.sb_rextsize = rextsize; 850 + xfs_mount_sb_set_rextsize(nmp, &nmp->m_sb); 851 + nmp->m_sb.sb_rbmblocks = bmbno + 1; 852 + nmp->m_sb.sb_rblocks = min(nrblocks, nrblocks_step); 853 + nmp->m_sb.sb_rextents = xfs_rtb_to_rtx(nmp, nmp->m_sb.sb_rblocks); 854 + nmp->m_sb.sb_rextslog = xfs_compute_rextslog(nmp->m_sb.sb_rextents); 855 + nmp->m_rsumlevels = nmp->m_sb.sb_rextslog + 1; 856 + nmp->m_rsumblocks = xfs_rtsummary_blockcount(mp, nmp->m_rsumlevels, 857 + nmp->m_sb.sb_rbmblocks); 858 + 859 + /* 860 + * Recompute the growfsrt reservation from the new rsumsize, so that the 861 + * transaction below use the new, potentially larger value. 862 + * */ 863 + xfs_trans_resv_calc(nmp, &nmp->m_resv); 864 + error = xfs_trans_alloc(mp, &M_RES(nmp)->tr_growrtfree, 0, 0, 0, 865 + &args.tp); 866 + if (error) 867 + goto out_free; 868 + nargs.tp = args.tp; 869 + 870 + xfs_rtbitmap_lock(mp); 871 + xfs_rtbitmap_trans_join(args.tp); 872 + 873 + /* 874 + * Update the bitmap inode's size ondisk and incore. We need to update 875 + * the incore size so that inode inactivation won't punch what it thinks 876 + * are "posteof" blocks. 877 + */ 878 + rbmip->i_disk_size = nmp->m_sb.sb_rbmblocks * nmp->m_sb.sb_blocksize; 879 + i_size_write(VFS_I(rbmip), rbmip->i_disk_size); 880 + xfs_trans_log_inode(args.tp, rbmip, XFS_ILOG_CORE); 881 + 882 + /* 883 + * Update the summary inode's size. We need to update the incore size 884 + * so that inode inactivation won't punch what it thinks are "posteof" 885 + * blocks. 886 + */ 887 + rsumip->i_disk_size = nmp->m_rsumblocks * nmp->m_sb.sb_blocksize; 888 + i_size_write(VFS_I(rsumip), rsumip->i_disk_size); 889 + xfs_trans_log_inode(args.tp, rsumip, XFS_ILOG_CORE); 890 + 891 + /* 892 + * Copy summary data from old to new sizes when the real size (not 893 + * block-aligned) changes. 894 + */ 895 + if (mp->m_sb.sb_rbmblocks != nmp->m_sb.sb_rbmblocks || 896 + mp->m_rsumlevels != nmp->m_rsumlevels) { 897 + error = xfs_rtcopy_summary(&args, &nargs); 898 + if (error) 899 + goto out_cancel; 900 + } 901 + 902 + /* 903 + * Update superblock fields. 904 + */ 905 + if (nmp->m_sb.sb_rextsize != mp->m_sb.sb_rextsize) 906 + xfs_trans_mod_sb(args.tp, XFS_TRANS_SB_REXTSIZE, 907 + nmp->m_sb.sb_rextsize - mp->m_sb.sb_rextsize); 908 + if (nmp->m_sb.sb_rbmblocks != mp->m_sb.sb_rbmblocks) 909 + xfs_trans_mod_sb(args.tp, XFS_TRANS_SB_RBMBLOCKS, 910 + nmp->m_sb.sb_rbmblocks - mp->m_sb.sb_rbmblocks); 911 + if (nmp->m_sb.sb_rblocks != mp->m_sb.sb_rblocks) 912 + xfs_trans_mod_sb(args.tp, XFS_TRANS_SB_RBLOCKS, 913 + nmp->m_sb.sb_rblocks - mp->m_sb.sb_rblocks); 914 + if (nmp->m_sb.sb_rextents != mp->m_sb.sb_rextents) 915 + xfs_trans_mod_sb(args.tp, XFS_TRANS_SB_REXTENTS, 916 + nmp->m_sb.sb_rextents - mp->m_sb.sb_rextents); 917 + if (nmp->m_sb.sb_rextslog != mp->m_sb.sb_rextslog) 918 + xfs_trans_mod_sb(args.tp, XFS_TRANS_SB_REXTSLOG, 919 + nmp->m_sb.sb_rextslog - mp->m_sb.sb_rextslog); 920 + 921 + /* 922 + * Free the new extent. 923 + */ 924 + freed_rtx = nmp->m_sb.sb_rextents - mp->m_sb.sb_rextents; 925 + error = xfs_rtfree_range(&nargs, mp->m_sb.sb_rextents, freed_rtx); 926 + xfs_rtbuf_cache_relse(&nargs); 927 + if (error) 928 + goto out_cancel; 929 + 930 + /* 931 + * Mark more blocks free in the superblock. 932 + */ 933 + xfs_trans_mod_sb(args.tp, XFS_TRANS_SB_FREXTENTS, freed_rtx); 934 + 935 + /* 936 + * Update the calculated values in the real mount structure. 937 + */ 938 + mp->m_rsumlevels = nmp->m_rsumlevels; 939 + mp->m_rsumblocks = nmp->m_rsumblocks; 940 + xfs_mount_sb_set_rextsize(mp, &mp->m_sb); 941 + 942 + /* 943 + * Recompute the growfsrt reservation from the new rsumsize. 944 + */ 945 + xfs_trans_resv_calc(mp, &mp->m_resv); 946 + 947 + error = xfs_trans_commit(args.tp); 948 + if (error) 949 + goto out_free; 950 + 951 + /* 952 + * Ensure the mount RT feature flag is now set. 953 + */ 954 + mp->m_features |= XFS_FEAT_REALTIME; 955 + 956 + kfree(nmp); 957 + return 0; 958 + 959 + out_cancel: 960 + xfs_trans_cancel(args.tp); 961 + out_free: 962 + kfree(nmp); 963 + return error; 964 + } 965 + 701 966 /* 702 - * Visible (exported) functions. 967 + * Calculate the last rbmblock currently used. 968 + * 969 + * This also deals with the case where there were no rtextents before. 703 970 */ 971 + static xfs_fileoff_t 972 + xfs_last_rt_bmblock( 973 + struct xfs_mount *mp) 974 + { 975 + xfs_fileoff_t bmbno = mp->m_sb.sb_rbmblocks; 976 + 977 + /* Skip the current block if it is exactly full. */ 978 + if (xfs_rtx_to_rbmword(mp, mp->m_sb.sb_rextents) != 0) 979 + bmbno--; 980 + return bmbno; 981 + } 704 982 705 983 /* 706 984 * Grow the realtime area of the filesystem. ··· 872 832 xfs_fileoff_t bmbno; /* bitmap block number */ 873 833 struct xfs_buf *bp; /* temporary buffer */ 874 834 int error; /* error return value */ 875 - xfs_mount_t *nmp; /* new (fake) mount structure */ 876 - xfs_rfsblock_t nrblocks; /* new number of realtime blocks */ 877 835 xfs_extlen_t nrbmblocks; /* new number of rt bitmap blocks */ 878 836 xfs_rtxnum_t nrextents; /* new number of realtime extents */ 879 - uint8_t nrextslog; /* new log2 of sb_rextents */ 880 837 xfs_extlen_t nrsumblocks; /* new number of summary blocks */ 881 - uint nrsumlevels; /* new rt summary levels */ 882 - uint nrsumsize; /* new size of rt summary, bytes */ 883 - xfs_sb_t *nsbp; /* new superblock */ 884 838 xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ 885 839 xfs_extlen_t rsumblocks; /* current number of rt summary blks */ 886 - xfs_sb_t *sbp; /* old superblock */ 887 840 uint8_t *rsum_cache; /* old summary cache */ 888 841 xfs_agblock_t old_rextsize = mp->m_sb.sb_rextsize; 889 - 890 - sbp = &mp->m_sb; 891 842 892 843 if (!capable(CAP_SYS_ADMIN)) 893 844 return -EPERM; ··· 898 867 goto out_unlock; 899 868 900 869 /* Shrink not supported. */ 901 - if (in->newblocks <= sbp->sb_rblocks) 870 + if (in->newblocks <= mp->m_sb.sb_rblocks) 902 871 goto out_unlock; 903 - 904 872 /* Can only change rt extent size when adding rt volume. */ 905 - if (sbp->sb_rblocks > 0 && in->extsize != sbp->sb_rextsize) 873 + if (mp->m_sb.sb_rblocks > 0 && in->extsize != mp->m_sb.sb_rextsize) 906 874 goto out_unlock; 907 875 908 876 /* Range check the extent size. */ ··· 914 884 if (xfs_has_rmapbt(mp) || xfs_has_reflink(mp) || xfs_has_quota(mp)) 915 885 goto out_unlock; 916 886 917 - nrblocks = in->newblocks; 918 - error = xfs_sb_validate_fsb_count(sbp, nrblocks); 887 + error = xfs_sb_validate_fsb_count(&mp->m_sb, in->newblocks); 919 888 if (error) 920 889 goto out_unlock; 921 890 /* 922 891 * Read in the last block of the device, make sure it exists. 923 892 */ 924 893 error = xfs_buf_read_uncached(mp->m_rtdev_targp, 925 - XFS_FSB_TO_BB(mp, nrblocks - 1), 894 + XFS_FSB_TO_BB(mp, in->newblocks - 1), 926 895 XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); 927 896 if (error) 928 897 goto out_unlock; ··· 930 901 /* 931 902 * Calculate new parameters. These are the final values to be reached. 932 903 */ 933 - nrextents = nrblocks; 934 - do_div(nrextents, in->extsize); 935 - if (!xfs_validate_rtextents(nrextents)) { 904 + nrextents = div_u64(in->newblocks, in->extsize); 905 + if (nrextents == 0) { 936 906 error = -EINVAL; 937 907 goto out_unlock; 938 908 } 939 909 nrbmblocks = xfs_rtbitmap_blockcount(mp, nrextents); 940 - nrextslog = xfs_compute_rextslog(nrextents); 941 - nrsumlevels = nrextslog + 1; 942 - nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, nrbmblocks); 943 - nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); 910 + nrsumblocks = xfs_rtsummary_blockcount(mp, 911 + xfs_compute_rextslog(nrextents) + 1, nrbmblocks); 912 + 944 913 /* 945 914 * New summary size can't be more than half the size of 946 915 * the log. This prevents us from getting a log overflow, ··· 958 931 /* 959 932 * Allocate space to the bitmap and summary files, as necessary. 960 933 */ 961 - error = xfs_growfs_rt_alloc(mp, rbmblocks, nrbmblocks, mp->m_rbmip); 934 + error = xfs_rtfile_initialize_blocks(mp->m_rbmip, rbmblocks, 935 + nrbmblocks, NULL); 962 936 if (error) 963 937 goto out_unlock; 964 - error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip); 938 + error = xfs_rtfile_initialize_blocks(mp->m_rsumip, rsumblocks, 939 + nrsumblocks, NULL); 965 940 if (error) 966 941 goto out_unlock; 967 942 968 943 rsum_cache = mp->m_rsum_cache; 969 - if (nrbmblocks != sbp->sb_rbmblocks) 970 - xfs_alloc_rsum_cache(mp, nrbmblocks); 971 - 972 - /* 973 - * Allocate a new (fake) mount/sb. 974 - */ 975 - nmp = kmalloc(sizeof(*nmp), GFP_KERNEL | __GFP_NOFAIL); 976 - /* 977 - * Loop over the bitmap blocks. 978 - * We will do everything one bitmap block at a time. 979 - * Skip the current block if it is exactly full. 980 - * This also deals with the case where there were no rtextents before. 981 - */ 982 - for (bmbno = sbp->sb_rbmblocks - 983 - ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); 984 - bmbno < nrbmblocks; 985 - bmbno++) { 986 - struct xfs_rtalloc_args args = { 987 - .mp = mp, 988 - }; 989 - struct xfs_rtalloc_args nargs = { 990 - .mp = nmp, 991 - }; 992 - struct xfs_trans *tp; 993 - xfs_rfsblock_t nrblocks_step; 994 - 995 - *nmp = *mp; 996 - nsbp = &nmp->m_sb; 997 - /* 998 - * Calculate new sb and mount fields for this round. 999 - */ 1000 - nsbp->sb_rextsize = in->extsize; 1001 - nmp->m_rtxblklog = -1; /* don't use shift or masking */ 1002 - nsbp->sb_rbmblocks = bmbno + 1; 1003 - nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize * 1004 - nsbp->sb_rextsize; 1005 - nsbp->sb_rblocks = min(nrblocks, nrblocks_step); 1006 - nsbp->sb_rextents = xfs_rtb_to_rtx(nmp, nsbp->sb_rblocks); 1007 - ASSERT(nsbp->sb_rextents != 0); 1008 - nsbp->sb_rextslog = xfs_compute_rextslog(nsbp->sb_rextents); 1009 - nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; 1010 - nrsumblocks = xfs_rtsummary_blockcount(mp, nrsumlevels, 1011 - nsbp->sb_rbmblocks); 1012 - nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks); 1013 - /* recompute growfsrt reservation from new rsumsize */ 1014 - xfs_trans_resv_calc(nmp, &nmp->m_resv); 1015 - 1016 - /* 1017 - * Start a transaction, get the log reservation. 1018 - */ 1019 - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtfree, 0, 0, 0, 1020 - &tp); 944 + if (nrbmblocks != mp->m_sb.sb_rbmblocks) { 945 + error = xfs_alloc_rsum_cache(mp, nrbmblocks); 1021 946 if (error) 1022 - break; 1023 - args.tp = tp; 1024 - nargs.tp = tp; 1025 - 1026 - /* 1027 - * Lock out other callers by grabbing the bitmap and summary 1028 - * inode locks and joining them to the transaction. 1029 - */ 1030 - xfs_rtbitmap_lock(tp, mp); 1031 - /* 1032 - * Update the bitmap inode's size ondisk and incore. We need 1033 - * to update the incore size so that inode inactivation won't 1034 - * punch what it thinks are "posteof" blocks. 1035 - */ 1036 - mp->m_rbmip->i_disk_size = 1037 - nsbp->sb_rbmblocks * nsbp->sb_blocksize; 1038 - i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_disk_size); 1039 - xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); 1040 - /* 1041 - * Update the summary inode's size. We need to update the 1042 - * incore size so that inode inactivation won't punch what it 1043 - * thinks are "posteof" blocks. 1044 - */ 1045 - mp->m_rsumip->i_disk_size = nmp->m_rsumsize; 1046 - i_size_write(VFS_I(mp->m_rsumip), mp->m_rsumip->i_disk_size); 1047 - xfs_trans_log_inode(tp, mp->m_rsumip, XFS_ILOG_CORE); 1048 - /* 1049 - * Copy summary data from old to new sizes. 1050 - * Do this when the real size (not block-aligned) changes. 1051 - */ 1052 - if (sbp->sb_rbmblocks != nsbp->sb_rbmblocks || 1053 - mp->m_rsumlevels != nmp->m_rsumlevels) { 1054 - error = xfs_rtcopy_summary(&args, &nargs); 1055 - if (error) 1056 - goto error_cancel; 1057 - } 1058 - /* 1059 - * Update superblock fields. 1060 - */ 1061 - if (nsbp->sb_rextsize != sbp->sb_rextsize) 1062 - xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSIZE, 1063 - nsbp->sb_rextsize - sbp->sb_rextsize); 1064 - if (nsbp->sb_rbmblocks != sbp->sb_rbmblocks) 1065 - xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBMBLOCKS, 1066 - nsbp->sb_rbmblocks - sbp->sb_rbmblocks); 1067 - if (nsbp->sb_rblocks != sbp->sb_rblocks) 1068 - xfs_trans_mod_sb(tp, XFS_TRANS_SB_RBLOCKS, 1069 - nsbp->sb_rblocks - sbp->sb_rblocks); 1070 - if (nsbp->sb_rextents != sbp->sb_rextents) 1071 - xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTENTS, 1072 - nsbp->sb_rextents - sbp->sb_rextents); 1073 - if (nsbp->sb_rextslog != sbp->sb_rextslog) 1074 - xfs_trans_mod_sb(tp, XFS_TRANS_SB_REXTSLOG, 1075 - nsbp->sb_rextslog - sbp->sb_rextslog); 1076 - /* 1077 - * Free new extent. 1078 - */ 1079 - error = xfs_rtfree_range(&nargs, sbp->sb_rextents, 1080 - nsbp->sb_rextents - sbp->sb_rextents); 1081 - xfs_rtbuf_cache_relse(&nargs); 1082 - if (error) { 1083 - error_cancel: 1084 - xfs_trans_cancel(tp); 1085 - break; 1086 - } 1087 - /* 1088 - * Mark more blocks free in the superblock. 1089 - */ 1090 - xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, 1091 - nsbp->sb_rextents - sbp->sb_rextents); 1092 - /* 1093 - * Update mp values into the real mp structure. 1094 - */ 1095 - mp->m_rsumlevels = nrsumlevels; 1096 - mp->m_rsumsize = nrsumsize; 1097 - /* recompute growfsrt reservation from new rsumsize */ 1098 - xfs_trans_resv_calc(mp, &mp->m_resv); 1099 - 1100 - error = xfs_trans_commit(tp); 1101 - if (error) 1102 - break; 1103 - 1104 - /* Ensure the mount RT feature flag is now set. */ 1105 - mp->m_features |= XFS_FEAT_REALTIME; 947 + goto out_unlock; 1106 948 } 1107 - if (error) 1108 - goto out_free; 949 + 950 + /* Initialize the free space bitmap one bitmap block at a time. */ 951 + for (bmbno = xfs_last_rt_bmblock(mp); bmbno < nrbmblocks; bmbno++) { 952 + error = xfs_growfs_rt_bmblock(mp, in->newblocks, in->extsize, 953 + bmbno); 954 + if (error) 955 + goto out_free; 956 + } 1109 957 1110 958 if (old_rextsize != in->extsize) { 1111 959 error = xfs_growfs_rt_fixup_extsize(mp); ··· 992 1090 error = xfs_update_secondary_sbs(mp); 993 1091 994 1092 out_free: 995 - /* 996 - * Free the fake mp structure. 997 - */ 998 - kfree(nmp); 999 - 1000 1093 /* 1001 1094 * If we had to allocate a new rsum_cache, we either need to free the 1002 1095 * old one (if we succeeded) or free the new one and restore the old one ··· 1021 1124 struct xfs_buf *bp; /* buffer for last block of subvolume */ 1022 1125 struct xfs_sb *sbp; /* filesystem superblock copy in mount */ 1023 1126 xfs_daddr_t d; /* address of last block of subvolume */ 1024 - unsigned int rsumblocks; 1025 1127 int error; 1026 1128 1027 1129 sbp = &mp->m_sb; ··· 1032 1136 return -ENODEV; 1033 1137 } 1034 1138 mp->m_rsumlevels = sbp->sb_rextslog + 1; 1035 - rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, 1139 + mp->m_rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels, 1036 1140 mp->m_sb.sb_rbmblocks); 1037 - mp->m_rsumsize = XFS_FSB_TO_B(mp, rsumblocks); 1038 1141 mp->m_rbmip = mp->m_rsumip = NULL; 1039 1142 /* 1040 1143 * Check that the realtime section is an ok size. ··· 1163 1268 if (error) 1164 1269 goto out_rele_summary; 1165 1270 1166 - xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); 1271 + error = xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); 1272 + if (error) 1273 + goto out_rele_summary; 1167 1274 return 0; 1168 1275 1169 1276 out_rele_summary: ··· 1193 1296 * of rtextents and the fraction. 1194 1297 * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ... 1195 1298 */ 1196 - static int 1299 + static xfs_rtxnum_t 1197 1300 xfs_rtpick_extent( 1198 1301 xfs_mount_t *mp, /* file system mount point */ 1199 1302 xfs_trans_t *tp, /* transaction pointer */ 1200 - xfs_rtxlen_t len, /* allocation length (rtextents) */ 1201 - xfs_rtxnum_t *pick) /* result rt extent */ 1303 + xfs_rtxlen_t len) /* allocation length (rtextents) */ 1202 1304 { 1203 1305 xfs_rtxnum_t b; /* result rtext */ 1204 1306 int log2; /* log of sequence number */ ··· 1228 1332 ts.tv_sec = seq + 1; 1229 1333 inode_set_atime_to_ts(VFS_I(mp->m_rbmip), ts); 1230 1334 xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE); 1231 - *pick = b; 1232 - return 0; 1335 + return b; 1233 1336 } 1234 1337 1235 1338 static void ··· 1260 1365 *raminlen = newminlen; 1261 1366 } 1262 1367 1263 - int 1264 - xfs_bmap_rtalloc( 1265 - struct xfs_bmalloca *ap) 1368 + static int 1369 + xfs_rtallocate( 1370 + struct xfs_trans *tp, 1371 + xfs_rtblock_t bno_hint, 1372 + xfs_rtxlen_t minlen, 1373 + xfs_rtxlen_t maxlen, 1374 + xfs_rtxlen_t prod, 1375 + bool wasdel, 1376 + bool initial_user_data, 1377 + bool *rtlocked, 1378 + xfs_rtblock_t *bno, 1379 + xfs_extlen_t *blen) 1380 + { 1381 + struct xfs_rtalloc_args args = { 1382 + .mp = tp->t_mountp, 1383 + .tp = tp, 1384 + }; 1385 + xfs_rtxnum_t start = 0; 1386 + xfs_rtxnum_t rtx; 1387 + xfs_rtxlen_t len = 0; 1388 + int error = 0; 1389 + 1390 + /* 1391 + * Lock out modifications to both the RT bitmap and summary inodes. 1392 + */ 1393 + if (!*rtlocked) { 1394 + xfs_rtbitmap_lock(args.mp); 1395 + xfs_rtbitmap_trans_join(tp); 1396 + *rtlocked = true; 1397 + } 1398 + 1399 + /* 1400 + * For an allocation to an empty file at offset 0, pick an extent that 1401 + * will space things out in the rt area. 1402 + */ 1403 + if (bno_hint) 1404 + start = xfs_rtb_to_rtx(args.mp, bno_hint); 1405 + else if (initial_user_data) 1406 + start = xfs_rtpick_extent(args.mp, tp, maxlen); 1407 + 1408 + if (start) { 1409 + error = xfs_rtallocate_extent_near(&args, start, minlen, maxlen, 1410 + &len, prod, &rtx); 1411 + /* 1412 + * If we can't allocate near a specific rt extent, try again 1413 + * without locality criteria. 1414 + */ 1415 + if (error == -ENOSPC) { 1416 + xfs_rtbuf_cache_relse(&args); 1417 + error = 0; 1418 + } 1419 + } 1420 + 1421 + if (!error) { 1422 + error = xfs_rtallocate_extent_size(&args, minlen, maxlen, &len, 1423 + prod, &rtx); 1424 + } 1425 + 1426 + if (error) 1427 + goto out_release; 1428 + 1429 + error = xfs_rtallocate_range(&args, rtx, len); 1430 + if (error) 1431 + goto out_release; 1432 + 1433 + xfs_trans_mod_sb(tp, wasdel ? 1434 + XFS_TRANS_SB_RES_FREXTENTS : XFS_TRANS_SB_FREXTENTS, 1435 + -(long)len); 1436 + *bno = xfs_rtx_to_rtb(args.mp, rtx); 1437 + *blen = xfs_rtxlen_to_extlen(args.mp, len); 1438 + 1439 + out_release: 1440 + xfs_rtbuf_cache_relse(&args); 1441 + return error; 1442 + } 1443 + 1444 + static int 1445 + xfs_rtallocate_align( 1446 + struct xfs_bmalloca *ap, 1447 + xfs_rtxlen_t *ralen, 1448 + xfs_rtxlen_t *raminlen, 1449 + xfs_rtxlen_t *prod, 1450 + bool *noalign) 1266 1451 { 1267 1452 struct xfs_mount *mp = ap->ip->i_mount; 1268 1453 xfs_fileoff_t orig_offset = ap->offset; 1269 - xfs_rtxnum_t start; /* allocation hint rtextent no */ 1270 - xfs_rtxnum_t rtx; /* actually allocated rtextent no */ 1271 - xfs_rtxlen_t prod = 0; /* product factor for allocators */ 1272 - xfs_extlen_t mod = 0; /* product factor for allocators */ 1273 - xfs_rtxlen_t ralen = 0; /* realtime allocation length */ 1274 - xfs_extlen_t align; /* minimum allocation alignment */ 1275 - xfs_extlen_t orig_length = ap->length; 1276 1454 xfs_extlen_t minlen = mp->m_sb.sb_rextsize; 1277 - xfs_rtxlen_t raminlen; 1278 - bool rtlocked = false; 1279 - bool ignore_locality = false; 1280 - struct xfs_rtalloc_args args = { 1281 - .mp = mp, 1282 - .tp = ap->tp, 1283 - }; 1455 + xfs_extlen_t align; /* minimum allocation alignment */ 1456 + xfs_extlen_t mod; /* product factor for allocators */ 1284 1457 int error; 1285 1458 1286 - align = xfs_get_extsz_hint(ap->ip); 1287 - if (!align) 1288 - align = 1; 1289 - retry: 1290 - error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, 1291 - align, 1, ap->eof, 0, 1292 - ap->conv, &ap->offset, &ap->length); 1459 + if (*noalign) { 1460 + align = mp->m_sb.sb_rextsize; 1461 + } else { 1462 + align = xfs_get_extsz_hint(ap->ip); 1463 + if (!align) 1464 + align = 1; 1465 + if (align == mp->m_sb.sb_rextsize) 1466 + *noalign = true; 1467 + } 1468 + 1469 + error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, align, 1, 1470 + ap->eof, 0, ap->conv, &ap->offset, &ap->length); 1293 1471 if (error) 1294 1472 return error; 1295 1473 ASSERT(ap->length); ··· 1386 1418 * XFS_BMBT_MAX_EXTLEN), we don't hear about that number, and can't 1387 1419 * adjust the starting point to match it. 1388 1420 */ 1389 - ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN)); 1390 - raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); 1391 - ASSERT(raminlen > 0); 1392 - ASSERT(raminlen <= ralen); 1393 - 1394 - /* 1395 - * Lock out modifications to both the RT bitmap and summary inodes 1396 - */ 1397 - if (!rtlocked) { 1398 - xfs_rtbitmap_lock(ap->tp, mp); 1399 - rtlocked = true; 1400 - } 1401 - 1402 - if (ignore_locality) { 1403 - start = 0; 1404 - } else if (xfs_bmap_adjacent(ap)) { 1405 - start = xfs_rtb_to_rtx(mp, ap->blkno); 1406 - } else if (ap->datatype & XFS_ALLOC_INITIAL_USER_DATA) { 1407 - /* 1408 - * If it's an allocation to an empty file at offset 0, pick an 1409 - * extent that will space things out in the rt area. 1410 - */ 1411 - error = xfs_rtpick_extent(mp, ap->tp, ralen, &start); 1412 - if (error) 1413 - return error; 1414 - } else { 1415 - start = 0; 1416 - } 1421 + *ralen = xfs_extlen_to_rtxlen(mp, min(ap->length, XFS_MAX_BMBT_EXTLEN)); 1422 + *raminlen = max_t(xfs_rtxlen_t, 1, xfs_extlen_to_rtxlen(mp, minlen)); 1423 + ASSERT(*raminlen > 0); 1424 + ASSERT(*raminlen <= *ralen); 1417 1425 1418 1426 /* 1419 1427 * Only bother calculating a real prod factor if offset & length are 1420 1428 * perfectly aligned, otherwise it will just get us in trouble. 1421 1429 */ 1422 1430 div_u64_rem(ap->offset, align, &mod); 1423 - if (mod || ap->length % align) { 1424 - prod = 1; 1425 - } else { 1426 - prod = xfs_extlen_to_rtxlen(mp, align); 1427 - if (prod > 1) 1428 - xfs_rtalloc_align_minmax(&raminlen, &ralen, &prod); 1429 - } 1431 + if (mod || ap->length % align) 1432 + *prod = 1; 1433 + else 1434 + *prod = xfs_extlen_to_rtxlen(mp, align); 1430 1435 1431 - if (start) { 1432 - error = xfs_rtallocate_extent_near(&args, start, raminlen, 1433 - ralen, &ralen, prod, &rtx); 1434 - } else { 1435 - error = xfs_rtallocate_extent_size(&args, raminlen, 1436 - ralen, &ralen, prod, &rtx); 1437 - } 1438 - xfs_rtbuf_cache_relse(&args); 1436 + if (*prod > 1) 1437 + xfs_rtalloc_align_minmax(raminlen, ralen, prod); 1438 + return 0; 1439 + } 1439 1440 1441 + int 1442 + xfs_bmap_rtalloc( 1443 + struct xfs_bmalloca *ap) 1444 + { 1445 + xfs_fileoff_t orig_offset = ap->offset; 1446 + xfs_rtxlen_t prod = 0; /* product factor for allocators */ 1447 + xfs_rtxlen_t ralen = 0; /* realtime allocation length */ 1448 + xfs_rtblock_t bno_hint = NULLRTBLOCK; 1449 + xfs_extlen_t orig_length = ap->length; 1450 + xfs_rtxlen_t raminlen; 1451 + bool rtlocked = false; 1452 + bool noalign = false; 1453 + bool initial_user_data = 1454 + ap->datatype & XFS_ALLOC_INITIAL_USER_DATA; 1455 + int error; 1456 + 1457 + retry: 1458 + error = xfs_rtallocate_align(ap, &ralen, &raminlen, &prod, &noalign); 1459 + if (error) 1460 + return error; 1461 + 1462 + if (xfs_bmap_adjacent(ap)) 1463 + bno_hint = ap->blkno; 1464 + 1465 + error = xfs_rtallocate(ap->tp, bno_hint, raminlen, ralen, prod, 1466 + ap->wasdel, initial_user_data, &rtlocked, 1467 + &ap->blkno, &ap->length); 1440 1468 if (error == -ENOSPC) { 1441 - if (align > mp->m_sb.sb_rextsize) { 1469 + if (!noalign) { 1442 1470 /* 1443 1471 * We previously enlarged the request length to try to 1444 1472 * satisfy an extent size hint. The allocator didn't ··· 1444 1480 */ 1445 1481 ap->offset = orig_offset; 1446 1482 ap->length = orig_length; 1447 - minlen = align = mp->m_sb.sb_rextsize; 1448 - goto retry; 1449 - } 1450 - 1451 - if (!ignore_locality && start != 0) { 1452 - /* 1453 - * If we can't allocate near a specific rt extent, try 1454 - * again without locality criteria. 1455 - */ 1456 - ignore_locality = true; 1483 + noalign = true; 1457 1484 goto retry; 1458 1485 } 1459 1486 ··· 1455 1500 if (error) 1456 1501 return error; 1457 1502 1458 - xfs_trans_mod_sb(ap->tp, ap->wasdel ? 1459 - XFS_TRANS_SB_RES_FREXTENTS : XFS_TRANS_SB_FREXTENTS, 1460 - -(long)ralen); 1461 - ap->blkno = xfs_rtx_to_rtb(mp, rtx); 1462 - ap->length = xfs_rtxlen_to_extlen(mp, ralen); 1463 1503 xfs_bmap_alloc_account(ap); 1464 1504 return 0; 1465 1505 }
+6 -7
fs/xfs/xfs_super.c
··· 311 311 * the allocator to accommodate the request. 312 312 */ 313 313 if (xfs_has_small_inums(mp) && ino > XFS_MAXINUMBER_32) 314 - set_bit(XFS_OPSTATE_INODE32, &mp->m_opstate); 314 + xfs_set_inode32(mp); 315 315 else 316 - clear_bit(XFS_OPSTATE_INODE32, &mp->m_opstate); 316 + xfs_clear_inode32(mp); 317 317 318 318 for (index = 0; index < agcount; index++) { 319 319 struct xfs_perag *pag; ··· 1511 1511 * the newer fsopen/fsconfig API. 1512 1512 */ 1513 1513 if (fc->sb_flags & SB_RDONLY) 1514 - set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); 1514 + xfs_set_readonly(mp); 1515 1515 if (fc->sb_flags & SB_DIRSYNC) 1516 1516 mp->m_features |= XFS_FEAT_DIRSYNC; 1517 1517 if (fc->sb_flags & SB_SYNCHRONOUS) ··· 1820 1820 return -EINVAL; 1821 1821 } 1822 1822 1823 - clear_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); 1823 + xfs_clear_readonly(mp); 1824 1824 1825 1825 /* 1826 1826 * If this is the first remount to writeable state we might have some ··· 1908 1908 xfs_save_resvblks(mp); 1909 1909 1910 1910 xfs_log_clean(mp); 1911 - set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); 1911 + xfs_set_readonly(mp); 1912 1912 1913 1913 return 0; 1914 1914 } ··· 2009 2009 return -ENOMEM; 2010 2010 2011 2011 spin_lock_init(&mp->m_sb_lock); 2012 - INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC); 2013 - spin_lock_init(&mp->m_perag_lock); 2012 + xa_init(&mp->m_perags); 2014 2013 mutex_init(&mp->m_growlock); 2015 2014 INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker); 2016 2015 INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
+1 -1
fs/xfs/xfs_symlink.c
··· 165 165 /* 166 166 * Allocate an inode for the symlink. 167 167 */ 168 - error = xfs_dialloc(&tp, dp->i_ino, S_IFLNK, &ino); 168 + error = xfs_dialloc(&tp, &args, &ino); 169 169 if (!error) 170 170 error = xfs_icreate(tp, ino, &args, &du.ip); 171 171 if (error)
+58 -3
fs/xfs/xfs_trace.h
··· 210 210 TP_PROTO(struct xfs_perag *pag, unsigned long caller_ip), \ 211 211 TP_ARGS(pag, caller_ip)) 212 212 DEFINE_PERAG_REF_EVENT(xfs_perag_get); 213 - DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag); 214 213 DEFINE_PERAG_REF_EVENT(xfs_perag_hold); 215 214 DEFINE_PERAG_REF_EVENT(xfs_perag_put); 216 215 DEFINE_PERAG_REF_EVENT(xfs_perag_grab); 217 - DEFINE_PERAG_REF_EVENT(xfs_perag_grab_tag); 216 + DEFINE_PERAG_REF_EVENT(xfs_perag_grab_next_tag); 218 217 DEFINE_PERAG_REF_EVENT(xfs_perag_rele); 219 218 DEFINE_PERAG_REF_EVENT(xfs_perag_set_inode_tag); 220 219 DEFINE_PERAG_REF_EVENT(xfs_perag_clear_inode_tag); 220 + DEFINE_PERAG_REF_EVENT(xfs_reclaim_inodes_count); 221 221 222 222 TRACE_EVENT(xfs_inodegc_worker, 223 223 TP_PROTO(struct xfs_mount *mp, unsigned int shrinker_hits), ··· 4926 4926 { XFS_EXCHANGE_RANGE_DRY_RUN, "DRY_RUN" }, \ 4927 4927 { XFS_EXCHANGE_RANGE_FILE1_WRITTEN, "F1_WRITTEN" }, \ 4928 4928 { __XFS_EXCHANGE_RANGE_UPD_CMTIME1, "CMTIME1" }, \ 4929 - { __XFS_EXCHANGE_RANGE_UPD_CMTIME2, "CMTIME2" } 4929 + { __XFS_EXCHANGE_RANGE_UPD_CMTIME2, "CMTIME2" }, \ 4930 + { __XFS_EXCHANGE_RANGE_CHECK_FRESH2, "FRESH2" } 4930 4931 4931 4932 /* file exchange-range tracepoint class */ 4932 4933 DECLARE_EVENT_CLASS(xfs_exchrange_class, ··· 4986 4985 DEFINE_EXCHRANGE_EVENT(xfs_exchrange_prep); 4987 4986 DEFINE_EXCHRANGE_EVENT(xfs_exchrange_flush); 4988 4987 DEFINE_EXCHRANGE_EVENT(xfs_exchrange_mappings); 4988 + 4989 + TRACE_EVENT(xfs_exchrange_freshness, 4990 + TP_PROTO(const struct xfs_exchrange *fxr, struct xfs_inode *ip2), 4991 + TP_ARGS(fxr, ip2), 4992 + TP_STRUCT__entry( 4993 + __field(dev_t, dev) 4994 + __field(xfs_ino_t, ip2_ino) 4995 + __field(long long, ip2_mtime) 4996 + __field(long long, ip2_ctime) 4997 + __field(int, ip2_mtime_nsec) 4998 + __field(int, ip2_ctime_nsec) 4999 + 5000 + __field(xfs_ino_t, file2_ino) 5001 + __field(long long, file2_mtime) 5002 + __field(long long, file2_ctime) 5003 + __field(int, file2_mtime_nsec) 5004 + __field(int, file2_ctime_nsec) 5005 + ), 5006 + TP_fast_assign( 5007 + struct timespec64 ts64; 5008 + struct inode *inode2 = VFS_I(ip2); 5009 + 5010 + __entry->dev = inode2->i_sb->s_dev; 5011 + __entry->ip2_ino = ip2->i_ino; 5012 + 5013 + ts64 = inode_get_ctime(inode2); 5014 + __entry->ip2_ctime = ts64.tv_sec; 5015 + __entry->ip2_ctime_nsec = ts64.tv_nsec; 5016 + 5017 + ts64 = inode_get_mtime(inode2); 5018 + __entry->ip2_mtime = ts64.tv_sec; 5019 + __entry->ip2_mtime_nsec = ts64.tv_nsec; 5020 + 5021 + __entry->file2_ino = fxr->file2_ino; 5022 + __entry->file2_mtime = fxr->file2_mtime.tv_sec; 5023 + __entry->file2_ctime = fxr->file2_ctime.tv_sec; 5024 + __entry->file2_mtime_nsec = fxr->file2_mtime.tv_nsec; 5025 + __entry->file2_ctime_nsec = fxr->file2_ctime.tv_nsec; 5026 + ), 5027 + TP_printk("dev %d:%d " 5028 + "ino 0x%llx mtime %lld:%d ctime %lld:%d -> " 5029 + "file 0x%llx mtime %lld:%d ctime %lld:%d", 5030 + MAJOR(__entry->dev), MINOR(__entry->dev), 5031 + __entry->ip2_ino, 5032 + __entry->ip2_mtime, 5033 + __entry->ip2_mtime_nsec, 5034 + __entry->ip2_ctime, 5035 + __entry->ip2_ctime_nsec, 5036 + __entry->file2_ino, 5037 + __entry->file2_mtime, 5038 + __entry->file2_mtime_nsec, 5039 + __entry->file2_ctime, 5040 + __entry->file2_ctime_nsec) 5041 + ); 4989 5042 4990 5043 TRACE_EVENT(xfs_exchmaps_overhead, 4991 5044 TP_PROTO(struct xfs_mount *mp, unsigned long long bmbt_blocks,