Blame view

fs/nilfs2/the_nilfs.c 20.3 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);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
77
  	INIT_LIST_HEAD(&nilfs->ns_dirty_files);
263d90cef   Ryusuke Konishi   nilfs2: remove ow...
78
  	INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
693dd3212   Ryusuke Konishi   nilfs2: move s_in...
79
  	spin_lock_init(&nilfs->ns_inode_lock);
9b1fc4e49   Ryusuke Konishi   nilfs2: move next...
80
  	spin_lock_init(&nilfs->ns_next_gen_lock);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
81
  	spin_lock_init(&nilfs->ns_last_segment_lock);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
82
83
  	nilfs->ns_cptree = RB_ROOT;
  	spin_lock_init(&nilfs->ns_cptree_lock);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
84
  	init_rwsem(&nilfs->ns_segctor_sem);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
85
86
87
88
89
  
  	return nilfs;
  }
  
  /**
348fe8da1   Ryusuke Konishi   nilfs2: simplify ...
90
91
   * destroy_nilfs - destroy nilfs object
   * @nilfs: nilfs object to be released
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
92
   */
348fe8da1   Ryusuke Konishi   nilfs2: simplify ...
93
  void destroy_nilfs(struct the_nilfs *nilfs)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
94
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
95
  	might_sleep();
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
96
  	if (nilfs_init(nilfs)) {
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
97
98
  		brelse(nilfs->ns_sbh[0]);
  		brelse(nilfs->ns_sbh[1]);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
99
100
101
  	}
  	kfree(nilfs);
  }
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
102
103
  static int nilfs_load_super_root(struct the_nilfs *nilfs,
  				 struct super_block *sb, sector_t sr_block)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
104
105
106
  {
  	struct buffer_head *bh_sr;
  	struct nilfs_super_root *raw_sr;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
107
  	struct nilfs_super_block **sbp = nilfs->ns_sbp;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
108
  	struct nilfs_inode *rawi;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
109
110
111
  	unsigned dat_entry_size, segment_usage_size, checkpoint_size;
  	unsigned inode_size;
  	int err;
8b94025c0   Ryusuke Konishi   nilfs2: refactor ...
112
  	err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
113
114
115
116
  	if (unlikely(err))
  		return err;
  
  	down_read(&nilfs->ns_sem);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
117
118
119
  	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...
120
121
122
  	up_read(&nilfs->ns_sem);
  
  	inode_size = nilfs->ns_inode_size;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
123
124
125
  	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...
126
  		goto failed;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
127
128
129
  	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...
130
  		goto failed_dat;
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
131
132
133
134
  	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...
135
  		goto failed_cpfile;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
136
137
138
139
140
141
  	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...
142
   failed_cpfile:
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
143
  	iput(nilfs->ns_cpfile);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
144
145
  
   failed_dat:
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
146
  	iput(nilfs->ns_dat);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  	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 ...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
   * 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...
179
  	nilfs->ns_prev_seq = nilfs->ns_last_seq;
843d63baa   Ryusuke Konishi   nilfs2: separate ...
180
181
182
183
184
185
186
187
188
189
190
191
192
  	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...
193
194
   * load_nilfs - load and recover the nilfs
   * @nilfs: the_nilfs structure to be released
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
195
   * @sb: super block isntance used to recover past segment
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
196
197
198
199
200
   *
   * 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...
201
  int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
202
203
  {
  	struct nilfs_recovery_info ri;
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
204
  	unsigned int s_flags = sb->s_flags;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
205
  	int really_read_only = bdev_read_only(nilfs->ns_bdev);
a057d2c01   Ryusuke Konishi   nilfs2: add helpe...
206
  	int valid_fs = nilfs_valid_fs(nilfs);
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
207
  	int err;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
208

f50a4c814   Ryusuke Konishi   nilfs2: move reco...
209
210
211
212
213
214
215
216
217
218
  	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...
219
  		}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
220
  	}
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
221
  	nilfs_init_recovery_info(&ri);
8b94025c0   Ryusuke Konishi   nilfs2: refactor ...
222
  	err = nilfs_search_super_root(nilfs, &ri);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
223
  	if (unlikely(err)) {
6c1251608   Ryusuke Konishi   nilfs2: implement...
224
225
226
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
  		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...
271
  	}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
