diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-27 13:56:29 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-27 13:56:29 -0400 |
| commit | 64ebe3126cefa45d7b97a6fc4de846285a55321f (patch) | |
| tree | d5da52890ad750e10aec7ddc6cfc1fb7f7c1381d | |
| parent | d8a332730e757129e70675679f2b2a03f1ecf65e (diff) | |
| parent | 9c55ad1c214d9f8c4594ac2c3fa392c1c32431a7 (diff) | |
Merge tag 'ceph-for-4.17-rc3' of git://github.com/ceph/ceph-client
Pull ceph fixes from Ilya Dryomov:
"A CephFS quota follow-up and fixes for two older issues in the
messenger layer, marked for stable"
* tag 'ceph-for-4.17-rc3' of git://github.com/ceph/ceph-client:
libceph: validate con->state at the top of try_write()
libceph: reschedule a tick in finish_hunting()
libceph: un-backoff on tick when we have a authenticated session
ceph: check if mds create snaprealm when setting quota
| -rw-r--r-- | fs/ceph/xattr.c | 28 | ||||
| -rw-r--r-- | net/ceph/messenger.c | 7 | ||||
| -rw-r--r-- | net/ceph/mon_client.c | 14 |
3 files changed, 43 insertions, 6 deletions
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 7e72348639e4..315f7e63e7cc 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
| @@ -228,7 +228,15 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val, | |||
| 228 | 228 | ||
| 229 | static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci) | 229 | static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci) |
| 230 | { | 230 | { |
| 231 | return (ci->i_max_files || ci->i_max_bytes); | 231 | bool ret = false; |
| 232 | spin_lock(&ci->i_ceph_lock); | ||
| 233 | if ((ci->i_max_files || ci->i_max_bytes) && | ||
| 234 | ci->i_vino.snap == CEPH_NOSNAP && | ||
| 235 | ci->i_snap_realm && | ||
| 236 | ci->i_snap_realm->ino == ci->i_vino.ino) | ||
| 237 | ret = true; | ||
| 238 | spin_unlock(&ci->i_ceph_lock); | ||
| 239 | return ret; | ||
| 232 | } | 240 | } |
| 233 | 241 | ||
| 234 | static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val, | 242 | static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val, |
| @@ -1008,14 +1016,19 @@ int __ceph_setxattr(struct inode *inode, const char *name, | |||
| 1008 | char *newval = NULL; | 1016 | char *newval = NULL; |
| 1009 | struct ceph_inode_xattr *xattr = NULL; | 1017 | struct ceph_inode_xattr *xattr = NULL; |
| 1010 | int required_blob_size; | 1018 | int required_blob_size; |
| 1019 | bool check_realm = false; | ||
| 1011 | bool lock_snap_rwsem = false; | 1020 | bool lock_snap_rwsem = false; |
| 1012 | 1021 | ||
| 1013 | if (ceph_snap(inode) != CEPH_NOSNAP) | 1022 | if (ceph_snap(inode) != CEPH_NOSNAP) |
| 1014 | return -EROFS; | 1023 | return -EROFS; |
| 1015 | 1024 | ||
| 1016 | vxattr = ceph_match_vxattr(inode, name); | 1025 | vxattr = ceph_match_vxattr(inode, name); |
| 1017 | if (vxattr && vxattr->readonly) | 1026 | if (vxattr) { |
| 1018 | return -EOPNOTSUPP; | 1027 | if (vxattr->readonly) |
| 1028 | return -EOPNOTSUPP; | ||
| 1029 | if (value && !strncmp(vxattr->name, "ceph.quota", 10)) | ||
| 1030 | check_realm = true; | ||
| 1031 | } | ||
| 1019 | 1032 | ||
| 1020 | /* pass any unhandled ceph.* xattrs through to the MDS */ | 1033 | /* pass any unhandled ceph.* xattrs through to the MDS */ |
| 1021 | if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) | 1034 | if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) |
| @@ -1109,6 +1122,15 @@ do_sync_unlocked: | |||
| 1109 | err = -EBUSY; | 1122 | err = -EBUSY; |
| 1110 | } else { | 1123 | } else { |
| 1111 | err = ceph_sync_setxattr(inode, name, value, size, flags); | 1124 | err = ceph_sync_setxattr(inode, name, value, size, flags); |
| 1125 | if (err >= 0 && check_realm) { | ||
| 1126 | /* check if snaprealm was created for quota inode */ | ||
| 1127 | spin_lock(&ci->i_ceph_lock); | ||
| 1128 | if ((ci->i_max_files || ci->i_max_bytes) && | ||
| 1129 | !(ci->i_snap_realm && | ||
| 1130 | ci->i_snap_realm->ino == ci->i_vino.ino)) | ||
| 1131 | err = -EOPNOTSUPP; | ||
| 1132 | spin_unlock(&ci->i_ceph_lock); | ||
| 1133 | } | ||
| 1112 | } | 1134 | } |
| 1113 | out: | 1135 | out: |
| 1114 | ceph_free_cap_flush(prealloc_cf); | 1136 | ceph_free_cap_flush(prealloc_cf); |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index fcb40c12b1f8..3b3d33ea9ed8 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
| @@ -2569,6 +2569,11 @@ static int try_write(struct ceph_connection *con) | |||
| 2569 | int ret = 1; | 2569 | int ret = 1; |
| 2570 | 2570 | ||
| 2571 | dout("try_write start %p state %lu\n", con, con->state); | 2571 | dout("try_write start %p state %lu\n", con, con->state); |
| 2572 | if (con->state != CON_STATE_PREOPEN && | ||
| 2573 | con->state != CON_STATE_CONNECTING && | ||
| 2574 | con->state != CON_STATE_NEGOTIATING && | ||
| 2575 | con->state != CON_STATE_OPEN) | ||
| 2576 | return 0; | ||
| 2572 | 2577 | ||
| 2573 | more: | 2578 | more: |
| 2574 | dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes); | 2579 | dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes); |
| @@ -2594,6 +2599,8 @@ more: | |||
| 2594 | } | 2599 | } |
| 2595 | 2600 | ||
| 2596 | more_kvec: | 2601 | more_kvec: |
| 2602 | BUG_ON(!con->sock); | ||
| 2603 | |||
| 2597 | /* kvec data queued? */ | 2604 | /* kvec data queued? */ |
| 2598 | if (con->out_kvec_left) { | 2605 | if (con->out_kvec_left) { |
| 2599 | ret = write_partial_kvec(con); | 2606 | ret = write_partial_kvec(con); |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index b3dac24412d3..21ac6e3b96bb 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
| @@ -209,6 +209,14 @@ static void reopen_session(struct ceph_mon_client *monc) | |||
| 209 | __open_session(monc); | 209 | __open_session(monc); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | static void un_backoff(struct ceph_mon_client *monc) | ||
| 213 | { | ||
| 214 | monc->hunt_mult /= 2; /* reduce by 50% */ | ||
| 215 | if (monc->hunt_mult < 1) | ||
| 216 | monc->hunt_mult = 1; | ||
| 217 | dout("%s hunt_mult now %d\n", __func__, monc->hunt_mult); | ||
| 218 | } | ||
| 219 | |||
| 212 | /* | 220 | /* |
| 213 | * Reschedule delayed work timer. | 221 | * Reschedule delayed work timer. |
| 214 | */ | 222 | */ |
| @@ -963,6 +971,7 @@ static void delayed_work(struct work_struct *work) | |||
| 963 | if (!monc->hunting) { | 971 | if (!monc->hunting) { |
| 964 | ceph_con_keepalive(&monc->con); | 972 | ceph_con_keepalive(&monc->con); |
| 965 | __validate_auth(monc); | 973 | __validate_auth(monc); |
| 974 | un_backoff(monc); | ||
| 966 | } | 975 | } |
| 967 | 976 | ||
| 968 | if (is_auth && | 977 | if (is_auth && |
| @@ -1123,9 +1132,8 @@ static void finish_hunting(struct ceph_mon_client *monc) | |||
| 1123 | dout("%s found mon%d\n", __func__, monc->cur_mon); | 1132 | dout("%s found mon%d\n", __func__, monc->cur_mon); |
| 1124 | monc->hunting = false; | 1133 | monc->hunting = false; |
| 1125 | monc->had_a_connection = true; | 1134 | monc->had_a_connection = true; |
| 1126 | monc->hunt_mult /= 2; /* reduce by 50% */ | 1135 | un_backoff(monc); |
| 1127 | if (monc->hunt_mult < 1) | 1136 | __schedule_delayed(monc); |
| 1128 | monc->hunt_mult = 1; | ||
| 1129 | } | 1137 | } |
| 1130 | } | 1138 | } |
| 1131 | 1139 | ||
