xref: /linux/fs/f2fs/xattr.c (revision 861e10be08c69808065d755d3e3cab5d520a2d32)
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 	name_len = strlen(name);
314 
315 	if (value == NULL)
316 		value_len = 0;
317 
318 	if (name_len > 255 || value_len > MAX_VALUE_LEN)
319 		return -ERANGE;
320 
321 	f2fs_balance_fs(sbi);
322 
323 	mutex_lock_op(sbi, NODE_NEW);
324 	if (!fi->i_xattr_nid) {
325 		/* Allocate new attribute block */
326 		struct dnode_of_data dn;
327 
328 		if (!alloc_nid(sbi, &fi->i_xattr_nid)) {
329 			mutex_unlock_op(sbi, NODE_NEW);
330 			return -ENOSPC;
331 		}
332 		set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
333 		mark_inode_dirty(inode);
334 
335 		page = new_node_page(&dn, XATTR_NODE_OFFSET);
336 		if (IS_ERR(page)) {
337 			alloc_nid_failed(sbi, fi->i_xattr_nid);
338 			fi->i_xattr_nid = 0;
339 			mutex_unlock_op(sbi, NODE_NEW);
340 			return PTR_ERR(page);
341 		}
342 
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);
348 	} else {
349 		/* The inode already has an extended attribute block. */
350 		page = get_node_page(sbi, fi->i_xattr_nid);
351 		if (IS_ERR(page)) {
352 			mutex_unlock_op(sbi, NODE_NEW);
353 			return PTR_ERR(page);
354 		}
355 
356 		base_addr = page_address(page);
357 		header = XATTR_HDR(base_addr);
358 	}
359 
360 	if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
361 		error = -EIO;
362 		goto cleanup;
363 	}
364 
365 	/* find entry with wanted name. */
366 	found = 0;
367 	list_for_each_xattr(here, base_addr) {
368 		if (here->e_name_index != name_index)
369 			continue;
370 		if (here->e_name_len != name_len)
371 			continue;
372 		if (!memcmp(here->e_name, name, name_len)) {
373 			found = 1;
374 			break;
375 		}
376 	}
377 
378 	last = here;
379 
380 	while (!IS_XATTR_LAST_ENTRY(last))
381 		last = XATTR_NEXT_ENTRY(last);
382 
383 	newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) +
384 			name_len + value_len);
385 
386 	/* 1. Check space */
387 	if (value) {
388 		/* If value is NULL, it is remove operation.
389 		 * In case of update operation, we caculate free.
390 		 */
391 		free = MIN_OFFSET - ((char *)last - (char *)header);
392 		if (found)
393 			free = free - ENTRY_SIZE(here);
394 
395 		if (free < newsize) {
396 			error = -ENOSPC;
397 			goto cleanup;
398 		}
399 	}
400 
401 	/* 2. Remove old entry */
402 	if (found) {
403 		/* If entry is found, remove old entry.
404 		 * If not found, remove operation is not needed.
405 		 */
406 		struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
407 		int oldsize = ENTRY_SIZE(here);
408 
409 		memmove(here, next, (char *)last - (char *)next);
410 		last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
411 		memset(last, 0, oldsize);
412 	}
413 
414 	/* 3. Write new entry */
415 	if (value) {
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);
425 	}
426 
427 	set_page_dirty(page);
428 	f2fs_put_page(page, 1);
429 
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);
434 	}
435 	f2fs_write_inode(inode, NULL);
436 	mutex_unlock_op(sbi, NODE_NEW);
437 
438 	return 0;
439 cleanup:
440 	f2fs_put_page(page, 1);
441 	mutex_unlock_op(sbi, NODE_NEW);
442 	return error;
443 }
444