aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 18:18:19 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 18:18:19 -0500
commitc6b1de1b646fe232206d4065df4d14040cebd613 (patch)
tree271b208be1e0e6e026da5979311197fe5a791a11 /fs
parent50652963eae6afe13678dc84d789a174306a4df7 (diff)
parente59b4e9187bd5175b9845dc10fedb0879b7efbfd (diff)
Merge branch 'debugfs_automount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull debugfs patches from Al Viro: "debugfs patches, mostly to make it possible for something like tracefs to be transparently automounted on given directory in debugfs. New primitive in there is debugfs_create_automount(name, parent, func, arg), which creates a directory and makes its ->d_automount() return func(arg). Another missing primitive was debugfs_create_file_size() - open-coded in quite a few places. Dave's patch adds it and converts the open-code instances to calling it" * 'debugfs_automount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: debugfs: Provide a file creation function that also takes an initial size new primitive: debugfs_create_automount() debugfs: split end_creating() into success and failure cases debugfs: take mode-dependent parts of debugfs_get_inode() into callers fold debugfs_mknod() into callers fold debugfs_create() into caller fold debugfs_mkdir() into caller debugfs_mknod(): get rid useless arguments fold debugfs_link() into caller debugfs: kill __create_file() debugfs: split the beginning and the end of __create_file() off debugfs_{mkdir,create,link}(): get rid of redundant argument
Diffstat (limited to 'fs')
-rw-r--r--fs/debugfs/inode.c291
1 files changed, 168 insertions, 123 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 05f2960ed7c3..45b18a5e225c 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -34,93 +34,16 @@ static struct vfsmount *debugfs_mount;
34static int debugfs_mount_count; 34static int debugfs_mount_count;
35static bool debugfs_registered; 35static bool debugfs_registered;
36 36
37static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev_t dev, 37static struct inode *debugfs_get_inode(struct super_block *sb)
38 void *data, const struct file_operations *fops)
39
40{ 38{
41 struct inode *inode = new_inode(sb); 39 struct inode *inode = new_inode(sb);
42
43 if (inode) { 40 if (inode) {
44 inode->i_ino = get_next_ino(); 41 inode->i_ino = get_next_ino();
45 inode->i_mode = mode;
46 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 42 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
47 switch (mode & S_IFMT) {
48 default:
49 init_special_inode(inode, mode, dev);
50 break;
51 case S_IFREG:
52 inode->i_fop = fops ? fops : &debugfs_file_operations;
53 inode->i_private = data;
54 break;
55 case S_IFLNK:
56 inode->i_op = &debugfs_link_operations;
57 inode->i_private = data;
58 break;
59 case S_IFDIR:
60 inode->i_op = &simple_dir_inode_operations;
61 inode->i_fop = &simple_dir_operations;
62
63 /* directory inodes start off with i_nlink == 2
64 * (for "." entry) */
65 inc_nlink(inode);
66 break;
67 }
68 } 43 }
69 return inode; 44 return inode;
70} 45}
71 46
72/* SMP-safe */
73static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
74 umode_t mode, dev_t dev, void *data,
75 const struct file_operations *fops)
76{
77 struct inode *inode;
78 int error = -EPERM;
79
80 if (dentry->d_inode)
81 return -EEXIST;
82
83 inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
84 if (inode) {
85 d_instantiate(dentry, inode);
86 dget(dentry);
87 error = 0;
88 }
89 return error;
90}
91
92static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
93{
94 int res;
95
96 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
97 res = debugfs_mknod(dir, dentry, mode, 0, NULL, NULL);
98 if (!res) {
99 inc_nlink(dir);
100 fsnotify_mkdir(dir, dentry);
101 }
102 return res;
103}
104
105static int debugfs_link(struct inode *dir, struct dentry *dentry, umode_t mode,
106 void *data)
107{
108 mode = (mode & S_IALLUGO) | S_IFLNK;
109 return debugfs_mknod(dir, dentry, mode, 0, data, NULL);
110}
111
112static int debugfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
113 void *data, const struct file_operations *fops)
114{
115 int res;
116
117 mode = (mode & S_IALLUGO) | S_IFREG;
118 res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
119 if (!res)
120 fsnotify_create(dir, dentry);
121 return res;
122}
123
124static inline int debugfs_positive(struct dentry *dentry) 47static inline int debugfs_positive(struct dentry *dentry)
125{ 48{
126 return dentry->d_inode && !d_unhashed(dentry); 49 return dentry->d_inode && !d_unhashed(dentry);
@@ -252,6 +175,18 @@ static const struct super_operations debugfs_super_operations = {
252 .show_options = debugfs_show_options, 175 .show_options = debugfs_show_options,
253}; 176};
254 177
178static struct vfsmount *debugfs_automount(struct path *path)
179{
180 struct vfsmount *(*f)(void *);
181 f = (struct vfsmount *(*)(void *))path->dentry->d_fsdata;
182 return f(path->dentry->d_inode->i_private);
183}
184
185static const struct dentry_operations debugfs_dops = {
186 .d_delete = always_delete_dentry,
187 .d_automount = debugfs_automount,
188};
189
255static int debug_fill_super(struct super_block *sb, void *data, int silent) 190static int debug_fill_super(struct super_block *sb, void *data, int silent)
256{ 191{
257 static struct tree_descr debug_files[] = {{""}}; 192 static struct tree_descr debug_files[] = {{""}};
@@ -276,6 +211,7 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
276 goto fail; 211 goto fail;
277 212
278 sb->s_op = &debugfs_super_operations; 213 sb->s_op = &debugfs_super_operations;
214 sb->s_d_op = &debugfs_dops;
279 215
280 debugfs_apply_options(sb); 216 debugfs_apply_options(sb);
281 217
@@ -302,11 +238,9 @@ static struct file_system_type debug_fs_type = {
302}; 238};
303MODULE_ALIAS_FS("debugfs"); 239MODULE_ALIAS_FS("debugfs");
304 240
305static struct dentry *__create_file(const char *name, umode_t mode, 241static struct dentry *start_creating(const char *name, struct dentry *parent)
306 struct dentry *parent, void *data,
307 const struct file_operations *fops)
308{ 242{
309 struct dentry *dentry = NULL; 243 struct dentry *dentry;
310 int error; 244 int error;
311 245
312 pr_debug("debugfs: creating file '%s'\n",name); 246 pr_debug("debugfs: creating file '%s'\n",name);
@@ -314,7 +248,7 @@ static struct dentry *__create_file(const char *name, umode_t mode,
314 error = simple_pin_fs(&debug_fs_type, &debugfs_mount, 248 error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
315 &debugfs_mount_count); 249 &debugfs_mount_count);
316 if (error) 250 if (error)
317 goto exit; 251 return ERR_PTR(error);
318 252
319 /* If the parent is not specified, we create it in the root. 253 /* If the parent is not specified, we create it in the root.
320 * We need the root dentry to do this, which is in the super 254 * We need the root dentry to do this, which is in the super
@@ -326,31 +260,26 @@ static struct dentry *__create_file(const char *name, umode_t mode,
326 260
327 mutex_lock(&parent->d_inode->i_mutex); 261 mutex_lock(&parent->d_inode->i_mutex);
328 dentry = lookup_one_len(name, parent, strlen(name)); 262 dentry = lookup_one_len(name, parent, strlen(name));
329 if (!IS_ERR(dentry)) { 263 if (!IS_ERR(dentry) && dentry->d_inode) {
330 switch (mode & S_IFMT) {
331 case S_IFDIR:
332 error = debugfs_mkdir(parent->d_inode, dentry, mode);
333
334 break;
335 case S_IFLNK:
336 error = debugfs_link(parent->d_inode, dentry, mode,
337 data);
338 break;
339 default:
340 error = debugfs_create(parent->d_inode, dentry, mode,
341 data, fops);
342 break;
343 }
344 dput(dentry); 264 dput(dentry);
345 } else 265 dentry = ERR_PTR(-EEXIST);
346 error = PTR_ERR(dentry);
347 mutex_unlock(&parent->d_inode->i_mutex);
348
349 if (error) {
350 dentry = NULL;
351 simple_release_fs(&debugfs_mount, &debugfs_mount_count);
352 } 266 }
353exit: 267 if (IS_ERR(dentry))
268 mutex_unlock(&parent->d_inode->i_mutex);
269 return dentry;
270}
271
272static struct dentry *failed_creating(struct dentry *dentry)
273{
274 mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
275 dput(dentry);
276 simple_release_fs(&debugfs_mount, &debugfs_mount_count);
277 return NULL;
278}
279
280static struct dentry *end_creating(struct dentry *dentry)
281{
282 mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
354 return dentry; 283 return dentry;
355} 284}
356 285
@@ -384,19 +313,71 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
384 struct dentry *parent, void *data, 313 struct dentry *parent, void *data,
385 const struct file_operations *fops) 314 const struct file_operations *fops)
386{ 315{
387 switch (mode & S_IFMT) { 316 struct dentry *dentry;
388 case S_IFREG: 317 struct inode *inode;
389 case 0: 318
390 break; 319 if (!(mode & S_IFMT))
391 default: 320 mode |= S_IFREG;
392 BUG(); 321 BUG_ON(!S_ISREG(mode));
393 } 322 dentry = start_creating(name, parent);
323
324 if (IS_ERR(dentry))
325 return NULL;
394 326
395 return __create_file(name, mode, parent, data, fops); 327 inode = debugfs_get_inode(dentry->d_sb);
328 if (unlikely(!inode))
329 return failed_creating(dentry);
330
331 inode->i_mode = mode;
332 inode->i_fop = fops ? fops : &debugfs_file_operations;
333 inode->i_private = data;
334 d_instantiate(dentry, inode);
335 fsnotify_create(dentry->d_parent->d_inode, dentry);
336 return end_creating(dentry);
396} 337}
397EXPORT_SYMBOL_GPL(debugfs_create_file); 338EXPORT_SYMBOL_GPL(debugfs_create_file);
398 339
399/** 340/**
341 * debugfs_create_file_size - create a file in the debugfs filesystem
342 * @name: a pointer to a string containing the name of the file to create.
343 * @mode: the permission that the file should have.
344 * @parent: a pointer to the parent dentry for this file. This should be a
345 * directory dentry if set. If this parameter is NULL, then the
346 * file will be created in the root of the debugfs filesystem.
347 * @data: a pointer to something that the caller will want to get to later
348 * on. The inode.i_private pointer will point to this value on
349 * the open() call.
350 * @fops: a pointer to a struct file_operations that should be used for
351 * this file.
352 * @file_size: initial file size
353 *
354 * This is the basic "create a file" function for debugfs. It allows for a
355 * wide range of flexibility in creating a file, or a directory (if you want
356 * to create a directory, the debugfs_create_dir() function is
357 * recommended to be used instead.)
358 *
359 * This function will return a pointer to a dentry if it succeeds. This
360 * pointer must be passed to the debugfs_remove() function when the file is
361 * to be removed (no automatic cleanup happens if your module is unloaded,
362 * you are responsible here.) If an error occurs, %NULL will be returned.
363 *
364 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
365 * returned.
366 */
367struct dentry *debugfs_create_file_size(const char *name, umode_t mode,
368 struct dentry *parent, void *data,
369 const struct file_operations *fops,
370 loff_t file_size)
371{
372 struct dentry *de = debugfs_create_file(name, mode, parent, data, fops);
373
374 if (de)
375 de->d_inode->i_size = file_size;
376 return de;
377}
378EXPORT_SYMBOL_GPL(debugfs_create_file_size);
379
380/**
400 * debugfs_create_dir - create a directory in the debugfs filesystem 381 * debugfs_create_dir - create a directory in the debugfs filesystem
401 * @name: a pointer to a string containing the name of the directory to 382 * @name: a pointer to a string containing the name of the directory to
402 * create. 383 * create.
@@ -416,12 +397,65 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
416 */ 397 */
417struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) 398struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
418{ 399{
419 return __create_file(name, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 400 struct dentry *dentry = start_creating(name, parent);
420 parent, NULL, NULL); 401 struct inode *inode;
402
403 if (IS_ERR(dentry))
404 return NULL;
405
406 inode = debugfs_get_inode(dentry->d_sb);
407 if (unlikely(!inode))
408 return failed_creating(dentry);
409
410 inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
411 inode->i_op = &simple_dir_inode_operations;
412 inode->i_fop = &simple_dir_operations;
413
414 /* directory inodes start off with i_nlink == 2 (for "." entry) */
415 inc_nlink(inode);
416 d_instantiate(dentry, inode);
417 inc_nlink(dentry->d_parent->d_inode);
418 fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
419 return end_creating(dentry);
421} 420}
422EXPORT_SYMBOL_GPL(debugfs_create_dir); 421EXPORT_SYMBOL_GPL(debugfs_create_dir);
423 422
424/** 423/**
424 * debugfs_create_automount - create automount point in the debugfs filesystem
425 * @name: a pointer to a string containing the name of the file to create.
426 * @parent: a pointer to the parent dentry for this file. This should be a
427 * directory dentry if set. If this parameter is NULL, then the
428 * file will be created in the root of the debugfs filesystem.
429 * @f: function to be called when pathname resolution steps on that one.
430 * @data: opaque argument to pass to f().
431 *
432 * @f should return what ->d_automount() would.
433 */
434struct dentry *debugfs_create_automount(const char *name,
435 struct dentry *parent,
436 struct vfsmount *(*f)(void *),
437 void *data)
438{
439 struct dentry *dentry = start_creating(name, parent);
440 struct inode *inode;
441
442 if (IS_ERR(dentry))
443 return NULL;
444
445 inode = debugfs_get_inode(dentry->d_sb);
446 if (unlikely(!inode))
447 return failed_creating(dentry);
448
449 inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
450 inode->i_flags |= S_AUTOMOUNT;
451 inode->i_private = data;
452 dentry->d_fsdata = (void *)f;
453 d_instantiate(dentry, inode);
454 return end_creating(dentry);
455}
456EXPORT_SYMBOL(debugfs_create_automount);
457
458/**
425 * debugfs_create_symlink- create a symbolic link in the debugfs filesystem 459 * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
426 * @name: a pointer to a string containing the name of the symbolic link to 460 * @name: a pointer to a string containing the name of the symbolic link to
427 * create. 461 * create.
@@ -447,17 +481,28 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
447struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, 481struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
448 const char *target) 482 const char *target)
449{ 483{
450 struct dentry *result; 484 struct dentry *dentry;
451 char *link; 485 struct inode *inode;
452 486 char *link = kstrdup(target, GFP_KERNEL);
453 link = kstrdup(target, GFP_KERNEL);
454 if (!link) 487 if (!link)
455 return NULL; 488 return NULL;
456 489
457 result = __create_file(name, S_IFLNK | S_IRWXUGO, parent, link, NULL); 490 dentry = start_creating(name, parent);
458 if (!result) 491 if (IS_ERR(dentry)) {
459 kfree(link); 492 kfree(link);
460 return result; 493 return NULL;
494 }
495
496 inode = debugfs_get_inode(dentry->d_sb);
497 if (unlikely(!inode)) {
498 kfree(link);
499 return failed_creating(dentry);
500 }
501 inode->i_mode = S_IFLNK | S_IRWXUGO;
502 inode->i_op = &debugfs_link_operations;
503 inode->i_private = link;
504 d_instantiate(dentry, inode);
505 return end_creating(dentry);
461} 506}
462EXPORT_SYMBOL_GPL(debugfs_create_symlink); 507EXPORT_SYMBOL_GPL(debugfs_create_symlink);
463 508