aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/debugfs
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/debugfs')
-rw-r--r--fs/debugfs/inode.c75
1 files changed, 39 insertions, 36 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index d22438ef7674..30a87b3dbcac 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -27,12 +27,15 @@
27#include <linux/fsnotify.h> 27#include <linux/fsnotify.h>
28#include <linux/string.h> 28#include <linux/string.h>
29#include <linux/magic.h> 29#include <linux/magic.h>
30#include <linux/slab.h>
30 31
31static struct vfsmount *debugfs_mount; 32static struct vfsmount *debugfs_mount;
32static int debugfs_mount_count; 33static int debugfs_mount_count;
33static bool debugfs_registered; 34static bool debugfs_registered;
34 35
35static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev) 36static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev,
37 void *data, const struct file_operations *fops)
38
36{ 39{
37 struct inode *inode = new_inode(sb); 40 struct inode *inode = new_inode(sb);
38 41
@@ -44,14 +47,18 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
44 init_special_inode(inode, mode, dev); 47 init_special_inode(inode, mode, dev);
45 break; 48 break;
46 case S_IFREG: 49 case S_IFREG:
47 inode->i_fop = &debugfs_file_operations; 50 inode->i_fop = fops ? fops : &debugfs_file_operations;
51 inode->i_private = data;
48 break; 52 break;
49 case S_IFLNK: 53 case S_IFLNK:
50 inode->i_op = &debugfs_link_operations; 54 inode->i_op = &debugfs_link_operations;
55 inode->i_fop = fops;
56 inode->i_private = data;
51 break; 57 break;
52 case S_IFDIR: 58 case S_IFDIR:
53 inode->i_op = &simple_dir_inode_operations; 59 inode->i_op = &simple_dir_inode_operations;
54 inode->i_fop = &simple_dir_operations; 60 inode->i_fop = fops ? fops : &simple_dir_operations;
61 inode->i_private = data;
55 62
56 /* directory inodes start off with i_nlink == 2 63 /* directory inodes start off with i_nlink == 2
57 * (for "." entry) */ 64 * (for "." entry) */
@@ -64,7 +71,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
64 71
65/* SMP-safe */ 72/* SMP-safe */
66static int debugfs_mknod(struct inode *dir, struct dentry *dentry, 73static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
67 int mode, dev_t dev) 74 int mode, dev_t dev, void *data,
75 const struct file_operations *fops)
68{ 76{
69 struct inode *inode; 77 struct inode *inode;
70 int error = -EPERM; 78 int error = -EPERM;
@@ -72,7 +80,7 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
72 if (dentry->d_inode) 80 if (dentry->d_inode)
73 return -EEXIST; 81 return -EEXIST;
74 82
75 inode = debugfs_get_inode(dir->i_sb, mode, dev); 83 inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
76 if (inode) { 84 if (inode) {
77 d_instantiate(dentry, inode); 85 d_instantiate(dentry, inode);
78 dget(dentry); 86 dget(dentry);
@@ -81,12 +89,13 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
81 return error; 89 return error;
82} 90}
83 91
84static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 92static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode,
93 void *data, const struct file_operations *fops)
85{ 94{
86 int res; 95 int res;
87 96
88 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; 97 mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
89 res = debugfs_mknod(dir, dentry, mode, 0); 98 res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
90 if (!res) { 99 if (!res) {
91 inc_nlink(dir); 100 inc_nlink(dir);
92 fsnotify_mkdir(dir, dentry); 101 fsnotify_mkdir(dir, dentry);
@@ -94,18 +103,20 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
94 return res; 103 return res;
95} 104}
96 105
97static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode) 106static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode,
107 void *data, const struct file_operations *fops)
98{ 108{
99 mode = (mode & S_IALLUGO) | S_IFLNK; 109 mode = (mode & S_IALLUGO) | S_IFLNK;
100 return debugfs_mknod(dir, dentry, mode, 0); 110 return debugfs_mknod(dir, dentry, mode, 0, data, fops);
101} 111}
102 112
103static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) 113static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode,
114 void *data, const struct file_operations *fops)
104{ 115{
105 int res; 116 int res;
106 117
107 mode = (mode & S_IALLUGO) | S_IFREG; 118 mode = (mode & S_IALLUGO) | S_IFREG;
108 res = debugfs_mknod(dir, dentry, mode, 0); 119 res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
109 if (!res) 120 if (!res)
110 fsnotify_create(dir, dentry); 121 fsnotify_create(dir, dentry);
111 return res; 122 return res;
@@ -139,7 +150,9 @@ static struct file_system_type debug_fs_type = {
139 150
140static int debugfs_create_by_name(const char *name, mode_t mode, 151static int debugfs_create_by_name(const char *name, mode_t mode,
141 struct dentry *parent, 152 struct dentry *parent,
142 struct dentry **dentry) 153 struct dentry **dentry,
154 void *data,
155 const struct file_operations *fops)
143{ 156{
144 int error = 0; 157 int error = 0;
145 158
@@ -148,15 +161,8 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
148 * block. A pointer to that is in the struct vfsmount that we 161 * block. A pointer to that is in the struct vfsmount that we
149 * have around. 162 * have around.
150 */ 163 */
151 if (!parent) { 164 if (!parent)
152 if (debugfs_mount && debugfs_mount->mnt_sb) { 165 parent = debugfs_mount->mnt_sb->s_root;
153 parent = debugfs_mount->mnt_sb->s_root;
154 }
155 }
156 if (!parent) {
157 pr_debug("debugfs: Ah! can not find a parent!\n");
158 return -EFAULT;
159 }
160 166
161 *dentry = NULL; 167 *dentry = NULL;
162 mutex_lock(&parent->d_inode->i_mutex); 168 mutex_lock(&parent->d_inode->i_mutex);
@@ -164,13 +170,16 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
164 if (!IS_ERR(*dentry)) { 170 if (!IS_ERR(*dentry)) {
165 switch (mode & S_IFMT) { 171 switch (mode & S_IFMT) {
166 case S_IFDIR: 172 case S_IFDIR:
167 error = debugfs_mkdir(parent->d_inode, *dentry, mode); 173 error = debugfs_mkdir(parent->d_inode, *dentry, mode,
174 data, fops);
168 break; 175 break;
169 case S_IFLNK: 176 case S_IFLNK:
170 error = debugfs_link(parent->d_inode, *dentry, mode); 177 error = debugfs_link(parent->d_inode, *dentry, mode,
178 data, fops);
171 break; 179 break;
172 default: 180 default:
173 error = debugfs_create(parent->d_inode, *dentry, mode); 181 error = debugfs_create(parent->d_inode, *dentry, mode,
182 data, fops);
174 break; 183 break;
175 } 184 }
176 dput(*dentry); 185 dput(*dentry);
@@ -184,7 +193,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
184/** 193/**
185 * debugfs_create_file - create a file in the debugfs filesystem 194 * debugfs_create_file - create a file in the debugfs filesystem
186 * @name: a pointer to a string containing the name of the file to create. 195 * @name: a pointer to a string containing the name of the file to create.
187 * @mode: the permission that the file should have 196 * @mode: the permission that the file should have.
188 * @parent: a pointer to the parent dentry for this file. This should be a 197 * @parent: a pointer to the parent dentry for this file. This should be a
189 * directory dentry if set. If this paramater is NULL, then the 198 * directory dentry if set. If this paramater is NULL, then the
190 * file will be created in the root of the debugfs filesystem. 199 * file will be created in the root of the debugfs filesystem.
@@ -195,8 +204,8 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
195 * this file. 204 * this file.
196 * 205 *
197 * This is the basic "create a file" function for debugfs. It allows for a 206 * This is the basic "create a file" function for debugfs. It allows for a
198 * wide range of flexibility in createing a file, or a directory (if you 207 * wide range of flexibility in creating a file, or a directory (if you want
199 * want to create a directory, the debugfs_create_dir() function is 208 * to create a directory, the debugfs_create_dir() function is
200 * recommended to be used instead.) 209 * recommended to be used instead.)
201 * 210 *
202 * This function will return a pointer to a dentry if it succeeds. This 211 * This function will return a pointer to a dentry if it succeeds. This
@@ -221,19 +230,13 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,
221 if (error) 230 if (error)
222 goto exit; 231 goto exit;
223 232
224 error = debugfs_create_by_name(name, mode, parent, &dentry); 233 error = debugfs_create_by_name(name, mode, parent, &dentry,
234 data, fops);
225 if (error) { 235 if (error) {
226 dentry = NULL; 236 dentry = NULL;
227 simple_release_fs(&debugfs_mount, &debugfs_mount_count); 237 simple_release_fs(&debugfs_mount, &debugfs_mount_count);
228 goto exit; 238 goto exit;
229 } 239 }
230
231 if (dentry->d_inode) {
232 if (data)
233 dentry->d_inode->i_private = data;
234 if (fops)
235 dentry->d_inode->i_fop = fops;
236 }
237exit: 240exit:
238 return dentry; 241 return dentry;
239} 242}
@@ -494,7 +497,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
494 } 497 }
495 d_move(old_dentry, dentry); 498 d_move(old_dentry, dentry);
496 fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name, 499 fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
497 old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode), 500 S_ISDIR(old_dentry->d_inode->i_mode),
498 NULL, old_dentry); 501 NULL, old_dentry);
499 fsnotify_oldname_free(old_name); 502 fsnotify_oldname_free(old_name);
500 unlock_rename(new_dir, old_dir); 503 unlock_rename(new_dir, old_dir);