aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-01-10 23:10:49 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-01-11 01:09:17 -0500
commit7d82db83165dbac8c3f6d47b73c84f38e3996e30 (patch)
treeca56c0038cff6030eed8704105af84421692cf3b /fs
parent408e9375610cca6d54e9c654cbe05a647687e12e (diff)
f2fs: add f2fs_balance_fs in several interfaces
The f2fs_balance_fs() is to check the number of free sections and decide whether it needs to conduct cleaning or not. If there are not enough free sections, the cleaning job should be started. In order to control an amount of free sections even under high utilization, f2fs should call f2fs_balance_fs at all the VFS interfaces that are able to produce dirty pages. This patch adds the function calls in the missing interfaces as follows. 1. f2fs_setxattr() The f2fs_setxattr() produces dirty node pages so that we should call f2fs_balance_fs() either likewise doing in other VFS interfaces such as f2fs_lookup(), f2fs_mkdir(), and so on. 2. f2fs_sync_file() We should guarantee serving free sections for syncing metadata during fsync. Previously, there is no space check before triggering checkpoint and sync_node_pages. Therefore, if a bunch of fsync calls are triggered under 100% of FS utilization, f2fs is able to be faced with no free sections, resulting in BUG_ON(). 3. f2fs_sync_fs() Before calling write_checkpoint(), we should guarantee that there are minimum free sections. 4. f2fs_write_inode() f2fs_write_inode() is also able to produce dirty node pages. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/file.c3
-rw-r--r--fs/f2fs/inode.c3
-rw-r--r--fs/f2fs/super.c2
-rw-r--r--fs/f2fs/xattr.c2
4 files changed, 10 insertions, 0 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 88593c5e743c..7354c2df1087 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -137,6 +137,9 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
137 if (ret) 137 if (ret)
138 return ret; 138 return ret;
139 139
140 /* guarantee free sections for fsync */
141 f2fs_balance_fs(sbi);
142
140 mutex_lock(&inode->i_mutex); 143 mutex_lock(&inode->i_mutex);
141 144
142 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 145 if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index bf20b4d03214..794241777322 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -217,6 +217,9 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
217 inode->i_ino == F2FS_META_INO(sbi)) 217 inode->i_ino == F2FS_META_INO(sbi))
218 return 0; 218 return 0;
219 219
220 if (wbc)
221 f2fs_balance_fs(sbi);
222
220 node_page = get_node_page(sbi, inode->i_ino); 223 node_page = get_node_page(sbi, inode->i_ino);
221 if (IS_ERR(node_page)) 224 if (IS_ERR(node_page))
222 return PTR_ERR(node_page); 225 return PTR_ERR(node_page);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index afa7ef0c4ba7..0f2b2eb86a05 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -137,6 +137,8 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
137 137
138 if (sync) 138 if (sync)
139 write_checkpoint(sbi, false, false); 139 write_checkpoint(sbi, false, false);
140 else
141 f2fs_balance_fs(sbi);
140 142
141 return 0; 143 return 0;
142} 144}
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 940136a3d3a6..8038c0496504 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -318,6 +318,8 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
318 if (name_len > 255 || value_len > MAX_VALUE_LEN) 318 if (name_len > 255 || value_len > MAX_VALUE_LEN)
319 return -ERANGE; 319 return -ERANGE;
320 320
321 f2fs_balance_fs(sbi);
322
321 mutex_lock_op(sbi, NODE_NEW); 323 mutex_lock_op(sbi, NODE_NEW);
322 if (!fi->i_xattr_nid) { 324 if (!fi->i_xattr_nid) {
323 /* Allocate new attribute block */ 325 /* Allocate new attribute block */