Commit 7e884479 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

Pull Ceph fixes from Sage Weil:
 "There are two critical regression fixes for CephFS from Zheng, and an
  RBD completion fix for layered images from Ilya"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  rbd: fix copyup completion race
  ceph: always re-send cap flushes when MDS recovers
  ceph: fix ceph_encode_locks_to_buffer()
parents 665aadc1 2761713d
...@@ -523,6 +523,7 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...) ...@@ -523,6 +523,7 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...)
# define rbd_assert(expr) ((void) 0) # define rbd_assert(expr) ((void) 0)
#endif /* !RBD_DEBUG */ #endif /* !RBD_DEBUG */
static void rbd_osd_copyup_callback(struct rbd_obj_request *obj_request);
static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request); static int rbd_img_obj_request_submit(struct rbd_obj_request *obj_request);
static void rbd_img_parent_read(struct rbd_obj_request *obj_request); static void rbd_img_parent_read(struct rbd_obj_request *obj_request);
static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
...@@ -1818,6 +1819,16 @@ static void rbd_osd_stat_callback(struct rbd_obj_request *obj_request) ...@@ -1818,6 +1819,16 @@ static void rbd_osd_stat_callback(struct rbd_obj_request *obj_request)
obj_request_done_set(obj_request); obj_request_done_set(obj_request);
} }
static void rbd_osd_call_callback(struct rbd_obj_request *obj_request)
{
dout("%s: obj %p\n", __func__, obj_request);
if (obj_request_img_data_test(obj_request))
rbd_osd_copyup_callback(obj_request);
else
obj_request_done_set(obj_request);
}
static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
struct ceph_msg *msg) struct ceph_msg *msg)
{ {
...@@ -1866,6 +1877,8 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, ...@@ -1866,6 +1877,8 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
rbd_osd_discard_callback(obj_request); rbd_osd_discard_callback(obj_request);
break; break;
case CEPH_OSD_OP_CALL: case CEPH_OSD_OP_CALL:
rbd_osd_call_callback(obj_request);
break;
case CEPH_OSD_OP_NOTIFY_ACK: case CEPH_OSD_OP_NOTIFY_ACK:
case CEPH_OSD_OP_WATCH: case CEPH_OSD_OP_WATCH:
rbd_osd_trivial_callback(obj_request); rbd_osd_trivial_callback(obj_request);
...@@ -2530,13 +2543,15 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request, ...@@ -2530,13 +2543,15 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request,
} }
static void static void
rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request) rbd_osd_copyup_callback(struct rbd_obj_request *obj_request)
{ {
struct rbd_img_request *img_request; struct rbd_img_request *img_request;
struct rbd_device *rbd_dev; struct rbd_device *rbd_dev;
struct page **pages; struct page **pages;
u32 page_count; u32 page_count;
dout("%s: obj %p\n", __func__, obj_request);
rbd_assert(obj_request->type == OBJ_REQUEST_BIO || rbd_assert(obj_request->type == OBJ_REQUEST_BIO ||
obj_request->type == OBJ_REQUEST_NODATA); obj_request->type == OBJ_REQUEST_NODATA);
rbd_assert(obj_request_img_data_test(obj_request)); rbd_assert(obj_request_img_data_test(obj_request));
...@@ -2563,9 +2578,7 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request) ...@@ -2563,9 +2578,7 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request)
if (!obj_request->result) if (!obj_request->result)
obj_request->xferred = obj_request->length; obj_request->xferred = obj_request->length;
/* Finish up with the normal image object callback */ obj_request_done_set(obj_request);
rbd_img_obj_callback(obj_request);
} }
static void static void
...@@ -2650,7 +2663,6 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) ...@@ -2650,7 +2663,6 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request)
/* All set, send it off. */ /* All set, send it off. */
orig_request->callback = rbd_img_obj_copyup_callback;
osdc = &rbd_dev->rbd_client->client->osdc; osdc = &rbd_dev->rbd_client->client->osdc;
img_result = rbd_obj_request_submit(osdc, orig_request); img_result = rbd_obj_request_submit(osdc, orig_request);
if (!img_result) if (!img_result)
......
...@@ -1506,7 +1506,6 @@ static int __mark_caps_flushing(struct inode *inode, ...@@ -1506,7 +1506,6 @@ static int __mark_caps_flushing(struct inode *inode,
swap(cf, ci->i_prealloc_cap_flush); swap(cf, ci->i_prealloc_cap_flush);
cf->caps = flushing; cf->caps = flushing;
cf->kick = false;
spin_lock(&mdsc->cap_dirty_lock); spin_lock(&mdsc->cap_dirty_lock);
list_del_init(&ci->i_dirty_item); list_del_init(&ci->i_dirty_item);
...@@ -2123,8 +2122,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, ...@@ -2123,8 +2122,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
static int __kick_flushing_caps(struct ceph_mds_client *mdsc, static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
struct ceph_mds_session *session, struct ceph_mds_session *session,
struct ceph_inode_info *ci, struct ceph_inode_info *ci)
bool kick_all)
{ {
struct inode *inode = &ci->vfs_inode; struct inode *inode = &ci->vfs_inode;
struct ceph_cap *cap; struct ceph_cap *cap;
...@@ -2150,9 +2148,7 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2150,9 +2148,7 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
for (n = rb_first(&ci->i_cap_flush_tree); n; n = rb_next(n)) { for (n = rb_first(&ci->i_cap_flush_tree); n; n = rb_next(n)) {
cf = rb_entry(n, struct ceph_cap_flush, i_node); cf = rb_entry(n, struct ceph_cap_flush, i_node);
if (cf->tid < first_tid) if (cf->tid >= first_tid)
continue;
if (kick_all || cf->kick)
break; break;
} }
if (!n) { if (!n) {
...@@ -2161,7 +2157,6 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2161,7 +2157,6 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
} }
cf = rb_entry(n, struct ceph_cap_flush, i_node); cf = rb_entry(n, struct ceph_cap_flush, i_node);
cf->kick = false;
first_tid = cf->tid + 1; first_tid = cf->tid + 1;
...@@ -2181,8 +2176,6 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2181,8 +2176,6 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc,
{ {
struct ceph_inode_info *ci; struct ceph_inode_info *ci;
struct ceph_cap *cap; struct ceph_cap *cap;
struct ceph_cap_flush *cf;
struct rb_node *n;
dout("early_kick_flushing_caps mds%d\n", session->s_mds); dout("early_kick_flushing_caps mds%d\n", session->s_mds);
list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) { list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
...@@ -2205,16 +2198,11 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2205,16 +2198,11 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc,
if ((cap->issued & ci->i_flushing_caps) != if ((cap->issued & ci->i_flushing_caps) !=
ci->i_flushing_caps) { ci->i_flushing_caps) {
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
if (!__kick_flushing_caps(mdsc, session, ci, true)) if (!__kick_flushing_caps(mdsc, session, ci))
continue; continue;
spin_lock(&ci->i_ceph_lock); spin_lock(&ci->i_ceph_lock);
} }
for (n = rb_first(&ci->i_cap_flush_tree); n; n = rb_next(n)) {
cf = rb_entry(n, struct ceph_cap_flush, i_node);
cf->kick = true;
}
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
} }
} }
...@@ -2228,7 +2216,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2228,7 +2216,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
dout("kick_flushing_caps mds%d\n", session->s_mds); dout("kick_flushing_caps mds%d\n", session->s_mds);
list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) { list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) {
int delayed = __kick_flushing_caps(mdsc, session, ci, false); int delayed = __kick_flushing_caps(mdsc, session, ci);
if (delayed) { if (delayed) {
spin_lock(&ci->i_ceph_lock); spin_lock(&ci->i_ceph_lock);
__cap_delay_requeue(mdsc, ci); __cap_delay_requeue(mdsc, ci);
...@@ -2261,7 +2249,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, ...@@ -2261,7 +2249,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc,
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
delayed = __kick_flushing_caps(mdsc, session, ci, true); delayed = __kick_flushing_caps(mdsc, session, ci);
if (delayed) { if (delayed) {
spin_lock(&ci->i_ceph_lock); spin_lock(&ci->i_ceph_lock);
__cap_delay_requeue(mdsc, ci); __cap_delay_requeue(mdsc, ci);
......
...@@ -287,7 +287,7 @@ int ceph_encode_locks_to_buffer(struct inode *inode, ...@@ -287,7 +287,7 @@ int ceph_encode_locks_to_buffer(struct inode *inode,
return 0; return 0;
spin_lock(&ctx->flc_lock); spin_lock(&ctx->flc_lock);
list_for_each_entry(lock, &ctx->flc_flock, fl_list) { list_for_each_entry(lock, &ctx->flc_posix, fl_list) {
++seen_fcntl; ++seen_fcntl;
if (seen_fcntl > num_fcntl_locks) { if (seen_fcntl > num_fcntl_locks) {
err = -ENOSPC; err = -ENOSPC;
......
...@@ -189,7 +189,6 @@ static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) ...@@ -189,7 +189,6 @@ static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
struct ceph_cap_flush { struct ceph_cap_flush {
u64 tid; u64 tid;
int caps; int caps;
bool kick;
struct rb_node g_node; // global struct rb_node g_node; // global
union { union {
struct rb_node i_node; // inode struct rb_node i_node; // inode
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment