2 File: fs/devpts/xattr.c
4 Derived from fs/ext3/xattr.c, changed in the following ways:
5 drop everything related to persistent storage of EAs
6 pass dentry rather than inode to internal methods
7 only presently define a handler for security modules
10 #include <linux/init.h>
12 #include <linux/slab.h>
13 #include <linux/string.h>
14 #include <asm/semaphore.h>
17 static struct devpts_xattr_handler *devpts_xattr_handlers[DEVPTS_XATTR_INDEX_MAX];
18 static rwlock_t devpts_handler_lock = RW_LOCK_UNLOCKED;
21 devpts_xattr_register(int name_index, struct devpts_xattr_handler *handler)
25 if (name_index > 0 && name_index <= DEVPTS_XATTR_INDEX_MAX) {
26 write_lock(&devpts_handler_lock);
27 if (!devpts_xattr_handlers[name_index-1]) {
28 devpts_xattr_handlers[name_index-1] = handler;
31 write_unlock(&devpts_handler_lock);
37 devpts_xattr_unregister(int name_index, struct devpts_xattr_handler *handler)
39 if (name_index > 0 || name_index <= DEVPTS_XATTR_INDEX_MAX) {
40 write_lock(&devpts_handler_lock);
41 devpts_xattr_handlers[name_index-1] = NULL;
42 write_unlock(&devpts_handler_lock);
46 static inline const char *
47 strcmp_prefix(const char *a, const char *a_prefix)
49 while (*a_prefix && *a == *a_prefix) {
53 return *a_prefix ? NULL : a;
57 * Decode the extended attribute name, and translate it into
58 * the name_index and name suffix.
60 static inline struct devpts_xattr_handler *
61 devpts_xattr_resolve_name(const char **name)
63 struct devpts_xattr_handler *handler = NULL;
68 read_lock(&devpts_handler_lock);
69 for (i=0; i<DEVPTS_XATTR_INDEX_MAX; i++) {
70 if (devpts_xattr_handlers[i]) {
71 const char *n = strcmp_prefix(*name,
72 devpts_xattr_handlers[i]->prefix);
74 handler = devpts_xattr_handlers[i];
80 read_unlock(&devpts_handler_lock);
84 static inline struct devpts_xattr_handler *
85 devpts_xattr_handler(int name_index)
87 struct devpts_xattr_handler *handler = NULL;
88 if (name_index > 0 && name_index <= DEVPTS_XATTR_INDEX_MAX) {
89 read_lock(&devpts_handler_lock);
90 handler = devpts_xattr_handlers[name_index-1];
91 read_unlock(&devpts_handler_lock);
97 * Inode operation getxattr()
99 * dentry->d_inode->i_sem down
102 devpts_getxattr(struct dentry *dentry, const char *name,
103 void *buffer, size_t size)
105 struct devpts_xattr_handler *handler;
107 handler = devpts_xattr_resolve_name(&name);
110 return handler->get(dentry, name, buffer, size);
114 * Inode operation listxattr()
116 * dentry->d_inode->i_sem down
119 devpts_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
121 struct devpts_xattr_handler *handler = NULL;
123 unsigned int size = 0;
126 read_lock(&devpts_handler_lock);
128 for (i=0; i<DEVPTS_XATTR_INDEX_MAX; i++) {
129 handler = devpts_xattr_handlers[i];
131 size += handler->list(dentry, NULL);
139 if (size > buffer_size)
144 for (i=0; i<DEVPTS_XATTR_INDEX_MAX; i++) {
145 handler = devpts_xattr_handlers[i];
147 buf += handler->list(dentry, buf);
152 read_unlock(&devpts_handler_lock);
157 * Inode operation setxattr()
159 * dentry->d_inode->i_sem down
162 devpts_setxattr(struct dentry *dentry, const char *name,
163 const void *value, size_t size, int flags)
165 struct devpts_xattr_handler *handler;
168 value = ""; /* empty EA, do not remove */
169 handler = devpts_xattr_resolve_name(&name);
172 return handler->set(dentry, name, value, size, flags);
176 * Inode operation removexattr()
178 * dentry->d_inode->i_sem down
181 devpts_removexattr(struct dentry *dentry, const char *name)
183 struct devpts_xattr_handler *handler;
185 handler = devpts_xattr_resolve_name(&name);
188 return handler->set(dentry, name, NULL, 0, XATTR_REPLACE);
192 init_devpts_xattr(void)
194 #ifdef CONFIG_DEVPTS_FS_SECURITY
197 err = devpts_xattr_register(DEVPTS_XATTR_INDEX_SECURITY,
198 &devpts_xattr_security_handler);
207 exit_devpts_xattr(void)
209 #ifdef CONFIG_DEVPTS_FS_SECURITY
210 devpts_xattr_unregister(DEVPTS_XATTR_INDEX_SECURITY,
211 &devpts_xattr_security_handler);