Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05c2cf35 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull f2fs fixes from Jaegeuk Kim:
 o Support swap file and link generic_file_remap_pages
 o Enhance the bio streaming flow and free section control
 o Major bug fix on recovery routine
 o Minor bug/warning fixes and code cleanups

* tag 'f2fs-for-3.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (22 commits)
  f2fs: use _safe() version of list_for_each
  f2fs: add comments of start_bidx_of_node
  f2fs: avoid issuing small bios due to several dirty node pages
  f2fs: support swapfile
  f2fs: add remap_pages as generic_file_remap_pages
  f2fs: add __init to functions in init_f2fs_fs
  f2fs: fix the debugfs entry creation path
  f2fs: add global mutex_lock to protect f2fs_stat_list
  f2fs: remove the blk_plug usage in f2fs_write_data_pages
  f2fs: avoid redundant time update for parent directory in f2fs_delete_entry
  f2fs: remove redundant call to set_blocksize in f2fs_fill_super
  f2fs: move f2fs_balance_fs to punch_hole
  f2fs: add f2fs_balance_fs in several interfaces
  f2fs: revisit the f2fs_gc flow
  f2fs: check return value during recovery
  f2fs: avoid null dereference in f2fs_acl_from_disk
  f2fs: initialize newly allocated dnode structure
  f2fs: update f2fs partition info about SIT/NAT layout
  f2fs: update f2fs document to reflect SIT/NAT layout correctly
  f2fs: remove unneeded INIT_LIST_HEAD at few places
  ...
parents 3c2a9f84 d8b79b2f
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -175,9 +175,9 @@ consists of multiple segments as described below.
                                            align with the zone size <-|
                 |-> align with the segment size
     _________________________________________________________________________
    |            |            |    Node     |   Segment   |   Segment  |      |
    | Superblock | Checkpoint |   Address   |    Info.    |   Summary  | Main |
    |    (SB)    |   (CP)     | Table (NAT) | Table (SIT) | Area (SSA) |      |
    |            |            |   Segment   |    Node     |   Segment  |      |
    | Superblock | Checkpoint |    Info.    |   Address   |   Summary  | Main |
    |    (SB)    |   (CP)     | Table (SIT) | Table (NAT) | Area (SSA) |      |
    |____________|_____2______|______N______|______N______|______N_____|__N___|
                                                                       .      .
                                                             .                .
@@ -200,14 +200,14 @@ consists of multiple segments as described below.
 : It contains file system information, bitmaps for valid NAT/SIT sets, orphan
   inode lists, and summary entries of current active segments.

- Node Address Table (NAT)
 : It is composed of a block address table for all the node blocks stored in
   Main area.

- Segment Information Table (SIT)
 : It contains segment information such as valid block count and bitmap for the
   validity of all the blocks.

- Node Address Table (NAT)
 : It is composed of a block address table for all the node blocks stored in
   Main area.

- Segment Summary Area (SSA)
 : It contains summary entries which contains the owner information of all the
   data and node blocks stored in Main area.
@@ -236,13 +236,13 @@ For file system consistency, each CP points to which NAT and SIT copies are
valid, as shown as below.

  +--------+----------+---------+
  |   CP   |    NAT   |   SIT   |
  |   CP   |    SIT   |   NAT   |
  +--------+----------+---------+
  .         .          .          .
  .            .              .              .
  .               .                 .                 .
  +-------+-------+--------+--------+--------+--------+
  | CP #0 | CP #1 | NAT #0 | NAT #1 | SIT #0 | SIT #1 |
  | CP #0 | CP #1 | SIT #0 | SIT #1 | NAT #0 | NAT #1 |
  +-------+-------+--------+--------+--------+--------+
     |             ^                          ^
     |             |                          |
+6 −7
Original line number Diff line number Diff line
@@ -191,15 +191,14 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type)
		retval = f2fs_getxattr(inode, name_index, "", value, retval);
	}

	if (retval < 0) {
		if (retval == -ENODATA)
	if (retval > 0)
		acl = f2fs_acl_from_disk(value, retval);
	else if (retval == -ENODATA)
		acl = NULL;
	else
		acl = ERR_PTR(retval);
	} else {
		acl = f2fs_acl_from_disk(value, retval);
	}
	kfree(value);

	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);

+1 −2
Original line number Diff line number Diff line
@@ -214,7 +214,6 @@ void add_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
		goto retry;
	}
	new->ino = ino;
	INIT_LIST_HEAD(&new->list);

	/* add new_oentry into list which is sorted by inode number */
	if (orphan) {
@@ -772,7 +771,7 @@ void init_orphan_info(struct f2fs_sb_info *sbi)
	sbi->n_orphans = 0;
}

