diff options
Diffstat (limited to 'fs/f2fs/super.c')
| -rw-r--r-- | fs/f2fs/super.c | 90 | 
1 files changed, 55 insertions, 35 deletions
| diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 65a7a432dfee..f2dfc21c6abb 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -24,6 +24,7 @@  #include <linux/sysfs.h>  #include <linux/quota.h>  #include <linux/unicode.h> +#include <linux/part_stat.h>  #include "f2fs.h"  #include "node.h" @@ -427,14 +428,11 @@ static int parse_options(struct super_block *sb, char *options)  			if (!name)  				return -ENOMEM;  			if (strlen(name) == 2 && !strncmp(name, "on", 2)) { -				set_opt(sbi, BG_GC); -				clear_opt(sbi, FORCE_FG_GC); +				F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON;  			} else if (strlen(name) == 3 && !strncmp(name, "off", 3)) { -				clear_opt(sbi, BG_GC); -				clear_opt(sbi, FORCE_FG_GC); +				F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_OFF;  			} else if (strlen(name) == 4 && !strncmp(name, "sync", 4)) { -				set_opt(sbi, BG_GC); -				set_opt(sbi, FORCE_FG_GC); +				F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_SYNC;  			} else {  				kvfree(name);  				return -EINVAL; @@ -446,7 +444,7 @@ static int parse_options(struct super_block *sb, char *options)  			break;  		case Opt_norecovery:  			/* this option mounts f2fs with ro */ -			set_opt(sbi, DISABLE_ROLL_FORWARD); +			set_opt(sbi, NORECOVERY);  			if (!f2fs_readonly(sb))  				return -EINVAL;  			break; @@ -600,10 +598,10 @@ static int parse_options(struct super_block *sb, char *options)  					kvfree(name);  					return -EINVAL;  				} -				set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE); +				F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE;  			} else if (strlen(name) == 3 &&  					!strncmp(name, "lfs", 3)) { -				set_opt_mode(sbi, F2FS_MOUNT_LFS); +				F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS;  			} else {  				kvfree(name);  				return -EINVAL; @@ -832,6 +830,10 @@ static int parse_options(struct super_block *sb, char *options)  					!strcmp(name, "lz4")) {  				F2FS_OPTION(sbi).compress_algorithm =  								COMPRESS_LZ4; +			} else if (strlen(name) == 4 && +					!strcmp(name, "zstd")) { +				F2FS_OPTION(sbi).compress_algorithm = +								COMPRESS_ZSTD;  			} else {  				kfree(name);  				return -EINVAL; @@ -904,7 +906,7 @@ static int parse_options(struct super_block *sb, char *options)  	}  #endif -	if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) { +	if (F2FS_IO_SIZE_BITS(sbi) && !f2fs_lfs_mode(sbi)) {  		f2fs_err(sbi, "Should set mode=lfs with %uKB-sized IO",  			 F2FS_IO_SIZE_KB(sbi));  		return -EINVAL; @@ -934,7 +936,7 @@ static int parse_options(struct super_block *sb, char *options)  		}  	} -	if (test_opt(sbi, DISABLE_CHECKPOINT) && test_opt(sbi, LFS)) { +	if (test_opt(sbi, DISABLE_CHECKPOINT) && f2fs_lfs_mode(sbi)) {  		f2fs_err(sbi, "LFS not compatible with checkpoint=disable\n");  		return -EINVAL;  	} @@ -960,6 +962,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)  	/* Initialize f2fs-specific inode info */  	atomic_set(&fi->dirty_pages, 0);  	init_rwsem(&fi->i_sem); +	spin_lock_init(&fi->i_size_lock);  	INIT_LIST_HEAD(&fi->dirty_list);  	INIT_LIST_HEAD(&fi->gdirty_list);  	INIT_LIST_HEAD(&fi->inmem_ilist); @@ -1172,7 +1175,7 @@ static void f2fs_put_super(struct super_block *sb)  	/* our cp_error case, we can wait for any writeback page */  	f2fs_flush_merged_writes(sbi); -	f2fs_wait_on_all_pages_writeback(sbi); +	f2fs_wait_on_all_pages(sbi, F2FS_WB_CP_DATA);  	f2fs_bug_on(sbi, sbi->fsync_node_num); @@ -1204,6 +1207,7 @@ static void f2fs_put_super(struct super_block *sb)  	kvfree(sbi->raw_super);  	destroy_device_list(sbi); +	f2fs_destroy_xattr_caches(sbi);  	mempool_destroy(sbi->write_io_dummy);  #ifdef CONFIG_QUOTA  	for (i = 0; i < MAXQUOTAS; i++) @@ -1420,6 +1424,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq,  	case COMPRESS_LZ4:  		algtype = "lz4";  		break; +	case COMPRESS_ZSTD: +		algtype = "zstd"; +		break;  	}  	seq_printf(seq, ",compress_algorithm=%s", algtype); @@ -1436,16 +1443,17 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)  {  	struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb); -	if (!f2fs_readonly(sbi->sb) && test_opt(sbi, BG_GC)) { -		if (test_opt(sbi, FORCE_FG_GC)) -			seq_printf(seq, ",background_gc=%s", "sync"); -		else -			seq_printf(seq, ",background_gc=%s", "on"); -	} else { +	if (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_SYNC) +		seq_printf(seq, ",background_gc=%s", "sync"); +	else if (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_ON) +		seq_printf(seq, ",background_gc=%s", "on"); +	else if (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF)  		seq_printf(seq, ",background_gc=%s", "off"); -	} +  	if (test_opt(sbi, DISABLE_ROLL_FORWARD))  		seq_puts(seq, ",disable_roll_forward"); +	if (test_opt(sbi, NORECOVERY)) +		seq_puts(seq, ",norecovery");  	if (test_opt(sbi, DISCARD))  		seq_puts(seq, ",discard");  	else @@ -1497,9 +1505,9 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)  		seq_puts(seq, ",data_flush");  	seq_puts(seq, ",mode="); -	if (test_opt(sbi, ADAPTIVE)) +	if (F2FS_OPTION(sbi).fs_mode == FS_MODE_ADAPTIVE)  		seq_puts(seq, "adaptive"); -	else if (test_opt(sbi, LFS)) +	else if (F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS)  		seq_puts(seq, "lfs");  	seq_printf(seq, ",active_logs=%u", F2FS_OPTION(sbi).active_logs);  	if (test_opt(sbi, RESERVE_ROOT)) @@ -1570,11 +1578,11 @@ static void default_options(struct f2fs_sb_info *sbi)  	F2FS_OPTION(sbi).test_dummy_encryption = false;  	F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);  	F2FS_OPTION(sbi).s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID); -	F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZO; +	F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZ4;  	F2FS_OPTION(sbi).compress_log_size = MIN_COMPRESS_LOG_SIZE;  	F2FS_OPTION(sbi).compress_ext_cnt = 0; +	F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON; -	set_opt(sbi, BG_GC);  	set_opt(sbi, INLINE_XATTR);  	set_opt(sbi, INLINE_DATA);  	set_opt(sbi, INLINE_DENTRY); @@ -1586,9 +1594,9 @@ static void default_options(struct f2fs_sb_info *sbi)  	set_opt(sbi, FLUSH_MERGE);  	set_opt(sbi, DISCARD);  	if (f2fs_sb_has_blkzoned(sbi)) -		set_opt_mode(sbi, F2FS_MOUNT_LFS); +		F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS;  	else -		set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE); +		F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE;  #ifdef CONFIG_F2FS_FS_XATTR  	set_opt(sbi, XATTR_USER); @@ -1657,7 +1665,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)  out_unlock:  	up_write(&sbi->gc_lock);  restore_flag: -	sbi->sb->s_flags = s_flags;	/* Restore MS_RDONLY status */ +	sbi->sb->s_flags = s_flags;	/* Restore SB_RDONLY status */  	return err;  } @@ -1780,7 +1788,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)  	 * or if background_gc = off is passed in mount  	 * option. Also sync the filesystem.  	 */ -	if ((*flags & SB_RDONLY) || !test_opt(sbi, BG_GC)) { +	if ((*flags & SB_RDONLY) || +			F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF) {  		if (sbi->gc_thread) {  			f2fs_stop_gc_thread(sbi);  			need_restart_gc = true; @@ -1885,7 +1894,8 @@ repeat:  		page = read_cache_page_gfp(mapping, blkidx, GFP_NOFS);  		if (IS_ERR(page)) {  			if (PTR_ERR(page) == -ENOMEM) { -				congestion_wait(BLK_RW_ASYNC, HZ/50); +				congestion_wait(BLK_RW_ASYNC, +						DEFAULT_IO_TIMEOUT);  				goto repeat;  			}  			set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); @@ -1927,6 +1937,7 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type,  	int offset = off & (sb->s_blocksize - 1);  	size_t towrite = len;  	struct page *page; +	void *fsdata = NULL;  	char *kaddr;  	int err = 0;  	int tocopy; @@ -1936,10 +1947,11 @@ static ssize_t f2fs_quota_write(struct super_block *sb, int type,  								towrite);  retry:  		err = a_ops->write_begin(NULL, mapping, off, tocopy, 0, -							&page, NULL); +							&page, &fsdata);  		if (unlikely(err)) {  			if (err == -ENOMEM) { -				congestion_wait(BLK_RW_ASYNC, HZ/50); +				congestion_wait(BLK_RW_ASYNC, +						DEFAULT_IO_TIMEOUT);  				goto retry;  			}  			set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); @@ -1952,7 +1964,7 @@ retry:  		flush_dcache_page(page);  		a_ops->write_end(NULL, mapping, off, tocopy, tocopy, -						page, NULL); +						page, fsdata);  		offset = 0;  		towrite -= tocopy;  		off += tocopy; @@ -3456,12 +3468,17 @@ try_onemore:  		}  	} +	/* init per sbi slab cache */ +	err = f2fs_init_xattr_caches(sbi); +	if (err) +		goto free_io_dummy; +  	/* get an inode for meta space */  	sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi));  	if (IS_ERR(sbi->meta_inode)) {  		f2fs_err(sbi, "Failed to read F2FS meta data inode");  		err = PTR_ERR(sbi->meta_inode); -		goto free_io_dummy; +		goto free_xattr_cache;  	}  	err = f2fs_get_valid_checkpoint(sbi); @@ -3589,7 +3606,7 @@ try_onemore:  			f2fs_err(sbi, "Cannot turn on quotas: error %d", err);  	}  #endif -	/* if there are nt orphan nodes free them */ +	/* if there are any orphan inodes, free them */  	err = f2fs_recover_orphan_inodes(sbi);  	if (err)  		goto free_meta; @@ -3598,7 +3615,8 @@ try_onemore:  		goto reset_checkpoint;  	/* recover fsynced data */ -	if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { +	if (!test_opt(sbi, DISABLE_ROLL_FORWARD) && +			!test_opt(sbi, NORECOVERY)) {  		/*  		 * mount should be failed, when device has readonly mode, and  		 * previous checkpoint was not done by clean system shutdown. @@ -3664,7 +3682,7 @@ reset_checkpoint:  	 * If filesystem is not mounted as read-only then  	 * do start the gc_thread.  	 */ -	if (test_opt(sbi, BG_GC) && !f2fs_readonly(sb)) { +	if (F2FS_OPTION(sbi).bggc_mode != BGGC_MODE_OFF && !f2fs_readonly(sb)) {  		/* After POR, we can run background GC thread.*/  		err = f2fs_start_gc_thread(sbi);  		if (err) @@ -3733,6 +3751,8 @@ free_meta_inode:  	make_bad_inode(sbi->meta_inode);  	iput(sbi->meta_inode);  	sbi->meta_inode = NULL; +free_xattr_cache: +	f2fs_destroy_xattr_caches(sbi);  free_io_dummy:  	mempool_destroy(sbi->write_io_dummy);  free_percpu: |