aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-13 12:24:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-13 12:24:40 -0500
commitca4ba96e02e932a0c9997a40fd51253b5b2d0f9d (patch)
treeca7cc57de628ec777d0fcda3425fcbba8b53d4ca /fs
parent4aeabc6b5ca3b9d025f287978096e138bdfbdd35 (diff)
parent583d0fef756a7615e50f0f68ea0892a497d03971 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull Ceph updates from Sage Weil: "There are several patches from Ilya fixing RBD allocation lifecycle issues, a series adding a nocephx_sign_messages option (and associated bug fixes/cleanups), several patches from Zheng improving the (directory) fsync behavior, a big improvement in IO for direct-io requests when striping is enabled from Caifeng, and several other small fixes and cleanups" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: libceph: clear msg->con in ceph_msg_release() only libceph: add nocephx_sign_messages option libceph: stop duplicating client fields in messenger libceph: drop authorizer check from cephx msg signing routines libceph: msg signing callouts don't need con argument libceph: evaluate osd_req_op_data() arguments only once ceph: make fsync() wait unsafe requests that created/modified inode ceph: add request to i_unsafe_dirops when getting unsafe reply libceph: introduce ceph_x_authorizer_cleanup() ceph: don't invalidate page cache when inode is no longer used rbd: remove duplicate calls to rbd_dev_mapping_clear() rbd: set device_type::release instead of device::release rbd: don't free rbd_dev outside of the release callback rbd: return -ENOMEM instead of pool id if rbd_dev_create() fails libceph: use local variable cursor instead of &msg->cursor libceph: remove con argument in handle_reply() ceph: combine as many iovec as possile into one OSD request ceph: fix message length computation ceph: fix a comment typo rbd: drop null test before destroy functions
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/cache.c2
-rw-r--r--fs/ceph/caps.c76
-rw-r--r--fs/ceph/file.c87
-rw-r--r--fs/ceph/inode.c1
-rw-r--r--fs/ceph/mds_client.c57
-rw-r--r--fs/ceph/mds_client.h3
-rw-r--r--fs/ceph/super.h1
7 files changed, 161 insertions, 66 deletions
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index 834f9f3723fb..a4766ded1ba7 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
@@ -88,7 +88,7 @@ static uint16_t ceph_fscache_inode_get_key(const void *cookie_netfs_data,
88 const struct ceph_inode_info* ci = cookie_netfs_data; 88 const struct ceph_inode_info* ci = cookie_netfs_data;
89 uint16_t klen; 89 uint16_t klen;
90 90
91 /* use ceph virtual inode (id + snaphot) */ 91 /* use ceph virtual inode (id + snapshot) */
92 klen = sizeof(ci->i_vino); 92 klen = sizeof(ci->i_vino);
93 if (klen > maxbuf) 93 if (klen > maxbuf)
94 return 0; 94 return 0;
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 27b566874bc1..c69e1253b47b 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1655,9 +1655,8 @@ retry_locked:
1655 !S_ISDIR(inode->i_mode) && /* ignore readdir cache */ 1655 !S_ISDIR(inode->i_mode) && /* ignore readdir cache */
1656 ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ 1656 ci->i_wrbuffer_ref == 0 && /* no dirty pages... */
1657 inode->i_data.nrpages && /* have cached pages */ 1657 inode->i_data.nrpages && /* have cached pages */
1658 (file_wanted == 0 || /* no open files */ 1658 (revoking & (CEPH_CAP_FILE_CACHE|
1659 (revoking & (CEPH_CAP_FILE_CACHE| 1659 CEPH_CAP_FILE_LAZYIO)) && /* or revoking cache */
1660 CEPH_CAP_FILE_LAZYIO))) && /* or revoking cache */
1661 !tried_invalidate) { 1660 !tried_invalidate) {
1662 dout("check_caps trying to invalidate on %p\n", inode); 1661 dout("check_caps trying to invalidate on %p\n", inode);
1663 if (try_nonblocking_invalidate(inode) < 0) { 1662 if (try_nonblocking_invalidate(inode) < 0) {
@@ -1971,49 +1970,46 @@ out:
1971} 1970}
1972 1971
1973/* 1972/*
1974 * wait for any uncommitted directory operations to commit. 1973 * wait for any unsafe requests to complete.
1975 */ 1974 */
1976static int unsafe_dirop_wait(struct inode *inode) 1975static int unsafe_request_wait(struct inode *inode)
1977{ 1976{
1978 struct ceph_inode_info *ci = ceph_inode(inode); 1977 struct ceph_inode_info *ci = ceph_inode(inode);
1979 struct list_head *head = &ci->i_unsafe_dirops; 1978 struct ceph_mds_request *req1 = NULL, *req2 = NULL;
1980 struct ceph_mds_request *req; 1979 int ret, err = 0;
1981 u64 last_tid;
1982 int ret = 0;
1983
1984 if (!S_ISDIR(inode->i_mode))
1985 return 0;
1986 1980
1987 spin_lock(&ci->i_unsafe_lock); 1981 spin_lock(&ci->i_unsafe_lock);
1988 if (list_empty(head)) 1982 if (S_ISDIR(inode->i_mode) && !list_empty(&ci->i_unsafe_dirops)) {
1989 goto out; 1983 req1 = list_last_entry(&ci->i_unsafe_dirops,
1990 1984 struct ceph_mds_request,
1991 req = list_last_entry(head, struct ceph_mds_request, 1985 r_unsafe_dir_item);
1992 r_unsafe_dir_item); 1986 ceph_mdsc_get_request(req1);
1993 last_tid = req->r_tid; 1987 }
1994 1988 if (!list_empty(&ci->i_unsafe_iops)) {
1995 do { 1989 req2 = list_last_entry(&ci->i_unsafe_iops,
1996 ceph_mdsc_get_request(req); 1990 struct ceph_mds_request,
1997 spin_unlock(&ci->i_unsafe_lock); 1991 r_unsafe_target_item);
1992 ceph_mdsc_get_request(req2);
1993 }
1994 spin_unlock(&ci->i_unsafe_lock);
1998 1995
1999 dout("unsafe_dirop_wait %p wait on tid %llu (until %llu)\n", 1996 dout("unsafe_requeset_wait %p wait on tid %llu %llu\n",
2000 inode, req->r_tid, last_tid); 1997 inode, req1 ? req1->r_tid : 0ULL, req2 ? req2->r_tid : 0ULL);
2001 ret = !wait_for_completion_timeout(&req->r_safe_completion, 1998 if (req1) {
2002 ceph_timeout_jiffies(req->r_timeout)); 1999 ret = !wait_for_completion_timeout(&req1->r_safe_completion,
2000 ceph_timeout_jiffies(req1->r_timeout));
2003 if (ret) 2001 if (ret)
2004 ret = -EIO; /* timed out */ 2002 err = -EIO;
2005 2003 ceph_mdsc_put_request(req1);
2006 ceph_mdsc_put_request(req); 2004 }
2007 2005 if (req2) {
2008 spin_lock(&ci->i_unsafe_lock); 2006 ret = !wait_for_completion_timeout(&req2->r_safe_completion,
2009 if (ret || list_empty(head)) 2007 ceph_timeout_jiffies(req2->r_timeout));
2010 break; 2008 if (ret)
2011 req = list_first_entry(head, struct ceph_mds_request, 2009 err = -EIO;
2012 r_unsafe_dir_item); 2010 ceph_mdsc_put_request(req2);
2013 } while (req->r_tid < last_tid); 2011 }
2014out: 2012 return err;
2015 spin_unlock(&ci->i_unsafe_lock);
2016 return ret;
2017} 2013}
2018 2014
2019int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) 2015int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
@@ -2039,7 +2035,7 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
2039 dirty = try_flush_caps(inode, &flush_tid); 2035 dirty = try_flush_caps(inode, &flush_tid);
2040 dout("fsync dirty caps are %s\n", ceph_cap_string(dirty)); 2036 dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
2041 2037
2042 ret = unsafe_dirop_wait(inode); 2038 ret = unsafe_request_wait(inode);
2043 2039
2044 /* 2040 /*
2045 * only wait on non-file metadata writeback (the mds 2041 * only wait on non-file metadata writeback (the mds
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 0c62868b5c56..3c68e6aee2f0 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -34,6 +34,74 @@
34 * need to wait for MDS acknowledgement. 34 * need to wait for MDS acknowledgement.
35 */ 35 */
36 36
37/*
38 * Calculate the length sum of direct io vectors that can
39 * be combined into one page vector.
40 */
41static size_t dio_get_pagev_size(const struct iov_iter *it)
42{
43 const struct iovec *iov = it->iov;
44 const struct iovec *iovend = iov + it->nr_segs;
45 size_t size;
46
47 size = iov->iov_len - it->iov_offset;
48 /*
49 * An iov can be page vectored when both the current tail
50 * and the next base are page aligned.
51 */
52 while (PAGE_ALIGNED((iov->iov_base + iov->iov_len)) &&
53 (++iov < iovend && PAGE_ALIGNED((iov->iov_base)))) {
54 size += iov->iov_len;
55 }
56 dout("dio_get_pagevlen len = %zu\n", size);
57 return size;
58}
59
60/*
61 * Allocate a page vector based on (@it, @nbytes).
62 * The return value is the tuple describing a page vector,
63 * that is (@pages, @page_align, @num_pages).
64 */
65static struct page **
66dio_get_pages_alloc(const struct iov_iter *it, size_t nbytes,
67 size_t *page_align, int *num_pages)
68{
69 struct iov_iter tmp_it = *it;
70 size_t align;
71 struct page **pages;
72 int ret = 0, idx, npages;
73
74 align = (unsigned long)(it->iov->iov_base + it->iov_offset) &
75 (PAGE_SIZE - 1);
76 npages = calc_pages_for(align, nbytes);
77 pages = kmalloc(sizeof(*pages) * npages, GFP_KERNEL);
78 if (!pages) {
79 pages = vmalloc(sizeof(*pages) * npages);
80 if (!pages)
81 return ERR_PTR(-ENOMEM);
82 }
83
84 for (idx = 0; idx < npages; ) {
85 size_t start;
86 ret = iov_iter_get_pages(&tmp_it, pages + idx, nbytes,
87 npages - idx, &start);
88 if (ret < 0)
89 goto fail;
90
91 iov_iter_advance(&tmp_it, ret);
92 nbytes -= ret;
93 idx += (ret + start + PAGE_SIZE - 1) / PAGE_SIZE;
94 }
95
96 BUG_ON(nbytes != 0);
97 *num_pages = npages;
98 *page_align = align;
99 dout("dio_get_pages_alloc: got %d pages align %zu\n", npages, align);
100 return pages;
101fail:
102 ceph_put_page_vector(pages, idx, false);
103 return ERR_PTR(ret);
104}
37 105
38/* 106/*
39 * Prepare an open request. Preallocate ceph_cap to avoid an 107 * Prepare an open request. Preallocate ceph_cap to avoid an
@@ -458,11 +526,10 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *i,
458 size_t start; 526 size_t start;
459 ssize_t n; 527 ssize_t n;
460 528
461 n = iov_iter_get_pages_alloc(i, &pages, INT_MAX, &start); 529 n = dio_get_pagev_size(i);
462 if (n < 0) 530 pages = dio_get_pages_alloc(i, n, &start, &num_pages);
463 return n; 531 if (IS_ERR(pages))
464 532 return PTR_ERR(pages);
465 num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE;
466 533
467 ret = striped_read(inode, off, n, 534 ret = striped_read(inode, off, n,
468 pages, num_pages, checkeof, 535 pages, num_pages, checkeof,
@@ -592,7 +659,7 @@ ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
592 CEPH_OSD_FLAG_WRITE; 659 CEPH_OSD_FLAG_WRITE;
593 660
594 while (iov_iter_count(from) > 0) { 661 while (iov_iter_count(from) > 0) {
595 u64 len = iov_iter_single_seg_count(from); 662 u64 len = dio_get_pagev_size(from);
596 size_t start; 663 size_t start;
597 ssize_t n; 664 ssize_t n;
598 665
@@ -611,14 +678,14 @@ ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
611 678
612 osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); 679 osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0);
613 680
614 n = iov_iter_get_pages_alloc(from, &pages, len, &start); 681 n = len;
615 if (unlikely(n < 0)) { 682 pages = dio_get_pages_alloc(from, len, &start, &num_pages);
616 ret = n; 683 if (IS_ERR(pages)) {
617 ceph_osdc_put_request(req); 684 ceph_osdc_put_request(req);
685 ret = PTR_ERR(pages);
618 break; 686 break;
619 } 687 }
620 688
621 num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE;
622 /* 689 /*
623 * throw out any page cache pages in this range. this 690 * throw out any page cache pages in this range. this
624 * may block. 691 * may block.
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 96d2bd829902..498dcfa2dcdb 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -452,6 +452,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
452 452
453 INIT_LIST_HEAD(&ci->i_unsafe_writes); 453 INIT_LIST_HEAD(&ci->i_unsafe_writes);
454 INIT_LIST_HEAD(&ci->i_unsafe_dirops); 454 INIT_LIST_HEAD(&ci->i_unsafe_dirops);
455 INIT_LIST_HEAD(&ci->i_unsafe_iops);
455 spin_lock_init(&ci->i_unsafe_lock); 456 spin_lock_init(&ci->i_unsafe_lock);
456 457
457 ci->i_snap_realm = NULL; 458 ci->i_snap_realm = NULL;
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 51cb02da75d9..e7b130a637f9 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -633,13 +633,8 @@ static void __register_request(struct ceph_mds_client *mdsc,
633 mdsc->oldest_tid = req->r_tid; 633 mdsc->oldest_tid = req->r_tid;
634 634
635 if (dir) { 635 if (dir) {
636 struct ceph_inode_info *ci = ceph_inode(dir);
637
638 ihold(dir); 636 ihold(dir);
639 spin_lock(&ci->i_unsafe_lock);
640 req->r_unsafe_dir = dir; 637 req->r_unsafe_dir = dir;
641 list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops);
642 spin_unlock(&ci->i_unsafe_lock);
643 } 638 }
644} 639}
645 640
@@ -665,13 +660,20 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
665 rb_erase(&req->r_node, &mdsc->request_tree); 660 rb_erase(&req->r_node, &mdsc->request_tree);
666 RB_CLEAR_NODE(&req->r_node); 661 RB_CLEAR_NODE(&req->r_node);
667 662
668 if (req->r_unsafe_dir) { 663 if (req->r_unsafe_dir && req->r_got_unsafe) {
669 struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); 664 struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir);
670
671 spin_lock(&ci->i_unsafe_lock); 665 spin_lock(&ci->i_unsafe_lock);
672 list_del_init(&req->r_unsafe_dir_item); 666 list_del_init(&req->r_unsafe_dir_item);
673 spin_unlock(&ci->i_unsafe_lock); 667 spin_unlock(&ci->i_unsafe_lock);
668 }
669 if (req->r_target_inode && req->r_got_unsafe) {
670 struct ceph_inode_info *ci = ceph_inode(req->r_target_inode);
671 spin_lock(&ci->i_unsafe_lock);
672 list_del_init(&req->r_unsafe_target_item);
673 spin_unlock(&ci->i_unsafe_lock);
674 }
674 675
676 if (req->r_unsafe_dir) {
675 iput(req->r_unsafe_dir); 677 iput(req->r_unsafe_dir);
676 req->r_unsafe_dir = NULL; 678 req->r_unsafe_dir = NULL;
677 } 679 }
@@ -1430,6 +1432,13 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
1430 if ((used | wanted) & CEPH_CAP_ANY_WR) 1432 if ((used | wanted) & CEPH_CAP_ANY_WR)
1431 goto out; 1433 goto out;
1432 } 1434 }
1435 /* The inode has cached pages, but it's no longer used.
1436 * we can safely drop it */
1437 if (wanted == 0 && used == CEPH_CAP_FILE_CACHE &&
1438 !(oissued & CEPH_CAP_FILE_CACHE)) {
1439 used = 0;
1440 oissued = 0;
1441 }
1433 if ((used | wanted) & ~oissued & mine) 1442 if ((used | wanted) & ~oissued & mine)
1434 goto out; /* we need these caps */ 1443 goto out; /* we need these caps */
1435 1444
@@ -1438,7 +1447,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
1438 /* we aren't the only cap.. just remove us */ 1447 /* we aren't the only cap.. just remove us */
1439 __ceph_remove_cap(cap, true); 1448 __ceph_remove_cap(cap, true);
1440 } else { 1449 } else {
1441 /* try to drop referring dentries */ 1450 /* try dropping referring dentries */
1442 spin_unlock(&ci->i_ceph_lock); 1451 spin_unlock(&ci->i_ceph_lock);
1443 d_prune_aliases(inode); 1452 d_prune_aliases(inode);
1444 dout("trim_caps_cb %p cap %p pruned, count now %d\n", 1453 dout("trim_caps_cb %p cap %p pruned, count now %d\n",
@@ -1704,6 +1713,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
1704 req->r_started = jiffies; 1713 req->r_started = jiffies;
1705 req->r_resend_mds = -1; 1714 req->r_resend_mds = -1;
1706 INIT_LIST_HEAD(&req->r_unsafe_dir_item); 1715 INIT_LIST_HEAD(&req->r_unsafe_dir_item);
1716 INIT_LIST_HEAD(&req->r_unsafe_target_item);
1707 req->r_fmode = -1; 1717 req->r_fmode = -1;
1708 kref_init(&req->r_kref); 1718 kref_init(&req->r_kref);
1709 INIT_LIST_HEAD(&req->r_wait); 1719 INIT_LIST_HEAD(&req->r_wait);
@@ -1935,7 +1945,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
1935 1945
1936 len = sizeof(*head) + 1946 len = sizeof(*head) +
1937 pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)) + 1947 pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)) +
1938 sizeof(struct timespec); 1948 sizeof(struct ceph_timespec);
1939 1949
1940 /* calculate (max) length for cap releases */ 1950 /* calculate (max) length for cap releases */
1941 len += sizeof(struct ceph_mds_request_release) * 1951 len += sizeof(struct ceph_mds_request_release) *
@@ -2477,6 +2487,14 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
2477 } else { 2487 } else {
2478 req->r_got_unsafe = true; 2488 req->r_got_unsafe = true;
2479 list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe); 2489 list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe);
2490 if (req->r_unsafe_dir) {
2491 struct ceph_inode_info *ci =
2492 ceph_inode(req->r_unsafe_dir);
2493 spin_lock(&ci->i_unsafe_lock);
2494 list_add_tail(&req->r_unsafe_dir_item,
2495 &ci->i_unsafe_dirops);
2496 spin_unlock(&ci->i_unsafe_lock);
2497 }
2480 } 2498 }
2481 2499
2482 dout("handle_reply tid %lld result %d\n", tid, result); 2500 dout("handle_reply tid %lld result %d\n", tid, result);
@@ -2518,6 +2536,13 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
2518 up_read(&mdsc->snap_rwsem); 2536 up_read(&mdsc->snap_rwsem);
2519 if (realm) 2537 if (realm)
2520 ceph_put_snap_realm(mdsc, realm); 2538 ceph_put_snap_realm(mdsc, realm);
2539
2540 if (err == 0 && req->r_got_unsafe && req->r_target_inode) {
2541 struct ceph_inode_info *ci = ceph_inode(req->r_target_inode);
2542 spin_lock(&ci->i_unsafe_lock);
2543 list_add_tail(&req->r_unsafe_target_item, &ci->i_unsafe_iops);
2544 spin_unlock(&ci->i_unsafe_lock);
2545 }
2521out_err: 2546out_err:
2522 mutex_lock(&mdsc->mutex); 2547 mutex_lock(&mdsc->mutex);
2523 if (!req->r_aborted) { 2548 if (!req->r_aborted) {
@@ -3917,17 +3942,19 @@ static struct ceph_msg *mds_alloc_msg(struct ceph_connection *con,
3917 return msg; 3942 return msg;
3918} 3943}
3919 3944
3920static int sign_message(struct ceph_connection *con, struct ceph_msg *msg) 3945static int mds_sign_message(struct ceph_msg *msg)
3921{ 3946{
3922 struct ceph_mds_session *s = con->private; 3947 struct ceph_mds_session *s = msg->con->private;
3923 struct ceph_auth_handshake *auth = &s->s_auth; 3948 struct ceph_auth_handshake *auth = &s->s_auth;
3949
3924 return ceph_auth_sign_message(auth, msg); 3950 return ceph_auth_sign_message(auth, msg);
3925} 3951}
3926 3952
3927static int check_message_signature(struct ceph_connection *con, struct ceph_msg *msg) 3953static int mds_check_message_signature(struct ceph_msg *msg)
3928{ 3954{
3929 struct ceph_mds_session *s = con->private; 3955 struct ceph_mds_session *s = msg->con->private;
3930 struct ceph_auth_handshake *auth = &s->s_auth; 3956 struct ceph_auth_handshake *auth = &s->s_auth;
3957
3931 return ceph_auth_check_message_signature(auth, msg); 3958 return ceph_auth_check_message_signature(auth, msg);
3932} 3959}
3933 3960
@@ -3940,8 +3967,8 @@ static const struct ceph_connection_operations mds_con_ops = {
3940 .invalidate_authorizer = invalidate_authorizer, 3967 .invalidate_authorizer = invalidate_authorizer,
3941 .peer_reset = peer_reset, 3968 .peer_reset = peer_reset,
3942 .alloc_msg = mds_alloc_msg, 3969 .alloc_msg = mds_alloc_msg,
3943 .sign_message = sign_message, 3970 .sign_message = mds_sign_message,
3944 .check_message_signature = check_message_signature, 3971 .check_message_signature = mds_check_message_signature,
3945}; 3972};
3946 3973
3947/* eof */ 3974/* eof */
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index f575eafe2261..ccf11ef0ca87 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -236,6 +236,9 @@ struct ceph_mds_request {
236 struct inode *r_unsafe_dir; 236 struct inode *r_unsafe_dir;
237 struct list_head r_unsafe_dir_item; 237 struct list_head r_unsafe_dir_item;
238 238
239 /* unsafe requests that modify the target inode */
240 struct list_head r_unsafe_target_item;
241
239 struct ceph_mds_session *r_session; 242 struct ceph_mds_session *r_session;
240 243
241 int r_attempts; /* resend attempts */ 244 int r_attempts; /* resend attempts */
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 2f2460d23a06..75b7d125ce66 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -342,6 +342,7 @@ struct ceph_inode_info {
342 342
343 struct list_head i_unsafe_writes; /* uncommitted sync writes */ 343 struct list_head i_unsafe_writes; /* uncommitted sync writes */
344 struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */ 344 struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */
345 struct list_head i_unsafe_iops; /* uncommitted mds inode ops */
345 spinlock_t i_unsafe_lock; 346 spinlock_t i_unsafe_lock;
346 347
347 struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */ 348 struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */