diff options
| author | Ilya Dryomov <idryomov@gmail.com> | 2019-02-25 06:37:50 -0500 |
|---|---|---|
| committer | Ilya Dryomov <idryomov@gmail.com> | 2019-03-05 12:55:17 -0500 |
| commit | 13488d53775ba5f82dc4075c424d06dfe4b6b162 (patch) | |
| tree | 96cf07b627778e4974edc95b81e48db350f5515a | |
| parent | e28eded58bdb5579e7f772160f09d33760e3354d (diff) | |
rbd: stop copying num_osd_ops in rbd_obj_issue_copyup()
In preparation for deep-flatten feature, stop copying num_osd_ops from
the original request in rbd_obj_issue_copyup(). Split the calculation
into count_{write,zeroout}_ops() respectively and determine whether the
assert_exists guard is needed with the new rbd_obj_copyup_enabled().
As a nice side effect, we no longer guard in the writefull case as the
copyup'ed object is always fully overwritten.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
| -rw-r--r-- | drivers/block/rbd.c | 90 |
1 files changed, 59 insertions, 31 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 66915528298e..f9cad40d95af 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -1424,6 +1424,18 @@ static bool rbd_obj_is_tail(struct rbd_obj_request *obj_req) | |||
| 1424 | rbd_dev->layout.object_size; | 1424 | rbd_dev->layout.object_size; |
| 1425 | } | 1425 | } |
| 1426 | 1426 | ||
| 1427 | /* | ||
| 1428 | * Must be called after rbd_obj_calc_img_extents(). | ||
| 1429 | */ | ||
| 1430 | static bool rbd_obj_copyup_enabled(struct rbd_obj_request *obj_req) | ||
| 1431 | { | ||
| 1432 | if (!obj_req->num_img_extents || | ||
| 1433 | rbd_obj_is_entire(obj_req)) | ||
| 1434 | return false; | ||
| 1435 | |||
| 1436 | return true; | ||
| 1437 | } | ||
| 1438 | |||
| 1427 | static u64 rbd_obj_img_extents_bytes(struct rbd_obj_request *obj_req) | 1439 | static u64 rbd_obj_img_extents_bytes(struct rbd_obj_request *obj_req) |
| 1428 | { | 1440 | { |
| 1429 | return ceph_file_extents_bytes(obj_req->img_extents, | 1441 | return ceph_file_extents_bytes(obj_req->img_extents, |
| @@ -1810,6 +1822,11 @@ static int __rbd_obj_setup_stat(struct rbd_obj_request *obj_req, | |||
| 1810 | return 0; | 1822 | return 0; |
| 1811 | } | 1823 | } |
| 1812 | 1824 | ||
| 1825 | static int count_write_ops(struct rbd_obj_request *obj_req) | ||
| 1826 | { | ||
| 1827 | return 2; /* setallochint + write/writefull */ | ||
| 1828 | } | ||
| 1829 | |||
| 1813 | static void __rbd_obj_setup_write(struct rbd_obj_request *obj_req, | 1830 | static void __rbd_obj_setup_write(struct rbd_obj_request *obj_req, |
| 1814 | unsigned int which) | 1831 | unsigned int which) |
| 1815 | { | 1832 | { |
| @@ -1836,6 +1853,7 @@ static void __rbd_obj_setup_write(struct rbd_obj_request *obj_req, | |||
| 1836 | static int rbd_obj_setup_write(struct rbd_obj_request *obj_req) | 1853 | static int rbd_obj_setup_write(struct rbd_obj_request *obj_req) |
| 1837 | { | 1854 | { |
| 1838 | unsigned int num_osd_ops, which = 0; | 1855 | unsigned int num_osd_ops, which = 0; |
| 1856 | bool need_guard; | ||
| 1839 | int ret; | 1857 | int ret; |
| 1840 | 1858 | ||
| 1841 | /* reverse map the entire object onto the parent */ | 1859 | /* reverse map the entire object onto the parent */ |
| @@ -1843,22 +1861,21 @@ static int rbd_obj_setup_write(struct rbd_obj_request *obj_req) | |||
| 1843 | if (ret) | 1861 | if (ret) |
| 1844 | return ret; | 1862 | return ret; |
| 1845 | 1863 | ||
| 1846 | if (obj_req->num_img_extents) { | 1864 | need_guard = rbd_obj_copyup_enabled(obj_req); |
| 1847 | obj_req->write_state = RBD_OBJ_WRITE_GUARD; | 1865 | num_osd_ops = need_guard + count_write_ops(obj_req); |
| 1848 | num_osd_ops = 3; /* stat + setallochint + write/writefull */ | ||
| 1849 | } else { | ||
| 1850 | obj_req->write_state = RBD_OBJ_WRITE_FLAT; | ||
| 1851 | num_osd_ops = 2; /* setallochint + write/writefull */ | ||
| 1852 | } | ||
| 1853 | 1866 | ||
| 1854 | obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); | 1867 | obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); |
| 1855 | if (!obj_req->osd_req) | 1868 | if (!obj_req->osd_req) |
| 1856 | return -ENOMEM; | 1869 | return -ENOMEM; |
| 1857 | 1870 | ||
| 1858 | if (obj_req->num_img_extents) { | 1871 | if (need_guard) { |
| 1859 | ret = __rbd_obj_setup_stat(obj_req, which++); | 1872 | ret = __rbd_obj_setup_stat(obj_req, which++); |
| 1860 | if (ret) | 1873 | if (ret) |
| 1861 | return ret; | 1874 | return ret; |
| 1875 | |||
| 1876 | obj_req->write_state = RBD_OBJ_WRITE_GUARD; | ||
| 1877 | } else { | ||
| 1878 | obj_req->write_state = RBD_OBJ_WRITE_FLAT; | ||
| 1862 | } | 1879 | } |
| 1863 | 1880 | ||
| 1864 | __rbd_obj_setup_write(obj_req, which); | 1881 | __rbd_obj_setup_write(obj_req, which); |
| @@ -1919,6 +1936,18 @@ static int rbd_obj_setup_discard(struct rbd_obj_request *obj_req) | |||
| 1919 | return 0; | 1936 | return 0; |
| 1920 | } | 1937 | } |
| 1921 | 1938 | ||
| 1939 | static int count_zeroout_ops(struct rbd_obj_request *obj_req) | ||
| 1940 | { | ||
| 1941 | int num_osd_ops; | ||
| 1942 | |||
| 1943 | if (rbd_obj_is_entire(obj_req) && obj_req->num_img_extents) | ||
| 1944 | num_osd_ops = 2; /* create + truncate */ | ||
| 1945 | else | ||
| 1946 | num_osd_ops = 1; /* delete/truncate/zero */ | ||
| 1947 | |||
| 1948 | return num_osd_ops; | ||
| 1949 | } | ||
| 1950 | |||
| 1922 | static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req, | 1951 | static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req, |
| 1923 | unsigned int which) | 1952 | unsigned int which) |
| 1924 | { | 1953 | { |
| @@ -1950,6 +1979,7 @@ static void __rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req, | |||
| 1950 | static int rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req) | 1979 | static int rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req) |
| 1951 | { | 1980 | { |
| 1952 | unsigned int num_osd_ops, which = 0; | 1981 | unsigned int num_osd_ops, which = 0; |
| 1982 | bool need_guard; | ||
| 1953 | int ret; | 1983 | int ret; |
| 1954 | 1984 | ||
| 1955 | /* reverse map the entire object onto the parent */ | 1985 | /* reverse map the entire object onto the parent */ |
| @@ -1957,30 +1987,21 @@ static int rbd_obj_setup_zeroout(struct rbd_obj_request *obj_req) | |||
| 1957 | if (ret) | 1987 | if (ret) |
| 1958 | return ret; | 1988 | return ret; |
| 1959 | 1989 | ||
| 1960 | if (rbd_obj_is_entire(obj_req)) { | 1990 | need_guard = rbd_obj_copyup_enabled(obj_req); |
| 1961 | obj_req->write_state = RBD_OBJ_WRITE_FLAT; | 1991 | num_osd_ops = need_guard + count_zeroout_ops(obj_req); |
| 1962 | if (obj_req->num_img_extents) | ||
| 1963 | num_osd_ops = 2; /* create + truncate */ | ||
| 1964 | else | ||
| 1965 | num_osd_ops = 1; /* delete */ | ||
| 1966 | } else { | ||
| 1967 | if (obj_req->num_img_extents) { | ||
| 1968 | obj_req->write_state = RBD_OBJ_WRITE_GUARD; | ||
| 1969 | num_osd_ops = 2; /* stat + truncate/zero */ | ||
| 1970 | } else { | ||
| 1971 | obj_req->write_state = RBD_OBJ_WRITE_FLAT; | ||
| 1972 | num_osd_ops = 1; /* truncate/zero */ | ||
| 1973 | } | ||
| 1974 | } | ||
| 1975 | 1992 | ||
| 1976 | obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); | 1993 | obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); |
| 1977 | if (!obj_req->osd_req) | 1994 | if (!obj_req->osd_req) |
| 1978 | return -ENOMEM; | 1995 | return -ENOMEM; |
| 1979 | 1996 | ||
| 1980 | if (!rbd_obj_is_entire(obj_req) && obj_req->num_img_extents) { | 1997 | if (need_guard) { |
| 1981 | ret = __rbd_obj_setup_stat(obj_req, which++); | 1998 | ret = __rbd_obj_setup_stat(obj_req, which++); |
| 1982 | if (ret) | 1999 | if (ret) |
| 1983 | return ret; | 2000 | return ret; |
| 2001 | |||
| 2002 | obj_req->write_state = RBD_OBJ_WRITE_GUARD; | ||
| 2003 | } else { | ||
| 2004 | obj_req->write_state = RBD_OBJ_WRITE_FLAT; | ||
| 1984 | } | 2005 | } |
| 1985 | 2006 | ||
| 1986 | __rbd_obj_setup_zeroout(obj_req, which); | 2007 | __rbd_obj_setup_zeroout(obj_req, which); |
| @@ -2439,18 +2460,25 @@ static bool is_zero_bvecs(struct bio_vec *bvecs, u32 bytes) | |||
| 2439 | 2460 | ||
| 2440 | static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) | 2461 | static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) |
| 2441 | { | 2462 | { |
| 2442 | unsigned int num_osd_ops = obj_req->osd_req->r_num_ops; | 2463 | struct rbd_img_request *img_req = obj_req->img_request; |
| 2464 | unsigned int num_osd_ops = 1; | ||
| 2443 | int ret; | 2465 | int ret; |
| 2444 | 2466 | ||
| 2445 | dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); | 2467 | dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); |
| 2446 | rbd_assert(obj_req->osd_req->r_ops[0].op == CEPH_OSD_OP_STAT); | 2468 | rbd_assert(obj_req->osd_req->r_ops[0].op == CEPH_OSD_OP_STAT); |
| 2447 | rbd_osd_req_destroy(obj_req->osd_req); | 2469 | rbd_osd_req_destroy(obj_req->osd_req); |
| 2448 | 2470 | ||
| 2449 | /* | 2471 | switch (img_req->op_type) { |
| 2450 | * Create a copyup request with the same number of OSD ops as | 2472 | case OBJ_OP_WRITE: |
| 2451 | * the original request. The original request was stat + op(s), | 2473 | num_osd_ops += count_write_ops(obj_req); |
| 2452 | * the new copyup request will be copyup + the same op(s). | 2474 | break; |
| 2453 | */ | 2475 | case OBJ_OP_ZEROOUT: |
| 2476 | num_osd_ops += count_zeroout_ops(obj_req); | ||
| 2477 | break; | ||
| 2478 | default: | ||
| 2479 | rbd_assert(0); | ||
| 2480 | } | ||
| 2481 | |||
| 2454 | obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); | 2482 | obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops); |
| 2455 | if (!obj_req->osd_req) | 2483 | if (!obj_req->osd_req) |
| 2456 | return -ENOMEM; | 2484 | return -ENOMEM; |
| @@ -2473,7 +2501,7 @@ static int rbd_obj_issue_copyup(struct rbd_obj_request *obj_req, u32 bytes) | |||
| 2473 | obj_req->copyup_bvec_count, | 2501 | obj_req->copyup_bvec_count, |
| 2474 | bytes); | 2502 | bytes); |
| 2475 | 2503 | ||
| 2476 | switch (obj_req->img_request->op_type) { | 2504 | switch (img_req->op_type) { |
| 2477 | case OBJ_OP_WRITE: | 2505 | case OBJ_OP_WRITE: |
| 2478 | __rbd_obj_setup_write(obj_req, 1); | 2506 | __rbd_obj_setup_write(obj_req, 1); |
| 2479 | break; | 2507 | break; |
