diff options
author | Nicolai Stange <nicstange@gmail.com> | 2017-10-30 19:15:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-11-07 14:25:03 -0500 |
commit | 154b9d7512ae012aca7b4e90af67a72419ad1941 (patch) | |
tree | 565b3295b5abdf575d519b336b01f1f8c1713224 /fs/debugfs/file.c | |
parent | c9afbec27089cd6b4e621b639f41c7fc726c3bf1 (diff) |
debugfs: call debugfs_real_fops() only after debugfs_file_get()
The current implementation of debugfs_real_fops() relies on a
debugfs_fsdata instance to be installed at ->d_fsdata.
With future patches introducing lazy allocation of these, this requirement
will be guaranteed to be fullfilled only inbetween a
debugfs_file_get()/debugfs_file_put() pair.
The full proxies' fops implemented by debugfs happen to be the only
offenders. Fix them up by moving their debugfs_real_fops() calls past those
to debugfs_file_get().
full_proxy_release() is special as it doesn't invoke debugfs_file_get() at
all. Leave it alone for now.
Signed-off-by: Nicolai Stange <nicstange@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/debugfs/file.c')
-rw-r--r-- | fs/debugfs/file.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 53f5c9a2af88..bc3549c95574 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c | |||
@@ -144,13 +144,13 @@ const struct file_operations debugfs_open_proxy_file_operations = { | |||
144 | static ret_type full_proxy_ ## name(proto) \ | 144 | static ret_type full_proxy_ ## name(proto) \ |
145 | { \ | 145 | { \ |
146 | struct dentry *dentry = F_DENTRY(filp); \ | 146 | struct dentry *dentry = F_DENTRY(filp); \ |
147 | const struct file_operations *real_fops = \ | 147 | const struct file_operations *real_fops; \ |
148 | debugfs_real_fops(filp); \ | ||
149 | ret_type r; \ | 148 | ret_type r; \ |
150 | \ | 149 | \ |
151 | r = debugfs_file_get(dentry); \ | 150 | r = debugfs_file_get(dentry); \ |
152 | if (unlikely(r)) \ | 151 | if (unlikely(r)) \ |
153 | return r; \ | 152 | return r; \ |
153 | real_fops = debugfs_real_fops(filp); \ | ||
154 | r = real_fops->name(args); \ | 154 | r = real_fops->name(args); \ |
155 | debugfs_file_put(dentry); \ | 155 | debugfs_file_put(dentry); \ |
156 | return r; \ | 156 | return r; \ |
@@ -177,13 +177,14 @@ FULL_PROXY_FUNC(unlocked_ioctl, long, filp, | |||
177 | static unsigned int full_proxy_poll(struct file *filp, | 177 | static unsigned int full_proxy_poll(struct file *filp, |
178 | struct poll_table_struct *wait) | 178 | struct poll_table_struct *wait) |
179 | { | 179 | { |
180 | const struct file_operations *real_fops = debugfs_real_fops(filp); | ||
181 | struct dentry *dentry = F_DENTRY(filp); | 180 | struct dentry *dentry = F_DENTRY(filp); |
182 | unsigned int r = 0; | 181 | unsigned int r = 0; |
182 | const struct file_operations *real_fops; | ||
183 | 183 | ||
184 | if (debugfs_file_get(dentry)) | 184 | if (debugfs_file_get(dentry)) |
185 | return POLLHUP; | 185 | return POLLHUP; |
186 | 186 | ||
187 | real_fops = debugfs_real_fops(filp); | ||
187 | r = real_fops->poll(filp, wait); | 188 | r = real_fops->poll(filp, wait); |
188 | debugfs_file_put(dentry); | 189 | debugfs_file_put(dentry); |
189 | return r; | 190 | return r; |