diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 17:04:23 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-27 17:04:23 -0800 |
| commit | 47a43f2f0ce24bb75e3e4500118000585a3b496a (patch) | |
| tree | 4decf322cd12b49c3bc82d7578617bb27db0541a /fs/xfs/xfs_rtalloc.c | |
| parent | e01799ac56306ab211f2edf1221a82dc57eab8f5 (diff) | |
| parent | 65eed012d1f2d0f0bf0ffc036826d58147de77b8 (diff) | |
Merge tag 'xfs-4.21-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull XFS updates from Darrick Wong:
- Fix CoW remapping of extremely fragmented file areas
- Fix a zero-length symlink verifier error
- Constify some of the rmap owner structures for per-AG metadata
- Precalculate inode geometry for later use
- Fix scrub counting problems
- Don't crash when rtsummary inode is null
- Fix x32 ioctl operation
- Fix enum->string mappings for ftrace output
- Cache realtime summary information in memory
* tag 'xfs-4.21-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (24 commits)
xfs: reallocate realtime summary cache on growfs
xfs: stringify scrub types in ftrace output
xfs: stringify btree cursor types in ftrace output
xfs: move XFS_INODE_FORMAT_STR mappings to libxfs
xfs: move XFS_AG_BTREE_CMP_FORMAT_STR mappings to libxfs
xfs: fix symbolic enum printing in ftrace output
xfs: fix function pointer type in ftrace format
xfs: Fix x32 ioctls when cmd numbers differ from ia32.
xfs: Fix bulkstat compat ioctls on x32 userspace.
xfs: Align compat attrlist_by_handle with native implementation.
xfs: require both realtime inodes to mount
xfs: cache minimum realtime summary level
xfs: count inode blocks correctly in inobt scrub
xfs: precalculate cluster alignment in inodes and blocks
xfs: precalculate inodes and blocks per inode cluster
xfs: add a block to inode count converter
xfs: remove xfs_rmap_ag_owner and friends
xfs: const-ify xfs_owner_info arguments
xfs: streamline defer op type handling
xfs: idiotproof defer op type configuration
...
Diffstat (limited to 'fs/xfs/xfs_rtalloc.c')
| -rw-r--r-- | fs/xfs/xfs_rtalloc.c | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 926ed314ffba..ac0fcdad0c4e 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -64,8 +64,12 @@ xfs_rtany_summary( int log; /* loop counter, log2 of ext. size */ xfs_suminfo_t sum; /* summary data */ + /* There are no extents at levels < m_rsum_cache[bbno]. */ + if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno]) + low = mp->m_rsum_cache[bbno]; + /* - * Loop over logs of extent sizes. Order is irrelevant. + * Loop over logs of extent sizes. */ for (log = low; log <= high; log++) { /* @@ -80,13 +84,17 @@ xfs_rtany_summary( */ if (sum) { *stat = 1; - return 0; + goto out; } } /* * Found nothing, return failure. */ *stat = 0; +out: + /* There were no extents at levels < log. */ + if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno]) + mp->m_rsum_cache[bbno] = log; return 0; } @@ -853,6 +861,21 @@ out_trans_cancel: return error; } +static void +xfs_alloc_rsum_cache( + xfs_mount_t *mp, /* file system mount structure */ + xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */ +{ + /* + * The rsum cache is initialized to all zeroes, which is trivially a + * lower bound on the minimum level with any free extents. We can + * continue without the cache if it couldn't be allocated. + */ + mp->m_rsum_cache = kmem_zalloc_large(rbmblocks, KM_SLEEP); + if (!mp->m_rsum_cache) + xfs_warn(mp, "could not allocate realtime summary cache"); +} + /* * Visible (exported) functions. */ @@ -881,6 +904,7 @@ xfs_growfs_rt( xfs_extlen_t rsumblocks; /* current number of rt summary blks */ xfs_sb_t *sbp; /* old superblock */ xfs_fsblock_t sumbno; /* summary block number */ + uint8_t *rsum_cache; /* old summary cache */ sbp = &mp->m_sb; /* @@ -937,6 +961,11 @@ xfs_growfs_rt( error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_rsumip); if (error) return error; + + rsum_cache = mp->m_rsum_cache; + if (nrbmblocks != sbp->sb_rbmblocks) + xfs_alloc_rsum_cache(mp, nrbmblocks); + /* * Allocate a new (fake) mount/sb. */ @@ -1062,6 +1091,20 @@ error_cancel: */ kmem_free(nmp); + /* + * If we had to allocate a new rsum_cache, we either need to free the + * old one (if we succeeded) or free the new one and restore the old one + * (if there was an error). + */ + if (rsum_cache != mp->m_rsum_cache) { + if (error) { + kmem_free(mp->m_rsum_cache); + mp->m_rsum_cache = rsum_cache; + } else { + kmem_free(rsum_cache); + } + } + return error; } @@ -1187,8 +1230,8 @@ xfs_rtmount_init( } /* - * Get the bitmap and summary inodes into the mount structure - * at mount time. + * Get the bitmap and summary inodes and the summary cache into the mount + * structure at mount time. */ int /* error */ xfs_rtmount_inodes( @@ -1198,19 +1241,18 @@ xfs_rtmount_inodes( xfs_sb_t *sbp; sbp = &mp->m_sb; - if (sbp->sb_rbmino == NULLFSINO) - return 0; error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip); if (error) return error; ASSERT(mp->m_rbmip != NULL); - ASSERT(sbp->sb_rsumino != NULLFSINO); + error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); if (error) { xfs_irele(mp->m_rbmip); return error; } ASSERT(mp->m_rsumip != NULL); + xfs_alloc_rsum_cache(mp, sbp->sb_rbmblocks); return 0; } @@ -1218,6 +1260,7 @@ void xfs_rtunmount_inodes( struct xfs_mount *mp) { + kmem_free(mp->m_rsum_cache); if (mp->m_rbmip) xfs_irele(mp->m_rbmip); if (mp->m_rsumip) |
