diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-06 14:31:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-06 14:31:13 -0500 |
commit | 21b27a74ec0f4e52e001912c89570a49494705a2 (patch) | |
tree | c9f1bc13a14ad1bd41739e12b92d9510d5b6e6e5 /fs | |
parent | a58b9adaf9f0913af2e5bf69565266335033b4fd (diff) | |
parent | 5ea5c5e0a7f70b256417d3b6e36bd9851504babd (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull ceph fix from Sage Weil:
"This is a final commit we missed to align the protocol compatibility
with the feature bits.
It decodes a few extra fields in two different messages and reports
EIO when they are used (not yet supported)"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
ceph: initial CEPH_FEATURE_FS_FILE_LAYOUT_V2 support
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/addr.c | 4 | ||||
-rw-r--r-- | fs/ceph/caps.c | 27 | ||||
-rw-r--r-- | fs/ceph/inode.c | 2 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 16 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 1 | ||||
-rw-r--r-- | fs/ceph/super.h | 1 |
6 files changed, 48 insertions, 3 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index c22213789090..19adeb0ef82a 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -1756,6 +1756,10 @@ int ceph_pool_perm_check(struct ceph_inode_info *ci, int need) | |||
1756 | u32 pool; | 1756 | u32 pool; |
1757 | int ret, flags; | 1757 | int ret, flags; |
1758 | 1758 | ||
1759 | /* does not support pool namespace yet */ | ||
1760 | if (ci->i_pool_ns_len) | ||
1761 | return -EIO; | ||
1762 | |||
1759 | if (ceph_test_mount_opt(ceph_inode_to_client(&ci->vfs_inode), | 1763 | if (ceph_test_mount_opt(ceph_inode_to_client(&ci->vfs_inode), |
1760 | NOPOOLPERM)) | 1764 | NOPOOLPERM)) |
1761 | return 0; | 1765 | return 0; |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index cdbf8cf3d52c..6fe0ad26a7df 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -2753,7 +2753,8 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc, | |||
2753 | void *inline_data, int inline_len, | 2753 | void *inline_data, int inline_len, |
2754 | struct ceph_buffer *xattr_buf, | 2754 | struct ceph_buffer *xattr_buf, |
2755 | struct ceph_mds_session *session, | 2755 | struct ceph_mds_session *session, |
2756 | struct ceph_cap *cap, int issued) | 2756 | struct ceph_cap *cap, int issued, |
2757 | u32 pool_ns_len) | ||
2757 | __releases(ci->i_ceph_lock) | 2758 | __releases(ci->i_ceph_lock) |
2758 | __releases(mdsc->snap_rwsem) | 2759 | __releases(mdsc->snap_rwsem) |
2759 | { | 2760 | { |
@@ -2873,6 +2874,8 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc, | |||
2873 | if (newcaps & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR)) { | 2874 | if (newcaps & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR)) { |
2874 | /* file layout may have changed */ | 2875 | /* file layout may have changed */ |
2875 | ci->i_layout = grant->layout; | 2876 | ci->i_layout = grant->layout; |
2877 | ci->i_pool_ns_len = pool_ns_len; | ||
2878 | |||
2876 | /* size/truncate_seq? */ | 2879 | /* size/truncate_seq? */ |
2877 | queue_trunc = ceph_fill_file_size(inode, issued, | 2880 | queue_trunc = ceph_fill_file_size(inode, issued, |
2878 | le32_to_cpu(grant->truncate_seq), | 2881 | le32_to_cpu(grant->truncate_seq), |
@@ -3411,6 +3414,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
3411 | u32 inline_len = 0; | 3414 | u32 inline_len = 0; |
3412 | void *snaptrace; | 3415 | void *snaptrace; |
3413 | size_t snaptrace_len; | 3416 | size_t snaptrace_len; |
3417 | u32 pool_ns_len = 0; | ||
3414 | void *p, *end; | 3418 | void *p, *end; |
3415 | 3419 | ||
3416 | dout("handle_caps from mds%d\n", mds); | 3420 | dout("handle_caps from mds%d\n", mds); |
@@ -3463,6 +3467,21 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
3463 | p += inline_len; | 3467 | p += inline_len; |
3464 | } | 3468 | } |
3465 | 3469 | ||
3470 | if (le16_to_cpu(msg->hdr.version) >= 8) { | ||
3471 | u64 flush_tid; | ||
3472 | u32 caller_uid, caller_gid; | ||
3473 | u32 osd_epoch_barrier; | ||
3474 | /* version >= 5 */ | ||
3475 | ceph_decode_32_safe(&p, end, osd_epoch_barrier, bad); | ||
3476 | /* version >= 6 */ | ||
3477 | ceph_decode_64_safe(&p, end, flush_tid, bad); | ||
3478 | /* version >= 7 */ | ||
3479 | ceph_decode_32_safe(&p, end, caller_uid, bad); | ||
3480 | ceph_decode_32_safe(&p, end, caller_gid, bad); | ||
3481 | /* version >= 8 */ | ||
3482 | ceph_decode_32_safe(&p, end, pool_ns_len, bad); | ||
3483 | } | ||
3484 | |||
3466 | /* lookup ino */ | 3485 | /* lookup ino */ |
3467 | inode = ceph_find_inode(sb, vino); | 3486 | inode = ceph_find_inode(sb, vino); |
3468 | ci = ceph_inode(inode); | 3487 | ci = ceph_inode(inode); |
@@ -3518,7 +3537,8 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
3518 | &cap, &issued); | 3537 | &cap, &issued); |
3519 | handle_cap_grant(mdsc, inode, h, | 3538 | handle_cap_grant(mdsc, inode, h, |
3520 | inline_version, inline_data, inline_len, | 3539 | inline_version, inline_data, inline_len, |
3521 | msg->middle, session, cap, issued); | 3540 | msg->middle, session, cap, issued, |
3541 | pool_ns_len); | ||
3522 | if (realm) | 3542 | if (realm) |
3523 | ceph_put_snap_realm(mdsc, realm); | 3543 | ceph_put_snap_realm(mdsc, realm); |
3524 | goto done_unlocked; | 3544 | goto done_unlocked; |
@@ -3542,7 +3562,8 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
3542 | issued |= __ceph_caps_dirty(ci); | 3562 | issued |= __ceph_caps_dirty(ci); |
3543 | handle_cap_grant(mdsc, inode, h, | 3563 | handle_cap_grant(mdsc, inode, h, |
3544 | inline_version, inline_data, inline_len, | 3564 | inline_version, inline_data, inline_len, |
3545 | msg->middle, session, cap, issued); | 3565 | msg->middle, session, cap, issued, |
3566 | pool_ns_len); | ||
3546 | goto done_unlocked; | 3567 | goto done_unlocked; |
3547 | 3568 | ||
3548 | case CEPH_CAP_OP_FLUSH_ACK: | 3569 | case CEPH_CAP_OP_FLUSH_ACK: |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index fb4ba2e4e2a5..5849b88bbed3 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -396,6 +396,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb) | |||
396 | ci->i_symlink = NULL; | 396 | ci->i_symlink = NULL; |
397 | 397 | ||
398 | memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout)); | 398 | memset(&ci->i_dir_layout, 0, sizeof(ci->i_dir_layout)); |
399 | ci->i_pool_ns_len = 0; | ||
399 | 400 | ||
400 | ci->i_fragtree = RB_ROOT; | 401 | ci->i_fragtree = RB_ROOT; |
401 | mutex_init(&ci->i_fragtree_mutex); | 402 | mutex_init(&ci->i_fragtree_mutex); |
@@ -756,6 +757,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page, | |||
756 | if (ci->i_layout.fl_pg_pool != info->layout.fl_pg_pool) | 757 | if (ci->i_layout.fl_pg_pool != info->layout.fl_pg_pool) |
757 | ci->i_ceph_flags &= ~CEPH_I_POOL_PERM; | 758 | ci->i_ceph_flags &= ~CEPH_I_POOL_PERM; |
758 | ci->i_layout = info->layout; | 759 | ci->i_layout = info->layout; |
760 | ci->i_pool_ns_len = iinfo->pool_ns_len; | ||
759 | 761 | ||
760 | queue_trunc = ceph_fill_file_size(inode, issued, | 762 | queue_trunc = ceph_fill_file_size(inode, issued, |
761 | le32_to_cpu(info->truncate_seq), | 763 | le32_to_cpu(info->truncate_seq), |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index e7b130a637f9..911d64d865f1 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -100,6 +100,14 @@ static int parse_reply_info_in(void **p, void *end, | |||
100 | } else | 100 | } else |
101 | info->inline_version = CEPH_INLINE_NONE; | 101 | info->inline_version = CEPH_INLINE_NONE; |
102 | 102 | ||
103 | if (features & CEPH_FEATURE_FS_FILE_LAYOUT_V2) { | ||
104 | ceph_decode_32_safe(p, end, info->pool_ns_len, bad); | ||
105 | ceph_decode_need(p, end, info->pool_ns_len, bad); | ||
106 | *p += info->pool_ns_len; | ||
107 | } else { | ||
108 | info->pool_ns_len = 0; | ||
109 | } | ||
110 | |||
103 | return 0; | 111 | return 0; |
104 | bad: | 112 | bad: |
105 | return err; | 113 | return err; |
@@ -2298,6 +2306,14 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, | |||
2298 | ceph_get_cap_refs(ceph_inode(req->r_old_dentry_dir), | 2306 | ceph_get_cap_refs(ceph_inode(req->r_old_dentry_dir), |
2299 | CEPH_CAP_PIN); | 2307 | CEPH_CAP_PIN); |
2300 | 2308 | ||
2309 | /* deny access to directories with pool_ns layouts */ | ||
2310 | if (req->r_inode && S_ISDIR(req->r_inode->i_mode) && | ||
2311 | ceph_inode(req->r_inode)->i_pool_ns_len) | ||
2312 | return -EIO; | ||
2313 | if (req->r_locked_dir && | ||
2314 | ceph_inode(req->r_locked_dir)->i_pool_ns_len) | ||
2315 | return -EIO; | ||
2316 | |||
2301 | /* issue */ | 2317 | /* issue */ |
2302 | mutex_lock(&mdsc->mutex); | 2318 | mutex_lock(&mdsc->mutex); |
2303 | __register_request(mdsc, req, dir); | 2319 | __register_request(mdsc, req, dir); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index ccf11ef0ca87..37712ccffcc6 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -44,6 +44,7 @@ struct ceph_mds_reply_info_in { | |||
44 | u64 inline_version; | 44 | u64 inline_version; |
45 | u32 inline_len; | 45 | u32 inline_len; |
46 | char *inline_data; | 46 | char *inline_data; |
47 | u32 pool_ns_len; | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | /* | 50 | /* |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 75b7d125ce66..9c458eb52245 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -287,6 +287,7 @@ struct ceph_inode_info { | |||
287 | 287 | ||
288 | struct ceph_dir_layout i_dir_layout; | 288 | struct ceph_dir_layout i_dir_layout; |
289 | struct ceph_file_layout i_layout; | 289 | struct ceph_file_layout i_layout; |
290 | size_t i_pool_ns_len; | ||
290 | char *i_symlink; | 291 | char *i_symlink; |
291 | 292 | ||
292 | /* for dirs */ | 293 | /* for dirs */ |