@@ -63,8 +63,11 @@ struct btrfs_dio_private {
u64 disk_bytenr;
u64 bytes;
- /* number of bios pending for this dio */
- atomic_t pending_bios;
+ /*
+ * References to this structure. There is one reference per in-flight
+ * bio plus one while we're still setting up.
+ */
+ refcount_t refs;
/* IO errors */
int errors;
@@ -7849,7 +7852,7 @@ static void btrfs_end_dio_bio(struct bio *bio)
}
/* if there are more bios still pending for this dio, just exit */
- if (!atomic_dec_and_test(&dip->pending_bios))
+ if (!refcount_dec_and_test(&dip->refs))
goto out;
if (dip->errors) {
@@ -8001,13 +8004,13 @@ static void btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
* count. Otherwise, the dip might get freed before we're
* done setting it up.
*/
- atomic_inc(&dip->pending_bios);
+ refcount_inc(&dip->refs);
status = btrfs_submit_dio_bio(bio, inode, file_offset,
async_submit);
if (status) {
bio_put(bio);
- atomic_dec(&dip->pending_bios);
+ refcount_dec(&dip->refs);
goto out_err;
}
@@ -8036,7 +8039,7 @@ static void btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
* atomic operations with a return value are fully ordered as per
* atomic_t.txt
*/
- if (atomic_dec_and_test(&dip->pending_bios))
+ if (refcount_dec_and_test(&dip->refs))
bio_io_error(dip->orig_bio);
}
@@ -8074,7 +8077,7 @@ static void btrfs_submit_direct(struct bio *dio_bio, struct inode *inode,
bio->bi_private = dip;
dip->orig_bio = bio;
dip->dio_bio = dio_bio;
- atomic_set(&dip->pending_bios, 1);
+ refcount_set(&dip->refs, 1);
io_bio = btrfs_io_bio(bio);
io_bio->logical = file_offset;