summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/delayed-inode.h
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2016-05-20 13:50:33 -0700
committerChris Mason <clm@fb.com>2016-06-25 06:20:10 -0700
commit02dbfc99b424dde3cf0a492ed3bec4f222441754 (patch)
treed08f267bac15ea5939185424bbe73306b7f11cb6 /fs/btrfs/delayed-inode.h
parent33688abb2802ff3a230bd2441f765477b94cc89e (diff)
downloadlinux-stable-02dbfc99b424dde3cf0a492ed3bec4f222441754.tar.gz
linux-stable-02dbfc99b424dde3cf0a492ed3bec4f222441754.tar.bz2
linux-stable-02dbfc99b424dde3cf0a492ed3bec4f222441754.zip
Btrfs: fix ->iterate_shared() by upgrading i_rwsem for delayed nodes
Commit fe742fd4f90f ("Revert "btrfs: switch to ->iterate_shared()"") backed out the conversion to ->iterate_shared() for Btrfs because the delayed inode handling in btrfs_real_readdir() is racy. However, we can still do readdir in parallel if there are no delayed nodes. This is a temporary fix which upgrades the shared inode lock to an exclusive lock only when we have delayed items until we come up with a more complete solution. While we're here, rename the btrfs_{get,put}_delayed_items functions to make it very clear that they're just for readdir. Tested with xfstests and by doing a parallel kernel build: while make tinyconfig && make -j4 && git clean dqfx; do : done along with a bunch of parallel finds in another shell: while true; do for ((i=0; i<4; i++)); do find . >/dev/null & done wait done Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/delayed-inode.h')
-rw-r--r--fs/btrfs/delayed-inode.h10
1 files changed, 6 insertions, 4 deletions
diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h
index 0167853c84ae..2495b3d4075f 100644
--- a/fs/btrfs/delayed-inode.h
+++ b/fs/btrfs/delayed-inode.h
@@ -137,10 +137,12 @@ void btrfs_kill_all_delayed_nodes(struct btrfs_root *root);
void btrfs_destroy_delayed_inodes(struct btrfs_root *root);
/* Used for readdir() */
-void btrfs_get_delayed_items(struct inode *inode, struct list_head *ins_list,
- struct list_head *del_list);
-void btrfs_put_delayed_items(struct list_head *ins_list,
- struct list_head *del_list);
+bool btrfs_readdir_get_delayed_items(struct inode *inode,
+ struct list_head *ins_list,
+ struct list_head *del_list);
+void btrfs_readdir_put_delayed_items(struct inode *inode,
+ struct list_head *ins_list,
+ struct list_head *del_list);
int btrfs_should_delete_dir_index(struct list_head *del_list,
u64 index);
int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,