4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
7 * Portions of this code from linux/fs/ext2/xattr.c
9 * Copyright (C) 2001-2003 Andreas Gruenbacher <agruen@suse.de>
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>,
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.
21 #include <linux/rwsem.h>
22 #include <linux/f2fs_fs.h>
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
)
29 struct f2fs_sb_info
*sbi
= F2FS_SB(dentry
->d_sb
);
30 int total_len
, prefix_len
= 0;
31 const char *prefix
= NULL
;
34 case F2FS_XATTR_INDEX_USER
:
35 if (!test_opt(sbi
, XATTR_USER
))
37 prefix
= XATTR_USER_PREFIX
;
38 prefix_len
= XATTR_USER_PREFIX_LEN
;
40 case F2FS_XATTR_INDEX_TRUSTED
:
41 if (!capable(CAP_SYS_ADMIN
))
43 prefix
= XATTR_TRUSTED_PREFIX
;
44 prefix_len
= XATTR_TRUSTED_PREFIX_LEN
;
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';
59 static int f2fs_xattr_generic_get(struct dentry
*dentry
, const char *name
,
60 void *buffer
, size_t size
, int type
)
62 struct f2fs_sb_info
*sbi
= F2FS_SB(dentry
->d_sb
);
65 case F2FS_XATTR_INDEX_USER
:
66 if (!test_opt(sbi
, XATTR_USER
))
69 case F2FS_XATTR_INDEX_TRUSTED
:
70 if (!capable(CAP_SYS_ADMIN
))
76 if (strcmp(name
, "") == 0)
78 return f2fs_getxattr(dentry
->d_inode
, type
, name
,
82 static int f2fs_xattr_generic_set(struct dentry
*dentry
, const char *name
,
83 const void *value
, size_t size
, int flags
, int type
)
85 struct f2fs_sb_info
*sbi
= F2FS_SB(dentry
->d_sb
);
88 case F2FS_XATTR_INDEX_USER
:
89 if (!test_opt(sbi
, XATTR_USER
))
92 case F2FS_XATTR_INDEX_TRUSTED
:
93 if (!capable(CAP_SYS_ADMIN
))
99 if (strcmp(name
, "") == 0)
102 return f2fs_setxattr(dentry
->d_inode
, type
, name
, value
, size
);
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
)
108 const char *xname
= F2FS_SYSTEM_ADVISE_PREFIX
;
111 if (type
!= F2FS_XATTR_INDEX_ADVISE
)
114 size
= strlen(xname
) + 1;
115 if (list
&& size
<= list_size
)
116 memcpy(list
, xname
, size
);
120 static int f2fs_xattr_advise_get(struct dentry
*dentry
, const char *name
,
121 void *buffer
, size_t size
, int type
)
123 struct inode
*inode
= dentry
->d_inode
;
125 if (strcmp(name
, "") != 0)
128 *((char *)buffer
) = F2FS_I(inode
)->i_advise
;
132 static int f2fs_xattr_advise_set(struct dentry
*dentry
, const char *name
,
133 const void *value
, size_t size
, int flags
, int type
)
135 struct inode
*inode
= dentry
->d_inode
;
137 if (strcmp(name
, "") != 0)
139 if (!inode_owner_or_capable(inode
))
144 F2FS_I(inode
)->i_advise
|= *(char *)value
;
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
,
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
,
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
,
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
,
178 [F2FS_XATTR_INDEX_TRUSTED
] = &f2fs_xattr_trusted_handler
,
179 [F2FS_XATTR_INDEX_ADVISE
] = &f2fs_xattr_advise_handler
,
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
,
188 &f2fs_xattr_trusted_handler
,
189 &f2fs_xattr_advise_handler
,
193 static inline const struct xattr_handler
*f2fs_xattr_handler(int name_index
)
195 const struct xattr_handler
*handler
= NULL
;
197 if (name_index
> 0 && name_index
< ARRAY_SIZE(f2fs_xattr_handler_map
))
198 handler
= f2fs_xattr_handler_map
[name_index
];
202 int f2fs_getxattr(struct inode
*inode
, int name_index
, const char *name
,
203 void *buffer
, size_t buffer_size
)
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
;
210 int error
= 0, found
= 0;
211 size_t value_len
, name_len
;
215 name_len
= strlen(name
);
217 if (!fi
->i_xattr_nid
)
220 page
= get_node_page(sbi
, fi
->i_xattr_nid
);
221 base_addr
= page_address(page
);
223 list_for_each_xattr(entry
, base_addr
) {
224 if (entry
->e_name_index
!= name_index
)
226 if (entry
->e_name_len
!= name_len
)
228 if (!memcmp(entry
->e_name
, name
, name_len
)) {
238 value_len
= le16_to_cpu(entry
->e_value_size
);
240 if (buffer
&& value_len
> buffer_size
) {
246 char *pval
= entry
->e_name
+ entry
->e_name_len
;
247 memcpy(buffer
, pval
, value_len
);
252 f2fs_put_page(page
, 1);
256 ssize_t
f2fs_listxattr(struct dentry
*dentry
, char *buffer
, size_t buffer_size
)
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
;
265 size_t rest
= buffer_size
;
267 if (!fi
->i_xattr_nid
)
270 page
= get_node_page(sbi
, fi
->i_xattr_nid
);
271 base_addr
= page_address(page
);
273 list_for_each_xattr(entry
, base_addr
) {
274 const struct xattr_handler
*handler
=
275 f2fs_xattr_handler(entry
->e_name_index
);
281 size
= handler
->list(dentry
, buffer
, rest
, entry
->e_name
,
282 entry
->e_name_len
, handler
->flags
);
283 if (buffer
&& size
> rest
) {
292 error
= buffer_size
- rest
;
294 f2fs_put_page(page
, 1);
298 int f2fs_setxattr(struct inode
*inode
, int name_index
, const char *name
,
299 const void *value
, size_t value_len
)
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
;
307 int error
, found
, free
, newsize
;
313 name_len
= strlen(name
);
318 if (name_len
> 255 || value_len
> MAX_VALUE_LEN
)
321 f2fs_balance_fs(sbi
);
323 mutex_lock_op(sbi
, NODE_NEW
);
324 if (!fi
->i_xattr_nid
) {
325 /* Allocate new attribute block */
326 struct dnode_of_data dn
;
328 if (!alloc_nid(sbi
, &fi
->i_xattr_nid
)) {
329 mutex_unlock_op(sbi
, NODE_NEW
);
332 set_new_dnode(&dn
, inode
, NULL
, NULL
, fi
->i_xattr_nid
);
333 mark_inode_dirty(inode
);
335 page
= new_node_page(&dn
, XATTR_NODE_OFFSET
);
337 alloc_nid_failed(sbi
, fi
->i_xattr_nid
);
339 mutex_unlock_op(sbi
, NODE_NEW
);
340 return PTR_ERR(page
);
343 alloc_nid_done(sbi
, fi
->i_xattr_nid
);
344 base_addr
= page_address(page
);
345 header
= XATTR_HDR(base_addr
);
346 header
->h_magic
= cpu_to_le32(F2FS_XATTR_MAGIC
);
347 header
->h_refcount
= cpu_to_le32(1);
349 /* The inode already has an extended attribute block. */
350 page
= get_node_page(sbi
, fi
->i_xattr_nid
);
352 mutex_unlock_op(sbi
, NODE_NEW
);
353 return PTR_ERR(page
);
356 base_addr
= page_address(page
);
357 header
= XATTR_HDR(base_addr
);
360 if (le32_to_cpu(header
->h_magic
) != F2FS_XATTR_MAGIC
) {
365 /* find entry with wanted name. */
367 list_for_each_xattr(here
, base_addr
) {
368 if (here
->e_name_index
!= name_index
)
370 if (here
->e_name_len
!= name_len
)
372 if (!memcmp(here
->e_name
, name
, name_len
)) {
380 while (!IS_XATTR_LAST_ENTRY(last
))
381 last
= XATTR_NEXT_ENTRY(last
);
383 newsize
= XATTR_ALIGN(sizeof(struct f2fs_xattr_entry
) +
384 name_len
+ value_len
);
388 /* If value is NULL, it is remove operation.
389 * In case of update operation, we caculate free.
391 free
= MIN_OFFSET
- ((char *)last
- (char *)header
);
393 free
= free
- ENTRY_SIZE(here
);
395 if (free
< newsize
) {
401 /* 2. Remove old entry */
403 /* If entry is found, remove old entry.
404 * If not found, remove operation is not needed.
406 struct f2fs_xattr_entry
*next
= XATTR_NEXT_ENTRY(here
);
407 int oldsize
= ENTRY_SIZE(here
);
409 memmove(here
, next
, (char *)last
- (char *)next
);
410 last
= (struct f2fs_xattr_entry
*)((char *)last
- oldsize
);
411 memset(last
, 0, oldsize
);
414 /* 3. Write new entry */
416 /* Before we come here, old entry is removed.
417 * We just write new entry. */
418 memset(last
, 0, newsize
);
419 last
->e_name_index
= name_index
;
420 last
->e_name_len
= name_len
;
421 memcpy(last
->e_name
, name
, name_len
);
422 pval
= last
->e_name
+ name_len
;
423 memcpy(pval
, value
, value_len
);
424 last
->e_value_size
= cpu_to_le16(value_len
);
427 set_page_dirty(page
);
428 f2fs_put_page(page
, 1);
430 if (is_inode_flag_set(fi
, FI_ACL_MODE
)) {
431 inode
->i_mode
= fi
->i_acl_mode
;
432 inode
->i_ctime
= CURRENT_TIME
;
433 clear_inode_flag(fi
, FI_ACL_MODE
);
435 f2fs_write_inode(inode
, NULL
);
436 mutex_unlock_op(sbi
, NODE_NEW
);
440 f2fs_put_page(page
, 1);
441 mutex_unlock_op(sbi
, NODE_NEW
);