* [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'?
@ 2024-08-22 20:35 kernel test robot
0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2024-08-22 20:35 UTC (permalink / raw)
To: cros-kernel-buildreports; +Cc: oe-kbuild-all
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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2024-08-22 20:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-22 20:35 [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'? kernel test robot
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.