Blame view

fs/btrfs/sysfs.c 23.4 KB
6cbd55707   Chris Mason   Btrfs: add GPLv2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * Copyright (C) 2007 Oracle.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License v2 as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   */
58176a960   Josef Bacik   Btrfs: Add per-ro...
18
19
20
21
22
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
58176a960   Josef Bacik   Btrfs: Add per-ro...
23
  #include <linux/kobject.h>
79da4fa4d   Jeff Mahoney   btrfs: publish un...
24
  #include <linux/bug.h>
29e5be240   Jeff Mahoney   btrfs: publish de...
25
  #include <linux/genhd.h>
1bae30982   David Sterba   btrfs: add simple...
26
  #include <linux/debugfs.h>
58176a960   Josef Bacik   Btrfs: Add per-ro...
27

bae45de03   Chris Mason   Btrfs: add dir in...
28
29
30
  #include "ctree.h"
  #include "disk-io.h"
  #include "transaction.h"
079b72bca   Jeff Mahoney   btrfs: publish su...
31
  #include "sysfs.h"
29e5be240   Jeff Mahoney   btrfs: publish de...
32
  #include "volumes.h"
079b72bca   Jeff Mahoney   btrfs: publish su...
33

510d73600   Jeff Mahoney   btrfs: publish pe...
34
  static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj);
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
35
  static inline struct btrfs_fs_devices *to_fs_devs(struct kobject *kobj);
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
36

510d73600   Jeff Mahoney   btrfs: publish pe...
37
38
  static u64 get_features(struct btrfs_fs_info *fs_info,
  			enum btrfs_feature_set set)
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
39
  {
510d73600   Jeff Mahoney   btrfs: publish pe...
40
41
42
43
44
45
46
  	struct btrfs_super_block *disk_super = fs_info->super_copy;
  	if (set == FEAT_COMPAT)
  		return btrfs_super_compat_flags(disk_super);
  	else if (set == FEAT_COMPAT_RO)
  		return btrfs_super_compat_ro_flags(disk_super);
  	else
  		return btrfs_super_incompat_flags(disk_super);
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
47
  }
ba631941e   Jeff Mahoney   btrfs: add abilit...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  static void set_features(struct btrfs_fs_info *fs_info,
  			 enum btrfs_feature_set set, u64 features)
  {
  	struct btrfs_super_block *disk_super = fs_info->super_copy;
  	if (set == FEAT_COMPAT)
  		btrfs_set_super_compat_flags(disk_super, features);
  	else if (set == FEAT_COMPAT_RO)
  		btrfs_set_super_compat_ro_flags(disk_super, features);
  	else
  		btrfs_set_super_incompat_flags(disk_super, features);
  }
  
  static int can_modify_feature(struct btrfs_feature_attr *fa)
  {
  	int val = 0;
  	u64 set, clear;
  	switch (fa->feature_set) {
  	case FEAT_COMPAT:
  		set = BTRFS_FEATURE_COMPAT_SAFE_SET;
  		clear = BTRFS_FEATURE_COMPAT_SAFE_CLEAR;
  		break;
  	case FEAT_COMPAT_RO:
  		set = BTRFS_FEATURE_COMPAT_RO_SAFE_SET;
  		clear = BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR;
  		break;
  	case FEAT_INCOMPAT:
  		set = BTRFS_FEATURE_INCOMPAT_SAFE_SET;
  		clear = BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR;
  		break;
  	default:
62e855771   Jeff Mahoney   btrfs: convert pr...
78
79
  		pr_warn("btrfs: sysfs: unknown feature set %d
  ",
cc37bb042   David Sterba   btrfs: replace BU...
80
81
  				fa->feature_set);
  		return 0;
ba631941e   Jeff Mahoney   btrfs: add abilit...
82
83
84
85
86
87
88
89
90
  	}
  
  	if (set & fa->feature_bit)
  		val |= 1;
  	if (clear & fa->feature_bit)
  		val |= 2;
  
  	return val;
  }
510d73600   Jeff Mahoney   btrfs: publish pe...
91
92
  static ssize_t btrfs_feature_attr_show(struct kobject *kobj,
  				       struct kobj_attribute *a, char *buf)
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
93
  {
510d73600   Jeff Mahoney   btrfs: publish pe...
94
  	int val = 0;
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
95
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
ba631941e   Jeff Mahoney   btrfs: add abilit...
96
  	struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a);
510d73600   Jeff Mahoney   btrfs: publish pe...
97
  	if (fs_info) {
510d73600   Jeff Mahoney   btrfs: publish pe...
98
99
100
  		u64 features = get_features(fs_info, fa->feature_set);
  		if (features & fa->feature_bit)
  			val = 1;
ba631941e   Jeff Mahoney   btrfs: add abilit...
101
102
  	} else
  		val = can_modify_feature(fa);
510d73600   Jeff Mahoney   btrfs: publish pe...
103
104
105
  
  	return snprintf(buf, PAGE_SIZE, "%d
  ", val);
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
106
  }
ba631941e   Jeff Mahoney   btrfs: add abilit...
107
108
109
110
111
112
  static ssize_t btrfs_feature_attr_store(struct kobject *kobj,
  					struct kobj_attribute *a,
  					const char *buf, size_t count)
  {
  	struct btrfs_fs_info *fs_info;
  	struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a);
ba631941e   Jeff Mahoney   btrfs: add abilit...
113
114
115
116
117
118
119
  	u64 features, set, clear;
  	unsigned long val;
  	int ret;
  
  	fs_info = to_fs_info(kobj);
  	if (!fs_info)
  		return -EPERM;
bc98a42c1   David Howells   VFS: Convert sb->...
120
  	if (sb_rdonly(fs_info->sb))
ee6111386   David Sterba   btrfs: add read-o...
121
  		return -EROFS;
ba631941e   Jeff Mahoney   btrfs: add abilit...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  	ret = kstrtoul(skip_spaces(buf), 0, &val);
  	if (ret)
  		return ret;
  
  	if (fa->feature_set == FEAT_COMPAT) {
  		set = BTRFS_FEATURE_COMPAT_SAFE_SET;
  		clear = BTRFS_FEATURE_COMPAT_SAFE_CLEAR;
  	} else if (fa->feature_set == FEAT_COMPAT_RO) {
  		set = BTRFS_FEATURE_COMPAT_RO_SAFE_SET;
  		clear = BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR;
  	} else {
  		set = BTRFS_FEATURE_INCOMPAT_SAFE_SET;
  		clear = BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR;
  	}
  
  	features = get_features(fs_info, fa->feature_set);
  
  	/* Nothing to do */
  	if ((val && (features & fa->feature_bit)) ||
  	    (!val && !(features & fa->feature_bit)))
  		return count;
  
  	if ((val && !(set & fa->feature_bit)) ||
  	    (!val && !(clear & fa->feature_bit))) {
  		btrfs_info(fs_info,
  			"%sabling feature %s on mounted fs is not supported.",
  			val ? "En" : "Dis", fa->kobj_attr.attr.name);
  		return -EPERM;
  	}
  
  	btrfs_info(fs_info, "%s %s feature flag",
  		   val ? "Setting" : "Clearing", fa->kobj_attr.attr.name);
ba631941e   Jeff Mahoney   btrfs: add abilit...
154
155
156
157
158
159
160
161
  	spin_lock(&fs_info->super_lock);
  	features = get_features(fs_info, fa->feature_set);
  	if (val)
  		features |= fa->feature_bit;
  	else
  		features &= ~fa->feature_bit;
  	set_features(fs_info, fa->feature_set, features);
  	spin_unlock(&fs_info->super_lock);
0eae2747e   David Sterba   btrfs: move commi...
162
163
164
165
166
  	/*
  	 * We don't want to do full transaction commit from inside sysfs
  	 */
  	btrfs_set_pending(fs_info, COMMIT);
  	wake_up_process(fs_info->transaction_kthread);
ba631941e   Jeff Mahoney   btrfs: add abilit...
167
168
169
  
  	return count;
  }
510d73600   Jeff Mahoney   btrfs: publish pe...
170
171
  static umode_t btrfs_feature_visible(struct kobject *kobj,
  				     struct attribute *attr, int unused)
079b72bca   Jeff Mahoney   btrfs: publish su...
172
  {
510d73600   Jeff Mahoney   btrfs: publish pe...
173
174
175
176
177
178
179
180
181
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
  	umode_t mode = attr->mode;
  
  	if (fs_info) {
  		struct btrfs_feature_attr *fa;
  		u64 features;
  
  		fa = attr_to_btrfs_feature_attr(attr);
  		features = get_features(fs_info, fa->feature_set);
ba631941e   Jeff Mahoney   btrfs: add abilit...
182
183
184
  		if (can_modify_feature(fa))
  			mode |= S_IWUSR;
  		else if (!(features & fa->feature_bit))
510d73600   Jeff Mahoney   btrfs: publish pe...
185
186
187
188
  			mode = 0;
  	}
  
  	return mode;
079b72bca   Jeff Mahoney   btrfs: publish su...
189
190
191
192
193
194
  }
  
  BTRFS_FEAT_ATTR_INCOMPAT(mixed_backref, MIXED_BACKREF);
  BTRFS_FEAT_ATTR_INCOMPAT(default_subvol, DEFAULT_SUBVOL);
  BTRFS_FEAT_ATTR_INCOMPAT(mixed_groups, MIXED_GROUPS);
  BTRFS_FEAT_ATTR_INCOMPAT(compress_lzo, COMPRESS_LZO);
5c1aab1dd   Nick Terrell   btrfs: Add zstd s...
195
  BTRFS_FEAT_ATTR_INCOMPAT(compress_zstd, COMPRESS_ZSTD);
079b72bca   Jeff Mahoney   btrfs: publish su...
196
197
198
199
  BTRFS_FEAT_ATTR_INCOMPAT(big_metadata, BIG_METADATA);
  BTRFS_FEAT_ATTR_INCOMPAT(extended_iref, EXTENDED_IREF);
  BTRFS_FEAT_ATTR_INCOMPAT(raid56, RAID56);
  BTRFS_FEAT_ATTR_INCOMPAT(skinny_metadata, SKINNY_METADATA);
c736c095d   David Sterba   btrfs: sysfs: lis...
200
  BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES);
3b5bb73bd   David Sterba   btrfs: sysfs: add...
201
  BTRFS_FEAT_ATTR_COMPAT_RO(free_space_tree, FREE_SPACE_TREE);
079b72bca   Jeff Mahoney   btrfs: publish su...
202
203
204
205
206
207
  
  static struct attribute *btrfs_supported_feature_attrs[] = {
  	BTRFS_FEAT_ATTR_PTR(mixed_backref),
  	BTRFS_FEAT_ATTR_PTR(default_subvol),
  	BTRFS_FEAT_ATTR_PTR(mixed_groups),
  	BTRFS_FEAT_ATTR_PTR(compress_lzo),
5c1aab1dd   Nick Terrell   btrfs: Add zstd s...
208
  	BTRFS_FEAT_ATTR_PTR(compress_zstd),
079b72bca   Jeff Mahoney   btrfs: publish su...
209
210
211
212
  	BTRFS_FEAT_ATTR_PTR(big_metadata),
  	BTRFS_FEAT_ATTR_PTR(extended_iref),
  	BTRFS_FEAT_ATTR_PTR(raid56),
  	BTRFS_FEAT_ATTR_PTR(skinny_metadata),
c736c095d   David Sterba   btrfs: sysfs: lis...
213
  	BTRFS_FEAT_ATTR_PTR(no_holes),
3b5bb73bd   David Sterba   btrfs: sysfs: add...
214
  	BTRFS_FEAT_ATTR_PTR(free_space_tree),
079b72bca   Jeff Mahoney   btrfs: publish su...
215
216
217
218
219
  	NULL
  };
  
  static const struct attribute_group btrfs_feature_attr_group = {
  	.name = "features",
510d73600   Jeff Mahoney   btrfs: publish pe...
220
  	.is_visible = btrfs_feature_visible,
079b72bca   Jeff Mahoney   btrfs: publish su...
221
222
  	.attrs = btrfs_supported_feature_attrs,
  };
58176a960   Josef Bacik   Btrfs: Add per-ro...
223

