From: kernel test robot <lkp@intel.com>
To: cros-kernel-buildreports@googlegroups.com
Cc: oe-kbuild-all@lists.linux.dev
Subject: [chrome-os:chromeos-5.15 46/47] fs/btrfs/file.c:2407:6: error: use of undeclared identifier 'skip_ilock'; did you mean 'spin_lock'?
Date: Fri, 23 Aug 2024 04:35:33 +0800 [thread overview]
Message-ID: <202408230435.vABlkoXP-lkp@intel.com> (raw)
tree: https://chromium.googlesource.com/chromiumos/third_party/kernel chromeos-5.15
head: ae30386317f21239fb5c3828122ffd6cec6c9b21
commit: 29349f0a02fdd1b1d14abb4b4dc53bed974b7d55 [46/47] UPSTREAM: btrfs: fix double inode unlock for direct IO sync writes
config: x86_64-rhel-8.3-rust (https://download.01.org/0day-ci/archive/20240823/202408230435.vABlkoXP-lkp@intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240823/202408230435.vABlkoXP-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408230435.vABlkoXP-lkp@intel.com/
Note: the chrome-os/chromeos-5.15 HEAD ae30386317f21239fb5c3828122ffd6cec6c9b21 builds fine.
It only hurts bisectability.
All errors (new ones prefixed by >>):
>> fs/btrfs/file.c:2407:6: error: use of undeclared identifier 'skip_ilock'; did you mean 'spin_lock'?
2407 | if (skip_ilock)
| ^~~~~~~~~~
| spin_lock
include/linux/spinlock.h:361:29: note: 'spin_lock' declared here
361 | static __always_inline void spin_lock(spinlock_t *lock)
| ^
>> fs/btrfs/file.c:2408:20: error: no member named 'i_mmap_lock' in 'struct inode'
2408 | up_write(&inode->i_mmap_lock);
| ~~~~~ ^
2 errors generated.
vim +2407 fs/btrfs/file.c
2166
2167 /*
2168 * fsync call for both files and directories. This logs the inode into
2169 * the tree log instead of forcing full commits whenever possible.
2170 *
2171 * It needs to call filemap_fdatawait so that all ordered extent updates are
2172 * in the metadata btree are up to date for copying to the log.
2173 *
2174 * It drops the inode mutex before doing the tree log commit. This is an
2175 * important optimization for directories because holding the mutex prevents
2176 * new operations on the dir while we write to disk.
2177 */
2178 int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
2179 {
2180 struct dentry *dentry = file_dentry(file);
2181 struct inode *inode = d_inode(dentry);
2182 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
2183 struct btrfs_root *root = BTRFS_I(inode)->root;
2184 struct btrfs_trans_handle *trans;
2185 struct btrfs_log_ctx ctx;
2186 int ret = 0, err;
2187 u64 len;
2188 bool full_sync;
2189
2190 trace_btrfs_sync_file(file, datasync);
2191
2192 btrfs_init_log_ctx(&ctx, inode);
2193
2194 /*
2195 * Always set the range to a full range, otherwise we can get into
2196 * several problems, from missing file extent items to represent holes
2197 * when not using the NO_HOLES feature, to log tree corruption due to
2198 * races between hole detection during logging and completion of ordered
2199 * extents outside the range, to missing checksums due to ordered extents
2200 * for which we flushed only a subset of their pages.
2201 */
2202 start = 0;
2203 end = LLONG_MAX;
2204 len = (u64)LLONG_MAX + 1;
2205
2206 /*
2207 * We write the dirty pages in the range and wait until they complete
2208 * out of the ->i_mutex. If so, we can flush the dirty pages by
2209 * multi-task, and make the performance up. See
2210 * btrfs_wait_ordered_range for an explanation of the ASYNC check.
2211 */
2212 ret = start_ordered_ops(inode, start, end);
2213 if (ret)
2214 goto out;
2215
2216 btrfs_inode_lock(inode, BTRFS_ILOCK_MMAP);
2217
2218 atomic_inc(&root->log_batch);
2219
2220 /*
2221 * Always check for the full sync flag while holding the inode's lock,
2222 * to avoid races with other tasks. The flag must be either set all the
2223 * time during logging or always off all the time while logging.
2224 */
2225 full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
2226 &BTRFS_I(inode)->runtime_flags);
2227
2228 /*
2229 * Before we acquired the inode's lock and the mmap lock, someone may
2230 * have dirtied more pages in the target range. We need to make sure
2231 * that writeback for any such pages does not start while we are logging
2232 * the inode, because if it does, any of the following might happen when
2233 * we are not doing a full inode sync:
2234 *
2235 * 1) We log an extent after its writeback finishes but before its
2236 * checksums are added to the csum tree, leading to -EIO errors
2237 * when attempting to read the extent after a log replay.
2238 *
2239 * 2) We can end up logging an extent before its writeback finishes.
2240 * Therefore after the log replay we will have a file extent item
2241 * pointing to an unwritten extent (and no data checksums as well).
2242 *
2243 * So trigger writeback for any eventual new dirty pages and then we
2244 * wait for all ordered extents to complete below.
2245 */
2246 ret = start_ordered_ops(inode, start, end);
2247 if (ret) {
2248 btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
2249 goto out;
2250 }
2251
2252 /*
2253 * We have to do this here to avoid the priority inversion of waiting on
2254 * IO of a lower priority task while holding a transaction open.
2255 *
2256 * For a full fsync we wait for the ordered extents to complete while
2257 * for a fast fsync we wait just for writeback to complete, and then
2258 * attach the ordered extents to the transaction so that a transaction
2259 * commit waits for their completion, to avoid data loss if we fsync,
2260 * the current transaction commits before the ordered extents complete
2261 * and a power failure happens right after that.
2262 *
2263 * For zoned filesystem, if a write IO uses a ZONE_APPEND command, the
2264 * logical address recorded in the ordered extent may change. We need
2265 * to wait for the IO to stabilize the logical address.
2266 */
2267 if (full_sync || btrfs_is_zoned(fs_info)) {
2268 ret = btrfs_wait_ordered_range(inode, start, len);
2269 } else {
2270 /*
2271 * Get our ordered extents as soon as possible to avoid doing
2272 * checksum lookups in the csum tree, and use instead the
2273 * checksums attached to the ordered extents.
2274 */
2275 btrfs_get_ordered_extents_for_logging(BTRFS_I(inode),
2276 &ctx.ordered_extents);
2277 ret = filemap_fdatawait_range(inode->i_mapping, start, end);
2278 }
2279
2280 if (ret)
2281 goto out_release_extents;
2282
2283 atomic_inc(&root->log_batch);
2284
2285 smp_mb();
2286 if (skip_inode_logging(&ctx)) {
2287 /*
2288 * We've had everything committed since the last time we were
2289 * modified so clear this flag in case it was set for whatever
2290 * reason, it's no longer relevant.
2291 */
2292 clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
2293 &BTRFS_I(inode)->runtime_flags);
2294 /*
2295 * An ordered extent might have started before and completed
2296 * already with io errors, in which case the inode was not
2297 * updated and we end up here. So check the inode's mapping
2298 * for any errors that might have happened since we last
2299 * checked called fsync.
2300 */
2301 ret = filemap_check_wb_err(inode->i_mapping, file->f_wb_err);
2302 goto out_release_extents;
2303 }
2304
2305 /*
2306 * We use start here because we will need to wait on the IO to complete
2307 * in btrfs_sync_log, which could require joining a transaction (for
2308 * example checking cross references in the nocow path). If we use join
2309 * here we could get into a situation where we're waiting on IO to
2310 * happen that is blocked on a transaction trying to commit. With start
2311 * we inc the extwriter counter, so we wait for all extwriters to exit
2312 * before we start blocking joiners. This comment is to keep somebody
2313 * from thinking they are super smart and changing this to
2314 * btrfs_join_transaction *cough*Josef*cough*.
2315 */
2316 trans = btrfs_start_transaction(root, 0);
2317 if (IS_ERR(trans)) {
2318 ret = PTR_ERR(trans);
2319 goto out_release_extents;
2320 }
2321 trans->in_fsync = true;
2322
2323 ret = btrfs_log_dentry_safe(trans, dentry, &ctx);
2324 btrfs_release_log_ctx_extents(&ctx);
2325 if (ret < 0) {
2326 /* Fallthrough and commit/free transaction. */
2327 ret = 1;
2328 }
2329
2330 /* we've logged all the items and now have a consistent
2331 * version of the file in the log. It is possible that
2332 * someone will come in and modify the file, but that's
2333 * fine because the log is consistent on disk, and we
2334 * have references to all of the file's extents
2335 *
2336 * It is possible that someone will come in and log the
2337 * file again, but that will end up using the synchronization
2338 * inside btrfs_sync_log to keep things safe.
2339 */
2340 btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
2341
2342 if (ret == BTRFS_NO_LOG_SYNC) {
2343 ret = btrfs_end_transaction(trans);
2344 goto out;
2345 }
2346
2347 /* We successfully logged the inode, attempt to sync the log. */
2348 if (!ret) {
2349 ret = btrfs_sync_log(trans, root, &ctx);
2350 if (!ret) {
2351 ret = btrfs_end_transaction(trans);
2352 goto out;
2353 }
2354 }
2355
2356 /*
2357 * At this point we need to commit the transaction because we had
2358 * btrfs_need_log_full_commit() or some other error.
2359 *
2360 * If we didn't do a full sync we have to stop the trans handle, wait on
2361 * the ordered extents, start it again and commit the transaction. If
2362 * we attempt to wait on the ordered extents here we could deadlock with
2363 * something like fallocate() that is holding the extent lock trying to
2364 * start a transaction while some other thread is trying to commit the
2365 * transaction while we (fsync) are currently holding the transaction
2366 * open.
2367 */
2368 if (!full_sync) {
2369 ret = btrfs_end_transaction(trans);
2370 if (ret)
2371 goto out;
2372 ret = btrfs_wait_ordered_range(inode, start, len);
2373 if (ret)
2374 goto out;
2375
2376 /*
2377 * This is safe to use here because we're only interested in
2378 * making sure the transaction that had the ordered extents is
2379 * committed. We aren't waiting on anything past this point,
2380 * we're purely getting the transaction and committing it.
2381 */
2382 trans = btrfs_attach_transaction_barrier(root);
2383 if (IS_ERR(trans)) {
2384 ret = PTR_ERR(trans);
2385
2386 /*
2387 * We committed the transaction and there's no currently
2388 * running transaction, this means everything we care
2389 * about made it to disk and we are done.
2390 */
2391 if (ret == -ENOENT)
2392 ret = 0;
2393 goto out;
2394 }
2395 }
2396
2397 ret = btrfs_commit_transaction(trans);
2398 out:
2399 ASSERT(list_empty(&ctx.list));
2400 err = file_check_and_advance_wb_err(file);
2401 if (!ret)
2402 ret = err;
2403 return ret > 0 ? -EIO : ret;
2404
2405 out_release_extents:
2406 btrfs_release_log_ctx_extents(&ctx);
> 2407 if (skip_ilock)
> 2408 up_write(&inode->i_mmap_lock);
2409 else
2410 btrfs_inode_unlock(inode, BTRFS_ILOCK_MMAP);
2411 goto out;
2412 }
2413
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
reply other threads:[~2024-08-22 20:36 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202408230435.vABlkoXP-lkp@intel.com \
--to=lkp@intel.com \
--cc=cros-kernel-buildreports@googlegroups.com \
--cc=oe-kbuild-all@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.