272
  	err = nilfs_load_super_root(nilfs, sb, ri.ri_super_root);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
273
274
275
276
277
  	if (unlikely(err)) {
  		printk(KERN_ERR "NILFS: error loading super root.
  ");
  		goto failed;
  	}
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
278
279
280
281
  	if (valid_fs)
  		goto skip_recovery;
  
  	if (s_flags & MS_RDONLY) {
c5ca48aab   Ryusuke Konishi   nilfs2: reject in...
282
  		__u64 features;
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
283
  		if (nilfs_test_opt(nilfs, NORECOVERY)) {
0234576d0   Ryusuke Konishi   nilfs2: add norec...
284
285
286
287
288
  			printk(KERN_INFO "NILFS: norecovery option specified. "
  			       "skipping roll-forward recovery
  ");
  			goto skip_recovery;
  		}
c5ca48aab   Ryusuke Konishi   nilfs2: reject in...
289
290
291
292
293
294
295
296
297
298
299
  		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...
300
301
302
303
304
305
  		if (really_read_only) {
  			printk(KERN_ERR "NILFS: write access "
  			       "unavailable, cannot proceed.
  ");
  			err = -EROFS;
  			goto failed_unload;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
306
  		}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
307
  		sb->s_flags &= ~MS_RDONLY;
3b2ce58b0   Ryusuke Konishi   nilfs2: move moun...
308
  	} else if (nilfs_test_opt(nilfs, NORECOVERY)) {
0234576d0   Ryusuke Konishi   nilfs2: add norec...
309
310
311
312
313
  		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...
314
  	}
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
315
  	err = nilfs_salvage_orphan_logs(nilfs, sb, &ri);
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
316
317
318
319
  	if (err)
  		goto failed_unload;
  
  	down_write(&nilfs->ns_sem);
7ecaa46cf   Ryusuke Konishi   nilfs2: add nilfs...
320
  	nilfs->ns_mount_state |= NILFS_VALID_FS; /* set "clean" flag */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
321
  	err = nilfs_cleanup_super(sb);
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
322
323
324
325
326
327
328
  	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...
329
  	}
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
330
331
  	printk(KERN_INFO "NILFS: recovery complete.
  ");
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
332

f50a4c814   Ryusuke Konishi   nilfs2: move reco...
333
   skip_recovery:
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
334
  	nilfs_clear_recovery_info(&ri);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
335
  	sb->s_flags = s_flags;
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
336
  	return 0;
6c1251608   Ryusuke Konishi   nilfs2: implement...
337
338
339
340
   scan_error:
  	printk(KERN_ERR "NILFS: error searching super root.
  ");
  	goto failed;
f50a4c814   Ryusuke Konishi   nilfs2: move reco...
341
   failed_unload:
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
342
343
344
  	iput(nilfs->ns_cpfile);
  	iput(nilfs->ns_sufile);
  	iput(nilfs->ns_dat);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
345
346
347
  
   failed:
  	nilfs_clear_recovery_info(&ri);
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
348
  	sb->s_flags = s_flags;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
349
350
351
352
353
354
355
356
357
358
359
360
361
  	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...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  /**
   * 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...
379
380
  static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
  				   struct nilfs_super_block *sbp)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
381
  {
9566a7a85   Ryusuke Konishi   nilfs2: accept fu...
382
383
  	if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) {
  		printk(KERN_ERR "NILFS: unsupported revision "
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
384
385
386
387
388
389
390
391
  		       "(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...
392
393
394
  	nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes);
  	if (nilfs->ns_sbsize > BLOCK_SIZE)
  		return -EINVAL;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
395
396
397
398
399
  	nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
  	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...
400
401
  		printk(KERN_ERR "NILFS: too short segment.
  ");
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
402
403
404
405
  		return -EINVAL;
  	}
  
  	nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
406
407
  	nilfs->ns_r_segments_percentage =
  		le32_to_cpu(sbp->s_r_segments_percentage);
4e33f9eab   Ryusuke Konishi   nilfs2: implement...
408
  	nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments));
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
409
410
411
  	nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
  	return 0;
  }
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
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
  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...
492
493
494
495
  		       "NILFS warning: unable to read primary superblock "
  		       "(blocksize = %d)
  ", blocksize);
  	} else if (!sbp[1]) {
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
496
  		printk(KERN_WARNING
4138ec238   Ryusuke Konishi   nilfs2: append bl...
497
498
499
500
  		       "NILFS warning: unable to read secondary superblock "
  		       "(blocksize = %d)
  ", blocksize);
  	}
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
501

25294d8c3   Ryusuke Konishi   nilfs2: use check...
502
503
504
505
  	/*
  	 * 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...
506
507
  	valid[0] = nilfs_valid_sb(sbp[0]);
  	valid[1] = nilfs_valid_sb(sbp[1]);
25294d8c3   Ryusuke Konishi   nilfs2: use check...
508
509
510
  	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...
511
512
513
514
515
516
517
518
519
520
521
522
523
524
  
  	if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) {
  		brelse(sbh[1]);
  		sbh[1] = NULL;
  		sbp[1] = NULL;
  		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...
525
  	if (!valid[!swp])
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
526
  		printk(KERN_WARNING "NILFS warning: broken superblock. "
4138ec238   Ryusuke Konishi   nilfs2: append bl...
527
528
  		       "using spare superblock (blocksize = %d).
  ", blocksize);
ea1a16f71   Ryusuke Konishi   nilfs2: fix false...
529
  	if (swp)
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
530
  		nilfs_swap_super_block(nilfs);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
531

b2ac86e1a   Jiro SEKIBA   nilfs2: sync supe...
532
533
  	nilfs->ns_sbwcount = 0;
  	nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
534
535
536
537
  	nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq);
  	*sbpp = sbp[0];
  	return 0;
  }
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
538
539
540
  /**
   * init_nilfs - initialize a NILFS instance.
   * @nilfs: the_nilfs structure
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
541
542
543
544
545
   * @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...
546
   * shared fields in the_nilfs).
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
547
548
549
550
   *
   * Return Value: On success, 0 is returned. On error, a negative error
   * code is returned.
   */
f7545144c   Ryusuke Konishi   nilfs2: use sb in...
551
  int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
552
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
553
  	struct nilfs_super_block *sbp;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
554
  	int blocksize;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
555
  	int err;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
556
557
  
  	down_write(&nilfs->ns_sem);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
558

89c0fd014   Ryusuke Konishi   nilfs2: reject fi...
559
  	blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
560
561
562
  	if (!blocksize) {
  		printk(KERN_ERR "NILFS: unable to set blocksize
  ");
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
563
564
565
  		err = -EINVAL;
  		goto out;
  	}
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
566
567
568
  	err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
  	if (err)
  		goto out;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
569
570
571
  	err = nilfs_store_magic_and_option(sb, sbp, data);
  	if (err)
  		goto failed_sbh;
c5ca48aab   Ryusuke Konishi   nilfs2: reject in...
572
573
574
  	err = nilfs_check_feature_compatibility(sb, sbp);
  	if (err)
  		goto failed_sbh;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
575
  	blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
89c0fd014   Ryusuke Konishi   nilfs2: reject fi...
576
577
578
579
580
581
582
583
  	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...
584
  	if (sb->s_blocksize != blocksize) {
e1defc4ff   Martin K. Petersen   block: Do away wi...
585
  		int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
586
587
588
589
590
591
592
  
  		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...
593
  			err = -EINVAL;
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
594
595
596
597
598
599
600
  			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...
601
602
603
  			goto out;
  			/* not failed_sbh; sbh is released automatically
  			   when reloading fails. */
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
604
605
  	}
  	nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
92c60ccaf   Ryusuke Konishi   nilfs2: add block...
606
  	nilfs->ns_blocksize = blocksize;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
607

9b1fc4e49   Ryusuke Konishi   nilfs2: move next...
608
609
  	get_random_bytes(&nilfs->ns_next_generation,
  			 sizeof(nilfs->ns_next_generation));
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
610
  	err = nilfs_store_disk_layout(nilfs, sbp);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
611
612
613
614
615
616
  	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...
617

843d63baa   Ryusuke Konishi   nilfs2: separate ...
618
619
  	err = nilfs_store_log_cursor(nilfs, sbp);
  	if (err)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
620
  		goto failed_sbh;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
621

8a9d2191e   Ryusuke Konishi   nilfs2: operation...
622
623
624
625
626
627
628
  	set_nilfs_init(nilfs);
  	err = 0;
   out:
  	up_write(&nilfs->ns_sem);
  	return err;
  
   failed_sbh:
e339ad31f   Ryusuke Konishi   nilfs2: introduce...
629
  	nilfs_release_super_block(nilfs);
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
630
631
  	goto out;
  }
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
  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...
655
  						   GFP_NOFS, 0);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
656
657
658
659
660
661
662
663
664
  			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...
665
  					   GFP_NOFS, 0);
e902ec990   Jiro SEKIBA   nilfs2: issue dis...
666
667
  	return ret;
  }
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
668
669
  int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
670
  	unsigned long ncleansegs;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
671

365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
672
  	down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
ef7d4757a   Ryusuke Konishi   nilfs2: simplify ...
673
  	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
365e215ce   Ryusuke Konishi   nilfs2: unfold ni...
674
  	up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
ef7d4757a   Ryusuke Konishi   nilfs2: simplify ...
675
676
  	*nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
  	return 0;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
677
  }
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
678
679
  int nilfs_near_disk_full(struct the_nilfs *nilfs)
  {
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
680
  	unsigned long ncleansegs, nincsegs;
ef7d4757a   Ryusuke Konishi   nilfs2: simplify ...
681
682
683
684
685
686
  
  	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...
687
  }