6ab0a2029   Jeff Mahoney   btrfs: publish al...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
  static ssize_t btrfs_show_u64(u64 *value_ptr, spinlock_t *lock, char *buf)
  {
  	u64 val;
  	if (lock)
  		spin_lock(lock);
  	val = *value_ptr;
  	if (lock)
  		spin_unlock(lock);
  	return snprintf(buf, PAGE_SIZE, "%llu
  ", val);
  }
  
  static ssize_t global_rsv_size_show(struct kobject *kobj,
  				    struct kobj_attribute *ka, char *buf)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
  	struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
  	return btrfs_show_u64(&block_rsv->size, &block_rsv->lock, buf);
  }
98b3d389e   Anand Jain   btrfs: code optim...
243
  BTRFS_ATTR(global_rsv_size, global_rsv_size_show);
6ab0a2029   Jeff Mahoney   btrfs: publish al...
244
245
246
247
248
249
250
251
  
  static ssize_t global_rsv_reserved_show(struct kobject *kobj,
  					struct kobj_attribute *a, char *buf)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
  	struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
  	return btrfs_show_u64(&block_rsv->reserved, &block_rsv->lock, buf);
  }
98b3d389e   Anand Jain   btrfs: code optim...
252
  BTRFS_ATTR(global_rsv_reserved, global_rsv_reserved_show);
6ab0a2029   Jeff Mahoney   btrfs: publish al...
253
254
  
  #define to_space_info(_kobj) container_of(_kobj, struct btrfs_space_info, kobj)
c1895442b   Jeff Mahoney   btrfs: allocate r...
255
  #define to_raid_kobj(_kobj) container_of(_kobj, struct raid_kobject, kobj)
6ab0a2029   Jeff Mahoney   btrfs: publish al...
256
257
258
259
260
261
262
263
264
265
266
267
  
  static ssize_t raid_bytes_show(struct kobject *kobj,
  			       struct kobj_attribute *attr, char *buf);
  BTRFS_RAID_ATTR(total_bytes, raid_bytes_show);
  BTRFS_RAID_ATTR(used_bytes, raid_bytes_show);
  
  static ssize_t raid_bytes_show(struct kobject *kobj,
  			       struct kobj_attribute *attr, char *buf)
  
  {
  	struct btrfs_space_info *sinfo = to_space_info(kobj->parent);
  	struct btrfs_block_group_cache *block_group;
c1895442b   Jeff Mahoney   btrfs: allocate r...
268
  	int index = to_raid_kobj(kobj)->raid_type;
6ab0a2029   Jeff Mahoney   btrfs: publish al...
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  	u64 val = 0;
  
  	down_read(&sinfo->groups_sem);
  	list_for_each_entry(block_group, &sinfo->block_groups[index], list) {
  		if (&attr->attr == BTRFS_RAID_ATTR_PTR(total_bytes))
  			val += block_group->key.offset;
  		else
  			val += btrfs_block_group_used(&block_group->item);
  	}
  	up_read(&sinfo->groups_sem);
  	return snprintf(buf, PAGE_SIZE, "%llu
  ", val);
  }
  
  static struct attribute *raid_attributes[] = {
  	BTRFS_RAID_ATTR_PTR(total_bytes),
  	BTRFS_RAID_ATTR_PTR(used_bytes),
  	NULL
  };
  
  static void release_raid_kobj(struct kobject *kobj)
  {
c1895442b   Jeff Mahoney   btrfs: allocate r...
291
  	kfree(to_raid_kobj(kobj));
6ab0a2029   Jeff Mahoney   btrfs: publish al...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
  }
  
  struct kobj_type btrfs_raid_ktype = {
  	.sysfs_ops = &kobj_sysfs_ops,
  	.release = release_raid_kobj,
  	.default_attrs = raid_attributes,
  };
  
  #define SPACE_INFO_ATTR(field)						\
  static ssize_t btrfs_space_info_show_##field(struct kobject *kobj,	\
  					     struct kobj_attribute *a,	\
  					     char *buf)			\
  {									\
  	struct btrfs_space_info *sinfo = to_space_info(kobj);		\
  	return btrfs_show_u64(&sinfo->field, &sinfo->lock, buf);	\
  }									\