int create_checkpoint_caches(void)
int __init create_checkpoint_caches(void)
{
	orphan_entry_slab = f2fs_kmem_cache_create("f2fs_orphan_entry",
			sizeof(struct orphan_inode_entry), NULL);
+16 −1
Original line number Diff line number Diff line
@@ -547,6 +547,15 @@ static int f2fs_write_data_page(struct page *page,

#define MAX_DESIRED_PAGES_WP	4096

static int __f2fs_writepage(struct page *page, struct writeback_control *wbc,
			void *data)
{
	struct address_space *mapping = data;
	int ret = mapping->a_ops->writepage(page, wbc);
	mapping_set_error(mapping, ret);
	return ret;
}

static int f2fs_write_data_pages(struct address_space *mapping,
			    struct writeback_control *wbc)
{
@@ -563,7 +572,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,

	if (!S_ISDIR(inode->i_mode))
		mutex_lock(&sbi->writepages);
	ret = generic_writepages(mapping, wbc);
	ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping);
	if (!S_ISDIR(inode->i_mode))
		mutex_unlock(&sbi->writepages);
	f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL));
@@ -689,6 +698,11 @@ static int f2fs_set_data_page_dirty(struct page *page)
	return 0;
}

static sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
{
	return generic_block_bmap(mapping, block, get_data_block_ro);
}

const struct address_space_operations f2fs_dblock_aops = {
	.readpage	= f2fs_read_data_page,
	.readpages	= f2fs_read_data_pages,
@@ -700,4 +714,5 @@ const struct address_space_operations f2fs_dblock_aops = {
	.invalidatepage	= f2fs_invalidate_data_page,
	.releasepage	= f2fs_release_data_page,
	.direct_IO	= f2fs_direct_IO,
	.bmap		= f2fs_bmap,
};
+21 −29
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

static LIST_HEAD(f2fs_stat_list);
static struct dentry *debugfs_root;
static DEFINE_MUTEX(f2fs_stat_mutex);

static void update_general_status(struct f2fs_sb_info *sbi)
{
@@ -180,18 +181,14 @@ static int stat_show(struct seq_file *s, void *v)
	int i = 0;
	int j;

	mutex_lock(&f2fs_stat_mutex);
	list_for_each_entry_safe(si, next, &f2fs_stat_list, stat_list) {

		mutex_lock(&si->stat_lock);
		if (!si->sbi) {
			mutex_unlock(&si->stat_lock);
			continue;
		}
		update_general_status(si->sbi);

		seq_printf(s, "\n=====[ partition info. #%d ]=====\n", i++);
		seq_printf(s, "[SB: 1] [CP: 2] [NAT: %d] [SIT: %d] ",
			   si->nat_area_segs, si->sit_area_segs);
		seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ",
			   si->sit_area_segs, si->nat_area_segs);
		seq_printf(s, "[SSA: %d] [MAIN: %d",
			   si->ssa_area_segs, si->main_area_segs);
		seq_printf(s, "(OverProv:%d Resv:%d)]\n\n",
@@ -286,8 +283,8 @@ static int stat_show(struct seq_file *s, void *v)
		seq_printf(s, "\nMemory: %u KB = static: %u + cached: %u\n",
				(si->base_mem + si->cache_mem) >> 10,
				si->base_mem >> 10, si->cache_mem >> 10);
		mutex_unlock(&si->stat_lock);
	}
	mutex_unlock(&f2fs_stat_mutex);
	return 0;
}

@@ -303,7 +300,7 @@ static const struct file_operations stat_fops = {
	.release = single_release,
};

static int init_stats(struct f2fs_sb_info *sbi)
int f2fs_build_stats(struct f2fs_sb_info *sbi)
{
	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
	struct f2fs_stat_info *si;
@@ -313,9 +310,6 @@ static int init_stats(struct f2fs_sb_info *sbi)
		return -ENOMEM;

	si = sbi->stat_info;
	mutex_init(&si->stat_lock);
	list_add_tail(&si->stat_list, &f2fs_stat_list);

	si->all_area_segs = le32_to_cpu(raw_super->segment_count);
	si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit);
	si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat);
@@ -325,21 +319,11 @@ static int init_stats(struct f2fs_sb_info *sbi)
	si->main_area_zones = si->main_area_sections /
				le32_to_cpu(raw_super->secs_per_zone);
	si->sbi = sbi;
	return 0;
}

int f2fs_build_stats(struct f2fs_sb_info *sbi)
{
	int retval;

	retval = init_stats(sbi);
	if (retval)
		return retval;

	if (!debugfs_root)
		debugfs_root = debugfs_create_dir("f2fs", NULL);
	mutex_lock(&f2fs_stat_mutex);
	list_add_tail(&si->stat_list, &f2fs_stat_list);
	mutex_unlock(&f2fs_stat_mutex);

	debugfs_create_file("status", S_IRUGO, debugfs_root, NULL, &stat_fops);
	return 0;
}

@@ -347,14 +331,22 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi)
{
	struct f2fs_stat_info *si = sbi->stat_info;

	mutex_lock(&f2fs_stat_mutex);
	list_del(&si->stat_list);
	mutex_lock(&si->stat_lock);
	si->sbi = NULL;
	mutex_unlock(&si->stat_lock);
	mutex_unlock(&f2fs_stat_mutex);

	kfree(sbi->stat_info);
}

void destroy_root_stats(void)
void __init f2fs_create_root_stats(void)
{
	debugfs_root = debugfs_create_dir("f2fs", NULL);
	if (debugfs_root)
		debugfs_create_file("status", S_IRUGO, debugfs_root,
					 NULL, &stat_fops);
}

void f2fs_destroy_root_stats(void)
{
	debugfs_remove_recursive(debugfs_root);
	debugfs_root = NULL;
Loading