ba65ae472   Ryusuke Konishi   nilfs2: add check...
688
  struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno)
6dd474066   Ryusuke Konishi   nilfs2: simplify ...
689
  {
ba65ae472   Ryusuke Konishi   nilfs2: add check...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
  	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 ...
707
  	}
ba65ae472   Ryusuke Konishi   nilfs2: add check...
708
  	spin_unlock(&nilfs->ns_cptree_lock);
6dd474066   Ryusuke Konishi   nilfs2: simplify ...
709

6dd474066   Ryusuke Konishi   nilfs2: simplify ...
710
  	return NULL;
6dd474066   Ryusuke Konishi   nilfs2: simplify ...
711
  }
ba65ae472   Ryusuke Konishi   nilfs2: add check...
712
713
  struct nilfs_root *
  nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno)
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
714
  {
ba65ae472   Ryusuke Konishi   nilfs2: add check...
715
716
  	struct rb_node **p, *parent;
  	struct nilfs_root *root, *new;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
717

ba65ae472   Ryusuke Konishi   nilfs2: add check...
718
719
720
  	root = nilfs_lookup_root(nilfs, cno);
  	if (root)
  		return root;
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
721

ba65ae472   Ryusuke Konishi   nilfs2: add check...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
  	new = kmalloc(sizeof(*root), GFP_KERNEL);
  	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...
744
745
  		}
  	}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
