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

xfs: streamline xfs_filestream_pick_ag

Directly return the error from xfs_bmap_longest_free_extent instead
of breaking from the loop and handling it there, and use a done
label to directly jump to the exist when we found a suitable perag
structure to reduce the indentation level and pag/max_pag check
complexity in the tail of the function.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>

authored by

Christoph Hellwig and committed by
Carlos Maiolino
81a1e1c3 dc60992c

+49 -53
+49 -53
fs/xfs/xfs_filestream.c
··· 67 67 xfs_extlen_t minfree, maxfree = 0; 68 68 xfs_agnumber_t agno; 69 69 bool first_pass = true; 70 - int err; 71 70 72 71 /* 2% of an AG's blocks must be free for it to be chosen. */ 73 72 minfree = mp->m_sb.sb_agblocks / 50; 74 73 75 74 restart: 76 75 for_each_perag_wrap(mp, start_agno, agno, pag) { 76 + int err; 77 + 77 78 trace_xfs_filestream_scan(pag, pino); 79 + 78 80 *longest = 0; 79 81 err = xfs_bmap_longest_free_extent(pag, NULL, longest); 80 82 if (err) { 81 - if (err != -EAGAIN) 82 - break; 83 - /* Couldn't lock the AGF, skip this AG. */ 84 - err = 0; 85 - continue; 83 + if (err == -EAGAIN) { 84 + /* Couldn't lock the AGF, skip this AG. */ 85 + err = 0; 86 + continue; 87 + } 88 + xfs_perag_rele(pag); 89 + if (max_pag) 90 + xfs_perag_rele(max_pag); 91 + return err; 86 92 } 87 93 88 94 /* Keep track of the AG with the most free blocks. */ ··· 113 107 !(flags & XFS_PICK_USERDATA) || 114 108 (flags & XFS_PICK_LOWSPACE))) { 115 109 /* Break out, retaining the reference on the AG. */ 116 - break; 110 + if (max_pag) 111 + xfs_perag_rele(max_pag); 112 + goto done; 117 113 } 118 114 } 119 115 ··· 123 115 atomic_dec(&pag->pagf_fstrms); 124 116 } 125 117 126 - if (err) { 127 - xfs_perag_rele(pag); 128 - if (max_pag) 129 - xfs_perag_rele(max_pag); 130 - return err; 118 + /* 119 + * Allow a second pass to give xfs_bmap_longest_free_extent() another 120 + * attempt at locking AGFs that it might have skipped over before we 121 + * fail. 122 + */ 123 + if (first_pass) { 124 + first_pass = false; 125 + goto restart; 131 126 } 132 127 133 - if (!pag) { 134 - /* 135 - * Allow a second pass to give xfs_bmap_longest_free_extent() 136 - * another attempt at locking AGFs that it might have skipped 137 - * over before we fail. 138 - */ 139 - if (first_pass) { 140 - first_pass = false; 141 - goto restart; 142 - } 143 - 144 - /* 145 - * We must be low on data space, so run a final lowspace 146 - * optimised selection pass if we haven't already. 147 - */ 148 - if (!(flags & XFS_PICK_LOWSPACE)) { 149 - flags |= XFS_PICK_LOWSPACE; 150 - goto restart; 151 - } 152 - 153 - /* 154 - * No unassociated AGs are available, so select the AG with the 155 - * most free space, regardless of whether it's already in use by 156 - * another filestream. It none suit, just use whatever AG we can 157 - * grab. 158 - */ 159 - if (!max_pag) { 160 - for_each_perag_wrap(args->mp, 0, start_agno, pag) { 161 - max_pag = pag; 162 - break; 163 - } 164 - 165 - /* Bail if there are no AGs at all to select from. */ 166 - if (!max_pag) 167 - return -ENOSPC; 168 - } 169 - 170 - pag = max_pag; 171 - atomic_inc(&pag->pagf_fstrms); 172 - } else if (max_pag) { 173 - xfs_perag_rele(max_pag); 128 + /* 129 + * We must be low on data space, so run a final lowspace optimised 130 + * selection pass if we haven't already. 131 + */ 132 + if (!(flags & XFS_PICK_LOWSPACE)) { 133 + flags |= XFS_PICK_LOWSPACE; 134 + goto restart; 174 135 } 175 136 137 + /* 138 + * No unassociated AGs are available, so select the AG with the most 139 + * free space, regardless of whether it's already in use by another 140 + * filestream. It none suit, just use whatever AG we can grab. 141 + */ 142 + if (!max_pag) { 143 + for_each_perag_wrap(args->mp, 0, start_agno, pag) { 144 + max_pag = pag; 145 + break; 146 + } 147 + 148 + /* Bail if there are no AGs at all to select from. */ 149 + if (!max_pag) 150 + return -ENOSPC; 151 + } 152 + 153 + pag = max_pag; 154 + atomic_inc(&pag->pagf_fstrms); 155 + done: 176 156 trace_xfs_filestream_pick(pag, pino); 177 157 args->pag = pag; 178 158 return 0;