Blame view

fs/nilfs2/the_nilfs.c 21.2 KB
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  /*
   * the_nilfs.c - the_nilfs shared structure.
   *
   * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   *
   * Written by Ryusuke Konishi <ryusuke@osrg.net>
   *
   */
  
  #include <linux/buffer_head.h>
  #include <linux/slab.h>
  #include <linux/blkdev.h>
  #include <linux/backing-dev.h>
9b1fc4e49   Ryusuke Konishi   nilfs2: move next...
28
  #include <linux/random.h>
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
29
  #include <linux/crc32.h>
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
30
31
32
33
34
35
  #include "nilfs.h"
  #include "segment.h"
  #include "alloc.h"
  #include "cpfile.h"
  #include "sufile.h"
  #include "dat.h"
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
36
  #include "segbuf.h"
33c8e57c8   Ryusuke Konishi   nilfs2: get rid o...
37

6c1251608   Ryusuke Konishi   nilfs2: implement...
38
  static int nilfs_valid_sb(struct nilfs_super_block *sbp);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
39
40
41
42
43
44
45
  void nilfs_set_last_segment(struct the_nilfs *nilfs,
  			    sector_t start_blocknr, u64 seq, __u64 cno)
  {
  	spin_lock(&nilfs->ns_last_segment_lock);
  	nilfs->ns_last_pseg = start_blocknr;
  	nilfs->ns_last_seq = seq;
  	nilfs->ns_last_cno = cno;
325020477   Ryusuke Konishi   nilfs2: do not up...
46
47
48
49
50
51
52
53
54
55
  
  	if (!nilfs_sb_dirty(nilfs)) {
  		if (nilfs->ns_prev_seq == nilfs->ns_last_seq)
  			goto stay_cursor;
  
  		set_nilfs_sb_dirty(nilfs);
  	}
  	nilfs->ns_prev_seq = nilfs->ns_last_seq;
  
   stay_cursor:
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
56
57
58
59
  	spin_unlock(&nilfs->ns_last_segment_lock);
  }
  
  /**
348fe8da1   Ryusuke Konishi   nilfs2: simplify ...
60
   * alloc_nilfs - allocate a nilfs object
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
61
62
   * @bdev: block device to which the_nilfs is related
   *
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
63
64
65
   * Return Value: On success, pointer to the_nilfs is returned.
   * On error, NULL is returned.
   */
348fe8da1   Ryusuke Konishi   nilfs2: simplify ...
66
  struct the_nilfs *alloc_nilfs(struct block_device *bdev)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
67
68
69
70
71
72
73
74
  {
  	struct the_nilfs *nilfs;
  
  	nilfs = kzalloc(sizeof(*nilfs), GFP_KERNEL);
  	if (!nilfs)
  		return NULL;
  
  	nilfs->ns_bdev = bdev;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
75
76
  	atomic_set(&nilfs->ns_ndirtyblks, 0);
  	init_rwsem(&nilfs->ns_sem);
572d8b394   Ryusuke Konishi   nilfs2: fix deadl...
77
  	mutex_init(&nilfs->ns_snapshot_mount_mutex);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
78
  	INIT_LIST_HEAD(&nilfs->ns_dirty_files);
263d90cef   Ryusuke Konishi   nilfs2: remove ow...
79
  	INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
80
  	spin_lock_init(&nilfs->ns_inode_lock);
9b1fc4e49   Ryusuke Konishi   nilfs2: move next...
81
  	spin_lock_init(&nilfs->ns_next_gen_lock);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
82
  	spin_lock_init(&nilfs->ns_last_segment_lock);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
83
84
  	nilfs->ns_cptree = RB_ROOT;
  	spin_lock_init(&nilfs->ns_cptree_lock);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
85
  	init_rwsem(&nilfs->ns_segctor_sem);
caa05d49d   Vyacheslav Dubeyko   nilfs2: add /sys/...
86
  	nilfs->ns_sb_update_freq = NILFS_SB_FREQ;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
87
88
89
90
91
  
  	return nilfs;
  }
  
  /**
348fe8da1   Ryusuke Konishi   nilfs2: simplify ...
92
93
   * destroy_nilfs - destroy nilfs object
   * @nilfs: nilfs object to be released
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
94
   */
348fe8da1   Ryusuke Konishi   nilfs2: simplify ...
95
  void destroy_nilfs(struct the_nilfs *nilfs)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
