f2fs: introduce FI_ATOMIC_COMMIT
authorChao Yu <yuchao0@huawei.com>
Sat, 7 Jan 2017 10:50:26 +0000 (18:50 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 23 Feb 2017 02:48:48 +0000 (18:48 -0800)
This patch introduces a new flag to indicate inode status of doing atomic
write committing, so that, we can keep atomic write status for inode
during atomic committing, then we can skip GCing pages of atomic write inode,
that avoids random GCed datas being mixed with current transaction, so
isolation of transaction can be kept.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/gc.c
fs/f2fs/segment.c

index ab2008dea9219361aefbc3fe12b5447955bac0ff..848d110dc1ca1c178ba571c78a30a6808c5f2380 100644 (file)
@@ -1977,7 +1977,7 @@ static int f2fs_set_data_page_dirty(struct page *page)
        if (!PageUptodate(page))
                SetPageUptodate(page);
 
-       if (f2fs_is_atomic_file(inode)) {
+       if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) {
                if (!IS_ATOMIC_WRITTEN_PAGE(page)) {
                        register_inmem_page(inode, page);
                        return 1;
index a4e8e6278a17dd9f36387c12c88b8756383e6b91..94250a69762a194893eeac85da02b2c006d7bdf4 100644 (file)
@@ -1639,6 +1639,7 @@ enum {
        FI_UPDATE_WRITE,        /* inode has in-place-update data */
        FI_NEED_IPU,            /* used for ipu per file */
        FI_ATOMIC_FILE,         /* indicate atomic file */
+       FI_ATOMIC_COMMIT,       /* indicate the state of atomical committing */
        FI_VOLATILE_FILE,       /* indicate volatile file */
        FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */
        FI_DROP_CACHE,          /* drop dirty page cache */
@@ -1828,6 +1829,11 @@ static inline bool f2fs_is_atomic_file(struct inode *inode)
        return is_inode_flag_set(inode, FI_ATOMIC_FILE);
 }
 
+static inline bool f2fs_is_commit_atomic_write(struct inode *inode)
+{
+       return is_inode_flag_set(inode, FI_ATOMIC_COMMIT);
+}
+
 static inline bool f2fs_is_volatile_file(struct inode *inode)
 {
        return is_inode_flag_set(inode, FI_VOLATILE_FILE);
index 6c335180b9d857d997eeee47ac6503e4168f688a..e45522115b1c7bface932e5b0b6ab89b867abc3a 100644 (file)
@@ -1569,14 +1569,15 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
                goto err_out;
 
        if (f2fs_is_atomic_file(inode)) {
-               clear_inode_flag(inode, FI_ATOMIC_FILE);
                ret = commit_inmem_pages(inode);
-               if (ret) {
-                       set_inode_flag(inode, FI_ATOMIC_FILE);
+               if (ret)
                        goto err_out;
-               }
+
                ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
-               stat_dec_atomic_write(inode);
+               if (!ret) {
+                       clear_inode_flag(inode, FI_ATOMIC_FILE);
+                       stat_dec_atomic_write(inode);
+               }
        } else {
                ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
        }
index 88bfc3dff496f9f31166da30293d9bdfe64d25b3..88e5e7b10ab6e2c67d6964689064bcab3f2d01e8 100644 (file)
@@ -569,6 +569,9 @@ static void move_encrypted_block(struct inode *inode, block_t bidx,
        if (!check_valid_map(F2FS_I_SB(inode), segno, off))
                goto out;
 
+       if (f2fs_is_atomic_file(inode))
+               goto out;
+
        set_new_dnode(&dn, inode, NULL, NULL, 0);
        err = get_dnode_of_data(&dn, bidx, LOOKUP_NODE);
        if (err)
@@ -661,6 +664,9 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type,
        if (!check_valid_map(F2FS_I_SB(inode), segno, off))
                goto out;
 
+       if (f2fs_is_atomic_file(inode))
+               goto out;
+
        if (gc_type == BG_GC) {
                if (PageWriteback(page))
                        goto out;
index 8b54b1fafa707742ebfb0d149269c5db7b5af1c9..02a8d4ee65eb09d959ed50b7e587638d1e231523 100644 (file)
@@ -242,12 +242,12 @@ void drop_inmem_pages(struct inode *inode)
 {
        struct f2fs_inode_info *fi = F2FS_I(inode);
 
-       clear_inode_flag(inode, FI_ATOMIC_FILE);
-       stat_dec_atomic_write(inode);
-
        mutex_lock(&fi->inmem_lock);
        __revoke_inmem_pages(inode, &fi->inmem_pages, true, false);
        mutex_unlock(&fi->inmem_lock);
+
+       clear_inode_flag(inode, FI_ATOMIC_FILE);
+       stat_dec_atomic_write(inode);
 }
 
 static int __commit_inmem_pages(struct inode *inode,
@@ -316,6 +316,8 @@ int commit_inmem_pages(struct inode *inode)
        f2fs_balance_fs(sbi, true);
        f2fs_lock_op(sbi);
 
+       set_inode_flag(inode, FI_ATOMIC_COMMIT);
+
        mutex_lock(&fi->inmem_lock);
        err = __commit_inmem_pages(inode, &revoke_list);
        if (err) {
@@ -337,6 +339,8 @@ int commit_inmem_pages(struct inode *inode)
        }
        mutex_unlock(&fi->inmem_lock);
 
+       clear_inode_flag(inode, FI_ATOMIC_COMMIT);
+
        f2fs_unlock_op(sbi);
        return err;
 }