@@ -128,11 +128,8 @@ static int atomic_dec_return_safe(atomic_t *v)
128128/*
129129 * An RBD device name will be "rbd#", where the "rbd" comes from
130130 * RBD_DRV_NAME above, and # is a unique integer identifier.
131- * MAX_INT_FORMAT_WIDTH is used in ensuring DEV_NAME_LEN is big
132- * enough to hold all possible device names.
133131 */
134132#define DEV_NAME_LEN 32
135- #define MAX_INT_FORMAT_WIDTH ((5 * sizeof (int)) / 2 + 1)
136133
137134/*
138135 * block device image metadata (in-memory version)
@@ -353,10 +350,12 @@ struct rbd_device {
353350 struct ceph_object_id header_oid ;
354351 struct ceph_object_locator header_oloc ;
355352
356- struct ceph_file_layout layout ;
353+ struct ceph_file_layout layout ; /* used for all rbd requests */
357354
358355 struct ceph_osd_linger_request * watch_handle ;
359356
357+ struct workqueue_struct * task_wq ;
358+
360359 struct rbd_spec * parent_spec ;
361360 u64 parent_overlap ;
362361 atomic_t parent_ref ;
@@ -3944,18 +3943,28 @@ static void rbd_spec_free(struct kref *kref)
39443943 kfree (spec );
39453944}
39463945
3947- static void rbd_dev_release (struct device * dev )
3946+ static void rbd_dev_free (struct rbd_device * rbd_dev )
39483947{
3949- struct rbd_device * rbd_dev = dev_to_rbd_dev (dev );
3950- bool need_put = !!rbd_dev -> opts ;
3951-
39523948 ceph_oid_destroy (& rbd_dev -> header_oid );
39533949 ceph_oloc_destroy (& rbd_dev -> header_oloc );
39543950
39553951 rbd_put_client (rbd_dev -> rbd_client );
39563952 rbd_spec_put (rbd_dev -> spec );
39573953 kfree (rbd_dev -> opts );
39583954 kfree (rbd_dev );
3955+ }
3956+
3957+ static void rbd_dev_release (struct device * dev )
3958+ {
3959+ struct rbd_device * rbd_dev = dev_to_rbd_dev (dev );
3960+ bool need_put = !!rbd_dev -> opts ;
3961+
3962+ if (need_put ) {
3963+ destroy_workqueue (rbd_dev -> task_wq );
3964+ ida_simple_remove (& rbd_dev_id_ida , rbd_dev -> dev_id );
3965+ }
3966+
3967+ rbd_dev_free (rbd_dev );
39593968
39603969 /*
39613970 * This is racy, but way better than putting module outside of
@@ -3966,19 +3975,16 @@ static void rbd_dev_release(struct device *dev)
39663975 module_put (THIS_MODULE );
39673976}
39683977
3969- static struct rbd_device * rbd_dev_create (struct rbd_client * rbdc ,
3970- struct rbd_spec * spec ,
3971- struct rbd_options * opts )
3978+ static struct rbd_device * __rbd_dev_create (struct rbd_client * rbdc ,
3979+ struct rbd_spec * spec )
39723980{
39733981 struct rbd_device * rbd_dev ;
39743982
3975- rbd_dev = kzalloc (sizeof (* rbd_dev ), GFP_KERNEL );
3983+ rbd_dev = kzalloc (sizeof (* rbd_dev ), GFP_KERNEL );
39763984 if (!rbd_dev )
39773985 return NULL ;
39783986
39793987 spin_lock_init (& rbd_dev -> lock );
3980- rbd_dev -> flags = 0 ;
3981- atomic_set (& rbd_dev -> parent_ref , 0 );
39823988 INIT_LIST_HEAD (& rbd_dev -> node );
39833989 init_rwsem (& rbd_dev -> header_rwsem );
39843990
@@ -3992,25 +3998,55 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc,
39923998
39933999 rbd_dev -> rbd_client = rbdc ;
39944000 rbd_dev -> spec = spec ;
3995- rbd_dev -> opts = opts ;
3996-
3997- /* Initialize the layout used for all rbd requests */
39984001
39994002 rbd_dev -> layout .stripe_unit = 1 << RBD_MAX_OBJ_ORDER ;
40004003 rbd_dev -> layout .stripe_count = 1 ;
40014004 rbd_dev -> layout .object_size = 1 << RBD_MAX_OBJ_ORDER ;
40024005 rbd_dev -> layout .pool_id = spec -> pool_id ;
40034006 RCU_INIT_POINTER (rbd_dev -> layout .pool_ns , NULL );
40044007
4005- /*
4006- * If this is a mapping rbd_dev (as opposed to a parent one),
4007- * pin our module. We have a ref from do_rbd_add(), so use
4008- * __module_get().
4009- */
4010- if (rbd_dev -> opts )
4011- __module_get (THIS_MODULE );
4008+ return rbd_dev ;
4009+ }
4010+
4011+ /*
4012+ * Create a mapping rbd_dev.
4013+ */
4014+ static struct rbd_device * rbd_dev_create (struct rbd_client * rbdc ,
4015+ struct rbd_spec * spec ,
4016+ struct rbd_options * opts )
4017+ {
4018+ struct rbd_device * rbd_dev ;
4019+
4020+ rbd_dev = __rbd_dev_create (rbdc , spec );
4021+ if (!rbd_dev )
4022+ return NULL ;
4023+
4024+ rbd_dev -> opts = opts ;
4025+
4026+ /* get an id and fill in device name */
4027+ rbd_dev -> dev_id = ida_simple_get (& rbd_dev_id_ida , 0 ,
4028+ minor_to_rbd_dev_id (1 << MINORBITS ),
4029+ GFP_KERNEL );
4030+ if (rbd_dev -> dev_id < 0 )
4031+ goto fail_rbd_dev ;
4032+
4033+ sprintf (rbd_dev -> name , RBD_DRV_NAME "%d" , rbd_dev -> dev_id );
4034+ rbd_dev -> task_wq = alloc_ordered_workqueue ("%s-tasks" , WQ_MEM_RECLAIM ,
4035+ rbd_dev -> name );
4036+ if (!rbd_dev -> task_wq )
4037+ goto fail_dev_id ;
40124038
4039+ /* we have a ref from do_rbd_add() */
4040+ __module_get (THIS_MODULE );
4041+
4042+ dout ("%s rbd_dev %p dev_id %d\n" , __func__ , rbd_dev , rbd_dev -> dev_id );
40134043 return rbd_dev ;
4044+
4045+ fail_dev_id :
4046+ ida_simple_remove (& rbd_dev_id_ida , rbd_dev -> dev_id );
4047+ fail_rbd_dev :
4048+ rbd_dev_free (rbd_dev );
4049+ return NULL ;
40144050}
40154051
40164052static void rbd_dev_destroy (struct rbd_device * rbd_dev )
@@ -4645,46 +4681,6 @@ static int rbd_dev_header_info(struct rbd_device *rbd_dev)
46454681 return rbd_dev_v2_header_info (rbd_dev );
46464682}
46474683
4648- /*
4649- * Get a unique rbd identifier for the given new rbd_dev, and add
4650- * the rbd_dev to the global list.
4651- */
4652- static int rbd_dev_id_get (struct rbd_device * rbd_dev )
4653- {
4654- int new_dev_id ;
4655-
4656- new_dev_id = ida_simple_get (& rbd_dev_id_ida ,
4657- 0 , minor_to_rbd_dev_id (1 << MINORBITS ),
4658- GFP_KERNEL );
4659- if (new_dev_id < 0 )
4660- return new_dev_id ;
4661-
4662- rbd_dev -> dev_id = new_dev_id ;
4663-
4664- spin_lock (& rbd_dev_list_lock );
4665- list_add_tail (& rbd_dev -> node , & rbd_dev_list );
4666- spin_unlock (& rbd_dev_list_lock );
4667-
4668- dout ("rbd_dev %p given dev id %d\n" , rbd_dev , rbd_dev -> dev_id );
4669-
4670- return 0 ;
4671- }
4672-
4673- /*
4674- * Remove an rbd_dev from the global list, and record that its
4675- * identifier is no longer in use.
4676- */
4677- static void rbd_dev_id_put (struct rbd_device * rbd_dev )
4678- {
4679- spin_lock (& rbd_dev_list_lock );
4680- list_del_init (& rbd_dev -> node );
4681- spin_unlock (& rbd_dev_list_lock );
4682-
4683- ida_simple_remove (& rbd_dev_id_ida , rbd_dev -> dev_id );
4684-
4685- dout ("rbd_dev %p released dev id %d\n" , rbd_dev , rbd_dev -> dev_id );
4686- }
4687-
46884684/*
46894685 * Skips over white space at *buf, and updates *buf to point to the
46904686 * first found non-space character (if any). Returns the length of
@@ -5077,8 +5073,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth)
50775073 goto out_err ;
50785074 }
50795075
5080- parent = rbd_dev_create (rbd_dev -> rbd_client , rbd_dev -> parent_spec ,
5081- NULL );
5076+ parent = __rbd_dev_create (rbd_dev -> rbd_client , rbd_dev -> parent_spec );
50825077 if (!parent ) {
50835078 ret = - ENOMEM ;
50845079 goto out_err ;
@@ -5113,22 +5108,12 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
51135108{
51145109 int ret ;
51155110
5116- /* Get an id and fill in device name. */
5117-
5118- ret = rbd_dev_id_get (rbd_dev );
5119- if (ret )
5120- goto err_out_unlock ;
5121-
5122- BUILD_BUG_ON (DEV_NAME_LEN
5123- < sizeof (RBD_DRV_NAME ) + MAX_INT_FORMAT_WIDTH );
5124- sprintf (rbd_dev -> name , "%s%d" , RBD_DRV_NAME , rbd_dev -> dev_id );
5125-
51265111 /* Record our major and minor device numbers. */
51275112
51285113 if (!single_major ) {
51295114 ret = register_blkdev (0 , rbd_dev -> name );
51305115 if (ret < 0 )
5131- goto err_out_id ;
5116+ goto err_out_unlock ;
51325117
51335118 rbd_dev -> major = ret ;
51345119 rbd_dev -> minor = 0 ;
@@ -5160,6 +5145,10 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
51605145 set_bit (RBD_DEV_FLAG_EXISTS , & rbd_dev -> flags );
51615146 up_write (& rbd_dev -> header_rwsem );
51625147
5148+ spin_lock (& rbd_dev_list_lock );
5149+ list_add_tail (& rbd_dev -> node , & rbd_dev_list );
5150+ spin_unlock (& rbd_dev_list_lock );
5151+
51635152 add_disk (rbd_dev -> disk );
51645153 pr_info ("%s: added with size 0x%llx\n" , rbd_dev -> disk -> disk_name ,
51655154 (unsigned long long ) rbd_dev -> mapping .size );
@@ -5173,8 +5162,6 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
51735162err_out_blkdev :
51745163 if (!single_major )
51755164 unregister_blkdev (rbd_dev -> major , rbd_dev -> name );
5176- err_out_id :
5177- rbd_dev_id_put (rbd_dev );
51785165err_out_unlock :
51795166 up_write (& rbd_dev -> header_rwsem );
51805167 return ret ;
@@ -5406,12 +5393,16 @@ static ssize_t rbd_add_single_major(struct bus_type *bus,
54065393static void rbd_dev_device_release (struct rbd_device * rbd_dev )
54075394{
54085395 rbd_free_disk (rbd_dev );
5396+
5397+ spin_lock (& rbd_dev_list_lock );
5398+ list_del_init (& rbd_dev -> node );
5399+ spin_unlock (& rbd_dev_list_lock );
5400+
54095401 clear_bit (RBD_DEV_FLAG_EXISTS , & rbd_dev -> flags );
54105402 device_del (& rbd_dev -> dev );
54115403 rbd_dev_mapping_clear (rbd_dev );
54125404 if (!single_major )
54135405 unregister_blkdev (rbd_dev -> major , rbd_dev -> name );
5414- rbd_dev_id_put (rbd_dev );
54155406}
54165407
54175408static void rbd_dev_remove_parent (struct rbd_device * rbd_dev )
0 commit comments