xref: /OK3568_Linux_fs/kernel/fs/btrfs/xattr.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2007 Red Hat.  All rights reserved.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/init.h>
7*4882a593Smuzhiyun #include <linux/fs.h>
8*4882a593Smuzhiyun #include <linux/slab.h>
9*4882a593Smuzhiyun #include <linux/rwsem.h>
10*4882a593Smuzhiyun #include <linux/xattr.h>
11*4882a593Smuzhiyun #include <linux/security.h>
12*4882a593Smuzhiyun #include <linux/posix_acl_xattr.h>
13*4882a593Smuzhiyun #include <linux/iversion.h>
14*4882a593Smuzhiyun #include <linux/sched/mm.h>
15*4882a593Smuzhiyun #include "ctree.h"
16*4882a593Smuzhiyun #include "btrfs_inode.h"
17*4882a593Smuzhiyun #include "transaction.h"
18*4882a593Smuzhiyun #include "xattr.h"
19*4882a593Smuzhiyun #include "disk-io.h"
20*4882a593Smuzhiyun #include "props.h"
21*4882a593Smuzhiyun #include "locking.h"
22*4882a593Smuzhiyun 
btrfs_getxattr(struct inode * inode,const char * name,void * buffer,size_t size)23*4882a593Smuzhiyun int btrfs_getxattr(struct inode *inode, const char *name,
24*4882a593Smuzhiyun 				void *buffer, size_t size)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	struct btrfs_dir_item *di;
27*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
28*4882a593Smuzhiyun 	struct btrfs_path *path;
29*4882a593Smuzhiyun 	struct extent_buffer *leaf;
30*4882a593Smuzhiyun 	int ret = 0;
31*4882a593Smuzhiyun 	unsigned long data_ptr;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	path = btrfs_alloc_path();
34*4882a593Smuzhiyun 	if (!path)
35*4882a593Smuzhiyun 		return -ENOMEM;
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	/* lookup the xattr by name */
38*4882a593Smuzhiyun 	di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(BTRFS_I(inode)),
39*4882a593Smuzhiyun 			name, strlen(name), 0);
40*4882a593Smuzhiyun 	if (!di) {
41*4882a593Smuzhiyun 		ret = -ENODATA;
42*4882a593Smuzhiyun 		goto out;
43*4882a593Smuzhiyun 	} else if (IS_ERR(di)) {
44*4882a593Smuzhiyun 		ret = PTR_ERR(di);
45*4882a593Smuzhiyun 		goto out;
46*4882a593Smuzhiyun 	}
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	leaf = path->nodes[0];
49*4882a593Smuzhiyun 	/* if size is 0, that means we want the size of the attr */
50*4882a593Smuzhiyun 	if (!size) {
51*4882a593Smuzhiyun 		ret = btrfs_dir_data_len(leaf, di);
52*4882a593Smuzhiyun 		goto out;
53*4882a593Smuzhiyun 	}
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	/* now get the data out of our dir_item */
56*4882a593Smuzhiyun 	if (btrfs_dir_data_len(leaf, di) > size) {
57*4882a593Smuzhiyun 		ret = -ERANGE;
58*4882a593Smuzhiyun 		goto out;
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	/*
62*4882a593Smuzhiyun 	 * The way things are packed into the leaf is like this
63*4882a593Smuzhiyun 	 * |struct btrfs_dir_item|name|data|
64*4882a593Smuzhiyun 	 * where name is the xattr name, so security.foo, and data is the
65*4882a593Smuzhiyun 	 * content of the xattr.  data_ptr points to the location in memory
66*4882a593Smuzhiyun 	 * where the data starts in the in memory leaf
67*4882a593Smuzhiyun 	 */
68*4882a593Smuzhiyun 	data_ptr = (unsigned long)((char *)(di + 1) +
69*4882a593Smuzhiyun 				   btrfs_dir_name_len(leaf, di));
70*4882a593Smuzhiyun 	read_extent_buffer(leaf, buffer, data_ptr,
71*4882a593Smuzhiyun 			   btrfs_dir_data_len(leaf, di));
72*4882a593Smuzhiyun 	ret = btrfs_dir_data_len(leaf, di);
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun out:
75*4882a593Smuzhiyun 	btrfs_free_path(path);
76*4882a593Smuzhiyun 	return ret;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
btrfs_setxattr(struct btrfs_trans_handle * trans,struct inode * inode,const char * name,const void * value,size_t size,int flags)79*4882a593Smuzhiyun int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
80*4882a593Smuzhiyun 		   const char *name, const void *value, size_t size, int flags)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	struct btrfs_dir_item *di = NULL;
83*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
84*4882a593Smuzhiyun 	struct btrfs_fs_info *fs_info = root->fs_info;
85*4882a593Smuzhiyun 	struct btrfs_path *path;
86*4882a593Smuzhiyun 	size_t name_len = strlen(name);
87*4882a593Smuzhiyun 	int ret = 0;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	ASSERT(trans);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	if (name_len + size > BTRFS_MAX_XATTR_SIZE(root->fs_info))
92*4882a593Smuzhiyun 		return -ENOSPC;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	path = btrfs_alloc_path();
95*4882a593Smuzhiyun 	if (!path)
96*4882a593Smuzhiyun 		return -ENOMEM;
97*4882a593Smuzhiyun 	path->skip_release_on_error = 1;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	if (!value) {
100*4882a593Smuzhiyun 		di = btrfs_lookup_xattr(trans, root, path,
101*4882a593Smuzhiyun 				btrfs_ino(BTRFS_I(inode)), name, name_len, -1);
102*4882a593Smuzhiyun 		if (!di && (flags & XATTR_REPLACE))
103*4882a593Smuzhiyun 			ret = -ENODATA;
104*4882a593Smuzhiyun 		else if (IS_ERR(di))
105*4882a593Smuzhiyun 			ret = PTR_ERR(di);
106*4882a593Smuzhiyun 		else if (di)
107*4882a593Smuzhiyun 			ret = btrfs_delete_one_dir_name(trans, root, path, di);
108*4882a593Smuzhiyun 		goto out;
109*4882a593Smuzhiyun 	}
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	/*
112*4882a593Smuzhiyun 	 * For a replace we can't just do the insert blindly.
113*4882a593Smuzhiyun 	 * Do a lookup first (read-only btrfs_search_slot), and return if xattr
114*4882a593Smuzhiyun 	 * doesn't exist. If it exists, fall down below to the insert/replace
115*4882a593Smuzhiyun 	 * path - we can't race with a concurrent xattr delete, because the VFS
116*4882a593Smuzhiyun 	 * locks the inode's i_mutex before calling setxattr or removexattr.
117*4882a593Smuzhiyun 	 */
118*4882a593Smuzhiyun 	if (flags & XATTR_REPLACE) {
119*4882a593Smuzhiyun 		ASSERT(inode_is_locked(inode));
120*4882a593Smuzhiyun 		di = btrfs_lookup_xattr(NULL, root, path,
121*4882a593Smuzhiyun 				btrfs_ino(BTRFS_I(inode)), name, name_len, 0);
122*4882a593Smuzhiyun 		if (!di)
123*4882a593Smuzhiyun 			ret = -ENODATA;
124*4882a593Smuzhiyun 		else if (IS_ERR(di))
125*4882a593Smuzhiyun 			ret = PTR_ERR(di);
126*4882a593Smuzhiyun 		if (ret)
127*4882a593Smuzhiyun 			goto out;
128*4882a593Smuzhiyun 		btrfs_release_path(path);
129*4882a593Smuzhiyun 		di = NULL;
130*4882a593Smuzhiyun 	}
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(BTRFS_I(inode)),
133*4882a593Smuzhiyun 				      name, name_len, value, size);
134*4882a593Smuzhiyun 	if (ret == -EOVERFLOW) {
135*4882a593Smuzhiyun 		/*
136*4882a593Smuzhiyun 		 * We have an existing item in a leaf, split_leaf couldn't
137*4882a593Smuzhiyun 		 * expand it. That item might have or not a dir_item that
138*4882a593Smuzhiyun 		 * matches our target xattr, so lets check.
139*4882a593Smuzhiyun 		 */
140*4882a593Smuzhiyun 		ret = 0;
141*4882a593Smuzhiyun 		btrfs_assert_tree_locked(path->nodes[0]);
142*4882a593Smuzhiyun 		di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
143*4882a593Smuzhiyun 		if (!di && !(flags & XATTR_REPLACE)) {
144*4882a593Smuzhiyun 			ret = -ENOSPC;
145*4882a593Smuzhiyun 			goto out;
146*4882a593Smuzhiyun 		}
147*4882a593Smuzhiyun 	} else if (ret == -EEXIST) {
148*4882a593Smuzhiyun 		ret = 0;
149*4882a593Smuzhiyun 		di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
150*4882a593Smuzhiyun 		ASSERT(di); /* logic error */
151*4882a593Smuzhiyun 	} else if (ret) {
152*4882a593Smuzhiyun 		goto out;
153*4882a593Smuzhiyun 	}
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	if (di && (flags & XATTR_CREATE)) {
156*4882a593Smuzhiyun 		ret = -EEXIST;
157*4882a593Smuzhiyun 		goto out;
158*4882a593Smuzhiyun 	}
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	if (di) {
161*4882a593Smuzhiyun 		/*
162*4882a593Smuzhiyun 		 * We're doing a replace, and it must be atomic, that is, at
163*4882a593Smuzhiyun 		 * any point in time we have either the old or the new xattr
164*4882a593Smuzhiyun 		 * value in the tree. We don't want readers (getxattr and
165*4882a593Smuzhiyun 		 * listxattrs) to miss a value, this is specially important
166*4882a593Smuzhiyun 		 * for ACLs.
167*4882a593Smuzhiyun 		 */
168*4882a593Smuzhiyun 		const int slot = path->slots[0];
169*4882a593Smuzhiyun 		struct extent_buffer *leaf = path->nodes[0];
170*4882a593Smuzhiyun 		const u16 old_data_len = btrfs_dir_data_len(leaf, di);
171*4882a593Smuzhiyun 		const u32 item_size = btrfs_item_size_nr(leaf, slot);
172*4882a593Smuzhiyun 		const u32 data_size = sizeof(*di) + name_len + size;
173*4882a593Smuzhiyun 		struct btrfs_item *item;
174*4882a593Smuzhiyun 		unsigned long data_ptr;
175*4882a593Smuzhiyun 		char *ptr;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 		if (size > old_data_len) {
178*4882a593Smuzhiyun 			if (btrfs_leaf_free_space(leaf) <
179*4882a593Smuzhiyun 			    (size - old_data_len)) {
180*4882a593Smuzhiyun 				ret = -ENOSPC;
181*4882a593Smuzhiyun 				goto out;
182*4882a593Smuzhiyun 			}
183*4882a593Smuzhiyun 		}
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 		if (old_data_len + name_len + sizeof(*di) == item_size) {
186*4882a593Smuzhiyun 			/* No other xattrs packed in the same leaf item. */
187*4882a593Smuzhiyun 			if (size > old_data_len)
188*4882a593Smuzhiyun 				btrfs_extend_item(path, size - old_data_len);
189*4882a593Smuzhiyun 			else if (size < old_data_len)
190*4882a593Smuzhiyun 				btrfs_truncate_item(path, data_size, 1);
191*4882a593Smuzhiyun 		} else {
192*4882a593Smuzhiyun 			/* There are other xattrs packed in the same item. */
193*4882a593Smuzhiyun 			ret = btrfs_delete_one_dir_name(trans, root, path, di);
194*4882a593Smuzhiyun 			if (ret)
195*4882a593Smuzhiyun 				goto out;
196*4882a593Smuzhiyun 			btrfs_extend_item(path, data_size);
197*4882a593Smuzhiyun 		}
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 		item = btrfs_item_nr(slot);
200*4882a593Smuzhiyun 		ptr = btrfs_item_ptr(leaf, slot, char);
201*4882a593Smuzhiyun 		ptr += btrfs_item_size(leaf, item) - data_size;
202*4882a593Smuzhiyun 		di = (struct btrfs_dir_item *)ptr;
203*4882a593Smuzhiyun 		btrfs_set_dir_data_len(leaf, di, size);
204*4882a593Smuzhiyun 		data_ptr = ((unsigned long)(di + 1)) + name_len;
205*4882a593Smuzhiyun 		write_extent_buffer(leaf, value, data_ptr, size);
206*4882a593Smuzhiyun 		btrfs_mark_buffer_dirty(leaf);
207*4882a593Smuzhiyun 	} else {
208*4882a593Smuzhiyun 		/*
209*4882a593Smuzhiyun 		 * Insert, and we had space for the xattr, so path->slots[0] is
210*4882a593Smuzhiyun 		 * where our xattr dir_item is and btrfs_insert_xattr_item()
211*4882a593Smuzhiyun 		 * filled it.
212*4882a593Smuzhiyun 		 */
213*4882a593Smuzhiyun 	}
214*4882a593Smuzhiyun out:
215*4882a593Smuzhiyun 	btrfs_free_path(path);
216*4882a593Smuzhiyun 	if (!ret) {
217*4882a593Smuzhiyun 		set_bit(BTRFS_INODE_COPY_EVERYTHING,
218*4882a593Smuzhiyun 			&BTRFS_I(inode)->runtime_flags);
219*4882a593Smuzhiyun 		clear_bit(BTRFS_INODE_NO_XATTRS, &BTRFS_I(inode)->runtime_flags);
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 	return ret;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun /*
225*4882a593Smuzhiyun  * @value: "" makes the attribute to empty, NULL removes it
226*4882a593Smuzhiyun  */
btrfs_setxattr_trans(struct inode * inode,const char * name,const void * value,size_t size,int flags)227*4882a593Smuzhiyun int btrfs_setxattr_trans(struct inode *inode, const char *name,
228*4882a593Smuzhiyun 			 const void *value, size_t size, int flags)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
231*4882a593Smuzhiyun 	struct btrfs_trans_handle *trans;
232*4882a593Smuzhiyun 	const bool start_trans = (current->journal_info == NULL);
233*4882a593Smuzhiyun 	int ret;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	if (start_trans) {
236*4882a593Smuzhiyun 		/*
237*4882a593Smuzhiyun 		 * 1 unit for inserting/updating/deleting the xattr
238*4882a593Smuzhiyun 		 * 1 unit for the inode item update
239*4882a593Smuzhiyun 		 */
240*4882a593Smuzhiyun 		trans = btrfs_start_transaction(root, 2);
241*4882a593Smuzhiyun 		if (IS_ERR(trans))
242*4882a593Smuzhiyun 			return PTR_ERR(trans);
243*4882a593Smuzhiyun 	} else {
244*4882a593Smuzhiyun 		/*
245*4882a593Smuzhiyun 		 * This can happen when smack is enabled and a directory is being
246*4882a593Smuzhiyun 		 * created. It happens through d_instantiate_new(), which calls
247*4882a593Smuzhiyun 		 * smack_d_instantiate(), which in turn calls __vfs_setxattr() to
248*4882a593Smuzhiyun 		 * set the transmute xattr (XATTR_NAME_SMACKTRANSMUTE) on the
249*4882a593Smuzhiyun 		 * inode. We have already reserved space for the xattr and inode
250*4882a593Smuzhiyun 		 * update at btrfs_mkdir(), so just use the transaction handle.
251*4882a593Smuzhiyun 		 * We don't join or start a transaction, as that will reset the
252*4882a593Smuzhiyun 		 * block_rsv of the handle and trigger a warning for the start
253*4882a593Smuzhiyun 		 * case.
254*4882a593Smuzhiyun 		 */
255*4882a593Smuzhiyun 		ASSERT(strncmp(name, XATTR_SECURITY_PREFIX,
256*4882a593Smuzhiyun 			       XATTR_SECURITY_PREFIX_LEN) == 0);
257*4882a593Smuzhiyun 		trans = current->journal_info;
258*4882a593Smuzhiyun 	}
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	ret = btrfs_setxattr(trans, inode, name, value, size, flags);
261*4882a593Smuzhiyun 	if (ret)
262*4882a593Smuzhiyun 		goto out;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	inode_inc_iversion(inode);
265*4882a593Smuzhiyun 	inode->i_ctime = current_time(inode);
266*4882a593Smuzhiyun 	ret = btrfs_update_inode(trans, root, inode);
267*4882a593Smuzhiyun 	BUG_ON(ret);
268*4882a593Smuzhiyun out:
269*4882a593Smuzhiyun 	if (start_trans)
270*4882a593Smuzhiyun 		btrfs_end_transaction(trans);
271*4882a593Smuzhiyun 	return ret;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
btrfs_listxattr(struct dentry * dentry,char * buffer,size_t size)274*4882a593Smuzhiyun ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	struct btrfs_key key;
277*4882a593Smuzhiyun 	struct inode *inode = d_inode(dentry);
278*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
279*4882a593Smuzhiyun 	struct btrfs_path *path;
280*4882a593Smuzhiyun 	int ret = 0;
281*4882a593Smuzhiyun 	size_t total_size = 0, size_left = size;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	/*
284*4882a593Smuzhiyun 	 * ok we want all objects associated with this id.
285*4882a593Smuzhiyun 	 * NOTE: we set key.offset = 0; because we want to start with the
286*4882a593Smuzhiyun 	 * first xattr that we find and walk forward
287*4882a593Smuzhiyun 	 */
288*4882a593Smuzhiyun 	key.objectid = btrfs_ino(BTRFS_I(inode));
289*4882a593Smuzhiyun 	key.type = BTRFS_XATTR_ITEM_KEY;
290*4882a593Smuzhiyun 	key.offset = 0;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	path = btrfs_alloc_path();
293*4882a593Smuzhiyun 	if (!path)
294*4882a593Smuzhiyun 		return -ENOMEM;
295*4882a593Smuzhiyun 	path->reada = READA_FORWARD;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	/* search for our xattrs */
298*4882a593Smuzhiyun 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
299*4882a593Smuzhiyun 	if (ret < 0)
300*4882a593Smuzhiyun 		goto err;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	while (1) {
303*4882a593Smuzhiyun 		struct extent_buffer *leaf;
304*4882a593Smuzhiyun 		int slot;
305*4882a593Smuzhiyun 		struct btrfs_dir_item *di;
306*4882a593Smuzhiyun 		struct btrfs_key found_key;
307*4882a593Smuzhiyun 		u32 item_size;
308*4882a593Smuzhiyun 		u32 cur;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 		leaf = path->nodes[0];
311*4882a593Smuzhiyun 		slot = path->slots[0];
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 		/* this is where we start walking through the path */
314*4882a593Smuzhiyun 		if (slot >= btrfs_header_nritems(leaf)) {
315*4882a593Smuzhiyun 			/*
316*4882a593Smuzhiyun 			 * if we've reached the last slot in this leaf we need
317*4882a593Smuzhiyun 			 * to go to the next leaf and reset everything
318*4882a593Smuzhiyun 			 */
319*4882a593Smuzhiyun 			ret = btrfs_next_leaf(root, path);
320*4882a593Smuzhiyun 			if (ret < 0)
321*4882a593Smuzhiyun 				goto err;
322*4882a593Smuzhiyun 			else if (ret > 0)
323*4882a593Smuzhiyun 				break;
324*4882a593Smuzhiyun 			continue;
325*4882a593Smuzhiyun 		}
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 		btrfs_item_key_to_cpu(leaf, &found_key, slot);
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 		/* check to make sure this item is what we want */
330*4882a593Smuzhiyun 		if (found_key.objectid != key.objectid)
331*4882a593Smuzhiyun 			break;
332*4882a593Smuzhiyun 		if (found_key.type > BTRFS_XATTR_ITEM_KEY)
333*4882a593Smuzhiyun 			break;
334*4882a593Smuzhiyun 		if (found_key.type < BTRFS_XATTR_ITEM_KEY)
335*4882a593Smuzhiyun 			goto next_item;
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 		di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
338*4882a593Smuzhiyun 		item_size = btrfs_item_size_nr(leaf, slot);
339*4882a593Smuzhiyun 		cur = 0;
340*4882a593Smuzhiyun 		while (cur < item_size) {
341*4882a593Smuzhiyun 			u16 name_len = btrfs_dir_name_len(leaf, di);
342*4882a593Smuzhiyun 			u16 data_len = btrfs_dir_data_len(leaf, di);
343*4882a593Smuzhiyun 			u32 this_len = sizeof(*di) + name_len + data_len;
344*4882a593Smuzhiyun 			unsigned long name_ptr = (unsigned long)(di + 1);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 			total_size += name_len + 1;
347*4882a593Smuzhiyun 			/*
348*4882a593Smuzhiyun 			 * We are just looking for how big our buffer needs to
349*4882a593Smuzhiyun 			 * be.
350*4882a593Smuzhiyun 			 */
351*4882a593Smuzhiyun 			if (!size)
352*4882a593Smuzhiyun 				goto next;
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 			if (!buffer || (name_len + 1) > size_left) {
355*4882a593Smuzhiyun 				ret = -ERANGE;
356*4882a593Smuzhiyun 				goto err;
357*4882a593Smuzhiyun 			}
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 			read_extent_buffer(leaf, buffer, name_ptr, name_len);
360*4882a593Smuzhiyun 			buffer[name_len] = '\0';
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 			size_left -= name_len + 1;
363*4882a593Smuzhiyun 			buffer += name_len + 1;
364*4882a593Smuzhiyun next:
365*4882a593Smuzhiyun 			cur += this_len;
366*4882a593Smuzhiyun 			di = (struct btrfs_dir_item *)((char *)di + this_len);
367*4882a593Smuzhiyun 		}
368*4882a593Smuzhiyun next_item:
369*4882a593Smuzhiyun 		path->slots[0]++;
370*4882a593Smuzhiyun 	}
371*4882a593Smuzhiyun 	ret = total_size;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun err:
374*4882a593Smuzhiyun 	btrfs_free_path(path);
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	return ret;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun 
btrfs_xattr_handler_get(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,void * buffer,size_t size,int flags)379*4882a593Smuzhiyun static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
380*4882a593Smuzhiyun 				   struct dentry *unused, struct inode *inode,
381*4882a593Smuzhiyun 				   const char *name, void *buffer, size_t size,
382*4882a593Smuzhiyun 				   int flags)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	name = xattr_full_name(handler, name);
385*4882a593Smuzhiyun 	return btrfs_getxattr(inode, name, buffer, size);
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun 
btrfs_xattr_handler_set(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,const void * buffer,size_t size,int flags)388*4882a593Smuzhiyun static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
389*4882a593Smuzhiyun 				   struct dentry *unused, struct inode *inode,
390*4882a593Smuzhiyun 				   const char *name, const void *buffer,
391*4882a593Smuzhiyun 				   size_t size, int flags)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	if (btrfs_root_readonly(BTRFS_I(inode)->root))
394*4882a593Smuzhiyun 		return -EROFS;
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	name = xattr_full_name(handler, name);
397*4882a593Smuzhiyun 	return btrfs_setxattr_trans(inode, name, buffer, size, flags);
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun 
btrfs_xattr_handler_set_prop(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,const void * value,size_t size,int flags)400*4882a593Smuzhiyun static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
401*4882a593Smuzhiyun 					struct dentry *unused, struct inode *inode,
402*4882a593Smuzhiyun 					const char *name, const void *value,
403*4882a593Smuzhiyun 					size_t size, int flags)
404*4882a593Smuzhiyun {
405*4882a593Smuzhiyun 	int ret;
406*4882a593Smuzhiyun 	struct btrfs_trans_handle *trans;
407*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	name = xattr_full_name(handler, name);
410*4882a593Smuzhiyun 	ret = btrfs_validate_prop(name, value, size);
411*4882a593Smuzhiyun 	if (ret)
412*4882a593Smuzhiyun 		return ret;
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	trans = btrfs_start_transaction(root, 2);
415*4882a593Smuzhiyun 	if (IS_ERR(trans))
416*4882a593Smuzhiyun 		return PTR_ERR(trans);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	ret = btrfs_set_prop(trans, inode, name, value, size, flags);
419*4882a593Smuzhiyun 	if (!ret) {
420*4882a593Smuzhiyun 		inode_inc_iversion(inode);
421*4882a593Smuzhiyun 		inode->i_ctime = current_time(inode);
422*4882a593Smuzhiyun 		ret = btrfs_update_inode(trans, root, inode);
423*4882a593Smuzhiyun 		BUG_ON(ret);
424*4882a593Smuzhiyun 	}
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	btrfs_end_transaction(trans);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	return ret;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun static const struct xattr_handler btrfs_security_xattr_handler = {
432*4882a593Smuzhiyun 	.prefix = XATTR_SECURITY_PREFIX,
433*4882a593Smuzhiyun 	.get = btrfs_xattr_handler_get,
434*4882a593Smuzhiyun 	.set = btrfs_xattr_handler_set,
435*4882a593Smuzhiyun };
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun static const struct xattr_handler btrfs_trusted_xattr_handler = {
438*4882a593Smuzhiyun 	.prefix = XATTR_TRUSTED_PREFIX,
439*4882a593Smuzhiyun 	.get = btrfs_xattr_handler_get,
440*4882a593Smuzhiyun 	.set = btrfs_xattr_handler_set,
441*4882a593Smuzhiyun };
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun static const struct xattr_handler btrfs_user_xattr_handler = {
444*4882a593Smuzhiyun 	.prefix = XATTR_USER_PREFIX,
445*4882a593Smuzhiyun 	.get = btrfs_xattr_handler_get,
446*4882a593Smuzhiyun 	.set = btrfs_xattr_handler_set,
447*4882a593Smuzhiyun };
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun static const struct xattr_handler btrfs_btrfs_xattr_handler = {
450*4882a593Smuzhiyun 	.prefix = XATTR_BTRFS_PREFIX,
451*4882a593Smuzhiyun 	.get = btrfs_xattr_handler_get,
452*4882a593Smuzhiyun 	.set = btrfs_xattr_handler_set_prop,
453*4882a593Smuzhiyun };
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun const struct xattr_handler *btrfs_xattr_handlers[] = {
456*4882a593Smuzhiyun 	&btrfs_security_xattr_handler,
457*4882a593Smuzhiyun #ifdef CONFIG_BTRFS_FS_POSIX_ACL
458*4882a593Smuzhiyun 	&posix_acl_access_xattr_handler,
459*4882a593Smuzhiyun 	&posix_acl_default_xattr_handler,
460*4882a593Smuzhiyun #endif
461*4882a593Smuzhiyun 	&btrfs_trusted_xattr_handler,
462*4882a593Smuzhiyun 	&btrfs_user_xattr_handler,
463*4882a593Smuzhiyun 	&btrfs_btrfs_xattr_handler,
464*4882a593Smuzhiyun 	NULL,
465*4882a593Smuzhiyun };
466*4882a593Smuzhiyun 
btrfs_initxattrs(struct inode * inode,const struct xattr * xattr_array,void * fs_private)467*4882a593Smuzhiyun static int btrfs_initxattrs(struct inode *inode,
468*4882a593Smuzhiyun 			    const struct xattr *xattr_array, void *fs_private)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun 	struct btrfs_trans_handle *trans = fs_private;
471*4882a593Smuzhiyun 	const struct xattr *xattr;
472*4882a593Smuzhiyun 	unsigned int nofs_flag;
473*4882a593Smuzhiyun 	char *name;
474*4882a593Smuzhiyun 	int err = 0;
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	/*
477*4882a593Smuzhiyun 	 * We're holding a transaction handle, so use a NOFS memory allocation
478*4882a593Smuzhiyun 	 * context to avoid deadlock if reclaim happens.
479*4882a593Smuzhiyun 	 */
480*4882a593Smuzhiyun 	nofs_flag = memalloc_nofs_save();
481*4882a593Smuzhiyun 	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
482*4882a593Smuzhiyun 		name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
483*4882a593Smuzhiyun 			       strlen(xattr->name) + 1, GFP_KERNEL);
484*4882a593Smuzhiyun 		if (!name) {
485*4882a593Smuzhiyun 			err = -ENOMEM;
486*4882a593Smuzhiyun 			break;
487*4882a593Smuzhiyun 		}
488*4882a593Smuzhiyun 		strcpy(name, XATTR_SECURITY_PREFIX);
489*4882a593Smuzhiyun 		strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
490*4882a593Smuzhiyun 		err = btrfs_setxattr(trans, inode, name, xattr->value,
491*4882a593Smuzhiyun 				     xattr->value_len, 0);
492*4882a593Smuzhiyun 		kfree(name);
493*4882a593Smuzhiyun 		if (err < 0)
494*4882a593Smuzhiyun 			break;
495*4882a593Smuzhiyun 	}
496*4882a593Smuzhiyun 	memalloc_nofs_restore(nofs_flag);
497*4882a593Smuzhiyun 	return err;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun 
btrfs_xattr_security_init(struct btrfs_trans_handle * trans,struct inode * inode,struct inode * dir,const struct qstr * qstr)500*4882a593Smuzhiyun int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
501*4882a593Smuzhiyun 			      struct inode *inode, struct inode *dir,
502*4882a593Smuzhiyun 			      const struct qstr *qstr)
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun 	return security_inode_init_security(inode, dir, qstr,
505*4882a593Smuzhiyun 					    &btrfs_initxattrs, trans);
506*4882a593Smuzhiyun }
507