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

ceph: Make ceph_init_request() check caps on readahead

Move the caps check from ceph_readahead() to ceph_init_request(),
conditional on the origin being NETFS_READAHEAD so that in a future patch,
ceph can point its ->readahead() vector directly at netfs_readahead().

Changes
=======
ver #4)
- Move the check for NETFS_READAHEAD up in ceph_init_request()[2].

ver #3)
- Split from the patch to add a netfs inode context[1].
- Need to store the caps got in rreq->netfs_priv for later freeing.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: ceph-devel@vger.kernel.org
cc: linux-cachefs@redhat.com

Link: https://lore.kernel.org/r/8af0d47f17d89c06bbf602496dd845f2b0bf25b3.camel@kernel.org/ [1]
Link: https://lore.kernel.org/r/dd054c962818716e718bd9b446ee5322ca097675.camel@redhat.com/ [2]
Link: https://lore.kernel.org/r/164692907694.2099075.10081819855690054094.stgit@warthog.procyon.org.uk/ # v3
Link: https://lore.kernel.org/r/2533821.1647006574@warthog.procyon.org.uk/ # v4

+41 -28
+41 -28
fs/ceph/addr.c
··· 354 354 dout("%s: result %d\n", __func__, err); 355 355 } 356 356 357 + static int ceph_init_request(struct netfs_io_request *rreq, struct file *file) 358 + { 359 + struct inode *inode = rreq->inode; 360 + int got = 0, want = CEPH_CAP_FILE_CACHE; 361 + int ret = 0; 362 + 363 + if (rreq->origin != NETFS_READAHEAD) 364 + return 0; 365 + 366 + if (file) { 367 + struct ceph_rw_context *rw_ctx; 368 + struct ceph_file_info *fi = file->private_data; 369 + 370 + rw_ctx = ceph_find_rw_context(fi); 371 + if (rw_ctx) 372 + return 0; 373 + } 374 + 375 + /* 376 + * readahead callers do not necessarily hold Fcb caps 377 + * (e.g. fadvise, madvise). 378 + */ 379 + ret = ceph_try_get_caps(inode, CEPH_CAP_FILE_RD, want, true, &got); 380 + if (ret < 0) { 381 + dout("start_read %p, error getting cap\n", inode); 382 + return ret; 383 + } 384 + 385 + if (!(got & want)) { 386 + dout("start_read %p, no cache cap\n", inode); 387 + return -EACCES; 388 + } 389 + if (ret == 0) 390 + return -EACCES; 391 + 392 + rreq->netfs_priv = (void *)(uintptr_t)got; 393 + return 0; 394 + } 395 + 357 396 static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) 358 397 { 359 398 struct inode *inode = mapping->host; ··· 404 365 } 405 366 406 367 static const struct netfs_request_ops ceph_netfs_read_ops = { 407 - .is_cache_enabled = ceph_is_cache_enabled, 368 + .init_request = ceph_init_request, 408 369 .begin_cache_operation = ceph_begin_cache_operation, 409 370 .issue_read = ceph_netfs_issue_read, 410 371 .expand_readahead = ceph_netfs_expand_readahead, ··· 432 393 433 394 static void ceph_readahead(struct readahead_control *ractl) 434 395 { 435 - struct inode *inode = file_inode(ractl->file); 436 - struct ceph_file_info *fi = ractl->file->private_data; 437 - struct ceph_rw_context *rw_ctx; 438 - int got = 0; 439 - int ret = 0; 440 - 441 - if (ceph_inode(inode)->i_inline_version != CEPH_INLINE_NONE) 442 - return; 443 - 444 - rw_ctx = ceph_find_rw_context(fi); 445 - if (!rw_ctx) { 446 - /* 447 - * readahead callers do not necessarily hold Fcb caps 448 - * (e.g. fadvise, madvise). 449 - */ 450 - int want = CEPH_CAP_FILE_CACHE; 451 - 452 - ret = ceph_try_get_caps(inode, CEPH_CAP_FILE_RD, want, true, &got); 453 - if (ret < 0) 454 - dout("start_read %p, error getting cap\n", inode); 455 - else if (!(got & want)) 456 - dout("start_read %p, no cache cap\n", inode); 457 - 458 - if (ret <= 0) 459 - return; 460 - } 461 - netfs_readahead(ractl, &ceph_netfs_read_ops, (void *)(uintptr_t)got); 396 + netfs_readahead(ractl, &ceph_netfs_read_ops, NULL); 462 397 } 463 398 464 399 #ifdef CONFIG_CEPH_FSCACHE