@@ -56,12 +56,14 @@ struct virtio_fs_vq {
56
56
bool connected ;
57
57
long in_flight ;
58
58
struct completion in_flight_zero ; /* No inflight requests */
59
+ struct kobject * kobj ;
59
60
char name [VQ_NAME_LEN ];
60
61
} ____cacheline_aligned_in_smp ;
61
62
62
63
/* A virtio-fs device instance */
63
64
struct virtio_fs {
64
65
struct kobject kobj ;
66
+ struct kobject * mqs_kobj ;
65
67
struct list_head list ; /* on virtio_fs_instances */
66
68
char * tag ;
67
69
struct virtio_fs_vq * vqs ;
@@ -200,6 +202,74 @@ static const struct kobj_type virtio_fs_ktype = {
200
202
.default_groups = virtio_fs_groups ,
201
203
};
202
204
205
+ static struct virtio_fs_vq * virtio_fs_kobj_to_vq (struct virtio_fs * fs ,
206
+ struct kobject * kobj )
207
+ {
208
+ int i ;
209
+
210
+ for (i = 0 ; i < fs -> nvqs ; i ++ ) {
211
+ if (kobj == fs -> vqs [i ].kobj )
212
+ return & fs -> vqs [i ];
213
+ }
214
+ return NULL ;
215
+ }
216
+
217
+ static ssize_t name_show (struct kobject * kobj ,
218
+ struct kobj_attribute * attr , char * buf )
219
+ {
220
+ struct virtio_fs * fs = container_of (kobj -> parent -> parent , struct virtio_fs , kobj );
221
+ struct virtio_fs_vq * fsvq = virtio_fs_kobj_to_vq (fs , kobj );
222
+
223
+ if (!fsvq )
224
+ return - EINVAL ;
225
+ return sysfs_emit (buf , "%s\n" , fsvq -> name );
226
+ }
227
+
228
+ static struct kobj_attribute virtio_fs_vq_name_attr = __ATTR_RO (name );
229
+
230
+ static ssize_t cpu_list_show (struct kobject * kobj ,
231
+ struct kobj_attribute * attr , char * buf )
232
+ {
233
+ struct virtio_fs * fs = container_of (kobj -> parent -> parent , struct virtio_fs , kobj );
234
+ struct virtio_fs_vq * fsvq = virtio_fs_kobj_to_vq (fs , kobj );
235
+ unsigned int cpu , qid ;
236
+ const size_t size = PAGE_SIZE - 1 ;
237
+ bool first = true;
238
+ int ret = 0 , pos = 0 ;
239
+
240
+ if (!fsvq )
241
+ return - EINVAL ;
242
+
243
+ qid = fsvq -> vq -> index ;
244
+ for (cpu = 0 ; cpu < nr_cpu_ids ; cpu ++ ) {
245
+ if (qid < VQ_REQUEST || (fs -> mq_map [cpu ] == qid - VQ_REQUEST )) {
246
+ if (first )
247
+ ret = snprintf (buf + pos , size - pos , "%u" , cpu );
248
+ else
249
+ ret = snprintf (buf + pos , size - pos , ", %u" , cpu );
250
+
251
+ if (ret >= size - pos )
252
+ break ;
253
+ first = false;
254
+ pos += ret ;
255
+ }
256
+ }
257
+ ret = snprintf (buf + pos , size + 1 - pos , "\n" );
258
+ return pos + ret ;
259
+ }
260
+
261
+ static struct kobj_attribute virtio_fs_vq_cpu_list_attr = __ATTR_RO (cpu_list );
262
+
263
+ static struct attribute * virtio_fs_vq_attrs [] = {
264
+ & virtio_fs_vq_name_attr .attr ,
265
+ & virtio_fs_vq_cpu_list_attr .attr ,
266
+ NULL
267
+ };
268
+
269
+ static struct attribute_group virtio_fs_vq_attr_group = {
270
+ .attrs = virtio_fs_vq_attrs ,
271
+ };
272
+
203
273
/* Make sure virtiofs_mutex is held */
204
274
static void virtio_fs_put_locked (struct virtio_fs * fs )
205
275
{
@@ -280,6 +350,50 @@ static void virtio_fs_start_all_queues(struct virtio_fs *fs)
280
350
}
281
351
}
282
352
353
+ static void virtio_fs_delete_queues_sysfs (struct virtio_fs * fs )
354
+ {
355
+ struct virtio_fs_vq * fsvq ;
356
+ int i ;
357
+
358
+ for (i = 0 ; i < fs -> nvqs ; i ++ ) {
359
+ fsvq = & fs -> vqs [i ];
360
+ kobject_put (fsvq -> kobj );
361
+ }
362
+ }
363
+
364
+ static int virtio_fs_add_queues_sysfs (struct virtio_fs * fs )
365
+ {
366
+ struct virtio_fs_vq * fsvq ;
367
+ char buff [12 ];
368
+ int i , j , ret ;
369
+
370
+ for (i = 0 ; i < fs -> nvqs ; i ++ ) {
371
+ fsvq = & fs -> vqs [i ];
372
+
373
+ sprintf (buff , "%d" , i );
374
+ fsvq -> kobj = kobject_create_and_add (buff , fs -> mqs_kobj );
375
+ if (!fs -> mqs_kobj ) {
376
+ ret = - ENOMEM ;
377
+ goto out_del ;
378
+ }
379
+
380
+ ret = sysfs_create_group (fsvq -> kobj , & virtio_fs_vq_attr_group );
381
+ if (ret ) {
382
+ kobject_put (fsvq -> kobj );
383
+ goto out_del ;
384
+ }
385
+ }
386
+
387
+ return 0 ;
388
+
389
+ out_del :
390
+ for (j = 0 ; j < i ; j ++ ) {
391
+ fsvq = & fs -> vqs [j ];
392
+ kobject_put (fsvq -> kobj );
393
+ }
394
+ return ret ;
395
+ }
396
+
283
397
/* Add a new instance to the list or return -EEXIST if tag name exists*/
284
398
static int virtio_fs_add_instance (struct virtio_device * vdev ,
285
399
struct virtio_fs * fs )
@@ -303,17 +417,22 @@ static int virtio_fs_add_instance(struct virtio_device *vdev,
303
417
*/
304
418
fs -> kobj .kset = virtio_fs_kset ;
305
419
ret = kobject_add (& fs -> kobj , NULL , "%d" , vdev -> index );
306
- if (ret < 0 ) {
307
- mutex_unlock (& virtio_fs_mutex );
308
- return ret ;
420
+ if (ret < 0 )
421
+ goto out_unlock ;
422
+
423
+ fs -> mqs_kobj = kobject_create_and_add ("mqs" , & fs -> kobj );
424
+ if (!fs -> mqs_kobj ) {
425
+ ret = - ENOMEM ;
426
+ goto out_del ;
309
427
}
310
428
311
429
ret = sysfs_create_link (& fs -> kobj , & vdev -> dev .kobj , "device" );
312
- if (ret < 0 ) {
313
- kobject_del (& fs -> kobj );
314
- mutex_unlock (& virtio_fs_mutex );
315
- return ret ;
316
- }
430
+ if (ret < 0 )
431
+ goto out_put ;
432
+
433
+ ret = virtio_fs_add_queues_sysfs (fs );
434
+ if (ret )
435
+ goto out_remove ;
317
436
318
437
list_add_tail (& fs -> list , & virtio_fs_instances );
319
438
@@ -322,6 +441,16 @@ static int virtio_fs_add_instance(struct virtio_device *vdev,
322
441
kobject_uevent (& fs -> kobj , KOBJ_ADD );
323
442
324
443
return 0 ;
444
+
445
+ out_remove :
446
+ sysfs_remove_link (& fs -> kobj , "device" );
447
+ out_put :
448
+ kobject_put (fs -> mqs_kobj );
449
+ out_del :
450
+ kobject_del (& fs -> kobj );
451
+ out_unlock :
452
+ mutex_unlock (& virtio_fs_mutex );
453
+ return ret ;
325
454
}
326
455
327
456
/* Return the virtio_fs with a given tag, or NULL */
@@ -1050,7 +1179,9 @@ static void virtio_fs_remove(struct virtio_device *vdev)
1050
1179
mutex_lock (& virtio_fs_mutex );
1051
1180
/* This device is going away. No one should get new reference */
1052
1181
list_del_init (& fs -> list );
1182
+ virtio_fs_delete_queues_sysfs (fs );
1053
1183
sysfs_remove_link (& fs -> kobj , "device" );
1184
+ kobject_put (fs -> mqs_kobj );
1054
1185
kobject_del (& fs -> kobj );
1055
1186
virtio_fs_stop_all_queues (fs );
1056
1187
virtio_fs_drain_all_queues_locked (fs );
0 commit comments