Skip to content

Commit edf54d9

Browse files
committed
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
2 parents 9e736cf + 03af4c7 commit edf54d9

File tree

8 files changed

+50
-37
lines changed

8 files changed

+50
-37
lines changed

fs/ceph/dir.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -668,14 +668,13 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
668668
* Handle lookups for the hidden .snap directory.
669669
*/
670670
struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req,
671-
struct dentry *dentry, int err)
671+
struct dentry *dentry)
672672
{
673673
struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb);
674674
struct inode *parent = d_inode(dentry->d_parent); /* we hold i_mutex */
675675

676676
/* .snap dir? */
677-
if (err == -ENOENT &&
678-
ceph_snap(parent) == CEPH_NOSNAP &&
677+
if (ceph_snap(parent) == CEPH_NOSNAP &&
679678
strcmp(dentry->d_name.name, fsc->mount_options->snapdir_name) == 0) {
680679
struct dentry *res;
681680
struct inode *inode = ceph_get_snapdir(parent);
@@ -742,7 +741,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
742741
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
743742
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
744743
struct ceph_mds_request *req;
745-
struct dentry *res;
746744
int op;
747745
int mask;
748746
int err;
@@ -793,12 +791,16 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
793791
req->r_parent = dir;
794792
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
795793
err = ceph_mdsc_do_request(mdsc, NULL, req);
796-
res = ceph_handle_snapdir(req, dentry, err);
797-
if (IS_ERR(res)) {
798-
err = PTR_ERR(res);
799-
} else {
800-
dentry = res;
801-
err = 0;
794+
if (err == -ENOENT) {
795+
struct dentry *res;
796+
797+
res = ceph_handle_snapdir(req, dentry);
798+
if (IS_ERR(res)) {
799+
err = PTR_ERR(res);
800+
} else {
801+
dentry = res;
802+
err = 0;
803+
}
802804
}
803805
dentry = ceph_finish_lookup(req, dentry, err);
804806
ceph_mdsc_put_request(req); /* will dput(dentry) */

fs/ceph/file.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
578578
struct ceph_inode_info *ci = ceph_inode(dir);
579579
struct inode *inode;
580580
struct timespec64 now;
581+
struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
581582
struct ceph_vino vino = { .ino = req->r_deleg_ino,
582583
.snap = CEPH_NOSNAP };
583584

@@ -615,8 +616,10 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
615616

616617
ceph_file_layout_to_legacy(lo, &in.layout);
617618

619+
down_read(&mdsc->snap_rwsem);
618620
ret = ceph_fill_inode(inode, NULL, &iinfo, NULL, req->r_session,
619621
req->r_fmode, NULL);
622+
up_read(&mdsc->snap_rwsem);
620623
if (ret) {
621624
dout("%s failed to fill inode: %d\n", __func__, ret);
622625
ceph_dir_clear_complete(dir);
@@ -739,14 +742,16 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
739742
err = ceph_mdsc_do_request(mdsc,
740743
(flags & (O_CREAT|O_TRUNC)) ? dir : NULL,
741744
req);
742-
dentry = ceph_handle_snapdir(req, dentry, err);
743-
if (IS_ERR(dentry)) {
744-
err = PTR_ERR(dentry);
745-
goto out_req;
745+
if (err == -ENOENT) {
746+
dentry = ceph_handle_snapdir(req, dentry);
747+
if (IS_ERR(dentry)) {
748+
err = PTR_ERR(dentry);
749+
goto out_req;
750+
}
751+
err = 0;
746752
}
747-
err = 0;
748753

749-
if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
754+
if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
750755
err = ceph_handle_notrace_create(dir, dentry);
751756

752757
if (d_in_lookup(dentry)) {

fs/ceph/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,8 @@ int ceph_fill_inode(struct inode *inode, struct page *locked_page,
777777
umode_t mode = le32_to_cpu(info->mode);
778778
dev_t rdev = le32_to_cpu(info->rdev);
779779

780+
lockdep_assert_held(&mdsc->snap_rwsem);
781+
780782
dout("%s %p ino %llx.%llx v %llu had %llu\n", __func__,
781783
inode, ceph_vinop(inode), le64_to_cpu(info->version),
782784
ci->i_version);

fs/ceph/super.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1218,7 +1218,7 @@ extern const struct dentry_operations ceph_dentry_ops;
12181218
extern loff_t ceph_make_fpos(unsigned high, unsigned off, bool hash_order);
12191219
extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry);
12201220
extern struct dentry *ceph_handle_snapdir(struct ceph_mds_request *req,
1221-
struct dentry *dentry, int err);
1221+
struct dentry *dentry);
12221222
extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
12231223
struct dentry *dentry, int err);
12241224

include/linux/ceph/auth.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct ceph_auth_client_ops {
5050
* another request.
5151
*/
5252
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,
5454
void *buf, void *end, u8 *session_key,
5555
int *session_key_len, u8 *con_secret,
5656
int *con_secret_len);
@@ -104,6 +104,8 @@ struct ceph_auth_client {
104104
struct mutex mutex;
105105
};
106106

107+
void ceph_auth_set_global_id(struct ceph_auth_client *ac, u64 global_id);
108+
107109
struct ceph_auth_client *ceph_auth_init(const char *name,
108110
const struct ceph_crypto_key *key,
109111
const int *con_modes);

net/ceph/auth.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static int init_protocol(struct ceph_auth_client *ac, int proto)
3636
}
3737
}
3838

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)
4040
{
4141
dout("%s global_id %llu\n", __func__, global_id);
4242

@@ -260,19 +260,22 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac,
260260
ac->negotiating = false;
261261
}
262262

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,
264271
NULL, NULL, NULL, NULL);
265272
if (ret == -EAGAIN) {
266273
ret = build_request(ac, true, reply_buf, reply_len);
267274
goto out;
268275
} else if (ret) {
269-
pr_err("auth protocol '%s' mauth authentication failed: %d\n",
270-
ceph_auth_proto_name(ac->protocol), result);
271276
goto out;
272277
}
273278

