xref: /OK3568_Linux_fs/kernel/fs/btrfs/props.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2014 Filipe David Borba Manana <fdmanana@gmail.com>
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/hashtable.h>
7*4882a593Smuzhiyun #include "props.h"
8*4882a593Smuzhiyun #include "btrfs_inode.h"
9*4882a593Smuzhiyun #include "transaction.h"
10*4882a593Smuzhiyun #include "ctree.h"
11*4882a593Smuzhiyun #include "xattr.h"
12*4882a593Smuzhiyun #include "compression.h"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define BTRFS_PROP_HANDLERS_HT_BITS 8
15*4882a593Smuzhiyun static DEFINE_HASHTABLE(prop_handlers_ht, BTRFS_PROP_HANDLERS_HT_BITS);
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun struct prop_handler {
18*4882a593Smuzhiyun 	struct hlist_node node;
19*4882a593Smuzhiyun 	const char *xattr_name;
20*4882a593Smuzhiyun 	int (*validate)(const char *value, size_t len);
21*4882a593Smuzhiyun 	int (*apply)(struct inode *inode, const char *value, size_t len);
22*4882a593Smuzhiyun 	const char *(*extract)(struct inode *inode);
23*4882a593Smuzhiyun 	int inheritable;
24*4882a593Smuzhiyun };
25*4882a593Smuzhiyun 
find_prop_handlers_by_hash(const u64 hash)26*4882a593Smuzhiyun static const struct hlist_head *find_prop_handlers_by_hash(const u64 hash)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun 	struct hlist_head *h;
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	h = &prop_handlers_ht[hash_min(hash, BTRFS_PROP_HANDLERS_HT_BITS)];
31*4882a593Smuzhiyun 	if (hlist_empty(h))
32*4882a593Smuzhiyun 		return NULL;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	return h;
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun static const struct prop_handler *
find_prop_handler(const char * name,const struct hlist_head * handlers)38*4882a593Smuzhiyun find_prop_handler(const char *name,
39*4882a593Smuzhiyun 		  const struct hlist_head *handlers)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	struct prop_handler *h;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	if (!handlers) {
44*4882a593Smuzhiyun 		u64 hash = btrfs_name_hash(name, strlen(name));
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 		handlers = find_prop_handlers_by_hash(hash);
47*4882a593Smuzhiyun 		if (!handlers)
48*4882a593Smuzhiyun 			return NULL;
49*4882a593Smuzhiyun 	}
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	hlist_for_each_entry(h, handlers, node)
52*4882a593Smuzhiyun 		if (!strcmp(h->xattr_name, name))
53*4882a593Smuzhiyun 			return h;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	return NULL;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
btrfs_validate_prop(const char * name,const char * value,size_t value_len)58*4882a593Smuzhiyun int btrfs_validate_prop(const char *name, const char *value, size_t value_len)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	const struct prop_handler *handler;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	if (strlen(name) <= XATTR_BTRFS_PREFIX_LEN)
63*4882a593Smuzhiyun 		return -EINVAL;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	handler = find_prop_handler(name, NULL);
66*4882a593Smuzhiyun 	if (!handler)
67*4882a593Smuzhiyun 		return -EINVAL;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	if (value_len == 0)
70*4882a593Smuzhiyun 		return 0;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	return handler->validate(value, value_len);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
btrfs_set_prop(struct btrfs_trans_handle * trans,struct inode * inode,const char * name,const char * value,size_t value_len,int flags)75*4882a593Smuzhiyun int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
76*4882a593Smuzhiyun 		   const char *name, const char *value, size_t value_len,
77*4882a593Smuzhiyun 		   int flags)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	const struct prop_handler *handler;
80*4882a593Smuzhiyun 	int ret;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	handler = find_prop_handler(name, NULL);
83*4882a593Smuzhiyun 	if (!handler)
84*4882a593Smuzhiyun 		return -EINVAL;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	if (value_len == 0) {
87*4882a593Smuzhiyun 		ret = btrfs_setxattr(trans, inode, handler->xattr_name,
88*4882a593Smuzhiyun 				     NULL, 0, flags);
89*4882a593Smuzhiyun 		if (ret)
90*4882a593Smuzhiyun 			return ret;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 		ret = handler->apply(inode, NULL, 0);
93*4882a593Smuzhiyun 		ASSERT(ret == 0);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 		return ret;
96*4882a593Smuzhiyun 	}
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	ret = btrfs_setxattr(trans, inode, handler->xattr_name, value,
99*4882a593Smuzhiyun 			     value_len, flags);
100*4882a593Smuzhiyun 	if (ret)
101*4882a593Smuzhiyun 		return ret;
102*4882a593Smuzhiyun 	ret = handler->apply(inode, value, value_len);
103*4882a593Smuzhiyun 	if (ret) {
104*4882a593Smuzhiyun 		btrfs_setxattr(trans, inode, handler->xattr_name, NULL,
105*4882a593Smuzhiyun 			       0, flags);
106*4882a593Smuzhiyun 		return ret;
107*4882a593Smuzhiyun 	}
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	return 0;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
iterate_object_props(struct btrfs_root * root,struct btrfs_path * path,u64 objectid,void (* iterator)(void *,const struct prop_handler *,const char *,size_t),void * ctx)114*4882a593Smuzhiyun static int iterate_object_props(struct btrfs_root *root,
115*4882a593Smuzhiyun 				struct btrfs_path *path,
116*4882a593Smuzhiyun 				u64 objectid,
117*4882a593Smuzhiyun 				void (*iterator)(void *,
118*4882a593Smuzhiyun 						 const struct prop_handler *,
119*4882a593Smuzhiyun 						 const char *,
120*4882a593Smuzhiyun 						 size_t),
121*4882a593Smuzhiyun 				void *ctx)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	int ret;
124*4882a593Smuzhiyun 	char *name_buf = NULL;
125*4882a593Smuzhiyun 	char *value_buf = NULL;
126*4882a593Smuzhiyun 	int name_buf_len = 0;
127*4882a593Smuzhiyun 	int value_buf_len = 0;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	while (1) {
130*4882a593Smuzhiyun 		struct btrfs_key key;
131*4882a593Smuzhiyun 		struct btrfs_dir_item *di;
132*4882a593Smuzhiyun 		struct extent_buffer *leaf;
133*4882a593Smuzhiyun 		u32 total_len, cur, this_len;
134*4882a593Smuzhiyun 		int slot;
135*4882a593Smuzhiyun 		const struct hlist_head *handlers;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 		slot = path->slots[0];
138*4882a593Smuzhiyun 		leaf = path->nodes[0];
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 		if (slot >= btrfs_header_nritems(leaf)) {
141*4882a593Smuzhiyun 			ret = btrfs_next_leaf(root, path);
142*4882a593Smuzhiyun 			if (ret < 0)
143*4882a593Smuzhiyun 				goto out;
144*4882a593Smuzhiyun 			else if (ret > 0)
145*4882a593Smuzhiyun 				break;
146*4882a593Smuzhiyun 			continue;
147*4882a593Smuzhiyun 		}
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 		btrfs_item_key_to_cpu(leaf, &key, slot);
150*4882a593Smuzhiyun 		if (key.objectid != objectid)
151*4882a593Smuzhiyun 			break;
152*4882a593Smuzhiyun 		if (key.type != BTRFS_XATTR_ITEM_KEY)
153*4882a593Smuzhiyun 			break;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 		handlers = find_prop_handlers_by_hash(key.offset);
156*4882a593Smuzhiyun 		if (!handlers)
157*4882a593Smuzhiyun 			goto next_slot;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 		di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
160*4882a593Smuzhiyun 		cur = 0;
161*4882a593Smuzhiyun 		total_len = btrfs_item_size_nr(leaf, slot);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 		while (cur < total_len) {
164*4882a593Smuzhiyun 			u32 name_len = btrfs_dir_name_len(leaf, di);
165*4882a593Smuzhiyun 			u32 data_len = btrfs_dir_data_len(leaf, di);
166*4882a593Smuzhiyun 			unsigned long name_ptr, data_ptr;
167*4882a593Smuzhiyun 			const struct prop_handler *handler;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 			this_len = sizeof(*di) + name_len + data_len;
170*4882a593Smuzhiyun 			name_ptr = (unsigned long)(di + 1);
171*4882a593Smuzhiyun 			data_ptr = name_ptr + name_len;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 			if (name_len <= XATTR_BTRFS_PREFIX_LEN ||
174*4882a593Smuzhiyun 			    memcmp_extent_buffer(leaf, XATTR_BTRFS_PREFIX,
175*4882a593Smuzhiyun 						 name_ptr,
176*4882a593Smuzhiyun 						 XATTR_BTRFS_PREFIX_LEN))
177*4882a593Smuzhiyun 				goto next_dir_item;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 			if (name_len >= name_buf_len) {
180*4882a593Smuzhiyun 				kfree(name_buf);
181*4882a593Smuzhiyun 				name_buf_len = name_len + 1;
182*4882a593Smuzhiyun 				name_buf = kmalloc(name_buf_len, GFP_NOFS);
183*4882a593Smuzhiyun 				if (!name_buf) {
184*4882a593Smuzhiyun 					ret = -ENOMEM;
185*4882a593Smuzhiyun 					goto out;
186*4882a593Smuzhiyun 				}
187*4882a593Smuzhiyun 			}
188*4882a593Smuzhiyun 			read_extent_buffer(leaf, name_buf, name_ptr, name_len);
189*4882a593Smuzhiyun 			name_buf[name_len] = '\0';
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 			handler = find_prop_handler(name_buf, handlers);
192*4882a593Smuzhiyun 			if (!handler)
193*4882a593Smuzhiyun 				goto next_dir_item;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 			if (data_len > value_buf_len) {
196*4882a593Smuzhiyun 				kfree(value_buf);
197*4882a593Smuzhiyun 				value_buf_len = data_len;
198*4882a593Smuzhiyun 				value_buf = kmalloc(data_len, GFP_NOFS);
199*4882a593Smuzhiyun 				if (!value_buf) {
200*4882a593Smuzhiyun 					ret = -ENOMEM;
201*4882a593Smuzhiyun 					goto out;
202*4882a593Smuzhiyun 				}
203*4882a593Smuzhiyun 			}
204*4882a593Smuzhiyun 			read_extent_buffer(leaf, value_buf, data_ptr, data_len);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 			iterator(ctx, handler, value_buf, data_len);
207*4882a593Smuzhiyun next_dir_item:
208*4882a593Smuzhiyun 			cur += this_len;
209*4882a593Smuzhiyun 			di = (struct btrfs_dir_item *)((char *) di + this_len);
210*4882a593Smuzhiyun 		}
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun next_slot:
213*4882a593Smuzhiyun 		path->slots[0]++;
214*4882a593Smuzhiyun 	}
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	ret = 0;
217*4882a593Smuzhiyun out:
218*4882a593Smuzhiyun 	btrfs_release_path(path);
219*4882a593Smuzhiyun 	kfree(name_buf);
220*4882a593Smuzhiyun 	kfree(value_buf);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	return ret;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
inode_prop_iterator(void * ctx,const struct prop_handler * handler,const char * value,size_t len)225*4882a593Smuzhiyun static void inode_prop_iterator(void *ctx,
226*4882a593Smuzhiyun 				const struct prop_handler *handler,
227*4882a593Smuzhiyun 				const char *value,
228*4882a593Smuzhiyun 				size_t len)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	struct inode *inode = ctx;
231*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
232*4882a593Smuzhiyun 	int ret;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	ret = handler->apply(inode, value, len);
235*4882a593Smuzhiyun 	if (unlikely(ret))
236*4882a593Smuzhiyun 		btrfs_warn(root->fs_info,
237*4882a593Smuzhiyun 			   "error applying prop %s to ino %llu (root %llu): %d",
238*4882a593Smuzhiyun 			   handler->xattr_name, btrfs_ino(BTRFS_I(inode)),
239*4882a593Smuzhiyun 			   root->root_key.objectid, ret);
240*4882a593Smuzhiyun 	else
241*4882a593Smuzhiyun 		set_bit(BTRFS_INODE_HAS_PROPS, &BTRFS_I(inode)->runtime_flags);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
btrfs_load_inode_props(struct inode * inode,struct btrfs_path * path)244*4882a593Smuzhiyun int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
247*4882a593Smuzhiyun 	u64 ino = btrfs_ino(BTRFS_I(inode));
248*4882a593Smuzhiyun 	int ret;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	ret = iterate_object_props(root, path, ino, inode_prop_iterator, inode);
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	return ret;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun 
prop_compression_validate(const char * value,size_t len)255*4882a593Smuzhiyun static int prop_compression_validate(const char *value, size_t len)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun 	if (!value)
258*4882a593Smuzhiyun 		return 0;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	if (btrfs_compress_is_valid_type(value, len))
261*4882a593Smuzhiyun 		return 0;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	return -EINVAL;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
prop_compression_apply(struct inode * inode,const char * value,size_t len)266*4882a593Smuzhiyun static int prop_compression_apply(struct inode *inode, const char *value,
267*4882a593Smuzhiyun 				  size_t len)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun 	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
270*4882a593Smuzhiyun 	int type;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if (len == 0) {
273*4882a593Smuzhiyun 		BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
274*4882a593Smuzhiyun 		BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
275*4882a593Smuzhiyun 		BTRFS_I(inode)->prop_compress = BTRFS_COMPRESS_NONE;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 		return 0;
278*4882a593Smuzhiyun 	}
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	if (!strncmp("lzo", value, 3)) {
281*4882a593Smuzhiyun 		type = BTRFS_COMPRESS_LZO;
282*4882a593Smuzhiyun 		btrfs_set_fs_incompat(fs_info, COMPRESS_LZO);
283*4882a593Smuzhiyun 	} else if (!strncmp("zlib", value, 4)) {
284*4882a593Smuzhiyun 		type = BTRFS_COMPRESS_ZLIB;
285*4882a593Smuzhiyun 	} else if (!strncmp("zstd", value, 4)) {
286*4882a593Smuzhiyun 		type = BTRFS_COMPRESS_ZSTD;
287*4882a593Smuzhiyun 		btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD);
288*4882a593Smuzhiyun 	} else {
289*4882a593Smuzhiyun 		return -EINVAL;
290*4882a593Smuzhiyun 	}
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	BTRFS_I(inode)->flags &= ~BTRFS_INODE_NOCOMPRESS;
293*4882a593Smuzhiyun 	BTRFS_I(inode)->flags |= BTRFS_INODE_COMPRESS;
294*4882a593Smuzhiyun 	BTRFS_I(inode)->prop_compress = type;
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	return 0;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun 
prop_compression_extract(struct inode * inode)299*4882a593Smuzhiyun static const char *prop_compression_extract(struct inode *inode)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun 	switch (BTRFS_I(inode)->prop_compress) {
302*4882a593Smuzhiyun 	case BTRFS_COMPRESS_ZLIB:
303*4882a593Smuzhiyun 	case BTRFS_COMPRESS_LZO:
304*4882a593Smuzhiyun 	case BTRFS_COMPRESS_ZSTD:
305*4882a593Smuzhiyun 		return btrfs_compress_type2str(BTRFS_I(inode)->prop_compress);
306*4882a593Smuzhiyun 	default:
307*4882a593Smuzhiyun 		break;
308*4882a593Smuzhiyun 	}
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	return NULL;
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun static struct prop_handler prop_handlers[] = {
314*4882a593Smuzhiyun 	{
315*4882a593Smuzhiyun 		.xattr_name = XATTR_BTRFS_PREFIX "compression",
316*4882a593Smuzhiyun 		.validate = prop_compression_validate,
317*4882a593Smuzhiyun 		.apply = prop_compression_apply,
318*4882a593Smuzhiyun 		.extract = prop_compression_extract,
319*4882a593Smuzhiyun 		.inheritable = 1
320*4882a593Smuzhiyun 	},
321*4882a593Smuzhiyun };
322*4882a593Smuzhiyun 
inherit_props(struct btrfs_trans_handle * trans,struct inode * inode,struct inode * parent)323*4882a593Smuzhiyun static int inherit_props(struct btrfs_trans_handle *trans,
324*4882a593Smuzhiyun 			 struct inode *inode,
325*4882a593Smuzhiyun 			 struct inode *parent)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	struct btrfs_root *root = BTRFS_I(inode)->root;
328*4882a593Smuzhiyun 	struct btrfs_fs_info *fs_info = root->fs_info;
329*4882a593Smuzhiyun 	int ret;
330*4882a593Smuzhiyun 	int i;
331*4882a593Smuzhiyun 	bool need_reserve = false;
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	if (!test_bit(BTRFS_INODE_HAS_PROPS,
334*4882a593Smuzhiyun 		      &BTRFS_I(parent)->runtime_flags))
335*4882a593Smuzhiyun 		return 0;
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
338*4882a593Smuzhiyun 		const struct prop_handler *h = &prop_handlers[i];
339*4882a593Smuzhiyun 		const char *value;
340*4882a593Smuzhiyun 		u64 num_bytes = 0;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 		if (!h->inheritable)
343*4882a593Smuzhiyun 			continue;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 		value = h->extract(parent);
346*4882a593Smuzhiyun 		if (!value)
347*4882a593Smuzhiyun 			continue;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 		/*
350*4882a593Smuzhiyun 		 * This is not strictly necessary as the property should be
351*4882a593Smuzhiyun 		 * valid, but in case it isn't, don't propagate it futher.
352*4882a593Smuzhiyun 		 */
353*4882a593Smuzhiyun 		ret = h->validate(value, strlen(value));
354*4882a593Smuzhiyun 		if (ret)
355*4882a593Smuzhiyun 			continue;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 		/*
358*4882a593Smuzhiyun 		 * Currently callers should be reserving 1 item for properties,
359*4882a593Smuzhiyun 		 * since we only have 1 property that we currently support.  If
360*4882a593Smuzhiyun 		 * we add more in the future we need to try and reserve more
361*4882a593Smuzhiyun 		 * space for them.  But we should also revisit how we do space
362*4882a593Smuzhiyun 		 * reservations if we do add more properties in the future.
363*4882a593Smuzhiyun 		 */
364*4882a593Smuzhiyun 		if (need_reserve) {
365*4882a593Smuzhiyun 			num_bytes = btrfs_calc_insert_metadata_size(fs_info, 1);
366*4882a593Smuzhiyun 			ret = btrfs_block_rsv_add(root, trans->block_rsv,
367*4882a593Smuzhiyun 					num_bytes, BTRFS_RESERVE_NO_FLUSH);
368*4882a593Smuzhiyun 			if (ret)
369*4882a593Smuzhiyun 				return ret;
370*4882a593Smuzhiyun 		}
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 		ret = btrfs_setxattr(trans, inode, h->xattr_name, value,
373*4882a593Smuzhiyun 				     strlen(value), 0);
374*4882a593Smuzhiyun 		if (!ret) {
375*4882a593Smuzhiyun 			ret = h->apply(inode, value, strlen(value));
376*4882a593Smuzhiyun 			if (ret)
377*4882a593Smuzhiyun 				btrfs_setxattr(trans, inode, h->xattr_name,
378*4882a593Smuzhiyun 					       NULL, 0, 0);
379*4882a593Smuzhiyun 			else
380*4882a593Smuzhiyun 				set_bit(BTRFS_INODE_HAS_PROPS,
381*4882a593Smuzhiyun 					&BTRFS_I(inode)->runtime_flags);
382*4882a593Smuzhiyun 		}
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 		if (need_reserve) {
385*4882a593Smuzhiyun 			btrfs_block_rsv_release(fs_info, trans->block_rsv,
386*4882a593Smuzhiyun 					num_bytes, NULL);
387*4882a593Smuzhiyun 			if (ret)
388*4882a593Smuzhiyun 				return ret;
389*4882a593Smuzhiyun 		}
390*4882a593Smuzhiyun 		need_reserve = true;
391*4882a593Smuzhiyun 	}
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	return 0;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
btrfs_inode_inherit_props(struct btrfs_trans_handle * trans,struct inode * inode,struct inode * dir)396*4882a593Smuzhiyun int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans,
397*4882a593Smuzhiyun 			      struct inode *inode,
398*4882a593Smuzhiyun 			      struct inode *dir)
399*4882a593Smuzhiyun {
400*4882a593Smuzhiyun 	if (!dir)
401*4882a593Smuzhiyun 		return 0;
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	return inherit_props(trans, inode, dir);
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun 
btrfs_subvol_inherit_props(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_root * parent_root)406*4882a593Smuzhiyun int btrfs_subvol_inherit_props(struct btrfs_trans_handle *trans,
407*4882a593Smuzhiyun 			       struct btrfs_root *root,
408*4882a593Smuzhiyun 			       struct btrfs_root *parent_root)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun 	struct super_block *sb = root->fs_info->sb;
411*4882a593Smuzhiyun 	struct inode *parent_inode, *child_inode;
412*4882a593Smuzhiyun 	int ret;
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	parent_inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, parent_root);
415*4882a593Smuzhiyun 	if (IS_ERR(parent_inode))
416*4882a593Smuzhiyun 		return PTR_ERR(parent_inode);
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	child_inode = btrfs_iget(sb, BTRFS_FIRST_FREE_OBJECTID, root);
419*4882a593Smuzhiyun 	if (IS_ERR(child_inode)) {
420*4882a593Smuzhiyun 		iput(parent_inode);
421*4882a593Smuzhiyun 		return PTR_ERR(child_inode);
422*4882a593Smuzhiyun 	}
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	ret = inherit_props(trans, child_inode, parent_inode);
425*4882a593Smuzhiyun 	iput(child_inode);
426*4882a593Smuzhiyun 	iput(parent_inode);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	return ret;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
btrfs_props_init(void)431*4882a593Smuzhiyun void __init btrfs_props_init(void)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun 	int i;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) {
436*4882a593Smuzhiyun 		struct prop_handler *p = &prop_handlers[i];
437*4882a593Smuzhiyun 		u64 h = btrfs_name_hash(p->xattr_name, strlen(p->xattr_name));
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 		hash_add(prop_handlers_ht, &p->node, h);
440*4882a593Smuzhiyun 	}
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
443