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
Unified · Split
| @@ -354,6 +354,45 @@ out: · 353 unmodified lines | |||
| 354 | dout("%s: result %d\n", __func__, err); | 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 | static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) | 396 | static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) |
| 358 | { | 397 | { |
| 359 | struct inode *inode = mapping->host; | 398 | struct inode *inode = mapping->host; |
| @@ -365,7 +404,7 @@ static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) · 5 unmodified lines | |||
| 365 | } | 404 | } |
| 366 | 405 | ||
| 367 | static const struct netfs_request_ops ceph_netfs_read_ops = { | 406 | static const struct netfs_request_ops ceph_netfs_read_ops = { |
| 368 | .is_cache_enabled = ceph_is_cache_enabled, | 407 | .init_request = ceph_init_request, |
| 369 | .begin_cache_operation = ceph_begin_cache_operation, | 408 | .begin_cache_operation = ceph_begin_cache_operation, |
| 370 | .issue_read = ceph_netfs_issue_read, | 409 | .issue_read = ceph_netfs_issue_read, |
| 371 | .expand_readahead = ceph_netfs_expand_readahead, | 410 | .expand_readahead = ceph_netfs_expand_readahead, |
| @@ -393,33 +432,7 @@ static int ceph_readpage(struct file *file, struct page *subpage) · 21 unmodified lines | |||
| 393 | 432 | ||
| 394 | static void ceph_readahead(struct readahead_control *ractl) | 433 | static void ceph_readahead(struct readahead_control *ractl) |
| 395 | { | 434 | { |
| 396 | struct inode *inode = file_inode(ractl->file); | 435 | netfs_readahead(ractl, &ceph_netfs_read_ops, NULL); |
| 397 | struct ceph_file_info *fi = ractl->file->private_data; | ||
| 398 | struct ceph_rw_context *rw_ctx; | ||
| 399 | int got = 0; | ||
| 400 | int ret = 0; | ||
| 401 | |||
| 402 | if (ceph_inode(inode)->i_inline_version != CEPH_INLINE_NONE) | ||
| 403 | return; | ||
| 404 | |||
| 405 | rw_ctx = ceph_find_rw_context(fi); | ||
| 406 | if (!rw_ctx) { | ||
| 407 | /* | ||
| 408 | * readahead callers do not necessarily hold Fcb caps | ||
| 409 | * (e.g. fadvise, madvise). | ||
| 410 | */ | ||
| 411 | int want = CEPH_CAP_FILE_CACHE; | ||
| 412 | |||
| 413 | ret = ceph_try_get_caps(inode, CEPH_CAP_FILE_RD, want, true, &got); | ||
| 414 | if (ret < 0) | ||
| 415 | dout("start_read %p, error getting cap\n", inode); | ||
| 416 | else if (!(got & want)) | ||
| 417 | dout("start_read %p, no cache cap\n", inode); | ||
| 418 | |||
| 419 | if (ret <= 0) | ||
| 420 | return; | ||
| 421 | } | ||
| 422 | netfs_readahead(ractl, &ceph_netfs_read_ops, (void *)(uintptr_t)got); | ||
| 423 | } | 436 | } |
| 424 | 437 | ||
| 425 | #ifdef CONFIG_CEPH_FSCACHE | 438 | #ifdef CONFIG_CEPH_FSCACHE |