Message ID | 20220611012659.3418072-6-david@fromorbit.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | xfs: per-ag centric allocation alogrithms | expand |
Hi Dave,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on v5.19-rc1]
[also build test WARNING on next-20220610]
[cannot apply to xfs-linux/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
base: f2906aa863381afb0015a9eb7fefad885d4e5a56
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20220611/202206111009.JR28QcIm-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/87045504fb13d6263ddf1d7780eef5eda1cee6ad
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
git checkout 87045504fb13d6263ddf1d7780eef5eda1cee6ad
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=arc SHELL=/bin/bash fs/xfs/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> fs/xfs/xfs_reflink.c:129:1: warning: no previous prototype for 'xfs_reflink_find_shared' [-Wmissing-prototypes]
129 | xfs_reflink_find_shared(
| ^~~~~~~~~~~~~~~~~~~~~~~
vim +/xfs_reflink_find_shared +129 fs/xfs/xfs_reflink.c
3993baeb3c52f4 Darrick J. Wong 2016-10-03 32
3993baeb3c52f4 Darrick J. Wong 2016-10-03 33 /*
3993baeb3c52f4 Darrick J. Wong 2016-10-03 34 * Copy on Write of Shared Blocks
3993baeb3c52f4 Darrick J. Wong 2016-10-03 35 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 36 * XFS must preserve "the usual" file semantics even when two files share
3993baeb3c52f4 Darrick J. Wong 2016-10-03 37 * the same physical blocks. This means that a write to one file must not
3993baeb3c52f4 Darrick J. Wong 2016-10-03 38 * alter the blocks in a different file; the way that we'll do that is
3993baeb3c52f4 Darrick J. Wong 2016-10-03 39 * through the use of a copy-on-write mechanism. At a high level, that
3993baeb3c52f4 Darrick J. Wong 2016-10-03 40 * means that when we want to write to a shared block, we allocate a new
3993baeb3c52f4 Darrick J. Wong 2016-10-03 41 * block, write the data to the new block, and if that succeeds we map the
3993baeb3c52f4 Darrick J. Wong 2016-10-03 42 * new block into the file.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 43 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 44 * XFS provides a "delayed allocation" mechanism that defers the allocation
3993baeb3c52f4 Darrick J. Wong 2016-10-03 45 * of disk blocks to dirty-but-not-yet-mapped file blocks as long as
3993baeb3c52f4 Darrick J. Wong 2016-10-03 46 * possible. This reduces fragmentation by enabling the filesystem to ask
3993baeb3c52f4 Darrick J. Wong 2016-10-03 47 * for bigger chunks less often, which is exactly what we want for CoW.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 48 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 49 * The delalloc mechanism begins when the kernel wants to make a block
3993baeb3c52f4 Darrick J. Wong 2016-10-03 50 * writable (write_begin or page_mkwrite). If the offset is not mapped, we
3993baeb3c52f4 Darrick J. Wong 2016-10-03 51 * create a delalloc mapping, which is a regular in-core extent, but without
3993baeb3c52f4 Darrick J. Wong 2016-10-03 52 * a real startblock. (For delalloc mappings, the startblock encodes both
3993baeb3c52f4 Darrick J. Wong 2016-10-03 53 * a flag that this is a delalloc mapping, and a worst-case estimate of how
3993baeb3c52f4 Darrick J. Wong 2016-10-03 54 * many blocks might be required to put the mapping into the BMBT.) delalloc
3993baeb3c52f4 Darrick J. Wong 2016-10-03 55 * mappings are a reservation against the free space in the filesystem;
3993baeb3c52f4 Darrick J. Wong 2016-10-03 56 * adjacent mappings can also be combined into fewer larger mappings.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 57 *
5eda43000064a6 Darrick J. Wong 2017-02-02 58 * As an optimization, the CoW extent size hint (cowextsz) creates
5eda43000064a6 Darrick J. Wong 2017-02-02 59 * outsized aligned delalloc reservations in the hope of landing out of
5eda43000064a6 Darrick J. Wong 2017-02-02 60 * order nearby CoW writes in a single extent on disk, thereby reducing
5eda43000064a6 Darrick J. Wong 2017-02-02 61 * fragmentation and improving future performance.
5eda43000064a6 Darrick J. Wong 2017-02-02 62 *
5eda43000064a6 Darrick J. Wong 2017-02-02 63 * D: --RRRRRRSSSRRRRRRRR--- (data fork)
5eda43000064a6 Darrick J. Wong 2017-02-02 64 * C: ------DDDDDDD--------- (CoW fork)
5eda43000064a6 Darrick J. Wong 2017-02-02 65 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 66 * When dirty pages are being written out (typically in writepage), the
5eda43000064a6 Darrick J. Wong 2017-02-02 67 * delalloc reservations are converted into unwritten mappings by
5eda43000064a6 Darrick J. Wong 2017-02-02 68 * allocating blocks and replacing the delalloc mapping with real ones.
5eda43000064a6 Darrick J. Wong 2017-02-02 69 * A delalloc mapping can be replaced by several unwritten ones if the
5eda43000064a6 Darrick J. Wong 2017-02-02 70 * free space is fragmented.
5eda43000064a6 Darrick J. Wong 2017-02-02 71 *
5eda43000064a6 Darrick J. Wong 2017-02-02 72 * D: --RRRRRRSSSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 73 * C: ------UUUUUUU---------
3993baeb3c52f4 Darrick J. Wong 2016-10-03 74 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 75 * We want to adapt the delalloc mechanism for copy-on-write, since the
3993baeb3c52f4 Darrick J. Wong 2016-10-03 76 * write paths are similar. The first two steps (creating the reservation
3993baeb3c52f4 Darrick J. Wong 2016-10-03 77 * and allocating the blocks) are exactly the same as delalloc except that
3993baeb3c52f4 Darrick J. Wong 2016-10-03 78 * the mappings must be stored in a separate CoW fork because we do not want
3993baeb3c52f4 Darrick J. Wong 2016-10-03 79 * to disturb the mapping in the data fork until we're sure that the write
3993baeb3c52f4 Darrick J. Wong 2016-10-03 80 * succeeded. IO completion in this case is the process of removing the old
3993baeb3c52f4 Darrick J. Wong 2016-10-03 81 * mapping from the data fork and moving the new mapping from the CoW fork to
3993baeb3c52f4 Darrick J. Wong 2016-10-03 82 * the data fork. This will be discussed shortly.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 83 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 84 * For now, unaligned directio writes will be bounced back to the page cache.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 85 * Block-aligned directio writes will use the same mechanism as buffered
3993baeb3c52f4 Darrick J. Wong 2016-10-03 86 * writes.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 87 *
5eda43000064a6 Darrick J. Wong 2017-02-02 88 * Just prior to submitting the actual disk write requests, we convert
5eda43000064a6 Darrick J. Wong 2017-02-02 89 * the extents representing the range of the file actually being written
5eda43000064a6 Darrick J. Wong 2017-02-02 90 * (as opposed to extra pieces created for the cowextsize hint) to real
5eda43000064a6 Darrick J. Wong 2017-02-02 91 * extents. This will become important in the next step:
5eda43000064a6 Darrick J. Wong 2017-02-02 92 *
5eda43000064a6 Darrick J. Wong 2017-02-02 93 * D: --RRRRRRSSSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 94 * C: ------UUrrUUU---------
5eda43000064a6 Darrick J. Wong 2017-02-02 95 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 96 * CoW remapping must be done after the data block write completes,
3993baeb3c52f4 Darrick J. Wong 2016-10-03 97 * because we don't want to destroy the old data fork map until we're sure
3993baeb3c52f4 Darrick J. Wong 2016-10-03 98 * the new block has been written. Since the new mappings are kept in a
3993baeb3c52f4 Darrick J. Wong 2016-10-03 99 * separate fork, we can simply iterate these mappings to find the ones
3993baeb3c52f4 Darrick J. Wong 2016-10-03 100 * that cover the file blocks that we just CoW'd. For each extent, simply
3993baeb3c52f4 Darrick J. Wong 2016-10-03 101 * unmap the corresponding range in the data fork, map the new range into
5eda43000064a6 Darrick J. Wong 2017-02-02 102 * the data fork, and remove the extent from the CoW fork. Because of
5eda43000064a6 Darrick J. Wong 2017-02-02 103 * the presence of the cowextsize hint, however, we must be careful
5eda43000064a6 Darrick J. Wong 2017-02-02 104 * only to remap the blocks that we've actually written out -- we must
5eda43000064a6 Darrick J. Wong 2017-02-02 105 * never remap delalloc reservations nor CoW staging blocks that have
5eda43000064a6 Darrick J. Wong 2017-02-02 106 * yet to be written. This corresponds exactly to the real extents in
5eda43000064a6 Darrick J. Wong 2017-02-02 107 * the CoW fork:
5eda43000064a6 Darrick J. Wong 2017-02-02 108 *
5eda43000064a6 Darrick J. Wong 2017-02-02 109 * D: --RRRRRRrrSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 110 * C: ------UU--UUU---------
3993baeb3c52f4 Darrick J. Wong 2016-10-03 111 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 112 * Since the remapping operation can be applied to an arbitrary file
3993baeb3c52f4 Darrick J. Wong 2016-10-03 113 * range, we record the need for the remap step as a flag in the ioend
3993baeb3c52f4 Darrick J. Wong 2016-10-03 114 * instead of declaring a new IO type. This is required for direct io
3993baeb3c52f4 Darrick J. Wong 2016-10-03 115 * because we only have ioend for the whole dio, and we have to be able to
3993baeb3c52f4 Darrick J. Wong 2016-10-03 116 * remember the presence of unwritten blocks and CoW blocks with a single
3993baeb3c52f4 Darrick J. Wong 2016-10-03 117 * ioend structure. Better yet, the more ground we can cover with one
3993baeb3c52f4 Darrick J. Wong 2016-10-03 118 * ioend, the better.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 119 */
2a06705cd59540 Darrick J. Wong 2016-10-03 120
2a06705cd59540 Darrick J. Wong 2016-10-03 121 /*
2a06705cd59540 Darrick J. Wong 2016-10-03 122 * Given an AG extent, find the lowest-numbered run of shared blocks
2a06705cd59540 Darrick J. Wong 2016-10-03 123 * within that range and return the range in fbno/flen. If
2a06705cd59540 Darrick J. Wong 2016-10-03 124 * find_end_of_shared is true, return the longest contiguous extent of
2a06705cd59540 Darrick J. Wong 2016-10-03 125 * shared blocks. If there are no shared extents, fbno and flen will
2a06705cd59540 Darrick J. Wong 2016-10-03 126 * be set to NULLAGBLOCK and 0, respectively.
2a06705cd59540 Darrick J. Wong 2016-10-03 127 */
2a06705cd59540 Darrick J. Wong 2016-10-03 128 int
2a06705cd59540 Darrick J. Wong 2016-10-03 @129 xfs_reflink_find_shared(
87045504fb13d6 Dave Chinner 2022-06-11 130 struct xfs_perag *pag,
92ff7285f1df55 Darrick J. Wong 2017-06-16 131 struct xfs_trans *tp,
2a06705cd59540 Darrick J. Wong 2016-10-03 132 xfs_agblock_t agbno,
2a06705cd59540 Darrick J. Wong 2016-10-03 133 xfs_extlen_t aglen,
2a06705cd59540 Darrick J. Wong 2016-10-03 134 xfs_agblock_t *fbno,
2a06705cd59540 Darrick J. Wong 2016-10-03 135 xfs_extlen_t *flen,
2a06705cd59540 Darrick J. Wong 2016-10-03 136 bool find_end_of_shared)
2a06705cd59540 Darrick J. Wong 2016-10-03 137 {
2a06705cd59540 Darrick J. Wong 2016-10-03 138 struct xfs_buf *agbp;
2a06705cd59540 Darrick J. Wong 2016-10-03 139 struct xfs_btree_cur *cur;
2a06705cd59540 Darrick J. Wong 2016-10-03 140 int error;
2a06705cd59540 Darrick J. Wong 2016-10-03 141
87045504fb13d6 Dave Chinner 2022-06-11 142 error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
2a06705cd59540 Darrick J. Wong 2016-10-03 143 if (error)
2a06705cd59540 Darrick J. Wong 2016-10-03 144 return error;
2a06705cd59540 Darrick J. Wong 2016-10-03 145
87045504fb13d6 Dave Chinner 2022-06-11 146 cur = xfs_refcountbt_init_cursor(pag->pag_mount, tp, agbp, pag);
2a06705cd59540 Darrick J. Wong 2016-10-03 147
2a06705cd59540 Darrick J. Wong 2016-10-03 148 error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen,
2a06705cd59540 Darrick J. Wong 2016-10-03 149 find_end_of_shared);
2a06705cd59540 Darrick J. Wong 2016-10-03 150
0b04b6b875b32f Darrick J. Wong 2018-07-19 151 xfs_btree_del_cursor(cur, error);
2a06705cd59540 Darrick J. Wong 2016-10-03 152
92ff7285f1df55 Darrick J. Wong 2017-06-16 153 xfs_trans_brelse(tp, agbp);
2a06705cd59540 Darrick J. Wong 2016-10-03 154 return error;
2a06705cd59540 Darrick J. Wong 2016-10-03 155 }
2a06705cd59540 Darrick J. Wong 2016-10-03 156
Hi Dave,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on v5.19-rc1]
[also build test WARNING on next-20220610]
[cannot apply to xfs-linux/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
base: f2906aa863381afb0015a9eb7fefad885d4e5a56
config: hexagon-randconfig-r012-20220611 (https://download.01.org/0day-ci/archive/20220611/202206111958.cftnGbOr-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project ff4abe755279a3a47cc416ef80dbc900d9a98a19)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/87045504fb13d6263ddf1d7780eef5eda1cee6ad
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
git checkout 87045504fb13d6263ddf1d7780eef5eda1cee6ad
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash fs/xfs/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> fs/xfs/xfs_reflink.c:129:1: warning: no previous prototype for function 'xfs_reflink_find_shared' [-Wmissing-prototypes]
xfs_reflink_find_shared(
^
fs/xfs/xfs_reflink.c:128:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int
^
static
fs/xfs/xfs_reflink.c:1029:12: warning: variable 'qdelta' set but not used [-Wunused-but-set-variable]
int64_t qdelta = 0;
^
2 warnings generated.
vim +/xfs_reflink_find_shared +129 fs/xfs/xfs_reflink.c
3993baeb3c52f4 Darrick J. Wong 2016-10-03 32
3993baeb3c52f4 Darrick J. Wong 2016-10-03 33 /*
3993baeb3c52f4 Darrick J. Wong 2016-10-03 34 * Copy on Write of Shared Blocks
3993baeb3c52f4 Darrick J. Wong 2016-10-03 35 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 36 * XFS must preserve "the usual" file semantics even when two files share
3993baeb3c52f4 Darrick J. Wong 2016-10-03 37 * the same physical blocks. This means that a write to one file must not
3993baeb3c52f4 Darrick J. Wong 2016-10-03 38 * alter the blocks in a different file; the way that we'll do that is
3993baeb3c52f4 Darrick J. Wong 2016-10-03 39 * through the use of a copy-on-write mechanism. At a high level, that
3993baeb3c52f4 Darrick J. Wong 2016-10-03 40 * means that when we want to write to a shared block, we allocate a new
3993baeb3c52f4 Darrick J. Wong 2016-10-03 41 * block, write the data to the new block, and if that succeeds we map the
3993baeb3c52f4 Darrick J. Wong 2016-10-03 42 * new block into the file.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 43 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 44 * XFS provides a "delayed allocation" mechanism that defers the allocation
3993baeb3c52f4 Darrick J. Wong 2016-10-03 45 * of disk blocks to dirty-but-not-yet-mapped file blocks as long as
3993baeb3c52f4 Darrick J. Wong 2016-10-03 46 * possible. This reduces fragmentation by enabling the filesystem to ask
3993baeb3c52f4 Darrick J. Wong 2016-10-03 47 * for bigger chunks less often, which is exactly what we want for CoW.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 48 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 49 * The delalloc mechanism begins when the kernel wants to make a block
3993baeb3c52f4 Darrick J. Wong 2016-10-03 50 * writable (write_begin or page_mkwrite). If the offset is not mapped, we
3993baeb3c52f4 Darrick J. Wong 2016-10-03 51 * create a delalloc mapping, which is a regular in-core extent, but without
3993baeb3c52f4 Darrick J. Wong 2016-10-03 52 * a real startblock. (For delalloc mappings, the startblock encodes both
3993baeb3c52f4 Darrick J. Wong 2016-10-03 53 * a flag that this is a delalloc mapping, and a worst-case estimate of how
3993baeb3c52f4 Darrick J. Wong 2016-10-03 54 * many blocks might be required to put the mapping into the BMBT.) delalloc
3993baeb3c52f4 Darrick J. Wong 2016-10-03 55 * mappings are a reservation against the free space in the filesystem;
3993baeb3c52f4 Darrick J. Wong 2016-10-03 56 * adjacent mappings can also be combined into fewer larger mappings.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 57 *
5eda43000064a6 Darrick J. Wong 2017-02-02 58 * As an optimization, the CoW extent size hint (cowextsz) creates
5eda43000064a6 Darrick J. Wong 2017-02-02 59 * outsized aligned delalloc reservations in the hope of landing out of
5eda43000064a6 Darrick J. Wong 2017-02-02 60 * order nearby CoW writes in a single extent on disk, thereby reducing
5eda43000064a6 Darrick J. Wong 2017-02-02 61 * fragmentation and improving future performance.
5eda43000064a6 Darrick J. Wong 2017-02-02 62 *
5eda43000064a6 Darrick J. Wong 2017-02-02 63 * D: --RRRRRRSSSRRRRRRRR--- (data fork)
5eda43000064a6 Darrick J. Wong 2017-02-02 64 * C: ------DDDDDDD--------- (CoW fork)
5eda43000064a6 Darrick J. Wong 2017-02-02 65 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 66 * When dirty pages are being written out (typically in writepage), the
5eda43000064a6 Darrick J. Wong 2017-02-02 67 * delalloc reservations are converted into unwritten mappings by
5eda43000064a6 Darrick J. Wong 2017-02-02 68 * allocating blocks and replacing the delalloc mapping with real ones.
5eda43000064a6 Darrick J. Wong 2017-02-02 69 * A delalloc mapping can be replaced by several unwritten ones if the
5eda43000064a6 Darrick J. Wong 2017-02-02 70 * free space is fragmented.
5eda43000064a6 Darrick J. Wong 2017-02-02 71 *
5eda43000064a6 Darrick J. Wong 2017-02-02 72 * D: --RRRRRRSSSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 73 * C: ------UUUUUUU---------
3993baeb3c52f4 Darrick J. Wong 2016-10-03 74 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 75 * We want to adapt the delalloc mechanism for copy-on-write, since the
3993baeb3c52f4 Darrick J. Wong 2016-10-03 76 * write paths are similar. The first two steps (creating the reservation
3993baeb3c52f4 Darrick J. Wong 2016-10-03 77 * and allocating the blocks) are exactly the same as delalloc except that
3993baeb3c52f4 Darrick J. Wong 2016-10-03 78 * the mappings must be stored in a separate CoW fork because we do not want
3993baeb3c52f4 Darrick J. Wong 2016-10-03 79 * to disturb the mapping in the data fork until we're sure that the write
3993baeb3c52f4 Darrick J. Wong 2016-10-03 80 * succeeded. IO completion in this case is the process of removing the old
3993baeb3c52f4 Darrick J. Wong 2016-10-03 81 * mapping from the data fork and moving the new mapping from the CoW fork to
3993baeb3c52f4 Darrick J. Wong 2016-10-03 82 * the data fork. This will be discussed shortly.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 83 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 84 * For now, unaligned directio writes will be bounced back to the page cache.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 85 * Block-aligned directio writes will use the same mechanism as buffered
3993baeb3c52f4 Darrick J. Wong 2016-10-03 86 * writes.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 87 *
5eda43000064a6 Darrick J. Wong 2017-02-02 88 * Just prior to submitting the actual disk write requests, we convert
5eda43000064a6 Darrick J. Wong 2017-02-02 89 * the extents representing the range of the file actually being written
5eda43000064a6 Darrick J. Wong 2017-02-02 90 * (as opposed to extra pieces created for the cowextsize hint) to real
5eda43000064a6 Darrick J. Wong 2017-02-02 91 * extents. This will become important in the next step:
5eda43000064a6 Darrick J. Wong 2017-02-02 92 *
5eda43000064a6 Darrick J. Wong 2017-02-02 93 * D: --RRRRRRSSSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 94 * C: ------UUrrUUU---------
5eda43000064a6 Darrick J. Wong 2017-02-02 95 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 96 * CoW remapping must be done after the data block write completes,
3993baeb3c52f4 Darrick J. Wong 2016-10-03 97 * because we don't want to destroy the old data fork map until we're sure
3993baeb3c52f4 Darrick J. Wong 2016-10-03 98 * the new block has been written. Since the new mappings are kept in a
3993baeb3c52f4 Darrick J. Wong 2016-10-03 99 * separate fork, we can simply iterate these mappings to find the ones
3993baeb3c52f4 Darrick J. Wong 2016-10-03 100 * that cover the file blocks that we just CoW'd. For each extent, simply
3993baeb3c52f4 Darrick J. Wong 2016-10-03 101 * unmap the corresponding range in the data fork, map the new range into
5eda43000064a6 Darrick J. Wong 2017-02-02 102 * the data fork, and remove the extent from the CoW fork. Because of
5eda43000064a6 Darrick J. Wong 2017-02-02 103 * the presence of the cowextsize hint, however, we must be careful
5eda43000064a6 Darrick J. Wong 2017-02-02 104 * only to remap the blocks that we've actually written out -- we must
5eda43000064a6 Darrick J. Wong 2017-02-02 105 * never remap delalloc reservations nor CoW staging blocks that have
5eda43000064a6 Darrick J. Wong 2017-02-02 106 * yet to be written. This corresponds exactly to the real extents in
5eda43000064a6 Darrick J. Wong 2017-02-02 107 * the CoW fork:
5eda43000064a6 Darrick J. Wong 2017-02-02 108 *
5eda43000064a6 Darrick J. Wong 2017-02-02 109 * D: --RRRRRRrrSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 110 * C: ------UU--UUU---------
3993baeb3c52f4 Darrick J. Wong 2016-10-03 111 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 112 * Since the remapping operation can be applied to an arbitrary file
3993baeb3c52f4 Darrick J. Wong 2016-10-03 113 * range, we record the need for the remap step as a flag in the ioend
3993baeb3c52f4 Darrick J. Wong 2016-10-03 114 * instead of declaring a new IO type. This is required for direct io
3993baeb3c52f4 Darrick J. Wong 2016-10-03 115 * because we only have ioend for the whole dio, and we have to be able to
3993baeb3c52f4 Darrick J. Wong 2016-10-03 116 * remember the presence of unwritten blocks and CoW blocks with a single
3993baeb3c52f4 Darrick J. Wong 2016-10-03 117 * ioend structure. Better yet, the more ground we can cover with one
3993baeb3c52f4 Darrick J. Wong 2016-10-03 118 * ioend, the better.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 119 */
2a06705cd59540 Darrick J. Wong 2016-10-03 120
2a06705cd59540 Darrick J. Wong 2016-10-03 121 /*
2a06705cd59540 Darrick J. Wong 2016-10-03 122 * Given an AG extent, find the lowest-numbered run of shared blocks
2a06705cd59540 Darrick J. Wong 2016-10-03 123 * within that range and return the range in fbno/flen. If
2a06705cd59540 Darrick J. Wong 2016-10-03 124 * find_end_of_shared is true, return the longest contiguous extent of
2a06705cd59540 Darrick J. Wong 2016-10-03 125 * shared blocks. If there are no shared extents, fbno and flen will
2a06705cd59540 Darrick J. Wong 2016-10-03 126 * be set to NULLAGBLOCK and 0, respectively.
2a06705cd59540 Darrick J. Wong 2016-10-03 127 */
2a06705cd59540 Darrick J. Wong 2016-10-03 128 int
2a06705cd59540 Darrick J. Wong 2016-10-03 @129 xfs_reflink_find_shared(
87045504fb13d6 Dave Chinner 2022-06-11 130 struct xfs_perag *pag,
92ff7285f1df55 Darrick J. Wong 2017-06-16 131 struct xfs_trans *tp,
2a06705cd59540 Darrick J. Wong 2016-10-03 132 xfs_agblock_t agbno,
2a06705cd59540 Darrick J. Wong 2016-10-03 133 xfs_extlen_t aglen,
2a06705cd59540 Darrick J. Wong 2016-10-03 134 xfs_agblock_t *fbno,
2a06705cd59540 Darrick J. Wong 2016-10-03 135 xfs_extlen_t *flen,
2a06705cd59540 Darrick J. Wong 2016-10-03 136 bool find_end_of_shared)
2a06705cd59540 Darrick J. Wong 2016-10-03 137 {
2a06705cd59540 Darrick J. Wong 2016-10-03 138 struct xfs_buf *agbp;
2a06705cd59540 Darrick J. Wong 2016-10-03 139 struct xfs_btree_cur *cur;
2a06705cd59540 Darrick J. Wong 2016-10-03 140 int error;
2a06705cd59540 Darrick J. Wong 2016-10-03 141
87045504fb13d6 Dave Chinner 2022-06-11 142 error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
2a06705cd59540 Darrick J. Wong 2016-10-03 143 if (error)
2a06705cd59540 Darrick J. Wong 2016-10-03 144 return error;
2a06705cd59540 Darrick J. Wong 2016-10-03 145
87045504fb13d6 Dave Chinner 2022-06-11 146 cur = xfs_refcountbt_init_cursor(pag->pag_mount, tp, agbp, pag);
2a06705cd59540 Darrick J. Wong 2016-10-03 147
2a06705cd59540 Darrick J. Wong 2016-10-03 148 error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen,
2a06705cd59540 Darrick J. Wong 2016-10-03 149 find_end_of_shared);
2a06705cd59540 Darrick J. Wong 2016-10-03 150
0b04b6b875b32f Darrick J. Wong 2018-07-19 151 xfs_btree_del_cursor(cur, error);
2a06705cd59540 Darrick J. Wong 2016-10-03 152
92ff7285f1df55 Darrick J. Wong 2017-06-16 153 xfs_trans_brelse(tp, agbp);
2a06705cd59540 Darrick J. Wong 2016-10-03 154 return error;
2a06705cd59540 Darrick J. Wong 2016-10-03 155 }
2a06705cd59540 Darrick J. Wong 2016-10-03 156
Hi Dave,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on v5.19-rc1]
[also build test WARNING on next-20220610]
[cannot apply to xfs-linux/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
base: f2906aa863381afb0015a9eb7fefad885d4e5a56
config: sparc64-randconfig-r034-20220611 (https://download.01.org/0day-ci/archive/20220611/202206112144.aFBVTYv8-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/87045504fb13d6263ddf1d7780eef5eda1cee6ad
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
git checkout 87045504fb13d6263ddf1d7780eef5eda1cee6ad
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=sparc64 SHELL=/bin/bash fs/xfs/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
fs/xfs/scrub/repair.c: In function 'xrep_reap_block':
>> fs/xfs/scrub/repair.c:539:41: warning: variable 'agno' set but not used [-Wunused-but-set-variable]
539 | xfs_agnumber_t agno;
| ^~~~
vim +/agno +539 fs/xfs/scrub/repair.c
12c6510e2ff17cf Darrick J. Wong 2018-05-29 528
86d969b425d7ecf Darrick J. Wong 2018-07-30 529 /* Dispose of a single block. */
12c6510e2ff17cf Darrick J. Wong 2018-05-29 530 STATIC int
86d969b425d7ecf Darrick J. Wong 2018-07-30 531 xrep_reap_block(
1d8a748a8aa94a7 Darrick J. Wong 2018-07-19 532 struct xfs_scrub *sc,
12c6510e2ff17cf Darrick J. Wong 2018-05-29 533 xfs_fsblock_t fsbno,
66e3237e724c665 Darrick J. Wong 2018-12-12 534 const struct xfs_owner_info *oinfo,
12c6510e2ff17cf Darrick J. Wong 2018-05-29 535 enum xfs_ag_resv_type resv)
12c6510e2ff17cf Darrick J. Wong 2018-05-29 536 {
12c6510e2ff17cf Darrick J. Wong 2018-05-29 537 struct xfs_btree_cur *cur;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 538 struct xfs_buf *agf_bp = NULL;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 @539 xfs_agnumber_t agno;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 540 xfs_agblock_t agbno;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 541 bool has_other_rmap;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 542 int error;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 543
12c6510e2ff17cf Darrick J. Wong 2018-05-29 544 agno = XFS_FSB_TO_AGNO(sc->mp, fsbno);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 545 agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno);
87045504fb13d62 Dave Chinner 2022-06-11 546 ASSERT(agno == sc->sa.pag->pag_agno);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 547
12c6510e2ff17cf Darrick J. Wong 2018-05-29 548 /*
12c6510e2ff17cf Darrick J. Wong 2018-05-29 549 * If we are repairing per-inode metadata, we need to read in the AGF
12c6510e2ff17cf Darrick J. Wong 2018-05-29 550 * buffer. Otherwise, we're repairing a per-AG structure, so reuse
12c6510e2ff17cf Darrick J. Wong 2018-05-29 551 * the AGF buffer that the setup functions already grabbed.
12c6510e2ff17cf Darrick J. Wong 2018-05-29 552 */
12c6510e2ff17cf Darrick J. Wong 2018-05-29 553 if (sc->ip) {
87045504fb13d62 Dave Chinner 2022-06-11 554 error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 555 if (error)
12c6510e2ff17cf Darrick J. Wong 2018-05-29 556 return error;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 557 } else {
12c6510e2ff17cf Darrick J. Wong 2018-05-29 558 agf_bp = sc->sa.agf_bp;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 559 }
fa9c3c197329fda Dave Chinner 2021-06-02 560 cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, agf_bp, sc->sa.pag);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 561
12c6510e2ff17cf Darrick J. Wong 2018-05-29 562 /* Can we find any other rmappings? */
12c6510e2ff17cf Darrick J. Wong 2018-05-29 563 error = xfs_rmap_has_other_keys(cur, agbno, 1, oinfo, &has_other_rmap);
ef97ef26d263fb6 Darrick J. Wong 2018-07-19 564 xfs_btree_del_cursor(cur, error);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 565 if (error)
ef97ef26d263fb6 Darrick J. Wong 2018-07-19 566 goto out_free;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 567
12c6510e2ff17cf Darrick J. Wong 2018-05-29 568 /*
12c6510e2ff17cf Darrick J. Wong 2018-05-29 569 * If there are other rmappings, this block is cross linked and must
12c6510e2ff17cf Darrick J. Wong 2018-05-29 570 * not be freed. Remove the reverse mapping and move on. Otherwise,
12c6510e2ff17cf Darrick J. Wong 2018-05-29 571 * we were the only owner of the block, so free the extent, which will
12c6510e2ff17cf Darrick J. Wong 2018-05-29 572 * also remove the rmap.
12c6510e2ff17cf Darrick J. Wong 2018-05-29 573 *
12c6510e2ff17cf Darrick J. Wong 2018-05-29 574 * XXX: XFS doesn't support detecting the case where a single block
12c6510e2ff17cf Darrick J. Wong 2018-05-29 575 * metadata structure is crosslinked with a multi-block structure
12c6510e2ff17cf Darrick J. Wong 2018-05-29 576 * because the buffer cache doesn't detect aliasing problems, so we
12c6510e2ff17cf Darrick J. Wong 2018-05-29 577 * can't fix 100% of crosslinking problems (yet). The verifiers will
12c6510e2ff17cf Darrick J. Wong 2018-05-29 578 * blow on writeout, the filesystem will shut down, and the admin gets
12c6510e2ff17cf Darrick J. Wong 2018-05-29 579 * to run xfs_repair.
12c6510e2ff17cf Darrick J. Wong 2018-05-29 580 */
12c6510e2ff17cf Darrick J. Wong 2018-05-29 581 if (has_other_rmap)
fa9c3c197329fda Dave Chinner 2021-06-02 582 error = xfs_rmap_free(sc->tp, agf_bp, sc->sa.pag, agbno,
fa9c3c197329fda Dave Chinner 2021-06-02 583 1, oinfo);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 584 else if (resv == XFS_AG_RESV_AGFL)
b5e2196e9c72173 Darrick J. Wong 2018-07-19 585 error = xrep_put_freelist(sc, agbno);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 586 else
12c6510e2ff17cf Darrick J. Wong 2018-05-29 587 error = xfs_free_extent(sc->tp, fsbno, 1, oinfo, resv);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 588 if (agf_bp != sc->sa.agf_bp)
12c6510e2ff17cf Darrick J. Wong 2018-05-29 589 xfs_trans_brelse(sc->tp, agf_bp);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 590 if (error)
12c6510e2ff17cf Darrick J. Wong 2018-05-29 591 return error;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 592
12c6510e2ff17cf Darrick J. Wong 2018-05-29 593 if (sc->ip)
12c6510e2ff17cf Darrick J. Wong 2018-05-29 594 return xfs_trans_roll_inode(&sc->tp, sc->ip);
b5e2196e9c72173 Darrick J. Wong 2018-07-19 595 return xrep_roll_ag_trans(sc);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 596
ef97ef26d263fb6 Darrick J. Wong 2018-07-19 597 out_free:
12c6510e2ff17cf Darrick J. Wong 2018-05-29 598 if (agf_bp != sc->sa.agf_bp)
12c6510e2ff17cf Darrick J. Wong 2018-05-29 599 xfs_trans_brelse(sc->tp, agf_bp);
12c6510e2ff17cf Darrick J. Wong 2018-05-29 600 return error;
12c6510e2ff17cf Darrick J. Wong 2018-05-29 601 }
12c6510e2ff17cf Darrick J. Wong 2018-05-29 602
Hi Dave,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on v5.19-rc1]
[also build test WARNING on next-20220614]
[cannot apply to xfs-linux/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
base: f2906aa863381afb0015a9eb7fefad885d4e5a56
config: arc-randconfig-s032-20220613 (https://download.01.org/0day-ci/archive/20220614/202206142004.Tnmd1NbS-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 11.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-30-g92122700-dirty
# https://github.com/intel-lab-lkp/linux/commit/87045504fb13d6263ddf1d7780eef5eda1cee6ad
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Dave-Chinner/xfs-per-ag-centric-allocation-alogrithms/20220611-093037
git checkout 87045504fb13d6263ddf1d7780eef5eda1cee6ad
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arc SHELL=/bin/bash fs/xfs/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> fs/xfs/xfs_reflink.c:129:1: sparse: sparse: symbol 'xfs_reflink_find_shared' was not declared. Should it be static?
vim +/xfs_reflink_find_shared +129 fs/xfs/xfs_reflink.c
3993baeb3c52f4 Darrick J. Wong 2016-10-03 32
3993baeb3c52f4 Darrick J. Wong 2016-10-03 33 /*
3993baeb3c52f4 Darrick J. Wong 2016-10-03 34 * Copy on Write of Shared Blocks
3993baeb3c52f4 Darrick J. Wong 2016-10-03 35 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 36 * XFS must preserve "the usual" file semantics even when two files share
3993baeb3c52f4 Darrick J. Wong 2016-10-03 37 * the same physical blocks. This means that a write to one file must not
3993baeb3c52f4 Darrick J. Wong 2016-10-03 38 * alter the blocks in a different file; the way that we'll do that is
3993baeb3c52f4 Darrick J. Wong 2016-10-03 39 * through the use of a copy-on-write mechanism. At a high level, that
3993baeb3c52f4 Darrick J. Wong 2016-10-03 40 * means that when we want to write to a shared block, we allocate a new
3993baeb3c52f4 Darrick J. Wong 2016-10-03 41 * block, write the data to the new block, and if that succeeds we map the
3993baeb3c52f4 Darrick J. Wong 2016-10-03 42 * new block into the file.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 43 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 44 * XFS provides a "delayed allocation" mechanism that defers the allocation
3993baeb3c52f4 Darrick J. Wong 2016-10-03 45 * of disk blocks to dirty-but-not-yet-mapped file blocks as long as
3993baeb3c52f4 Darrick J. Wong 2016-10-03 46 * possible. This reduces fragmentation by enabling the filesystem to ask
3993baeb3c52f4 Darrick J. Wong 2016-10-03 47 * for bigger chunks less often, which is exactly what we want for CoW.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 48 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 49 * The delalloc mechanism begins when the kernel wants to make a block
3993baeb3c52f4 Darrick J. Wong 2016-10-03 50 * writable (write_begin or page_mkwrite). If the offset is not mapped, we
3993baeb3c52f4 Darrick J. Wong 2016-10-03 51 * create a delalloc mapping, which is a regular in-core extent, but without
3993baeb3c52f4 Darrick J. Wong 2016-10-03 52 * a real startblock. (For delalloc mappings, the startblock encodes both
3993baeb3c52f4 Darrick J. Wong 2016-10-03 53 * a flag that this is a delalloc mapping, and a worst-case estimate of how
3993baeb3c52f4 Darrick J. Wong 2016-10-03 54 * many blocks might be required to put the mapping into the BMBT.) delalloc
3993baeb3c52f4 Darrick J. Wong 2016-10-03 55 * mappings are a reservation against the free space in the filesystem;
3993baeb3c52f4 Darrick J. Wong 2016-10-03 56 * adjacent mappings can also be combined into fewer larger mappings.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 57 *
5eda43000064a6 Darrick J. Wong 2017-02-02 58 * As an optimization, the CoW extent size hint (cowextsz) creates
5eda43000064a6 Darrick J. Wong 2017-02-02 59 * outsized aligned delalloc reservations in the hope of landing out of
5eda43000064a6 Darrick J. Wong 2017-02-02 60 * order nearby CoW writes in a single extent on disk, thereby reducing
5eda43000064a6 Darrick J. Wong 2017-02-02 61 * fragmentation and improving future performance.
5eda43000064a6 Darrick J. Wong 2017-02-02 62 *
5eda43000064a6 Darrick J. Wong 2017-02-02 63 * D: --RRRRRRSSSRRRRRRRR--- (data fork)
5eda43000064a6 Darrick J. Wong 2017-02-02 64 * C: ------DDDDDDD--------- (CoW fork)
5eda43000064a6 Darrick J. Wong 2017-02-02 65 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 66 * When dirty pages are being written out (typically in writepage), the
5eda43000064a6 Darrick J. Wong 2017-02-02 67 * delalloc reservations are converted into unwritten mappings by
5eda43000064a6 Darrick J. Wong 2017-02-02 68 * allocating blocks and replacing the delalloc mapping with real ones.
5eda43000064a6 Darrick J. Wong 2017-02-02 69 * A delalloc mapping can be replaced by several unwritten ones if the
5eda43000064a6 Darrick J. Wong 2017-02-02 70 * free space is fragmented.
5eda43000064a6 Darrick J. Wong 2017-02-02 71 *
5eda43000064a6 Darrick J. Wong 2017-02-02 72 * D: --RRRRRRSSSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 73 * C: ------UUUUUUU---------
3993baeb3c52f4 Darrick J. Wong 2016-10-03 74 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 75 * We want to adapt the delalloc mechanism for copy-on-write, since the
3993baeb3c52f4 Darrick J. Wong 2016-10-03 76 * write paths are similar. The first two steps (creating the reservation
3993baeb3c52f4 Darrick J. Wong 2016-10-03 77 * and allocating the blocks) are exactly the same as delalloc except that
3993baeb3c52f4 Darrick J. Wong 2016-10-03 78 * the mappings must be stored in a separate CoW fork because we do not want
3993baeb3c52f4 Darrick J. Wong 2016-10-03 79 * to disturb the mapping in the data fork until we're sure that the write
3993baeb3c52f4 Darrick J. Wong 2016-10-03 80 * succeeded. IO completion in this case is the process of removing the old
3993baeb3c52f4 Darrick J. Wong 2016-10-03 81 * mapping from the data fork and moving the new mapping from the CoW fork to
3993baeb3c52f4 Darrick J. Wong 2016-10-03 82 * the data fork. This will be discussed shortly.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 83 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 84 * For now, unaligned directio writes will be bounced back to the page cache.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 85 * Block-aligned directio writes will use the same mechanism as buffered
3993baeb3c52f4 Darrick J. Wong 2016-10-03 86 * writes.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 87 *
5eda43000064a6 Darrick J. Wong 2017-02-02 88 * Just prior to submitting the actual disk write requests, we convert
5eda43000064a6 Darrick J. Wong 2017-02-02 89 * the extents representing the range of the file actually being written
5eda43000064a6 Darrick J. Wong 2017-02-02 90 * (as opposed to extra pieces created for the cowextsize hint) to real
5eda43000064a6 Darrick J. Wong 2017-02-02 91 * extents. This will become important in the next step:
5eda43000064a6 Darrick J. Wong 2017-02-02 92 *
5eda43000064a6 Darrick J. Wong 2017-02-02 93 * D: --RRRRRRSSSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 94 * C: ------UUrrUUU---------
5eda43000064a6 Darrick J. Wong 2017-02-02 95 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 96 * CoW remapping must be done after the data block write completes,
3993baeb3c52f4 Darrick J. Wong 2016-10-03 97 * because we don't want to destroy the old data fork map until we're sure
3993baeb3c52f4 Darrick J. Wong 2016-10-03 98 * the new block has been written. Since the new mappings are kept in a
3993baeb3c52f4 Darrick J. Wong 2016-10-03 99 * separate fork, we can simply iterate these mappings to find the ones
3993baeb3c52f4 Darrick J. Wong 2016-10-03 100 * that cover the file blocks that we just CoW'd. For each extent, simply
3993baeb3c52f4 Darrick J. Wong 2016-10-03 101 * unmap the corresponding range in the data fork, map the new range into
5eda43000064a6 Darrick J. Wong 2017-02-02 102 * the data fork, and remove the extent from the CoW fork. Because of
5eda43000064a6 Darrick J. Wong 2017-02-02 103 * the presence of the cowextsize hint, however, we must be careful
5eda43000064a6 Darrick J. Wong 2017-02-02 104 * only to remap the blocks that we've actually written out -- we must
5eda43000064a6 Darrick J. Wong 2017-02-02 105 * never remap delalloc reservations nor CoW staging blocks that have
5eda43000064a6 Darrick J. Wong 2017-02-02 106 * yet to be written. This corresponds exactly to the real extents in
5eda43000064a6 Darrick J. Wong 2017-02-02 107 * the CoW fork:
5eda43000064a6 Darrick J. Wong 2017-02-02 108 *
5eda43000064a6 Darrick J. Wong 2017-02-02 109 * D: --RRRRRRrrSRRRRRRRR---
5eda43000064a6 Darrick J. Wong 2017-02-02 110 * C: ------UU--UUU---------
3993baeb3c52f4 Darrick J. Wong 2016-10-03 111 *
3993baeb3c52f4 Darrick J. Wong 2016-10-03 112 * Since the remapping operation can be applied to an arbitrary file
3993baeb3c52f4 Darrick J. Wong 2016-10-03 113 * range, we record the need for the remap step as a flag in the ioend
3993baeb3c52f4 Darrick J. Wong 2016-10-03 114 * instead of declaring a new IO type. This is required for direct io
3993baeb3c52f4 Darrick J. Wong 2016-10-03 115 * because we only have ioend for the whole dio, and we have to be able to
3993baeb3c52f4 Darrick J. Wong 2016-10-03 116 * remember the presence of unwritten blocks and CoW blocks with a single
3993baeb3c52f4 Darrick J. Wong 2016-10-03 117 * ioend structure. Better yet, the more ground we can cover with one
3993baeb3c52f4 Darrick J. Wong 2016-10-03 118 * ioend, the better.
3993baeb3c52f4 Darrick J. Wong 2016-10-03 119 */
2a06705cd59540 Darrick J. Wong 2016-10-03 120
2a06705cd59540 Darrick J. Wong 2016-10-03 121 /*
2a06705cd59540 Darrick J. Wong 2016-10-03 122 * Given an AG extent, find the lowest-numbered run of shared blocks
2a06705cd59540 Darrick J. Wong 2016-10-03 123 * within that range and return the range in fbno/flen. If
2a06705cd59540 Darrick J. Wong 2016-10-03 124 * find_end_of_shared is true, return the longest contiguous extent of
2a06705cd59540 Darrick J. Wong 2016-10-03 125 * shared blocks. If there are no shared extents, fbno and flen will
2a06705cd59540 Darrick J. Wong 2016-10-03 126 * be set to NULLAGBLOCK and 0, respectively.
2a06705cd59540 Darrick J. Wong 2016-10-03 127 */
2a06705cd59540 Darrick J. Wong 2016-10-03 128 int
2a06705cd59540 Darrick J. Wong 2016-10-03 @129 xfs_reflink_find_shared(
87045504fb13d6 Dave Chinner 2022-06-11 130 struct xfs_perag *pag,
92ff7285f1df55 Darrick J. Wong 2017-06-16 131 struct xfs_trans *tp,
2a06705cd59540 Darrick J. Wong 2016-10-03 132 xfs_agblock_t agbno,
2a06705cd59540 Darrick J. Wong 2016-10-03 133 xfs_extlen_t aglen,
2a06705cd59540 Darrick J. Wong 2016-10-03 134 xfs_agblock_t *fbno,
2a06705cd59540 Darrick J. Wong 2016-10-03 135 xfs_extlen_t *flen,
2a06705cd59540 Darrick J. Wong 2016-10-03 136 bool find_end_of_shared)
2a06705cd59540 Darrick J. Wong 2016-10-03 137 {
2a06705cd59540 Darrick J. Wong 2016-10-03 138 struct xfs_buf *agbp;
2a06705cd59540 Darrick J. Wong 2016-10-03 139 struct xfs_btree_cur *cur;
2a06705cd59540 Darrick J. Wong 2016-10-03 140 int error;
2a06705cd59540 Darrick J. Wong 2016-10-03 141
87045504fb13d6 Dave Chinner 2022-06-11 142 error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
2a06705cd59540 Darrick J. Wong 2016-10-03 143 if (error)
2a06705cd59540 Darrick J. Wong 2016-10-03 144 return error;
2a06705cd59540 Darrick J. Wong 2016-10-03 145
87045504fb13d6 Dave Chinner 2022-06-11 146 cur = xfs_refcountbt_init_cursor(pag->pag_mount, tp, agbp, pag);
2a06705cd59540 Darrick J. Wong 2016-10-03 147
2a06705cd59540 Darrick J. Wong 2016-10-03 148 error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen,
2a06705cd59540 Darrick J. Wong 2016-10-03 149 find_end_of_shared);
2a06705cd59540 Darrick J. Wong 2016-10-03 150
0b04b6b875b32f Darrick J. Wong 2018-07-19 151 xfs_btree_del_cursor(cur, error);
2a06705cd59540 Darrick J. Wong 2016-10-03 152
92ff7285f1df55 Darrick J. Wong 2017-06-16 153 xfs_trans_brelse(tp, agbp);
2a06705cd59540 Darrick J. Wong 2016-10-03 154 return error;
2a06705cd59540 Darrick J. Wong 2016-10-03 155 }
2a06705cd59540 Darrick J. Wong 2016-10-03 156
On Sat, Jun 11, 2022 at 11:26:14AM +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@redhat.com> > > xfs_alloc_read_agf() initialises the perag if it hasn't been done > yet, so it makes sense to pass it the perag rather than pull a > reference from the buffer. This allows callers to be per-ag centric > rather than passing mount/agno pairs everywhere. > > Signed-off-by: Dave Chinner <dchinner@redhat.com> > --- > fs/xfs/libxfs/xfs_ag.c | 19 +++++++-------- > fs/xfs/libxfs/xfs_ag_resv.c | 2 +- > fs/xfs/libxfs/xfs_alloc.c | 30 ++++++++++------------- > fs/xfs/libxfs/xfs_alloc.h | 13 ++-------- > fs/xfs/libxfs/xfs_bmap.c | 2 +- > fs/xfs/libxfs/xfs_ialloc.c | 2 +- > fs/xfs/libxfs/xfs_refcount.c | 6 ++--- > fs/xfs/libxfs/xfs_refcount_btree.c | 2 +- > fs/xfs/libxfs/xfs_rmap_btree.c | 2 +- > fs/xfs/scrub/agheader_repair.c | 6 ++--- > fs/xfs/scrub/bmap.c | 2 +- > fs/xfs/scrub/common.c | 2 +- > fs/xfs/scrub/fscounters.c | 2 +- > fs/xfs/scrub/repair.c | 5 ++-- > fs/xfs/xfs_discard.c | 2 +- > fs/xfs/xfs_extfree_item.c | 6 ++++- > fs/xfs/xfs_filestream.c | 2 +- > fs/xfs/xfs_fsmap.c | 3 +-- > fs/xfs/xfs_reflink.c | 38 +++++++++++++++++------------- > fs/xfs/xfs_reflink.h | 3 --- > 20 files changed, 68 insertions(+), 81 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c > index 734ef170936e..c1a1c9f414c3 100644 > --- a/fs/xfs/libxfs/xfs_ag.c > +++ b/fs/xfs/libxfs/xfs_ag.c > @@ -120,16 +120,13 @@ xfs_initialize_perag_data( > > for (index = 0; index < agcount; index++) { > /* > - * read the agf, then the agi. This gets us > - * all the information we need and populates the > - * per-ag structures for us. > + * Read the AGF and AGI buffers to populate the per-ag > + * structures for us. > */ > - error = xfs_alloc_read_agf(mp, NULL, index, 0, NULL); > - if (error) > - return error; > - > pag = xfs_perag_get(mp, index); > - error = xfs_ialloc_read_agi(pag, NULL, NULL); > + error = xfs_alloc_read_agf(pag, NULL, 0, NULL); > + if (!error) > + error = xfs_ialloc_read_agi(pag, NULL, NULL); > if (error) { > xfs_perag_put(pag); > return error; > @@ -792,7 +789,7 @@ xfs_ag_shrink_space( > > agi = agibp->b_addr; > > - error = xfs_alloc_read_agf(mp, *tpp, pag->pag_agno, 0, &agfbp); > + error = xfs_alloc_read_agf(pag, *tpp, 0, &agfbp); > if (error) > return error; > > @@ -909,7 +906,7 @@ xfs_ag_extend_space( > /* > * Change agf length. > */ > - error = xfs_alloc_read_agf(pag->pag_mount, tp, pag->pag_agno, 0, &bp); > + error = xfs_alloc_read_agf(pag, tp, 0, &bp); > if (error) > return error; > > @@ -952,7 +949,7 @@ xfs_ag_get_geometry( > error = xfs_ialloc_read_agi(pag, NULL, &agi_bp); > if (error) > return error; > - error = xfs_alloc_read_agf(pag->pag_mount, NULL, pag->pag_agno, 0, &agf_bp); > + error = xfs_alloc_read_agf(pag, NULL, 0, &agf_bp); > if (error) > goto out_agi; > > diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c > index ce28bf8f72dc..5af123d13a63 100644 > --- a/fs/xfs/libxfs/xfs_ag_resv.c > +++ b/fs/xfs/libxfs/xfs_ag_resv.c > @@ -322,7 +322,7 @@ xfs_ag_resv_init( > * address. > */ > if (has_resv) { > - error2 = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, NULL); > + error2 = xfs_alloc_read_agf(pag, tp, 0, NULL); > if (error2) > return error2; > > diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c > index f7853ab7b962..5d6ca86c4882 100644 > --- a/fs/xfs/libxfs/xfs_alloc.c > +++ b/fs/xfs/libxfs/xfs_alloc.c > @@ -2609,7 +2609,7 @@ xfs_alloc_fix_freelist( > ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); > > if (!pag->pagf_init) { > - error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp); > + error = xfs_alloc_read_agf(pag, tp, flags, &agbp); > if (error) { > /* Couldn't lock the AGF so skip this AG. */ > if (error == -EAGAIN) > @@ -2639,7 +2639,7 @@ xfs_alloc_fix_freelist( > * Can fail if we're not blocking on locks, and it's held. > */ > if (!agbp) { > - error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp); > + error = xfs_alloc_read_agf(pag, tp, flags, &agbp); > if (error) { > /* Couldn't lock the AGF so skip this AG. */ > if (error == -EAGAIN) > @@ -3080,34 +3080,30 @@ xfs_read_agf( > * perag structure if necessary. If the caller provides @agfbpp, then return the > * locked buffer to the caller, otherwise free it. > */ > -int /* error */ > +int > xfs_alloc_read_agf( > - struct xfs_mount *mp, /* mount point structure */ > - struct xfs_trans *tp, /* transaction pointer */ > - xfs_agnumber_t agno, /* allocation group number */ > - int flags, /* XFS_ALLOC_FLAG_... */ > + struct xfs_perag *pag, > + struct xfs_trans *tp, > + int flags, > struct xfs_buf **agfbpp) > { > struct xfs_buf *agfbp; > - struct xfs_agf *agf; /* ag freelist header */ > - struct xfs_perag *pag; /* per allocation group data */ > + struct xfs_agf *agf; > int error; > int allocbt_blks; > > - trace_xfs_alloc_read_agf(mp, agno); > + trace_xfs_alloc_read_agf(pag->pag_mount, pag->pag_agno); > > /* We don't support trylock when freeing. */ > ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) != > (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)); > - ASSERT(agno != NULLAGNUMBER); > - error = xfs_read_agf(mp, tp, agno, > + error = xfs_read_agf(pag->pag_mount, tp, pag->pag_agno, > (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0, > &agfbp); > if (error) > return error; > > agf = agfbp->b_addr; > - pag = agfbp->b_pag; > if (!pag->pagf_init) { > pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); > pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); > @@ -3121,7 +3117,7 @@ xfs_alloc_read_agf( > be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); > pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); > pag->pagf_init = 1; > - pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf); > + pag->pagf_agflreset = xfs_agfl_needs_reset(pag->pag_mount, agf); > > /* > * Update the in-core allocbt counter. Filter out the rmapbt > @@ -3131,13 +3127,13 @@ xfs_alloc_read_agf( > * counter only tracks non-root blocks. > */ > allocbt_blks = pag->pagf_btreeblks; > - if (xfs_has_rmapbt(mp)) > + if (xfs_has_rmapbt(pag->pag_mount)) > allocbt_blks -= be32_to_cpu(agf->agf_rmap_blocks) - 1; > if (allocbt_blks > 0) > - atomic64_add(allocbt_blks, &mp->m_allocbt_blks); > + atomic64_add(allocbt_blks, &pag->pag_mount->m_allocbt_blks); Overly long line here. I think in general this function would benefit from a local xfs_mount *mp variable anyway. > diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h > index bea65f2fe657..65c5dfe17ecf 100644 > --- a/fs/xfs/xfs_reflink.h > +++ b/fs/xfs/xfs_reflink.h > @@ -16,9 +16,6 @@ static inline bool xfs_is_cow_inode(struct xfs_inode *ip) > return xfs_is_reflink_inode(ip) || xfs_is_always_cow_inode(ip); > } > > -extern int xfs_reflink_find_shared(struct xfs_mount *mp, struct xfs_trans *tp, > - xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t aglen, > - xfs_agblock_t *fbno, xfs_extlen_t *flen, bool find_maximal); Dropping this extern seems unrelated, and should move into a separate patch together with actually marking it static. Otherwise looks good: Reviewed-by: Christoph Hellwig <hch@lst.de>
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 734ef170936e..c1a1c9f414c3 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -120,16 +120,13 @@ xfs_initialize_perag_data( for (index = 0; index < agcount; index++) { /* - * read the agf, then the agi. This gets us - * all the information we need and populates the - * per-ag structures for us. + * Read the AGF and AGI buffers to populate the per-ag + * structures for us. */ - error = xfs_alloc_read_agf(mp, NULL, index, 0, NULL); - if (error) - return error; - pag = xfs_perag_get(mp, index); - error = xfs_ialloc_read_agi(pag, NULL, NULL); + error = xfs_alloc_read_agf(pag, NULL, 0, NULL); + if (!error) + error = xfs_ialloc_read_agi(pag, NULL, NULL); if (error) { xfs_perag_put(pag); return error; @@ -792,7 +789,7 @@ xfs_ag_shrink_space( agi = agibp->b_addr; - error = xfs_alloc_read_agf(mp, *tpp, pag->pag_agno, 0, &agfbp); + error = xfs_alloc_read_agf(pag, *tpp, 0, &agfbp); if (error) return error; @@ -909,7 +906,7 @@ xfs_ag_extend_space( /* * Change agf length. */ - error = xfs_alloc_read_agf(pag->pag_mount, tp, pag->pag_agno, 0, &bp); + error = xfs_alloc_read_agf(pag, tp, 0, &bp); if (error) return error; @@ -952,7 +949,7 @@ xfs_ag_get_geometry( error = xfs_ialloc_read_agi(pag, NULL, &agi_bp); if (error) return error; - error = xfs_alloc_read_agf(pag->pag_mount, NULL, pag->pag_agno, 0, &agf_bp); + error = xfs_alloc_read_agf(pag, NULL, 0, &agf_bp); if (error) goto out_agi; diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index ce28bf8f72dc..5af123d13a63 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -322,7 +322,7 @@ xfs_ag_resv_init( * address. */ if (has_resv) { - error2 = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, NULL); + error2 = xfs_alloc_read_agf(pag, tp, 0, NULL); if (error2) return error2; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index f7853ab7b962..5d6ca86c4882 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2609,7 +2609,7 @@ xfs_alloc_fix_freelist( ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); if (!pag->pagf_init) { - error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp); + error = xfs_alloc_read_agf(pag, tp, flags, &agbp); if (error) { /* Couldn't lock the AGF so skip this AG. */ if (error == -EAGAIN) @@ -2639,7 +2639,7 @@ xfs_alloc_fix_freelist( * Can fail if we're not blocking on locks, and it's held. */ if (!agbp) { - error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp); + error = xfs_alloc_read_agf(pag, tp, flags, &agbp); if (error) { /* Couldn't lock the AGF so skip this AG. */ if (error == -EAGAIN) @@ -3080,34 +3080,30 @@ xfs_read_agf( * perag structure if necessary. If the caller provides @agfbpp, then return the * locked buffer to the caller, otherwise free it. */ -int /* error */ +int xfs_alloc_read_agf( - struct xfs_mount *mp, /* mount point structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - int flags, /* XFS_ALLOC_FLAG_... */ + struct xfs_perag *pag, + struct xfs_trans *tp, + int flags, struct xfs_buf **agfbpp) { struct xfs_buf *agfbp; - struct xfs_agf *agf; /* ag freelist header */ - struct xfs_perag *pag; /* per allocation group data */ + struct xfs_agf *agf; int error; int allocbt_blks; - trace_xfs_alloc_read_agf(mp, agno); + trace_xfs_alloc_read_agf(pag->pag_mount, pag->pag_agno); /* We don't support trylock when freeing. */ ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) != (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)); - ASSERT(agno != NULLAGNUMBER); - error = xfs_read_agf(mp, tp, agno, + error = xfs_read_agf(pag->pag_mount, tp, pag->pag_agno, (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0, &agfbp); if (error) return error; agf = agfbp->b_addr; - pag = agfbp->b_pag; if (!pag->pagf_init) { pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); @@ -3121,7 +3117,7 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); pag->pagf_init = 1; - pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf); + pag->pagf_agflreset = xfs_agfl_needs_reset(pag->pag_mount, agf); /* * Update the in-core allocbt counter. Filter out the rmapbt @@ -3131,13 +3127,13 @@ xfs_alloc_read_agf( * counter only tracks non-root blocks. */ allocbt_blks = pag->pagf_btreeblks; - if (xfs_has_rmapbt(mp)) + if (xfs_has_rmapbt(pag->pag_mount)) allocbt_blks -= be32_to_cpu(agf->agf_rmap_blocks) - 1; if (allocbt_blks > 0) - atomic64_add(allocbt_blks, &mp->m_allocbt_blks); + atomic64_add(allocbt_blks, &pag->pag_mount->m_allocbt_blks); } #ifdef DEBUG - else if (!xfs_is_shutdown(mp)) { + else if (!xfs_is_shutdown(pag->pag_mount)) { ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks)); ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks)); ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount)); diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 96d5301a5c8b..b8cf5beb26d4 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -134,17 +134,6 @@ xfs_alloc_put_freelist( xfs_agblock_t bno, /* block being freed */ int btreeblk); /* owner was a AGF btree */ -/* - * Read in the allocation group header (free/alloc section). - */ -int /* error */ -xfs_alloc_read_agf( - struct xfs_mount *mp, /* mount point structure */ - struct xfs_trans *tp, /* transaction pointer */ - xfs_agnumber_t agno, /* allocation group number */ - int flags, /* XFS_ALLOC_FLAG_... */ - struct xfs_buf **bpp); /* buffer for the ag freelist header */ - /* * Allocate an extent (variable-size). */ @@ -198,6 +187,8 @@ xfs_alloc_get_rec( int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); +int xfs_alloc_read_agf(struct xfs_perag *pag, struct xfs_trans *tp, int flags, + struct xfs_buf **agfbpp); int xfs_alloc_read_agfl(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, struct xfs_buf **bpp); int xfs_free_agfl_block(struct xfs_trans *, xfs_agnumber_t, xfs_agblock_t, diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index a76d5894641b..88828fcf0453 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3185,7 +3185,7 @@ xfs_bmap_longest_free_extent( pag = xfs_perag_get(mp, ag); if (!pag->pagf_init) { - error = xfs_alloc_read_agf(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK, + error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_TRYLOCK, NULL); if (error) { /* Couldn't lock the AGF, so skip this AG. */ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 8e252207b131..dfa8061f65d9 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1621,7 +1621,7 @@ xfs_dialloc_good_ag( return false; if (!pag->pagf_init) { - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, flags, NULL); + error = xfs_alloc_read_agf(pag, tp, flags, NULL); if (error) return false; } diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 97e9e6020596..098dac888c22 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -1177,8 +1177,8 @@ xfs_refcount_finish_one( *pcur = NULL; } if (rcur == NULL) { - error = xfs_alloc_read_agf(tp->t_mountp, tp, pag->pag_agno, - XFS_ALLOC_FLAG_FREEING, &agbp); + error = xfs_alloc_read_agf(pag, tp, XFS_ALLOC_FLAG_FREEING, + &agbp); if (error) goto out_drop; @@ -1710,7 +1710,7 @@ xfs_refcount_recover_cow_leftovers( if (error) return error; - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) goto out_trans; cur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag); diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index d14c1720b0fb..1063234df34a 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -493,7 +493,7 @@ xfs_refcountbt_calc_reserves( if (!xfs_has_reflink(mp)) return 0; - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 69e104d0277f..d6d45992fe7b 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -652,7 +652,7 @@ xfs_rmapbt_calc_reserves( if (!xfs_has_rmapbt(mp)) return 0; - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) return error; diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 6da7f2ca77de..230bdfe36e80 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -666,8 +666,7 @@ xrep_agfl( * nothing wrong with the AGF, but all the AG header repair functions * have this chicken-and-egg problem. */ - error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.pag->pag_agno, 0, - &agf_bp); + error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp); if (error) return error; @@ -742,8 +741,7 @@ xrep_agi_find_btrees( int error; /* Read the AGF. */ - error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.pag->pag_agno, 0, - &agf_bp); + error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp); if (error) return error; diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 285995ba3947..9353fd060525 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -540,7 +540,7 @@ xchk_bmap_check_ag_rmaps( struct xfs_buf *agf; int error; - error = xfs_alloc_read_agf(sc->mp, sc->tp, pag->pag_agno, 0, &agf); + error = xfs_alloc_read_agf(pag, sc->tp, 0, &agf); if (error) return error; diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 62997791694a..cd7d4ebd240b 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -420,7 +420,7 @@ xchk_ag_read_headers( if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI)) return error; - error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &sa->agf_bp); + error = xfs_alloc_read_agf(sa->pag, sc->tp, 0, &sa->agf_bp); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGF)) return error; diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index bd06a184c81c..6a6f8fe7f87c 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -81,7 +81,7 @@ xchk_fscount_warmup( error = xfs_ialloc_read_agi(pag, sc->tp, &agi_bp); if (error) break; - error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &agf_bp); + error = xfs_alloc_read_agf(pag, sc->tp, 0, &agf_bp); if (error) break; diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 14acf1df3dd3..1c66f7ee6282 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -207,7 +207,7 @@ xrep_calc_ag_resblks( } /* Now grab the block counters from the AGF. */ - error = xfs_alloc_read_agf(mp, NULL, sm->sm_agno, 0, &bp); + error = xfs_alloc_read_agf(pag, NULL, 0, &bp); if (error) { aglen = xfs_ag_block_count(mp, sm->sm_agno); freelen = aglen; @@ -543,6 +543,7 @@ xrep_reap_block( agno = XFS_FSB_TO_AGNO(sc->mp, fsbno); agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno); + ASSERT(agno == sc->sa.pag->pag_agno); /* * If we are repairing per-inode metadata, we need to read in the AGF @@ -550,7 +551,7 @@ xrep_reap_block( * the AGF buffer that the setup functions already grabbed. */ if (sc->ip) { - error = xfs_alloc_read_agf(sc->mp, sc->tp, agno, 0, &agf_bp); + error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp); if (error) return error; } else { diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index c6fe3f6ebb6b..bfc829c07f03 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -45,7 +45,7 @@ xfs_trim_extents( */ xfs_log_force(mp, XFS_LOG_SYNC); - error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, NULL, 0, &agbp); if (error) goto out_put_perag; agf = agbp->b_addr; diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 765be054dffe..0d0a0b37d8c5 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -11,6 +11,7 @@ #include "xfs_bit.h" #include "xfs_shared.h" #include "xfs_mount.h" +#include "xfs_ag.h" #include "xfs_defer.h" #include "xfs_trans.h" #include "xfs_trans_priv.h" @@ -551,6 +552,7 @@ xfs_agfl_free_finish_item( xfs_agnumber_t agno; xfs_agblock_t agbno; uint next_extent; + struct xfs_perag *pag; free = container_of(item, struct xfs_extent_free_item, xefi_list); ASSERT(free->xefi_blockcount == 1); @@ -560,9 +562,11 @@ xfs_agfl_free_finish_item( trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount); - error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + pag = xfs_perag_get(mp, agno); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (!error) error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo); + xfs_perag_put(pag); /* * Mark the transaction dirty, even on error. This ensures the diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 6b09a30f8d06..34b21a29c39b 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -126,7 +126,7 @@ xfs_filestream_pick_ag( pag = xfs_perag_get(mp, ag); if (!pag->pagf_init) { - err = xfs_alloc_read_agf(mp, NULL, ag, trylock, NULL); + err = xfs_alloc_read_agf(pag, NULL, trylock, NULL); if (err) { if (err != -EAGAIN) { xfs_perag_put(pag); diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index bb23199f65c3..d8337274c74d 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -642,8 +642,7 @@ __xfs_getfsmap_datadev( info->agf_bp = NULL; } - error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, - &info->agf_bp); + error = xfs_alloc_read_agf(pag, tp, 0, &info->agf_bp); if (error) break; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index e7a7c00d93be..d2328cc26ddf 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -127,9 +127,8 @@ */ int xfs_reflink_find_shared( - struct xfs_mount *mp, + struct xfs_perag *pag, struct xfs_trans *tp, - xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno, @@ -140,11 +139,11 @@ xfs_reflink_find_shared( struct xfs_btree_cur *cur; int error; - error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + error = xfs_alloc_read_agf(pag, tp, 0, &agbp); if (error) return error; - cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agbp->b_pag); + cur = xfs_refcountbt_init_cursor(pag->pag_mount, tp, agbp, pag); error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen, find_end_of_shared); @@ -171,7 +170,8 @@ xfs_reflink_trim_around_shared( struct xfs_bmbt_irec *irec, bool *shared) { - xfs_agnumber_t agno; + struct xfs_mount *mp = ip->i_mount; + struct xfs_perag *pag; xfs_agblock_t agbno; xfs_extlen_t aglen; xfs_agblock_t fbno; @@ -186,12 +186,13 @@ xfs_reflink_trim_around_shared( trace_xfs_reflink_trim_around_shared(ip, irec); - agno = XFS_FSB_TO_AGNO(ip->i_mount, irec->br_startblock); - agbno = XFS_FSB_TO_AGBNO(ip->i_mount, irec->br_startblock); + pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, irec->br_startblock)); + agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock); aglen = irec->br_blockcount; - error = xfs_reflink_find_shared(ip->i_mount, NULL, agno, agbno, - aglen, &fbno, &flen, true); + error = xfs_reflink_find_shared(pag, NULL, agbno, aglen, &fbno, &flen, + true); + xfs_perag_put(pag); if (error) return error; @@ -1420,11 +1421,6 @@ xfs_reflink_inode_has_shared_extents( struct xfs_bmbt_irec got; struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; - xfs_agnumber_t agno; - xfs_agblock_t agbno; - xfs_extlen_t aglen; - xfs_agblock_t rbno; - xfs_extlen_t rlen; struct xfs_iext_cursor icur; bool found; int error; @@ -1437,17 +1433,25 @@ xfs_reflink_inode_has_shared_extents( *has_shared = false; found = xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got); while (found) { + struct xfs_perag *pag; + xfs_agblock_t agbno; + xfs_extlen_t aglen; + xfs_agblock_t rbno; + xfs_extlen_t rlen; + if (isnullstartblock(got.br_startblock) || got.br_state != XFS_EXT_NORM) goto next; - agno = XFS_FSB_TO_AGNO(mp, got.br_startblock); + + pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, got.br_startblock)); agbno = XFS_FSB_TO_AGBNO(mp, got.br_startblock); aglen = got.br_blockcount; - - error = xfs_reflink_find_shared(mp, tp, agno, agbno, aglen, + error = xfs_reflink_find_shared(pag, tp, agbno, aglen, &rbno, &rlen, false); + xfs_perag_put(pag); if (error) return error; + /* Is there still a shared block here? */ if (rbno != NULLAGBLOCK) { *has_shared = true; diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index bea65f2fe657..65c5dfe17ecf 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -16,9 +16,6 @@ static inline bool xfs_is_cow_inode(struct xfs_inode *ip) return xfs_is_reflink_inode(ip) || xfs_is_always_cow_inode(ip); } -extern int xfs_reflink_find_shared(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t aglen, - xfs_agblock_t *fbno, xfs_extlen_t *flen, bool find_maximal); extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip, struct xfs_bmbt_irec *irec, bool *shared); int xfs_bmap_trim_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap,