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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'fscache-fixes-20220121' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

Pull more fscache updates from David Howells:
"A set of fixes and minor updates for the fscache rewrite:

- Fix mishandling of volume collisions (the wait condition is
inverted and so it was only waiting if the volume collision was
already resolved).

- Fix miscalculation of whether there's space available in
cachefiles.

- Make sure a default cache name is set on a cache if the user hasn't
set one by the time they bind the cache.

- Adjust the way the backing inode is presented in tracepoints, add a
tracepoint for mkdir and trace directory lookup.

- Add a tracepoint for failure to set the active file mark.

- Add an explanation of the checks made on the backing filesystem.

- Check that the backing filesystem supports tmpfile.

- Document how the page-release cancellation of the read-skip
optimisation works.

And I've included a change for netfslib:

- Make ops->init_rreq() optional"

* tag 'fscache-fixes-20220121' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
netfs: Make ops->init_rreq() optional
fscache: Add a comment explaining how page-release optimisation works
cachefiles: Check that the backing filesystem supports tmpfiles
cachefiles: Explain checks in a comment
cachefiles: Trace active-mark failure
cachefiles: Make some tracepoint adjustments
cachefiles: set default tag name if it's unspecified
cachefiles: Calculate the blockshift in terms of bytes, not pages
fscache: Fix the volume collision wait condition

