Skip to content

Commit e013f74

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull Ceph update from Sage Weil: "There are a few fixes for snapshot behavior with CephFS and support for the new keepalive protocol from Zheng, a libceph fix that affects both RBD and CephFS, a few bug fixes and cleanups for RBD from Ilya, and several small fixes and cleanups from Jianpeng and others" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: ceph: improve readahead for file holes ceph: get inode size for each append write libceph: check data_len in ->alloc_msg() libceph: use keepalive2 to verify the mon session is alive rbd: plug rbd_dev->header.object_prefix memory leak rbd: fix double free on rbd_dev->header_name libceph: set 'exists' flag for newly up osd ceph: cleanup use of ceph_msg_get ceph: no need to get parent inode in ceph_open ceph: remove the useless judgement ceph: remove redundant test of head->safe and silence static analysis warnings ceph: fix queuing inode to mdsdir's snaprealm libceph: rename con_work() to ceph_con_workfn() libceph: Avoid holding the zero page on ceph_msgr_slab_init errors libceph: remove the unused macro AES_KEY_SIZE ceph: invalidate dirty pages after forced umount ceph: EIO all operations after forced umount
2 parents 01cab55 + 4383868 commit e013f74

File tree

17 files changed

+191
-98
lines changed

17 files changed

+191
-98
lines changed

drivers/block/rbd.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4673,7 +4673,10 @@ static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
46734673
}
46744674

46754675
ret = rbd_dev_v2_snap_context(rbd_dev);
4676-
dout("rbd_dev_v2_snap_context returned %d\n", ret);
4676+
if (ret && first_time) {
4677+
kfree(rbd_dev->header.object_prefix);
4678+
rbd_dev->header.object_prefix = NULL;
4679+
}
46774680