98b3d389e   Anand Jain   btrfs: code optim...
308
  BTRFS_ATTR(field, btrfs_space_info_show_##field)
6ab0a2029   Jeff Mahoney   btrfs: publish al...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  
  static ssize_t btrfs_space_info_show_total_bytes_pinned(struct kobject *kobj,
  						       struct kobj_attribute *a,
  						       char *buf)
  {
  	struct btrfs_space_info *sinfo = to_space_info(kobj);
  	s64 val = percpu_counter_sum(&sinfo->total_bytes_pinned);
  	return snprintf(buf, PAGE_SIZE, "%lld
  ", val);
  }
  
  SPACE_INFO_ATTR(flags);
  SPACE_INFO_ATTR(total_bytes);
  SPACE_INFO_ATTR(bytes_used);
  SPACE_INFO_ATTR(bytes_pinned);
  SPACE_INFO_ATTR(bytes_reserved);
  SPACE_INFO_ATTR(bytes_may_use);
c1fd5c30d   Wang Xiaoguang   btrfs: add missin...
326
  SPACE_INFO_ATTR(bytes_readonly);
6ab0a2029   Jeff Mahoney   btrfs: publish al...
327
328
  SPACE_INFO_ATTR(disk_used);
  SPACE_INFO_ATTR(disk_total);
98b3d389e   Anand Jain   btrfs: code optim...
329
  BTRFS_ATTR(total_bytes_pinned, btrfs_space_info_show_total_bytes_pinned);
6ab0a2029   Jeff Mahoney   btrfs: publish al...
330
331
332
333
334
335
336
337
  
  static struct attribute *space_info_attrs[] = {
  	BTRFS_ATTR_PTR(flags),
  	BTRFS_ATTR_PTR(total_bytes),
  	BTRFS_ATTR_PTR(bytes_used),
  	BTRFS_ATTR_PTR(bytes_pinned),
  	BTRFS_ATTR_PTR(bytes_reserved),
  	BTRFS_ATTR_PTR(bytes_may_use),
c1fd5c30d   Wang Xiaoguang   btrfs: add missin...
338
  	BTRFS_ATTR_PTR(bytes_readonly),
6ab0a2029   Jeff Mahoney   btrfs: publish al...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
  	BTRFS_ATTR_PTR(disk_used),
  	BTRFS_ATTR_PTR(disk_total),
  	BTRFS_ATTR_PTR(total_bytes_pinned),
  	NULL,
  };
  
  static void space_info_release(struct kobject *kobj)
  {
  	struct btrfs_space_info *sinfo = to_space_info(kobj);
  	percpu_counter_destroy(&sinfo->total_bytes_pinned);
  	kfree(sinfo);
  }
  
  struct kobj_type space_info_ktype = {
  	.sysfs_ops = &kobj_sysfs_ops,
  	.release = space_info_release,
  	.default_attrs = space_info_attrs,
  };
  
  static const struct attribute *allocation_attrs[] = {
  	BTRFS_ATTR_PTR(global_rsv_reserved),
  	BTRFS_ATTR_PTR(global_rsv_size),
  	NULL,
  };
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
363
364
365
366
  static ssize_t btrfs_label_show(struct kobject *kobj,
  				struct kobj_attribute *a, char *buf)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
48fcc3ff7   Satoru Takeuchi   btrfs: label shou...
367
  	char *label = fs_info->super_copy->label;
ee17fc800   David Sterba   btrfs: sysfs: pro...
368
369
370
371
372
373
374
375
  	ssize_t ret;
  
  	spin_lock(&fs_info->super_lock);
  	ret = snprintf(buf, PAGE_SIZE, label[0] ? "%s
  " : "%s", label);
  	spin_unlock(&fs_info->super_lock);
  
  	return ret;
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
376
377
378
379
380
381
382
  }
  
  static ssize_t btrfs_label_store(struct kobject *kobj,
  				 struct kobj_attribute *a,
  				 const char *buf, size_t len)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
48fcc3ff7   Satoru Takeuchi   btrfs: label shou...
383
  	size_t p_len;
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
384

66ac9fe7b   David Sterba   btrfs: add check ...
385
386
  	if (!fs_info)
  		return -EPERM;
bc98a42c1   David Howells   VFS: Convert sb->...
387
  	if (sb_rdonly(fs_info->sb))
79aec2b80   Anand Jain   btrfs: sysfs labe...
388
  		return -EROFS;
48fcc3ff7   Satoru Takeuchi   btrfs: label shou...
389
390
391
392
393
394
395
396
397
  	/*
  	 * p_len is the len until the first occurrence of either
  	 * '
  ' or '\0'
  	 */
  	p_len = strcspn(buf, "
  ");
  
  	if (p_len >= BTRFS_LABEL_SIZE)
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
398
  		return -EINVAL;
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
399

a6f69dc80   David Sterba   btrfs: move commi...
400
  	spin_lock(&fs_info->super_lock);
48fcc3ff7   Satoru Takeuchi   btrfs: label shou...
401
402
  	memset(fs_info->super_copy->label, 0, BTRFS_LABEL_SIZE);
  	memcpy(fs_info->super_copy->label, buf, p_len);
a6f69dc80   David Sterba   btrfs: move commi...
403
  	spin_unlock(&fs_info->super_lock);
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
404

a6f69dc80   David Sterba   btrfs: move commi...
405
406
407
408
409
  	/*
  	 * We don't want to do full transaction commit from inside sysfs
  	 */
  	btrfs_set_pending(fs_info, COMMIT);
  	wake_up_process(fs_info->transaction_kthread);
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
410

a6f69dc80   David Sterba   btrfs: move commi...
411
  	return len;
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
412
  }
20ee0825e   Anand Jain   btrfs: code optim...
413
  BTRFS_ATTR_RW(label, btrfs_label_show, btrfs_label_store);
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
414

df93589a1   David Sterba   btrfs: export mor...
415
416
417
418
  static ssize_t btrfs_nodesize_show(struct kobject *kobj,
  				struct kobj_attribute *a, char *buf)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
2b0509fa4   Greg Kroah-Hartman   Revert "btrfs: us...
419
420
  	return snprintf(buf, PAGE_SIZE, "%u
  ", fs_info->super_copy->nodesize);
df93589a1   David Sterba   btrfs: export mor...
421
  }
98b3d389e   Anand Jain   btrfs: code optim...
422
  BTRFS_ATTR(nodesize, btrfs_nodesize_show);
df93589a1   David Sterba   btrfs: export mor...
423
424
425
426
427
  
  static ssize_t btrfs_sectorsize_show(struct kobject *kobj,
  				struct kobj_attribute *a, char *buf)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
2b0509fa4   Greg Kroah-Hartman   Revert "btrfs: us...
428
429
430
  	return snprintf(buf, PAGE_SIZE, "%u
  ",
  			fs_info->super_copy->sectorsize);
df93589a1   David Sterba   btrfs: export mor...
431
  }
98b3d389e   Anand Jain   btrfs: code optim...
432
  BTRFS_ATTR(sectorsize, btrfs_sectorsize_show);
df93589a1   David Sterba   btrfs: export mor...
433
434
435
436
437
  
  static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,
  				struct kobj_attribute *a, char *buf)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
2b0509fa4   Greg Kroah-Hartman   Revert "btrfs: us...
438
439
440
  	return snprintf(buf, PAGE_SIZE, "%u
  ",
  			fs_info->super_copy->sectorsize);
df93589a1   David Sterba   btrfs: export mor...
441
  }
98b3d389e   Anand Jain   btrfs: code optim...
442
  BTRFS_ATTR(clone_alignment, btrfs_clone_alignment_show);
df93589a1   David Sterba   btrfs: export mor...
443

2723480a0   Sargun Dhillon   btrfs: Add quota_...
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
  static ssize_t quota_override_show(struct kobject *kobj,
  				   struct kobj_attribute *a, char *buf)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
  	int quota_override;
  
  	quota_override = test_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags);
  	return snprintf(buf, PAGE_SIZE, "%d
  ", quota_override);
  }
  
  static ssize_t quota_override_store(struct kobject *kobj,
  				    struct kobj_attribute *a,
  				    const char *buf, size_t len)
  {
  	struct btrfs_fs_info *fs_info = to_fs_info(kobj);
  	unsigned long knob;
  	int err;
  
  	if (!fs_info)
  		return -EPERM;
  
  	if (!capable(CAP_SYS_RESOURCE))
  		return -EPERM;
  
  	err = kstrtoul(buf, 10, &knob);
  	if (err)
  		return err;
  	if (knob > 1)
  		return -EINVAL;
  
  	if (knob)
  		set_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags);
  	else
  		clear_bit(BTRFS_FS_QUOTA_OVERRIDE, &fs_info->flags);
  
  	return len;
  }
  
  BTRFS_ATTR_RW(quota_override, quota_override_show, quota_override_store);