+113 -51
+11 -6
fs/cachefiles/cache.c
··· 49 49 goto error_unsupported; 50 50 } 51 51 52 - /* check parameters */ 52 + /* Check features of the backing filesystem: 53 + * - Directories must support looking up and directory creation 54 + * - We create tmpfiles to handle invalidation 55 + * - We use xattrs to store metadata 56 + * - We need to be able to query the amount of space available 57 + * - We want to be able to sync the filesystem when stopping the cache 58 + * - We use DIO to/from pages, so the blocksize mustn't be too big. 59 + */ 53 60 ret = -EOPNOTSUPP; 54 61 if (d_is_negative(root) || 55 62 !d_backing_inode(root)->i_op->lookup || 56 63 !d_backing_inode(root)->i_op->mkdir || 64 + !d_backing_inode(root)->i_op->tmpfile || 57 65 !(d_backing_inode(root)->i_opflags & IOP_XATTR) || 58 66 !root->d_sb->s_op->statfs || 59 67 !root->d_sb->s_op->sync_fs || ··· 92 84 goto error_unsupported; 93 85 94 86 cache->bsize = stats.f_bsize; 95 - cache->bshift = 0; 96 - if (stats.f_bsize < PAGE_SIZE) 97 - cache->bshift = PAGE_SHIFT - ilog2(stats.f_bsize); 87 + cache->bshift = ilog2(stats.f_bsize); 98 88 99 89 _debug("blksize %u (shift %u)", 100 90 cache->bsize, cache->bshift); ··· 112 106 (unsigned long long) cache->fcull, 113 107 (unsigned long long) cache->fstop); 114 108 115 - stats.f_blocks >>= cache->bshift; 116 109 do_div(stats.f_blocks, 100); 117 110 cache->bstop = stats.f_blocks * cache->bstop_percent; 118 111 cache->bcull = stats.f_blocks * cache->bcull_percent; ··· 214 209 return ret; 215 210 } 216 211 217 - b_avail = stats.f_bavail >> cache->bshift; 212 + b_avail = stats.f_bavail; 218 213 b_writing = atomic_long_read(&cache->b_writing); 219 214 if (b_avail > b_writing) 220 215 b_avail -= b_writing;
+11
fs/cachefiles/daemon.c
··· 703 703 return -EBUSY; 704 704 } 705 705 706 + /* Make sure we have copies of the tag string */ 707 + if (!cache->tag) { 708 + /* 709 + * The tag string is released by the fops->release() 710 + * function, so we don't release it on error here 711 + */ 712 + cache->tag = kstrdup("CacheFiles", GFP_KERNEL); 713 + if (!cache->tag) 714 + return -ENOMEM; 715 + } 716 + 706 717 return cachefiles_add_cache(cache); 707 718 } 708 719
+1 -1
fs/cachefiles/internal.h
··· 86 86 unsigned bcull_percent; /* when to start culling (% blocks) */ 87 87 unsigned bstop_percent; /* when to stop allocating (% blocks) */ 88 88 unsigned bsize; /* cache's block size */ 89 - unsigned bshift; /* min(ilog2(PAGE_SIZE / bsize), 0) */ 89 + unsigned bshift; /* ilog2(bsize) */ 90 90 uint64_t frun; /* when to stop culling */ 91 91 uint64_t fcull; /* when to start culling */ 92 92 uint64_t fstop; /* when to stop allocating */
+1 -1
fs/cachefiles/io.c
··· 264 264 ki->term_func = term_func; 265 265 ki->term_func_priv = term_func_priv; 266 266 ki->was_async = true; 267 - ki->b_writing = (len + (1 << cache->bshift)) >> cache->bshift; 267 + ki->b_writing = (len + (1 << cache->bshift) - 1) >> cache->bshift; 268 268 269 269 if (ki->term_func) 270 270 ki->iocb.ki_complete = cachefiles_write_complete;
+8 -4
fs/cachefiles/namei.c
··· 25 25 trace_cachefiles_mark_active(object, inode); 26 26 can_use = true; 27 27 } else { 28 - pr_notice("cachefiles: Inode already in use: %pd\n", dentry); 28 + trace_cachefiles_mark_failed(object, inode); 29 + pr_notice("cachefiles: Inode already in use: %pd (B=%lx)\n", 30 + dentry, inode->i_ino); 29 31 } 30 32 31 33 return can_use; ··· 103 101 subdir = lookup_one_len(dirname, dir, strlen(dirname)); 104 102 else 105 103 subdir = ERR_PTR(ret); 104 + trace_cachefiles_lookup(NULL, dir, subdir); 106 105 if (IS_ERR(subdir)) { 107 106 trace_cachefiles_vfs_error(NULL, d_backing_inode(dir), 108 107 PTR_ERR(subdir), ··· 138 135 cachefiles_trace_mkdir_error); 139 136 goto mkdir_error; 140 137 } 138 + trace_cachefiles_mkdir(dir, subdir); 141 139 142 140 if (unlikely(d_unhashed(subdir))) { 143 141 cachefiles_put_directory(subdir); ··· 237 233 }; 238 234 int ret; 239 235 240 - trace_cachefiles_unlink(object, dentry, why); 236 + trace_cachefiles_unlink(object, d_inode(dentry)->i_ino, why); 241 237 ret = security_path_unlink(&path, dentry); 242 238 if (ret < 0) { 243 239 cachefiles_io_error(cache, "Unlink security error"); ··· 390 386 .new_dir = d_inode(cache->graveyard), 391 387 .new_dentry = grave, 392 388 }; 393 - trace_cachefiles_rename(object, rep, grave, why); 389 + trace_cachefiles_rename(object, d_inode(rep)->i_ino, why); 394 390 ret = cachefiles_inject_read_error(); 395 391 if (ret == 0) 396 392 ret = vfs_rename(&rd); ··· 621 617 object->d_name_len); 622 618 else 623 619 dentry = ERR_PTR(ret); 624 - trace_cachefiles_lookup(object, dentry); 620 + trace_cachefiles_lookup(object, fan, dentry); 625 621 if (IS_ERR(dentry)) { 626 622 if (dentry == ERR_PTR(-ENOENT)) 627 623 goto new_file;
-5
fs/ceph/addr.c
··· 297 297 dout("%s: result %d\n", __func__, err); 298 298 } 299 299 300 - static void ceph_init_rreq(struct netfs_read_request *rreq, struct file *file) 301 - { 302 - } 303 - 304 300 static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) 305 301 { 306 302 struct inode *inode = mapping->host; ··· 308 312 } 309 313 310 314 static const struct netfs_read_request_ops ceph_netfs_read_ops = { 311 - .init_rreq = ceph_init_rreq, 312 315 .is_cache_enabled = ceph_is_cache_enabled, 313 316 .begin_cache_operation = ceph_begin_cache_operation, 314 317 .issue_op = ceph_netfs_issue_op,
+2 -2
fs/fscache/volume.c
··· 142 142 unsigned int collidee_debug_id) 143 143 { 144 144 wait_var_event_timeout(&candidate->flags, 145 - fscache_is_acquire_pending(candidate), 20 * HZ); 145 + !fscache_is_acquire_pending(candidate), 20 * HZ); 146 146 if (!fscache_is_acquire_pending(candidate)) { 147 147 pr_notice("Potential volume collision new=%08x old=%08x", 148 148 candidate->debug_id, collidee_debug_id); 149 149 fscache_stat(&fscache_n_volumes_collision); 150 - wait_var_event(&candidate->flags, fscache_is_acquire_pending(candidate)); 150 + wait_var_event(&candidate->flags, !fscache_is_acquire_pending(candidate)); 151 151 } 152 152 } 153 153
+2 -1
fs/netfs/read_helper.c
··· 55 55 INIT_WORK(&rreq->work, netfs_rreq_work); 56 56 refcount_set(&rreq->usage, 1); 57 57 __set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags); 58 - ops->init_rreq(rreq, file); 58 + if (ops->init_rreq) 59 + ops->init_rreq(rreq, file); 59 60 netfs_stat(&netfs_n_rh_rreq); 60 61 } 61 62
+5
include/linux/fscache.h
··· 665 665 static inline 666 666 void fscache_note_page_release(struct fscache_cookie *cookie) 667 667 { 668 + /* If we've written data to the cache (HAVE_DATA) and there wasn't any 669 + * data in the cache when we started (NO_DATA_TO_READ), it may no 670 + * longer be true that we can skip reading from the cache - so clear 671 + * the flag that causes reads to be skipped. 672 + */ 668 673 if (cookie && 669 674 test_bit(FSCACHE_COOKIE_HAVE_DATA, &cookie->flags) && 670 675 test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags))
+72 -31
include/trace/events/cachefiles.h
··· 233 233 234 234 TRACE_EVENT(cachefiles_lookup, 235 235 TP_PROTO(struct cachefiles_object *obj, 236 + struct dentry *dir, 236 237 struct dentry *de), 237 238 238 - TP_ARGS(obj, de), 239 + TP_ARGS(obj, dir, de), 239 240 240 241 TP_STRUCT__entry( 241 242 __field(unsigned int, obj ) 242 243 __field(short, error ) 244 + __field(unsigned long, dino ) 243 245 __field(unsigned long, ino ) 244 246 ), 245 247 246 248 TP_fast_assign( 247 - __entry->obj = obj->debug_id; 249 + __entry->obj = obj ? obj->debug_id : 0; 250 + __entry->dino = d_backing_inode(dir)->i_ino; 248 251 __entry->ino = (!IS_ERR(de) && d_backing_inode(de) ? 249 252 d_backing_inode(de)->i_ino : 0); 250 253 __entry->error = IS_ERR(de) ? PTR_ERR(de) : 0; 251 254 ), 252 255 253 - TP_printk("o=%08x i=%lx e=%d", 254 - __entry->obj, __entry->ino, __entry->error) 256 + TP_printk("o=%08x dB=%lx B=%lx e=%d", 257 + __entry->obj, __entry->dino, __entry->ino, __entry->error) 258 + ); 259 + 260 + TRACE_EVENT(cachefiles_mkdir, 261 + TP_PROTO(struct dentry *dir, struct dentry *subdir), 262 + 263 + TP_ARGS(dir, subdir), 264 + 265 + TP_STRUCT__entry( 266 + __field(unsigned int, dir ) 267 + __field(unsigned int, subdir ) 268 + ), 269 + 270 + TP_fast_assign( 271 + __entry->dir = d_backing_inode(dir)->i_ino; 272 + __entry->subdir = d_backing_inode(subdir)->i_ino; 273 + ), 274 + 275 + TP_printk("dB=%x sB=%x", 276 + __entry->dir, 277 + __entry->subdir) 255 278 ); 256 279 257 280 TRACE_EVENT(cachefiles_tmpfile, ··· 292 269 __entry->backer = backer->i_ino; 293 270 ), 294 271 295 - TP_printk("o=%08x b=%08x", 272 + TP_printk("o=%08x B=%x", 296 273 __entry->obj, 297 274 __entry->backer) 298 275 ); ··· 312 289 __entry->backer = backer->i_ino; 313 290 ), 314 291 315 - TP_printk("o=%08x b=%08x", 292 + TP_printk("o=%08x B=%x", 316 293 __entry->obj, 317 294 __entry->backer) 318 295 ); 319 296 320 297 TRACE_EVENT(cachefiles_unlink, 321 298 TP_PROTO(struct cachefiles_object *obj, 322 - struct dentry *de, 299 + ino_t ino, 323 300 enum fscache_why_object_killed why), 324 301 325 - TP_ARGS(obj, de, why), 302 + TP_ARGS(obj, ino, why), 326 303 327 304 /* Note that obj may be NULL */ 328 305 TP_STRUCT__entry( 329 306 __field(unsigned int, obj ) 330 - __field(struct dentry *, de ) 307 + __field(unsigned int, ino ) 331 308 __field(enum fscache_why_object_killed, why ) 332 309 ), 333 310 334 311 TP_fast_assign( 335 312 __entry->obj = obj ? obj->debug_id : UINT_MAX; 336 - __entry->de = de; 313 + __entry->ino = ino; 337 314 __entry->why = why; 338 315 ), 339 316 340 - TP_printk("o=%08x d=%p w=%s", 341 - __entry->obj, __entry->de, 317 + TP_printk("o=%08x B=%x w=%s", 318 + __entry->obj, __entry->ino, 342 319 __print_symbolic(__entry->why, cachefiles_obj_kill_traces)) 343 320 ); 344 321 345 322 TRACE_EVENT(cachefiles_rename, 346 323 TP_PROTO(struct cachefiles_object *obj, 347 - struct dentry *de, 348 - struct dentry *to, 324 + ino_t ino, 349 325 enum fscache_why_object_killed why), 350 326 351 - TP_ARGS(obj, de, to, why), 327 + TP_ARGS(obj, ino, why), 352 328 353 329 /* Note that obj may be NULL */ 354 330 TP_STRUCT__entry( 355 331 __field(unsigned int, obj ) 356 - __field(struct dentry *, de ) 357 - __field(struct dentry *, to ) 332 + __field(unsigned int, ino ) 358 333 __field(enum fscache_why_object_killed, why ) 359 334 ), 360 335 361 336 TP_fast_assign( 362 337 __entry->obj = obj ? obj->debug_id : UINT_MAX; 363 - __entry->de = de; 364 - __entry->to = to; 338 + __entry->ino = ino; 365 339 __entry->why = why; 366 340 ), 367 341 368 - TP_printk("o=%08x d=%p t=%p w=%s", 369 - __entry->obj, __entry->de, __entry->to, 342 + TP_printk("o=%08x B=%x w=%s", 343 + __entry->obj, __entry->ino, 370 344 __print_symbolic(__entry->why, cachefiles_obj_kill_traces)) 371 345 ); 372 346 ··· 390 370 __entry->ino = ino; 391 371 ), 392 372 393 - TP_printk("o=%08x %s i=%llx c=%u", 373 + TP_printk("o=%08x %s B=%llx c=%u", 394 374 __entry->obj, 395 375 __print_symbolic(__entry->why, cachefiles_coherency_traces), 396 376 __entry->ino, ··· 417 397 __entry->ino = ino; 418 398 ), 419 399 420 - TP_printk("V=%08x %s i=%llx", 400 + TP_printk("V=%08x %s B=%llx", 421 401 __entry->vol, 422 402 __print_symbolic(__entry->why, cachefiles_coherency_traces), 423 403 __entry->ino) ··· 455 435 __entry->cache_inode = cache_inode; 456 436 ), 457 437 458 - TP_printk("R=%08x[%u] %s %s f=%02x s=%llx %zx ni=%x b=%x", 438 + TP_printk("R=%08x[%u] %s %s f=%02x s=%llx %zx ni=%x B=%x", 459 439 __entry->rreq, __entry->index, 460 440 __print_symbolic(__entry->source, netfs_sreq_sources), 461 441 __print_symbolic(__entry->why, cachefiles_prepare_read_traces), ··· 486 466 __entry->len = len; 487 467 ), 488 468 489 - TP_printk("o=%08x b=%08x s=%llx l=%zx", 469 + TP_printk("o=%08x B=%x s=%llx l=%zx", 490 470 __entry->obj, 491 471 __entry->backer, 492 472 __entry->start, ··· 515 495 __entry->len = len; 516 496 ), 517 497 518 - TP_printk("o=%08x b=%08x s=%llx l=%zx", 498 + TP_printk("o=%08x B=%x s=%llx l=%zx", 519 499 __entry->obj, 520 500 __entry->backer, 521 501 __entry->start, ··· 544 524 __entry->why = why; 545 525 ), 546 526 547 - TP_printk("o=%08x b=%08x %s l=%llx->%llx", 527 + TP_printk("o=%08x B=%x %s l=%llx->%llx", 548 528 __entry->obj, 549 529 __entry->backer, 550 530 __print_symbolic(__entry->why, cachefiles_trunc_traces), ··· 569 549 __entry->inode = inode->i_ino; 570 550 ), 571 551 572 - TP_printk("o=%08x i=%lx", 552 + TP_printk("o=%08x B=%lx", 553 + __entry->obj, __entry->inode) 554 + ); 555 + 556 + TRACE_EVENT(cachefiles_mark_failed, 557 + TP_PROTO(struct cachefiles_object *obj, 558 + struct inode *inode), 559 + 560 + TP_ARGS(obj, inode), 561 + 562 + /* Note that obj may be NULL */ 563 + TP_STRUCT__entry( 564 + __field(unsigned int, obj ) 565 + __field(ino_t, inode ) 566 + ), 567 + 568 + TP_fast_assign( 569 + __entry->obj = obj ? obj->debug_id : 0; 570 + __entry->inode = inode->i_ino; 571 + ), 572 + 573 + TP_printk("o=%08x B=%lx", 573 574 __entry->obj, __entry->inode) 574 575 ); 575 576 ··· 611 570 __entry->inode = inode->i_ino; 612 571 ), 613 572 614 - TP_printk("o=%08x i=%lx", 573 + TP_printk("o=%08x B=%lx", 615 574 __entry->obj, __entry->inode) 616 575 ); 617 576 ··· 635 594 __entry->where = where; 636 595 ), 637 596 638 - TP_printk("o=%08x b=%08x %s e=%d", 597 + TP_printk("o=%08x B=%x %s e=%d", 639 598 __entry->obj, 640 599 __entry->backer, 641 600 __print_symbolic(__entry->where, cachefiles_error_traces), ··· 662 621 __entry->where = where; 663 622 ), 664 623 665 - TP_printk("o=%08x b=%08x %s e=%d", 624 + TP_printk("o=%08x B=%x %s e=%d", 666 625 __entry->obj, 667 626 __entry->backer, 668 627 __print_symbolic(__entry->where, cachefiles_error_traces),