46784681
return ret;
46794682
}
@@ -5154,7 +5157,6 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
51545157
out_err:
51555158
if (parent) {
51565159
rbd_dev_unparent(rbd_dev);
5157-
kfree(rbd_dev->header_name);
51585160
rbd_dev_destroy(parent);
51595161
} else {
51605162
rbd_put_client(rbdc);

fs/ceph/addr.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg)
276276
for (i = 0; i < num_pages; i++) {
277277
struct page *page = osd_data->pages[i];
278278

279-
if (rc < 0)
279+
if (rc < 0 && rc != ENOENT)
280280
goto unlock;
281281
if (bytes < (int)PAGE_CACHE_SIZE) {
282282
/* zero (remainder of) page */
@@ -717,8 +717,10 @@ static int ceph_writepages_start(struct address_space *mapping,
717717
wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
718718
(wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
719719

720-
if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) {
720+
if (ACCESS_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
721721
pr_warn("writepage_start %p on forced umount\n", inode);
722+
truncate_pagecache(inode, 0);
723+
mapping_set_error(mapping, -EIO);
722724
return -EIO; /* we're in a forced umount, don't write! */
723725
}
724726
if (fsc->mount_options->wsize && fsc->mount_options->wsize < wsize)

fs/ceph/caps.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,14 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
24132413
goto out_unlock;
24142414
}
24152415

2416+
if (!__ceph_is_any_caps(ci) &&
2417+
ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
2418+
dout("get_cap_refs %p forced umount\n", inode);
2419+
*err = -EIO;
2420+
ret = 1;
2421+
goto out_unlock;
2422+
}
2423+
24162424
dout("get_cap_refs %p have %s needed %s\n", inode,
24172425
ceph_cap_string(have), ceph_cap_string(need));
24182426
}

fs/ceph/file.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ int ceph_open(struct inode *inode, struct file *file)
136136
struct ceph_mds_client *mdsc = fsc->mdsc;
137137
struct ceph_mds_request *req;
138138
struct ceph_file_info *cf = file->private_data;
139-
struct inode *parent_inode = NULL;
140139
int err;
141140
int flags, fmode, wanted;
142141

@@ -210,10 +209,7 @@ int ceph_open(struct inode *inode, struct file *file)
210209
ihold(inode);
211210

212211
req->r_num_caps = 1;
213-
if (flags & O_CREAT)
214-
parent_inode = ceph_get_dentry_parent_inode(file->f_path.dentry);
215-
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
216-
iput(parent_inode);
212+
err = ceph_mdsc_do_request(mdsc, NULL, req);
217213
if (!err)
218214
err = ceph_init_file(inode, file, req->r_fmode);
219215
ceph_mdsc_put_request(req);
@@ -279,7 +275,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
279275
if (err)
280276
goto out_req;
281277

282-
if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
278+
if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
283279
err = ceph_handle_notrace_create(dir, dentry);
284280

285281
if (d_unhashed(dentry)) {
@@ -956,6 +952,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
956952
/* We can write back this queue in page reclaim */
957953
current->backing_dev_info = inode_to_bdi(inode);
958954

955+
if (iocb->ki_flags & IOCB_APPEND) {
956+
err = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false);
957+
if (err < 0)
958+
goto out;
959+
}
960+
959961
err = generic_write_checks(iocb, from);
960962
if (err <= 0)
961963
goto out;

fs/ceph/mds_client.c

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,7 +2107,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
21072107
msg = create_request_message(mdsc, req, mds, drop_cap_releases);
21082108
if (IS_ERR(msg)) {
21092109
req->r_err = PTR_ERR(msg);
2110-
complete_request(mdsc, req);
21112110
return PTR_ERR(msg);
21122111
}
21132112
req->r_request = msg;
@@ -2135,7 +2134,7 @@ static int __do_request(struct ceph_mds_client *mdsc,
21352134
{
21362135
struct ceph_mds_session *session = NULL;
21372136
int mds = -1;
2138-
int err = -EAGAIN;
2137+
int err = 0;
21392138

21402139
if (req->r_err || req->r_got_result) {
21412140
if (req->r_aborted)
@@ -2149,6 +2148,11 @@ static int __do_request(struct ceph_mds_client *mdsc,
21492148
err = -EIO;
21502149
goto finish;
21512150
}
2151+
if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
2152+
dout("do_request forced umount\n");
2153+
err = -EIO;
2154+
goto finish;
2155+
}
21522156

21532157
put_request_session(req);
21542158

@@ -2196,13 +2200,15 @@ static int __do_request(struct ceph_mds_client *mdsc,
21962200

21972201
out_session:
21982202
ceph_put_mds_session(session);
2203+
finish:
2204+
if (err) {
2205+
dout("__do_request early error %d\n", err);
2206+
req->r_err = err;
2207+
complete_request(mdsc, req);
2208+
__unregister_request(mdsc, req);
2209+
}
21992210
out:
22002211
return err;
2201-
2202-
finish:
2203-
req->r_err = err;
2204-
complete_request(mdsc, req);
2205-
goto out;
22062212
}
22072213

22082214
/*
@@ -2289,8 +2295,6 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
22892295

22902296
if (req->r_err) {
22912297
err = req->r_err;
2292-
__unregister_request(mdsc, req);
2293-
dout("do_request early error %d\n", err);
22942298
goto out;
22952299
}
22962300

@@ -2411,7 +2415,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
24112415
mutex_unlock(&mdsc->mutex);
24122416
goto out;
24132417
}
2414-
if (req->r_got_safe && !head->safe) {
2418+
if (req->r_got_safe) {
24152419
pr_warn("got unsafe after safe on %llu from mds%d\n",
24162420
tid, mds);
24172421
mutex_unlock(&mdsc->mutex);
@@ -2520,8 +2524,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
25202524
if (err) {
25212525
req->r_err = err;
25222526
} else {
2523-
req->r_reply = msg;
2524-
ceph_msg_get(msg);
2527+
req->r_reply = ceph_msg_get(msg);
25252528
req->r_got_result = true;
25262529
}
25272530
} else {
@@ -3555,7 +3558,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
35553558
{
35563559
u64 want_tid, want_flush, want_snap;
35573560

3558-
if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN)
3561+
if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
35593562
return;
35603563

35613564
dout("sync\n");
@@ -3584,7 +3587,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
35843587
*/
35853588
static bool done_closing_sessions(struct ceph_mds_client *mdsc)
35863589
{
3587-
if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN)
3590+
if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
35883591
return true;
35893592
return atomic_read(&mdsc->num_sessions) == 0;
35903593
}
@@ -3643,6 +3646,34 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
36433646
dout("stopped\n");
36443647
}
36453648

3649+
void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc)
3650+
{
3651+
struct ceph_mds_session *session;
3652+
int mds;
3653+
3654+
dout("force umount\n");
3655+
3656+
mutex_lock(&mdsc->mutex);
3657+
for (mds = 0; mds < mdsc->max_sessions; mds++) {
3658+
session = __ceph_lookup_mds_session(mdsc, mds);
3659+
if (!session)
3660+
continue;
3661+
mutex_unlock(&mdsc->mutex);
3662+
mutex_lock(&session->s_mutex);
3663+
__close_session(mdsc, session);
3664+
if (session->s_state == CEPH_MDS_SESSION_CLOSING) {
3665+
cleanup_session_requests(mdsc, session);
3666+
remove_session_caps(session);
3667+
}
3668+
mutex_unlock(&session->s_mutex);
3669+
ceph_put_mds_session(session);
3670+
mutex_lock(&mdsc->mutex);
3671+
kick_requests(mdsc, mds);
3672+
}
3673+
__wake_requests(mdsc, &mdsc->waiting_for_map);
3674+
mutex_unlock(&mdsc->mutex);
3675+
}
3676+
36463677
static void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
36473678
{
36483679
dout("stop\n");

fs/ceph/mds_client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
366366

367367
extern int ceph_mdsc_init(struct ceph_fs_client *fsc);
368368
extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
369+
extern void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc);
369370
extern void ceph_mdsc_destroy(struct ceph_fs_client *fsc);
370371

371372
extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);