96
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
97
  	might_sleep();
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
98
  	if (nilfs_init(nilfs)) {
dd70edbde   Vyacheslav Dubeyko   nilfs2: integrate...
99
  		nilfs_sysfs_delete_device_group(nilfs);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
100
101
  		brelse(nilfs->ns_sbh[0]);
  		brelse(nilfs->ns_sbh[1]);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
102
103
104
  	}
  	kfree(nilfs);
  }
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
105
106
  static int nilfs_load_super_root(struct the_nilfs *nilfs,
  				 struct super_block *sb, sector_t sr_block)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
107
108
109
  {
  	struct buffer_head *bh_sr;
  	struct nilfs_super_root *raw_sr;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
110
  	struct nilfs_super_block **sbp = nilfs->ns_sbp;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
111
  	struct nilfs_inode *rawi;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
112
113
114
  	unsigned dat_entry_size, segment_usage_size, checkpoint_size;
  	unsigned inode_size;
  	int err;
8b94025c0   Ryusuke Konishi   nilfs2: refactor ...
115
  	err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
116
117
118
119
  	if (unlikely(err))
  		return err;
  
  	down_read(&nilfs->ns_sem);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
120
121
122
  	dat_entry_size = le16_to_cpu(sbp[0]->s_dat_entry_size);
  	checkpoint_size = le16_to_cpu(sbp[0]->s_checkpoint_size);
  	segment_usage_size = le16_to_cpu(sbp[0]->s_segment_usage_size);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
123
124
125
  	up_read(&nilfs->ns_sem);
  
  	inode_size = nilfs->ns_inode_size;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
126
127
128
  	rawi = (void *)bh_sr->b_data + NILFS_SR_DAT_OFFSET(inode_size);
  	err = nilfs_dat_read(sb, dat_entry_size, rawi, &nilfs->ns_dat);
  	if (err)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
129
  		goto failed;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
130
131
132
  	rawi = (void *)bh_sr->b_data + NILFS_SR_CPFILE_OFFSET(inode_size);
  	err = nilfs_cpfile_read(sb, checkpoint_size, rawi, &nilfs->ns_cpfile);
  	if (err)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
133
  		goto failed_dat;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
134
135
136
137
  	rawi = (void *)bh_sr->b_data + NILFS_SR_SUFILE_OFFSET(inode_size);
  	err = nilfs_sufile_read(sb, segment_usage_size, rawi,
  				&nilfs->ns_sufile);
  	if (err)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
138
  		goto failed_cpfile;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
139
140
141
142
143
144
  	raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
  	nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime);
  
   failed:
  	brelse(bh_sr);
  	return err;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
145
   failed_cpfile:
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
146
  	iput(nilfs->ns_cpfile);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
147
148
  
   failed_dat:
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
149
  	iput(nilfs->ns_dat);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  	goto failed;
  }
  
  static void nilfs_init_recovery_info(struct nilfs_recovery_info *ri)
  {
  	memset(ri, 0, sizeof(*ri));
  	INIT_LIST_HEAD(&ri->ri_used_segments);
  }
  
  static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri)
  {
  	nilfs_dispose_segment_list(&ri->ri_used_segments);
  }
  
  /**
843d63baa   Ryusuke Konishi   nilfs2: separate ...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
   * nilfs_store_log_cursor - load log cursor from a super block
   * @nilfs: nilfs object
   * @sbp: buffer storing super block to be read
   *
   * nilfs_store_log_cursor() reads the last position of the log
   * containing a super root from a given super block, and initializes
   * relevant information on the nilfs object preparatory for log
   * scanning and recovery.
   */
  static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
  				  struct nilfs_super_block *sbp)
  {
  	int ret = 0;
  
  	nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg);
  	nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
  	nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);
325020477   Ryusuke Konishi   nilfs2: do not up...
182
  	nilfs->ns_prev_seq = nilfs->ns_last_seq;
843d63baa   Ryusuke Konishi   nilfs2: separate ...
183
184
185
186
187
188
189
190
191
192
193
194
195
  	nilfs->ns_seg_seq = nilfs->ns_last_seq;
  	nilfs->ns_segnum =
  		nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
  	nilfs->ns_cno = nilfs->ns_last_cno + 1;
  	if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
  		printk(KERN_ERR "NILFS invalid last segment number.
  ");
  		ret = -EINVAL;
  	}
  	return ret;
  }
  
  /**
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
196
197
   * load_nilfs - load and recover the nilfs
   * @nilfs: the_nilfs structure to be released
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
198
   * @sb: super block isntance used to recover past segment
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
199
200
201
202
203
   *
   * load_nilfs() searches and load the latest super root,
   * attaches the last segment, and does recovery if needed.
   * The caller must call this exclusively for simultaneous mounts.
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
204
  int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
205
206
  {
  	struct nilfs_recovery_info ri;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
207
  	unsigned int s_flags = sb->s_flags;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
208
  	int really_read_only = bdev_read_only(nilfs->ns_bdev);
a057d2c01   Ryusuke Konishi   nilfs2: add helpe...
209
  	int valid_fs = nilfs_valid_fs(nilfs);
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
210
  	int err;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
211

f50a4c814   Ryusuke Konishi   nilfs2: move reco...
212
213
214
215
216
217
218
219
220
221
  	if (!valid_fs) {
  		printk(KERN_WARNING "NILFS warning: mounting unchecked fs
  ");
  		if (s_flags & MS_RDONLY) {
  			printk(KERN_INFO "NILFS: INFO: recovery "
  			       "required for readonly filesystem.
  ");
  			printk(KERN_INFO "NILFS: write access will "
  			       "be enabled during recovery.
  ");
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
222
  		}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
223
  	}
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
224
  	nilfs_init_recovery_info(&ri);
8b94025c0   Ryusuke Konishi   nilfs2: refactor ...
225
  	err = nilfs_search_super_root(nilfs, &ri);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
226
  	if (unlikely(err)) {
6c1251608   Ryusuke Konishi   nilfs2: implement...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
  		struct nilfs_super_block **sbp = nilfs->ns_sbp;
  		int blocksize;
  
  		if (err != -EINVAL)
  			goto scan_error;
  
  		if (!nilfs_valid_sb(sbp[1])) {
  			printk(KERN_WARNING
  			       "NILFS warning: unable to fall back to spare"
  			       "super block
  ");
  			goto scan_error;
  		}
  		printk(KERN_INFO
  		       "NILFS: try rollback from an earlier position
  ");
  
  		/*
  		 * restore super block with its spare and reconfigure
  		 * relevant states of the nilfs object.
  		 */
  		memcpy(sbp[0], sbp[1], nilfs->ns_sbsize);
  		nilfs->ns_crc_seed = le32_to_cpu(sbp[0]->s_crc_seed);
  		nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
  
  		/* verify consistency between two super blocks */
  		blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
  		if (blocksize != nilfs->ns_blocksize) {
  			printk(KERN_WARNING
  			       "NILFS warning: blocksize differs between "
  			       "two super blocks (%d != %d)
  ",
  			       blocksize, nilfs->ns_blocksize);
  			goto scan_error;
  		}
  
  		err = nilfs_store_log_cursor(nilfs, sbp[0]);
  		if (err)
  			goto scan_error;
  
  		/* drop clean flag to allow roll-forward and recovery */
  		nilfs->ns_mount_state &= ~NILFS_VALID_FS;
  		valid_fs = 0;
  
  		err = nilfs_search_super_root(nilfs, &ri);
  		if (err)
  			goto scan_error;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
274
  	}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
275
  	err = nilfs_load_super_root(nilfs, sb, ri.ri_super_root);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
276
277
278
279
280
  	if (unlikely(err)) {
  		printk(KERN_ERR "NILFS: error loading super root.
  ");
  		goto failed;
  	}
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
281
282
283
284
  	if (valid_fs)
  		goto skip_recovery;
  
  	if (s_flags & MS_RDONLY) {
c5ca48aab   Ryusuke Konishi   nilfs2: reject in...
285
  		__u64 features;
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
286
  		if (nilfs_test_opt(nilfs, NORECOVERY)) {
0234576d0   Ryusuke Konishi   nilfs2: add norec...
287
288
289
290
291
  			printk(KERN_INFO "NILFS: norecovery option specified. "
  			       "skipping roll-forward recovery
  ");
  			goto skip_recovery;
  		}
c5ca48aab   Ryusuke Konishi   nilfs2: reject in...
292
293
294
295
296
297
298
299
300
301
302
  		features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) &
  			~NILFS_FEATURE_COMPAT_RO_SUPP;
  		if (features) {
  			printk(KERN_ERR "NILFS: couldn't proceed with "
  			       "recovery because of unsupported optional "
  			       "features (%llx)
  ",
  			       (unsigned long long)features);
  			err = -EROFS;
  			goto failed_unload;
  		}
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
303
304
305
306
307
308
  		if (really_read_only) {
  			printk(KERN_ERR "NILFS: write access "
  			       "unavailable, cannot proceed.
  ");
  			err = -EROFS;
  			goto failed_unload;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
309
  		}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
310
  		sb->s_flags &= ~MS_RDONLY;
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
311
  	} else if (nilfs_test_opt(nilfs, NORECOVERY)) {
0234576d0   Ryusuke Konishi   nilfs2: add norec...
312
313
314
315
316
  		printk(KERN_ERR "NILFS: recovery cancelled because norecovery "
  		       "option was specified for a read/write mount
  ");
  		err = -EINVAL;
  		goto failed_unload;
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
317
  	}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
318
  	err = nilfs_salvage_orphan_logs(nilfs, sb, &ri);
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
319
320
321
322
  	if (err)
  		goto failed_unload;
  
  	down_write(&nilfs->ns_sem);
7ecaa46cf   Ryusuke Konishi   nilfs2: add nilfs...
323
  	nilfs->ns_mount_state |= NILFS_VALID_FS; /* set "clean" flag */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
324
  	err = nilfs_cleanup_super(sb);
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
325
326
327
328
329
330
331
  	up_write(&nilfs->ns_sem);
  
  	if (err) {
  		printk(KERN_ERR "NILFS: failed to update super block. "
  		       "recovery unfinished.
  ");
  		goto failed_unload;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
332
  	}
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
333
334
  	printk(KERN_INFO "NILFS: recovery complete.
  ");
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
335

f50a4c814   Ryusuke Konishi   nilfs2: move reco...
336
   skip_recovery:
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
337
  	nilfs_clear_recovery_info(&ri);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
338
  	sb->s_flags = s_flags;
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
339
  	return 0;
6c1251608   Ryusuke Konishi   nilfs2: implement...
340
341
342
343
   scan_error:
  	printk(KERN_ERR "NILFS: error searching super root.
  ");
  	goto failed;
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
344
   failed_unload:
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
345
346
347
  	iput(nilfs->ns_cpfile);
  	iput(nilfs->ns_sufile);
  	iput(nilfs->ns_dat);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
348
349
350
  
   failed:
  	nilfs_clear_recovery_info(&ri);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
351
  	sb->s_flags = s_flags;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
352
353
354
355
356
357
358
359
360
361
362
363
364
  	return err;
  }
  
  static unsigned long long nilfs_max_size(unsigned int blkbits)
  {
  	unsigned int max_bits;
  	unsigned long long res = MAX_LFS_FILESIZE; /* page cache limit */
  
  	max_bits = blkbits + NILFS_BMAP_KEY_BIT; /* bmap size limit */
  	if (max_bits < 64)
  		res = min_t(unsigned long long, res, (1ULL << max_bits) - 1);
  	return res;
  }
4e33f9eab   Ryusuke Konishi   nilfs2: implement...
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
  /**
   * nilfs_nrsvsegs - calculate the number of reserved segments
   * @nilfs: nilfs object
   * @nsegs: total number of segments
   */
  unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs)
  {
  	return max_t(unsigned long, NILFS_MIN_NRSVSEGS,
  		     DIV_ROUND_UP(nsegs * nilfs->ns_r_segments_percentage,
  				  100));
  }
  
  void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)
  {
  	nilfs->ns_nsegments = nsegs;
  	nilfs->ns_nrsvsegs = nilfs_nrsvsegs(nilfs, nsegs);
  }
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
382
383
  static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
  				   struct nilfs_super_block *sbp)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
384
  {
9566a7a85   Ryusuke Konishi   nilfs2: accept fu...
385
386
  	if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) {
  		printk(KERN_ERR "NILFS: unsupported revision "
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
387
388
389
390
391
392
393
394
  		       "(superblock rev.=%d.%d, current rev.=%d.%d). "
  		       "Please check the version of mkfs.nilfs.
  ",
  		       le32_to_cpu(sbp->s_rev_level),
  		       le16_to_cpu(sbp->s_minor_rev_level),
  		       NILFS_CURRENT_REV, NILFS_MINOR_REV);
  		return -EINVAL;
  	}
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
395
396
397
  	nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes);
  	if (nilfs->ns_sbsize > BLOCK_SIZE)
  		return -EINVAL;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
398
  	nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
0ec060d18   Ryusuke Konishi   nilfs2: verify me...
399
400
401
402
403
404
405
406
407
408
409
  	if (nilfs->ns_inode_size > nilfs->ns_blocksize) {
  		printk(KERN_ERR "NILFS: too large inode size: %d bytes.
  ",
  		       nilfs->ns_inode_size);
  		return -EINVAL;
  	} else if (nilfs->ns_inode_size < NILFS_MIN_INODE_SIZE) {
  		printk(KERN_ERR "NILFS: too small inode size: %d bytes.
  ",
  		       nilfs->ns_inode_size);
  		return -EINVAL;
  	}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
410
411
412
413
  	nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino);
  
  	nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
  	if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
