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