diff options
author | Alex Elder <elder@inktank.com> | 2013-01-19 01:30:28 -0500 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-02-13 21:29:09 -0500 |
commit | 36be9a761844e186f629f463b665945df4f67766 (patch) | |
tree | a7d32f82cc212b2e2c91346087f7c2cc4691b7c2 /drivers/block | |
parent | cf81b60e4bbd4a1281fe2640f9c0c40fe3a85fdf (diff) |
rbd: implement sync method with new code
Reimplement synchronous object method calls using the new request
tracking code. Use the name rbd_obj_method_sync()
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/rbd.c | 114 |
1 files changed, 96 insertions, 18 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 76917cc3e5a1..d10649f2e346 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -1415,6 +1415,7 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, | |||
1415 | case CEPH_OSD_OP_WRITE: | 1415 | case CEPH_OSD_OP_WRITE: |
1416 | rbd_osd_write_callback(obj_request, op); | 1416 | rbd_osd_write_callback(obj_request, op); |
1417 | break; | 1417 | break; |
1418 | case CEPH_OSD_OP_CALL: | ||
1418 | case CEPH_OSD_OP_NOTIFY_ACK: | 1419 | case CEPH_OSD_OP_NOTIFY_ACK: |
1419 | case CEPH_OSD_OP_WATCH: | 1420 | case CEPH_OSD_OP_WATCH: |
1420 | rbd_osd_trivial_callback(obj_request, op); | 1421 | rbd_osd_trivial_callback(obj_request, op); |
@@ -1904,6 +1905,82 @@ done: | |||
1904 | return ret; | 1905 | return ret; |
1905 | } | 1906 | } |
1906 | 1907 | ||
1908 | /* | ||
1909 | * Synchronous osd object method call | ||
1910 | */ | ||
1911 | static int rbd_obj_method_sync(struct rbd_device *rbd_dev, | ||
1912 | const char *object_name, | ||
1913 | const char *class_name, | ||
1914 | const char *method_name, | ||
1915 | const char *outbound, | ||
1916 | size_t outbound_size, | ||
1917 | char *inbound, | ||
1918 | size_t inbound_size, | ||
1919 | u64 *version) | ||
1920 | { | ||
1921 | struct rbd_obj_request *obj_request; | ||
1922 | struct ceph_osd_client *osdc; | ||
1923 | struct ceph_osd_req_op *op; | ||
1924 | struct page **pages; | ||
1925 | u32 page_count; | ||
1926 | int ret; | ||
1927 | |||
1928 | /* | ||
1929 | * Method calls are ultimately read operations but they | ||
1930 | * don't involve object data (so no offset or length). | ||
1931 | * The result should placed into the inbound buffer | ||
1932 | * provided. They also supply outbound data--parameters for | ||
1933 | * the object method. Currently if this is present it will | ||
1934 | * be a snapshot id. | ||
1935 | */ | ||
1936 | page_count = (u32) calc_pages_for(0, inbound_size); | ||
1937 | pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); | ||
1938 | if (IS_ERR(pages)) | ||
1939 | return PTR_ERR(pages); | ||
1940 | |||
1941 | ret = -ENOMEM; | ||
1942 | obj_request = rbd_obj_request_create(object_name, 0, 0, | ||
1943 | OBJ_REQUEST_PAGES); | ||
1944 | if (!obj_request) | ||
1945 | goto out; | ||
1946 | |||
1947 | obj_request->pages = pages; | ||
1948 | obj_request->page_count = page_count; | ||
1949 | |||
1950 | op = rbd_osd_req_op_create(CEPH_OSD_OP_CALL, class_name, | ||
1951 | method_name, outbound, outbound_size); | ||
1952 | if (!op) | ||
1953 | goto out; | ||
1954 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, | ||
1955 | obj_request, op); | ||
1956 | rbd_osd_req_op_destroy(op); | ||
1957 | if (!obj_request->osd_req) | ||
1958 | goto out; | ||
1959 | |||
1960 | osdc = &rbd_dev->rbd_client->client->osdc; | ||
1961 | ret = rbd_obj_request_submit(osdc, obj_request); | ||
1962 | if (ret) | ||
1963 | goto out; | ||
1964 | ret = rbd_obj_request_wait(obj_request); | ||
1965 | if (ret) | ||
1966 | goto out; | ||
1967 | |||
1968 | ret = obj_request->result; | ||
1969 | if (ret < 0) | ||
1970 | goto out; | ||
1971 | ret = ceph_copy_from_page_vector(pages, inbound, 0, | ||
1972 | obj_request->xferred); | ||
1973 | if (version) | ||
1974 | *version = obj_request->version; | ||
1975 | out: | ||
1976 | if (obj_request) | ||
1977 | rbd_obj_request_put(obj_request); | ||
1978 | else | ||
1979 | ceph_release_page_vector(pages, page_count); | ||
1980 | |||
1981 | return ret; | ||
1982 | } | ||
1983 | |||
1907 | static void rbd_request_fn(struct request_queue *q) | 1984 | static void rbd_request_fn(struct request_queue *q) |
1908 | { | 1985 | { |
1909 | struct rbd_device *rbd_dev = q->queuedata; | 1986 | struct rbd_device *rbd_dev = q->queuedata; |
@@ -2054,7 +2131,7 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, | |||
2054 | 2131 | ||
2055 | ret = -ENOMEM; | 2132 | ret = -ENOMEM; |
2056 | obj_request = rbd_obj_request_create(object_name, offset, length, | 2133 | obj_request = rbd_obj_request_create(object_name, offset, length, |
2057 | OBJ_REQUEST_PAGES); | 2134 | OBJ_REQUEST_PAGES); |
2058 | if (!obj_request) | 2135 | if (!obj_request) |
2059 | goto out; | 2136 | goto out; |
2060 | 2137 | ||
@@ -2754,11 +2831,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, | |||
2754 | __le64 size; | 2831 | __le64 size; |
2755 | } __attribute__ ((packed)) size_buf = { 0 }; | 2832 | } __attribute__ ((packed)) size_buf = { 0 }; |
2756 | 2833 | ||
2757 | ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, | 2834 | (void) rbd_req_sync_exec; /* Avoid a warning */ |
2835 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, | ||
2758 | "rbd", "get_size", | 2836 | "rbd", "get_size", |
2759 | (char *) &snapid, sizeof (snapid), | 2837 | (char *) &snapid, sizeof (snapid), |
2760 | (char *) &size_buf, sizeof (size_buf), NULL); | 2838 | (char *) &size_buf, sizeof (size_buf), NULL); |
2761 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | 2839 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
2762 | if (ret < 0) | 2840 | if (ret < 0) |
2763 | return ret; | 2841 | return ret; |
2764 | 2842 | ||
@@ -2789,14 +2867,14 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) | |||
2789 | if (!reply_buf) | 2867 | if (!reply_buf) |
2790 | return -ENOMEM; | 2868 | return -ENOMEM; |
2791 | 2869 | ||
2792 | ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, | 2870 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
2793 | "rbd", "get_object_prefix", | 2871 | "rbd", "get_object_prefix", |
2794 | NULL, 0, | 2872 | NULL, 0, |
2795 | reply_buf, RBD_OBJ_PREFIX_LEN_MAX, NULL); | 2873 | reply_buf, RBD_OBJ_PREFIX_LEN_MAX, NULL); |
2796 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | 2874 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
2797 | if (ret < 0) | 2875 | if (ret < 0) |
2798 | goto out; | 2876 | goto out; |
2799 | ret = 0; /* rbd_req_sync_exec() can return positive */ | 2877 | ret = 0; /* rbd_obj_method_sync() can return positive */ |
2800 | 2878 | ||
2801 | p = reply_buf; | 2879 | p = reply_buf; |
2802 | rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, | 2880 | rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, |
@@ -2827,12 +2905,12 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, | |||
2827 | u64 incompat; | 2905 | u64 incompat; |
2828 | int ret; | 2906 | int ret; |
2829 | 2907 | ||
2830 | ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, | 2908 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
2831 | "rbd", "get_features", | 2909 | "rbd", "get_features", |
2832 | (char *) &snapid, sizeof (snapid), | 2910 | (char *) &snapid, sizeof (snapid), |
2833 | (char *) &features_buf, sizeof (features_buf), | 2911 | (char *) &features_buf, sizeof (features_buf), |
2834 | NULL); | 2912 | NULL); |
2835 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | 2913 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
2836 | if (ret < 0) | 2914 | if (ret < 0) |
2837 | return ret; | 2915 | return ret; |
2838 | 2916 | ||
@@ -2883,11 +2961,11 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) | |||
2883 | } | 2961 | } |
2884 | 2962 | ||
2885 | snapid = cpu_to_le64(CEPH_NOSNAP); | 2963 | snapid = cpu_to_le64(CEPH_NOSNAP); |
2886 | ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, | 2964 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
2887 | "rbd", "get_parent", | 2965 | "rbd", "get_parent", |
2888 | (char *) &snapid, sizeof (snapid), | 2966 | (char *) &snapid, sizeof (snapid), |
2889 | (char *) reply_buf, size, NULL); | 2967 | (char *) reply_buf, size, NULL); |
2890 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | 2968 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
2891 | if (ret < 0) | 2969 | if (ret < 0) |
2892 | goto out_err; | 2970 | goto out_err; |
2893 | 2971 | ||
@@ -2954,7 +3032,7 @@ static char *rbd_dev_image_name(struct rbd_device *rbd_dev) | |||
2954 | if (!reply_buf) | 3032 | if (!reply_buf) |
2955 | goto out; | 3033 | goto out; |
2956 | 3034 | ||
2957 | ret = rbd_req_sync_exec(rbd_dev, RBD_DIRECTORY, | 3035 | ret = rbd_obj_method_sync(rbd_dev, RBD_DIRECTORY, |
2958 | "rbd", "dir_get_name", | 3036 | "rbd", "dir_get_name", |
2959 | image_id, image_id_size, | 3037 | image_id, image_id_size, |
2960 | (char *) reply_buf, size, NULL); | 3038 | (char *) reply_buf, size, NULL); |
@@ -3060,11 +3138,11 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver) | |||
3060 | if (!reply_buf) | 3138 | if (!reply_buf) |
3061 | return -ENOMEM; | 3139 | return -ENOMEM; |
3062 | 3140 | ||
3063 | ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, | 3141 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
3064 | "rbd", "get_snapcontext", | 3142 | "rbd", "get_snapcontext", |
3065 | NULL, 0, | 3143 | NULL, 0, |
3066 | reply_buf, size, ver); | 3144 | reply_buf, size, ver); |
3067 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | 3145 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
3068 | if (ret < 0) | 3146 | if (ret < 0) |
3069 | goto out; | 3147 | goto out; |
3070 | 3148 | ||
@@ -3129,11 +3207,11 @@ static char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u32 which) | |||
3129 | return ERR_PTR(-ENOMEM); | 3207 | return ERR_PTR(-ENOMEM); |
3130 | 3208 | ||
3131 | snap_id = cpu_to_le64(rbd_dev->header.snapc->snaps[which]); | 3209 | snap_id = cpu_to_le64(rbd_dev->header.snapc->snaps[which]); |
3132 | ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name, | 3210 | ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name, |
3133 | "rbd", "get_snapshot_name", | 3211 | "rbd", "get_snapshot_name", |
3134 | (char *) &snap_id, sizeof (snap_id), | 3212 | (char *) &snap_id, sizeof (snap_id), |
3135 | reply_buf, size, NULL); | 3213 | reply_buf, size, NULL); |
3136 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | 3214 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
3137 | if (ret < 0) | 3215 | if (ret < 0) |
3138 | goto out; | 3216 | goto out; |
3139 | 3217 | ||
@@ -3721,14 +3799,14 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev) | |||
3721 | goto out; | 3799 | goto out; |
3722 | } | 3800 | } |
3723 | 3801 | ||
3724 | ret = rbd_req_sync_exec(rbd_dev, object_name, | 3802 | ret = rbd_obj_method_sync(rbd_dev, object_name, |
3725 | "rbd", "get_id", | 3803 | "rbd", "get_id", |
3726 | NULL, 0, | 3804 | NULL, 0, |
3727 | response, RBD_IMAGE_ID_LEN_MAX, NULL); | 3805 | response, RBD_IMAGE_ID_LEN_MAX, NULL); |
3728 | dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret); | 3806 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); |
3729 | if (ret < 0) | 3807 | if (ret < 0) |
3730 | goto out; | 3808 | goto out; |
3731 | ret = 0; /* rbd_req_sync_exec() can return positive */ | 3809 | ret = 0; /* rbd_obj_method_sync() can return positive */ |
3732 | 3810 | ||
3733 | p = response; | 3811 | p = response; |
3734 | rbd_dev->spec->image_id = ceph_extract_encoded_string(&p, | 3812 | rbd_dev->spec->image_id = ceph_extract_encoded_string(&p, |