c91cea11d   Ryusuke Konishi   nilfs2: remove wh...
414
415
  		printk(KERN_ERR "NILFS: too short segment.
  ");
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
416
417
418
419
  		return -EINVAL;
  	}
  
  	nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
420
421
  	nilfs->ns_r_segments_percentage =
  		le32_to_cpu(sbp->s_r_segments_percentage);
3d777a640   Haogang Chen   nilfs2: clamp ns_...
422
423
424
425
426
427
  	if (nilfs->ns_r_segments_percentage < 1 ||
  	    nilfs->ns_r_segments_percentage > 99) {
  		printk(KERN_ERR "NILFS: invalid reserved segments percentage.
  ");
  		return -EINVAL;
  	}
4e33f9eab   Ryusuke Konishi   nilfs2: implement...
428
  	nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments));
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
429
430
431
  	nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
  	return 0;
  }
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
432
433
434
435
436
437
438
439
440
441
442
443
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
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  static int nilfs_valid_sb(struct nilfs_super_block *sbp)
  {
  	static unsigned char sum[4];
  	const int sumoff = offsetof(struct nilfs_super_block, s_sum);
  	size_t bytes;
  	u32 crc;
  
  	if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC)
  		return 0;
  	bytes = le16_to_cpu(sbp->s_bytes);
  	if (bytes > BLOCK_SIZE)
  		return 0;
  	crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp,
  		       sumoff);
  	crc = crc32_le(crc, sum, 4);
  	crc = crc32_le(crc, (unsigned char *)sbp + sumoff + 4,
  		       bytes - sumoff - 4);
  	return crc == le32_to_cpu(sbp->s_sum);
  }
  
  static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
  {
  	return offset < ((le64_to_cpu(sbp->s_nsegments) *
  			  le32_to_cpu(sbp->s_blocks_per_segment)) <<
  			 (le32_to_cpu(sbp->s_log_block_size) + 10));
  }
  
  static void nilfs_release_super_block(struct the_nilfs *nilfs)
  {
  	int i;
  
  	for (i = 0; i < 2; i++) {
  		if (nilfs->ns_sbp[i]) {
  			brelse(nilfs->ns_sbh[i]);
  			nilfs->ns_sbh[i] = NULL;
  			nilfs->ns_sbp[i] = NULL;
  		}
  	}
  }
  
  void nilfs_fall_back_super_block(struct the_nilfs *nilfs)
  {
  	brelse(nilfs->ns_sbh[0]);
  	nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
  	nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
  	nilfs->ns_sbh[1] = NULL;
  	nilfs->ns_sbp[1] = NULL;
  }
  
  void nilfs_swap_super_block(struct the_nilfs *nilfs)
  {
  	struct buffer_head *tsbh = nilfs->ns_sbh[0];
  	struct nilfs_super_block *tsbp = nilfs->ns_sbp[0];
  
  	nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
  	nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
  	nilfs->ns_sbh[1] = tsbh;
  	nilfs->ns_sbp[1] = tsbp;
  }
  
  static int nilfs_load_super_block(struct the_nilfs *nilfs,
  				  struct super_block *sb, int blocksize,
  				  struct nilfs_super_block **sbpp)
  {
  	struct nilfs_super_block **sbp = nilfs->ns_sbp;
  	struct buffer_head **sbh = nilfs->ns_sbh;
  	u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size);
  	int valid[2], swp = 0;
  
  	sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize,
  					&sbh[0]);
  	sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]);
  
  	if (!sbp[0]) {
  		if (!sbp[1]) {
  			printk(KERN_ERR "NILFS: unable to read superblock
  ");
  			return -EIO;
  		}
  		printk(KERN_WARNING
4138ec238   Ryusuke Konishi   nilfs2: append bl...
512
513
514
515
  		       "NILFS warning: unable to read primary superblock "
  		       "(blocksize = %d)
  ", blocksize);
  	} else if (!sbp[1]) {
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
516
  		printk(KERN_WARNING
4138ec238   Ryusuke Konishi   nilfs2: append bl...
517
518
519
520
  		       "NILFS warning: unable to read secondary superblock "
  		       "(blocksize = %d)
  ", blocksize);
  	}
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
521

25294d8c3   Ryusuke Konishi   nilfs2: use check...
522
523
524
525
  	/*
  	 * Compare two super blocks and set 1 in swp if the secondary
  	 * super block is valid and newer.  Otherwise, set 0 in swp.
  	 */
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
526
527
  	valid[0] = nilfs_valid_sb(sbp[0]);
  	valid[1] = nilfs_valid_sb(sbp[1]);
25294d8c3   Ryusuke Konishi   nilfs2: use check...
528
529
530
  	swp = valid[1] && (!valid[0] ||
  			   le64_to_cpu(sbp[1]->s_last_cno) >
  			   le64_to_cpu(sbp[0]->s_last_cno));
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
531
532
533
534
535
  
  	if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) {
  		brelse(sbh[1]);
  		sbh[1] = NULL;
  		sbp[1] = NULL;
d7178c79d   Ryusuke Konishi   nilfs2: fix NULL ...
536
  		valid[1] = 0;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
537
538
539
540
541
542
543
544
545
  		swp = 0;
  	}
  	if (!valid[swp]) {
  		nilfs_release_super_block(nilfs);
  		printk(KERN_ERR "NILFS: Can't find nilfs on dev %s.
  ",
  		       sb->s_id);
  		return -EINVAL;
  	}
ea1a16f71   Ryusuke Konishi   nilfs2: fix false...
546
  	if (!valid[!swp])
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
547
  		printk(KERN_WARNING "NILFS warning: broken superblock. "
4138ec238   Ryusuke Konishi   nilfs2: append bl...
548
549
  		       "using spare superblock (blocksize = %d).
  ", blocksize);
ea1a16f71   Ryusuke Konishi   nilfs2: fix false...
550
  	if (swp)
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
551
  		nilfs_swap_super_block(nilfs);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
552

b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
553
554
  	nilfs->ns_sbwcount = 0;
  	nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
555
556
557
558
  	nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq);
  	*sbpp = sbp[0];
  	return 0;
  }
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
559
560
561
  /**
   * init_nilfs - initialize a NILFS instance.
   * @nilfs: the_nilfs structure
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
562
563
564
565
566
   * @sb: super block
   * @data: mount options
   *
   * init_nilfs() performs common initialization per block device (e.g.
   * reading the super block, getting disk layout information, initializing
f11459ad7   Ryusuke Konishi   nilfs2: do not al...
567
   * shared fields in the_nilfs).
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
568
569
570
571
   *
   * Return Value: On success, 0 is returned. On error, a negative error
   * code is returned.
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
572
  int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
573
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
574
  	struct nilfs_super_block *sbp;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
575
  	int blocksize;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
576
  	int err;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
577
578
  
  	down_write(&nilfs->ns_sem);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
579

89c0fd014   Ryusuke Konishi   nilfs2: reject fi...
580
  	blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
581
582
583
  	if (!blocksize) {
  		printk(KERN_ERR "NILFS: unable to set blocksize
  ");
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
584
585
586
  		err = -EINVAL;
  		goto out;
  	}
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
587
588
589
  	err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
  	if (err)
  		goto out;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
590
591
592
  	err = nilfs_store_magic_and_option(sb, sbp, data);
  	if (err)
  		goto failed_sbh;
c5ca48aab   Ryusuke Konishi   nilfs2: reject in...
593
594
595
  	err = nilfs_check_feature_compatibility(sb, sbp);
  	if (err)
  		goto failed_sbh;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
596
  	blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
89c0fd014   Ryusuke Konishi   nilfs2: reject fi...
597
598
599
600
601
602
603
604
  	if (blocksize < NILFS_MIN_BLOCK_SIZE ||
  	    blocksize > NILFS_MAX_BLOCK_SIZE) {
  		printk(KERN_ERR "NILFS: couldn't mount because of unsupported "
  		       "filesystem blocksize %d
  ", blocksize);
  		err = -EINVAL;
  		goto failed_sbh;
  	}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
605
  	if (sb->s_blocksize != blocksize) {
e1defc4ff   Martin K. Petersen   block: Do away wi...
606
  		int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
607
608
609
610
611
612
613
  
  		if (blocksize < hw_blocksize) {
  			printk(KERN_ERR
  			       "NILFS: blocksize %d too small for device "
  			       "(sector-size = %d).
  ",
  			       blocksize, hw_blocksize);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
614
  			err = -EINVAL;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
615
616
617
618
619
620
621
  			goto failed_sbh;
  		}
  		nilfs_release_super_block(nilfs);
  		sb_set_blocksize(sb, blocksize);
  
  		err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
  		if (err)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
622
623
624
  			goto out;
  			/* not failed_sbh; sbh is released automatically
  			   when reloading fails. */
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
625
626
  	}
  	nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
