aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-12 10:20:45 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-31 01:45:52 -0400
commitb2b5ef5c8e89f19b68c174bf246f3ca212dbf0bc (patch)
tree05bc5ec6d01f45307eed33082f9f1c288c907999 /fs
parent2c22b337b5bbb497c41b348b2357b7070ed5ba88 (diff)
btrfs: Convert to new freezing mechanism
We convert btrfs_file_aio_write() to use new freeze check. We also add proper freeze protection to btrfs_page_mkwrite(). We also add freeze protection to the transaction mechanism to avoid starting transactions on frozen filesystem. At minimum this is necessary to stop iput() of unlinked file to change frozen filesystem during truncation. Checks in cleaner_kthread() and transaction_kthread() can be safely removed since btrfs_freeze() will lock the mutexes and thus block the threads (and they shouldn't have anything to do anyway). CC: linux-btrfs@vger.kernel.org CC: Chris Mason <chris.mason@oracle.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/disk-io.c3
-rw-r--r--fs/btrfs/file.c3
-rw-r--r--fs/btrfs/inode.c6
-rw-r--r--fs/btrfs/transaction.c7
4 files changed, 14 insertions, 5 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 2936ca49b3b4..20c49b16b759 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1533,8 +1533,6 @@ static int cleaner_kthread(void *arg)
1533 struct btrfs_root *root = arg; 1533 struct btrfs_root *root = arg;
1534 1534
1535 do { 1535 do {
1536 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
1537
1538 if (!(root->fs_info->sb->s_flags & MS_RDONLY) && 1536 if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
1539 mutex_trylock(&root->fs_info->cleaner_mutex)) { 1537 mutex_trylock(&root->fs_info->cleaner_mutex)) {
1540 btrfs_run_delayed_iputs(root); 1538 btrfs_run_delayed_iputs(root);
@@ -1566,7 +1564,6 @@ static int transaction_kthread(void *arg)
1566 do { 1564 do {
1567 cannot_commit = false; 1565 cannot_commit = false;
1568 delay = HZ * 30; 1566 delay = HZ * 30;
1569 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
1570 mutex_lock(&root->fs_info->transaction_kthread_mutex); 1567 mutex_lock(&root->fs_info->transaction_kthread_mutex);
1571 1568
1572 spin_lock(&root->fs_info->trans_lock); 1569 spin_lock(&root->fs_info->trans_lock);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 9aa01ec2138d..5caf285c6e4d 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1379,7 +1379,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1379 ssize_t err = 0; 1379 ssize_t err = 0;
1380 size_t count, ocount; 1380 size_t count, ocount;
1381 1381
1382 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); 1382 sb_start_write(inode->i_sb);
1383 1383
1384 mutex_lock(&inode->i_mutex); 1384 mutex_lock(&inode->i_mutex);
1385 1385
@@ -1469,6 +1469,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1469 num_written = err; 1469 num_written = err;
1470 } 1470 }
1471out: 1471out:
1472 sb_end_write(inode->i_sb);
1472 current->backing_dev_info = NULL; 1473 current->backing_dev_info = NULL;
1473 return num_written ? num_written : err; 1474 return num_written ? num_written : err;
1474} 1475}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index fb8d671d00e6..f4d901786b3c 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6620,6 +6620,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
6620 u64 page_start; 6620 u64 page_start;
6621 u64 page_end; 6621 u64 page_end;
6622 6622
6623 sb_start_pagefault(inode->i_sb);
6623 ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); 6624 ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
6624 if (!ret) { 6625 if (!ret) {
6625 ret = file_update_time(vma->vm_file); 6626 ret = file_update_time(vma->vm_file);
@@ -6709,12 +6710,15 @@ again:
6709 unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS); 6710 unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS);
6710 6711
6711out_unlock: 6712out_unlock:
6712 if (!ret) 6713 if (!ret) {
6714 sb_end_pagefault(inode->i_sb);
6713 return VM_FAULT_LOCKED; 6715 return VM_FAULT_LOCKED;
6716 }
6714 unlock_page(page); 6717 unlock_page(page);
6715out: 6718out:
6716 btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); 6719 btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE);
6717out_noreserve: 6720out_noreserve:
6721 sb_end_pagefault(inode->i_sb);
6718 return ret; 6722 return ret;
6719} 6723}
6720 6724
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index b72b068183ec..fa67ba51516e 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -329,6 +329,8 @@ again:
329 if (!h) 329 if (!h)
330 return ERR_PTR(-ENOMEM); 330 return ERR_PTR(-ENOMEM);
331 331
332 sb_start_intwrite(root->fs_info->sb);
333
332 if (may_wait_transaction(root, type)) 334 if (may_wait_transaction(root, type))
333 wait_current_trans(root); 335 wait_current_trans(root);
334 336
@@ -339,6 +341,7 @@ again:
339 } while (ret == -EBUSY); 341 } while (ret == -EBUSY);
340 342
341 if (ret < 0) { 343 if (ret < 0) {
344 sb_end_intwrite(root->fs_info->sb);
342 kmem_cache_free(btrfs_trans_handle_cachep, h); 345 kmem_cache_free(btrfs_trans_handle_cachep, h);
343 return ERR_PTR(ret); 346 return ERR_PTR(ret);
344 } 347 }
@@ -528,6 +531,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
528 count++; 531 count++;
529 } 532 }
530 533
534 sb_end_intwrite(root->fs_info->sb);
535
531 if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) && 536 if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
532 should_end_transaction(trans, root)) { 537 should_end_transaction(trans, root)) {
533 trans->transaction->blocked = 1; 538 trans->transaction->blocked = 1;
@@ -1517,6 +1522,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1517 put_transaction(cur_trans); 1522 put_transaction(cur_trans);
1518 put_transaction(cur_trans); 1523 put_transaction(cur_trans);
1519 1524
1525 sb_end_intwrite(root->fs_info->sb);
1526
1520 trace_btrfs_transaction_commit(root); 1527 trace_btrfs_transaction_commit(root);
1521 1528
1522 btrfs_scrub_continue(root); 1529 btrfs_scrub_continue(root);