f2fs: reorganize f2fs_setxattr
[platform/adaptation/renesas_rcar/renesas_kernel.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         size_t 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, newsize;
308         size_t name_len;
309         char *pval;
310
311         if (name == NULL)
312                 return -EINVAL;
313
314         if (value == NULL)
315                 value_len = 0;
316
317         name_len = strlen(name);
318
319         if (name_len > F2FS_NAME_LEN || value_len > MAX_VALUE_LEN)
320                 return -ERANGE;
321
322         f2fs_balance_fs(sbi);
323
324         mutex_lock_op(sbi, NODE_NEW);
325         if (!fi->i_xattr_nid) {
326                 /* Allocate new attribute block */
327                 struct dnode_of_data dn;
328
329                 if (!alloc_nid(sbi, &fi->i_xattr_nid)) {
330                         error = -ENOSPC;
331                         goto exit;
332                 }
333                 set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
334                 mark_inode_dirty(inode);
335
336                 page = new_node_page(&dn, XATTR_NODE_OFFSET);
337                 if (IS_ERR(page)) {
338                         alloc_nid_failed(sbi, fi->i_xattr_nid);
339                         fi->i_xattr_nid = 0;
340                         error = PTR_ERR(page);
341                         goto exit;
342                 }
343
344                 alloc_nid_done(sbi, fi->i_xattr_nid);
345                 base_addr = page_address(page);
346                 header = XATTR_HDR(base_addr);
347                 header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
348                 header->h_refcount = cpu_to_le32(1);
349         } else {
350                 /* The inode already has an extended attribute block. */
351                 page = get_node_page(sbi, fi->i_xattr_nid);
352                 if (IS_ERR(page)) {
353                         error = PTR_ERR(page);
354                         goto exit;
355                 }
356
357                 base_addr = page_address(page);
358                 header = XATTR_HDR(base_addr);
359         }
360
361         if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
362                 error = -EIO;
363                 goto cleanup;
364         }
365
366         /* find entry with wanted name. */
367         found = 0;
368         list_for_each_xattr(here, base_addr) {
369                 if (here->e_name_index != name_index)
370                         continue;
371                 if (here->e_name_len != name_len)
372                         continue;
373                 if (!memcmp(here->e_name, name, name_len)) {
374                         found = 1;
375                         break;
376                 }
377         }
378
379         last = here;
380
381         while (!IS_XATTR_LAST_ENTRY(last))
382                 last = XATTR_NEXT_ENTRY(last);
383
384         newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) +
385                         name_len + value_len);
386
387         /* 1. Check space */
388         if (value) {
389                 /* If value is NULL, it is remove operation.
390                  * In case of update operation, we caculate free.
391                  */
392                 free = MIN_OFFSET - ((char *)last - (char *)header);
393                 if (found)
394                         free = free - ENTRY_SIZE(here);
395
396                 if (free < newsize) {
397                         error = -ENOSPC;
398                         goto cleanup;
399                 }
400         }
401
402         /* 2. Remove old entry */
403         if (found) {
404                 /* If entry is found, remove old entry.
405                  * If not found, remove operation is not needed.
406                  */
407                 struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
408                 int oldsize = ENTRY_SIZE(here);
409
410                 memmove(here, next, (char *)last - (char *)next);
411                 last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
412                 memset(last, 0, oldsize);
413         }
414
415         /* 3. Write new entry */
416         if (value) {
417                 /* Before we come here, old entry is removed.
418                  * We just write new entry. */
419                 memset(last, 0, newsize);
420                 last->e_name_index = name_index;
421                 last->e_name_len = name_len;
422                 memcpy(last->e_name, name, name_len);
423                 pval = last->e_name + name_len;
424                 memcpy(pval, value, value_len);
425                 last->e_value_size = cpu_to_le16(value_len);
426         }
427
428         set_page_dirty(page);
429         f2fs_put_page(page, 1);
430
431         if (is_inode_flag_set(fi, FI_ACL_MODE)) {
432                 inode->i_mode = fi->i_acl_mode;
433                 inode->i_ctime = CURRENT_TIME;
434                 clear_inode_flag(fi, FI_ACL_MODE);
435         }
436         f2fs_write_inode(inode, NULL);
437         mutex_unlock_op(sbi, NODE_NEW);
438
439         return 0;
440 cleanup:
441         f2fs_put_page(page, 1);
442 exit:
443         mutex_unlock_op(sbi, NODE_NEW);
444         return error;
445 }