diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2011-03-09 14:23:34 -0500 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2011-07-18 12:29:39 -0400 |
commit | 1601fbad2b14e0b8d4dbb55e749bfe31e972818a (patch) | |
tree | ca9271af43fc7b0edaaa9e5464a82d3b427db8b2 /fs/xattr.c | |
parent | f381c272224f5f158f5cff64f8f3481fa0eee8b3 (diff) |
xattr: define vfs_getxattr_alloc and vfs_xattr_cmp
vfs_getxattr_alloc() and vfs_xattr_cmp() are two new kernel xattr helper
functions. vfs_getxattr_alloc() first allocates memory for the requested
xattr and then retrieves it. vfs_xattr_cmp() compares a given value with
the contents of an extended attribute.
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Diffstat (limited to 'fs/xattr.c')
-rw-r--r-- | fs/xattr.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index f060663ab70c..851808c92b30 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -166,6 +166,64 @@ out_noalloc: | |||
166 | } | 166 | } |
167 | EXPORT_SYMBOL_GPL(xattr_getsecurity); | 167 | EXPORT_SYMBOL_GPL(xattr_getsecurity); |
168 | 168 | ||
169 | /* | ||
170 | * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr | ||
171 | * | ||
172 | * Allocate memory, if not already allocated, or re-allocate correct size, | ||
173 | * before retrieving the extended attribute. | ||
174 | * | ||
175 | * Returns the result of alloc, if failed, or the getxattr operation. | ||
176 | */ | ||
177 | ssize_t | ||
178 | vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, | ||
179 | size_t xattr_size, gfp_t flags) | ||
180 | { | ||
181 | struct inode *inode = dentry->d_inode; | ||
182 | char *value = *xattr_value; | ||
183 | int error; | ||
184 | |||
185 | error = xattr_permission(inode, name, MAY_READ); | ||
186 | if (error) | ||
187 | return error; | ||
188 | |||
189 | if (!inode->i_op->getxattr) | ||
190 | return -EOPNOTSUPP; | ||
191 | |||
192 | error = inode->i_op->getxattr(dentry, name, NULL, 0); | ||
193 | if (error < 0) | ||
194 | return error; | ||
195 | |||
196 | if (!value || (error > xattr_size)) { | ||
197 | value = krealloc(*xattr_value, error + 1, flags); | ||
198 | if (!value) | ||
199 | return -ENOMEM; | ||
200 | memset(value, 0, error + 1); | ||
201 | } | ||
202 | |||
203 | error = inode->i_op->getxattr(dentry, name, value, error); | ||
204 | *xattr_value = value; | ||
205 | return error; | ||
206 | } | ||
207 | |||
208 | /* Compare an extended attribute value with the given value */ | ||
209 | int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name, | ||
210 | const char *value, size_t size, gfp_t flags) | ||
211 | { | ||
212 | char *xattr_value = NULL; | ||
213 | int rc; | ||
214 | |||
215 | rc = vfs_getxattr_alloc(dentry, xattr_name, &xattr_value, 0, flags); | ||
216 | if (rc < 0) | ||
217 | return rc; | ||
218 | |||
219 | if ((rc != size) || (memcmp(xattr_value, value, rc) != 0)) | ||
220 | rc = -EINVAL; | ||
221 | else | ||
222 | rc = 0; | ||
223 | kfree(xattr_value); | ||
224 | return rc; | ||
225 | } | ||
226 | |||
169 | ssize_t | 227 | ssize_t |
170 | vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) | 228 | vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) |
171 | { | 229 | { |