Message ID | 1424920823-12176-2-git-send-email-zhaolei@cn.fujitsu.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On Thu, Feb 26, 2015 at 11:20:23AM +0800, Zhaolei wrote: > --- a/fs/btrfs/transaction.c > +++ b/fs/btrfs/transaction.c > @@ -2068,8 +2068,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, > > kmem_cache_free(btrfs_trans_handle_cachep, trans); > > - if (current != root->fs_info->transaction_kthread) > + if (current != root->fs_info->transaction_kthread) { > btrfs_run_delayed_iputs(root); Using a mutex for this kind of synchronization is not entirely correct though it works. > + /* make sure that all running delayed iput are done */ > + down_write(&root->fs_info->delayed_iput_sem); > + up_write(&root->fs_info->delayed_iput_sem); -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, David Sterba * From: David Sterba [mailto:dsterba@suse.cz] > Sent: Friday, February 27, 2015 6:29 AM > To: Zhaolei > Cc: linux-btrfs@vger.kernel.org > Subject: Re: [PATCH 1/1] btrfs: Fix NO_SPACE bug caused by delayed-iput > > On Thu, Feb 26, 2015 at 11:20:23AM +0800, Zhaolei wrote: > > --- a/fs/btrfs/transaction.c > > +++ b/fs/btrfs/transaction.c > > @@ -2068,8 +2068,12 @@ int btrfs_commit_transaction(struct > > btrfs_trans_handle *trans, > > > > kmem_cache_free(btrfs_trans_handle_cachep, trans); > > > > - if (current != root->fs_info->transaction_kthread) > > + if (current != root->fs_info->transaction_kthread) { > > btrfs_run_delayed_iputs(root); > > Using a mutex for this kind of synchronization is not entirely correct though it > works. > rw sem is best way I thought which was choosed from mutex, rw_sem, and wait_queue, although the function name is not self documented... Do you have some suggestion for this kind of synchronization? Thanks Zhaolei > > + /* make sure that all running delayed iput are done */ > > + down_write(&root->fs_info->delayed_iput_sem); > > + up_write(&root->fs_info->delayed_iput_sem); -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Feb 27, 2015 at 09:21:43AM +0800, Zhao Lei wrote: > Hi, David Sterba > > * From: David Sterba [mailto:dsterba@suse.cz] > > Sent: Friday, February 27, 2015 6:29 AM > > To: Zhaolei > > Cc: linux-btrfs@vger.kernel.org > > Subject: Re: [PATCH 1/1] btrfs: Fix NO_SPACE bug caused by delayed-iput > > > > On Thu, Feb 26, 2015 at 11:20:23AM +0800, Zhaolei wrote: > > > --- a/fs/btrfs/transaction.c > > > +++ b/fs/btrfs/transaction.c > > > @@ -2068,8 +2068,12 @@ int btrfs_commit_transaction(struct > > > btrfs_trans_handle *trans, > > > > > > kmem_cache_free(btrfs_trans_handle_cachep, trans); > > > > > > - if (current != root->fs_info->transaction_kthread) > > > + if (current != root->fs_info->transaction_kthread) { > > > btrfs_run_delayed_iputs(root); > > > > Using a mutex for this kind of synchronization is not entirely correct though it > > works. > > > rw sem is best way I thought which was choosed from > mutex, rw_sem, and wait_queue, although the function name is not > self documented... > Do you have some suggestion for this kind of synchronization? No better ideas at the moment, please proceed. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 84c3b00..ec2dac0 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1513,6 +1513,7 @@ struct btrfs_fs_info { spinlock_t delayed_iput_lock; struct list_head delayed_iputs; + struct rw_semaphore delayed_iput_sem; /* this protects tree_mod_seq_list */ spinlock_t tree_mod_seq_lock; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index f79f385..1c0d8ec 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2241,11 +2241,12 @@ int open_ctree(struct super_block *sb, spin_lock_init(&fs_info->qgroup_op_lock); spin_lock_init(&fs_info->buffer_lock); spin_lock_init(&fs_info->unused_bgs_lock); - mutex_init(&fs_info->unused_bg_unpin_mutex); rwlock_init(&fs_info->tree_mod_log_lock); + mutex_init(&fs_info->unused_bg_unpin_mutex); mutex_init(&fs_info->reloc_mutex); mutex_init(&fs_info->delalloc_root_mutex); seqlock_init(&fs_info->profiles_lock); + init_rwsem(&fs_info->delayed_iput_sem); init_completion(&fs_info->kobj_unregister); INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a85c23d..a396bb9 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3087,6 +3087,8 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root) if (empty) return; + down_read(&fs_info->delayed_iput_sem); + spin_lock(&fs_info->delayed_iput_lock); list_splice_init(&fs_info->delayed_iputs, &list); spin_unlock(&fs_info->delayed_iput_lock); @@ -3097,6 +3099,8 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root) iput(delayed->inode); kfree(delayed); } + + up_read(&fs_info->delayed_iput_sem); } /* diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 7e80f32..175cdef 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -2068,8 +2068,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, kmem_cache_free(btrfs_trans_handle_cachep, trans); - if (current != root->fs_info->transaction_kthread) + if (current != root->fs_info->transaction_kthread) { btrfs_run_delayed_iputs(root); + /* make sure that all running delayed iput are done */ + down_write(&root->fs_info->delayed_iput_sem); + up_write(&root->fs_info->delayed_iput_sem); + } return ret;