f2fs: add xattr and acl functionalities
[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 const struct xattr_handler f2fs_xattr_user_handler = {
106         .prefix = XATTR_USER_PREFIX,
107         .flags  = F2FS_XATTR_INDEX_USER,
108         .list   = f2fs_xattr_generic_list,
109         .get    = f2fs_xattr_generic_get,
110         .set    = f2fs_xattr_generic_set,
111 };
112
113 const struct xattr_handler f2fs_xattr_trusted_handler = {
114         .prefix = XATTR_TRUSTED_PREFIX,
115         .flags  = F2FS_XATTR_INDEX_TRUSTED,
116         .list   = f2fs_xattr_generic_list,
117         .get    = f2fs_xattr_generic_get,
118         .set    = f2fs_xattr_generic_set,
119 };
120
121 static const struct xattr_handler *f2fs_xattr_handler_map[] = {
122         [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
123 #ifdef CONFIG_F2FS_FS_POSIX_ACL
124         [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &f2fs_xattr_acl_access_handler,
125         [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
126 #endif
127         [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
128         [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
129 };
130
131 const struct xattr_handler *f2fs_xattr_handlers[] = {
132         &f2fs_xattr_user_handler,
133 #ifdef CONFIG_F2FS_FS_POSIX_ACL
134         &f2fs_xattr_acl_access_handler,
135         &f2fs_xattr_acl_default_handler,
136 #endif
137         &f2fs_xattr_trusted_handler,
138         &f2fs_xattr_advise_handler,
139         NULL,
140 };
141
142 static inline const struct xattr_handler *f2fs_xattr_handler(int name_index)
143 {
144         const struct xattr_handler *handler = NULL;
145
146         if (name_index > 0 && name_index < ARRAY_SIZE(f2fs_xattr_handler_map))
147                 handler = f2fs_xattr_handler_map[name_index];
148         return handler;
149 }
150
151 int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
152                 void *buffer, size_t buffer_size)
153 {
154         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
155         struct f2fs_inode_info *fi = F2FS_I(inode);
156         struct f2fs_xattr_entry *entry;
157         struct page *page;
158         void *base_addr;
159         int error = 0, found = 0;
160         int value_len, name_len;
161
162         if (name == NULL)
163                 return -EINVAL;
164         name_len = strlen(name);
165
166         if (!fi->i_xattr_nid)
167                 return -ENODATA;
168
169         page = get_node_page(sbi, fi->i_xattr_nid);
170         base_addr = page_address(page);
171
172         list_for_each_xattr(entry, base_addr) {
173                 if (entry->e_name_index != name_index)
174                         continue;
175                 if (entry->e_name_len != name_len)
176                         continue;
177                 if (!memcmp(entry->e_name, name, name_len)) {
178                         found = 1;
179                         break;
180                 }
181         }
182         if (!found) {
183                 error = -ENODATA;
184                 goto cleanup;
185         }
186
187         value_len = le16_to_cpu(entry->e_value_size);
188
189         if (buffer && value_len > buffer_size) {
190                 error = -ERANGE;
191                 goto cleanup;
192         }
193
194         if (buffer) {
195                 char *pval = entry->e_name + entry->e_name_len;
196                 memcpy(buffer, pval, value_len);
197         }
198         error = value_len;
199
200 cleanup:
201         f2fs_put_page(page, 1);
202         return error;
203 }
204
205 ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
206 {
207         struct inode *inode = dentry->d_inode;
208         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
209         struct f2fs_inode_info *fi = F2FS_I(inode);
210         struct f2fs_xattr_entry *entry;
211         struct page *page;
212         void *base_addr;
213         int error = 0;
214         size_t rest = buffer_size;
215
216         if (!fi->i_xattr_nid)
217                 return 0;
218
219         page = get_node_page(sbi, fi->i_xattr_nid);
220         base_addr = page_address(page);
221
222         list_for_each_xattr(entry, base_addr) {
223                 const struct xattr_handler *handler =
224                         f2fs_xattr_handler(entry->e_name_index);
225                 size_t size;
226
227                 if (!handler)
228                         continue;
229
230                 size = handler->list(dentry, buffer, rest, entry->e_name,
231                                 entry->e_name_len, handler->flags);
232                 if (buffer && size > rest) {
233                         error = -ERANGE;
234                         goto cleanup;
235                 }
236
237                 if (buffer)
238                         buffer += size;
239                 rest -= size;
240         }
241         error = buffer_size - rest;
242 cleanup:
243         f2fs_put_page(page, 1);
244         return error;
245 }
246
247 int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
248                                         const void *value, size_t value_len)
249 {
250         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
251         struct f2fs_inode_info *fi = F2FS_I(inode);
252         struct f2fs_xattr_header *header = NULL;
253         struct f2fs_xattr_entry *here, *last;
254         struct page *page;
255         void *base_addr;
256         int error, found, free, name_len, newsize;
257         char *pval;
258
259         if (name == NULL)
260                 return -EINVAL;
261         name_len = strlen(name);
262
263         if (value == NULL)
264                 value_len = 0;
265
266         if (name_len > 255 || value_len > MAX_VALUE_LEN)
267                 return -ERANGE;
268
269         mutex_lock_op(sbi, NODE_NEW);
270         if (!fi->i_xattr_nid) {
271                 /* Allocate new attribute block */
272                 struct dnode_of_data dn;
273
274                 if (!alloc_nid(sbi, &fi->i_xattr_nid)) {
275                         mutex_unlock_op(sbi, NODE_NEW);
276                         return -ENOSPC;
277                 }
278                 set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
279                 mark_inode_dirty(inode);
280
281                 page = new_node_page(&dn, XATTR_NODE_OFFSET);
282                 if (IS_ERR(page)) {
283                         alloc_nid_failed(sbi, fi->i_xattr_nid);
284                         fi->i_xattr_nid = 0;
285                         mutex_unlock_op(sbi, NODE_NEW);
286                         return PTR_ERR(page);
287                 }
288
289                 alloc_nid_done(sbi, fi->i_xattr_nid);
290                 base_addr = page_address(page);
291                 header = XATTR_HDR(base_addr);
292                 header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
293                 header->h_refcount = cpu_to_le32(1);
294         } else {
295                 /* The inode already has an extended attribute block. */
296                 page = get_node_page(sbi, fi->i_xattr_nid);
297                 if (IS_ERR(page)) {
298                         mutex_unlock_op(sbi, NODE_NEW);
299                         return PTR_ERR(page);
300                 }
301
302                 base_addr = page_address(page);
303                 header = XATTR_HDR(base_addr);
304         }
305
306         if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
307                 error = -EIO;
308                 goto cleanup;
309         }
310
311         /* find entry with wanted name. */
312         found = 0;
313         list_for_each_xattr(here, base_addr) {
314                 if (here->e_name_index != name_index)
315                         continue;
316                 if (here->e_name_len != name_len)
317                         continue;
318                 if (!memcmp(here->e_name, name, name_len)) {
319                         found = 1;
320                         break;
321                 }
322         }
323
324         last = here;
325
326         while (!IS_XATTR_LAST_ENTRY(last))
327                 last = XATTR_NEXT_ENTRY(last);
328
329         newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) +
330                         name_len + value_len);
331
332         /* 1. Check space */
333         if (value) {
334                 /* If value is NULL, it is remove operation.
335                  * In case of update operation, we caculate free.
336                  */
337                 free = MIN_OFFSET - ((char *)last - (char *)header);
338                 if (found)
339                         free = free - ENTRY_SIZE(here);
340
341                 if (free < newsize) {
342                         error = -ENOSPC;
343                         goto cleanup;
344                 }
345         }
346
347         /* 2. Remove old entry */
348         if (found) {
349                 /* If entry is found, remove old entry.
350                  * If not found, remove operation is not needed.
351                  */
352                 struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
353                 int oldsize = ENTRY_SIZE(here);
354
355                 memmove(here, next, (char *)last - (char *)next);
356                 last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
357                 memset(last, 0, oldsize);
358         }
359
360         /* 3. Write new entry */
361         if (value) {
362                 /* Before we come here, old entry is removed.
363                  * We just write new entry. */
364                 memset(last, 0, newsize);
365                 last->e_name_index = name_index;
366                 last->e_name_len = name_len;
367                 memcpy(last->e_name, name, name_len);
368                 pval = last->e_name + name_len;
369                 memcpy(pval, value, value_len);
370                 last->e_value_size = cpu_to_le16(value_len);
371         }
372
373         set_page_dirty(page);
374         f2fs_put_page(page, 1);
375
376         if (is_inode_flag_set(fi, FI_ACL_MODE)) {
377                 inode->i_mode = fi->i_acl_mode;
378                 inode->i_ctime = CURRENT_TIME;
379                 clear_inode_flag(fi, FI_ACL_MODE);
380         }
381         f2fs_write_inode(inode, NULL);
382         mutex_unlock_op(sbi, NODE_NEW);
383
384         return 0;
385 cleanup:
386         f2fs_put_page(page, 1);
387         mutex_unlock_op(sbi, NODE_NEW);
388         return error;
389 }