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
此提交包含在:
@@ -276,7 +276,7 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg)
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
struct page *page = osd_data->pages[i];
|
||||
|
||||
if (rc < 0)
|
||||
if (rc < 0 && rc != ENOENT)
|
||||
goto unlock;
|
||||
if (bytes < (int)PAGE_CACHE_SIZE) {
|
||||
/* zero (remainder of) page */
|
||||
@@ -717,8 +717,10 @@ static int ceph_writepages_start(struct address_space *mapping,
|
||||
wbc->sync_mode == WB_SYNC_NONE ? "NONE" :
|
||||
(wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD"));
|
||||
|
||||
if (fsc->mount_state == CEPH_MOUNT_SHUTDOWN) {
|
||||
if (ACCESS_ONCE(fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
|
||||
pr_warn("writepage_start %p on forced umount\n", inode);
|
||||
truncate_pagecache(inode, 0);
|
||||
mapping_set_error(mapping, -EIO);
|
||||
return -EIO; /* we're in a forced umount, don't write! */
|
||||
}
|
||||
if (fsc->mount_options->wsize && fsc->mount_options->wsize < wsize)
|
||||
|
@@ -2413,6 +2413,14 @@ again:
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (!__ceph_is_any_caps(ci) &&
|
||||
ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
|
||||
dout("get_cap_refs %p forced umount\n", inode);
|
||||
*err = -EIO;
|
||||
ret = 1;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
dout("get_cap_refs %p have %s needed %s\n", inode,
|
||||
ceph_cap_string(have), ceph_cap_string(need));
|
||||
}
|
||||
|
@@ -136,7 +136,6 @@ int ceph_open(struct inode *inode, struct file *file)
|
||||
struct ceph_mds_client *mdsc = fsc->mdsc;
|
||||
struct ceph_mds_request *req;
|
||||
struct ceph_file_info *cf = file->private_data;
|
||||
struct inode *parent_inode = NULL;
|
||||
int err;
|
||||
int flags, fmode, wanted;
|
||||
|
||||
@@ -210,10 +209,7 @@ int ceph_open(struct inode *inode, struct file *file)
|
||||
ihold(inode);
|
||||
|
||||
req->r_num_caps = 1;
|
||||
if (flags & O_CREAT)
|
||||
parent_inode = ceph_get_dentry_parent_inode(file->f_path.dentry);
|
||||
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
|
||||
iput(parent_inode);
|
||||
err = ceph_mdsc_do_request(mdsc, NULL, req);
|
||||
if (!err)
|
||||
err = ceph_init_file(inode, file, req->r_fmode);
|
||||
ceph_mdsc_put_request(req);
|
||||
@@ -279,7 +275,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
if (err)
|
||||
goto out_req;
|
||||
|
||||
if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
|
||||
if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry)
|
||||
err = ceph_handle_notrace_create(dir, dentry);
|
||||
|
||||
if (d_unhashed(dentry)) {
|
||||
@@ -956,6 +952,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
/* We can write back this queue in page reclaim */
|
||||
current->backing_dev_info = inode_to_bdi(inode);
|
||||
|
||||
if (iocb->ki_flags & IOCB_APPEND) {
|
||||
err = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = generic_write_checks(iocb, from);
|
||||
if (err <= 0)
|
||||
goto out;
|
||||
|
@@ -2107,7 +2107,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
|
||||
msg = create_request_message(mdsc, req, mds, drop_cap_releases);
|
||||
if (IS_ERR(msg)) {
|
||||
req->r_err = PTR_ERR(msg);
|
||||
complete_request(mdsc, req);
|
||||
return PTR_ERR(msg);
|
||||
}
|
||||
req->r_request = msg;
|
||||
@@ -2135,7 +2134,7 @@ static int __do_request(struct ceph_mds_client *mdsc,
|
||||
{
|
||||
struct ceph_mds_session *session = NULL;
|
||||
int mds = -1;
|
||||
int err = -EAGAIN;
|
||||
int err = 0;
|
||||
|
||||
if (req->r_err || req->r_got_result) {
|
||||
if (req->r_aborted)
|
||||
@@ -2149,6 +2148,11 @@ static int __do_request(struct ceph_mds_client *mdsc,
|
||||
err = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN) {
|
||||
dout("do_request forced umount\n");
|
||||
err = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
put_request_session(req);
|
||||
|
||||
@@ -2196,13 +2200,15 @@ static int __do_request(struct ceph_mds_client *mdsc,
|
||||
|
||||
out_session:
|
||||
ceph_put_mds_session(session);
|
||||
finish:
|
||||
if (err) {
|
||||
dout("__do_request early error %d\n", err);
|
||||
req->r_err = err;
|
||||
complete_request(mdsc, req);
|
||||
__unregister_request(mdsc, req);
|
||||
}
|
||||
out:
|
||||
return err;
|
||||
|
||||
finish:
|
||||
req->r_err = err;
|
||||
complete_request(mdsc, req);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2289,8 +2295,6 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
|
||||
|
||||
if (req->r_err) {
|
||||
err = req->r_err;
|
||||
__unregister_request(mdsc, req);
|
||||
dout("do_request early error %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2411,7 +2415,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
goto out;
|
||||
}
|
||||
if (req->r_got_safe && !head->safe) {
|
||||
if (req->r_got_safe) {
|
||||
pr_warn("got unsafe after safe on %llu from mds%d\n",
|
||||
tid, mds);
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
@@ -2520,8 +2524,7 @@ out_err:
|
||||
if (err) {
|
||||
req->r_err = err;
|
||||
} else {
|
||||
req->r_reply = msg;
|
||||
ceph_msg_get(msg);
|
||||
req->r_reply = ceph_msg_get(msg);
|
||||
req->r_got_result = true;
|
||||
}
|
||||
} else {
|
||||
@@ -3555,7 +3558,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
|
||||
{
|
||||
u64 want_tid, want_flush, want_snap;
|
||||
|
||||
if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN)
|
||||
if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
|
||||
return;
|
||||
|
||||
dout("sync\n");
|
||||
@@ -3584,7 +3587,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
|
||||
*/
|
||||
static bool done_closing_sessions(struct ceph_mds_client *mdsc)
|
||||
{
|
||||
if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN)
|
||||
if (ACCESS_ONCE(mdsc->fsc->mount_state) == CEPH_MOUNT_SHUTDOWN)
|
||||
return true;
|
||||
return atomic_read(&mdsc->num_sessions) == 0;
|
||||
}
|
||||
@@ -3643,6 +3646,34 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
|
||||
dout("stopped\n");
|
||||
}
|
||||
|
||||
void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc)
|
||||
{
|
||||
struct ceph_mds_session *session;
|
||||
int mds;
|
||||
|
||||
dout("force umount\n");
|
||||
|
||||
mutex_lock(&mdsc->mutex);
|
||||
for (mds = 0; mds < mdsc->max_sessions; mds++) {
|
||||
session = __ceph_lookup_mds_session(mdsc, mds);
|
||||
if (!session)
|
||||
continue;
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
mutex_lock(&session->s_mutex);
|
||||
__close_session(mdsc, session);
|
||||
if (session->s_state == CEPH_MDS_SESSION_CLOSING) {
|
||||
cleanup_session_requests(mdsc, session);
|
||||
remove_session_caps(session);
|
||||
}
|
||||
mutex_unlock(&session->s_mutex);
|
||||
ceph_put_mds_session(session);
|
||||
mutex_lock(&mdsc->mutex);
|
||||
kick_requests(mdsc, mds);
|
||||
}
|
||||
__wake_requests(mdsc, &mdsc->waiting_for_map);
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
}
|
||||
|
||||
static void ceph_mdsc_stop(struct ceph_mds_client *mdsc)
|
||||
{
|
||||
dout("stop\n");
|
||||
|
@@ -366,6 +366,7 @@ extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
|
||||
|
||||
extern int ceph_mdsc_init(struct ceph_fs_client *fsc);
|
||||
extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc);
|
||||
extern void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc);
|
||||
extern void ceph_mdsc_destroy(struct ceph_fs_client *fsc);
|
||||
|
||||
extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc);
|
||||
|
@@ -338,12 +338,6 @@ static int build_snap_context(struct ceph_snap_realm *realm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (num == 0 && realm->seq == ceph_empty_snapc->seq) {
|
||||
ceph_get_snap_context(ceph_empty_snapc);
|
||||
snapc = ceph_empty_snapc;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* alloc new snap context */
|
||||
err = -ENOMEM;
|
||||
if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
|
||||
@@ -381,7 +375,6 @@ static int build_snap_context(struct ceph_snap_realm *realm)
|
||||
realm->ino, realm, snapc, snapc->seq,
|
||||
(unsigned int) snapc->num_snaps);
|
||||
|
||||
done:
|
||||
ceph_put_snap_context(realm->cached_context);
|
||||
realm->cached_context = snapc;
|
||||
return 0;
|
||||
|
@@ -708,6 +708,7 @@ static void ceph_umount_begin(struct super_block *sb)
|
||||
if (!fsc)
|
||||
return;
|
||||
fsc->mount_state = CEPH_MOUNT_SHUTDOWN;
|
||||
ceph_mdsc_force_umount(fsc->mdsc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
新增問題並參考
封鎖使用者