92c60ccaf   Ryusuke Konishi   nilfs2: add block...
627
  	nilfs->ns_blocksize = blocksize;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
628

9b1fc4e49   Ryusuke Konishi   nilfs2: move next...
629
630
  	get_random_bytes(&nilfs->ns_next_generation,
  			 sizeof(nilfs->ns_next_generation));
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
631
  	err = nilfs_store_disk_layout(nilfs, sbp);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
632
633
634
635
636
637
  	if (err)
  		goto failed_sbh;
  
  	sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
  
  	nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
638

843d63baa   Ryusuke Konishi   nilfs2: separate ...
639
640
  	err = nilfs_store_log_cursor(nilfs, sbp);
  	if (err)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
641
  		goto failed_sbh;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
642

dd70edbde   Vyacheslav Dubeyko   nilfs2: integrate...
643
644
645
  	err = nilfs_sysfs_create_device_group(sb);
  	if (err)
  		goto failed_sbh;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
646
647
648
649
650
651
652
  	set_nilfs_init(nilfs);
  	err = 0;
   out:
  	up_write(&nilfs->ns_sem);
  	return err;
  
   failed_sbh:
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
653
  	nilfs_release_super_block(nilfs);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
654
655
  	goto out;
  }
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
  int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump,
  			    size_t nsegs)
  {
  	sector_t seg_start, seg_end;
  	sector_t start = 0, nblocks = 0;
  	unsigned int sects_per_block;
  	__u64 *sn;
  	int ret = 0;
  
  	sects_per_block = (1 << nilfs->ns_blocksize_bits) /
  		bdev_logical_block_size(nilfs->ns_bdev);
  	for (sn = segnump; sn < segnump + nsegs; sn++) {
  		nilfs_get_segment_range(nilfs, *sn, &seg_start, &seg_end);
  
  		if (!nblocks) {
  			start = seg_start;
  			nblocks = seg_end - seg_start + 1;
  		} else if (start + nblocks == seg_start) {
  			nblocks += seg_end - seg_start + 1;
  		} else {
  			ret = blkdev_issue_discard(nilfs->ns_bdev,
  						   start * sects_per_block,
  						   nblocks * sects_per_block,
dd3932edd   Christoph Hellwig   block: remove BLK...
679
  						   GFP_NOFS, 0);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
680
681
682
683
684
685
686
687
688
  			if (ret < 0)
  				return ret;
  			nblocks = 0;
  		}
  	}
  	if (nblocks)
  		ret = blkdev_issue_discard(nilfs->ns_bdev,
  					   start * sects_per_block,
  					   nblocks * sects_per_block,
dd3932edd   Christoph Hellwig   block: remove BLK...
689
  					   GFP_NOFS, 0);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
690
691
  	return ret;
  }
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
692
693
  int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