746

ba65ae472   Ryusuke Konishi   nilfs2: add check...
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
  	new->cno = cno;
  	new->ifile = NULL;
  	new->nilfs = nilfs;
  	atomic_set(&new->count, 1);
  	atomic_set(&new->inodes_count, 0);
  	atomic_set(&new->blocks_count, 0);
  
  	rb_link_node(&new->rb_node, parent, p);
  	rb_insert_color(&new->rb_node, &nilfs->ns_cptree);
  
  	spin_unlock(&nilfs->ns_cptree_lock);
  
  	return new;
  }
  
  void nilfs_put_root(struct nilfs_root *root)
  {
  	if (atomic_dec_and_test(&root->count)) {
  		struct the_nilfs *nilfs = root->nilfs;
  
  		spin_lock(&nilfs->ns_cptree_lock);
  		rb_erase(&root->rb_node, &nilfs->ns_cptree);
  		spin_unlock(&nilfs->ns_cptree_lock);
  		if (root->ifile)
f1e89c86f   Ryusuke Konishi   nilfs2: use iget ...
771
  			iput(root->ifile);
ba65ae472   Ryusuke Konishi   nilfs2: add check...
772
773
774
  
  		kfree(root);
  	}
8a9d2191e   Ryusuke Konishi   nilfs2: operation...
775
  }