0dd2906f7   Anand Jain   Btrfs: sysfs: let...
484
  static const struct attribute *btrfs_attrs[] = {
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
485
  	BTRFS_ATTR_PTR(label),
df93589a1   David Sterba   btrfs: export mor...
486
487
488
  	BTRFS_ATTR_PTR(nodesize),
  	BTRFS_ATTR_PTR(sectorsize),
  	BTRFS_ATTR_PTR(clone_alignment),
2723480a0   Sargun Dhillon   btrfs: Add quota_...
489
  	BTRFS_ATTR_PTR(quota_override),
f8ba9c11f   Jeff Mahoney   btrfs: publish fs...
490
491
  	NULL,
  };
c1b7e4745   Anand Jain   Btrfs: rename sup...
492
  static void btrfs_release_fsid_kobj(struct kobject *kobj)
510d73600   Jeff Mahoney   btrfs: publish pe...
493
  {
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
494
  	struct btrfs_fs_devices *fs_devs = to_fs_devs(kobj);
248d200df   Anand Jain   Btrfs: sysfs: fix...
495

c1b7e4745   Anand Jain   Btrfs: rename sup...
496
  	memset(&fs_devs->fsid_kobj, 0, sizeof(struct kobject));
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
497
  	complete(&fs_devs->kobj_unregister);
510d73600   Jeff Mahoney   btrfs: publish pe...
498
499
500
501
  }
  
  static struct kobj_type btrfs_ktype = {
  	.sysfs_ops	= &kobj_sysfs_ops,
c1b7e4745   Anand Jain   Btrfs: rename sup...
502
  	.release	= btrfs_release_fsid_kobj,
510d73600   Jeff Mahoney   btrfs: publish pe...
503
  };
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
504
505
506
507
  static inline struct btrfs_fs_devices *to_fs_devs(struct kobject *kobj)
  {
  	if (kobj->ktype != &btrfs_ktype)
  		return NULL;
c1b7e4745   Anand Jain   Btrfs: rename sup...
508
  	return container_of(kobj, struct btrfs_fs_devices, fsid_kobj);
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
509
  }
510d73600   Jeff Mahoney   btrfs: publish pe...
510
511
512
513
  static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
  {
  	if (kobj->ktype != &btrfs_ktype)
  		return NULL;
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
514
  	return to_fs_devs(kobj)->fs_info;
510d73600   Jeff Mahoney   btrfs: publish pe...
515
  }
58176a960   Josef Bacik   Btrfs: Add per-ro...
516

e453d989e   Jeff Mahoney   btrfs: fix leaks ...
517
518
519
  #define NUM_FEATURE_BITS 64
  static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13];
  static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS];
e8c9f1860   David Sterba   btrfs: constify s...
520
  static const u64 supported_feature_masks[3] = {
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
  	[FEAT_COMPAT]    = BTRFS_FEATURE_COMPAT_SUPP,
  	[FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP,
  	[FEAT_INCOMPAT]  = BTRFS_FEATURE_INCOMPAT_SUPP,
  };
  
  static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add)
  {
  	int set;
  
  	for (set = 0; set < FEAT_MAX; set++) {
  		int i;
  		struct attribute *attrs[2];
  		struct attribute_group agroup = {
  			.name = "features",
  			.attrs = attrs,
  		};
  		u64 features = get_features(fs_info, set);
  		features &= ~supported_feature_masks[set];
  
  		if (!features)
  			continue;
  
  		attrs[1] = NULL;
  		for (i = 0; i < NUM_FEATURE_BITS; i++) {
  			struct btrfs_feature_attr *fa;
  
  			if (!(features & (1ULL << i)))
  				continue;
  
  			fa = &btrfs_feature_attrs[set][i];
  			attrs[0] = &fa->kobj_attr.attr;
  			if (add) {
  				int ret;
c1b7e4745   Anand Jain   Btrfs: rename sup...
554
  				ret = sysfs_merge_group(&fs_info->fs_devices->fsid_kobj,
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
555
556
557
558
  							&agroup);
  				if (ret)
  					return ret;
  			} else
c1b7e4745   Anand Jain   Btrfs: rename sup...
559
  				sysfs_unmerge_group(&fs_info->fs_devices->fsid_kobj,
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
560
561
562
563
564
565
  						    &agroup);
  		}
  
  	}
  	return 0;
  }
2e3e12815   Anand Jain   Btrfs: sysfs: pro...
566
  static void __btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
567
  {
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
568
569
570
571
  	if (fs_devs->device_dir_kobj) {
  		kobject_del(fs_devs->device_dir_kobj);
  		kobject_put(fs_devs->device_dir_kobj);
  		fs_devs->device_dir_kobj = NULL;
aaf133051   Anand Jain   Btrfs: sysfs: reo...
572
  	}
c1b7e4745   Anand Jain   Btrfs: rename sup...
573
574
575
  	if (fs_devs->fsid_kobj.state_initialized) {
  		kobject_del(&fs_devs->fsid_kobj);
  		kobject_put(&fs_devs->fsid_kobj);
f90fc5472   Anand Jain   Btrfs: Check if k...
576
577
  		wait_for_completion(&fs_devs->kobj_unregister);
  	}
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
578
  }
2e3e12815   Anand Jain   Btrfs: sysfs: pro...
579
  /* when fs_devs is NULL it will remove all fsid kobject */
1d1c1be37   Anand Jain   Btrfs: sysfs: btr...
580
  void btrfs_sysfs_remove_fsid(struct btrfs_fs_devices *fs_devs)
2e3e12815   Anand Jain   Btrfs: sysfs: pro...
581
582
583
584
585
586
587
588
589
590
591
592
  {
  	struct list_head *fs_uuids = btrfs_get_fs_uuids();
  
  	if (fs_devs) {
  		__btrfs_sysfs_remove_fsid(fs_devs);
  		return;
  	}
  
  	list_for_each_entry(fs_devs, fs_uuids, list) {
  		__btrfs_sysfs_remove_fsid(fs_devs);
  	}
  }
