18a9d2191SRyusuke Konishi /* 28a9d2191SRyusuke Konishi * the_nilfs.c - the_nilfs shared structure. 38a9d2191SRyusuke Konishi * 48a9d2191SRyusuke Konishi * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation. 58a9d2191SRyusuke Konishi * 68a9d2191SRyusuke Konishi * This program is free software; you can redistribute it and/or modify 78a9d2191SRyusuke Konishi * it under the terms of the GNU General Public License as published by 88a9d2191SRyusuke Konishi * the Free Software Foundation; either version 2 of the License, or 98a9d2191SRyusuke Konishi * (at your option) any later version. 108a9d2191SRyusuke Konishi * 118a9d2191SRyusuke Konishi * This program is distributed in the hope that it will be useful, 128a9d2191SRyusuke Konishi * but WITHOUT ANY WARRANTY; without even the implied warranty of 138a9d2191SRyusuke Konishi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 148a9d2191SRyusuke Konishi * GNU General Public License for more details. 158a9d2191SRyusuke Konishi * 168a9d2191SRyusuke Konishi * You should have received a copy of the GNU General Public License 178a9d2191SRyusuke Konishi * along with this program; if not, write to the Free Software 188a9d2191SRyusuke Konishi * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 198a9d2191SRyusuke Konishi * 208a9d2191SRyusuke Konishi * Written by Ryusuke Konishi <ryusuke@osrg.net> 218a9d2191SRyusuke Konishi * 228a9d2191SRyusuke Konishi */ 238a9d2191SRyusuke Konishi 248a9d2191SRyusuke Konishi #include <linux/buffer_head.h> 258a9d2191SRyusuke Konishi #include <linux/slab.h> 268a9d2191SRyusuke Konishi #include <linux/blkdev.h> 278a9d2191SRyusuke Konishi #include <linux/backing-dev.h> 28e339ad31SRyusuke Konishi #include <linux/crc32.h> 298a9d2191SRyusuke Konishi #include "nilfs.h" 308a9d2191SRyusuke Konishi #include "segment.h" 318a9d2191SRyusuke Konishi #include "alloc.h" 328a9d2191SRyusuke Konishi #include "cpfile.h" 338a9d2191SRyusuke Konishi #include "sufile.h" 348a9d2191SRyusuke Konishi #include "dat.h" 358a9d2191SRyusuke Konishi #include "segbuf.h" 368a9d2191SRyusuke Konishi 3733c8e57cSRyusuke Konishi 3833c8e57cSRyusuke Konishi static LIST_HEAD(nilfs_objects); 3933c8e57cSRyusuke Konishi static DEFINE_SPINLOCK(nilfs_lock); 4033c8e57cSRyusuke Konishi 418a9d2191SRyusuke Konishi void nilfs_set_last_segment(struct the_nilfs *nilfs, 428a9d2191SRyusuke Konishi sector_t start_blocknr, u64 seq, __u64 cno) 438a9d2191SRyusuke Konishi { 448a9d2191SRyusuke Konishi spin_lock(&nilfs->ns_last_segment_lock); 458a9d2191SRyusuke Konishi nilfs->ns_last_pseg = start_blocknr; 468a9d2191SRyusuke Konishi nilfs->ns_last_seq = seq; 478a9d2191SRyusuke Konishi nilfs->ns_last_cno = cno; 488a9d2191SRyusuke Konishi spin_unlock(&nilfs->ns_last_segment_lock); 498a9d2191SRyusuke Konishi } 508a9d2191SRyusuke Konishi 518a9d2191SRyusuke Konishi /** 528a9d2191SRyusuke Konishi * alloc_nilfs - allocate the_nilfs structure 538a9d2191SRyusuke Konishi * @bdev: block device to which the_nilfs is related 548a9d2191SRyusuke Konishi * 558a9d2191SRyusuke Konishi * alloc_nilfs() allocates memory for the_nilfs and 568a9d2191SRyusuke Konishi * initializes its reference count and locks. 578a9d2191SRyusuke Konishi * 588a9d2191SRyusuke Konishi * Return Value: On success, pointer to the_nilfs is returned. 598a9d2191SRyusuke Konishi * On error, NULL is returned. 608a9d2191SRyusuke Konishi */ 6133c8e57cSRyusuke Konishi static struct the_nilfs *alloc_nilfs(struct block_device *bdev) 628a9d2191SRyusuke Konishi { 638a9d2191SRyusuke Konishi struct the_nilfs *nilfs; 648a9d2191SRyusuke Konishi 658a9d2191SRyusuke Konishi nilfs = kzalloc(sizeof(*nilfs), GFP_KERNEL); 668a9d2191SRyusuke Konishi if (!nilfs) 678a9d2191SRyusuke Konishi return NULL; 688a9d2191SRyusuke Konishi 698a9d2191SRyusuke Konishi nilfs->ns_bdev = bdev; 708a9d2191SRyusuke Konishi atomic_set(&nilfs->ns_count, 1); 718a9d2191SRyusuke Konishi atomic_set(&nilfs->ns_ndirtyblks, 0); 728a9d2191SRyusuke Konishi init_rwsem(&nilfs->ns_sem); 73e59399d0SRyusuke Konishi init_rwsem(&nilfs->ns_super_sem); 74aa7dfb89SRyusuke Konishi mutex_init(&nilfs->ns_mount_mutex); 75027d6404SRyusuke Konishi init_rwsem(&nilfs->ns_writer_sem); 7633c8e57cSRyusuke Konishi INIT_LIST_HEAD(&nilfs->ns_list); 778a9d2191SRyusuke Konishi INIT_LIST_HEAD(&nilfs->ns_supers); 788a9d2191SRyusuke Konishi spin_lock_init(&nilfs->ns_last_segment_lock); 798a9d2191SRyusuke Konishi nilfs->ns_gc_inodes_h = NULL; 808a9d2191SRyusuke Konishi init_rwsem(&nilfs->ns_segctor_sem); 818a9d2191SRyusuke Konishi 828a9d2191SRyusuke Konishi return nilfs; 838a9d2191SRyusuke Konishi } 848a9d2191SRyusuke Konishi 858a9d2191SRyusuke Konishi /** 8633c8e57cSRyusuke Konishi * find_or_create_nilfs - find or create nilfs object 8733c8e57cSRyusuke Konishi * @bdev: block device to which the_nilfs is related 8833c8e57cSRyusuke Konishi * 8933c8e57cSRyusuke Konishi * find_nilfs() looks up an existent nilfs object created on the 9033c8e57cSRyusuke Konishi * device and gets the reference count of the object. If no nilfs object 9133c8e57cSRyusuke Konishi * is found on the device, a new nilfs object is allocated. 9233c8e57cSRyusuke Konishi * 9333c8e57cSRyusuke Konishi * Return Value: On success, pointer to the nilfs object is returned. 9433c8e57cSRyusuke Konishi * On error, NULL is returned. 9533c8e57cSRyusuke Konishi */ 9633c8e57cSRyusuke Konishi struct the_nilfs *find_or_create_nilfs(struct block_device *bdev) 9733c8e57cSRyusuke Konishi { 9833c8e57cSRyusuke Konishi struct the_nilfs *nilfs, *new = NULL; 9933c8e57cSRyusuke Konishi 10033c8e57cSRyusuke Konishi retry: 10133c8e57cSRyusuke Konishi spin_lock(&nilfs_lock); 10233c8e57cSRyusuke Konishi list_for_each_entry(nilfs, &nilfs_objects, ns_list) { 10333c8e57cSRyusuke Konishi if (nilfs->ns_bdev == bdev) { 10433c8e57cSRyusuke Konishi get_nilfs(nilfs); 10533c8e57cSRyusuke Konishi spin_unlock(&nilfs_lock); 10633c8e57cSRyusuke Konishi if (new) 10733c8e57cSRyusuke Konishi put_nilfs(new); 10833c8e57cSRyusuke Konishi return nilfs; /* existing object */ 10933c8e57cSRyusuke Konishi } 11033c8e57cSRyusuke Konishi } 11133c8e57cSRyusuke Konishi if (new) { 11233c8e57cSRyusuke Konishi list_add_tail(&new->ns_list, &nilfs_objects); 11333c8e57cSRyusuke Konishi spin_unlock(&nilfs_lock); 11433c8e57cSRyusuke Konishi return new; /* new object */ 11533c8e57cSRyusuke Konishi } 11633c8e57cSRyusuke Konishi spin_unlock(&nilfs_lock); 11733c8e57cSRyusuke Konishi 11833c8e57cSRyusuke Konishi new = alloc_nilfs(bdev); 11933c8e57cSRyusuke Konishi if (new) 12033c8e57cSRyusuke Konishi goto retry; 12133c8e57cSRyusuke Konishi return NULL; /* insufficient memory */ 12233c8e57cSRyusuke Konishi } 12333c8e57cSRyusuke Konishi 12433c8e57cSRyusuke Konishi /** 1258a9d2191SRyusuke Konishi * put_nilfs - release a reference to the_nilfs 1268a9d2191SRyusuke Konishi * @nilfs: the_nilfs structure to be released 1278a9d2191SRyusuke Konishi * 1288a9d2191SRyusuke Konishi * put_nilfs() decrements a reference counter of the_nilfs. 1298a9d2191SRyusuke Konishi * If the reference count reaches zero, the_nilfs is freed. 1308a9d2191SRyusuke Konishi */ 1318a9d2191SRyusuke Konishi void put_nilfs(struct the_nilfs *nilfs) 1328a9d2191SRyusuke Konishi { 13333c8e57cSRyusuke Konishi spin_lock(&nilfs_lock); 13433c8e57cSRyusuke Konishi if (!atomic_dec_and_test(&nilfs->ns_count)) { 13533c8e57cSRyusuke Konishi spin_unlock(&nilfs_lock); 1368a9d2191SRyusuke Konishi return; 13733c8e57cSRyusuke Konishi } 13833c8e57cSRyusuke Konishi list_del_init(&nilfs->ns_list); 13933c8e57cSRyusuke Konishi spin_unlock(&nilfs_lock); 14033c8e57cSRyusuke Konishi 1418a9d2191SRyusuke Konishi /* 14233c8e57cSRyusuke Konishi * Increment of ns_count never occurs below because the caller 1438a9d2191SRyusuke Konishi * of get_nilfs() holds at least one reference to the_nilfs. 1448a9d2191SRyusuke Konishi * Thus its exclusion control is not required here. 1458a9d2191SRyusuke Konishi */ 14633c8e57cSRyusuke Konishi 1478a9d2191SRyusuke Konishi might_sleep(); 1488a9d2191SRyusuke Konishi if (nilfs_loaded(nilfs)) { 1498a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_sufile); 1508a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_cpfile); 1518a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_dat); 1528a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_gc_dat); 1538a9d2191SRyusuke Konishi } 1548a9d2191SRyusuke Konishi if (nilfs_init(nilfs)) { 1558a9d2191SRyusuke Konishi nilfs_destroy_gccache(nilfs); 156e339ad31SRyusuke Konishi brelse(nilfs->ns_sbh[0]); 157e339ad31SRyusuke Konishi brelse(nilfs->ns_sbh[1]); 1588a9d2191SRyusuke Konishi } 1598a9d2191SRyusuke Konishi kfree(nilfs); 1608a9d2191SRyusuke Konishi } 1618a9d2191SRyusuke Konishi 1628b94025cSRyusuke Konishi static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block) 1638a9d2191SRyusuke Konishi { 1648a9d2191SRyusuke Konishi struct buffer_head *bh_sr; 1658a9d2191SRyusuke Konishi struct nilfs_super_root *raw_sr; 166e339ad31SRyusuke Konishi struct nilfs_super_block **sbp = nilfs->ns_sbp; 1678a9d2191SRyusuke Konishi unsigned dat_entry_size, segment_usage_size, checkpoint_size; 1688a9d2191SRyusuke Konishi unsigned inode_size; 1698a9d2191SRyusuke Konishi int err; 1708a9d2191SRyusuke Konishi 1718b94025cSRyusuke Konishi err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1); 1728a9d2191SRyusuke Konishi if (unlikely(err)) 1738a9d2191SRyusuke Konishi return err; 1748a9d2191SRyusuke Konishi 1758a9d2191SRyusuke Konishi down_read(&nilfs->ns_sem); 176e339ad31SRyusuke Konishi dat_entry_size = le16_to_cpu(sbp[0]->s_dat_entry_size); 177e339ad31SRyusuke Konishi checkpoint_size = le16_to_cpu(sbp[0]->s_checkpoint_size); 178e339ad31SRyusuke Konishi segment_usage_size = le16_to_cpu(sbp[0]->s_segment_usage_size); 1798a9d2191SRyusuke Konishi up_read(&nilfs->ns_sem); 1808a9d2191SRyusuke Konishi 1818a9d2191SRyusuke Konishi inode_size = nilfs->ns_inode_size; 1828a9d2191SRyusuke Konishi 1838a9d2191SRyusuke Konishi err = -ENOMEM; 18479739565SRyusuke Konishi nilfs->ns_dat = nilfs_dat_new(nilfs, dat_entry_size); 1858a9d2191SRyusuke Konishi if (unlikely(!nilfs->ns_dat)) 1868a9d2191SRyusuke Konishi goto failed; 1878a9d2191SRyusuke Konishi 18879739565SRyusuke Konishi nilfs->ns_gc_dat = nilfs_dat_new(nilfs, dat_entry_size); 1898a9d2191SRyusuke Konishi if (unlikely(!nilfs->ns_gc_dat)) 1908a9d2191SRyusuke Konishi goto failed_dat; 1918a9d2191SRyusuke Konishi 19279739565SRyusuke Konishi nilfs->ns_cpfile = nilfs_cpfile_new(nilfs, checkpoint_size); 1938a9d2191SRyusuke Konishi if (unlikely(!nilfs->ns_cpfile)) 1948a9d2191SRyusuke Konishi goto failed_gc_dat; 1958a9d2191SRyusuke Konishi 19679739565SRyusuke Konishi nilfs->ns_sufile = nilfs_sufile_new(nilfs, segment_usage_size); 1978a9d2191SRyusuke Konishi if (unlikely(!nilfs->ns_sufile)) 1988a9d2191SRyusuke Konishi goto failed_cpfile; 1998a9d2191SRyusuke Konishi 2008a9d2191SRyusuke Konishi nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat); 2018a9d2191SRyusuke Konishi 2028707df38SRyusuke Konishi err = nilfs_dat_read(nilfs->ns_dat, (void *)bh_sr->b_data + 2038707df38SRyusuke Konishi NILFS_SR_DAT_OFFSET(inode_size)); 2048a9d2191SRyusuke Konishi if (unlikely(err)) 2058a9d2191SRyusuke Konishi goto failed_sufile; 2068a9d2191SRyusuke Konishi 2078707df38SRyusuke Konishi err = nilfs_cpfile_read(nilfs->ns_cpfile, (void *)bh_sr->b_data + 2088707df38SRyusuke Konishi NILFS_SR_CPFILE_OFFSET(inode_size)); 2098a9d2191SRyusuke Konishi if (unlikely(err)) 2108a9d2191SRyusuke Konishi goto failed_sufile; 2118a9d2191SRyusuke Konishi 2128707df38SRyusuke Konishi err = nilfs_sufile_read(nilfs->ns_sufile, (void *)bh_sr->b_data + 2138707df38SRyusuke Konishi NILFS_SR_SUFILE_OFFSET(inode_size)); 2148a9d2191SRyusuke Konishi if (unlikely(err)) 2158a9d2191SRyusuke Konishi goto failed_sufile; 2168a9d2191SRyusuke Konishi 2178a9d2191SRyusuke Konishi raw_sr = (struct nilfs_super_root *)bh_sr->b_data; 2188a9d2191SRyusuke Konishi nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime); 2198a9d2191SRyusuke Konishi 2208a9d2191SRyusuke Konishi failed: 2218a9d2191SRyusuke Konishi brelse(bh_sr); 2228a9d2191SRyusuke Konishi return err; 2238a9d2191SRyusuke Konishi 2248a9d2191SRyusuke Konishi failed_sufile: 2258a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_sufile); 2268a9d2191SRyusuke Konishi 2278a9d2191SRyusuke Konishi failed_cpfile: 2288a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_cpfile); 2298a9d2191SRyusuke Konishi 2308a9d2191SRyusuke Konishi failed_gc_dat: 2318a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_gc_dat); 2328a9d2191SRyusuke Konishi 2338a9d2191SRyusuke Konishi failed_dat: 2348a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_dat); 2358a9d2191SRyusuke Konishi goto failed; 2368a9d2191SRyusuke Konishi } 2378a9d2191SRyusuke Konishi 2388a9d2191SRyusuke Konishi static void nilfs_init_recovery_info(struct nilfs_recovery_info *ri) 2398a9d2191SRyusuke Konishi { 2408a9d2191SRyusuke Konishi memset(ri, 0, sizeof(*ri)); 2418a9d2191SRyusuke Konishi INIT_LIST_HEAD(&ri->ri_used_segments); 2428a9d2191SRyusuke Konishi } 2438a9d2191SRyusuke Konishi 2448a9d2191SRyusuke Konishi static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri) 2458a9d2191SRyusuke Konishi { 2468a9d2191SRyusuke Konishi nilfs_dispose_segment_list(&ri->ri_used_segments); 2478a9d2191SRyusuke Konishi } 2488a9d2191SRyusuke Konishi 2498a9d2191SRyusuke Konishi /** 2508a9d2191SRyusuke Konishi * load_nilfs - load and recover the nilfs 2518a9d2191SRyusuke Konishi * @nilfs: the_nilfs structure to be released 2528a9d2191SRyusuke Konishi * @sbi: nilfs_sb_info used to recover past segment 2538a9d2191SRyusuke Konishi * 2548a9d2191SRyusuke Konishi * load_nilfs() searches and load the latest super root, 2558a9d2191SRyusuke Konishi * attaches the last segment, and does recovery if needed. 2568a9d2191SRyusuke Konishi * The caller must call this exclusively for simultaneous mounts. 2578a9d2191SRyusuke Konishi */ 2588a9d2191SRyusuke Konishi int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) 2598a9d2191SRyusuke Konishi { 2608a9d2191SRyusuke Konishi struct nilfs_recovery_info ri; 2618a9d2191SRyusuke Konishi unsigned int s_flags = sbi->s_super->s_flags; 2628a9d2191SRyusuke Konishi int really_read_only = bdev_read_only(nilfs->ns_bdev); 263a057d2c0SRyusuke Konishi int valid_fs = nilfs_valid_fs(nilfs); 264f50a4c81SRyusuke Konishi int err; 2658a9d2191SRyusuke Konishi 2660234576dSRyusuke Konishi if (nilfs_loaded(nilfs)) { 2670234576dSRyusuke Konishi if (valid_fs || 2680234576dSRyusuke Konishi ((s_flags & MS_RDONLY) && nilfs_test_opt(sbi, NORECOVERY))) 269f50a4c81SRyusuke Konishi return 0; 2700234576dSRyusuke Konishi printk(KERN_ERR "NILFS: the filesystem is in an incomplete " 2710234576dSRyusuke Konishi "recovery state.\n"); 2720234576dSRyusuke Konishi return -EINVAL; 2730234576dSRyusuke Konishi } 2748a9d2191SRyusuke Konishi 275f50a4c81SRyusuke Konishi if (!valid_fs) { 276f50a4c81SRyusuke Konishi printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n"); 277f50a4c81SRyusuke Konishi if (s_flags & MS_RDONLY) { 2788a9d2191SRyusuke Konishi printk(KERN_INFO "NILFS: INFO: recovery " 2798a9d2191SRyusuke Konishi "required for readonly filesystem.\n"); 2808a9d2191SRyusuke Konishi printk(KERN_INFO "NILFS: write access will " 2818a9d2191SRyusuke Konishi "be enabled during recovery.\n"); 2828a9d2191SRyusuke Konishi } 283f50a4c81SRyusuke Konishi } 284f50a4c81SRyusuke Konishi 285f50a4c81SRyusuke Konishi nilfs_init_recovery_info(&ri); 2868a9d2191SRyusuke Konishi 2878b94025cSRyusuke Konishi err = nilfs_search_super_root(nilfs, &ri); 2888a9d2191SRyusuke Konishi if (unlikely(err)) { 2898a9d2191SRyusuke Konishi printk(KERN_ERR "NILFS: error searching super root.\n"); 2908a9d2191SRyusuke Konishi goto failed; 2918a9d2191SRyusuke Konishi } 2928a9d2191SRyusuke Konishi 2938b94025cSRyusuke Konishi err = nilfs_load_super_root(nilfs, ri.ri_super_root); 2948a9d2191SRyusuke Konishi if (unlikely(err)) { 2958a9d2191SRyusuke Konishi printk(KERN_ERR "NILFS: error loading super root.\n"); 2968a9d2191SRyusuke Konishi goto failed; 2978a9d2191SRyusuke Konishi } 2988a9d2191SRyusuke Konishi 299f50a4c81SRyusuke Konishi if (valid_fs) 300f50a4c81SRyusuke Konishi goto skip_recovery; 301f50a4c81SRyusuke Konishi 302f50a4c81SRyusuke Konishi if (s_flags & MS_RDONLY) { 3030234576dSRyusuke Konishi if (nilfs_test_opt(sbi, NORECOVERY)) { 3040234576dSRyusuke Konishi printk(KERN_INFO "NILFS: norecovery option specified. " 3050234576dSRyusuke Konishi "skipping roll-forward recovery\n"); 3060234576dSRyusuke Konishi goto skip_recovery; 3070234576dSRyusuke Konishi } 308f50a4c81SRyusuke Konishi if (really_read_only) { 309f50a4c81SRyusuke Konishi printk(KERN_ERR "NILFS: write access " 310f50a4c81SRyusuke Konishi "unavailable, cannot proceed.\n"); 311f50a4c81SRyusuke Konishi err = -EROFS; 312f50a4c81SRyusuke Konishi goto failed_unload; 313f50a4c81SRyusuke Konishi } 314f50a4c81SRyusuke Konishi sbi->s_super->s_flags &= ~MS_RDONLY; 3150234576dSRyusuke Konishi } else if (nilfs_test_opt(sbi, NORECOVERY)) { 3160234576dSRyusuke Konishi printk(KERN_ERR "NILFS: recovery cancelled because norecovery " 3170234576dSRyusuke Konishi "option was specified for a read/write mount\n"); 3180234576dSRyusuke Konishi err = -EINVAL; 3190234576dSRyusuke Konishi goto failed_unload; 320f50a4c81SRyusuke Konishi } 321f50a4c81SRyusuke Konishi 3228a9d2191SRyusuke Konishi err = nilfs_recover_logical_segments(nilfs, sbi, &ri); 323f50a4c81SRyusuke Konishi if (err) 324f50a4c81SRyusuke Konishi goto failed_unload; 325f50a4c81SRyusuke Konishi 326f50a4c81SRyusuke Konishi down_write(&nilfs->ns_sem); 327f50a4c81SRyusuke Konishi nilfs->ns_mount_state |= NILFS_VALID_FS; 328f50a4c81SRyusuke Konishi nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state); 329f50a4c81SRyusuke Konishi err = nilfs_commit_super(sbi, 1); 330f50a4c81SRyusuke Konishi up_write(&nilfs->ns_sem); 331f50a4c81SRyusuke Konishi 332f50a4c81SRyusuke Konishi if (err) { 333f50a4c81SRyusuke Konishi printk(KERN_ERR "NILFS: failed to update super block. " 334f50a4c81SRyusuke Konishi "recovery unfinished.\n"); 335f50a4c81SRyusuke Konishi goto failed_unload; 336f50a4c81SRyusuke Konishi } 337f50a4c81SRyusuke Konishi printk(KERN_INFO "NILFS: recovery complete.\n"); 338f50a4c81SRyusuke Konishi 339f50a4c81SRyusuke Konishi skip_recovery: 340f50a4c81SRyusuke Konishi set_nilfs_loaded(nilfs); 341f50a4c81SRyusuke Konishi nilfs_clear_recovery_info(&ri); 342f50a4c81SRyusuke Konishi sbi->s_super->s_flags = s_flags; 343f50a4c81SRyusuke Konishi return 0; 344f50a4c81SRyusuke Konishi 345f50a4c81SRyusuke Konishi failed_unload: 3468a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_cpfile); 3478a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_sufile); 3488a9d2191SRyusuke Konishi nilfs_mdt_destroy(nilfs->ns_dat); 3498a9d2191SRyusuke Konishi 3508a9d2191SRyusuke Konishi failed: 3518a9d2191SRyusuke Konishi nilfs_clear_recovery_info(&ri); 3528a9d2191SRyusuke Konishi sbi->s_super->s_flags = s_flags; 3538a9d2191SRyusuke Konishi return err; 3548a9d2191SRyusuke Konishi } 3558a9d2191SRyusuke Konishi 3568a9d2191SRyusuke Konishi static unsigned long long nilfs_max_size(unsigned int blkbits) 3578a9d2191SRyusuke Konishi { 3588a9d2191SRyusuke Konishi unsigned int max_bits; 3598a9d2191SRyusuke Konishi unsigned long long res = MAX_LFS_FILESIZE; /* page cache limit */ 3608a9d2191SRyusuke Konishi 3618a9d2191SRyusuke Konishi max_bits = blkbits + NILFS_BMAP_KEY_BIT; /* bmap size limit */ 3628a9d2191SRyusuke Konishi if (max_bits < 64) 3638a9d2191SRyusuke Konishi res = min_t(unsigned long long, res, (1ULL << max_bits) - 1); 3648a9d2191SRyusuke Konishi return res; 3658a9d2191SRyusuke Konishi } 3668a9d2191SRyusuke Konishi 367e339ad31SRyusuke Konishi static int nilfs_store_disk_layout(struct the_nilfs *nilfs, 3688a9d2191SRyusuke Konishi struct nilfs_super_block *sbp) 3698a9d2191SRyusuke Konishi { 3708a9d2191SRyusuke Konishi if (le32_to_cpu(sbp->s_rev_level) != NILFS_CURRENT_REV) { 3718a9d2191SRyusuke Konishi printk(KERN_ERR "NILFS: revision mismatch " 3728a9d2191SRyusuke Konishi "(superblock rev.=%d.%d, current rev.=%d.%d). " 3738a9d2191SRyusuke Konishi "Please check the version of mkfs.nilfs.\n", 3748a9d2191SRyusuke Konishi le32_to_cpu(sbp->s_rev_level), 3758a9d2191SRyusuke Konishi le16_to_cpu(sbp->s_minor_rev_level), 3768a9d2191SRyusuke Konishi NILFS_CURRENT_REV, NILFS_MINOR_REV); 3778a9d2191SRyusuke Konishi return -EINVAL; 3788a9d2191SRyusuke Konishi } 379e339ad31SRyusuke Konishi nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes); 380e339ad31SRyusuke Konishi if (nilfs->ns_sbsize > BLOCK_SIZE) 381e339ad31SRyusuke Konishi return -EINVAL; 382e339ad31SRyusuke Konishi 3838a9d2191SRyusuke Konishi nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size); 3848a9d2191SRyusuke Konishi nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino); 3858a9d2191SRyusuke Konishi 3868a9d2191SRyusuke Konishi nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment); 3878a9d2191SRyusuke Konishi if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) { 3888a9d2191SRyusuke Konishi printk(KERN_ERR "NILFS: too short segment.\n"); 3898a9d2191SRyusuke Konishi return -EINVAL; 3908a9d2191SRyusuke Konishi } 3918a9d2191SRyusuke Konishi 3928a9d2191SRyusuke Konishi nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block); 3938a9d2191SRyusuke Konishi nilfs->ns_nsegments = le64_to_cpu(sbp->s_nsegments); 3948a9d2191SRyusuke Konishi nilfs->ns_r_segments_percentage = 3958a9d2191SRyusuke Konishi le32_to_cpu(sbp->s_r_segments_percentage); 3968a9d2191SRyusuke Konishi nilfs->ns_nrsvsegs = 3978a9d2191SRyusuke Konishi max_t(unsigned long, NILFS_MIN_NRSVSEGS, 3988a9d2191SRyusuke Konishi DIV_ROUND_UP(nilfs->ns_nsegments * 3998a9d2191SRyusuke Konishi nilfs->ns_r_segments_percentage, 100)); 4008a9d2191SRyusuke Konishi nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed); 4018a9d2191SRyusuke Konishi return 0; 4028a9d2191SRyusuke Konishi } 4038a9d2191SRyusuke Konishi 404e339ad31SRyusuke Konishi static int nilfs_valid_sb(struct nilfs_super_block *sbp) 405e339ad31SRyusuke Konishi { 406e339ad31SRyusuke Konishi static unsigned char sum[4]; 407e339ad31SRyusuke Konishi const int sumoff = offsetof(struct nilfs_super_block, s_sum); 408e339ad31SRyusuke Konishi size_t bytes; 409e339ad31SRyusuke Konishi u32 crc; 410e339ad31SRyusuke Konishi 411e339ad31SRyusuke Konishi if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC) 412e339ad31SRyusuke Konishi return 0; 413e339ad31SRyusuke Konishi bytes = le16_to_cpu(sbp->s_bytes); 414e339ad31SRyusuke Konishi if (bytes > BLOCK_SIZE) 415e339ad31SRyusuke Konishi return 0; 416e339ad31SRyusuke Konishi crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp, 417e339ad31SRyusuke Konishi sumoff); 418e339ad31SRyusuke Konishi crc = crc32_le(crc, sum, 4); 419e339ad31SRyusuke Konishi crc = crc32_le(crc, (unsigned char *)sbp + sumoff + 4, 420e339ad31SRyusuke Konishi bytes - sumoff - 4); 421e339ad31SRyusuke Konishi return crc == le32_to_cpu(sbp->s_sum); 422e339ad31SRyusuke Konishi } 423e339ad31SRyusuke Konishi 424e339ad31SRyusuke Konishi static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset) 425e339ad31SRyusuke Konishi { 426e339ad31SRyusuke Konishi return offset < ((le64_to_cpu(sbp->s_nsegments) * 427e339ad31SRyusuke Konishi le32_to_cpu(sbp->s_blocks_per_segment)) << 428e339ad31SRyusuke Konishi (le32_to_cpu(sbp->s_log_block_size) + 10)); 429e339ad31SRyusuke Konishi } 430e339ad31SRyusuke Konishi 431e339ad31SRyusuke Konishi static void nilfs_release_super_block(struct the_nilfs *nilfs) 432e339ad31SRyusuke Konishi { 433e339ad31SRyusuke Konishi int i; 434e339ad31SRyusuke Konishi 435e339ad31SRyusuke Konishi for (i = 0; i < 2; i++) { 436e339ad31SRyusuke Konishi if (nilfs->ns_sbp[i]) { 437e339ad31SRyusuke Konishi brelse(nilfs->ns_sbh[i]); 438e339ad31SRyusuke Konishi nilfs->ns_sbh[i] = NULL; 439e339ad31SRyusuke Konishi nilfs->ns_sbp[i] = NULL; 440e339ad31SRyusuke Konishi } 441e339ad31SRyusuke Konishi } 442e339ad31SRyusuke Konishi } 443e339ad31SRyusuke Konishi 444e339ad31SRyusuke Konishi void nilfs_fall_back_super_block(struct the_nilfs *nilfs) 445e339ad31SRyusuke Konishi { 446e339ad31SRyusuke Konishi brelse(nilfs->ns_sbh[0]); 447e339ad31SRyusuke Konishi nilfs->ns_sbh[0] = nilfs->ns_sbh[1]; 448e339ad31SRyusuke Konishi nilfs->ns_sbp[0] = nilfs->ns_sbp[1]; 449e339ad31SRyusuke Konishi nilfs->ns_sbh[1] = NULL; 450e339ad31SRyusuke Konishi nilfs->ns_sbp[1] = NULL; 451e339ad31SRyusuke Konishi } 452e339ad31SRyusuke Konishi 453e339ad31SRyusuke Konishi void nilfs_swap_super_block(struct the_nilfs *nilfs) 454e339ad31SRyusuke Konishi { 455e339ad31SRyusuke Konishi struct buffer_head *tsbh = nilfs->ns_sbh[0]; 456e339ad31SRyusuke Konishi struct nilfs_super_block *tsbp = nilfs->ns_sbp[0]; 457e339ad31SRyusuke Konishi 458e339ad31SRyusuke Konishi nilfs->ns_sbh[0] = nilfs->ns_sbh[1]; 459e339ad31SRyusuke Konishi nilfs->ns_sbp[0] = nilfs->ns_sbp[1]; 460e339ad31SRyusuke Konishi nilfs->ns_sbh[1] = tsbh; 461e339ad31SRyusuke Konishi nilfs->ns_sbp[1] = tsbp; 462e339ad31SRyusuke Konishi } 463e339ad31SRyusuke Konishi 464e339ad31SRyusuke Konishi static int nilfs_load_super_block(struct the_nilfs *nilfs, 465e339ad31SRyusuke Konishi struct super_block *sb, int blocksize, 466e339ad31SRyusuke Konishi struct nilfs_super_block **sbpp) 467e339ad31SRyusuke Konishi { 468e339ad31SRyusuke Konishi struct nilfs_super_block **sbp = nilfs->ns_sbp; 469e339ad31SRyusuke Konishi struct buffer_head **sbh = nilfs->ns_sbh; 470e339ad31SRyusuke Konishi u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size); 471e339ad31SRyusuke Konishi int valid[2], swp = 0; 472e339ad31SRyusuke Konishi 473e339ad31SRyusuke Konishi sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize, 474e339ad31SRyusuke Konishi &sbh[0]); 475e339ad31SRyusuke Konishi sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]); 476e339ad31SRyusuke Konishi 477e339ad31SRyusuke Konishi if (!sbp[0]) { 478e339ad31SRyusuke Konishi if (!sbp[1]) { 479e339ad31SRyusuke Konishi printk(KERN_ERR "NILFS: unable to read superblock\n"); 480e339ad31SRyusuke Konishi return -EIO; 481e339ad31SRyusuke Konishi } 482e339ad31SRyusuke Konishi printk(KERN_WARNING 483e339ad31SRyusuke Konishi "NILFS warning: unable to read primary superblock\n"); 484e339ad31SRyusuke Konishi } else if (!sbp[1]) 485e339ad31SRyusuke Konishi printk(KERN_WARNING 486e339ad31SRyusuke Konishi "NILFS warning: unable to read secondary superblock\n"); 487e339ad31SRyusuke Konishi 48825294d8cSRyusuke Konishi /* 48925294d8cSRyusuke Konishi * Compare two super blocks and set 1 in swp if the secondary 49025294d8cSRyusuke Konishi * super block is valid and newer. Otherwise, set 0 in swp. 49125294d8cSRyusuke Konishi */ 492e339ad31SRyusuke Konishi valid[0] = nilfs_valid_sb(sbp[0]); 493e339ad31SRyusuke Konishi valid[1] = nilfs_valid_sb(sbp[1]); 49425294d8cSRyusuke Konishi swp = valid[1] && (!valid[0] || 49525294d8cSRyusuke Konishi le64_to_cpu(sbp[1]->s_last_cno) > 49625294d8cSRyusuke Konishi le64_to_cpu(sbp[0]->s_last_cno)); 497e339ad31SRyusuke Konishi 498e339ad31SRyusuke Konishi if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) { 499e339ad31SRyusuke Konishi brelse(sbh[1]); 500e339ad31SRyusuke Konishi sbh[1] = NULL; 501e339ad31SRyusuke Konishi sbp[1] = NULL; 502e339ad31SRyusuke Konishi swp = 0; 503e339ad31SRyusuke Konishi } 504e339ad31SRyusuke Konishi if (!valid[swp]) { 505e339ad31SRyusuke Konishi nilfs_release_super_block(nilfs); 506e339ad31SRyusuke Konishi printk(KERN_ERR "NILFS: Can't find nilfs on dev %s.\n", 507e339ad31SRyusuke Konishi sb->s_id); 508e339ad31SRyusuke Konishi return -EINVAL; 509e339ad31SRyusuke Konishi } 510e339ad31SRyusuke Konishi 511e339ad31SRyusuke Konishi if (swp) { 512e339ad31SRyusuke Konishi printk(KERN_WARNING "NILFS warning: broken superblock. " 513e339ad31SRyusuke Konishi "using spare superblock.\n"); 514e339ad31SRyusuke Konishi nilfs_swap_super_block(nilfs); 515e339ad31SRyusuke Konishi } 516e339ad31SRyusuke Konishi 517e339ad31SRyusuke Konishi nilfs->ns_sbwtime[0] = le64_to_cpu(sbp[0]->s_wtime); 518e339ad31SRyusuke Konishi nilfs->ns_sbwtime[1] = valid[!swp] ? le64_to_cpu(sbp[1]->s_wtime) : 0; 519e339ad31SRyusuke Konishi nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq); 520e339ad31SRyusuke Konishi *sbpp = sbp[0]; 521e339ad31SRyusuke Konishi return 0; 522e339ad31SRyusuke Konishi } 523e339ad31SRyusuke Konishi 5248a9d2191SRyusuke Konishi /** 5258a9d2191SRyusuke Konishi * init_nilfs - initialize a NILFS instance. 5268a9d2191SRyusuke Konishi * @nilfs: the_nilfs structure 5278a9d2191SRyusuke Konishi * @sbi: nilfs_sb_info 5288a9d2191SRyusuke Konishi * @sb: super block 5298a9d2191SRyusuke Konishi * @data: mount options 5308a9d2191SRyusuke Konishi * 5318a9d2191SRyusuke Konishi * init_nilfs() performs common initialization per block device (e.g. 5328a9d2191SRyusuke Konishi * reading the super block, getting disk layout information, initializing 5338a9d2191SRyusuke Konishi * shared fields in the_nilfs). It takes on some portion of the jobs 5348a9d2191SRyusuke Konishi * typically done by a fill_super() routine. This division arises from 5358a9d2191SRyusuke Konishi * the nature that multiple NILFS instances may be simultaneously 5368a9d2191SRyusuke Konishi * mounted on a device. 5378a9d2191SRyusuke Konishi * For multiple mounts on the same device, only the first mount 5388a9d2191SRyusuke Konishi * invokes these tasks. 5398a9d2191SRyusuke Konishi * 5408a9d2191SRyusuke Konishi * Return Value: On success, 0 is returned. On error, a negative error 5418a9d2191SRyusuke Konishi * code is returned. 5428a9d2191SRyusuke Konishi */ 5438a9d2191SRyusuke Konishi int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) 5448a9d2191SRyusuke Konishi { 5458a9d2191SRyusuke Konishi struct super_block *sb = sbi->s_super; 5468a9d2191SRyusuke Konishi struct nilfs_super_block *sbp; 5478a9d2191SRyusuke Konishi struct backing_dev_info *bdi; 5488a9d2191SRyusuke Konishi int blocksize; 549e339ad31SRyusuke Konishi int err; 5508a9d2191SRyusuke Konishi 5518a9d2191SRyusuke Konishi down_write(&nilfs->ns_sem); 5528a9d2191SRyusuke Konishi if (nilfs_init(nilfs)) { 5538a9d2191SRyusuke Konishi /* Load values from existing the_nilfs */ 554e339ad31SRyusuke Konishi sbp = nilfs->ns_sbp[0]; 5558a9d2191SRyusuke Konishi err = nilfs_store_magic_and_option(sb, sbp, data); 5568a9d2191SRyusuke Konishi if (err) 5578a9d2191SRyusuke Konishi goto out; 5588a9d2191SRyusuke Konishi 5598a9d2191SRyusuke Konishi blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); 5608a9d2191SRyusuke Konishi if (sb->s_blocksize != blocksize && 5618a9d2191SRyusuke Konishi !sb_set_blocksize(sb, blocksize)) { 5628a9d2191SRyusuke Konishi printk(KERN_ERR "NILFS: blocksize %d unfit to device\n", 5638a9d2191SRyusuke Konishi blocksize); 5648a9d2191SRyusuke Konishi err = -EINVAL; 5658a9d2191SRyusuke Konishi } 5668a9d2191SRyusuke Konishi sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits); 5678a9d2191SRyusuke Konishi goto out; 5688a9d2191SRyusuke Konishi } 5698a9d2191SRyusuke Konishi 570e339ad31SRyusuke Konishi blocksize = sb_min_blocksize(sb, BLOCK_SIZE); 571e339ad31SRyusuke Konishi if (!blocksize) { 572e339ad31SRyusuke Konishi printk(KERN_ERR "NILFS: unable to set blocksize\n"); 5738a9d2191SRyusuke Konishi err = -EINVAL; 5748a9d2191SRyusuke Konishi goto out; 5758a9d2191SRyusuke Konishi } 576e339ad31SRyusuke Konishi err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp); 577e339ad31SRyusuke Konishi if (err) 578e339ad31SRyusuke Konishi goto out; 579e339ad31SRyusuke Konishi 5808a9d2191SRyusuke Konishi err = nilfs_store_magic_and_option(sb, sbp, data); 5818a9d2191SRyusuke Konishi if (err) 5828a9d2191SRyusuke Konishi goto failed_sbh; 5838a9d2191SRyusuke Konishi 5848a9d2191SRyusuke Konishi blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); 5858a9d2191SRyusuke Konishi if (sb->s_blocksize != blocksize) { 586e1defc4fSMartin K. Petersen int hw_blocksize = bdev_logical_block_size(sb->s_bdev); 587e339ad31SRyusuke Konishi 588e339ad31SRyusuke Konishi if (blocksize < hw_blocksize) { 589e339ad31SRyusuke Konishi printk(KERN_ERR 590e339ad31SRyusuke Konishi "NILFS: blocksize %d too small for device " 591e339ad31SRyusuke Konishi "(sector-size = %d).\n", 592e339ad31SRyusuke Konishi blocksize, hw_blocksize); 5938a9d2191SRyusuke Konishi err = -EINVAL; 594e339ad31SRyusuke Konishi goto failed_sbh; 595e339ad31SRyusuke Konishi } 596e339ad31SRyusuke Konishi nilfs_release_super_block(nilfs); 597e339ad31SRyusuke Konishi sb_set_blocksize(sb, blocksize); 598e339ad31SRyusuke Konishi 599e339ad31SRyusuke Konishi err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp); 600e339ad31SRyusuke Konishi if (err) 6018a9d2191SRyusuke Konishi goto out; 6028a9d2191SRyusuke Konishi /* not failed_sbh; sbh is released automatically 6038a9d2191SRyusuke Konishi when reloading fails. */ 6048a9d2191SRyusuke Konishi } 6058a9d2191SRyusuke Konishi nilfs->ns_blocksize_bits = sb->s_blocksize_bits; 60692c60ccaSRyusuke Konishi nilfs->ns_blocksize = blocksize; 6078a9d2191SRyusuke Konishi 608e339ad31SRyusuke Konishi err = nilfs_store_disk_layout(nilfs, sbp); 6098a9d2191SRyusuke Konishi if (err) 6108a9d2191SRyusuke Konishi goto failed_sbh; 6118a9d2191SRyusuke Konishi 6128a9d2191SRyusuke Konishi sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits); 6138a9d2191SRyusuke Konishi 6148a9d2191SRyusuke Konishi nilfs->ns_mount_state = le16_to_cpu(sbp->s_state); 6158a9d2191SRyusuke Konishi 6168a9d2191SRyusuke Konishi bdi = nilfs->ns_bdev->bd_inode->i_mapping->backing_dev_info; 6178a9d2191SRyusuke Konishi nilfs->ns_bdi = bdi ? : &default_backing_dev_info; 6188a9d2191SRyusuke Konishi 6198a9d2191SRyusuke Konishi /* Finding last segment */ 6208a9d2191SRyusuke Konishi nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg); 6218a9d2191SRyusuke Konishi nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno); 6228a9d2191SRyusuke Konishi nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq); 6238a9d2191SRyusuke Konishi 6248a9d2191SRyusuke Konishi nilfs->ns_seg_seq = nilfs->ns_last_seq; 6258a9d2191SRyusuke Konishi nilfs->ns_segnum = 6268a9d2191SRyusuke Konishi nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg); 6278a9d2191SRyusuke Konishi nilfs->ns_cno = nilfs->ns_last_cno + 1; 6288a9d2191SRyusuke Konishi if (nilfs->ns_segnum >= nilfs->ns_nsegments) { 6298a9d2191SRyusuke Konishi printk(KERN_ERR "NILFS invalid last segment number.\n"); 6308a9d2191SRyusuke Konishi err = -EINVAL; 6318a9d2191SRyusuke Konishi goto failed_sbh; 6328a9d2191SRyusuke Konishi } 6338a9d2191SRyusuke Konishi /* Dummy values */ 6348a9d2191SRyusuke Konishi nilfs->ns_free_segments_count = 6358a9d2191SRyusuke Konishi nilfs->ns_nsegments - (nilfs->ns_segnum + 1); 6368a9d2191SRyusuke Konishi 6378a9d2191SRyusuke Konishi /* Initialize gcinode cache */ 6388a9d2191SRyusuke Konishi err = nilfs_init_gccache(nilfs); 6398a9d2191SRyusuke Konishi if (err) 6408a9d2191SRyusuke Konishi goto failed_sbh; 6418a9d2191SRyusuke Konishi 6428a9d2191SRyusuke Konishi set_nilfs_init(nilfs); 6438a9d2191SRyusuke Konishi err = 0; 6448a9d2191SRyusuke Konishi out: 6458a9d2191SRyusuke Konishi up_write(&nilfs->ns_sem); 6468a9d2191SRyusuke Konishi return err; 6478a9d2191SRyusuke Konishi 6488a9d2191SRyusuke Konishi failed_sbh: 649e339ad31SRyusuke Konishi nilfs_release_super_block(nilfs); 6508a9d2191SRyusuke Konishi goto out; 6518a9d2191SRyusuke Konishi } 6528a9d2191SRyusuke Konishi 653e902ec99SJiro SEKIBA int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump, 654e902ec99SJiro SEKIBA size_t nsegs) 655e902ec99SJiro SEKIBA { 656e902ec99SJiro SEKIBA sector_t seg_start, seg_end; 657e902ec99SJiro SEKIBA sector_t start = 0, nblocks = 0; 658e902ec99SJiro SEKIBA unsigned int sects_per_block; 659e902ec99SJiro SEKIBA __u64 *sn; 660e902ec99SJiro SEKIBA int ret = 0; 661e902ec99SJiro SEKIBA 662e902ec99SJiro SEKIBA sects_per_block = (1 << nilfs->ns_blocksize_bits) / 663e902ec99SJiro SEKIBA bdev_logical_block_size(nilfs->ns_bdev); 664e902ec99SJiro SEKIBA for (sn = segnump; sn < segnump + nsegs; sn++) { 665e902ec99SJiro SEKIBA nilfs_get_segment_range(nilfs, *sn, &seg_start, &seg_end); 666e902ec99SJiro SEKIBA 667e902ec99SJiro SEKIBA if (!nblocks) { 668e902ec99SJiro SEKIBA start = seg_start; 669e902ec99SJiro SEKIBA nblocks = seg_end - seg_start + 1; 670e902ec99SJiro SEKIBA } else if (start + nblocks == seg_start) { 671e902ec99SJiro SEKIBA nblocks += seg_end - seg_start + 1; 672e902ec99SJiro SEKIBA } else { 673e902ec99SJiro SEKIBA ret = blkdev_issue_discard(nilfs->ns_bdev, 674e902ec99SJiro SEKIBA start * sects_per_block, 675e902ec99SJiro SEKIBA nblocks * sects_per_block, 676e902ec99SJiro SEKIBA GFP_NOFS, 6776a47dc14SStephen Rothwell BLKDEV_IFL_BARRIER); 678e902ec99SJiro SEKIBA if (ret < 0) 679e902ec99SJiro SEKIBA return ret; 680e902ec99SJiro SEKIBA nblocks = 0; 681e902ec99SJiro SEKIBA } 682e902ec99SJiro SEKIBA } 683e902ec99SJiro SEKIBA if (nblocks) 684e902ec99SJiro SEKIBA ret = blkdev_issue_discard(nilfs->ns_bdev, 685e902ec99SJiro SEKIBA start * sects_per_block, 686e902ec99SJiro SEKIBA nblocks * sects_per_block, 6876a47dc14SStephen Rothwell GFP_NOFS, BLKDEV_IFL_BARRIER); 688e902ec99SJiro SEKIBA return ret; 689e902ec99SJiro SEKIBA } 690e902ec99SJiro SEKIBA 6918a9d2191SRyusuke Konishi int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks) 6928a9d2191SRyusuke Konishi { 6938a9d2191SRyusuke Konishi struct inode *dat = nilfs_dat_inode(nilfs); 6948a9d2191SRyusuke Konishi unsigned long ncleansegs; 6958a9d2191SRyusuke Konishi 6968a9d2191SRyusuke Konishi down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ 697ef7d4757SRyusuke Konishi ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile); 6988a9d2191SRyusuke Konishi up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ 6998a9d2191SRyusuke Konishi *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment; 700ef7d4757SRyusuke Konishi return 0; 7018a9d2191SRyusuke Konishi } 7028a9d2191SRyusuke Konishi 7038a9d2191SRyusuke Konishi int nilfs_near_disk_full(struct the_nilfs *nilfs) 7048a9d2191SRyusuke Konishi { 7058a9d2191SRyusuke Konishi unsigned long ncleansegs, nincsegs; 7068a9d2191SRyusuke Konishi 707ef7d4757SRyusuke Konishi ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile); 7088a9d2191SRyusuke Konishi nincsegs = atomic_read(&nilfs->ns_ndirtyblks) / 7098a9d2191SRyusuke Konishi nilfs->ns_blocks_per_segment + 1; 710ef7d4757SRyusuke Konishi 711ef7d4757SRyusuke Konishi return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs; 7128a9d2191SRyusuke Konishi } 7138a9d2191SRyusuke Konishi 7146dd47406SRyusuke Konishi /** 7156dd47406SRyusuke Konishi * nilfs_find_sbinfo - find existing nilfs_sb_info structure 7166dd47406SRyusuke Konishi * @nilfs: nilfs object 7176dd47406SRyusuke Konishi * @rw_mount: mount type (non-zero value for read/write mount) 7186dd47406SRyusuke Konishi * @cno: checkpoint number (zero for read-only mount) 7196dd47406SRyusuke Konishi * 7206dd47406SRyusuke Konishi * nilfs_find_sbinfo() returns the nilfs_sb_info structure which 7216dd47406SRyusuke Konishi * @rw_mount and @cno (in case of snapshots) matched. If no instance 7226dd47406SRyusuke Konishi * was found, NULL is returned. Although the super block instance can 7236dd47406SRyusuke Konishi * be unmounted after this function returns, the nilfs_sb_info struct 7246dd47406SRyusuke Konishi * is kept on memory until nilfs_put_sbinfo() is called. 7256dd47406SRyusuke Konishi */ 7266dd47406SRyusuke Konishi struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *nilfs, 7276dd47406SRyusuke Konishi int rw_mount, __u64 cno) 7286dd47406SRyusuke Konishi { 7296dd47406SRyusuke Konishi struct nilfs_sb_info *sbi; 7306dd47406SRyusuke Konishi 731e59399d0SRyusuke Konishi down_read(&nilfs->ns_super_sem); 7326dd47406SRyusuke Konishi /* 7336dd47406SRyusuke Konishi * The SNAPSHOT flag and sb->s_flags are supposed to be 734e59399d0SRyusuke Konishi * protected with nilfs->ns_super_sem. 7356dd47406SRyusuke Konishi */ 7366dd47406SRyusuke Konishi sbi = nilfs->ns_current; 7376dd47406SRyusuke Konishi if (rw_mount) { 7386dd47406SRyusuke Konishi if (sbi && !(sbi->s_super->s_flags & MS_RDONLY)) 7396dd47406SRyusuke Konishi goto found; /* read/write mount */ 7406dd47406SRyusuke Konishi else 7416dd47406SRyusuke Konishi goto out; 7426dd47406SRyusuke Konishi } else if (cno == 0) { 7436dd47406SRyusuke Konishi if (sbi && (sbi->s_super->s_flags & MS_RDONLY)) 7446dd47406SRyusuke Konishi goto found; /* read-only mount */ 7456dd47406SRyusuke Konishi else 7466dd47406SRyusuke Konishi goto out; 7476dd47406SRyusuke Konishi } 7486dd47406SRyusuke Konishi 7496dd47406SRyusuke Konishi list_for_each_entry(sbi, &nilfs->ns_supers, s_list) { 7506dd47406SRyusuke Konishi if (nilfs_test_opt(sbi, SNAPSHOT) && 7516dd47406SRyusuke Konishi sbi->s_snapshot_cno == cno) 7526dd47406SRyusuke Konishi goto found; /* snapshot mount */ 7536dd47406SRyusuke Konishi } 7546dd47406SRyusuke Konishi out: 755e59399d0SRyusuke Konishi up_read(&nilfs->ns_super_sem); 7566dd47406SRyusuke Konishi return NULL; 7576dd47406SRyusuke Konishi 7586dd47406SRyusuke Konishi found: 7596dd47406SRyusuke Konishi atomic_inc(&sbi->s_count); 760e59399d0SRyusuke Konishi up_read(&nilfs->ns_super_sem); 7616dd47406SRyusuke Konishi return sbi; 7626dd47406SRyusuke Konishi } 7636dd47406SRyusuke Konishi 7648a9d2191SRyusuke Konishi int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno, 7658a9d2191SRyusuke Konishi int snapshot_mount) 7668a9d2191SRyusuke Konishi { 7678a9d2191SRyusuke Konishi struct nilfs_sb_info *sbi; 7688a9d2191SRyusuke Konishi int ret = 0; 7698a9d2191SRyusuke Konishi 770e59399d0SRyusuke Konishi down_read(&nilfs->ns_super_sem); 7718a9d2191SRyusuke Konishi if (cno == 0 || cno > nilfs->ns_cno) 7728a9d2191SRyusuke Konishi goto out_unlock; 7738a9d2191SRyusuke Konishi 7748a9d2191SRyusuke Konishi list_for_each_entry(sbi, &nilfs->ns_supers, s_list) { 7758a9d2191SRyusuke Konishi if (sbi->s_snapshot_cno == cno && 7768a9d2191SRyusuke Konishi (!snapshot_mount || nilfs_test_opt(sbi, SNAPSHOT))) { 7778a9d2191SRyusuke Konishi /* exclude read-only mounts */ 7788a9d2191SRyusuke Konishi ret++; 7798a9d2191SRyusuke Konishi break; 7808a9d2191SRyusuke Konishi } 7818a9d2191SRyusuke Konishi } 7828a9d2191SRyusuke Konishi /* for protecting recent checkpoints */ 7838a9d2191SRyusuke Konishi if (cno >= nilfs_last_cno(nilfs)) 7848a9d2191SRyusuke Konishi ret++; 7858a9d2191SRyusuke Konishi 7868a9d2191SRyusuke Konishi out_unlock: 787e59399d0SRyusuke Konishi up_read(&nilfs->ns_super_sem); 7888a9d2191SRyusuke Konishi return ret; 7898a9d2191SRyusuke Konishi } 790