@@ -51,7 +51,7 @@ const struct file_operations *debugfs_real_fops(const struct file *filp)
51
51
{
52
52
struct debugfs_fsdata * fsd = F_DENTRY (filp )-> d_fsdata ;
53
53
54
- if (( unsigned long ) fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT ) {
54
+ if (! fsd ) {
55
55
/*
56
56
* Urgh, we've been called w/o a protecting
57
57
* debugfs_file_get().
@@ -84,9 +84,11 @@ static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode)
84
84
return - EINVAL ;
85
85
86
86
d_fsd = READ_ONCE (dentry -> d_fsdata );
87
- if (!(( unsigned long ) d_fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT ) ) {
87
+ if (d_fsd ) {
88
88
fsd = d_fsd ;
89
89
} else {
90
+ struct inode * inode = dentry -> d_inode ;
91
+
90
92
if (WARN_ON (mode == DBGFS_GET_ALREADY ))
91
93
return - EINVAL ;
92
94
@@ -96,9 +98,7 @@ static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode)
96
98
97
99
if (mode == DBGFS_GET_SHORT ) {
98
100
const struct debugfs_short_fops * ops ;
99
- ops = (void * )((unsigned long )d_fsd &
100
- ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT );
101
- fsd -> short_fops = ops ;
101
+ ops = fsd -> short_fops = DEBUGFS_I (inode )-> short_fops ;
102
102
if (ops -> llseek )
103
103
fsd -> methods |= HAS_LSEEK ;
104
104
if (ops -> read )
@@ -107,9 +107,7 @@ static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode)
107
107
fsd -> methods |= HAS_WRITE ;
108
108
} else {
109
109
const struct file_operations * ops ;
110
- ops = (void * )((unsigned long )d_fsd &
111
- ~DEBUGFS_FSDATA_IS_REAL_FOPS_BIT );
112
- fsd -> real_fops = ops ;
110
+ ops = fsd -> real_fops = DEBUGFS_I (inode )-> real_fops ;
113
111
if (ops -> llseek )
114
112
fsd -> methods |= HAS_LSEEK ;
115
113
if (ops -> read )
@@ -126,10 +124,11 @@ static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode)
126
124
INIT_LIST_HEAD (& fsd -> cancellations );
127
125
mutex_init (& fsd -> cancellations_mtx );
128
126
129
- if (cmpxchg (& dentry -> d_fsdata , d_fsd , fsd ) != d_fsd ) {
127
+ d_fsd = cmpxchg (& dentry -> d_fsdata , NULL , fsd );
128
+ if (d_fsd ) {
130
129
mutex_destroy (& fsd -> cancellations_mtx );
131
130
kfree (fsd );
132
- fsd = READ_ONCE ( dentry -> d_fsdata ) ;
131
+ fsd = d_fsd ;
133
132
}
134
133
}
135
134
@@ -226,8 +225,7 @@ void debugfs_enter_cancellation(struct file *file,
226
225
return ;
227
226
228
227
fsd = READ_ONCE (dentry -> d_fsdata );
229
- if (WARN_ON (!fsd ||
230
- ((unsigned long )fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT )))
228
+ if (WARN_ON (!fsd ))
231
229
return ;
232
230
233
231
mutex_lock (& fsd -> cancellations_mtx );
@@ -258,8 +256,7 @@ void debugfs_leave_cancellation(struct file *file,
258
256
return ;
259
257
260
258
fsd = READ_ONCE (dentry -> d_fsdata );
261
- if (WARN_ON (!fsd ||
262
- ((unsigned long )fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT )))
259
+ if (WARN_ON (!fsd ))
263
260
return ;
264
261
265
262
mutex_lock (& fsd -> cancellations_mtx );
@@ -427,22 +424,21 @@ static int full_proxy_release(struct inode *inode, struct file *filp)
427
424
* not to leak any resources. Releasers must not assume that
428
425
* ->i_private is still being meaningful here.
429
426
*/
430
- if (real_fops && real_fops -> release )
427
+ if (real_fops -> release )
431
428
r = real_fops -> release (inode , filp );
432
429
433
430
fops_put (real_fops );
434
431
return r ;
435
432
}
436
433
437
- static int full_proxy_open (struct inode * inode , struct file * filp ,
438
- enum dbgfs_get_mode mode )
434
+ static int full_proxy_open_regular (struct inode * inode , struct file * filp )
439
435
{
440
436
struct dentry * dentry = F_DENTRY (filp );
441
437
const struct file_operations * real_fops ;
442
438
struct debugfs_fsdata * fsd ;
443
439
int r ;
444
440
445
- r = __debugfs_file_get (dentry , mode );
441
+ r = __debugfs_file_get (dentry , DBGFS_GET_REGULAR );
446
442
if (r )
447
443
return r == - EIO ? - ENOENT : r ;
448
444
@@ -452,7 +448,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp,
452
448
if (r )
453
449
goto out ;
454
450
455
- if (real_fops && !fops_get (real_fops )) {
451
+ if (!fops_get (real_fops )) {
456
452
#ifdef CONFIG_MODULES
457
453
if (real_fops -> owner &&
458
454
real_fops -> owner -> state == MODULE_STATE_GOING ) {
@@ -468,11 +464,8 @@ static int full_proxy_open(struct inode *inode, struct file *filp,
468
464
goto out ;
469
465
}
470
466
471
- if (!real_fops || real_fops -> open ) {
472
- if (real_fops )
473
- r = real_fops -> open (inode , filp );
474
- else
475
- r = simple_open (inode , filp );
467
+ if (real_fops -> open ) {
468
+ r = real_fops -> open (inode , filp );
476
469
if (r ) {
477
470
fops_put (real_fops );
478
471
} else if (filp -> f_op != & debugfs_full_proxy_file_operations ) {
@@ -487,11 +480,6 @@ static int full_proxy_open(struct inode *inode, struct file *filp,
487
480
return r ;
488
481
}
489
482
490
- static int full_proxy_open_regular (struct inode * inode , struct file * filp )
491
- {
492
- return full_proxy_open (inode , filp , DBGFS_GET_REGULAR );
493
- }
494
-
495
483
const struct file_operations debugfs_full_proxy_file_operations = {
496
484
.open = full_proxy_open_regular ,
497
485
.release = full_proxy_release ,
@@ -504,7 +492,17 @@ const struct file_operations debugfs_full_proxy_file_operations = {
504
492
505
493
static int full_proxy_open_short (struct inode * inode , struct file * filp )
506
494
{
507
- return full_proxy_open (inode , filp , DBGFS_GET_SHORT );
495
+ struct dentry * dentry = F_DENTRY (filp );
496
+ int r ;
497
+
498
+ r = __debugfs_file_get (dentry , DBGFS_GET_SHORT );
499
+ if (r )
500
+ return r == - EIO ? - ENOENT : r ;
501
+ r = debugfs_locked_down (inode , filp , NULL );
502
+ if (!r )
503
+ r = simple_open (inode , filp );
504
+ debugfs_file_put (dentry );
505
+ return r ;
508
506
}
509
507
510
508
const struct file_operations debugfs_full_short_proxy_file_operations = {
0 commit comments