]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - fs/f2fs/xattr.c
regmap: debugfs: Fix seeking from the cache
[karo-tx-linux.git] / fs / f2fs / xattr.c
1 /*
2  * fs/f2fs/xattr.c
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5  *             http://www.samsung.com/
6  *
7  * Portions of this code from linux/fs/ext2/xattr.c
8  *
9  * Copyright (C) 2001-2003 Andreas Gruenbacher <agruen@suse.de>
10  *
11  * Fix by Harrison Xing <harrison@mountainviewdata.com>.
12  * Extended attributes for symlinks and special files added per
13  *  suggestion of Luka Renko <luka.renko@hermes.si>.
14  * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
15  *  Red Hat Inc.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License version 2 as
19  * published by the Free Software Foundation.
20  */
21 #include <linux/rwsem.h>
22 #include <linux/f2fs_fs.h>
23 #include "f2fs.h"
24 #include "xattr.h"
25
26 static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list,
27                 size_t list_size, const char *name, size_t name_len, int type)
28 {
29         struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
30         int total_len, prefix_len = 0;
31         const char *prefix = NULL;
32
33         switch (type) {
34         case F2FS_XATTR_INDEX_USER:
35                 if (!test_opt(sbi, XATTR_USER))
36                         return -EOPNOTSUPP;
37                 prefix = XATTR_USER_PREFIX;
38                 prefix_len = XATTR_USER_PREFIX_LEN;
39                 break;
40         case F2FS_XATTR_INDEX_TRUSTED:
41                 if (!capable(CAP_SYS_ADMIN))
42                         return -EPERM;
43                 prefix = XATTR_TRUSTED_PREFIX;
44                 prefix_len = XATTR_TRUSTED_PREFIX_LEN;
45                 break;
46         default:
47                 return -EINVAL;
48         }
49
50         total_len = prefix_len + name_len + 1;
51         if (list && total_len <= list_size) {
52                 memcpy(list, prefix, prefix_len);
53                 memcpy(list+prefix_len, name, name_len);
54                 list[prefix_len + name_len] = '\0';
55         }
56         return total_len;
57 }
58
59 static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name,
60                 void *buffer, size_t size, int type)
61 {
62         struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
63
64         switch (type) {
65         case F2FS_XATTR_INDEX_USER:
66                 if (!test_opt(sbi, XATTR_USER))
67                         return -EOPNOTSUPP;
68                 break;
69         case F2FS_XATTR_INDEX_TRUSTED:
70                 if (!capable(CAP_SYS_ADMIN))
71                         return -EPERM;
72                 break;
73         default:
74                 return -EINVAL;
75         }
76         if (strcmp(name, "") == 0)
77                 return -EINVAL;
78         return f2fs_getxattr(dentry->d_inode, type, name,
79                         buffer, size);
80 }
81
82 static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
83                 const void *value, size_t size, int flags, int type)
84 {
85         struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
86
87         switch (type) {
88         case F2FS_XATTR_INDEX_USER:
89                 if (!test_opt(sbi, XATTR_USER))
90                         return -EOPNOTSUPP;
91                 break;
92         case F2FS_XATTR_INDEX_TRUSTED:
93                 if (!capable(CAP_SYS_ADMIN))
94                         return -EPERM;
95                 break;
96         default:
97                 return -EINVAL;
98         }
99         if (strcmp(name, "") == 0)
100                 return -EINVAL;
101
102         return f2fs_setxattr(dentry->d_inode, type, name, value, size);
103 }
104
105 static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list,
106                 size_t list_size, const char *name, size_t name_len, int type)
107 {
108         const char *xname = F2FS_SYSTEM_ADVISE_PREFIX;
109         size_t size;
110
111         if (type != F2FS_XATTR_INDEX_ADVISE)
112                 return 0;
113
114         size = strlen(xname) + 1;
115         if (list && size <= list_size)
116                 memcpy(list, xname, size);
117         return size;
118 }
119
120 static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name,
121                 void *buffer, size_t size, int type)
122 {
123         struct inode *inode = dentry->d_inode;
124
125         if (strcmp(name, "") != 0)
126                 return -EINVAL;
127
128         *((char *)buffer) = F2FS_I(inode)->i_advise;
129         return sizeof(char);
130 }
131
132 static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name,
133                 const void *value, size_t size, int flags, int type)
134 {
135         struct inode *inode = dentry->d_inode;
136
137         if (strcmp(name, "") != 0)
138                 return -EINVAL;
139         if (!inode_owner_or_capable(inode))
140                 return -EPERM;
141         if (value == NULL)
142                 return -EINVAL;
143
144         F2FS_I(inode)->i_advise |= *(char *)value;
145         return 0;
146 }
147
148 const struct xattr_handler f2fs_xattr_user_handler = {
149         .prefix = XATTR_USER_PREFIX,
150         .flags  = F2FS_XATTR_INDEX_USER,
151         .list   = f2fs_xattr_generic_list,
152         .get    = f2fs_xattr_generic_get,
153         .set    = f2fs_xattr_generic_set,
154 };
155
156 const struct xattr_handler f2fs_xattr_trusted_handler = {
157         .prefix = XATTR_TRUSTED_PREFIX,
158         .flags  = F2FS_XATTR_INDEX_TRUSTED,
159         .list   = f2fs_xattr_generic_list,
160         .get    = f2fs_xattr_generic_get,
161         .set    = f2fs_xattr_generic_set,
162 };
163
164 const struct xattr_handler f2fs_xattr_advise_handler = {
165         .prefix = F2FS_SYSTEM_ADVISE_PREFIX,
166         .flags  = F2FS_XATTR_INDEX_ADVISE,
167         .list   = f2fs_xattr_advise_list,
168         .get    = f2fs_xattr_advise_get,
169         .set    = f2fs_xattr_advise_set,
170 };
171
172 static const struct xattr_handler *f2fs_xattr_handler_map[] = {
173         [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
174 #ifdef CONFIG_F2FS_FS_POSIX_ACL
175         [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &f2fs_xattr_acl_access_handler,
176         [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
177 #endif
178         [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
179         [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
180 };
181
182 const struct xattr_handler *f2fs_xattr_handlers[] = {
183         &f2fs_xattr_user_handler,
184 #ifdef CONFIG_F2FS_FS_POSIX_ACL
185         &f2fs_xattr_acl_access_handler,
186         &f2fs_xattr_acl_default_handler,
187 #endif
188         &f2fs_xattr_trusted_handler,
189         &f2fs_xattr_advise_handler,
190         NULL,
191 };
192
193 static inline const struct xattr_handler *f2fs_xattr_handler(int name_index)
194 {
195         const struct xattr_handler *handler = NULL;
196
197         if (name_index > 0 && name_index < ARRAY_SIZE(f2fs_xattr_handler_map))
198                 handler = f2fs_xattr_handler_map[name_index];
199         return handler;
200 }
201
202 int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
203                 void *buffer, size_t buffer_size)
204 {
205         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
206         struct f2fs_inode_info *fi = F2FS_I(inode);
207         struct f2fs_xattr_entry *entry;
208         struct page *page;
209         void *base_addr;
210         int error = 0, found = 0;
211         int value_len, name_len;
212
213         if (name == NULL)
214                 return -EINVAL;
215         name_len = strlen(name);
216
217         if (!fi->i_xattr_nid)
218                 return -ENODATA;
219
220         page = get_node_page(sbi, fi->i_xattr_nid);
221         base_addr = page_address(page);
222
223         list_for_each_xattr(entry, base_addr) {
224                 if (entry->e_name_index != name_index)
225                         continue;
226                 if (entry->e_name_len != name_len)
227                         continue;
228                 if (!memcmp(entry->e_name, name, name_len)) {
229                         found = 1;
230                         break;
231                 }
232         }
233         if (!found) {
234                 error = -ENODATA;
235                 goto cleanup;
236         }
237
238         value_len = le16_to_cpu(entry->e_value_size);
239
240         if (buffer && value_len > buffer_size) {
241                 error = -ERANGE;
242                 goto cleanup;
243         }
244
245         if (buffer) {
246                 char *pval = entry->e_name + entry->e_name_len;
247                 memcpy(buffer, pval, value_len);
248         }
249         error = value_len;
250
251 cleanup:
252         f2fs_put_page(page, 1);
253         return error;
254 }
255
256 ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
257 {
258         struct inode *inode = dentry->d_inode;
259         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
260         struct f2fs_inode_info *fi = F2FS_I(inode);
261         struct f2fs_xattr_entry *entry;
262         struct page *page;
263         void *base_addr;
264         int error = 0;
265         size_t rest = buffer_size;
266
267         if (!fi->i_xattr_nid)
268                 return 0;
269
270         page = get_node_page(sbi, fi->i_xattr_nid);
271         base_addr = page_address(page);
272
273         list_for_each_xattr(entry, base_addr) {
274                 const struct xattr_handler *handler =
275                         f2fs_xattr_handler(entry->e_name_index);
276                 size_t size;
277
278                 if (!handler)
279                         continue;
280
281                 size = handler->list(dentry, buffer, rest, entry->e_name,
282                                 entry->e_name_len, handler->flags);
283                 if (buffer && size > rest) {
284                         error = -ERANGE;
285                         goto cleanup;
286                 }
287
288                 if (buffer)
289                         buffer += size;
290                 rest -= size;
291         }
292         error = buffer_size - rest;
293 cleanup:
294         f2fs_put_page(page, 1);
295         return error;
296 }
297
298 int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
299                                         const void *value, size_t value_len)
300 {
301         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
302         struct f2fs_inode_info *fi = F2FS_I(inode);
303         struct f2fs_xattr_header *header = NULL;
304         struct f2fs_xattr_entry *here, *last;
305         struct page *page;
306         void *base_addr;
307         int error, found, free, name_len, newsize;
308         char *pval;
309
310         if (name == NULL)
311                 return -EINVAL;
312         name_len = strlen(name);
313
314         if (value == NULL)
315                 value_len = 0;
316
317         if (name_len > 255 || value_len > MAX_VALUE_LEN)
318                 return -ERANGE;
319
320         mutex_lock_op(sbi, NODE_NEW);
321         if (!fi->i_xattr_nid) {
322                 /* Allocate new attribute block */
323                 struct dnode_of_data dn;
324
325                 if (!alloc_nid(sbi, &fi->i_xattr_nid)) {
326                         mutex_unlock_op(sbi, NODE_NEW);
327                         return -ENOSPC;
328                 }
329                 set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
330                 mark_inode_dirty(inode);
331
332                 page = new_node_page(&dn, XATTR_NODE_OFFSET);
333                 if (IS_ERR(page)) {
334                         alloc_nid_failed(sbi, fi->i_xattr_nid);
335                         fi->i_xattr_nid = 0;
336                         mutex_unlock_op(sbi, NODE_NEW);
337                         return PTR_ERR(page);
338                 }
339
340                 alloc_nid_done(sbi, fi->i_xattr_nid);
341                 base_addr = page_address(page);
342                 header = XATTR_HDR(base_addr);
343                 header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
344                 header->h_refcount = cpu_to_le32(1);
345         } else {
346                 /* The inode already has an extended attribute block. */
347                 page = get_node_page(sbi, fi->i_xattr_nid);
348                 if (IS_ERR(page)) {
349                         mutex_unlock_op(sbi, NODE_NEW);
350                         return PTR_ERR(page);
351                 }
352
353                 base_addr = page_address(page);
354                 header = XATTR_HDR(base_addr);
355         }
356
357         if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
358                 error = -EIO;
359                 goto cleanup;
360         }
361
362         /* find entry with wanted name. */
363         found = 0;
364         list_for_each_xattr(here, base_addr) {
365                 if (here->e_name_index != name_index)
366                         continue;
367                 if (here->e_name_len != name_len)
368                         continue;
369                 if (!memcmp(here->e_name, name, name_len)) {
370                         found = 1;
371                         break;
372                 }
373         }
374
375         last = here;
376
377         while (!IS_XATTR_LAST_ENTRY(last))
378                 last = XATTR_NEXT_ENTRY(last);
379
380         newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) +
381                         name_len + value_len);
382
383         /* 1. Check space */
384         if (value) {
385                 /* If value is NULL, it is remove operation.
386                  * In case of update operation, we caculate free.
387                  */
388                 free = MIN_OFFSET - ((char *)last - (char *)header);
389                 if (found)
390                         free = free - ENTRY_SIZE(here);
391
392                 if (free < newsize) {
393                         error = -ENOSPC;
394                         goto cleanup;
395                 }
396         }
397
398         /* 2. Remove old entry */
399         if (found) {
400                 /* If entry is found, remove old entry.
401                  * If not found, remove operation is not needed.
402                  */
403                 struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
404                 int oldsize = ENTRY_SIZE(here);
405
406                 memmove(here, next, (char *)last - (char *)next);
407                 last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
408                 memset(last, 0, oldsize);
409         }
410
411         /* 3. Write new entry */
412         if (value) {
413                 /* Before we come here, old entry is removed.
414                  * We just write new entry. */
415                 memset(last, 0, newsize);
416                 last->e_name_index = name_index;
417                 last->e_name_len = name_len;
418                 memcpy(last->e_name, name, name_len);
419                 pval = last->e_name + name_len;
420                 memcpy(pval, value, value_len);
421                 last->e_value_size = cpu_to_le16(value_len);
422         }
423
424         set_page_dirty(page);
425         f2fs_put_page(page, 1);
426
427         if (is_inode_flag_set(fi, FI_ACL_MODE)) {
428                 inode->i_mode = fi->i_acl_mode;
429                 inode->i_ctime = CURRENT_TIME;
430                 clear_inode_flag(fi, FI_ACL_MODE);
431         }
432         f2fs_write_inode(inode, NULL);
433         mutex_unlock_op(sbi, NODE_NEW);
434
435         return 0;
436 cleanup:
437         f2fs_put_page(page, 1);
438         mutex_unlock_op(sbi, NODE_NEW);
439         return error;
440 }