@@ -39,40 +39,34 @@ struct configfs_buffer {
39
39
bool write_in_progress ;
40
40
char * bin_buffer ;
41
41
int bin_buffer_size ;
42
+ int cb_max_size ;
43
+ struct config_item * item ;
44
+ struct module * owner ;
45
+ union {
46
+ struct configfs_attribute * attr ;
47
+ struct configfs_bin_attribute * bin_attr ;
48
+ };
42
49
};
43
50
44
51
45
- /**
46
- * fill_read_buffer - allocate and fill buffer from item.
47
- * @dentry: dentry pointer.
48
- * @buffer: data buffer for file.
49
- *
50
- * Allocate @buffer->page, if it hasn't been already, then call the
51
- * config_item's show() method to fill the buffer with this attribute's
52
- * data.
53
- * This is called only once, on the file's first read.
54
- */
55
- static int fill_read_buffer (struct dentry * dentry , struct configfs_buffer * buffer )
52
+ static int fill_read_buffer (struct configfs_buffer * buffer )
56
53
{
57
- struct configfs_attribute * attr = to_attr (dentry );
58
- struct config_item * item = to_item (dentry -> d_parent );
59
- int ret = 0 ;
60
54
ssize_t count ;
61
55
62
56
if (!buffer -> page )
63
57
buffer -> page = (char * ) get_zeroed_page (GFP_KERNEL );
64
58
if (!buffer -> page )
65
59
return - ENOMEM ;
66
60
67
- count = attr -> show (item , buffer -> page );
61
+ count = buffer -> attr -> show (buffer -> item , buffer -> page );
62
+ if (count < 0 )
63
+ return count ;
64
+ if (WARN_ON_ONCE (count > (ssize_t )SIMPLE_ATTR_SIZE ))
65
+ return - EIO ;
68
66
69
- BUG_ON (count > (ssize_t )SIMPLE_ATTR_SIZE );
70
- if (count >= 0 ) {
71
- buffer -> needs_read_fill = 0 ;
72
- buffer -> count = count ;
73
- } else
74
- ret = count ;
75
- return ret ;
67
+ buffer -> needs_read_fill = 0 ;
68
+ buffer -> count = count ;
69
+ return 0 ;
76
70
}
77
71
78
72
/**
@@ -97,12 +91,13 @@ static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buf
97
91
static ssize_t
98
92
configfs_read_file (struct file * file , char __user * buf , size_t count , loff_t * ppos )
99
93
{
100
- struct configfs_buffer * buffer = file -> private_data ;
94
+ struct configfs_buffer * buffer = file -> private_data ;
101
95
ssize_t retval = 0 ;
102
96
103
97
mutex_lock (& buffer -> mutex );
104
98
if (buffer -> needs_read_fill ) {
105
- if ((retval = fill_read_buffer (file -> f_path .dentry ,buffer )))
99
+ retval = fill_read_buffer (buffer );
100
+ if (retval )
106
101
goto out ;
107
102
}
108
103
pr_debug ("%s: count = %zd, ppos = %lld, buf = %s\n" ,
@@ -139,9 +134,6 @@ configfs_read_bin_file(struct file *file, char __user *buf,
139
134
size_t count , loff_t * ppos )
140
135
{
141
136
struct configfs_buffer * buffer = file -> private_data ;
142
- struct dentry * dentry = file -> f_path .dentry ;
143
- struct config_item * item = to_item (dentry -> d_parent );
144
- struct configfs_bin_attribute * bin_attr = to_bin_attr (dentry );
145
137
ssize_t retval = 0 ;
146
138
ssize_t len = min_t (size_t , count , PAGE_SIZE );
147
139
@@ -156,14 +148,14 @@ configfs_read_bin_file(struct file *file, char __user *buf,
156
148
157
149
if (buffer -> needs_read_fill ) {
158
150
/* perform first read with buf == NULL to get extent */
159
- len = bin_attr -> read (item , NULL , 0 );
151
+ len = buffer -> bin_attr -> read (buffer -> item , NULL , 0 );
160
152
if (len <= 0 ) {
161
153
retval = len ;
162
154
goto out ;
163
155
}
164
156
165
157
/* do not exceed the maximum value */
166
- if (bin_attr -> cb_max_size && len > bin_attr -> cb_max_size ) {
158
+ if (buffer -> cb_max_size && len > buffer -> cb_max_size ) {
167
159
retval = - EFBIG ;
168
160
goto out ;
169
161
}
@@ -176,7 +168,8 @@ configfs_read_bin_file(struct file *file, char __user *buf,
176
168
buffer -> bin_buffer_size = len ;
177
169
178
170
/* perform second read to fill buffer */
179
- len = bin_attr -> read (item , buffer -> bin_buffer , len );
171
+ len = buffer -> bin_attr -> read (buffer -> item ,
172
+ buffer -> bin_buffer , len );
180
173
if (len < 0 ) {
181
174
retval = len ;
182
175
vfree (buffer -> bin_buffer );
@@ -226,25 +219,10 @@ fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size
226
219
return error ? - EFAULT : count ;
227
220
}
228
221
229
-
230
- /**
231
- * flush_write_buffer - push buffer to config_item.
232
- * @dentry: dentry to the attribute
233
- * @buffer: data buffer for file.
234
- * @count: number of bytes
235
- *
236
- * Get the correct pointers for the config_item and the attribute we're
237
- * dealing with, then call the store() method for the attribute,
238
- * passing the buffer that we acquired in fill_write_buffer().
239
- */
240
-
241
222
static int
242
- flush_write_buffer (struct dentry * dentry , struct configfs_buffer * buffer , size_t count )
223
+ flush_write_buffer (struct configfs_buffer * buffer , size_t count )
243
224
{
244
- struct configfs_attribute * attr = to_attr (dentry );
245
- struct config_item * item = to_item (dentry -> d_parent );
246
-
247
- return attr -> store (item , buffer -> page , count );
225
+ return buffer -> attr -> store (buffer -> item , buffer -> page , count );
248
226
}
249
227
250
228
@@ -268,13 +246,13 @@ flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size
268
246
static ssize_t
269
247
configfs_write_file (struct file * file , const char __user * buf , size_t count , loff_t * ppos )
270
248
{
271
- struct configfs_buffer * buffer = file -> private_data ;
249
+ struct configfs_buffer * buffer = file -> private_data ;
272
250
ssize_t len ;
273
251
274
252
mutex_lock (& buffer -> mutex );
275
253
len = fill_write_buffer (buffer , buf , count );
276
254
if (len > 0 )
277
- len = flush_write_buffer (file -> f_path . dentry , buffer , len );
255
+ len = flush_write_buffer (buffer , len );
278
256
if (len > 0 )
279
257
* ppos += len ;
280
258
mutex_unlock (& buffer -> mutex );
@@ -299,8 +277,6 @@ configfs_write_bin_file(struct file *file, const char __user *buf,
299
277
size_t count , loff_t * ppos )
300
278
{
301
279
struct configfs_buffer * buffer = file -> private_data ;
302
- struct dentry * dentry = file -> f_path .dentry ;
303
- struct configfs_bin_attribute * bin_attr = to_bin_attr (dentry );
304
280
void * tbuf = NULL ;
305
281
ssize_t len ;
306
282
@@ -316,8 +292,8 @@ configfs_write_bin_file(struct file *file, const char __user *buf,
316
292
/* buffer grows? */
317
293
if (* ppos + count > buffer -> bin_buffer_size ) {
318
294
319
- if (bin_attr -> cb_max_size &&
320
- * ppos + count > bin_attr -> cb_max_size ) {
295
+ if (buffer -> cb_max_size &&
296
+ * ppos + count > buffer -> cb_max_size ) {
321
297
len = - EFBIG ;
322
298
goto out ;
323
299
}
@@ -349,45 +325,57 @@ configfs_write_bin_file(struct file *file, const char __user *buf,
349
325
return len ;
350
326
}
351
327
352
- static int check_perm (struct inode * inode , struct file * file , int type )
328
+ static int __configfs_open_file (struct inode * inode , struct file * file , int type )
353
329
{
354
- struct config_item * item = configfs_get_config_item (file -> f_path .dentry -> d_parent );
355
- struct configfs_attribute * attr = to_attr (file -> f_path .dentry );
356
- struct configfs_bin_attribute * bin_attr = NULL ;
357
- struct configfs_buffer * buffer ;
358
- struct configfs_item_operations * ops = NULL ;
359
- int error = 0 ;
330
+ struct dentry * dentry = file -> f_path .dentry ;
331
+ struct configfs_attribute * attr ;
332
+ struct configfs_buffer * buffer ;
333
+ int error ;
360
334
361
- if (!item || !attr )
362
- goto Einval ;
335
+ error = - ENOMEM ;
336
+ buffer = kzalloc (sizeof (struct configfs_buffer ), GFP_KERNEL );
337
+ if (!buffer )
338
+ goto out ;
363
339
364
- if (type & CONFIGFS_ITEM_BIN_ATTR )
365
- bin_attr = to_bin_attr (file -> f_path .dentry );
340
+ error = - EINVAL ;
341
+ buffer -> item = configfs_get_config_item (dentry -> d_parent );
342
+ if (!buffer -> item )
343
+ goto out_free_buffer ;
344
+
345
+ attr = to_attr (dentry );
346
+ if (!attr )
347
+ goto out_put_item ;
348
+
349
+ if (type & CONFIGFS_ITEM_BIN_ATTR ) {
350
+ buffer -> bin_attr = to_bin_attr (dentry );
351
+ buffer -> cb_max_size = buffer -> bin_attr -> cb_max_size ;
352
+ } else {
353
+ buffer -> attr = attr ;
354
+ }
366
355
356
+ buffer -> owner = attr -> ca_owner ;
367
357
/* Grab the module reference for this attribute if we have one */
368
- if (!try_module_get (attr -> ca_owner )) {
369
- error = - ENODEV ;
370
- goto Done ;
371
- }
358
+ error = - ENODEV ;
359
+ if (!try_module_get (buffer -> owner ))
360
+ goto out_put_item ;
372
361
373
- if (item -> ci_type )
374
- ops = item -> ci_type -> ct_item_ops ;
375
- else
376
- goto Eaccess ;
362
+ error = - EACCES ;
363
+ if (!buffer -> item -> ci_type )
364
+ goto out_put_module ;
365
+
366
+ buffer -> ops = buffer -> item -> ci_type -> ct_item_ops ;
377
367
378
368
/* File needs write support.
379
369
* The inode's perms must say it's ok,
380
370
* and we must have a store method.
381
371
*/
382
372
if (file -> f_mode & FMODE_WRITE ) {
383
373
if (!(inode -> i_mode & S_IWUGO ))
384
- goto Eaccess ;
385
-
374
+ goto out_put_module ;
386
375
if ((type & CONFIGFS_ITEM_ATTR ) && !attr -> store )
387
- goto Eaccess ;
388
-
389
- if ((type & CONFIGFS_ITEM_BIN_ATTR ) && !bin_attr -> write )
390
- goto Eaccess ;
376
+ goto out_put_module ;
377
+ if ((type & CONFIGFS_ITEM_BIN_ATTR ) && !buffer -> bin_attr -> write )
378
+ goto out_put_module ;
391
379
}
392
380
393
381
/* File needs read support.
@@ -396,90 +384,65 @@ static int check_perm(struct inode * inode, struct file * file, int type)
396
384
*/
397
385
if (file -> f_mode & FMODE_READ ) {
398
386
if (!(inode -> i_mode & S_IRUGO ))
399
- goto Eaccess ;
400
-
387
+ goto out_put_module ;
401
388
if ((type & CONFIGFS_ITEM_ATTR ) && !attr -> show )
402
- goto Eaccess ;
403
-
404
- if ((type & CONFIGFS_ITEM_BIN_ATTR ) && !bin_attr -> read )
405
- goto Eaccess ;
389
+ goto out_put_module ;
390
+ if ((type & CONFIGFS_ITEM_BIN_ATTR ) && !buffer -> bin_attr -> read )
391
+ goto out_put_module ;
406
392
}
407
393
408
- /* No error? Great, allocate a buffer for the file, and store it
409
- * it in file->private_data for easy access.
410
- */
411
- buffer = kzalloc (sizeof (struct configfs_buffer ),GFP_KERNEL );
412
- if (!buffer ) {
413
- error = - ENOMEM ;
414
- goto Enomem ;
415
- }
416
394
mutex_init (& buffer -> mutex );
417
395
buffer -> needs_read_fill = 1 ;
418
396
buffer -> read_in_progress = false;
419
397
buffer -> write_in_progress = false;
420
- buffer -> ops = ops ;
421
398
file -> private_data = buffer ;
422
- goto Done ;
399
+ return 0 ;
423
400
424
- Einval :
425
- error = - EINVAL ;
426
- goto Done ;
427
- Eaccess :
428
- error = - EACCES ;
429
- Enomem :
430
- module_put (attr -> ca_owner );
431
- Done :
432
- if (error && item )
433
- config_item_put (item );
401
+ out_put_module :
402
+ module_put (buffer -> owner );
403
+ out_put_item :
404
+ config_item_put (buffer -> item );
405
+ out_free_buffer :
406
+ kfree (buffer );
407
+ out :
434
408
return error ;
435
409
}
436
410
437
411
static int configfs_release (struct inode * inode , struct file * filp )
438
412
{
439
- struct config_item * item = to_item (filp -> f_path .dentry -> d_parent );
440
- struct configfs_attribute * attr = to_attr (filp -> f_path .dentry );
441
- struct module * owner = attr -> ca_owner ;
442
- struct configfs_buffer * buffer = filp -> private_data ;
443
-
444
- if (item )
445
- config_item_put (item );
446
- /* After this point, attr should not be accessed. */
447
- module_put (owner );
448
-
449
- if (buffer ) {
450
- if (buffer -> page )
451
- free_page ((unsigned long )buffer -> page );
452
- mutex_destroy (& buffer -> mutex );
453
- kfree (buffer );
454
- }
413
+ struct configfs_buffer * buffer = filp -> private_data ;
414
+
415
+ if (buffer -> item )
416
+ config_item_put (buffer -> item );
417
+ module_put (buffer -> owner );
418
+ if (buffer -> page )
419
+ free_page ((unsigned long )buffer -> page );
420
+ mutex_destroy (& buffer -> mutex );
421
+ kfree (buffer );
455
422
return 0 ;
456
423
}
457
424
458
425
static int configfs_open_file (struct inode * inode , struct file * filp )
459
426
{
460
- return check_perm (inode , filp , CONFIGFS_ITEM_ATTR );
427
+ return __configfs_open_file (inode , filp , CONFIGFS_ITEM_ATTR );
461
428
}
462
429
463
430
static int configfs_open_bin_file (struct inode * inode , struct file * filp )
464
431
{
465
- return check_perm (inode , filp , CONFIGFS_ITEM_BIN_ATTR );
432
+ return __configfs_open_file (inode , filp , CONFIGFS_ITEM_BIN_ATTR );
466
433
}
467
434
468
- static int configfs_release_bin_file (struct inode * inode , struct file * filp )
435
+ static int configfs_release_bin_file (struct inode * inode , struct file * file )
469
436
{
470
- struct configfs_buffer * buffer = filp -> private_data ;
471
- struct dentry * dentry = filp -> f_path .dentry ;
472
- struct config_item * item = to_item (dentry -> d_parent );
473
- struct configfs_bin_attribute * bin_attr = to_bin_attr (dentry );
474
- ssize_t len = 0 ;
475
- int ret ;
437
+ struct configfs_buffer * buffer = file -> private_data ;
476
438
477
439
buffer -> read_in_progress = false;
478
440
479
441
if (buffer -> write_in_progress ) {
480
442
buffer -> write_in_progress = false;
481
443
482
- len = bin_attr -> write (item , buffer -> bin_buffer ,
444
+ /* result of ->release() is ignored */
445
+ buffer -> bin_attr -> write (buffer -> item , buffer -> bin_buffer ,
483
446
buffer -> bin_buffer_size );
484
447
485
448
/* vfree on NULL is safe */
@@ -489,10 +452,8 @@ static int configfs_release_bin_file(struct inode *inode, struct file *filp)
489
452
buffer -> needs_read_fill = 1 ;
490
453
}
491
454
492
- ret = configfs_release (inode , filp );
493
- if (len < 0 )
494
- return len ;
495
- return ret ;
455
+ configfs_release (inode , file );
456
+ return 0 ;
496
457
}
497
458
498
459
0 commit comments