274-
set_global_id(ac, global_id);
275-
276279
out:
277280
mutex_unlock(&ac->mutex);
278281
return ret;
@@ -498,11 +501,10 @@ int ceph_auth_handle_reply_done(struct ceph_auth_client *ac,
498501
int ret;
499502

500503
mutex_lock(&ac->mutex);
501-
ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len,
504+
ret = ac->ops->handle_reply(ac, global_id, reply, reply + reply_len,
502505
session_key, session_key_len,
503506
con_secret, con_secret_len);
504-
if (!ret)
505-
set_global_id(ac, global_id);
507+
WARN_ON(ret == -EAGAIN || ret > 0);
506508
mutex_unlock(&ac->mutex);
507509
return ret;
508510
}

net/ceph/auth_none.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,16 @@ static int build_request(struct ceph_auth_client *ac, void *buf, void *end)
6969
* the generic auth code decode the global_id, and we carry no actual
7070
* authenticate state, so nothing happens here.
7171
*/
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,
7373
void *buf, void *end, u8 *session_key,
7474
int *session_key_len, u8 *con_secret,
7575
int *con_secret_len)
7676
{
7777
struct ceph_auth_none_info *xi = ac->private;
7878

7979
xi->starting = false;
80-
return result;
80+
ceph_auth_set_global_id(ac, global_id);
81+
return 0;
8182
}
8283

8384
static void ceph_auth_none_destroy_authorizer(struct ceph_authorizer *a)

net/ceph/auth_x.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ static int decode_con_secret(void **p, void *end, u8 *con_secret,
597597
return -EINVAL;
598598
}
599599

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,
601601
void **p, void *end,
602602
u8 *session_key, int *session_key_len,
603603
u8 *con_secret, int *con_secret_len)
@@ -613,6 +613,7 @@ static int handle_auth_session_key(struct ceph_auth_client *ac,
613613
if (ret)
614614
return ret;
615615

616+
ceph_auth_set_global_id(ac, global_id);
616617
if (*p == end) {
617618
/* pre-nautilus (or didn't request service tickets!) */
618619
WARN_ON(session_key || con_secret);
@@ -661,21 +662,19 @@ static int handle_auth_session_key(struct ceph_auth_client *ac,
661662
return -EINVAL;
662663
}
663664

664-
static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
665+
static int ceph_x_handle_reply(struct ceph_auth_client *ac, u64 global_id,
665666
void *buf, void *end,
666667
u8 *session_key, int *session_key_len,
667668
u8 *con_secret, int *con_secret_len)
668669
{
669670
struct ceph_x_info *xi = ac->private;
670671
struct ceph_x_ticket_handler *th;
671672
int len = end - buf;
673+
int result;
672674
void *p;
673675
int op;
674676
int ret;
675677

676-
if (result)
677-
return result; /* XXX hmm? */
678-
679678
if (xi->starting) {
680679
/* it's a hello */
681680
struct ceph_x_server_challenge *sc = buf;
@@ -697,9 +696,9 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
697696
switch (op) {
698697
case CEPHX_GET_AUTH_SESSION_KEY:
699698
/* AUTH ticket + [connection secret] + service tickets */
700-
ret = handle_auth_session_key(ac, &p, end, session_key,
701-
session_key_len, con_secret,
702-
con_secret_len);
699+
ret = handle_auth_session_key(ac, global_id, &p, end,
700+
session_key, session_key_len,
701+
con_secret, con_secret_len);
703702
break;
704703

705704
case CEPHX_GET_PRINCIPAL_SESSION_KEY:

0 commit comments

Comments
 (0)