|
@@ -1606,15 +1606,23 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-void btrfs_get_delayed_items(struct inode *inode, 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)
|
|
|
{
|
|
|
struct btrfs_delayed_node *delayed_node;
|
|
|
struct btrfs_delayed_item *item;
|
|
|
|
|
|
delayed_node = btrfs_get_delayed_node(inode);
|
|
|
if (!delayed_node)
|
|
|
- return;
|
|
|
+ return false;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We can only do one readdir with delayed items at a time because of
|
|
|
+ * item->readdir_list.
|
|
|
+ */
|
|
|
+ inode_unlock_shared(inode);
|
|
|
+ inode_lock(inode);
|
|
|
|
|
|
mutex_lock(&delayed_node->mutex);
|
|
|
item = __btrfs_first_delayed_insertion_item(delayed_node);
|
|
@@ -1641,10 +1649,13 @@ void btrfs_get_delayed_items(struct inode *inode, struct list_head *ins_list,
|
|
|
* requeue or dequeue this delayed node.
|
|
|
*/
|
|
|
atomic_dec(&delayed_node->refs);
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
-void btrfs_put_delayed_items(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)
|
|
|
{
|
|
|
struct btrfs_delayed_item *curr, *next;
|
|
|
|
|
@@ -1659,6 +1670,12 @@ void btrfs_put_delayed_items(struct list_head *ins_list,
|
|
|
if (atomic_dec_and_test(&curr->refs))
|
|
|
kfree(curr);
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The VFS is going to do up_read(), so we need to downgrade back to a
|
|
|
+ * read lock.
|
|
|
+ */
|
|
|
+ downgrade_write(&inode->i_rwsem);
|
|
|
}
|
|
|
|
|
|
int btrfs_should_delete_dir_index(struct list_head *del_list,
|