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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ceph-for-5.13-rc8' of https://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
"Two regression fixes from the merge window: one in the auth code
affecting old clusters and one in the filesystem for proper
propagation of MDS request errors.

Also included a locking fix for async creates, marked for stable"

* tag 'ceph-for-5.13-rc8' of https://github.com/ceph/ceph-client:
libceph: set global_id as soon as we get an auth ticket
libceph: don't pass result into ac->ops->handle_reply()
ceph: fix error handling in ceph_atomic_open and ceph_lookup
ceph: must hold snap_rwsem when filling inode for async create

+50 -37
+12 -10
fs/ceph/dir.c
··· 668 668 * Handle lookups for the hidden .snap directory. 669 669 */ 670 670 struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req, 671 - struct dentry *dentry, int err) 671 + struct dentry *dentry) 672 672 { 673 673 struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); 674 674 struct inode *parent = d_inode(dentry->d_parent); /* we hold i_mutex */ 675 675 676 676 /* .snap dir? */ 677 - if (err == -ENOENT && 678 - ceph_snap(parent) == CEPH_NOSNAP && 677 + if (ceph_snap(parent) == CEPH_NOSNAP && 679 678 strcmp(dentry->d_name.name, fsc->mount_options->snapdir_name) == 0) { 680 679 struct dentry *res; 681 680 struct inode *inode = ceph_get_snapdir(parent); ··· 741 742 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); 742 743 struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); 743 744 struct ceph_mds_request *req; 744 - struct dentry *res; 745 745 int op; 746 746 int mask; 747 747 int err; ··· 791 793 req->r_parent = dir; 792 794 set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags); 793 795 err = ceph_mdsc_do_request(mdsc, NULL, req); 794 - res = ceph_handle_snapdir(req, dentry, err); 795 - if (IS_ERR(res)) { 796 - err = PTR_ERR(res); 797 - } else { 798 - dentry = res; 799 - err = 0; 796 + if (err == -ENOENT) { 797 + struct dentry *res; 798 + 799 + res = ceph_handle_snapdir(req, dentry); 800 + if (IS_ERR(res)) { 801 + err = PTR_ERR(res); 802 + } else { 803 + dentry = res; 804 + err = 0; 805 + } 800 806 } 801 807 dentry = ceph_finish_lookup(req, dentry, err); 802 808 ceph_mdsc_put_request(req); /* will dput(dentry) */
+11 -6
fs/ceph/file.c
··· 578 578 struct ceph_inode_info *ci = ceph_inode(dir); 579 579 struct inode *inode; 580 580 struct timespec64 now; 581 + struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb); 581 582 struct ceph_vino vino = { .ino = req->r_deleg_ino, 582 583 .snap = CEPH_NOSNAP }; 583 584 ··· 616 615 617 616 ceph_file_layout_to_legacy(lo, &in.layout); 618 617 618 + down_read(&mdsc->snap_rwsem); 619 619 ret = ceph_fill_inode(inode, NULL, &iinfo, NULL, req->r_session, 620 620 req->r_fmode, NULL); 621 + up_read(&mdsc->snap_rwsem); 621 622 if (ret) { 622 623 dout("%s failed to fill inode: %d\n", __func__, ret); 623 624 ceph_dir_clear_complete(dir); ··· 742 739 err = ceph_mdsc_do_request(mdsc, 743 740 (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, 744 741 req); 745 - dentry = ceph_handle_snapdir(req, dentry, err); 746 - if (IS_ERR(dentry)) { 747 - err = PTR_ERR(dentry); 748 - goto out_req; 742 + if (err == -ENOENT) { 743 + dentry = ceph_handle_snapdir(req, dentry); 744 + if (IS_ERR(dentry)) { 745 + err = PTR_ERR(dentry); 746 + goto out_req; 747 + } 748 + err = 0; 749 749 } 750 - err = 0; 751 750 752 - if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry) 751 + if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) 753 752 err = ceph_handle_notrace_create(dir, dentry); 754 753 755 754 if (d_in_lookup(dentry)) {
+2
fs/ceph/inode.c
··· 777 777 umode_t mode = le32_to_cpu(info->mode); 778 778 dev_t rdev = le32_to_cpu(info->rdev); 779 779 780 + lockdep_assert_held(&mdsc->snap_rwsem); 781 + 780 782 dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__, 781 783 inode, ceph_vinop(inode), le64_to_cpu(info->version), 782 784 ci->i_version);
+1 -1
fs/ceph/super.h
··· 1218 1218 extern loff_t ceph_make_fpos(unsigned high, unsigned off, bool hash_order); 1219 1219 extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry); 1220 1220 extern struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req, 1221 - struct dentry *dentry, int err); 1221 + struct dentry *dentry); 1222 1222 extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, 1223 1223 struct dentry *dentry, int err); 1224 1224
+3 -1
include/linux/ceph/auth.h
··· 50 50 * another request. 51 51 */ 52 52 int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end); 53 - int (*handle_reply)(struct ceph_auth_client *ac, int result, 53 + int (*handle_reply)(struct ceph_auth_client *ac, u64 global_id, 54 54 void *buf, void *end, u8 *session_key, 55 55 int *session_key_len, u8 *con_secret, 56 56 int *con_secret_len); ··· 103 103 104 104 struct mutex mutex; 105 105 }; 106 + 107 + void ceph_auth_set_global_id(struct ceph_auth_client *ac, u64 global_id); 106 108 107 109 struct ceph_auth_client *ceph_auth_init(const char *name, 108 110 const struct ceph_crypto_key *key,
+11 -9
net/ceph/auth.c
··· 36 36 } 37 37 } 38 38 39 - static void set_global_id(struct ceph_auth_client *ac, u64 global_id) 39 + void ceph_auth_set_global_id(struct ceph_auth_client *ac, u64 global_id) 40 40 { 41 41 dout("%s global_id %llu\n", __func__, global_id); 42 42 ··· 260 260 ac->negotiating = false; 261 261 } 262 262 263 - ret = ac->ops->handle_reply(ac, result, payload, payload_end, 263 + if (result) { 264 + pr_err("auth protocol '%s' mauth authentication failed: %d\n", 265 + ceph_auth_proto_name(ac->protocol), result); 266 + ret = result; 267 + goto out; 268 + } 269 + 270 + ret = ac->ops->handle_reply(ac, global_id, payload, payload_end, 264 271 NULL, NULL, NULL, NULL); 265 272 if (ret == -EAGAIN) { 266 273 ret = build_request(ac, true, reply_buf, reply_len); 267 274 goto out; 268 275 } else if (ret) { 269 - pr_err("auth protocol '%s' mauth authentication failed: %d\n", 270 - ceph_auth_proto_name(ac->protocol), result); 271 276 goto out; 272 277 } 273 - 274 - set_global_id(ac, global_id); 275 278 276 279 out: 277 280 mutex_unlock(&ac->mutex); ··· 501 498 int ret; 502 499 503 500 mutex_lock(&ac->mutex); 504 - ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len, 501 + ret = ac->ops->handle_reply(ac, global_id, reply, reply + reply_len, 505 502 session_key, session_key_len, 506 503 con_secret, con_secret_len); 507 - if (!ret) 508 - set_global_id(ac, global_id); 504 + WARN_ON(ret == -EAGAIN || ret > 0); 509 505 mutex_unlock(&ac->mutex); 510 506 return ret; 511 507 }
+3 -2
net/ceph/auth_none.c
··· 69 69 * the generic auth code decode the global_id, and we carry no actual 70 70 * authenticate state, so nothing happens here. 71 71 */ 72 - static int handle_reply(struct ceph_auth_client *ac, int result, 72 + static int handle_reply(struct ceph_auth_client *ac, u64 global_id, 73 73 void *buf, void *end, u8 *session_key, 74 74 int *session_key_len, u8 *con_secret, 75 75 int *con_secret_len) ··· 77 77 struct ceph_auth_none_info *xi = ac->private; 78 78 79 79 xi->starting = false; 80 - return result; 80 + ceph_auth_set_global_id(ac, global_id); 81 + return 0; 81 82 } 82 83 83 84 static void ceph_auth_none_destroy_authorizer(struct ceph_authorizer *a)
+7 -8
net/ceph/auth_x.c
··· 597 597 return -EINVAL; 598 598 } 599 599 600 - static int handle_auth_session_key(struct ceph_auth_client *ac, 600 + static int handle_auth_session_key(struct ceph_auth_client *ac, u64 global_id, 601 601 void **p, void *end, 602 602 u8 *session_key, int *session_key_len, 603 603 u8 *con_secret, int *con_secret_len) ··· 613 613 if (ret) 614 614 return ret; 615 615 616 + ceph_auth_set_global_id(ac, global_id); 616 617 if (*p == end) { 617 618 /* pre-nautilus (or didn't request service tickets!) */ 618 619 WARN_ON(session_key || con_secret); ··· 662 661 return -EINVAL; 663 662 } 664 663 665 - static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, 664 + static int ceph_x_handle_reply(struct ceph_auth_client *ac, u64 global_id, 666 665 void *buf, void *end, 667 666 u8 *session_key, int *session_key_len, 668 667 u8 *con_secret, int *con_secret_len) ··· 670 669 struct ceph_x_info *xi = ac->private; 671 670 struct ceph_x_ticket_handler *th; 672 671 int len = end - buf; 672 + int result; 673 673 void *p; 674 674 int op; 675 675 int ret; 676 - 677 - if (result) 678 - return result; /* XXX hmm? */ 679 676 680 677 if (xi->starting) { 681 678 /* it's a hello */ ··· 696 697 switch (op) { 697 698 case CEPHX_GET_AUTH_SESSION_KEY: 698 699 /* AUTH ticket + [connection secret] + service tickets */ 699 - ret = handle_auth_session_key(ac, &p, end, session_key, 700 - session_key_len, con_secret, 701 - con_secret_len); 700 + ret = handle_auth_session_key(ac, global_id, &p, end, 701 + session_key, session_key_len, 702 + con_secret, con_secret_len); 702 703 break; 703 704 704 705 case CEPHX_GET_PRINCIPAL_SESSION_KEY: