From 4559071063270999d016c92a0b9241692cbbb522 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Mon, 15 Jul 2013 17:57:38 +0800 Subject: f2fs: introduce help function F2FS_NODE() Introduce help function F2FS_NODE() to simplify the conversion of node_page to f2fs_node. Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 035f9a345cdf..c73c394c3d8c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -39,7 +39,7 @@ static void __set_data_blkaddr(struct dnode_of_data *dn, block_t new_addr) wait_on_page_writeback(node_page); - rn = (struct f2fs_node *)page_address(node_page); + rn = F2FS_NODE(node_page); /* Get physical address of data block */ addr_array = blkaddr_in_node(rn); -- cgit v1.2.3 From d8207f69589c74037128ff6c9e1a44223fad3b7c Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Thu, 25 Jul 2013 11:30:01 +0800 Subject: f2fs: move bio_private allocation out of f2fs_bio_alloc() bio->bi_private is not always needed. As in the reading data path, end_read_io does not need bio_private for further using, so moving bio_private allocation out of f2fs_bio_alloc(). Alloc it in the submit_write_page(), and ignore it in the f2fs_readpage(). Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index c73c394c3d8c..19cd7c6e964c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -365,7 +365,6 @@ static void read_end_io(struct bio *bio, int err) } unlock_page(page); } while (bvec >= bio->bi_io_vec); - kfree(bio->bi_private); bio_put(bio); } -- cgit v1.2.3 From f0c5e565bb05a4cd6105bb197c56078462252e78 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 31 Jul 2013 11:44:13 +0300 Subject: f2fs: remove an unneeded kfree(NULL) This kfree() is no longer needed after a79dc083d7 "f2fs: move bio_private allocation out of f2fs_bio_alloc()". The "bio->bi_private" is NULL here so it's a no-op. Signed-off-by: Dan Carpenter Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 19cd7c6e964c..027341cacd2b 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -390,7 +390,6 @@ int f2fs_readpage(struct f2fs_sb_info *sbi, struct page *page, bio->bi_end_io = read_end_io; if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) { - kfree(bio->bi_private); bio_put(bio); up_read(&sbi->bio_sem); f2fs_put_page(page, 1); -- cgit v1.2.3 From df273efc36024a9ea97fd687d638a70c3ea8c37a Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Sun, 4 Aug 2013 23:10:28 +0900 Subject: f2fs: remove redundant code from f2fs_write_begin This code is being used for nobh_write_end() function. But since now f2fs_write_end function is added so there is no need for this code. Signed-off-by: Namjae Jeon Signed-off-by: Pankaj Kumar Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 027341cacd2b..f458883af815 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -634,9 +634,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, int err = 0; int ilock; - /* for nobh_write_end */ - *fsdata = NULL; - f2fs_balance_fs(sbi); repeat: page = grab_cache_page_write_begin(mapping, index, flags); -- cgit v1.2.3 From a569469e967022d9ceeaa4b73619f96614087d2d Mon Sep 17 00:00:00 2001 From: Jin Xu Date: Mon, 5 Aug 2013 20:02:04 +0800 Subject: f2fs: fix a deadlock in fsync This patch fixes a deadlock bug that occurs quite often when there are concurrent write and fsync on a same file. Following is the simplified call trace when tasks get hung. fsync thread: - f2fs_sync_file ... - f2fs_write_data_pages ... - update_extent_cache ... - update_inode - wait_on_page_writeback bdi writeback thread - __writeback_single_inode - f2fs_write_data_pages - mutex_lock(sbi->writepages) The deadlock happens when the fsync thread waits on a inode page that has been added to the f2fs' cached bio sbi->bio[NODE], and unfortunately, no one else could be able to submit the cached bio to block layer for writeback. This is because the fsync thread already hold a sbi->fs_lock and the sbi->writepages lock, causing the bdi thread being blocked when attempt to write data pages for the same inode. At the same time, f2fs_gc thread does not notice the situation and could not help. Even the sync syscall gets blocked. To fix it, we could submit the cached bio first before waiting on a inode page that is being written back. Signed-off-by: Jin Xu [Jaegeuk Kim: add more cases to use f2fs_wait_on_page_writeback] Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index f458883af815..a7eb52925723 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -37,7 +37,7 @@ static void __set_data_blkaddr(struct dnode_of_data *dn, block_t new_addr) struct page *node_page = dn->node_page; unsigned int ofs_in_node = dn->ofs_in_node; - wait_on_page_writeback(node_page); + f2fs_wait_on_page_writeback(node_page, NODE, false); rn = F2FS_NODE(node_page); -- cgit v1.2.3 From 41dfde135f9169948dd0c9bba948774f2e521210 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Fri, 9 Aug 2013 18:21:24 +0800 Subject: f2fs: clean up the needless end 'return' of void function Signed-off-by: Gu Zheng Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a7eb52925723..ea3cb29018e9 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -176,7 +176,6 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn) end_update: write_unlock(&fi->ext.ext_lock); sync_inode_page(dn); - return; } struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) -- cgit v1.2.3 From d59ff4df7b7ae39e6fb047db9e83cd899b5764f1 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 20 Aug 2013 19:13:07 +0900 Subject: f2fs: fix wrong BUG_ON condition This patch removes a false-alaramed BUG_ON. The previous BUG_ON condition didn't cover the following true scenario. In f2fs_add_link, 1) get_new_data_page gives an uptodate page successfully, and then, 2) init_inode_metadata returns -ENOSPC. At this moment, a new clean data page is remained in the page cache, but its block address still indicates NEW_ADDR. After then, even if sync is called, this clean data page cannot be written to the disk due to the clean state. So this means that get_lock_data_page should make a new empty page when its block address is NEW_ADDR and its page is not uptodated. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index ea3cb29018e9..6b328de41728 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -259,8 +259,17 @@ repeat: if (PageUptodate(page)) return page; - BUG_ON(dn.data_blkaddr == NEW_ADDR); - BUG_ON(dn.data_blkaddr == NULL_ADDR); + /* + * A new dentry page is allocated but not able to be written, since its + * new inode page couldn't be allocated due to -ENOSPC. + * In such the case, its blkaddr can be remained as NEW_ADDR. + * see, f2fs_add_link -> get_new_data_page -> init_inode_metadata. + */ + if (dn.data_blkaddr == NEW_ADDR) { + zero_user_segment(page, 0, PAGE_CACHE_SIZE); + SetPageUptodate(page); + return page; + } err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC); if (err) -- cgit v1.2.3 From de93653fe31fc9439971296842dcd0280f8ab5f4 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 12 Aug 2013 21:08:03 +0900 Subject: f2fs: reserve the xattr space dynamically This patch enables the number of direct pointers inside on-disk inode block to be changed dynamically according to the size of inline xattr space. The number of direct pointers, ADDRS_PER_INODE, can be changed only if the file has inline xattr flag. The number of direct pointers that will be used by inline xattrs is defined as F2FS_INLINE_XATTR_ADDRS. Current patch assigns F2FS_INLINE_XATTR_ADDRS to 0 temporarily. Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'fs/f2fs/data.c') diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 6b328de41728..941f9b9ca3a5 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -117,7 +117,8 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn) block_t start_blkaddr, end_blkaddr; BUG_ON(blk_addr == NEW_ADDR); - fofs = start_bidx_of_node(ofs_of_node(dn->node_page)) + dn->ofs_in_node; + fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) + + dn->ofs_in_node; /* Update the page address in the parent node */ __set_data_blkaddr(dn, blk_addr); @@ -448,7 +449,7 @@ static int get_data_block_ro(struct inode *inode, sector_t iblock, unsigned int end_offset; end_offset = IS_INODE(dn.node_page) ? - ADDRS_PER_INODE : + ADDRS_PER_INODE(F2FS_I(inode)) : ADDRS_PER_BLOCK; clear_buffer_new(bh_result); -- cgit v1.2.3