6618a59bf   Anand Jain   Btrfs: rename btr...
593
  void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info)
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
594
  {
5a13f4308   Anand Jain   Btrfs: sysfs: add...
595
  	btrfs_reset_fs_info_ptr(fs_info);
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
596
597
598
599
600
  	if (fs_info->space_info_kobj) {
  		sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
  		kobject_del(fs_info->space_info_kobj);
  		kobject_put(fs_info->space_info_kobj);
  	}
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
601
  	addrm_unknown_feature_attrs(fs_info, false);
c1b7e4745   Anand Jain   Btrfs: rename sup...
602
603
  	sysfs_remove_group(&fs_info->fs_devices->fsid_kobj, &btrfs_feature_attr_group);
  	sysfs_remove_files(&fs_info->fs_devices->fsid_kobj, btrfs_attrs);
325760404   Anand Jain   Btrfs: rename btr...
604
  	btrfs_sysfs_rm_device_link(fs_info->fs_devices, NULL);
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
605
  }
79da4fa4d   Jeff Mahoney   btrfs: publish un...
606
607
608
609
610
  const char * const btrfs_feature_set_names[3] = {
  	[FEAT_COMPAT]	 = "compat",
  	[FEAT_COMPAT_RO] = "compat_ro",
  	[FEAT_INCOMPAT]	 = "incompat",
  };
3b02a68a6   Jeff Mahoney   btrfs: use featur...
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
  char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags)
  {
  	size_t bufsize = 4096; /* safe max, 64 names * 64 bytes */
  	int len = 0;
  	int i;
  	char *str;
  
  	str = kmalloc(bufsize, GFP_KERNEL);
  	if (!str)
  		return str;
  
  	for (i = 0; i < ARRAY_SIZE(btrfs_feature_attrs[set]); i++) {
  		const char *name;
  
  		if (!(flags & (1ULL << i)))
  			continue;
  
  		name = btrfs_feature_attrs[set][i].kobj_attr.attr.name;
  		len += snprintf(str + len, bufsize - len, "%s%s",
  				len ? "," : "", name);
  	}
  
  	return str;
  }
79da4fa4d   Jeff Mahoney   btrfs: publish un...
635
636
637
638
639
640
641
642
643
  static void init_feature_attrs(void)
  {
  	struct btrfs_feature_attr *fa;
  	int set, i;
  
  	BUILD_BUG_ON(ARRAY_SIZE(btrfs_unknown_feature_names) !=
  		     ARRAY_SIZE(btrfs_feature_attrs));
  	BUILD_BUG_ON(ARRAY_SIZE(btrfs_unknown_feature_names[0]) !=
  		     ARRAY_SIZE(btrfs_feature_attrs[0]));
3b02a68a6   Jeff Mahoney   btrfs: use featur...
644
645
646
  	memset(btrfs_feature_attrs, 0, sizeof(btrfs_feature_attrs));
  	memset(btrfs_unknown_feature_names, 0,
  	       sizeof(btrfs_unknown_feature_names));
79da4fa4d   Jeff Mahoney   btrfs: publish un...
647
648
649
  	for (i = 0; btrfs_supported_feature_attrs[i]; i++) {
  		struct btrfs_feature_attr *sfa;
  		struct attribute *a = btrfs_supported_feature_attrs[i];
3b02a68a6   Jeff Mahoney   btrfs: use featur...
650
  		int bit;
79da4fa4d   Jeff Mahoney   btrfs: publish un...
651
  		sfa = attr_to_btrfs_feature_attr(a);
3b02a68a6   Jeff Mahoney   btrfs: use featur...
652
653
  		bit = ilog2(sfa->feature_bit);
  		fa = &btrfs_feature_attrs[sfa->feature_set][bit];
79da4fa4d   Jeff Mahoney   btrfs: publish un...
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
  
  		fa->kobj_attr.attr.name = sfa->kobj_attr.attr.name;
  	}
  
  	for (set = 0; set < FEAT_MAX; set++) {
  		for (i = 0; i < ARRAY_SIZE(btrfs_feature_attrs[set]); i++) {
  			char *name = btrfs_unknown_feature_names[set][i];
  			fa = &btrfs_feature_attrs[set][i];
  
  			if (fa->kobj_attr.attr.name)
  				continue;
  
  			snprintf(name, 13, "%s:%u",
  				 btrfs_feature_set_names[set], i);
  
  			fa->kobj_attr.attr.name = name;
  			fa->kobj_attr.attr.mode = S_IRUGO;
  			fa->feature_set = set;
  			fa->feature_bit = 1ULL << i;
  		}
  	}
  }
e7e1aa9c9   Anand Jain   Btrfs: sysfs: fix...
676
  /* when one_device is NULL, it removes all device links */
325760404   Anand Jain   Btrfs: rename btr...
677
  int btrfs_sysfs_rm_device_link(struct btrfs_fs_devices *fs_devices,
99994cde9   Anand Jain   btrfs: dev delete...
678
679
680
681
  		struct btrfs_device *one_device)
  {
  	struct hd_struct *disk;
  	struct kobject *disk_kobj;
6c14a1641   Anand Jain   Btrfs: sysfs btrf...
682
  	if (!fs_devices->device_dir_kobj)
99994cde9   Anand Jain   btrfs: dev delete...
683
  		return -EINVAL;
87fa3bb07   Liu Bo   Btrfs: fix regres...
684
  	if (one_device && one_device->bdev) {
99994cde9   Anand Jain   btrfs: dev delete...
685
686
  		disk = one_device->bdev->bd_part;
  		disk_kobj = &part_to_dev(disk)->kobj;
6c14a1641   Anand Jain   Btrfs: sysfs btrf...
687
  		sysfs_remove_link(fs_devices->device_dir_kobj,
99994cde9   Anand Jain   btrfs: dev delete...
688
689
  						disk_kobj->name);
  	}
e7e1aa9c9   Anand Jain   Btrfs: sysfs: fix...
690
691
692
693
  	if (one_device)
  		return 0;
  
  	list_for_each_entry(one_device,
6c14a1641   Anand Jain   Btrfs: sysfs btrf...
694
  			&fs_devices->devices, dev_list) {
e7e1aa9c9   Anand Jain   Btrfs: sysfs: fix...
695
696
697
698
  		if (!one_device->bdev)
  			continue;
  		disk = one_device->bdev->bd_part;
  		disk_kobj = &part_to_dev(disk)->kobj;
6c14a1641   Anand Jain   Btrfs: sysfs btrf...
699
  		sysfs_remove_link(fs_devices->device_dir_kobj,
e7e1aa9c9   Anand Jain   Btrfs: sysfs: fix...
700
701
  						disk_kobj->name);
  	}
99994cde9   Anand Jain   btrfs: dev delete...
702
703
  	return 0;
  }
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
704
  int btrfs_sysfs_add_device(struct btrfs_fs_devices *fs_devs)
