diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/rbd.c | 158 |
1 files changed, 90 insertions, 68 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index ab6e6d8364ef..2049810fcdc2 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -112,6 +112,27 @@ struct rbd_image_header { | |||
112 | u64 obj_version; | 112 | u64 obj_version; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | /* | ||
116 | * An rbd image specification. | ||
117 | * | ||
118 | * The tuple (pool_id, image_id, snap_id) is sufficient to uniquely | ||
119 | * identify an image. | ||
120 | */ | ||
121 | struct rbd_spec { | ||
122 | u64 pool_id; | ||
123 | char *pool_name; | ||
124 | |||
125 | char *image_id; | ||
126 | size_t image_id_len; | ||
127 | char *image_name; | ||
128 | size_t image_name_len; | ||
129 | |||
130 | u64 snap_id; | ||
131 | char *snap_name; | ||
132 | |||
133 | struct kref kref; | ||
134 | }; | ||
135 | |||
115 | struct rbd_options { | 136 | struct rbd_options { |
116 | bool read_only; | 137 | bool read_only; |
117 | }; | 138 | }; |
@@ -189,16 +210,9 @@ struct rbd_device { | |||
189 | 210 | ||
190 | struct rbd_image_header header; | 211 | struct rbd_image_header header; |
191 | bool exists; | 212 | bool exists; |
192 | char *image_id; | 213 | struct rbd_spec *spec; |
193 | size_t image_id_len; | ||
194 | char *image_name; | ||
195 | size_t image_name_len; | ||
196 | char *header_name; | ||
197 | char *pool_name; | ||
198 | u64 pool_id; | ||
199 | 214 | ||
200 | char *snap_name; | 215 | char *header_name; |
201 | u64 snap_id; | ||
202 | 216 | ||
203 | struct ceph_osd_event *watch_event; | 217 | struct ceph_osd_event *watch_event; |
204 | struct ceph_osd_request *watch_request; | 218 | struct ceph_osd_request *watch_request; |
@@ -654,7 +668,7 @@ static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name) | |||
654 | 668 | ||
655 | list_for_each_entry(snap, &rbd_dev->snaps, node) { | 669 | list_for_each_entry(snap, &rbd_dev->snaps, node) { |
656 | if (!strcmp(snap_name, snap->name)) { | 670 | if (!strcmp(snap_name, snap->name)) { |
657 | rbd_dev->snap_id = snap->id; | 671 | rbd_dev->spec->snap_id = snap->id; |
658 | rbd_dev->mapping.size = snap->size; | 672 | rbd_dev->mapping.size = snap->size; |
659 | rbd_dev->mapping.features = snap->features; | 673 | rbd_dev->mapping.features = snap->features; |
660 | 674 | ||
@@ -669,14 +683,14 @@ static int rbd_dev_set_mapping(struct rbd_device *rbd_dev) | |||
669 | { | 683 | { |
670 | int ret; | 684 | int ret; |
671 | 685 | ||
672 | if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME, | 686 | if (!memcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME, |
673 | sizeof (RBD_SNAP_HEAD_NAME))) { | 687 | sizeof (RBD_SNAP_HEAD_NAME))) { |
674 | rbd_dev->snap_id = CEPH_NOSNAP; | 688 | rbd_dev->spec->snap_id = CEPH_NOSNAP; |
675 | rbd_dev->mapping.size = rbd_dev->header.image_size; | 689 | rbd_dev->mapping.size = rbd_dev->header.image_size; |
676 | rbd_dev->mapping.features = rbd_dev->header.features; | 690 | rbd_dev->mapping.features = rbd_dev->header.features; |
677 | ret = 0; | 691 | ret = 0; |
678 | } else { | 692 | } else { |
679 | ret = snap_by_name(rbd_dev, rbd_dev->snap_name); | 693 | ret = snap_by_name(rbd_dev, rbd_dev->spec->snap_name); |
680 | if (ret < 0) | 694 | if (ret < 0) |
681 | goto done; | 695 | goto done; |
682 | rbd_dev->mapping.read_only = true; | 696 | rbd_dev->mapping.read_only = true; |
@@ -1096,7 +1110,7 @@ static int rbd_do_request(struct request *rq, | |||
1096 | layout->fl_stripe_unit = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER); | 1110 | layout->fl_stripe_unit = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER); |
1097 | layout->fl_stripe_count = cpu_to_le32(1); | 1111 | layout->fl_stripe_count = cpu_to_le32(1); |
1098 | layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER); | 1112 | layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER); |
1099 | layout->fl_pg_pool = cpu_to_le32((int) rbd_dev->pool_id); | 1113 | layout->fl_pg_pool = cpu_to_le32((int) rbd_dev->spec->pool_id); |
1100 | ret = ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno, | 1114 | ret = ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno, |
1101 | req, ops); | 1115 | req, ops); |
1102 | rbd_assert(ret == 0); | 1116 | rbd_assert(ret == 0); |
@@ -1261,7 +1275,7 @@ static int rbd_do_op(struct request *rq, | |||
1261 | opcode = CEPH_OSD_OP_READ; | 1275 | opcode = CEPH_OSD_OP_READ; |
1262 | flags = CEPH_OSD_FLAG_READ; | 1276 | flags = CEPH_OSD_FLAG_READ; |
1263 | snapc = NULL; | 1277 | snapc = NULL; |
1264 | snapid = rbd_dev->snap_id; | 1278 | snapid = rbd_dev->spec->snap_id; |
1265 | payload_len = 0; | 1279 | payload_len = 0; |
1266 | } | 1280 | } |
1267 | 1281 | ||
@@ -1545,7 +1559,7 @@ static void rbd_rq_fn(struct request_queue *q) | |||
1545 | down_read(&rbd_dev->header_rwsem); | 1559 | down_read(&rbd_dev->header_rwsem); |
1546 | 1560 | ||
1547 | if (!rbd_dev->exists) { | 1561 | if (!rbd_dev->exists) { |
1548 | rbd_assert(rbd_dev->snap_id != CEPH_NOSNAP); | 1562 | rbd_assert(rbd_dev->spec->snap_id != CEPH_NOSNAP); |
1549 | up_read(&rbd_dev->header_rwsem); | 1563 | up_read(&rbd_dev->header_rwsem); |
1550 | dout("request for non-existent snapshot"); | 1564 | dout("request for non-existent snapshot"); |
1551 | spin_lock_irq(q->queue_lock); | 1565 | spin_lock_irq(q->queue_lock); |
@@ -1726,13 +1740,13 @@ rbd_dev_v1_header_read(struct rbd_device *rbd_dev, u64 *version) | |||
1726 | ret = -ENXIO; | 1740 | ret = -ENXIO; |
1727 | pr_warning("short header read for image %s" | 1741 | pr_warning("short header read for image %s" |
1728 | " (want %zd got %d)\n", | 1742 | " (want %zd got %d)\n", |
1729 | rbd_dev->image_name, size, ret); | 1743 | rbd_dev->spec->image_name, size, ret); |
1730 | goto out_err; | 1744 | goto out_err; |
1731 | } | 1745 | } |
1732 | if (!rbd_dev_ondisk_valid(ondisk)) { | 1746 | if (!rbd_dev_ondisk_valid(ondisk)) { |
1733 | ret = -ENXIO; | 1747 | ret = -ENXIO; |
1734 | pr_warning("invalid header for image %s\n", | 1748 | pr_warning("invalid header for image %s\n", |
1735 | rbd_dev->image_name); | 1749 | rbd_dev->spec->image_name); |
1736 | goto out_err; | 1750 | goto out_err; |
1737 | } | 1751 | } |
1738 | 1752 | ||
@@ -1783,7 +1797,7 @@ static void rbd_update_mapping_size(struct rbd_device *rbd_dev) | |||
1783 | { | 1797 | { |
1784 | sector_t size; | 1798 | sector_t size; |
1785 | 1799 | ||
1786 | if (rbd_dev->snap_id != CEPH_NOSNAP) | 1800 | if (rbd_dev->spec->snap_id != CEPH_NOSNAP) |
1787 | return; | 1801 | return; |
1788 | 1802 | ||
1789 | size = (sector_t) rbd_dev->header.image_size / SECTOR_SIZE; | 1803 | size = (sector_t) rbd_dev->header.image_size / SECTOR_SIZE; |
@@ -1957,7 +1971,7 @@ static ssize_t rbd_pool_show(struct device *dev, | |||
1957 | { | 1971 | { |
1958 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); | 1972 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); |
1959 | 1973 | ||
1960 | return sprintf(buf, "%s\n", rbd_dev->pool_name); | 1974 | return sprintf(buf, "%s\n", rbd_dev->spec->pool_name); |
1961 | } | 1975 | } |
1962 | 1976 | ||
1963 | static ssize_t rbd_pool_id_show(struct device *dev, | 1977 | static ssize_t rbd_pool_id_show(struct device *dev, |
@@ -1965,7 +1979,8 @@ static ssize_t rbd_pool_id_show(struct device *dev, | |||
1965 | { | 1979 | { |
1966 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); | 1980 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); |
1967 | 1981 | ||
1968 | return sprintf(buf, "%llu\n", (unsigned long long) rbd_dev->pool_id); | 1982 | return sprintf(buf, "%llu\n", |
1983 | (unsigned long long) rbd_dev->spec->pool_id); | ||
1969 | } | 1984 | } |
1970 | 1985 | ||
1971 | static ssize_t rbd_name_show(struct device *dev, | 1986 | static ssize_t rbd_name_show(struct device *dev, |
@@ -1973,7 +1988,7 @@ static ssize_t rbd_name_show(struct device *dev, | |||
1973 | { | 1988 | { |
1974 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); | 1989 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); |
1975 | 1990 | ||
1976 | return sprintf(buf, "%s\n", rbd_dev->image_name); | 1991 | return sprintf(buf, "%s\n", rbd_dev->spec->image_name); |
1977 | } | 1992 | } |
1978 | 1993 | ||
1979 | static ssize_t rbd_image_id_show(struct device *dev, | 1994 | static ssize_t rbd_image_id_show(struct device *dev, |
@@ -1981,7 +1996,7 @@ static ssize_t rbd_image_id_show(struct device *dev, | |||
1981 | { | 1996 | { |
1982 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); | 1997 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); |
1983 | 1998 | ||
1984 | return sprintf(buf, "%s\n", rbd_dev->image_id); | 1999 | return sprintf(buf, "%s\n", rbd_dev->spec->image_id); |
1985 | } | 2000 | } |
1986 | 2001 | ||
1987 | /* | 2002 | /* |
@@ -1994,7 +2009,7 @@ static ssize_t rbd_snap_show(struct device *dev, | |||
1994 | { | 2009 | { |
1995 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); | 2010 | struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); |
1996 | 2011 | ||
1997 | return sprintf(buf, "%s\n", rbd_dev->snap_name); | 2012 | return sprintf(buf, "%s\n", rbd_dev->spec->snap_name); |
1998 | } | 2013 | } |
1999 | 2014 | ||
2000 | static ssize_t rbd_image_refresh(struct device *dev, | 2015 | static ssize_t rbd_image_refresh(struct device *dev, |
@@ -2547,11 +2562,12 @@ static int rbd_dev_snaps_update(struct rbd_device *rbd_dev) | |||
2547 | 2562 | ||
2548 | /* Existing snapshot not in the new snap context */ | 2563 | /* Existing snapshot not in the new snap context */ |
2549 | 2564 | ||
2550 | if (rbd_dev->snap_id == snap->id) | 2565 | if (rbd_dev->spec->snap_id == snap->id) |
2551 | rbd_dev->exists = false; | 2566 | rbd_dev->exists = false; |
2552 | rbd_remove_snap_dev(snap); | 2567 | rbd_remove_snap_dev(snap); |
2553 | dout("%ssnap id %llu has been removed\n", | 2568 | dout("%ssnap id %llu has been removed\n", |
2554 | rbd_dev->snap_id == snap->id ? "mapped " : "", | 2569 | rbd_dev->spec->snap_id == snap->id ? |
2570 | "mapped " : "", | ||
2555 | (unsigned long long) snap->id); | 2571 | (unsigned long long) snap->id); |
2556 | 2572 | ||
2557 | /* Done with this list entry; advance */ | 2573 | /* Done with this list entry; advance */ |
@@ -2869,16 +2885,17 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev, | |||
2869 | if (!*options) | 2885 | if (!*options) |
2870 | goto out_err; /* Missing options */ | 2886 | goto out_err; /* Missing options */ |
2871 | 2887 | ||
2872 | rbd_dev->pool_name = dup_token(&buf, NULL); | 2888 | rbd_dev->spec->pool_name = dup_token(&buf, NULL); |
2873 | if (!rbd_dev->pool_name) | 2889 | if (!rbd_dev->spec->pool_name) |
2874 | goto out_mem; | 2890 | goto out_mem; |
2875 | if (!*rbd_dev->pool_name) | 2891 | if (!*rbd_dev->spec->pool_name) |
2876 | goto out_err; /* Missing pool name */ | 2892 | goto out_err; /* Missing pool name */ |
2877 | 2893 | ||
2878 | rbd_dev->image_name = dup_token(&buf, &rbd_dev->image_name_len); | 2894 | rbd_dev->spec->image_name = |
2879 | if (!rbd_dev->image_name) | 2895 | dup_token(&buf, &rbd_dev->spec->image_name_len); |
2896 | if (!rbd_dev->spec->image_name) | ||
2880 | goto out_mem; | 2897 | goto out_mem; |
2881 | if (!*rbd_dev->image_name) | 2898 | if (!*rbd_dev->spec->image_name) |
2882 | goto out_err; /* Missing image name */ | 2899 | goto out_err; /* Missing image name */ |
2883 | 2900 | ||
2884 | /* | 2901 | /* |
@@ -2893,11 +2910,11 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev, | |||
2893 | ret = -ENAMETOOLONG; | 2910 | ret = -ENAMETOOLONG; |
2894 | goto out_err; | 2911 | goto out_err; |
2895 | } | 2912 | } |
2896 | rbd_dev->snap_name = kmalloc(len + 1, GFP_KERNEL); | 2913 | rbd_dev->spec->snap_name = kmalloc(len + 1, GFP_KERNEL); |
2897 | if (!rbd_dev->snap_name) | 2914 | if (!rbd_dev->spec->snap_name) |
2898 | goto out_mem; | 2915 | goto out_mem; |
2899 | memcpy(rbd_dev->snap_name, buf, len); | 2916 | memcpy(rbd_dev->spec->snap_name, buf, len); |
2900 | *(rbd_dev->snap_name + len) = '\0'; | 2917 | *(rbd_dev->spec->snap_name + len) = '\0'; |
2901 | 2918 | ||
2902 | /* Initialize all rbd options to the defaults */ | 2919 | /* Initialize all rbd options to the defaults */ |
2903 | 2920 | ||
@@ -2921,11 +2938,11 @@ static int rbd_add_parse_args(struct rbd_device *rbd_dev, | |||
2921 | out_mem: | 2938 | out_mem: |
2922 | ret = -ENOMEM; | 2939 | ret = -ENOMEM; |
2923 | out_err: | 2940 | out_err: |
2924 | kfree(rbd_dev->image_name); | 2941 | kfree(rbd_dev->spec->image_name); |
2925 | rbd_dev->image_name = NULL; | 2942 | rbd_dev->spec->image_name = NULL; |
2926 | rbd_dev->image_name_len = 0; | 2943 | rbd_dev->spec->image_name_len = 0; |
2927 | kfree(rbd_dev->pool_name); | 2944 | kfree(rbd_dev->spec->pool_name); |
2928 | rbd_dev->pool_name = NULL; | 2945 | rbd_dev->spec->pool_name = NULL; |
2929 | kfree(options); | 2946 | kfree(options); |
2930 | 2947 | ||
2931 | return ret; | 2948 | return ret; |
@@ -2957,11 +2974,11 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev) | |||
2957 | * First, see if the format 2 image id file exists, and if | 2974 | * First, see if the format 2 image id file exists, and if |
2958 | * so, get the image's persistent id from it. | 2975 | * so, get the image's persistent id from it. |
2959 | */ | 2976 | */ |
2960 | size = sizeof (RBD_ID_PREFIX) + rbd_dev->image_name_len; | 2977 | size = sizeof (RBD_ID_PREFIX) + rbd_dev->spec->image_name_len; |
2961 | object_name = kmalloc(size, GFP_NOIO); | 2978 | object_name = kmalloc(size, GFP_NOIO); |
2962 | if (!object_name) | 2979 | if (!object_name) |
2963 | return -ENOMEM; | 2980 | return -ENOMEM; |
2964 | sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->image_name); | 2981 | sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->spec->image_name); |
2965 | dout("rbd id object name is %s\n", object_name); | 2982 | dout("rbd id object name is %s\n", object_name); |
2966 | 2983 | ||
2967 | /* Response will be an encoded string, which includes a length */ | 2984 | /* Response will be an encoded string, which includes a length */ |
@@ -2984,15 +3001,15 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev) | |||
2984 | ret = 0; /* rbd_req_sync_exec() can return positive */ | 3001 | ret = 0; /* rbd_req_sync_exec() can return positive */ |
2985 | 3002 | ||
2986 | p = response; | 3003 | p = response; |
2987 | rbd_dev->image_id = ceph_extract_encoded_string(&p, | 3004 | rbd_dev->spec->image_id = ceph_extract_encoded_string(&p, |
2988 | p + RBD_IMAGE_ID_LEN_MAX, | 3005 | p + RBD_IMAGE_ID_LEN_MAX, |
2989 | &rbd_dev->image_id_len, | 3006 | &rbd_dev->spec->image_id_len, |
2990 | GFP_NOIO); | 3007 | GFP_NOIO); |
2991 | if (IS_ERR(rbd_dev->image_id)) { | 3008 | if (IS_ERR(rbd_dev->spec->image_id)) { |
2992 | ret = PTR_ERR(rbd_dev->image_id); | 3009 | ret = PTR_ERR(rbd_dev->spec->image_id); |
2993 | rbd_dev->image_id = NULL; | 3010 | rbd_dev->spec->image_id = NULL; |
2994 | } else { | 3011 | } else { |
2995 | dout("image_id is %s\n", rbd_dev->image_id); | 3012 | dout("image_id is %s\n", rbd_dev->spec->image_id); |
2996 | } | 3013 | } |
2997 | out: | 3014 | out: |
2998 | kfree(response); | 3015 | kfree(response); |
@@ -3008,20 +3025,21 @@ static int rbd_dev_v1_probe(struct rbd_device *rbd_dev) | |||
3008 | 3025 | ||
3009 | /* Version 1 images have no id; empty string is used */ | 3026 | /* Version 1 images have no id; empty string is used */ |
3010 | 3027 | ||
3011 | rbd_dev->image_id = kstrdup("", GFP_KERNEL); | 3028 | rbd_dev->spec->image_id = kstrdup("", GFP_KERNEL); |
3012 | if (!rbd_dev->image_id) | 3029 | if (!rbd_dev->spec->image_id) |
3013 | return -ENOMEM; | 3030 | return -ENOMEM; |
3014 | rbd_dev->image_id_len = 0; | 3031 | rbd_dev->spec->image_id_len = 0; |
3015 | 3032 | ||
3016 | /* Record the header object name for this rbd image. */ | 3033 | /* Record the header object name for this rbd image. */ |
3017 | 3034 | ||
3018 | size = rbd_dev->image_name_len + sizeof (RBD_SUFFIX); | 3035 | size = rbd_dev->spec->image_name_len + sizeof (RBD_SUFFIX); |
3019 | rbd_dev->header_name = kmalloc(size, GFP_KERNEL); | 3036 | rbd_dev->header_name = kmalloc(size, GFP_KERNEL); |
3020 | if (!rbd_dev->header_name) { | 3037 | if (!rbd_dev->header_name) { |
3021 | ret = -ENOMEM; | 3038 | ret = -ENOMEM; |
3022 | goto out_err; | 3039 | goto out_err; |
3023 | } | 3040 | } |
3024 | sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX); | 3041 | sprintf(rbd_dev->header_name, "%s%s", |
3042 | rbd_dev->spec->image_name, RBD_SUFFIX); | ||
3025 | 3043 | ||
3026 | /* Populate rbd image metadata */ | 3044 | /* Populate rbd image metadata */ |
3027 | 3045 | ||
@@ -3038,8 +3056,8 @@ static int rbd_dev_v1_probe(struct rbd_device *rbd_dev) | |||
3038 | out_err: | 3056 | out_err: |
3039 | kfree(rbd_dev->header_name); | 3057 | kfree(rbd_dev->header_name); |
3040 | rbd_dev->header_name = NULL; | 3058 | rbd_dev->header_name = NULL; |
3041 | kfree(rbd_dev->image_id); | 3059 | kfree(rbd_dev->spec->image_id); |
3042 | rbd_dev->image_id = NULL; | 3060 | rbd_dev->spec->image_id = NULL; |
3043 | 3061 | ||
3044 | return ret; | 3062 | return ret; |
3045 | } | 3063 | } |
@@ -3054,12 +3072,12 @@ static int rbd_dev_v2_probe(struct rbd_device *rbd_dev) | |||
3054 | * Image id was filled in by the caller. Record the header | 3072 | * Image id was filled in by the caller. Record the header |
3055 | * object name for this rbd image. | 3073 | * object name for this rbd image. |
3056 | */ | 3074 | */ |
3057 | size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->image_id_len; | 3075 | size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->spec->image_id_len; |
3058 | rbd_dev->header_name = kmalloc(size, GFP_KERNEL); | 3076 | rbd_dev->header_name = kmalloc(size, GFP_KERNEL); |
3059 | if (!rbd_dev->header_name) | 3077 | if (!rbd_dev->header_name) |
3060 | return -ENOMEM; | 3078 | return -ENOMEM; |
3061 | sprintf(rbd_dev->header_name, "%s%s", | 3079 | sprintf(rbd_dev->header_name, "%s%s", |
3062 | RBD_HEADER_PREFIX, rbd_dev->image_id); | 3080 | RBD_HEADER_PREFIX, rbd_dev->spec->image_id); |
3063 | 3081 | ||
3064 | /* Get the size and object order for the image */ | 3082 | /* Get the size and object order for the image */ |
3065 | 3083 | ||
@@ -3147,6 +3165,9 @@ static ssize_t rbd_add(struct bus_type *bus, | |||
3147 | rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); | 3165 | rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); |
3148 | if (!rbd_dev) | 3166 | if (!rbd_dev) |
3149 | return -ENOMEM; | 3167 | return -ENOMEM; |
3168 | rbd_dev->spec = kzalloc(sizeof (*rbd_dev->spec), GFP_KERNEL); | ||
3169 | if (!rbd_dev->spec) | ||
3170 | goto err_out_mem; | ||
3150 | 3171 | ||
3151 | /* static rbd_device initialization */ | 3172 | /* static rbd_device initialization */ |
3152 | spin_lock_init(&rbd_dev->lock); | 3173 | spin_lock_init(&rbd_dev->lock); |
@@ -3167,10 +3188,10 @@ static ssize_t rbd_add(struct bus_type *bus, | |||
3167 | 3188 | ||
3168 | /* pick the pool */ | 3189 | /* pick the pool */ |
3169 | osdc = &rbd_dev->rbd_client->client->osdc; | 3190 | osdc = &rbd_dev->rbd_client->client->osdc; |
3170 | rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->pool_name); | 3191 | rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->spec->pool_name); |
3171 | if (rc < 0) | 3192 | if (rc < 0) |
3172 | goto err_out_client; | 3193 | goto err_out_client; |
3173 | rbd_dev->pool_id = (u64) rc; | 3194 | rbd_dev->spec->pool_id = (u64) rc; |
3174 | 3195 | ||
3175 | rc = rbd_dev_probe(rbd_dev); | 3196 | rc = rbd_dev_probe(rbd_dev); |
3176 | if (rc < 0) | 3197 | if (rc < 0) |
@@ -3257,15 +3278,16 @@ err_out_probe: | |||
3257 | err_out_client: | 3278 | err_out_client: |
3258 | kfree(rbd_dev->header_name); | 3279 | kfree(rbd_dev->header_name); |
3259 | rbd_put_client(rbd_dev); | 3280 | rbd_put_client(rbd_dev); |
3260 | kfree(rbd_dev->image_id); | 3281 | kfree(rbd_dev->spec->image_id); |
3261 | err_out_args: | 3282 | err_out_args: |
3262 | if (ceph_opts) | 3283 | if (ceph_opts) |
3263 | ceph_destroy_options(ceph_opts); | 3284 | ceph_destroy_options(ceph_opts); |
3264 | kfree(rbd_dev->snap_name); | 3285 | kfree(rbd_dev->spec->snap_name); |
3265 | kfree(rbd_dev->image_name); | 3286 | kfree(rbd_dev->spec->image_name); |
3266 | kfree(rbd_dev->pool_name); | 3287 | kfree(rbd_dev->spec->pool_name); |
3267 | kfree(rbd_opts); | 3288 | kfree(rbd_opts); |
3268 | err_out_mem: | 3289 | err_out_mem: |
3290 | kfree(rbd_dev->spec); | ||
3269 | kfree(rbd_dev); | 3291 | kfree(rbd_dev); |
3270 | 3292 | ||
3271 | dout("Error adding device %s\n", buf); | 3293 | dout("Error adding device %s\n", buf); |
@@ -3314,11 +3336,11 @@ static void rbd_dev_release(struct device *dev) | |||
3314 | rbd_header_free(&rbd_dev->header); | 3336 | rbd_header_free(&rbd_dev->header); |
3315 | 3337 | ||
3316 | /* done with the id, and with the rbd_dev */ | 3338 | /* done with the id, and with the rbd_dev */ |
3317 | kfree(rbd_dev->snap_name); | 3339 | kfree(rbd_dev->spec->snap_name); |
3318 | kfree(rbd_dev->image_id); | 3340 | kfree(rbd_dev->spec->image_id); |
3319 | kfree(rbd_dev->header_name); | 3341 | kfree(rbd_dev->header_name); |
3320 | kfree(rbd_dev->pool_name); | 3342 | kfree(rbd_dev->spec->pool_name); |
3321 | kfree(rbd_dev->image_name); | 3343 | kfree(rbd_dev->spec->image_name); |
3322 | rbd_dev_id_put(rbd_dev); | 3344 | rbd_dev_id_put(rbd_dev); |
3323 | kfree(rbd_dev); | 3345 | kfree(rbd_dev); |
3324 | 3346 | ||