694
  	unsigned long ncleansegs;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
695

365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
696
  	down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
ef7d4757a   Ryusuke Konishi   nilfs2: simplify ...
697
  	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
698
  	up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
ef7d4757a   Ryusuke Konishi   nilfs2: simplify ...
699
700
  	*nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
  	return 0;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
701
  }
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
702
703
  int nilfs_near_disk_full(struct the_nilfs *nilfs)
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
704
  	unsigned long ncleansegs, nincsegs;
ef7d4757a   Ryusuke Konishi   nilfs2: simplify ...
705
706
707
708
709
710
  
  	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
  	nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
  		nilfs->ns_blocks_per_segment + 1;
  
  	return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
711
  }
ba65ae472   Ryusuke Konishi   nilfs2: add check...
712
  struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno)
6dd474066   Ryusuke Konishi   nilfs2: simplify ...
713
  {
ba65ae472   Ryusuke Konishi   nilfs2: add check...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
  	struct rb_node *n;
  	struct nilfs_root *root;
  
  	spin_lock(&nilfs->ns_cptree_lock);
  	n = nilfs->ns_cptree.rb_node;
  	while (n) {
  		root = rb_entry(n, struct nilfs_root, rb_node);
  
  		if (cno < root->cno) {
  			n = n->rb_left;
  		} else if (cno > root->cno) {
  			n = n->rb_right;
  		} else {
  			atomic_inc(&root->count);
  			spin_unlock(&nilfs->ns_cptree_lock);
  			return root;
  		}
6dd474066   Ryusuke Konishi   nilfs2: simplify ...
731
  	}
ba65ae472   Ryusuke Konishi   nilfs2: add check...
732
  	spin_unlock(&nilfs->ns_cptree_lock);
6dd474066   Ryusuke Konishi   nilfs2: simplify ...
733

6dd474066   Ryusuke Konishi   nilfs2: simplify ...
734
  	return NULL;
6dd474066   Ryusuke Konishi   nilfs2: simplify ...
735
  }
