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