fs/ceph/snap.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -338,12 +338,6 @@ static int build_snap_context(struct ceph_snap_realm *realm)
338338
return 0;
339339
}
340340

341-
if (num == 0 && realm->seq == ceph_empty_snapc->seq) {
342-
ceph_get_snap_context(ceph_empty_snapc);
343-
snapc = ceph_empty_snapc;
344-
goto done;
345-
}
346-
347341
/* alloc new snap context */
348342
err = -ENOMEM;
349343
if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
@@ -381,7 +375,6 @@ static int build_snap_context(struct ceph_snap_realm *realm)
381375
realm->ino, realm, snapc, snapc->seq,
382376
(unsigned int) snapc->num_snaps);
383377

384-
done:
385378
ceph_put_snap_context(realm->cached_context);
386379
realm->cached_context = snapc;
387380
return 0;

fs/ceph/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ static void ceph_umount_begin(struct super_block *sb)
708708
if (!fsc)
709709
return;
710710
fsc->mount_state = CEPH_MOUNT_SHUTDOWN;
711+
ceph_mdsc_force_umount(fsc->mdsc);
711712
return;
712713
}
713714

include/linux/ceph/libceph.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct ceph_options {
4646
unsigned long mount_timeout; /* jiffies */
4747
unsigned long osd_idle_ttl; /* jiffies */
4848
unsigned long osd_keepalive_timeout; /* jiffies */
49+
unsigned long monc_ping_timeout; /* jiffies */
4950

5051
/*
5152
* any type that can't be simply compared or doesn't need need
@@ -66,6 +67,7 @@ struct ceph_options {
6667
#define CEPH_MOUNT_TIMEOUT_DEFAULT msecs_to_jiffies(60 * 1000)
6768
#define CEPH_OSD_KEEPALIVE_DEFAULT msecs_to_jiffies(5 * 1000)
6869
#define CEPH_OSD_IDLE_TTL_DEFAULT msecs_to_jiffies(60 * 1000)
70+
#define CEPH_MONC_PING_TIMEOUT_DEFAULT msecs_to_jiffies(30 * 1000)
6971

7072
#define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024)
7173
#define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024)

include/linux/ceph/messenger.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ struct ceph_connection {
248248
int in_base_pos; /* bytes read */
249249
__le64 in_temp_ack; /* for reading an ack */
250250

251+
struct timespec last_keepalive_ack;
252+
251253
struct delayed_work work; /* send|recv work */
252254
unsigned long delay; /* current delay interval */
253255
};
@@ -285,6 +287,8 @@ extern void ceph_msg_revoke(struct ceph_msg *msg);
285287
extern void ceph_msg_revoke_incoming(struct ceph_msg *msg);
286288

287289
extern void ceph_con_keepalive(struct ceph_connection *con);
290+
extern bool ceph_con_keepalive_expired(struct ceph_connection *con,
291+
unsigned long interval);
288292

289293
extern void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages,
290294
size_t length, size_t alignment);

include/linux/ceph/msgr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,12 @@ struct ceph_entity_inst {
8484
#define CEPH_MSGR_TAG_MSG 7 /* message */
8585
#define CEPH_MSGR_TAG_ACK 8 /* message ack */
8686
#define CEPH_MSGR_TAG_KEEPALIVE 9 /* just a keepalive byte! */
87-
#define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */
87+
#define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */
8888
#define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
8989
#define CEPH_MSGR_TAG_FEATURES 12 /* insufficient features */
9090
#define CEPH_MSGR_TAG_SEQ 13 /* 64-bit int follows with seen seq number */
91+
#define CEPH_MSGR_TAG_KEEPALIVE2 14 /* keepalive2 byte + ceph_timespec */
92+
#define CEPH_MSGR_TAG_KEEPALIVE2_ACK 15 /* keepalive2 reply */
9193

9294

9395
/*

net/ceph/ceph_common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ ceph_parse_options(char *options, const char *dev_name,
357357
opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
358358
opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT;
359359
opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;
360+
opt->monc_ping_timeout = CEPH_MONC_PING_TIMEOUT_DEFAULT;
360361

361362
/* get mon ip(s) */
362363
/* ip1[:port1][,ip2[:port2]...] */

net/ceph/crypto.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,6 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
7979
return 0;
8080
}
8181

82-
83-
84-
#define AES_KEY_SIZE 16
85-
8682
static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
8783
{
8884
return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);

0 commit comments

Comments
 (0)