29e5be240   Jeff Mahoney   btrfs: publish de...
705
  {
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
706
707
  	if (!fs_devs->device_dir_kobj)
  		fs_devs->device_dir_kobj = kobject_create_and_add("devices",
c1b7e4745   Anand Jain   Btrfs: rename sup...
708
  						&fs_devs->fsid_kobj);
0d39376aa   Anand Jain   btrfs: dev add sh...
709

2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
710
  	if (!fs_devs->device_dir_kobj)
29e5be240   Jeff Mahoney   btrfs: publish de...
711
  		return -ENOMEM;
00c921c23   Anand Jain   Btrfs: sysfs: sep...
712
713
  	return 0;
  }
e3bd6973b   Anand Jain   Btrfs: rename btr...
714
  int btrfs_sysfs_add_device_link(struct btrfs_fs_devices *fs_devices,
1ba43816a   Anand Jain   Btrfs: sysfs btrf...
715
  				struct btrfs_device *one_device)
00c921c23   Anand Jain   Btrfs: sysfs: sep...
716
717
  {
  	int error = 0;
00c921c23   Anand Jain   Btrfs: sysfs: sep...
718
  	struct btrfs_device *dev;
29e5be240   Jeff Mahoney   btrfs: publish de...
719
  	list_for_each_entry(dev, &fs_devices->devices, dev_list) {
f085381e6   Anand Jain   btrfs: fix null p...
720
721
722
723
724
  		struct hd_struct *disk;
  		struct kobject *disk_kobj;
  
  		if (!dev->bdev)
  			continue;
0d39376aa   Anand Jain   btrfs: dev add sh...
725
726
  		if (one_device && one_device != dev)
  			continue;
f085381e6   Anand Jain   btrfs: fix null p...
727
728
  		disk = dev->bdev->bd_part;
  		disk_kobj = &part_to_dev(disk)->kobj;
29e5be240   Jeff Mahoney   btrfs: publish de...
729

2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
730
  		error = sysfs_create_link(fs_devices->device_dir_kobj,
29e5be240   Jeff Mahoney   btrfs: publish de...
731
732
733
734
735
736
737
  					  disk_kobj, disk_kobj->name);
  		if (error)
  			break;
  	}
  
  	return error;
  }
510d73600   Jeff Mahoney   btrfs: publish pe...
738
739
  /* /sys/fs/btrfs/ entry */
  static struct kset *btrfs_kset;
1bae30982   David Sterba   btrfs: add simple...
740
741
742
743
744
  /* /sys/kernel/debug/btrfs */
  static struct dentry *btrfs_debugfs_root_dentry;
  
  /* Debugging tunables and exported data */
  u64 btrfs_debugfs_test;
720592157   Anand Jain   Btrfs: sysfs: int...
745
746
747
748
  /*
   * Can be called by the device discovery thread.
   * And parent can be specified for seed device
   */
0c10e2d48   Anand Jain   Btrfs: sysfs: mak...
749
  int btrfs_sysfs_add_fsid(struct btrfs_fs_devices *fs_devs,
720592157   Anand Jain   Btrfs: sysfs: int...
750
  				struct kobject *parent)
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
751
752
  {
  	int error;
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
753
  	init_completion(&fs_devs->kobj_unregister);
c1b7e4745   Anand Jain   Btrfs: rename sup...
754
755
  	fs_devs->fsid_kobj.kset = btrfs_kset;
  	error = kobject_init_and_add(&fs_devs->fsid_kobj,
24bd69cb0   Anand Jain   Btrfs: sysfs: add...
756
  				&btrfs_ktype, parent, "%pU", fs_devs->fsid);
720592157   Anand Jain   Btrfs: sysfs: int...
757
758
  	return error;
  }
96f3136e5   Anand Jain   Btrfs: rename btr...
759
  int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info)
720592157   Anand Jain   Btrfs: sysfs: int...
760
761
  {
  	int error;
2e7910d6c   Anand Jain   Btrfs: sysfs: mov...
762
  	struct btrfs_fs_devices *fs_devs = fs_info->fs_devices;
c1b7e4745   Anand Jain   Btrfs: rename sup...
763
  	struct kobject *fsid_kobj = &fs_devs->fsid_kobj;
720592157   Anand Jain   Btrfs: sysfs: int...
764

5a13f4308   Anand Jain   Btrfs: sysfs: add...
765
  	btrfs_set_fs_info_ptr(fs_info);
e3bd6973b   Anand Jain   Btrfs: rename btr...
766
  	error = btrfs_sysfs_add_device_link(fs_devs, NULL);
b7c35e81a   Anand Jain   Btrfs: sysfs: sep...
767
  	if (error)
aaf133051   Anand Jain   Btrfs: sysfs: reo...
768
  		return error;
aaf133051   Anand Jain   Btrfs: sysfs: reo...
769

c1b7e4745   Anand Jain   Btrfs: rename sup...
770
  	error = sysfs_create_files(fsid_kobj, btrfs_attrs);
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
771
  	if (error) {
325760404   Anand Jain   Btrfs: rename btr...
772
  		btrfs_sysfs_rm_device_link(fs_devs, NULL);
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
773
774
  		return error;
  	}
79da4fa4d   Jeff Mahoney   btrfs: publish un...
775

c1b7e4745   Anand Jain   Btrfs: rename sup...
776
  	error = sysfs_create_group(fsid_kobj,
0dd2906f7   Anand Jain   Btrfs: sysfs: let...
777
778
779
  				   &btrfs_feature_attr_group);
  	if (error)
  		goto failure;
e453d989e   Jeff Mahoney   btrfs: fix leaks ...
780
  	error = addrm_unknown_feature_attrs(fs_info, true);
79da4fa4d   Jeff Mahoney   btrfs: publish un...
781
782
  	if (error)
  		goto failure;
6ab0a2029   Jeff Mahoney   btrfs: publish al...
783
  	fs_info->space_info_kobj = kobject_create_and_add("allocation",
c1b7e4745   Anand Jain   Btrfs: rename sup...
784
  						  fsid_kobj);
6ab0a2029   Jeff Mahoney   btrfs: publish al...
785
786
787
788
789
790
791
792
  	if (!fs_info->space_info_kobj) {
  		error = -ENOMEM;
  		goto failure;
  	}
  
  	error = sysfs_create_files(fs_info->space_info_kobj, allocation_attrs);
  	if (error)
  		goto failure;
79da4fa4d   Jeff Mahoney   btrfs: publish un...
793
794
  	return 0;
  failure:
6618a59bf   Anand Jain   Btrfs: rename btr...
795
  	btrfs_sysfs_remove_mounted(fs_info);
5ac1d209f   Jeff Mahoney   btrfs: publish pe...
796
797
  	return error;
  }
