xref: /openbmc/linux/fs/nilfs2/the_nilfs.c (revision dd3932ed)
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 
416c125160SRyusuke Konishi static int nilfs_valid_sb(struct nilfs_super_block *sbp);
426c125160SRyusuke Konishi 
438a9d2191SRyusuke Konishi void nilfs_set_last_segment(struct the_nilfs *nilfs,
448a9d2191SRyusuke Konishi 			    sector_t start_blocknr, u64 seq, __u64 cno)
458a9d2191SRyusuke Konishi {
468a9d2191SRyusuke Konishi 	spin_lock(&nilfs->ns_last_segment_lock);
478a9d2191SRyusuke Konishi 	nilfs->ns_last_pseg = start_blocknr;
488a9d2191SRyusuke Konishi 	nilfs->ns_last_seq = seq;
498a9d2191SRyusuke Konishi 	nilfs->ns_last_cno = cno;
5032502047SRyusuke Konishi 
5132502047SRyusuke Konishi 	if (!nilfs_sb_dirty(nilfs)) {
5232502047SRyusuke Konishi 		if (nilfs->ns_prev_seq == nilfs->ns_last_seq)
5332502047SRyusuke Konishi 			goto stay_cursor;
5432502047SRyusuke Konishi 
5532502047SRyusuke Konishi 		set_nilfs_sb_dirty(nilfs);
5632502047SRyusuke Konishi 	}
5732502047SRyusuke Konishi 	nilfs->ns_prev_seq = nilfs->ns_last_seq;
5832502047SRyusuke Konishi 
5932502047SRyusuke Konishi  stay_cursor:
608a9d2191SRyusuke Konishi 	spin_unlock(&nilfs->ns_last_segment_lock);
618a9d2191SRyusuke Konishi }
628a9d2191SRyusuke Konishi 
638a9d2191SRyusuke Konishi /**
648a9d2191SRyusuke Konishi  * alloc_nilfs - allocate the_nilfs structure
658a9d2191SRyusuke Konishi  * @bdev: block device to which the_nilfs is related
668a9d2191SRyusuke Konishi  *
678a9d2191SRyusuke Konishi  * alloc_nilfs() allocates memory for the_nilfs and
688a9d2191SRyusuke Konishi  * initializes its reference count and locks.
698a9d2191SRyusuke Konishi  *
708a9d2191SRyusuke Konishi  * Return Value: On success, pointer to the_nilfs is returned.
718a9d2191SRyusuke Konishi  * On error, NULL is returned.
728a9d2191SRyusuke Konishi  */
7333c8e57cSRyusuke Konishi static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
748a9d2191SRyusuke Konishi {
758a9d2191SRyusuke Konishi 	struct the_nilfs *nilfs;
768a9d2191SRyusuke Konishi 
778a9d2191SRyusuke Konishi 	nilfs = kzalloc(sizeof(*nilfs), GFP_KERNEL);
788a9d2191SRyusuke Konishi 	if (!nilfs)
798a9d2191SRyusuke Konishi 		return NULL;
808a9d2191SRyusuke Konishi 
818a9d2191SRyusuke Konishi 	nilfs->ns_bdev = bdev;
828a9d2191SRyusuke Konishi 	atomic_set(&nilfs->ns_count, 1);
838a9d2191SRyusuke Konishi 	atomic_set(&nilfs->ns_ndirtyblks, 0);
848a9d2191SRyusuke Konishi 	init_rwsem(&nilfs->ns_sem);
85e59399d0SRyusuke Konishi 	init_rwsem(&nilfs->ns_super_sem);
86aa7dfb89SRyusuke Konishi 	mutex_init(&nilfs->ns_mount_mutex);
87027d6404SRyusuke Konishi 	init_rwsem(&nilfs->ns_writer_sem);
8833c8e57cSRyusuke Konishi 	INIT_LIST_HEAD(&nilfs->ns_list);
898a9d2191SRyusuke Konishi 	INIT_LIST_HEAD(&nilfs->ns_supers);
908a9d2191SRyusuke Konishi 	spin_lock_init(&nilfs->ns_last_segment_lock);
918a9d2191SRyusuke Konishi 	nilfs->ns_gc_inodes_h = NULL;
928a9d2191SRyusuke Konishi 	init_rwsem(&nilfs->ns_segctor_sem);
938a9d2191SRyusuke Konishi 
948a9d2191SRyusuke Konishi 	return nilfs;
958a9d2191SRyusuke Konishi }
968a9d2191SRyusuke Konishi 
978a9d2191SRyusuke Konishi /**
9833c8e57cSRyusuke Konishi  * find_or_create_nilfs - find or create nilfs object
9933c8e57cSRyusuke Konishi  * @bdev: block device to which the_nilfs is related
10033c8e57cSRyusuke Konishi  *
10133c8e57cSRyusuke Konishi  * find_nilfs() looks up an existent nilfs object created on the
10233c8e57cSRyusuke Konishi  * device and gets the reference count of the object.  If no nilfs object
10333c8e57cSRyusuke Konishi  * is found on the device, a new nilfs object is allocated.
10433c8e57cSRyusuke Konishi  *
10533c8e57cSRyusuke Konishi  * Return Value: On success, pointer to the nilfs object is returned.
10633c8e57cSRyusuke Konishi  * On error, NULL is returned.
10733c8e57cSRyusuke Konishi  */
10833c8e57cSRyusuke Konishi struct the_nilfs *find_or_create_nilfs(struct block_device *bdev)
10933c8e57cSRyusuke Konishi {
11033c8e57cSRyusuke Konishi 	struct the_nilfs *nilfs, *new = NULL;
11133c8e57cSRyusuke Konishi 
11233c8e57cSRyusuke Konishi  retry:
11333c8e57cSRyusuke Konishi 	spin_lock(&nilfs_lock);
11433c8e57cSRyusuke Konishi 	list_for_each_entry(nilfs, &nilfs_objects, ns_list) {
11533c8e57cSRyusuke Konishi 		if (nilfs->ns_bdev == bdev) {
11633c8e57cSRyusuke Konishi 			get_nilfs(nilfs);
11733c8e57cSRyusuke Konishi 			spin_unlock(&nilfs_lock);
11833c8e57cSRyusuke Konishi 			if (new)
11933c8e57cSRyusuke Konishi 				put_nilfs(new);
12033c8e57cSRyusuke Konishi 			return nilfs; /* existing object */
12133c8e57cSRyusuke Konishi 		}
12233c8e57cSRyusuke Konishi 	}
12333c8e57cSRyusuke Konishi 	if (new) {
12433c8e57cSRyusuke Konishi 		list_add_tail(&new->ns_list, &nilfs_objects);
12533c8e57cSRyusuke Konishi 		spin_unlock(&nilfs_lock);
12633c8e57cSRyusuke Konishi 		return new; /* new object */
12733c8e57cSRyusuke Konishi 	}
12833c8e57cSRyusuke Konishi 	spin_unlock(&nilfs_lock);
12933c8e57cSRyusuke Konishi 
13033c8e57cSRyusuke Konishi 	new = alloc_nilfs(bdev);
13133c8e57cSRyusuke Konishi 	if (new)
13233c8e57cSRyusuke Konishi 		goto retry;
13333c8e57cSRyusuke Konishi 	return NULL; /* insufficient memory */
13433c8e57cSRyusuke Konishi }
13533c8e57cSRyusuke Konishi 
13633c8e57cSRyusuke Konishi /**
1378a9d2191SRyusuke Konishi  * put_nilfs - release a reference to the_nilfs
1388a9d2191SRyusuke Konishi  * @nilfs: the_nilfs structure to be released
1398a9d2191SRyusuke Konishi  *
1408a9d2191SRyusuke Konishi  * put_nilfs() decrements a reference counter of the_nilfs.
1418a9d2191SRyusuke Konishi  * If the reference count reaches zero, the_nilfs is freed.
1428a9d2191SRyusuke Konishi  */
1438a9d2191SRyusuke Konishi void put_nilfs(struct the_nilfs *nilfs)
1448a9d2191SRyusuke Konishi {
14533c8e57cSRyusuke Konishi 	spin_lock(&nilfs_lock);
14633c8e57cSRyusuke Konishi 	if (!atomic_dec_and_test(&nilfs->ns_count)) {
14733c8e57cSRyusuke Konishi 		spin_unlock(&nilfs_lock);
1488a9d2191SRyusuke Konishi 		return;
14933c8e57cSRyusuke Konishi 	}
15033c8e57cSRyusuke Konishi 	list_del_init(&nilfs->ns_list);
15133c8e57cSRyusuke Konishi 	spin_unlock(&nilfs_lock);
15233c8e57cSRyusuke Konishi 
1538a9d2191SRyusuke Konishi 	/*
15433c8e57cSRyusuke Konishi 	 * Increment of ns_count never occurs below because the caller
1558a9d2191SRyusuke Konishi 	 * of get_nilfs() holds at least one reference to the_nilfs.
1568a9d2191SRyusuke Konishi 	 * Thus its exclusion control is not required here.
1578a9d2191SRyusuke Konishi 	 */
15833c8e57cSRyusuke Konishi 
1598a9d2191SRyusuke Konishi 	might_sleep();
1608a9d2191SRyusuke Konishi 	if (nilfs_loaded(nilfs)) {
1618a9d2191SRyusuke Konishi 		nilfs_mdt_destroy(nilfs->ns_sufile);
1628a9d2191SRyusuke Konishi 		nilfs_mdt_destroy(nilfs->ns_cpfile);
1638a9d2191SRyusuke Konishi 		nilfs_mdt_destroy(nilfs->ns_dat);
1648a9d2191SRyusuke Konishi 		nilfs_mdt_destroy(nilfs->ns_gc_dat);
1658a9d2191SRyusuke Konishi 	}
1668a9d2191SRyusuke Konishi 	if (nilfs_init(nilfs)) {
1678a9d2191SRyusuke Konishi 		nilfs_destroy_gccache(nilfs);
168e339ad31SRyusuke Konishi 		brelse(nilfs->ns_sbh[0]);
169e339ad31SRyusuke Konishi 		brelse(nilfs->ns_sbh[1]);
1708a9d2191SRyusuke Konishi 	}
1718a9d2191SRyusuke Konishi 	kfree(nilfs);
1728a9d2191SRyusuke Konishi }
1738a9d2191SRyusuke Konishi 
1748b94025cSRyusuke Konishi static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block)
1758a9d2191SRyusuke Konishi {
1768a9d2191SRyusuke Konishi 	struct buffer_head *bh_sr;
1778a9d2191SRyusuke Konishi 	struct nilfs_super_root *raw_sr;
178e339ad31SRyusuke Konishi 	struct nilfs_super_block **sbp = nilfs->ns_sbp;
1798a9d2191SRyusuke Konishi 	unsigned dat_entry_size, segment_usage_size, checkpoint_size;
1808a9d2191SRyusuke Konishi 	unsigned inode_size;
1818a9d2191SRyusuke Konishi 	int err;
1828a9d2191SRyusuke Konishi 
1838b94025cSRyusuke Konishi 	err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1);
1848a9d2191SRyusuke Konishi 	if (unlikely(err))
1858a9d2191SRyusuke Konishi 		return err;
1868a9d2191SRyusuke Konishi 
1878a9d2191SRyusuke Konishi 	down_read(&nilfs->ns_sem);
188e339ad31SRyusuke Konishi 	dat_entry_size = le16_to_cpu(sbp[0]->s_dat_entry_size);
189e339ad31SRyusuke Konishi 	checkpoint_size = le16_to_cpu(sbp[0]->s_checkpoint_size);
190e339ad31SRyusuke Konishi 	segment_usage_size = le16_to_cpu(sbp[0]->s_segment_usage_size);
1918a9d2191SRyusuke Konishi 	up_read(&nilfs->ns_sem);
1928a9d2191SRyusuke Konishi 
1938a9d2191SRyusuke Konishi 	inode_size = nilfs->ns_inode_size;
1948a9d2191SRyusuke Konishi 
1958a9d2191SRyusuke Konishi 	err = -ENOMEM;
19679739565SRyusuke Konishi 	nilfs->ns_dat = nilfs_dat_new(nilfs, dat_entry_size);
1978a9d2191SRyusuke Konishi 	if (unlikely(!nilfs->ns_dat))
1988a9d2191SRyusuke Konishi 		goto failed;
1998a9d2191SRyusuke Konishi 
20079739565SRyusuke Konishi 	nilfs->ns_gc_dat = nilfs_dat_new(nilfs, dat_entry_size);
2018a9d2191SRyusuke Konishi 	if (unlikely(!nilfs->ns_gc_dat))
2028a9d2191SRyusuke Konishi 		goto failed_dat;
2038a9d2191SRyusuke Konishi 
20479739565SRyusuke Konishi 	nilfs->ns_cpfile = nilfs_cpfile_new(nilfs, checkpoint_size);
2058a9d2191SRyusuke Konishi 	if (unlikely(!nilfs->ns_cpfile))
2068a9d2191SRyusuke Konishi 		goto failed_gc_dat;
2078a9d2191SRyusuke Konishi 
20879739565SRyusuke Konishi 	nilfs->ns_sufile = nilfs_sufile_new(nilfs, segment_usage_size);
2098a9d2191SRyusuke Konishi 	if (unlikely(!nilfs->ns_sufile))
2108a9d2191SRyusuke Konishi 		goto failed_cpfile;
2118a9d2191SRyusuke Konishi 
2128a9d2191SRyusuke Konishi 	nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat);
2138a9d2191SRyusuke Konishi 
2148707df38SRyusuke Konishi 	err = nilfs_dat_read(nilfs->ns_dat, (void *)bh_sr->b_data +
2158707df38SRyusuke Konishi 			     NILFS_SR_DAT_OFFSET(inode_size));
2168a9d2191SRyusuke Konishi 	if (unlikely(err))
2178a9d2191SRyusuke Konishi 		goto failed_sufile;
2188a9d2191SRyusuke Konishi 
2198707df38SRyusuke Konishi 	err = nilfs_cpfile_read(nilfs->ns_cpfile, (void *)bh_sr->b_data +
2208707df38SRyusuke Konishi 				NILFS_SR_CPFILE_OFFSET(inode_size));
2218a9d2191SRyusuke Konishi 	if (unlikely(err))
2228a9d2191SRyusuke Konishi 		goto failed_sufile;
2238a9d2191SRyusuke Konishi 
2248707df38SRyusuke Konishi 	err = nilfs_sufile_read(nilfs->ns_sufile, (void *)bh_sr->b_data +
2258707df38SRyusuke Konishi 				NILFS_SR_SUFILE_OFFSET(inode_size));
2268a9d2191SRyusuke Konishi 	if (unlikely(err))
2278a9d2191SRyusuke Konishi 		goto failed_sufile;
2288a9d2191SRyusuke Konishi 
2298a9d2191SRyusuke Konishi 	raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
2308a9d2191SRyusuke Konishi 	nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime);
2318a9d2191SRyusuke Konishi 
2328a9d2191SRyusuke Konishi  failed:
2338a9d2191SRyusuke Konishi 	brelse(bh_sr);
2348a9d2191SRyusuke Konishi 	return err;
2358a9d2191SRyusuke Konishi 
2368a9d2191SRyusuke Konishi  failed_sufile:
2378a9d2191SRyusuke Konishi 	nilfs_mdt_destroy(nilfs->ns_sufile);
2388a9d2191SRyusuke Konishi 
2398a9d2191SRyusuke Konishi  failed_cpfile:
2408a9d2191SRyusuke Konishi 	nilfs_mdt_destroy(nilfs->ns_cpfile);
2418a9d2191SRyusuke Konishi 
2428a9d2191SRyusuke Konishi  failed_gc_dat:
2438a9d2191SRyusuke Konishi 	nilfs_mdt_destroy(nilfs->ns_gc_dat);
2448a9d2191SRyusuke Konishi 
2458a9d2191SRyusuke Konishi  failed_dat:
2468a9d2191SRyusuke Konishi 	nilfs_mdt_destroy(nilfs->ns_dat);
2478a9d2191SRyusuke Konishi 	goto failed;
2488a9d2191SRyusuke Konishi }
2498a9d2191SRyusuke Konishi 
2508a9d2191SRyusuke Konishi static void nilfs_init_recovery_info(struct nilfs_recovery_info *ri)
2518a9d2191SRyusuke Konishi {
2528a9d2191SRyusuke Konishi 	memset(ri, 0, sizeof(*ri));
2538a9d2191SRyusuke Konishi 	INIT_LIST_HEAD(&ri->ri_used_segments);
2548a9d2191SRyusuke Konishi }
2558a9d2191SRyusuke Konishi 
2568a9d2191SRyusuke Konishi static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri)
2578a9d2191SRyusuke Konishi {
2588a9d2191SRyusuke Konishi 	nilfs_dispose_segment_list(&ri->ri_used_segments);
2598a9d2191SRyusuke Konishi }
2608a9d2191SRyusuke Konishi 
2618a9d2191SRyusuke Konishi /**
262843d63baSRyusuke Konishi  * nilfs_store_log_cursor - load log cursor from a super block
263843d63baSRyusuke Konishi  * @nilfs: nilfs object
264843d63baSRyusuke Konishi  * @sbp: buffer storing super block to be read
265843d63baSRyusuke Konishi  *
266843d63baSRyusuke Konishi  * nilfs_store_log_cursor() reads the last position of the log
267843d63baSRyusuke Konishi  * containing a super root from a given super block, and initializes
268843d63baSRyusuke Konishi  * relevant information on the nilfs object preparatory for log
269843d63baSRyusuke Konishi  * scanning and recovery.
270843d63baSRyusuke Konishi  */
271843d63baSRyusuke Konishi static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
272843d63baSRyusuke Konishi 				  struct nilfs_super_block *sbp)
273843d63baSRyusuke Konishi {
274843d63baSRyusuke Konishi 	int ret = 0;
275843d63baSRyusuke Konishi 
276843d63baSRyusuke Konishi 	nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg);
277843d63baSRyusuke Konishi 	nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
278843d63baSRyusuke Konishi 	nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);
279843d63baSRyusuke Konishi 
28032502047SRyusuke Konishi 	nilfs->ns_prev_seq = nilfs->ns_last_seq;
281843d63baSRyusuke Konishi 	nilfs->ns_seg_seq = nilfs->ns_last_seq;
282843d63baSRyusuke Konishi 	nilfs->ns_segnum =
283843d63baSRyusuke Konishi 		nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
284843d63baSRyusuke Konishi 	nilfs->ns_cno = nilfs->ns_last_cno + 1;
285843d63baSRyusuke Konishi 	if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
286843d63baSRyusuke Konishi 		printk(KERN_ERR "NILFS invalid last segment number.\n");
287843d63baSRyusuke Konishi 		ret = -EINVAL;
288843d63baSRyusuke Konishi 	}
289843d63baSRyusuke Konishi 	return ret;
290843d63baSRyusuke Konishi }
291843d63baSRyusuke Konishi 
292843d63baSRyusuke Konishi /**
2938a9d2191SRyusuke Konishi  * load_nilfs - load and recover the nilfs
2948a9d2191SRyusuke Konishi  * @nilfs: the_nilfs structure to be released
2958a9d2191SRyusuke Konishi  * @sbi: nilfs_sb_info used to recover past segment
2968a9d2191SRyusuke Konishi  *
2978a9d2191SRyusuke Konishi  * load_nilfs() searches and load the latest super root,
2988a9d2191SRyusuke Konishi  * attaches the last segment, and does recovery if needed.
2998a9d2191SRyusuke Konishi  * The caller must call this exclusively for simultaneous mounts.
3008a9d2191SRyusuke Konishi  */
3018a9d2191SRyusuke Konishi int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
3028a9d2191SRyusuke Konishi {
3038a9d2191SRyusuke Konishi 	struct nilfs_recovery_info ri;
3048a9d2191SRyusuke Konishi 	unsigned int s_flags = sbi->s_super->s_flags;
3058a9d2191SRyusuke Konishi 	int really_read_only = bdev_read_only(nilfs->ns_bdev);
306a057d2c0SRyusuke Konishi 	int valid_fs = nilfs_valid_fs(nilfs);
307f50a4c81SRyusuke Konishi 	int err;
3088a9d2191SRyusuke Konishi 
3090234576dSRyusuke Konishi 	if (nilfs_loaded(nilfs)) {
3100234576dSRyusuke Konishi 		if (valid_fs ||
3110234576dSRyusuke Konishi 		    ((s_flags & MS_RDONLY) && nilfs_test_opt(sbi, NORECOVERY)))
312f50a4c81SRyusuke Konishi 			return 0;
3130234576dSRyusuke Konishi 		printk(KERN_ERR "NILFS: the filesystem is in an incomplete "
3140234576dSRyusuke Konishi 		       "recovery state.\n");
3150234576dSRyusuke Konishi 		return -EINVAL;
3160234576dSRyusuke Konishi 	}
3178a9d2191SRyusuke Konishi 
318f50a4c81SRyusuke Konishi 	if (!valid_fs) {
319f50a4c81SRyusuke Konishi 		printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
320f50a4c81SRyusuke Konishi 		if (s_flags & MS_RDONLY) {
3218a9d2191SRyusuke Konishi 			printk(KERN_INFO "NILFS: INFO: recovery "
3228a9d2191SRyusuke Konishi 			       "required for readonly filesystem.\n");
3238a9d2191SRyusuke Konishi 			printk(KERN_INFO "NILFS: write access will "
3248a9d2191SRyusuke Konishi 			       "be enabled during recovery.\n");
3258a9d2191SRyusuke Konishi 		}
326f50a4c81SRyusuke Konishi 	}
327f50a4c81SRyusuke Konishi 
328f50a4c81SRyusuke Konishi 	nilfs_init_recovery_info(&ri);
3298a9d2191SRyusuke Konishi 
3308b94025cSRyusuke Konishi 	err = nilfs_search_super_root(nilfs, &ri);
3318a9d2191SRyusuke Konishi 	if (unlikely(err)) {
3326c125160SRyusuke Konishi 		struct nilfs_super_block **sbp = nilfs->ns_sbp;
3336c125160SRyusuke Konishi 		int blocksize;
3346c125160SRyusuke Konishi 
3356c125160SRyusuke Konishi 		if (err != -EINVAL)
3366c125160SRyusuke Konishi 			goto scan_error;
3376c125160SRyusuke Konishi 
3386c125160SRyusuke Konishi 		if (!nilfs_valid_sb(sbp[1])) {
3396c125160SRyusuke Konishi 			printk(KERN_WARNING
3406c125160SRyusuke Konishi 			       "NILFS warning: unable to fall back to spare"
3416c125160SRyusuke Konishi 			       "super block\n");
3426c125160SRyusuke Konishi 			goto scan_error;
3436c125160SRyusuke Konishi 		}
3446c125160SRyusuke Konishi 		printk(KERN_INFO
3456c125160SRyusuke Konishi 		       "NILFS: try rollback from an earlier position\n");
3466c125160SRyusuke Konishi 
3476c125160SRyusuke Konishi 		/*
3486c125160SRyusuke Konishi 		 * restore super block with its spare and reconfigure
3496c125160SRyusuke Konishi 		 * relevant states of the nilfs object.
3506c125160SRyusuke Konishi 		 */
3516c125160SRyusuke Konishi 		memcpy(sbp[0], sbp[1], nilfs->ns_sbsize);
3526c125160SRyusuke Konishi 		nilfs->ns_crc_seed = le32_to_cpu(sbp[0]->s_crc_seed);
3536c125160SRyusuke Konishi 		nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
3546c125160SRyusuke Konishi 
3556c125160SRyusuke Konishi 		/* verify consistency between two super blocks */
3566c125160SRyusuke Konishi 		blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
3576c125160SRyusuke Konishi 		if (blocksize != nilfs->ns_blocksize) {
3586c125160SRyusuke Konishi 			printk(KERN_WARNING
3596c125160SRyusuke Konishi 			       "NILFS warning: blocksize differs between "
3606c125160SRyusuke Konishi 			       "two super blocks (%d != %d)\n",
3616c125160SRyusuke Konishi 			       blocksize, nilfs->ns_blocksize);
3626c125160SRyusuke Konishi 			goto scan_error;
3636c125160SRyusuke Konishi 		}
3646c125160SRyusuke Konishi 
3656c125160SRyusuke Konishi 		err = nilfs_store_log_cursor(nilfs, sbp[0]);
3666c125160SRyusuke Konishi 		if (err)
3676c125160SRyusuke Konishi 			goto scan_error;
3686c125160SRyusuke Konishi 
3696c125160SRyusuke Konishi 		/* drop clean flag to allow roll-forward and recovery */
3706c125160SRyusuke Konishi 		nilfs->ns_mount_state &= ~NILFS_VALID_FS;
3716c125160SRyusuke Konishi 		valid_fs = 0;
3726c125160SRyusuke Konishi 
3736c125160SRyusuke Konishi 		err = nilfs_search_super_root(nilfs, &ri);
3746c125160SRyusuke Konishi 		if (err)
3756c125160SRyusuke Konishi 			goto scan_error;
3768a9d2191SRyusuke Konishi 	}
3778a9d2191SRyusuke Konishi 
3788b94025cSRyusuke Konishi 	err = nilfs_load_super_root(nilfs, ri.ri_super_root);
3798a9d2191SRyusuke Konishi 	if (unlikely(err)) {
3808a9d2191SRyusuke Konishi 		printk(KERN_ERR "NILFS: error loading super root.\n");
3818a9d2191SRyusuke Konishi 		goto failed;
3828a9d2191SRyusuke Konishi 	}
3838a9d2191SRyusuke Konishi 
384f50a4c81SRyusuke Konishi 	if (valid_fs)
385f50a4c81SRyusuke Konishi 		goto skip_recovery;
386f50a4c81SRyusuke Konishi 
387f50a4c81SRyusuke Konishi 	if (s_flags & MS_RDONLY) {
388c5ca48aaSRyusuke Konishi 		__u64 features;
389c5ca48aaSRyusuke Konishi 
3900234576dSRyusuke Konishi 		if (nilfs_test_opt(sbi, NORECOVERY)) {
3910234576dSRyusuke Konishi 			printk(KERN_INFO "NILFS: norecovery option specified. "
3920234576dSRyusuke Konishi 			       "skipping roll-forward recovery\n");
3930234576dSRyusuke Konishi 			goto skip_recovery;
3940234576dSRyusuke Konishi 		}
395c5ca48aaSRyusuke Konishi 		features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) &
396c5ca48aaSRyusuke Konishi 			~NILFS_FEATURE_COMPAT_RO_SUPP;
397c5ca48aaSRyusuke Konishi 		if (features) {
398c5ca48aaSRyusuke Konishi 			printk(KERN_ERR "NILFS: couldn't proceed with "
399c5ca48aaSRyusuke Konishi 			       "recovery because of unsupported optional "
400c5ca48aaSRyusuke Konishi 			       "features (%llx)\n",
401c5ca48aaSRyusuke Konishi 			       (unsigned long long)features);
402c5ca48aaSRyusuke Konishi 			err = -EROFS;
403c5ca48aaSRyusuke Konishi 			goto failed_unload;
404c5ca48aaSRyusuke Konishi 		}
405f50a4c81SRyusuke Konishi 		if (really_read_only) {
406f50a4c81SRyusuke Konishi 			printk(KERN_ERR "NILFS: write access "
407f50a4c81SRyusuke Konishi 			       "unavailable, cannot proceed.\n");
408f50a4c81SRyusuke Konishi 			err = -EROFS;
409f50a4c81SRyusuke Konishi 			goto failed_unload;
410f50a4c81SRyusuke Konishi 		}
411f50a4c81SRyusuke Konishi 		sbi->s_super->s_flags &= ~MS_RDONLY;
4120234576dSRyusuke Konishi 	} else if (nilfs_test_opt(sbi, NORECOVERY)) {
4130234576dSRyusuke Konishi 		printk(KERN_ERR "NILFS: recovery cancelled because norecovery "
4140234576dSRyusuke Konishi 		       "option was specified for a read/write mount\n");
4150234576dSRyusuke Konishi 		err = -EINVAL;
4160234576dSRyusuke Konishi 		goto failed_unload;
417f50a4c81SRyusuke Konishi 	}
418f50a4c81SRyusuke Konishi 
419aee5ce2fSRyusuke Konishi 	err = nilfs_salvage_orphan_logs(nilfs, sbi, &ri);
420f50a4c81SRyusuke Konishi 	if (err)
421f50a4c81SRyusuke Konishi 		goto failed_unload;
422f50a4c81SRyusuke Konishi 
423f50a4c81SRyusuke Konishi 	down_write(&nilfs->ns_sem);
4247ecaa46cSRyusuke Konishi 	nilfs->ns_mount_state |= NILFS_VALID_FS; /* set "clean" flag */
4257ecaa46cSRyusuke Konishi 	err = nilfs_cleanup_super(sbi);
426f50a4c81SRyusuke Konishi 	up_write(&nilfs->ns_sem);
427f50a4c81SRyusuke Konishi 
428f50a4c81SRyusuke Konishi 	if (err) {
429f50a4c81SRyusuke Konishi 		printk(KERN_ERR "NILFS: failed to update super block. "
430f50a4c81SRyusuke Konishi 		       "recovery unfinished.\n");
431f50a4c81SRyusuke Konishi 		goto failed_unload;
432f50a4c81SRyusuke Konishi 	}
433f50a4c81SRyusuke Konishi 	printk(KERN_INFO "NILFS: recovery complete.\n");
434f50a4c81SRyusuke Konishi 
435f50a4c81SRyusuke Konishi  skip_recovery:
436f50a4c81SRyusuke Konishi 	set_nilfs_loaded(nilfs);
437f50a4c81SRyusuke Konishi 	nilfs_clear_recovery_info(&ri);
438f50a4c81SRyusuke Konishi 	sbi->s_super->s_flags = s_flags;
439f50a4c81SRyusuke Konishi 	return 0;
440f50a4c81SRyusuke Konishi 
4416c125160SRyusuke Konishi  scan_error:
4426c125160SRyusuke Konishi 	printk(KERN_ERR "NILFS: error searching super root.\n");
4436c125160SRyusuke Konishi 	goto failed;
4446c125160SRyusuke Konishi 
445f50a4c81SRyusuke Konishi  failed_unload:
4468a9d2191SRyusuke Konishi 	nilfs_mdt_destroy(nilfs->ns_cpfile);
4478a9d2191SRyusuke Konishi 	nilfs_mdt_destroy(nilfs->ns_sufile);
4488a9d2191SRyusuke Konishi 	nilfs_mdt_destroy(nilfs->ns_dat);
4498a9d2191SRyusuke Konishi 
4508a9d2191SRyusuke Konishi  failed:
4518a9d2191SRyusuke Konishi 	nilfs_clear_recovery_info(&ri);
4528a9d2191SRyusuke Konishi 	sbi->s_super->s_flags = s_flags;
4538a9d2191SRyusuke Konishi 	return err;
4548a9d2191SRyusuke Konishi }
4558a9d2191SRyusuke Konishi 
4568a9d2191SRyusuke Konishi static unsigned long long nilfs_max_size(unsigned int blkbits)
4578a9d2191SRyusuke Konishi {
4588a9d2191SRyusuke Konishi 	unsigned int max_bits;
4598a9d2191SRyusuke Konishi 	unsigned long long res = MAX_LFS_FILESIZE; /* page cache limit */
4608a9d2191SRyusuke Konishi 
4618a9d2191SRyusuke Konishi 	max_bits = blkbits + NILFS_BMAP_KEY_BIT; /* bmap size limit */
4628a9d2191SRyusuke Konishi 	if (max_bits < 64)
4638a9d2191SRyusuke Konishi 		res = min_t(unsigned long long, res, (1ULL << max_bits) - 1);
4648a9d2191SRyusuke Konishi 	return res;
4658a9d2191SRyusuke Konishi }
4668a9d2191SRyusuke Konishi 
467e339ad31SRyusuke Konishi static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
4688a9d2191SRyusuke Konishi 				   struct nilfs_super_block *sbp)
4698a9d2191SRyusuke Konishi {
4708a9d2191SRyusuke Konishi 	if (le32_to_cpu(sbp->s_rev_level) != NILFS_CURRENT_REV) {
4718a9d2191SRyusuke Konishi 		printk(KERN_ERR "NILFS: revision mismatch "
4728a9d2191SRyusuke Konishi 		       "(superblock rev.=%d.%d, current rev.=%d.%d). "
4738a9d2191SRyusuke Konishi 		       "Please check the version of mkfs.nilfs.\n",
4748a9d2191SRyusuke Konishi 		       le32_to_cpu(sbp->s_rev_level),
4758a9d2191SRyusuke Konishi 		       le16_to_cpu(sbp->s_minor_rev_level),
4768a9d2191SRyusuke Konishi 		       NILFS_CURRENT_REV, NILFS_MINOR_REV);
4778a9d2191SRyusuke Konishi 		return -EINVAL;
4788a9d2191SRyusuke Konishi 	}
479e339ad31SRyusuke Konishi 	nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes);
480e339ad31SRyusuke Konishi 	if (nilfs->ns_sbsize > BLOCK_SIZE)
481e339ad31SRyusuke Konishi 		return -EINVAL;
482e339ad31SRyusuke Konishi 
4838a9d2191SRyusuke Konishi 	nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
4848a9d2191SRyusuke Konishi 	nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino);
4858a9d2191SRyusuke Konishi 
4868a9d2191SRyusuke Konishi 	nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
4878a9d2191SRyusuke Konishi 	if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
4888a9d2191SRyusuke Konishi 		printk(KERN_ERR "NILFS: too short segment.\n");
4898a9d2191SRyusuke Konishi 		return -EINVAL;
4908a9d2191SRyusuke Konishi 	}
4918a9d2191SRyusuke Konishi 
4928a9d2191SRyusuke Konishi 	nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block);
4938a9d2191SRyusuke Konishi 	nilfs->ns_nsegments = le64_to_cpu(sbp->s_nsegments);
4948a9d2191SRyusuke Konishi 	nilfs->ns_r_segments_percentage =
4958a9d2191SRyusuke Konishi 		le32_to_cpu(sbp->s_r_segments_percentage);
4968a9d2191SRyusuke Konishi 	nilfs->ns_nrsvsegs =
4978a9d2191SRyusuke Konishi 		max_t(unsigned long, NILFS_MIN_NRSVSEGS,
4988a9d2191SRyusuke Konishi 		      DIV_ROUND_UP(nilfs->ns_nsegments *
4998a9d2191SRyusuke Konishi 				   nilfs->ns_r_segments_percentage, 100));
5008a9d2191SRyusuke Konishi 	nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
5018a9d2191SRyusuke Konishi 	return 0;
5028a9d2191SRyusuke Konishi }
5038a9d2191SRyusuke Konishi 
504e339ad31SRyusuke Konishi static int nilfs_valid_sb(struct nilfs_super_block *sbp)
505e339ad31SRyusuke Konishi {
506e339ad31SRyusuke Konishi 	static unsigned char sum[4];
507e339ad31SRyusuke Konishi 	const int sumoff = offsetof(struct nilfs_super_block, s_sum);
508e339ad31SRyusuke Konishi 	size_t bytes;
509e339ad31SRyusuke Konishi 	u32 crc;
510e339ad31SRyusuke Konishi 
511e339ad31SRyusuke Konishi 	if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC)
512e339ad31SRyusuke Konishi 		return 0;
513e339ad31SRyusuke Konishi 	bytes = le16_to_cpu(sbp->s_bytes);
514e339ad31SRyusuke Konishi 	if (bytes > BLOCK_SIZE)
515e339ad31SRyusuke Konishi 		return 0;
516e339ad31SRyusuke Konishi 	crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp,
517e339ad31SRyusuke Konishi 		       sumoff);
518e339ad31SRyusuke Konishi 	crc = crc32_le(crc, sum, 4);
519e339ad31SRyusuke Konishi 	crc = crc32_le(crc, (unsigned char *)sbp + sumoff + 4,
520e339ad31SRyusuke Konishi 		       bytes - sumoff - 4);
521e339ad31SRyusuke Konishi 	return crc == le32_to_cpu(sbp->s_sum);
522e339ad31SRyusuke Konishi }
523e339ad31SRyusuke Konishi 
524e339ad31SRyusuke Konishi static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
525e339ad31SRyusuke Konishi {
526e339ad31SRyusuke Konishi 	return offset < ((le64_to_cpu(sbp->s_nsegments) *
527e339ad31SRyusuke Konishi 			  le32_to_cpu(sbp->s_blocks_per_segment)) <<
528e339ad31SRyusuke Konishi 			 (le32_to_cpu(sbp->s_log_block_size) + 10));
529e339ad31SRyusuke Konishi }
530e339ad31SRyusuke Konishi 
531e339ad31SRyusuke Konishi static void nilfs_release_super_block(struct the_nilfs *nilfs)
532e339ad31SRyusuke Konishi {
533e339ad31SRyusuke Konishi 	int i;
534e339ad31SRyusuke Konishi 
535e339ad31SRyusuke Konishi 	for (i = 0; i < 2; i++) {
536e339ad31SRyusuke Konishi 		if (nilfs->ns_sbp[i]) {
537e339ad31SRyusuke Konishi 			brelse(nilfs->ns_sbh[i]);
538e339ad31SRyusuke Konishi 			nilfs->ns_sbh[i] = NULL;
539e339ad31SRyusuke Konishi 			nilfs->ns_sbp[i] = NULL;
540e339ad31SRyusuke Konishi 		}
541e339ad31SRyusuke Konishi 	}
542e339ad31SRyusuke Konishi }
543e339ad31SRyusuke Konishi 
544e339ad31SRyusuke Konishi void nilfs_fall_back_super_block(struct the_nilfs *nilfs)
545e339ad31SRyusuke Konishi {
546e339ad31SRyusuke Konishi 	brelse(nilfs->ns_sbh[0]);
547e339ad31SRyusuke Konishi 	nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
548e339ad31SRyusuke Konishi 	nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
549e339ad31SRyusuke Konishi 	nilfs->ns_sbh[1] = NULL;
550e339ad31SRyusuke Konishi 	nilfs->ns_sbp[1] = NULL;
551e339ad31SRyusuke Konishi }
552e339ad31SRyusuke Konishi 
553e339ad31SRyusuke Konishi void nilfs_swap_super_block(struct the_nilfs *nilfs)
554e339ad31SRyusuke Konishi {
555e339ad31SRyusuke Konishi 	struct buffer_head *tsbh = nilfs->ns_sbh[0];
556e339ad31SRyusuke Konishi 	struct nilfs_super_block *tsbp = nilfs->ns_sbp[0];
557e339ad31SRyusuke Konishi 
558e339ad31SRyusuke Konishi 	nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
559e339ad31SRyusuke Konishi 	nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
560e339ad31SRyusuke Konishi 	nilfs->ns_sbh[1] = tsbh;
561e339ad31SRyusuke Konishi 	nilfs->ns_sbp[1] = tsbp;
562e339ad31SRyusuke Konishi }
563e339ad31SRyusuke Konishi 
564e339ad31SRyusuke Konishi static int nilfs_load_super_block(struct the_nilfs *nilfs,
565e339ad31SRyusuke Konishi 				  struct super_block *sb, int blocksize,
566e339ad31SRyusuke Konishi 				  struct nilfs_super_block **sbpp)
567e339ad31SRyusuke Konishi {
568e339ad31SRyusuke Konishi 	struct nilfs_super_block **sbp = nilfs->ns_sbp;
569e339ad31SRyusuke Konishi 	struct buffer_head **sbh = nilfs->ns_sbh;
570e339ad31SRyusuke Konishi 	u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size);
571e339ad31SRyusuke Konishi 	int valid[2], swp = 0;
572e339ad31SRyusuke Konishi 
573e339ad31SRyusuke Konishi 	sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize,
574e339ad31SRyusuke Konishi 					&sbh[0]);
575e339ad31SRyusuke Konishi 	sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]);
576e339ad31SRyusuke Konishi 
577e339ad31SRyusuke Konishi 	if (!sbp[0]) {
578e339ad31SRyusuke Konishi 		if (!sbp[1]) {
579e339ad31SRyusuke Konishi 			printk(KERN_ERR "NILFS: unable to read superblock\n");
580e339ad31SRyusuke Konishi 			return -EIO;
581e339ad31SRyusuke Konishi 		}
582e339ad31SRyusuke Konishi 		printk(KERN_WARNING
583e339ad31SRyusuke Konishi 		       "NILFS warning: unable to read primary superblock\n");
584e339ad31SRyusuke Konishi 	} else if (!sbp[1])
585e339ad31SRyusuke Konishi 		printk(KERN_WARNING
586e339ad31SRyusuke Konishi 		       "NILFS warning: unable to read secondary superblock\n");
587e339ad31SRyusuke Konishi 
58825294d8cSRyusuke Konishi 	/*
58925294d8cSRyusuke Konishi 	 * Compare two super blocks and set 1 in swp if the secondary
59025294d8cSRyusuke Konishi 	 * super block is valid and newer.  Otherwise, set 0 in swp.
59125294d8cSRyusuke Konishi 	 */
592e339ad31SRyusuke Konishi 	valid[0] = nilfs_valid_sb(sbp[0]);
593e339ad31SRyusuke Konishi 	valid[1] = nilfs_valid_sb(sbp[1]);
59425294d8cSRyusuke Konishi 	swp = valid[1] && (!valid[0] ||
59525294d8cSRyusuke Konishi 			   le64_to_cpu(sbp[1]->s_last_cno) >
59625294d8cSRyusuke Konishi 			   le64_to_cpu(sbp[0]->s_last_cno));
597e339ad31SRyusuke Konishi 
598e339ad31SRyusuke Konishi 	if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) {
599e339ad31SRyusuke Konishi 		brelse(sbh[1]);
600e339ad31SRyusuke Konishi 		sbh[1] = NULL;
601e339ad31SRyusuke Konishi 		sbp[1] = NULL;
602e339ad31SRyusuke Konishi 		swp = 0;
603e339ad31SRyusuke Konishi 	}
604e339ad31SRyusuke Konishi 	if (!valid[swp]) {
605e339ad31SRyusuke Konishi 		nilfs_release_super_block(nilfs);
606e339ad31SRyusuke Konishi 		printk(KERN_ERR "NILFS: Can't find nilfs on dev %s.\n",
607e339ad31SRyusuke Konishi 		       sb->s_id);
608e339ad31SRyusuke Konishi 		return -EINVAL;
609e339ad31SRyusuke Konishi 	}
610e339ad31SRyusuke Konishi 
611ea1a16f7SRyusuke Konishi 	if (!valid[!swp])
612e339ad31SRyusuke Konishi 		printk(KERN_WARNING "NILFS warning: broken superblock. "
613e339ad31SRyusuke Konishi 		       "using spare superblock.\n");
614ea1a16f7SRyusuke Konishi 	if (swp)
615e339ad31SRyusuke Konishi 		nilfs_swap_super_block(nilfs);
616e339ad31SRyusuke Konishi 
617b2ac86e1SJiro SEKIBA 	nilfs->ns_sbwcount = 0;
618b2ac86e1SJiro SEKIBA 	nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
619e339ad31SRyusuke Konishi 	nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq);
620e339ad31SRyusuke Konishi 	*sbpp = sbp[0];
621e339ad31SRyusuke Konishi 	return 0;
622e339ad31SRyusuke Konishi }
623e339ad31SRyusuke Konishi 
6248a9d2191SRyusuke Konishi /**
6258a9d2191SRyusuke Konishi  * init_nilfs - initialize a NILFS instance.
6268a9d2191SRyusuke Konishi  * @nilfs: the_nilfs structure
6278a9d2191SRyusuke Konishi  * @sbi: nilfs_sb_info
6288a9d2191SRyusuke Konishi  * @sb: super block
6298a9d2191SRyusuke Konishi  * @data: mount options
6308a9d2191SRyusuke Konishi  *
6318a9d2191SRyusuke Konishi  * init_nilfs() performs common initialization per block device (e.g.
6328a9d2191SRyusuke Konishi  * reading the super block, getting disk layout information, initializing
6338a9d2191SRyusuke Konishi  * shared fields in the_nilfs). It takes on some portion of the jobs
6348a9d2191SRyusuke Konishi  * typically done by a fill_super() routine. This division arises from
6358a9d2191SRyusuke Konishi  * the nature that multiple NILFS instances may be simultaneously
6368a9d2191SRyusuke Konishi  * mounted on a device.
6378a9d2191SRyusuke Konishi  * For multiple mounts on the same device, only the first mount
6388a9d2191SRyusuke Konishi  * invokes these tasks.
6398a9d2191SRyusuke Konishi  *
6408a9d2191SRyusuke Konishi  * Return Value: On success, 0 is returned. On error, a negative error
6418a9d2191SRyusuke Konishi  * code is returned.
6428a9d2191SRyusuke Konishi  */
6438a9d2191SRyusuke Konishi int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
6448a9d2191SRyusuke Konishi {
6458a9d2191SRyusuke Konishi 	struct super_block *sb = sbi->s_super;
6468a9d2191SRyusuke Konishi 	struct nilfs_super_block *sbp;
6478a9d2191SRyusuke Konishi 	struct backing_dev_info *bdi;
6488a9d2191SRyusuke Konishi 	int blocksize;
649e339ad31SRyusuke Konishi 	int err;
6508a9d2191SRyusuke Konishi 
6518a9d2191SRyusuke Konishi 	down_write(&nilfs->ns_sem);
6528a9d2191SRyusuke Konishi 	if (nilfs_init(nilfs)) {
6538a9d2191SRyusuke Konishi 		/* Load values from existing the_nilfs */
654e339ad31SRyusuke Konishi 		sbp = nilfs->ns_sbp[0];
6558a9d2191SRyusuke Konishi 		err = nilfs_store_magic_and_option(sb, sbp, data);
6568a9d2191SRyusuke Konishi 		if (err)
6578a9d2191SRyusuke Konishi 			goto out;
6588a9d2191SRyusuke Konishi 
659c5ca48aaSRyusuke Konishi 		err = nilfs_check_feature_compatibility(sb, sbp);
660c5ca48aaSRyusuke Konishi 		if (err)
661c5ca48aaSRyusuke Konishi 			goto out;
662c5ca48aaSRyusuke Konishi 
6638a9d2191SRyusuke Konishi 		blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
6648a9d2191SRyusuke Konishi 		if (sb->s_blocksize != blocksize &&
6658a9d2191SRyusuke Konishi 		    !sb_set_blocksize(sb, blocksize)) {
6668a9d2191SRyusuke Konishi 			printk(KERN_ERR "NILFS: blocksize %d unfit to device\n",
6678a9d2191SRyusuke Konishi 			       blocksize);
6688a9d2191SRyusuke Konishi 			err = -EINVAL;
6698a9d2191SRyusuke Konishi 		}
6708a9d2191SRyusuke Konishi 		sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
6718a9d2191SRyusuke Konishi 		goto out;
6728a9d2191SRyusuke Konishi 	}
6738a9d2191SRyusuke Konishi 
67489c0fd01SRyusuke Konishi 	blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
675e339ad31SRyusuke Konishi 	if (!blocksize) {
676e339ad31SRyusuke Konishi 		printk(KERN_ERR "NILFS: unable to set blocksize\n");
6778a9d2191SRyusuke Konishi 		err = -EINVAL;
6788a9d2191SRyusuke Konishi 		goto out;
6798a9d2191SRyusuke Konishi 	}
680e339ad31SRyusuke Konishi 	err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
681e339ad31SRyusuke Konishi 	if (err)
682e339ad31SRyusuke Konishi 		goto out;
683e339ad31SRyusuke Konishi 
6848a9d2191SRyusuke Konishi 	err = nilfs_store_magic_and_option(sb, sbp, data);
6858a9d2191SRyusuke Konishi 	if (err)
6868a9d2191SRyusuke Konishi 		goto failed_sbh;
6878a9d2191SRyusuke Konishi 
688c5ca48aaSRyusuke Konishi 	err = nilfs_check_feature_compatibility(sb, sbp);
689c5ca48aaSRyusuke Konishi 	if (err)
690c5ca48aaSRyusuke Konishi 		goto failed_sbh;
691c5ca48aaSRyusuke Konishi 
6928a9d2191SRyusuke Konishi 	blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
69389c0fd01SRyusuke Konishi 	if (blocksize < NILFS_MIN_BLOCK_SIZE ||
69489c0fd01SRyusuke Konishi 	    blocksize > NILFS_MAX_BLOCK_SIZE) {
69589c0fd01SRyusuke Konishi 		printk(KERN_ERR "NILFS: couldn't mount because of unsupported "
69689c0fd01SRyusuke Konishi 		       "filesystem blocksize %d\n", blocksize);
69789c0fd01SRyusuke Konishi 		err = -EINVAL;
69889c0fd01SRyusuke Konishi 		goto failed_sbh;
69989c0fd01SRyusuke Konishi 	}
7008a9d2191SRyusuke Konishi 	if (sb->s_blocksize != blocksize) {
701e1defc4fSMartin K. Petersen 		int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
702e339ad31SRyusuke Konishi 
703e339ad31SRyusuke Konishi 		if (blocksize < hw_blocksize) {
704e339ad31SRyusuke Konishi 			printk(KERN_ERR
705e339ad31SRyusuke Konishi 			       "NILFS: blocksize %d too small for device "
706e339ad31SRyusuke Konishi 			       "(sector-size = %d).\n",
707e339ad31SRyusuke Konishi 			       blocksize, hw_blocksize);
7088a9d2191SRyusuke Konishi 			err = -EINVAL;
709e339ad31SRyusuke Konishi 			goto failed_sbh;
710e339ad31SRyusuke Konishi 		}
711e339ad31SRyusuke Konishi 		nilfs_release_super_block(nilfs);
712e339ad31SRyusuke Konishi 		sb_set_blocksize(sb, blocksize);
713e339ad31SRyusuke Konishi 
714e339ad31SRyusuke Konishi 		err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
715e339ad31SRyusuke Konishi 		if (err)
7168a9d2191SRyusuke Konishi 			goto out;
7178a9d2191SRyusuke Konishi 			/* not failed_sbh; sbh is released automatically
7188a9d2191SRyusuke Konishi 			   when reloading fails. */
7198a9d2191SRyusuke Konishi 	}
7208a9d2191SRyusuke Konishi 	nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
72192c60ccaSRyusuke Konishi 	nilfs->ns_blocksize = blocksize;
7228a9d2191SRyusuke Konishi 
723e339ad31SRyusuke Konishi 	err = nilfs_store_disk_layout(nilfs, sbp);
7248a9d2191SRyusuke Konishi 	if (err)
7258a9d2191SRyusuke Konishi 		goto failed_sbh;
7268a9d2191SRyusuke Konishi 
7278a9d2191SRyusuke Konishi 	sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
7288a9d2191SRyusuke Konishi 
7298a9d2191SRyusuke Konishi 	nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
7308a9d2191SRyusuke Konishi 
7318a9d2191SRyusuke Konishi 	bdi = nilfs->ns_bdev->bd_inode->i_mapping->backing_dev_info;
7328a9d2191SRyusuke Konishi 	nilfs->ns_bdi = bdi ? : &default_backing_dev_info;
7338a9d2191SRyusuke Konishi 
734843d63baSRyusuke Konishi 	err = nilfs_store_log_cursor(nilfs, sbp);
735843d63baSRyusuke Konishi 	if (err)
7368a9d2191SRyusuke Konishi 		goto failed_sbh;
7378a9d2191SRyusuke Konishi 
7388a9d2191SRyusuke Konishi 	/* Initialize gcinode cache */
7398a9d2191SRyusuke Konishi 	err = nilfs_init_gccache(nilfs);
7408a9d2191SRyusuke Konishi 	if (err)
7418a9d2191SRyusuke Konishi 		goto failed_sbh;
7428a9d2191SRyusuke Konishi 
7438a9d2191SRyusuke Konishi 	set_nilfs_init(nilfs);
7448a9d2191SRyusuke Konishi 	err = 0;
7458a9d2191SRyusuke Konishi  out:
7468a9d2191SRyusuke Konishi 	up_write(&nilfs->ns_sem);
7478a9d2191SRyusuke Konishi 	return err;
7488a9d2191SRyusuke Konishi 
7498a9d2191SRyusuke Konishi  failed_sbh:
750e339ad31SRyusuke Konishi 	nilfs_release_super_block(nilfs);
7518a9d2191SRyusuke Konishi 	goto out;
7528a9d2191SRyusuke Konishi }
7538a9d2191SRyusuke Konishi 
754e902ec99SJiro SEKIBA int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump,
755e902ec99SJiro SEKIBA 			    size_t nsegs)
756e902ec99SJiro SEKIBA {
757e902ec99SJiro SEKIBA 	sector_t seg_start, seg_end;
758e902ec99SJiro SEKIBA 	sector_t start = 0, nblocks = 0;
759e902ec99SJiro SEKIBA 	unsigned int sects_per_block;
760e902ec99SJiro SEKIBA 	__u64 *sn;
761e902ec99SJiro SEKIBA 	int ret = 0;
762e902ec99SJiro SEKIBA 
763e902ec99SJiro SEKIBA 	sects_per_block = (1 << nilfs->ns_blocksize_bits) /
764e902ec99SJiro SEKIBA 		bdev_logical_block_size(nilfs->ns_bdev);
765e902ec99SJiro SEKIBA 	for (sn = segnump; sn < segnump + nsegs; sn++) {
766e902ec99SJiro SEKIBA 		nilfs_get_segment_range(nilfs, *sn, &seg_start, &seg_end);
767e902ec99SJiro SEKIBA 
768e902ec99SJiro SEKIBA 		if (!nblocks) {
769e902ec99SJiro SEKIBA 			start = seg_start;
770e902ec99SJiro SEKIBA 			nblocks = seg_end - seg_start + 1;
771e902ec99SJiro SEKIBA 		} else if (start + nblocks == seg_start) {
772e902ec99SJiro SEKIBA 			nblocks += seg_end - seg_start + 1;
773e902ec99SJiro SEKIBA 		} else {
774e902ec99SJiro SEKIBA 			ret = blkdev_issue_discard(nilfs->ns_bdev,
775e902ec99SJiro SEKIBA 						   start * sects_per_block,
776e902ec99SJiro SEKIBA 						   nblocks * sects_per_block,
777dd3932edSChristoph Hellwig 						   GFP_NOFS, 0);
778e902ec99SJiro SEKIBA 			if (ret < 0)
779e902ec99SJiro SEKIBA 				return ret;
780e902ec99SJiro SEKIBA 			nblocks = 0;
781e902ec99SJiro SEKIBA 		}
782e902ec99SJiro SEKIBA 	}
783e902ec99SJiro SEKIBA 	if (nblocks)
784e902ec99SJiro SEKIBA 		ret = blkdev_issue_discard(nilfs->ns_bdev,
785e902ec99SJiro SEKIBA 					   start * sects_per_block,
786e902ec99SJiro SEKIBA 					   nblocks * sects_per_block,
787dd3932edSChristoph Hellwig 					   GFP_NOFS, 0);
788e902ec99SJiro SEKIBA 	return ret;
789e902ec99SJiro SEKIBA }
790e902ec99SJiro SEKIBA 
7918a9d2191SRyusuke Konishi int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
7928a9d2191SRyusuke Konishi {
7938a9d2191SRyusuke Konishi 	struct inode *dat = nilfs_dat_inode(nilfs);
7948a9d2191SRyusuke Konishi 	unsigned long ncleansegs;
7958a9d2191SRyusuke Konishi 
7968a9d2191SRyusuke Konishi 	down_read(&NILFS_MDT(dat)->mi_sem);	/* XXX */
797ef7d4757SRyusuke Konishi 	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
7988a9d2191SRyusuke Konishi 	up_read(&NILFS_MDT(dat)->mi_sem);	/* XXX */
7998a9d2191SRyusuke Konishi 	*nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
800ef7d4757SRyusuke Konishi 	return 0;
8018a9d2191SRyusuke Konishi }
8028a9d2191SRyusuke Konishi 
8038a9d2191SRyusuke Konishi int nilfs_near_disk_full(struct the_nilfs *nilfs)
8048a9d2191SRyusuke Konishi {
8058a9d2191SRyusuke Konishi 	unsigned long ncleansegs, nincsegs;
8068a9d2191SRyusuke Konishi 
807ef7d4757SRyusuke Konishi 	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
8088a9d2191SRyusuke Konishi 	nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
8098a9d2191SRyusuke Konishi 		nilfs->ns_blocks_per_segment + 1;
810ef7d4757SRyusuke Konishi 
811ef7d4757SRyusuke Konishi 	return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs;
8128a9d2191SRyusuke Konishi }
8138a9d2191SRyusuke Konishi 
8146dd47406SRyusuke Konishi /**
8156dd47406SRyusuke Konishi  * nilfs_find_sbinfo - find existing nilfs_sb_info structure
8166dd47406SRyusuke Konishi  * @nilfs: nilfs object
8176dd47406SRyusuke Konishi  * @rw_mount: mount type (non-zero value for read/write mount)
8186dd47406SRyusuke Konishi  * @cno: checkpoint number (zero for read-only mount)
8196dd47406SRyusuke Konishi  *
8206dd47406SRyusuke Konishi  * nilfs_find_sbinfo() returns the nilfs_sb_info structure which
8216dd47406SRyusuke Konishi  * @rw_mount and @cno (in case of snapshots) matched.  If no instance
8226dd47406SRyusuke Konishi  * was found, NULL is returned.  Although the super block instance can
8236dd47406SRyusuke Konishi  * be unmounted after this function returns, the nilfs_sb_info struct
8246dd47406SRyusuke Konishi  * is kept on memory until nilfs_put_sbinfo() is called.
8256dd47406SRyusuke Konishi  */
8266dd47406SRyusuke Konishi struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *nilfs,
8276dd47406SRyusuke Konishi 					int rw_mount, __u64 cno)
8286dd47406SRyusuke Konishi {
8296dd47406SRyusuke Konishi 	struct nilfs_sb_info *sbi;
8306dd47406SRyusuke Konishi 
831e59399d0SRyusuke Konishi 	down_read(&nilfs->ns_super_sem);
8326dd47406SRyusuke Konishi 	/*
8336dd47406SRyusuke Konishi 	 * The SNAPSHOT flag and sb->s_flags are supposed to be
834e59399d0SRyusuke Konishi 	 * protected with nilfs->ns_super_sem.
8356dd47406SRyusuke Konishi 	 */
8366dd47406SRyusuke Konishi 	sbi = nilfs->ns_current;
8376dd47406SRyusuke Konishi 	if (rw_mount) {
8386dd47406SRyusuke Konishi 		if (sbi && !(sbi->s_super->s_flags & MS_RDONLY))
8396dd47406SRyusuke Konishi 			goto found; /* read/write mount */
8406dd47406SRyusuke Konishi 		else
8416dd47406SRyusuke Konishi 			goto out;
8426dd47406SRyusuke Konishi 	} else if (cno == 0) {
8436dd47406SRyusuke Konishi 		if (sbi && (sbi->s_super->s_flags & MS_RDONLY))
8446dd47406SRyusuke Konishi 			goto found; /* read-only mount */
8456dd47406SRyusuke Konishi 		else
8466dd47406SRyusuke Konishi 			goto out;
8476dd47406SRyusuke Konishi 	}
8486dd47406SRyusuke Konishi 
8496dd47406SRyusuke Konishi 	list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
8506dd47406SRyusuke Konishi 		if (nilfs_test_opt(sbi, SNAPSHOT) &&
8516dd47406SRyusuke Konishi 		    sbi->s_snapshot_cno == cno)
8526dd47406SRyusuke Konishi 			goto found; /* snapshot mount */
8536dd47406SRyusuke Konishi 	}
8546dd47406SRyusuke Konishi  out:
855e59399d0SRyusuke Konishi 	up_read(&nilfs->ns_super_sem);
8566dd47406SRyusuke Konishi 	return NULL;
8576dd47406SRyusuke Konishi 
8586dd47406SRyusuke Konishi  found:
8596dd47406SRyusuke Konishi 	atomic_inc(&sbi->s_count);
860e59399d0SRyusuke Konishi 	up_read(&nilfs->ns_super_sem);
8616dd47406SRyusuke Konishi 	return sbi;
8626dd47406SRyusuke Konishi }
8636dd47406SRyusuke Konishi 
8648a9d2191SRyusuke Konishi int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno,
8658a9d2191SRyusuke Konishi 				int snapshot_mount)
8668a9d2191SRyusuke Konishi {
8678a9d2191SRyusuke Konishi 	struct nilfs_sb_info *sbi;
8688a9d2191SRyusuke Konishi 	int ret = 0;
8698a9d2191SRyusuke Konishi 
870e59399d0SRyusuke Konishi 	down_read(&nilfs->ns_super_sem);
8718a9d2191SRyusuke Konishi 	if (cno == 0 || cno > nilfs->ns_cno)
8728a9d2191SRyusuke Konishi 		goto out_unlock;
8738a9d2191SRyusuke Konishi 
8748a9d2191SRyusuke Konishi 	list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
8758a9d2191SRyusuke Konishi 		if (sbi->s_snapshot_cno == cno &&
8768a9d2191SRyusuke Konishi 		    (!snapshot_mount || nilfs_test_opt(sbi, SNAPSHOT))) {
8778a9d2191SRyusuke Konishi 					/* exclude read-only mounts */
8788a9d2191SRyusuke Konishi 			ret++;
8798a9d2191SRyusuke Konishi 			break;
8808a9d2191SRyusuke Konishi 		}
8818a9d2191SRyusuke Konishi 	}
8828a9d2191SRyusuke Konishi 	/* for protecting recent checkpoints */
8838a9d2191SRyusuke Konishi 	if (cno >= nilfs_last_cno(nilfs))
8848a9d2191SRyusuke Konishi 		ret++;
8858a9d2191SRyusuke Konishi 
8868a9d2191SRyusuke Konishi  out_unlock:
887e59399d0SRyusuke Konishi 	up_read(&nilfs->ns_super_sem);
8888a9d2191SRyusuke Konishi 	return ret;
8898a9d2191SRyusuke Konishi }
890