Skip to content

Commit f753c4e

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull ceph fixes from Sage Weil: "Jim's fix closes a narrow race introduced with the msgr changes. One fix resolves problems with debugfs initialization that Yan found when multiple client instances are created (e.g., two clusters mounted, or rbd + cephfs), another one fixes problems with mounting a nonexistent server subdirectory, and the last one fixes a divide by zero error from unsanitized ioctl input that Dan Carpenter found." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: ceph: avoid divide by zero in __validate_layout() libceph: avoid truncation due to racing banners ceph: tolerate (and warn on) extraneous dentry from mds libceph: delay debugfs initialization until we learn global_id
2 parents ad746be + 45f2e08 commit f753c4e

File tree

7 files changed

+72
-14
lines changed

7 files changed

+72
-14
lines changed

fs/ceph/debugfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
201201
int err = -ENOMEM;
202202

203203
dout("ceph_fs_debugfs_init\n");
204+
BUG_ON(!fsc->client->debugfs_dir);
204205
fsc->debugfs_congestion_kb =
205206
debugfs_create_file("writeback_congestion_kb",
206207
0600,

fs/ceph/inode.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -992,18 +992,23 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
992992
if (rinfo->head->is_dentry) {
993993
struct inode *dir = req->r_locked_dir;
994994

995-
err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
996-
session, req->r_request_started, -1,
997-
&req->r_caps_reservation);
998-
if (err < 0)
999-
return err;
995+
if (dir) {
996+
err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
997+
session, req->r_request_started, -1,
998+
&req->r_caps_reservation);
999+
if (err < 0)
1000+
return err;
1001+
} else {
1002+
WARN_ON_ONCE(1);
1003+
}
10001004
}
10011005

10021006
/*
10031007
* ignore null lease/binding on snapdir ENOENT, or else we
10041008
* will have trouble splicing in the virtual snapdir later
10051009
*/
10061010
if (rinfo->head->is_dentry && !req->r_aborted &&
1011+
req->r_locked_dir &&
10071012
(rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
10081013
fsc->mount_options->snapdir_name,
10091014
req->r_dentry->d_name.len))) {

fs/ceph/ioctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ static long __validate_layout(struct ceph_mds_client *mdsc,
4242
/* validate striping parameters */
4343
if ((l->object_size & ~PAGE_MASK) ||
4444
(l->stripe_unit & ~PAGE_MASK) ||
45-
((unsigned)l->object_size % (unsigned)l->stripe_unit))
45+
(l->stripe_unit != 0 &&
46+
((unsigned)l->object_size % (unsigned)l->stripe_unit)))
4647
return -EINVAL;
4748

4849
/* make sure it's a valid data pool */

net/ceph/ceph_common.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid)
8484
return -1;
8585
}
8686
} else {
87-
pr_info("client%lld fsid %pU\n", ceph_client_id(client), fsid);
8887
memcpy(&client->fsid, fsid, sizeof(*fsid));
8988
}
9089
return 0;

net/ceph/debugfs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ int ceph_debugfs_client_init(struct ceph_client *client)
189189
snprintf(name, sizeof(name), "%pU.client%lld", &client->fsid,
190190
client->monc.auth->global_id);
191191

192+
dout("ceph_debugfs_client_init %p %s\n", client, name);
193+
194+
BUG_ON(client->debugfs_dir);
192195
client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir);
193196
if (!client->debugfs_dir)
194197
goto out;
@@ -234,6 +237,7 @@ int ceph_debugfs_client_init(struct ceph_client *client)
234237

235238
void ceph_debugfs_client_cleanup(struct ceph_client *client)
236239
{
240+
dout("ceph_debugfs_client_cleanup %p\n", client);
237241
debugfs_remove(client->debugfs_osdmap);
238242
debugfs_remove(client->debugfs_monmap);
239243
debugfs_remove(client->osdc.debugfs_file);

net/ceph/messenger.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,6 @@ static int prepare_write_connect(struct ceph_connection *con)
915915
con->out_connect.authorizer_len = auth ?
916916
cpu_to_le32(auth->authorizer_buf_len) : 0;
917917

918-
con_out_kvec_reset(con);
919918
con_out_kvec_add(con, sizeof (con->out_connect),
920919
&con->out_connect);
921920
if (auth && auth->authorizer_buf_len)
@@ -1557,6 +1556,7 @@ static int process_connect(struct ceph_connection *con)
15571556
return -1;
15581557
}
15591558
con->auth_retry = 1;
1559+
con_out_kvec_reset(con);
15601560
ret = prepare_write_connect(con);
15611561
if (ret < 0)
15621562
return ret;
@@ -1577,6 +1577,7 @@ static int process_connect(struct ceph_connection *con)
15771577
ENTITY_NAME(con->peer_name),
15781578
ceph_pr_addr(&con->peer_addr.in_addr));
15791579
reset_connection(con);
1580+
con_out_kvec_reset(con);
15801581
ret = prepare_write_connect(con);
15811582
if (ret < 0)
15821583
return ret;
@@ -1601,6 +1602,7 @@ static int process_connect(struct ceph_connection *con)
16011602
le32_to_cpu(con->out_connect.connect_seq),
16021603
le32_to_cpu(con->in_reply.connect_seq));
16031604
con->connect_seq = le32_to_cpu(con->in_reply.connect_seq);
1605+
con_out_kvec_reset(con);
16041606
ret = prepare_write_connect(con);
16051607
if (ret < 0)
16061608
return ret;
@@ -1617,6 +1619,7 @@ static int process_connect(struct ceph_connection *con)
16171619
le32_to_cpu(con->in_reply.global_seq));
16181620
get_global_seq(con->msgr,
16191621
le32_to_cpu(con->in_reply.global_seq));
1622+
con_out_kvec_reset(con);
16201623
ret = prepare_write_connect(con);
16211624
if (ret < 0)
16221625
return ret;
@@ -2135,7 +2138,11 @@ static int try_read(struct ceph_connection *con)
21352138
BUG_ON(con->state != CON_STATE_CONNECTING);
21362139
con->state = CON_STATE_NEGOTIATING;
21372140