444e75169   David Sterba   btrfs: sysfs: int...
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
  
  /*
   * Change per-fs features in /sys/fs/btrfs/UUID/features to match current
   * values in superblock. Call after any changes to incompat/compat_ro flags
   */
  void btrfs_sysfs_feature_update(struct btrfs_fs_info *fs_info,
  		u64 bit, enum btrfs_feature_set set)
  {
  	struct btrfs_fs_devices *fs_devs;
  	struct kobject *fsid_kobj;
  	u64 features;
  	int ret;
  
  	if (!fs_info)
  		return;
  
  	features = get_features(fs_info, set);
  	ASSERT(bit & supported_feature_masks[set]);
  
  	fs_devs = fs_info->fs_devices;
  	fsid_kobj = &fs_devs->fsid_kobj;
bf6092066   David Sterba   btrfs: sysfs: che...
819
820
  	if (!fsid_kobj->state_initialized)
  		return;
444e75169   David Sterba   btrfs: sysfs: int...
821
822
823
824
825
826
827
  	/*
  	 * FIXME: this is too heavy to update just one value, ideally we'd like
  	 * to use sysfs_update_group but some refactoring is needed first.
  	 */
  	sysfs_remove_group(fsid_kobj, &btrfs_feature_attr_group);
  	ret = sysfs_create_group(fsid_kobj, &btrfs_feature_attr_group);
  }
1bae30982   David Sterba   btrfs: add simple...
828
829
830
831
832
833
  static int btrfs_init_debugfs(void)
  {
  #ifdef CONFIG_DEBUG_FS
  	btrfs_debugfs_root_dentry = debugfs_create_dir("btrfs", NULL);
  	if (!btrfs_debugfs_root_dentry)
  		return -ENOMEM;
b0de6c4c8   David Sterba   btrfs: create exa...
834
835
836
837
838
839
840
  	/*
  	 * Example code, how to export data through debugfs.
  	 *
  	 * file:        /sys/kernel/debug/btrfs/test
  	 * contents of: btrfs_debugfs_test
  	 */
  #ifdef CONFIG_BTRFS_DEBUG
07f6a4804   Eric Sandeen   btrfs: fix perms ...
841
  	debugfs_create_u64("test", S_IRUGO | S_IWUSR, btrfs_debugfs_root_dentry,
1bae30982   David Sterba   btrfs: add simple...
842
843
  			&btrfs_debugfs_test);
  #endif
b0de6c4c8   David Sterba   btrfs: create exa...
844
845
  
  #endif
1bae30982   David Sterba   btrfs: add simple...
846
847
  	return 0;
  }
b214107ed   Christoph Hellwig   Btrfs: trivial sp...
848
  int btrfs_init_sysfs(void)
58176a960   Josef Bacik   Btrfs: Add per-ro...
849
  {
079b72bca   Jeff Mahoney   btrfs: publish su...
850
  	int ret;
1bae30982   David Sterba   btrfs: add simple...
851

e3fe4e712   Greg Kroah-Hartman   btrfs: fixes for ...
852
853
854
  	btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
  	if (!btrfs_kset)
  		return -ENOMEM;
079b72bca   Jeff Mahoney   btrfs: publish su...
855

1bae30982   David Sterba   btrfs: add simple...
856
857
  	ret = btrfs_init_debugfs();
  	if (ret)
001a648df   Filipe Manana   Btrfs: add missin...
858
  		goto out1;
79da4fa4d   Jeff Mahoney   btrfs: publish un...
859

1bae30982   David Sterba   btrfs: add simple...
860
  	init_feature_attrs();
079b72bca   Jeff Mahoney   btrfs: publish su...
861
  	ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
001a648df   Filipe Manana   Btrfs: add missin...
862
863
864
865
866
867
868
869
  	if (ret)
  		goto out2;
  
  	return 0;
  out2:
  	debugfs_remove_recursive(btrfs_debugfs_root_dentry);
  out1:
  	kset_unregister(btrfs_kset);
079b72bca   Jeff Mahoney   btrfs: publish su...
870

1bae30982   David Sterba   btrfs: add simple...
871
  	return ret;
58176a960   Josef Bacik   Btrfs: Add per-ro...
872
  }
b214107ed   Christoph Hellwig   Btrfs: trivial sp...
873
  void btrfs_exit_sysfs(void)
58176a960   Josef Bacik   Btrfs: Add per-ro...
874
  {
079b72bca   Jeff Mahoney   btrfs: publish su...
875
  	sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group);
e3fe4e712   Greg Kroah-Hartman   btrfs: fixes for ...
876
  	kset_unregister(btrfs_kset);
1bae30982   David Sterba   btrfs: add simple...
877
  	debugfs_remove_recursive(btrfs_debugfs_root_dentry);
58176a960   Josef Bacik   Btrfs: Add per-ro...
878
  }
55d474148   Chris Mason   Btrfs: Disable sy...
879