aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/configfs/configfs.txt57
-rw-r--r--fs/configfs/configfs_internal.h14
-rw-r--r--fs/configfs/dir.c18
-rw-r--r--fs/configfs/file.c255
-rw-r--r--fs/configfs/inode.c2
-rw-r--r--include/linux/configfs.h50
6 files changed, 374 insertions, 22 deletions
diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt
index af68efdbbfad..e5fe521eea1d 100644
--- a/Documentation/filesystems/configfs/configfs.txt
+++ b/Documentation/filesystems/configfs/configfs.txt
@@ -51,15 +51,27 @@ configfs tree is always there, whether mounted on /config or not.
51An item is created via mkdir(2). The item's attributes will also 51An item is created via mkdir(2). The item's attributes will also
52appear at this time. readdir(3) can determine what the attributes are, 52appear at this time. readdir(3) can determine what the attributes are,
53read(2) can query their default values, and write(2) can store new 53read(2) can query their default values, and write(2) can store new
54values. Like sysfs, attributes should be ASCII text files, preferably 54values. Don't mix more than one attribute in one attribute file.
55with only one value per file. The same efficiency caveats from sysfs 55
56apply. Don't mix more than one attribute in one attribute file. 56There are two types of configfs attributes:
57 57
58Like sysfs, configfs expects write(2) to store the entire buffer at 58* Normal attributes, which similar to sysfs attributes, are small ASCII text
59once. When writing to configfs attributes, userspace processes should 59files, with a maximum size of one page (PAGE_SIZE, 4096 on i386). Preferably
60first read the entire file, modify the portions they wish to change, and 60only one value per file should be used, and the same caveats from sysfs apply.
61then write the entire buffer back. Attribute files have a maximum size 61Configfs expects write(2) to store the entire buffer at once. When writing to
62of one page (PAGE_SIZE, 4096 on i386). 62normal configfs attributes, userspace processes should first read the entire
63file, modify the portions they wish to change, and then write the entire
64buffer back.
65
66* Binary attributes, which are somewhat similar to sysfs binary attributes,
67but with a few slight changes to semantics. The PAGE_SIZE limitation does not
68apply, but the whole binary item must fit in single kernel vmalloc'ed buffer.
69The write(2) calls from user space are buffered, and the attributes'
70write_bin_attribute method will be invoked on the final close, therefore it is
71imperative for user-space to check the return code of close(2) in order to
72verify that the operation finished successfully.
73To avoid a malicious user OOMing the kernel, there's a per-binary attribute
74maximum buffer value.
63 75
64When an item needs to be destroyed, remove it with rmdir(2). An 76When an item needs to be destroyed, remove it with rmdir(2). An
65item cannot be destroyed if any other item has a link to it (via 77item cannot be destroyed if any other item has a link to it (via
@@ -171,6 +183,7 @@ among other things. For that, it needs a type.
171 struct configfs_item_operations *ct_item_ops; 183 struct configfs_item_operations *ct_item_ops;
172 struct configfs_group_operations *ct_group_ops; 184 struct configfs_group_operations *ct_group_ops;
173 struct configfs_attribute **ct_attrs; 185 struct configfs_attribute **ct_attrs;
186 struct configfs_bin_attribute **ct_bin_attrs;
174 }; 187 };
175 188
176The most basic function of a config_item_type is to define what 189The most basic function of a config_item_type is to define what
@@ -201,6 +214,32 @@ be called whenever userspace asks for a read(2) on the attribute. If an
201attribute is writable and provides a ->store method, that method will be 214attribute is writable and provides a ->store method, that method will be
202be called whenever userspace asks for a write(2) on the attribute. 215be called whenever userspace asks for a write(2) on the attribute.
203 216
217[struct configfs_bin_attribute]
218
219 struct configfs_attribute {
220 struct configfs_attribute cb_attr;
221 void *cb_private;
222 size_t cb_max_size;
223 };
224
225The binary attribute is used when the one needs to use binary blob to
226appear as the contents of a file in the item's configfs directory.
227To do so add the binary attribute to the NULL-terminated array
228config_item_type->ct_bin_attrs, and the item appears in configfs, the
229attribute file will appear with the configfs_bin_attribute->cb_attr.ca_name
230filename. configfs_bin_attribute->cb_attr.ca_mode specifies the file
231permissions.
232The cb_private member is provided for use by the driver, while the
233cb_max_size member specifies the maximum amount of vmalloc buffer
234to be used.
235
236If binary attribute is readable and the config_item provides a
237ct_item_ops->read_bin_attribute() method, that method will be called
238whenever userspace asks for a read(2) on the attribute. The converse
239will happen for write(2). The reads/writes are bufferred so only a
240single read/write will occur; the attributes' need not concern itself
241with it.
242
204[struct config_group] 243[struct config_group]
205 244
206A config_item cannot live in a vacuum. The only way one can be created 245A config_item cannot live in a vacuum. The only way one can be created
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h
index b65d1ef532d5..ccc31fa6f1a7 100644
--- a/fs/configfs/configfs_internal.h
+++ b/fs/configfs/configfs_internal.h
@@ -53,13 +53,14 @@ struct configfs_dirent {
53#define CONFIGFS_ROOT 0x0001 53#define CONFIGFS_ROOT 0x0001
54#define CONFIGFS_DIR 0x0002 54#define CONFIGFS_DIR 0x0002
55#define CONFIGFS_ITEM_ATTR 0x0004 55#define CONFIGFS_ITEM_ATTR 0x0004
56#define CONFIGFS_ITEM_BIN_ATTR 0x0008
56#define CONFIGFS_ITEM_LINK 0x0020 57#define CONFIGFS_ITEM_LINK 0x0020
57#define CONFIGFS_USET_DIR 0x0040 58#define CONFIGFS_USET_DIR 0x0040
58#define CONFIGFS_USET_DEFAULT 0x0080 59#define CONFIGFS_USET_DEFAULT 0x0080
59#define CONFIGFS_USET_DROPPING 0x0100 60#define CONFIGFS_USET_DROPPING 0x0100
60#define CONFIGFS_USET_IN_MKDIR 0x0200 61#define CONFIGFS_USET_IN_MKDIR 0x0200
61#define CONFIGFS_USET_CREATING 0x0400 62#define CONFIGFS_USET_CREATING 0x0400
62#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) 63#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)
63 64
64extern struct mutex configfs_symlink_mutex; 65extern struct mutex configfs_symlink_mutex;
65extern spinlock_t configfs_dirent_lock; 66extern spinlock_t configfs_dirent_lock;
@@ -72,6 +73,8 @@ extern struct inode * configfs_new_inode(umode_t mode, struct configfs_dirent *,
72extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct inode *)); 73extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct inode *));
73 74
74extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); 75extern int configfs_create_file(struct config_item *, const struct configfs_attribute *);
76extern int configfs_create_bin_file(struct config_item *,
77 const struct configfs_bin_attribute *);
75extern int configfs_make_dirent(struct configfs_dirent *, 78extern int configfs_make_dirent(struct configfs_dirent *,
76 struct dentry *, void *, umode_t, int); 79 struct dentry *, void *, umode_t, int);
77extern int configfs_dirent_is_ready(struct configfs_dirent *); 80extern int configfs_dirent_is_ready(struct configfs_dirent *);
@@ -88,7 +91,7 @@ extern void configfs_release_fs(void);
88extern struct rw_semaphore configfs_rename_sem; 91extern struct rw_semaphore configfs_rename_sem;
89extern const struct file_operations configfs_dir_operations; 92extern const struct file_operations configfs_dir_operations;
90extern const struct file_operations configfs_file_operations; 93extern const struct file_operations configfs_file_operations;
91extern const struct file_operations bin_fops; 94extern const struct file_operations configfs_bin_file_operations;
92extern const struct inode_operations configfs_dir_inode_operations; 95extern const struct inode_operations configfs_dir_inode_operations;
93extern const struct inode_operations configfs_root_inode_operations; 96extern const struct inode_operations configfs_root_inode_operations;
94extern const struct inode_operations configfs_symlink_inode_operations; 97extern const struct inode_operations configfs_symlink_inode_operations;
@@ -119,6 +122,13 @@ static inline struct configfs_attribute * to_attr(struct dentry * dentry)
119 return ((struct configfs_attribute *) sd->s_element); 122 return ((struct configfs_attribute *) sd->s_element);
120} 123}
121 124
125static inline struct configfs_bin_attribute *to_bin_attr(struct dentry *dentry)
126{
127 struct configfs_attribute *attr = to_attr(dentry);
128
129 return container_of(attr, struct configfs_bin_attribute, cb_attr);
130}
131
122static inline struct config_item *configfs_get_config_item(struct dentry *dentry) 132static inline struct config_item *configfs_get_config_item(struct dentry *dentry)
123{ 133{
124 struct config_item * item = NULL; 134 struct config_item * item = NULL;
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index a7a1b218f308..7ae97e83f121 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -255,6 +255,12 @@ static void configfs_init_file(struct inode * inode)
255 inode->i_fop = &configfs_file_operations; 255 inode->i_fop = &configfs_file_operations;
256} 256}
257 257
258static void configfs_init_bin_file(struct inode *inode)
259{
260 inode->i_size = 0;
261 inode->i_fop = &configfs_bin_file_operations;
262}
263
258static void init_symlink(struct inode * inode) 264static void init_symlink(struct inode * inode)
259{ 265{
260 inode->i_op = &configfs_symlink_inode_operations; 266 inode->i_op = &configfs_symlink_inode_operations;
@@ -423,7 +429,9 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
423 spin_unlock(&configfs_dirent_lock); 429 spin_unlock(&configfs_dirent_lock);
424 430
425 error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, 431 error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG,
426 configfs_init_file); 432 (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) ?
433 configfs_init_bin_file :
434 configfs_init_file);
427 if (error) { 435 if (error) {
428 configfs_put(sd); 436 configfs_put(sd);
429 return error; 437 return error;
@@ -583,6 +591,7 @@ static int populate_attrs(struct config_item *item)
583{ 591{
584 struct config_item_type *t = item->ci_type; 592 struct config_item_type *t = item->ci_type;
585 struct configfs_attribute *attr; 593 struct configfs_attribute *attr;
594 struct configfs_bin_attribute *bin_attr;
586 int error = 0; 595 int error = 0;
587 int i; 596 int i;
588 597
@@ -594,6 +603,13 @@ static int populate_attrs(struct config_item *item)
594 break;