1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * the_nilfs shared structure. |
4 | * |
5 | * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. |
6 | * |
7 | * Written by Ryusuke Konishi. |
8 | * |
9 | */ |
10 | |
11 | #include <linux/buffer_head.h> |
12 | #include <linux/slab.h> |
13 | #include <linux/blkdev.h> |
14 | #include <linux/backing-dev.h> |
15 | #include <linux/random.h> |
16 | #include <linux/log2.h> |
17 | #include <linux/crc32.h> |
18 | #include "nilfs.h" |
19 | #include "segment.h" |
20 | #include "alloc.h" |
21 | #include "cpfile.h" |
22 | #include "sufile.h" |
23 | #include "dat.h" |
24 | #include "segbuf.h" |
25 | |
26 | |
27 | static int nilfs_valid_sb(struct nilfs_super_block *sbp); |
28 | |
29 | void nilfs_set_last_segment(struct the_nilfs *nilfs, |
30 | sector_t start_blocknr, u64 seq, __u64 cno) |
31 | { |
32 | spin_lock(lock: &nilfs->ns_last_segment_lock); |
33 | nilfs->ns_last_pseg = start_blocknr; |
34 | nilfs->ns_last_seq = seq; |
35 | nilfs->ns_last_cno = cno; |
36 | |
37 | if (!nilfs_sb_dirty(nilfs)) { |
38 | if (nilfs->ns_prev_seq == nilfs->ns_last_seq) |
39 | goto stay_cursor; |
40 | |
41 | set_nilfs_sb_dirty(nilfs); |
42 | } |
43 | nilfs->ns_prev_seq = nilfs->ns_last_seq; |
44 | |
45 | stay_cursor: |
46 | spin_unlock(lock: &nilfs->ns_last_segment_lock); |
47 | } |
48 | |
49 | /** |
50 | * alloc_nilfs - allocate a nilfs object |
51 | * @sb: super block instance |
52 | * |
53 | * Return Value: On success, pointer to the_nilfs is returned. |
54 | * On error, NULL is returned. |
55 | */ |
56 | struct the_nilfs *alloc_nilfs(struct super_block *sb) |
57 | { |
58 | struct the_nilfs *nilfs; |
59 | |
60 | nilfs = kzalloc(size: sizeof(*nilfs), GFP_KERNEL); |
61 | if (!nilfs) |
62 | return NULL; |
63 | |
64 | nilfs->ns_sb = sb; |
65 | nilfs->ns_bdev = sb->s_bdev; |
66 | atomic_set(v: &nilfs->ns_ndirtyblks, i: 0); |
67 | init_rwsem(&nilfs->ns_sem); |
68 | mutex_init(&nilfs->ns_snapshot_mount_mutex); |
69 | INIT_LIST_HEAD(list: &nilfs->ns_dirty_files); |
70 | INIT_LIST_HEAD(list: &nilfs->ns_gc_inodes); |
71 | spin_lock_init(&nilfs->ns_inode_lock); |
72 | spin_lock_init(&nilfs->ns_next_gen_lock); |
73 | spin_lock_init(&nilfs->ns_last_segment_lock); |
74 | nilfs->ns_cptree = RB_ROOT; |
75 | spin_lock_init(&nilfs->ns_cptree_lock); |
76 | init_rwsem(&nilfs->ns_segctor_sem); |
77 | nilfs->ns_sb_update_freq = NILFS_SB_FREQ; |
78 | |
79 | return nilfs; |
80 | } |
81 | |
82 | /** |
83 | * destroy_nilfs - destroy nilfs object |
84 | * @nilfs: nilfs object to be released |
85 | */ |
86 | void destroy_nilfs(struct the_nilfs *nilfs) |
87 | { |
88 | might_sleep(); |
89 | if (nilfs_init(nilfs)) { |
90 | brelse(bh: nilfs->ns_sbh[0]); |
91 | brelse(bh: nilfs->ns_sbh[1]); |
92 | } |
93 | kfree(objp: nilfs); |
94 | } |
95 | |
96 | static int nilfs_load_super_root(struct the_nilfs *nilfs, |
97 | struct super_block *sb, sector_t sr_block) |
98 | { |
99 | struct buffer_head *bh_sr; |
100 | struct nilfs_super_root *raw_sr; |
101 | struct nilfs_super_block **sbp = nilfs->ns_sbp; |
102 | struct nilfs_inode *rawi; |
103 | unsigned int dat_entry_size, segment_usage_size, checkpoint_size; |
104 | unsigned int inode_size; |
105 | int err; |
106 | |
107 | err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1); |
108 | if (unlikely(err)) |
109 | return err; |
110 | |
111 | down_read(sem: &nilfs->ns_sem); |
112 | dat_entry_size = le16_to_cpu(sbp[0]->s_dat_entry_size); |
113 | checkpoint_size = le16_to_cpu(sbp[0]->s_checkpoint_size); |
114 | segment_usage_size = le16_to_cpu(sbp[0]->s_segment_usage_size); |
115 | up_read(sem: &nilfs->ns_sem); |
116 | |
117 | inode_size = nilfs->ns_inode_size; |
118 | |
119 | rawi = (void *)bh_sr->b_data + NILFS_SR_DAT_OFFSET(inode_size); |
120 | err = nilfs_dat_read(sb, entry_size: dat_entry_size, raw_inode: rawi, inodep: &nilfs->ns_dat); |
121 | if (err) |
122 | goto failed; |
123 | |
124 | rawi = (void *)bh_sr->b_data + NILFS_SR_CPFILE_OFFSET(inode_size); |
125 | err = nilfs_cpfile_read(sb, cpsize: checkpoint_size, raw_inode: rawi, inodep: &nilfs->ns_cpfile); |
126 | if (err) |
127 | goto failed_dat; |
128 | |
129 | rawi = (void *)bh_sr->b_data + NILFS_SR_SUFILE_OFFSET(inode_size); |
130 | err = nilfs_sufile_read(sb, susize: segment_usage_size, raw_inode: rawi, |
131 | inodep: &nilfs->ns_sufile); |
132 | if (err) |
133 | goto failed_cpfile; |
134 | |
135 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; |
136 | nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime); |
137 | |
138 | failed: |
139 | brelse(bh: bh_sr); |
140 | return err; |
141 | |
142 | failed_cpfile: |
143 | iput(nilfs->ns_cpfile); |
144 | |
145 | failed_dat: |
146 | iput(nilfs->ns_dat); |
147 | goto failed; |
148 | } |
149 | |
150 | static void nilfs_init_recovery_info(struct nilfs_recovery_info *ri) |
151 | { |
152 | memset(ri, 0, sizeof(*ri)); |
153 | INIT_LIST_HEAD(list: &ri->ri_used_segments); |
154 | } |
155 | |
156 | static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri) |
157 | { |
158 | nilfs_dispose_segment_list(&ri->ri_used_segments); |
159 | } |
160 | |
161 | /** |
162 | * nilfs_store_log_cursor - load log cursor from a super block |
163 | * @nilfs: nilfs object |
164 | * @sbp: buffer storing super block to be read |
165 | * |
166 | * nilfs_store_log_cursor() reads the last position of the log |
167 | * containing a super root from a given super block, and initializes |
168 | * relevant information on the nilfs object preparatory for log |
169 | * scanning and recovery. |
170 | */ |
171 | static int nilfs_store_log_cursor(struct the_nilfs *nilfs, |
172 | struct nilfs_super_block *sbp) |
173 | { |
174 | int ret = 0; |
175 | |
176 | nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg); |
177 | nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno); |
178 | nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq); |
179 | |
180 | nilfs->ns_prev_seq = nilfs->ns_last_seq; |
181 | nilfs->ns_seg_seq = nilfs->ns_last_seq; |
182 | nilfs->ns_segnum = |
183 | nilfs_get_segnum_of_block(nilfs, blocknr: nilfs->ns_last_pseg); |
184 | nilfs->ns_cno = nilfs->ns_last_cno + 1; |
185 | if (nilfs->ns_segnum >= nilfs->ns_nsegments) { |
186 | nilfs_err(nilfs->ns_sb, |
187 | "pointed segment number is out of range: segnum=%llu, nsegments=%lu" , |
188 | (unsigned long long)nilfs->ns_segnum, |
189 | nilfs->ns_nsegments); |
190 | ret = -EINVAL; |
191 | } |
192 | return ret; |
193 | } |
194 | |
195 | /** |
196 | * nilfs_get_blocksize - get block size from raw superblock data |
197 | * @sb: super block instance |
198 | * @sbp: superblock raw data buffer |
199 | * @blocksize: place to store block size |
200 | * |
201 | * nilfs_get_blocksize() calculates the block size from the block size |
202 | * exponent information written in @sbp and stores it in @blocksize, |
203 | * or aborts with an error message if it's too large. |
204 | * |
205 | * Return Value: On success, 0 is returned. If the block size is too |
206 | * large, -EINVAL is returned. |
207 | */ |
208 | static int nilfs_get_blocksize(struct super_block *sb, |
209 | struct nilfs_super_block *sbp, int *blocksize) |
210 | { |
211 | unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size); |
212 | |
213 | if (unlikely(shift_bits > |
214 | ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)) { |
215 | nilfs_err(sb, "too large filesystem blocksize: 2 ^ %u KiB" , |
216 | shift_bits); |
217 | return -EINVAL; |
218 | } |
219 | *blocksize = BLOCK_SIZE << shift_bits; |
220 | return 0; |
221 | } |
222 | |
223 | /** |
224 | * load_nilfs - load and recover the nilfs |
225 | * @nilfs: the_nilfs structure to be released |
226 | * @sb: super block instance used to recover past segment |
227 | * |
228 | * load_nilfs() searches and load the latest super root, |
229 | * attaches the last segment, and does recovery if needed. |
230 | * The caller must call this exclusively for simultaneous mounts. |
231 | */ |
232 | int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb) |
233 | { |
234 | struct nilfs_recovery_info ri; |
235 | unsigned int s_flags = sb->s_flags; |
236 | int really_read_only = bdev_read_only(bdev: nilfs->ns_bdev); |
237 | int valid_fs = nilfs_valid_fs(nilfs); |
238 | int err; |
239 | |
240 | if (!valid_fs) { |
241 | nilfs_warn(sb, "mounting unchecked fs" ); |
242 | if (s_flags & SB_RDONLY) { |
243 | nilfs_info(sb, |
244 | "recovery required for readonly filesystem" ); |
245 | nilfs_info(sb, |
246 | "write access will be enabled during recovery" ); |
247 | } |
248 | } |
249 | |
250 | nilfs_init_recovery_info(ri: &ri); |
251 | |
252 | err = nilfs_search_super_root(nilfs, &ri); |
253 | if (unlikely(err)) { |
254 | struct nilfs_super_block **sbp = nilfs->ns_sbp; |
255 | int blocksize; |
256 | |
257 | if (err != -EINVAL) |
258 | goto scan_error; |
259 | |
260 | if (!nilfs_valid_sb(sbp: sbp[1])) { |
261 | nilfs_warn(sb, |
262 | "unable to fall back to spare super block" ); |
263 | goto scan_error; |
264 | } |
265 | nilfs_info(sb, "trying rollback from an earlier position" ); |
266 | |
267 | /* |
268 | * restore super block with its spare and reconfigure |
269 | * relevant states of the nilfs object. |
270 | */ |
271 | memcpy(sbp[0], sbp[1], nilfs->ns_sbsize); |
272 | nilfs->ns_crc_seed = le32_to_cpu(sbp[0]->s_crc_seed); |
273 | nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime); |
274 | |
275 | /* verify consistency between two super blocks */ |
276 | err = nilfs_get_blocksize(sb, sbp: sbp[0], blocksize: &blocksize); |
277 | if (err) |
278 | goto scan_error; |
279 | |
280 | if (blocksize != nilfs->ns_blocksize) { |
281 | nilfs_warn(sb, |
282 | "blocksize differs between two super blocks (%d != %d)" , |
283 | blocksize, nilfs->ns_blocksize); |
284 | err = -EINVAL; |
285 | goto scan_error; |
286 | } |
287 | |
288 | err = nilfs_store_log_cursor(nilfs, sbp: sbp[0]); |
289 | if (err) |
290 | goto scan_error; |
291 | |
292 | /* drop clean flag to allow roll-forward and recovery */ |
293 | nilfs->ns_mount_state &= ~NILFS_VALID_FS; |
294 | valid_fs = 0; |
295 | |
296 | err = nilfs_search_super_root(nilfs, &ri); |
297 | if (err) |
298 | goto scan_error; |
299 | } |
300 | |
301 | err = nilfs_load_super_root(nilfs, sb, sr_block: ri.ri_super_root); |
302 | if (unlikely(err)) { |
303 | nilfs_err(sb, "error %d while loading super root" , err); |
304 | goto failed; |
305 | } |
306 | |
307 | err = nilfs_sysfs_create_device_group(sb); |
308 | if (unlikely(err)) |
309 | goto sysfs_error; |
310 | |
311 | if (valid_fs) |
312 | goto skip_recovery; |
313 | |
314 | if (s_flags & SB_RDONLY) { |
315 | __u64 features; |
316 | |
317 | if (nilfs_test_opt(nilfs, NORECOVERY)) { |
318 | nilfs_info(sb, |
319 | "norecovery option specified, skipping roll-forward recovery" ); |
320 | goto skip_recovery; |
321 | } |
322 | features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) & |
323 | ~NILFS_FEATURE_COMPAT_RO_SUPP; |
324 | if (features) { |
325 | nilfs_err(sb, |
326 | "couldn't proceed with recovery because of unsupported optional features (%llx)" , |
327 | (unsigned long long)features); |
328 | err = -EROFS; |
329 | goto failed_unload; |
330 | } |
331 | if (really_read_only) { |
332 | nilfs_err(sb, |
333 | "write access unavailable, cannot proceed" ); |
334 | err = -EROFS; |
335 | goto failed_unload; |
336 | } |
337 | sb->s_flags &= ~SB_RDONLY; |
338 | } else if (nilfs_test_opt(nilfs, NORECOVERY)) { |
339 | nilfs_err(sb, |
340 | "recovery cancelled because norecovery option was specified for a read/write mount" ); |
341 | err = -EINVAL; |
342 | goto failed_unload; |
343 | } |
344 | |
345 | err = nilfs_salvage_orphan_logs(nilfs, sb, ri: &ri); |
346 | if (err) |
347 | goto failed_unload; |
348 | |
349 | down_write(sem: &nilfs->ns_sem); |
350 | nilfs->ns_mount_state |= NILFS_VALID_FS; /* set "clean" flag */ |
351 | err = nilfs_cleanup_super(sb); |
352 | up_write(sem: &nilfs->ns_sem); |
353 | |
354 | if (err) { |
355 | nilfs_err(sb, |
356 | "error %d updating super block. recovery unfinished." , |
357 | err); |
358 | goto failed_unload; |
359 | } |
360 | nilfs_info(sb, "recovery complete" ); |
361 | |
362 | skip_recovery: |
363 | nilfs_clear_recovery_info(ri: &ri); |
364 | sb->s_flags = s_flags; |
365 | return 0; |
366 | |
367 | scan_error: |
368 | nilfs_err(sb, "error %d while searching super root" , err); |
369 | goto failed; |
370 | |
371 | failed_unload: |
372 | nilfs_sysfs_delete_device_group(nilfs); |
373 | |
374 | sysfs_error: |
375 | iput(nilfs->ns_cpfile); |
376 | iput(nilfs->ns_sufile); |
377 | iput(nilfs->ns_dat); |
378 | |
379 | failed: |
380 | nilfs_clear_recovery_info(ri: &ri); |
381 | sb->s_flags = s_flags; |
382 | return err; |
383 | } |
384 | |
385 | static unsigned long long nilfs_max_size(unsigned int blkbits) |
386 | { |
387 | unsigned int max_bits; |
388 | unsigned long long res = MAX_LFS_FILESIZE; /* page cache limit */ |
389 | |
390 | max_bits = blkbits + NILFS_BMAP_KEY_BIT; /* bmap size limit */ |
391 | if (max_bits < 64) |
392 | res = min_t(unsigned long long, res, (1ULL << max_bits) - 1); |
393 | return res; |
394 | } |
395 | |
396 | /** |
397 | * nilfs_nrsvsegs - calculate the number of reserved segments |
398 | * @nilfs: nilfs object |
399 | * @nsegs: total number of segments |
400 | */ |
401 | unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs) |
402 | { |
403 | return max_t(unsigned long, NILFS_MIN_NRSVSEGS, |
404 | DIV_ROUND_UP(nsegs * nilfs->ns_r_segments_percentage, |
405 | 100)); |
406 | } |
407 | |
408 | /** |
409 | * nilfs_max_segment_count - calculate the maximum number of segments |
410 | * @nilfs: nilfs object |
411 | */ |
412 | static u64 nilfs_max_segment_count(struct the_nilfs *nilfs) |
413 | { |
414 | u64 max_count = U64_MAX; |
415 | |
416 | do_div(max_count, nilfs->ns_blocks_per_segment); |
417 | return min_t(u64, max_count, ULONG_MAX); |
418 | } |
419 | |
420 | void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs) |
421 | { |
422 | nilfs->ns_nsegments = nsegs; |
423 | nilfs->ns_nrsvsegs = nilfs_nrsvsegs(nilfs, nsegs); |
424 | } |
425 | |
426 | static int nilfs_store_disk_layout(struct the_nilfs *nilfs, |
427 | struct nilfs_super_block *sbp) |
428 | { |
429 | u64 nsegments, nblocks; |
430 | |
431 | if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) { |
432 | nilfs_err(nilfs->ns_sb, |
433 | "unsupported revision (superblock rev.=%d.%d, current rev.=%d.%d). Please check the version of mkfs.nilfs(2)." , |
434 | le32_to_cpu(sbp->s_rev_level), |
435 | le16_to_cpu(sbp->s_minor_rev_level), |
436 | NILFS_CURRENT_REV, NILFS_MINOR_REV); |
437 | return -EINVAL; |
438 | } |
439 | nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes); |
440 | if (nilfs->ns_sbsize > BLOCK_SIZE) |
441 | return -EINVAL; |
442 | |
443 | nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size); |
444 | if (nilfs->ns_inode_size > nilfs->ns_blocksize) { |
445 | nilfs_err(nilfs->ns_sb, "too large inode size: %d bytes" , |
446 | nilfs->ns_inode_size); |
447 | return -EINVAL; |
448 | } else if (nilfs->ns_inode_size < NILFS_MIN_INODE_SIZE) { |
449 | nilfs_err(nilfs->ns_sb, "too small inode size: %d bytes" , |
450 | nilfs->ns_inode_size); |
451 | return -EINVAL; |
452 | } |
453 | |
454 | nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino); |
455 | |
456 | nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment); |
457 | if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) { |
458 | nilfs_err(nilfs->ns_sb, "too short segment: %lu blocks" , |
459 | nilfs->ns_blocks_per_segment); |
460 | return -EINVAL; |
461 | } |
462 | |
463 | nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block); |
464 | nilfs->ns_r_segments_percentage = |
465 | le32_to_cpu(sbp->s_r_segments_percentage); |
466 | if (nilfs->ns_r_segments_percentage < 1 || |
467 | nilfs->ns_r_segments_percentage > 99) { |
468 | nilfs_err(nilfs->ns_sb, |
469 | "invalid reserved segments percentage: %lu" , |
470 | nilfs->ns_r_segments_percentage); |
471 | return -EINVAL; |
472 | } |
473 | |
474 | nsegments = le64_to_cpu(sbp->s_nsegments); |
475 | if (nsegments > nilfs_max_segment_count(nilfs)) { |
476 | nilfs_err(nilfs->ns_sb, |
477 | "segment count %llu exceeds upper limit (%llu segments)" , |
478 | (unsigned long long)nsegments, |
479 | (unsigned long long)nilfs_max_segment_count(nilfs)); |
480 | return -EINVAL; |
481 | } |
482 | |
483 | nblocks = sb_bdev_nr_blocks(sb: nilfs->ns_sb); |
484 | if (nblocks) { |
485 | u64 min_block_count = nsegments * nilfs->ns_blocks_per_segment; |
486 | /* |
487 | * To avoid failing to mount early device images without a |
488 | * second superblock, exclude that block count from the |
489 | * "min_block_count" calculation. |
490 | */ |
491 | |
492 | if (nblocks < min_block_count) { |
493 | nilfs_err(nilfs->ns_sb, |
494 | "total number of segment blocks %llu exceeds device size (%llu blocks)" , |
495 | (unsigned long long)min_block_count, |
496 | (unsigned long long)nblocks); |
497 | return -EINVAL; |
498 | } |
499 | } |
500 | |
501 | nilfs_set_nsegments(nilfs, nsegs: nsegments); |
502 | nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed); |
503 | return 0; |
504 | } |
505 | |
506 | static int nilfs_valid_sb(struct nilfs_super_block *sbp) |
507 | { |
508 | static unsigned char sum[4]; |
509 | const int sumoff = offsetof(struct nilfs_super_block, s_sum); |
510 | size_t bytes; |
511 | u32 crc; |
512 | |
513 | if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC) |
514 | return 0; |
515 | bytes = le16_to_cpu(sbp->s_bytes); |
516 | if (bytes < sumoff + 4 || bytes > BLOCK_SIZE) |
517 | return 0; |
518 | crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), p: (unsigned char *)sbp, |
519 | len: sumoff); |
520 | crc = crc32_le(crc, p: sum, len: 4); |
521 | crc = crc32_le(crc, p: (unsigned char *)sbp + sumoff + 4, |
522 | len: bytes - sumoff - 4); |
523 | return crc == le32_to_cpu(sbp->s_sum); |
524 | } |
525 | |
526 | /** |
527 | * nilfs_sb2_bad_offset - check the location of the second superblock |
528 | * @sbp: superblock raw data buffer |
529 | * @offset: byte offset of second superblock calculated from device size |
530 | * |
531 | * nilfs_sb2_bad_offset() checks if the position on the second |
532 | * superblock is valid or not based on the filesystem parameters |
533 | * stored in @sbp. If @offset points to a location within the segment |
534 | * area, or if the parameters themselves are not normal, it is |
535 | * determined to be invalid. |
536 | * |
537 | * Return Value: true if invalid, false if valid. |
538 | */ |
539 | static bool nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset) |
540 | { |
541 | unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size); |
542 | u32 blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment); |
543 | u64 nsegments = le64_to_cpu(sbp->s_nsegments); |
544 | u64 index; |
545 | |
546 | if (blocks_per_segment < NILFS_SEG_MIN_BLOCKS || |
547 | shift_bits > ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS) |
548 | return true; |
549 | |
550 | index = offset >> (shift_bits + BLOCK_SIZE_BITS); |
551 | do_div(index, blocks_per_segment); |
552 | return index < nsegments; |
553 | } |
554 | |
555 | static void nilfs_release_super_block(struct the_nilfs *nilfs) |
556 | { |
557 | int i; |
558 | |
559 | for (i = 0; i < 2; i++) { |
560 | if (nilfs->ns_sbp[i]) { |
561 | brelse(bh: nilfs->ns_sbh[i]); |
562 | nilfs->ns_sbh[i] = NULL; |
563 | nilfs->ns_sbp[i] = NULL; |
564 | } |
565 | } |
566 | } |
567 | |
568 | void nilfs_fall_back_super_block(struct the_nilfs *nilfs) |
569 | { |
570 | brelse(bh: nilfs->ns_sbh[0]); |
571 | nilfs->ns_sbh[0] = nilfs->ns_sbh[1]; |
572 | nilfs->ns_sbp[0] = nilfs->ns_sbp[1]; |
573 | nilfs->ns_sbh[1] = NULL; |
574 | nilfs->ns_sbp[1] = NULL; |
575 | } |
576 | |
577 | void nilfs_swap_super_block(struct the_nilfs *nilfs) |
578 | { |
579 | struct buffer_head *tsbh = nilfs->ns_sbh[0]; |
580 | struct nilfs_super_block *tsbp = nilfs->ns_sbp[0]; |
581 | |
582 | nilfs->ns_sbh[0] = nilfs->ns_sbh[1]; |
583 | nilfs->ns_sbp[0] = nilfs->ns_sbp[1]; |
584 | nilfs->ns_sbh[1] = tsbh; |
585 | nilfs->ns_sbp[1] = tsbp; |
586 | } |
587 | |
588 | static int nilfs_load_super_block(struct the_nilfs *nilfs, |
589 | struct super_block *sb, int blocksize, |
590 | struct nilfs_super_block **sbpp) |
591 | { |
592 | struct nilfs_super_block **sbp = nilfs->ns_sbp; |
593 | struct buffer_head **sbh = nilfs->ns_sbh; |
594 | u64 sb2off, devsize = bdev_nr_bytes(bdev: nilfs->ns_bdev); |
595 | int valid[2], swp = 0; |
596 | |
597 | if (devsize < NILFS_SEG_MIN_BLOCKS * NILFS_MIN_BLOCK_SIZE + 4096) { |
598 | nilfs_err(sb, "device size too small" ); |
599 | return -EINVAL; |
600 | } |
601 | sb2off = NILFS_SB2_OFFSET_BYTES(devsize); |
602 | |
603 | sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize, |
604 | &sbh[0]); |
605 | sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]); |
606 | |
607 | if (!sbp[0]) { |
608 | if (!sbp[1]) { |
609 | nilfs_err(sb, "unable to read superblock" ); |
610 | return -EIO; |
611 | } |
612 | nilfs_warn(sb, |
613 | "unable to read primary superblock (blocksize = %d)" , |
614 | blocksize); |
615 | } else if (!sbp[1]) { |
616 | nilfs_warn(sb, |
617 | "unable to read secondary superblock (blocksize = %d)" , |
618 | blocksize); |
619 | } |
620 | |
621 | /* |
622 | * Compare two super blocks and set 1 in swp if the secondary |
623 | * super block is valid and newer. Otherwise, set 0 in swp. |
624 | */ |
625 | valid[0] = nilfs_valid_sb(sbp: sbp[0]); |
626 | valid[1] = nilfs_valid_sb(sbp: sbp[1]); |
627 | swp = valid[1] && (!valid[0] || |
628 | le64_to_cpu(sbp[1]->s_last_cno) > |
629 | le64_to_cpu(sbp[0]->s_last_cno)); |
630 | |
631 | if (valid[swp] && nilfs_sb2_bad_offset(sbp: sbp[swp], offset: sb2off)) { |
632 | brelse(bh: sbh[1]); |
633 | sbh[1] = NULL; |
634 | sbp[1] = NULL; |
635 | valid[1] = 0; |
636 | swp = 0; |
637 | } |
638 | if (!valid[swp]) { |
639 | nilfs_release_super_block(nilfs); |
640 | nilfs_err(sb, "couldn't find nilfs on the device" ); |
641 | return -EINVAL; |
642 | } |
643 | |
644 | if (!valid[!swp]) |
645 | nilfs_warn(sb, |
646 | "broken superblock, retrying with spare superblock (blocksize = %d)" , |
647 | blocksize); |
648 | if (swp) |
649 | nilfs_swap_super_block(nilfs); |
650 | |
651 | nilfs->ns_sbwcount = 0; |
652 | nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime); |
653 | nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq); |
654 | *sbpp = sbp[0]; |
655 | return 0; |
656 | } |
657 | |
658 | /** |
659 | * init_nilfs - initialize a NILFS instance. |
660 | * @nilfs: the_nilfs structure |
661 | * @sb: super block |
662 | * @data: mount options |
663 | * |
664 | * init_nilfs() performs common initialization per block device (e.g. |
665 | * reading the super block, getting disk layout information, initializing |
666 | * shared fields in the_nilfs). |
667 | * |
668 | * Return Value: On success, 0 is returned. On error, a negative error |
669 | * code is returned. |
670 | */ |
671 | int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data) |
672 | { |
673 | struct nilfs_super_block *sbp; |
674 | int blocksize; |
675 | int err; |
676 | |
677 | down_write(sem: &nilfs->ns_sem); |
678 | |
679 | blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE); |
680 | if (!blocksize) { |
681 | nilfs_err(sb, "unable to set blocksize" ); |
682 | err = -EINVAL; |
683 | goto out; |
684 | } |
685 | err = nilfs_load_super_block(nilfs, sb, blocksize, sbpp: &sbp); |
686 | if (err) |
687 | goto out; |
688 | |
689 | err = nilfs_store_magic_and_option(sb, sbp, data); |
690 | if (err) |
691 | goto failed_sbh; |
692 | |
693 | err = nilfs_check_feature_compatibility(sb, sbp); |
694 | if (err) |
695 | goto failed_sbh; |
696 | |
697 | err = nilfs_get_blocksize(sb, sbp, blocksize: &blocksize); |
698 | if (err) |
699 | goto failed_sbh; |
700 | |
701 | if (blocksize < NILFS_MIN_BLOCK_SIZE) { |
702 | nilfs_err(sb, |
703 | "couldn't mount because of unsupported filesystem blocksize %d" , |
704 | blocksize); |
705 | err = -EINVAL; |
706 | goto failed_sbh; |
707 | } |
708 | if (sb->s_blocksize != blocksize) { |
709 | int hw_blocksize = bdev_logical_block_size(bdev: sb->s_bdev); |
710 | |
711 | if (blocksize < hw_blocksize) { |
712 | nilfs_err(sb, |
713 | "blocksize %d too small for device (sector-size = %d)" , |
714 | blocksize, hw_blocksize); |
715 | err = -EINVAL; |
716 | goto failed_sbh; |
717 | } |
718 | nilfs_release_super_block(nilfs); |
719 | sb_set_blocksize(sb, blocksize); |
720 | |
721 | err = nilfs_load_super_block(nilfs, sb, blocksize, sbpp: &sbp); |
722 | if (err) |
723 | goto out; |
724 | /* |
725 | * Not to failed_sbh; sbh is released automatically |
726 | * when reloading fails. |
727 | */ |
728 | } |
729 | nilfs->ns_blocksize_bits = sb->s_blocksize_bits; |
730 | nilfs->ns_blocksize = blocksize; |
731 | |
732 | get_random_bytes(buf: &nilfs->ns_next_generation, |
733 | len: sizeof(nilfs->ns_next_generation)); |
734 | |
735 | err = nilfs_store_disk_layout(nilfs, sbp); |
736 | if (err) |
737 | goto failed_sbh; |
738 | |
739 | sb->s_maxbytes = nilfs_max_size(blkbits: sb->s_blocksize_bits); |
740 | |
741 | nilfs->ns_mount_state = le16_to_cpu(sbp->s_state); |
742 | |
743 | err = nilfs_store_log_cursor(nilfs, sbp); |
744 | if (err) |
745 | goto failed_sbh; |
746 | |
747 | set_nilfs_init(nilfs); |
748 | err = 0; |
749 | out: |
750 | up_write(sem: &nilfs->ns_sem); |
751 | return err; |
752 | |
753 | failed_sbh: |
754 | nilfs_release_super_block(nilfs); |
755 | goto out; |
756 | } |
757 | |
758 | int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump, |
759 | size_t nsegs) |
760 | { |
761 | sector_t seg_start, seg_end; |
762 | sector_t start = 0, nblocks = 0; |
763 | unsigned int sects_per_block; |
764 | __u64 *sn; |
765 | int ret = 0; |
766 | |
767 | sects_per_block = (1 << nilfs->ns_blocksize_bits) / |
768 | bdev_logical_block_size(bdev: nilfs->ns_bdev); |
769 | for (sn = segnump; sn < segnump + nsegs; sn++) { |
770 | nilfs_get_segment_range(nilfs, segnum: *sn, seg_start: &seg_start, seg_end: &seg_end); |
771 | |
772 | if (!nblocks) { |
773 | start = seg_start; |
774 | nblocks = seg_end - seg_start + 1; |
775 | } else if (start + nblocks == seg_start) { |
776 | nblocks += seg_end - seg_start + 1; |
777 | } else { |
778 | ret = blkdev_issue_discard(bdev: nilfs->ns_bdev, |
779 | sector: start * sects_per_block, |
780 | nr_sects: nblocks * sects_per_block, |
781 | GFP_NOFS); |
782 | if (ret < 0) |
783 | return ret; |
784 | nblocks = 0; |
785 | } |
786 | } |
787 | if (nblocks) |
788 | ret = blkdev_issue_discard(bdev: nilfs->ns_bdev, |
789 | sector: start * sects_per_block, |
790 | nr_sects: nblocks * sects_per_block, |
791 | GFP_NOFS); |
792 | return ret; |
793 | } |
794 | |
795 | int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks) |
796 | { |
797 | unsigned long ncleansegs; |
798 | |
799 | ncleansegs = nilfs_sufile_get_ncleansegs(sufile: nilfs->ns_sufile); |
800 | *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment; |
801 | return 0; |
802 | } |
803 | |
804 | int nilfs_near_disk_full(struct the_nilfs *nilfs) |
805 | { |
806 | unsigned long ncleansegs, nincsegs; |
807 | |
808 | ncleansegs = nilfs_sufile_get_ncleansegs(sufile: nilfs->ns_sufile); |
809 | nincsegs = atomic_read(v: &nilfs->ns_ndirtyblks) / |
810 | nilfs->ns_blocks_per_segment + 1; |
811 | |
812 | return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs; |
813 | } |
814 | |
815 | struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno) |
816 | { |
817 | struct rb_node *n; |
818 | struct nilfs_root *root; |
819 | |
820 | spin_lock(lock: &nilfs->ns_cptree_lock); |
821 | n = nilfs->ns_cptree.rb_node; |
822 | while (n) { |
823 | root = rb_entry(n, struct nilfs_root, rb_node); |
824 | |
825 | if (cno < root->cno) { |
826 | n = n->rb_left; |
827 | } else if (cno > root->cno) { |
828 | n = n->rb_right; |
829 | } else { |
830 | refcount_inc(r: &root->count); |
831 | spin_unlock(lock: &nilfs->ns_cptree_lock); |
832 | return root; |
833 | } |
834 | } |
835 | spin_unlock(lock: &nilfs->ns_cptree_lock); |
836 | |
837 | return NULL; |
838 | } |
839 | |
840 | struct nilfs_root * |
841 | nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno) |
842 | { |
843 | struct rb_node **p, *parent; |
844 | struct nilfs_root *root, *new; |
845 | int err; |
846 | |
847 | root = nilfs_lookup_root(nilfs, cno); |
848 | if (root) |
849 | return root; |
850 | |
851 | new = kzalloc(size: sizeof(*root), GFP_KERNEL); |
852 | if (!new) |
853 | return NULL; |
854 | |
855 | spin_lock(lock: &nilfs->ns_cptree_lock); |
856 | |
857 | p = &nilfs->ns_cptree.rb_node; |
858 | parent = NULL; |
859 | |
860 | while (*p) { |
861 | parent = *p; |
862 | root = rb_entry(parent, struct nilfs_root, rb_node); |
863 | |
864 | if (cno < root->cno) { |
865 | p = &(*p)->rb_left; |
866 | } else if (cno > root->cno) { |
867 | p = &(*p)->rb_right; |
868 | } else { |
869 | refcount_inc(r: &root->count); |
870 | spin_unlock(lock: &nilfs->ns_cptree_lock); |
871 | kfree(objp: new); |
872 | return root; |
873 | } |
874 | } |
875 | |
876 | new->cno = cno; |
877 | new->ifile = NULL; |
878 | new->nilfs = nilfs; |
879 | refcount_set(r: &new->count, n: 1); |
880 | atomic64_set(v: &new->inodes_count, i: 0); |
881 | atomic64_set(v: &new->blocks_count, i: 0); |
882 | |
883 | rb_link_node(node: &new->rb_node, parent, rb_link: p); |
884 | rb_insert_color(&new->rb_node, &nilfs->ns_cptree); |
885 | |
886 | spin_unlock(lock: &nilfs->ns_cptree_lock); |
887 | |
888 | err = nilfs_sysfs_create_snapshot_group(new); |
889 | if (err) { |
890 | kfree(objp: new); |
891 | new = NULL; |
892 | } |
893 | |
894 | return new; |
895 | } |
896 | |
897 | void nilfs_put_root(struct nilfs_root *root) |
898 | { |
899 | struct the_nilfs *nilfs = root->nilfs; |
900 | |
901 | if (refcount_dec_and_lock(r: &root->count, lock: &nilfs->ns_cptree_lock)) { |
902 | rb_erase(&root->rb_node, &nilfs->ns_cptree); |
903 | spin_unlock(lock: &nilfs->ns_cptree_lock); |
904 | |
905 | nilfs_sysfs_delete_snapshot_group(root); |
906 | iput(root->ifile); |
907 | |
908 | kfree(objp: root); |
909 | } |
910 | } |
911 | |