ba65ae472   Ryusuke Konishi   nilfs2: add check...
736
737
  struct nilfs_root *
  nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
738
  {
ba65ae472   Ryusuke Konishi   nilfs2: add check...
739
740
  	struct rb_node **p, *parent;
  	struct nilfs_root *root, *new;
dd70edbde   Vyacheslav Dubeyko   nilfs2: integrate...
741
  	int err;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
742

ba65ae472   Ryusuke Konishi   nilfs2: add check...
743
744
745
  	root = nilfs_lookup_root(nilfs, cno);
  	if (root)
  		return root;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
746

dd70edbde   Vyacheslav Dubeyko   nilfs2: integrate...
747
  	new = kzalloc(sizeof(*root), GFP_KERNEL);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
  	if (!new)
  		return NULL;
  
  	spin_lock(&nilfs->ns_cptree_lock);
  
  	p = &nilfs->ns_cptree.rb_node;
  	parent = NULL;
  
  	while (*p) {
  		parent = *p;
  		root = rb_entry(parent, struct nilfs_root, rb_node);
  
  		if (cno < root->cno) {
  			p = &(*p)->rb_left;
  		} else if (cno > root->cno) {
  			p = &(*p)->rb_right;
  		} else {
  			atomic_inc(&root->count);
  			spin_unlock(&nilfs->ns_cptree_lock);
  			kfree(new);
  			return root;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
769
770
  		}
  	}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
771

ba65ae472   Ryusuke Konishi   nilfs2: add check...
772
773
774
775
  	new->cno = cno;
  	new->ifile = NULL;
  	new->nilfs = nilfs;
  	atomic_set(&new->count, 1);
e5f7f8484   Vyacheslav Dubeyko   ] nilfs2: use ato...
776
777
  	atomic64_set(&new->inodes_count, 0);
  	atomic64_set(&new->blocks_count, 0);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
778
779
780
781
782
  
  	rb_link_node(&new->rb_node, parent, p);
  	rb_insert_color(&new->rb_node, &nilfs->ns_cptree);
  
  	spin_unlock(&nilfs->ns_cptree_lock);
dd70edbde   Vyacheslav Dubeyko   nilfs2: integrate...
783
784
785
786
787
  	err = nilfs_sysfs_create_snapshot_group(new);
  	if (err) {
  		kfree(new);
  		new = NULL;
  	}
ba65ae472   Ryusuke Konishi   nilfs2: add check...
788
789
790
791
792
793
794
  	return new;
  }
  
  void nilfs_put_root(struct nilfs_root *root)
  {
  	if (atomic_dec_and_test(&root->count)) {
  		struct the_nilfs *nilfs = root->nilfs;
dd70edbde   Vyacheslav Dubeyko   nilfs2: integrate...
795
  		nilfs_sysfs_delete_snapshot_group(root);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
796
797
798
  		spin_lock(&nilfs->ns_cptree_lock);
  		rb_erase(&root->rb_node, &nilfs->ns_cptree);
  		spin_unlock(&nilfs->ns_cptree_lock);
72b9918ea   Markus Elfring   nilfs2: deletion ...
799
  		iput(root->ifile);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
800
801
802
  
  		kfree(root);
  	}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
803
  }