2138-
/* Banner is good, exchange connection info */
2141+
/*
2142+
* Received banner is good, exchange connection info.
2143+
* Do not reset out_kvec, as sending our banner raced
2144+
* with receiving peer banner after connect completed.
2145+
*/
21392146
ret = prepare_write_connect(con);
21402147
if (ret < 0)
21412148
goto out;

net/ceph/mon_client.c

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,17 @@ int ceph_monc_open_session(struct ceph_mon_client *monc)
310310
}
311311
EXPORT_SYMBOL(ceph_monc_open_session);
312312

313+
/*
314+
* We require the fsid and global_id in order to initialize our
315+
* debugfs dir.
316+
*/
317+
static bool have_debugfs_info(struct ceph_mon_client *monc)
318+
{
319+
dout("have_debugfs_info fsid %d globalid %lld\n",
320+
(int)monc->client->have_fsid, monc->auth->global_id);
321+
return monc->client->have_fsid && monc->auth->global_id > 0;
322+
}
323+
313324
/*
314325
* The monitor responds with mount ack indicate mount success. The
315326
* included client ticket allows the client to talk to MDSs and OSDs.
@@ -320,9 +331,12 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
320331
struct ceph_client *client = monc->client;
321332
struct ceph_monmap *monmap = NULL, *old = monc->monmap;
322333
void *p, *end;
334+
int had_debugfs_info, init_debugfs = 0;
323335

324336
mutex_lock(&monc->mutex);
325337

338+
had_debugfs_info = have_debugfs_info(monc);
339+
326340
dout("handle_monmap\n");
327341
p = msg->front.iov_base;
328342
end = p + msg->front.iov_len;
@@ -344,12 +358,22 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
344358

345359
if (!client->have_fsid) {
346360
client->have_fsid = true;
361+
if (!had_debugfs_info && have_debugfs_info(monc)) {
362+
pr_info("client%lld fsid %pU\n",
363+
ceph_client_id(monc->client),
364+
&monc->client->fsid);
365+
init_debugfs = 1;
366+
}
347367
mutex_unlock(&monc->mutex);
348-
/*
349-
* do debugfs initialization without mutex to avoid
350-
* creating a locking dependency
351-
*/
352-
ceph_debugfs_client_init(client);
368+
369+
if (init_debugfs) {
370+
/*
371+
* do debugfs initialization without mutex to avoid
372+
* creating a locking dependency
373+
*/
374+
ceph_debugfs_client_init(monc->client);
375+
}
376+
353377
goto out_unlocked;
354378
}
355379
out:
@@ -865,8 +889,10 @@ static void handle_auth_reply(struct ceph_mon_client *monc,
865889
{
866890
int ret;
867891
int was_auth = 0;
892+
int had_debugfs_info, init_debugfs = 0;
868893

869894
mutex_lock(&monc->mutex);
895+
had_debugfs_info = have_debugfs_info(monc);
870896
if (monc->auth->ops)
871897
was_auth = monc->auth->ops->is_authenticated(monc->auth);
872898
monc->pending_auth = 0;
@@ -889,7 +915,22 @@ static void handle_auth_reply(struct ceph_mon_client *monc,
889915
__send_subscribe(monc);
890916
__resend_generic_request(monc);
891917
}
918+
919+
if (!had_debugfs_info && have_debugfs_info(monc)) {
920+
pr_info("client%lld fsid %pU\n",
921+
ceph_client_id(monc->client),
922+
&monc->client->fsid);
923+
init_debugfs = 1;
924+
}
892925
mutex_unlock(&monc->mutex);
926+
927+
if (init_debugfs) {
928+
/*
929+
* do debugfs initialization without mutex to avoid
930+
* creating a locking dependency
931+
*/
932+
ceph_debugfs_client_init(monc->client);
933+
}
893934
}
894935

895936
static int __validate_auth(struct ceph_mon_client *monc)

0 commit comments

Comments
 (0)