aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-15 00:46:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-15 00:46:01 -0400
commit6b0490816671b2f4126a99998c9bf3c8c0472de2 (patch)
tree016543455c2bdbe47b422fed6a3b4ffb991c97d6 /drivers/block
parentce9d7f7b45930ed16c512aabcfe651d44f1c8619 (diff)
parent0bc62284ee3f2a228c64902ed818b6ba8e04159b (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 is the long-awaited discard support for RBD (Guangliang Zhao, Josh Durgin), a pile of RBD bug fixes that didn't belong in late -rc's (Ilya Dryomov, Li RongQing), a pile of fs/ceph bug fixes and performance and debugging improvements (Yan, Zheng, John Spray), and a smattering of cleanups (Chao Yu, Fabian Frederick, Joe Perches)" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (40 commits) ceph: fix divide-by-zero in __validate_layout() rbd: rbd workqueues need a resque worker libceph: ceph-msgr workqueue needs a resque worker ceph: fix bool assignments libceph: separate multiple ops with commas in debugfs output libceph: sync osd op definitions in rados.h libceph: remove redundant declaration ceph: additional debugfs output ceph: export ceph_session_state_name function ceph: include the initial ACL in create/mkdir/mknod MDS requests ceph: use pagelist to present MDS request data libceph: reference counting pagelist ceph: fix llistxattr on symlink ceph: send client metadata to MDS ceph: remove redundant code for max file size verification ceph: remove redundant io_iter_advance() ceph: move ceph_find_inode() outside the s_mutex ceph: request xattrs if xattr_version is zero rbd: set the remaining discard properties to enable support rbd: use helpers to handle discard for layered images correctly ...
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c396
1 files changed, 276 insertions, 120 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4b97baf8afa3..0a54c588e433 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -210,6 +210,12 @@ enum obj_request_type {
210 OBJ_REQUEST_NODATA, OBJ_REQUEST_BIO, OBJ_REQUEST_PAGES 210 OBJ_REQUEST_NODATA, OBJ_REQUEST_BIO, OBJ_REQUEST_PAGES
211}; 211};
212 212
213enum obj_operation_type {
214 OBJ_OP_WRITE,
215 OBJ_OP_READ,
216 OBJ_OP_DISCARD,
217};
218
213enum obj_req_flags { 219enum obj_req_flags {
214 OBJ_REQ_DONE, /* completion flag: not done = 0, done = 1 */ 220 OBJ_REQ_DONE, /* completion flag: not done = 0, done = 1 */
215 OBJ_REQ_IMG_DATA, /* object usage: standalone = 0, image = 1 */ 221 OBJ_REQ_IMG_DATA, /* object usage: standalone = 0, image = 1 */
@@ -276,6 +282,7 @@ enum img_req_flags {
276 IMG_REQ_WRITE, /* I/O direction: read = 0, write = 1 */ 282 IMG_REQ_WRITE, /* I/O direction: read = 0, write = 1 */
277 IMG_REQ_CHILD, /* initiator: block = 0, child image = 1 */ 283 IMG_REQ_CHILD, /* initiator: block = 0, child image = 1 */
278 IMG_REQ_LAYERED, /* ENOENT handling: normal = 0, layered = 1 */ 284 IMG_REQ_LAYERED, /* ENOENT handling: normal = 0, layered = 1 */
285 IMG_REQ_DISCARD, /* discard: normal = 0, discard request = 1 */
279}; 286};
280 287
281struct rbd_img_request { 288struct rbd_img_request {
@@ -785,6 +792,20 @@ static int parse_rbd_opts_token(char *c, void *private)
785 return 0; 792 return 0;
786} 793}
787 794
795static char* obj_op_name(enum obj_operation_type op_type)
796{
797 switch (op_type) {
798 case OBJ_OP_READ:
799 return "read";
800 case OBJ_OP_WRITE:
801 return "write";
802 case OBJ_OP_DISCARD:
803 return "discard";
804 default:
805 return "???";
806 }
807}
808
788/* 809/*
789 * Get a ceph client with specific addr and configuration, if one does 810 * Get a ceph client with specific addr and configuration, if one does
790 * not exist create it. Either way, ceph_opts is consumed by this 811 * not exist create it. Either way, ceph_opts is consumed by this
@@ -1600,6 +1621,21 @@ static bool img_request_write_test(struct rbd_img_request *img_request)
1600 return test_bit(IMG_REQ_WRITE, &img_request->flags) != 0; 1621 return test_bit(IMG_REQ_WRITE, &img_request->flags) != 0;
1601} 1622}
1602 1623
1624/*
1625 * Set the discard flag when the img_request is an discard request
1626 */
1627static void img_request_discard_set(struct rbd_img_request *img_request)
1628{
1629 set_bit(IMG_REQ_DISCARD, &img_request->flags);
1630 smp_mb();
1631}
1632
1633static bool img_request_discard_test(struct rbd_img_request *img_request)
1634{
1635 smp_mb();
1636 return test_bit(IMG_REQ_DISCARD, &img_request->flags) != 0;
1637}
1638
1603static void img_request_child_set(struct rbd_img_request *img_request) 1639static void img_request_child_set(struct rbd_img_request *img_request)
1604{ 1640{
1605 set_bit(IMG_REQ_CHILD, &img_request->flags); 1641 set_bit(IMG_REQ_CHILD, &img_request->flags);
@@ -1636,6 +1672,17 @@ static bool img_request_layered_test(struct rbd_img_request *img_request)
1636 return test_bit(IMG_REQ_LAYERED, &img_request->flags) != 0; 1672 return test_bit(IMG_REQ_LAYERED, &img_request->flags) != 0;
1637} 1673}
1638 1674
1675static enum obj_operation_type
1676rbd_img_request_op_type(struct rbd_img_request *img_request)
1677{
1678 if (img_request_write_test(img_request))
1679 return OBJ_OP_WRITE;
1680 else if (img_request_discard_test(img_request))
1681 return OBJ_OP_DISCARD;
1682 else
1683 return OBJ_OP_READ;
1684}
1685
1639static void 1686static void
1640rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request) 1687rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
1641{ 1688{
@@ -1722,6 +1769,21 @@ static void rbd_osd_write_callback(struct rbd_obj_request *obj_request)
1722 obj_request_done_set(obj_request); 1769 obj_request_done_set(obj_request);
1723} 1770}
1724 1771
1772static void rbd_osd_discard_callback(struct rbd_obj_request *obj_request)
1773{
1774 dout("%s: obj %p result %d %llu\n", __func__, obj_request,
1775 obj_request->result, obj_request->length);
1776 /*
1777 * There is no such thing as a successful short discard. Set
1778 * it to our originally-requested length.
1779 */
1780 obj_request->xferred = obj_request->length;
1781 /* discarding a non-existent object is not a problem */
1782 if (obj_request->result == -ENOENT)
1783 obj_request->result = 0;
1784 obj_request_done_set(obj_request);
1785}
1786
1725/* 1787/*
1726 * For a simple stat call there's nothing to do. We'll do more if 1788 * For a simple stat call there's nothing to do. We'll do more if
1727 * this is part of a write sequence for a layered image. 1789 * this is part of a write sequence for a layered image.
@@ -1773,6 +1835,11 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
1773 case CEPH_OSD_OP_STAT: 1835 case CEPH_OSD_OP_STAT:
1774 rbd_osd_stat_callback(obj_request); 1836 rbd_osd_stat_callback(obj_request);
1775 break; 1837 break;
1838 case CEPH_OSD_OP_DELETE:
1839 case CEPH_OSD_OP_TRUNCATE:
1840 case CEPH_OSD_OP_ZERO:
1841 rbd_osd_discard_callback(obj_request);
1842 break;
1776 case CEPH_OSD_OP_CALL: 1843 case CEPH_OSD_OP_CALL:
1777 case CEPH_OSD_OP_NOTIFY_ACK: 1844 case CEPH_OSD_OP_NOTIFY_ACK:
1778 case CEPH_OSD_OP_WATCH: 1845 case CEPH_OSD_OP_WATCH:
@@ -1823,7 +1890,7 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request)
1823 */ 1890 */
1824static struct ceph_osd_request *rbd_osd_req_create( 1891static struct ceph_osd_request *rbd_osd_req_create(
1825 struct rbd_device *rbd_dev, 1892 struct rbd_device *rbd_dev,
1826 bool write_request, 1893 enum obj_operation_type op_type,
1827 unsigned int num_ops, 1894 unsigned int num_ops,
1828 struct rbd_obj_request *obj_request) 1895 struct rbd_obj_request *obj_request)
1829{ 1896{
@@ -1831,16 +1898,18 @@ static struct ceph_osd_request *rbd_osd_req_create(
1831 struct ceph_osd_client *osdc; 1898 struct ceph_osd_client *osdc;
1832 struct ceph_osd_request *osd_req; 1899 struct ceph_osd_request *osd_req;
1833 1900
1834 if (obj_request_img_data_test(obj_request)) { 1901 if (obj_request_img_data_test(obj_request) &&
1902 (op_type == OBJ_OP_DISCARD || op_type == OBJ_OP_WRITE)) {
1835 struct rbd_img_request *img_request = obj_request->img_request; 1903 struct rbd_img_request *img_request = obj_request->img_request;
1836 1904 if (op_type == OBJ_OP_WRITE) {
1837 rbd_assert(write_request == 1905 rbd_assert(img_request_write_test(img_request));
1838 img_request_write_test(img_request)); 1906 } else {
1839 if (write_request) 1907 rbd_assert(img_request_discard_test(img_request));
1840 snapc = img_request->snapc; 1908 }
1909 snapc = img_request->snapc;
1841 } 1910 }
1842 1911
1843 rbd_assert(num_ops == 1 || (write_request && num_ops == 2)); 1912 rbd_assert(num_ops == 1 || ((op_type == OBJ_OP_WRITE) && num_ops == 2));
1844 1913
1845 /* Allocate and initialize the request, for the num_ops ops */ 1914 /* Allocate and initialize the request, for the num_ops ops */
1846 1915
@@ -1850,7 +1919,7 @@ static struct ceph_osd_request *rbd_osd_req_create(
1850 if (!osd_req) 1919 if (!osd_req)
1851 return NULL; /* ENOMEM */ 1920 return NULL; /* ENOMEM */
1852 1921
1853 if (write_request) 1922 if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
1854 osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK; 1923 osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK;
1855 else 1924 else
1856 osd_req->r_flags = CEPH_OSD_FLAG_READ; 1925 osd_req->r_flags = CEPH_OSD_FLAG_READ;
@@ -1865,9 +1934,10 @@ static struct ceph_osd_request *rbd_osd_req_create(
1865} 1934}
1866 1935</