diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-10-24 22:51:55 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-12-12 17:54:27 -0500 |
commit | 2b1ac852eb67a6e95595e576371d23519105559f (patch) | |
tree | 076e01b89275932db841f55fb604744b5c84bc5a /fs/ceph/caps.c | |
parent | 5c341ee32881c554727ec14b71ec3e8832f01989 (diff) |
ceph: try getting buffer capability for readahead/fadvise
For readahead/fadvise cases, caller of ceph_readpages does not
hold buffer capability. Pages can be added to page cache while
there is no buffer capability. This can cause data integrity
issue.
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 4037b389a7e9..edb407f38b40 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -2479,6 +2479,27 @@ static void check_max_size(struct inode *inode, loff_t endoff) | |||
2479 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); | 2479 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); |
2480 | } | 2480 | } |
2481 | 2481 | ||
2482 | int ceph_try_get_caps(struct ceph_inode_info *ci, int need, int want, int *got) | ||
2483 | { | ||
2484 | int ret, err = 0; | ||
2485 | |||
2486 | BUG_ON(need & ~CEPH_CAP_FILE_RD); | ||
2487 | BUG_ON(want & ~(CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)); | ||
2488 | ret = ceph_pool_perm_check(ci, need); | ||
2489 | if (ret < 0) | ||
2490 | return ret; | ||
2491 | |||
2492 | ret = try_get_cap_refs(ci, need, want, 0, true, got, &err); | ||
2493 | if (ret) { | ||
2494 | if (err == -EAGAIN) { | ||
2495 | ret = 0; | ||
2496 | } else if (err < 0) { | ||
2497 | ret = err; | ||
2498 | } | ||
2499 | } | ||
2500 | return ret; | ||
2501 | } | ||
2502 | |||
2482 | /* | 2503 | /* |
2483 | * Wait for caps, and take cap references. If we can't get a WR cap | 2504 | * Wait for caps, and take cap references. If we can't get a WR cap |
2484 | * due to a small max_size, make sure we check_max_size (and possibly | 2505 | * due to a small max_size, make sure we check_max_size (and possibly |