diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2017-02-27 15:10:38 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2017-06-29 20:17:02 +0200 |
commit | 364ecf3651e0862152c8b340d7cb3021dc0122c7 (patch) | |
tree | 9e1e9d93a88677df69305345f02efae073c042b3 /fs/btrfs/extent_io.h | |
parent | a12b877b557dde885bdb6978cec86bf761e63c9a (diff) | |
download | linux-stable-364ecf3651e0862152c8b340d7cb3021dc0122c7.tar.gz linux-stable-364ecf3651e0862152c8b340d7cb3021dc0122c7.tar.bz2 linux-stable-364ecf3651e0862152c8b340d7cb3021dc0122c7.zip |
btrfs: qgroup: Introduce extent changeset for qgroup reserve functions
Introduce a new parameter, struct extent_changeset for
btrfs_qgroup_reserved_data() and its callers.
Such extent_changeset was used in btrfs_qgroup_reserve_data() to record
which range it reserved in current reserve, so it can free it in error
paths.
The reason we need to export it to callers is, at buffered write error
path, without knowing what exactly which range we reserved in current
allocation, we can free space which is not reserved by us.
This will lead to qgroup reserved space underflow.
Reviewed-by: Chandan Rajendra <chandan@linux.vnet.ibm.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/extent_io.h')
-rw-r--r-- | fs/btrfs/extent_io.h | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index ce670d213913..aeafdb35d90b 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -215,6 +215,40 @@ struct extent_changeset { struct ulist range_changed; }; +static inline void extent_changeset_init(struct extent_changeset *changeset) +{ + changeset->bytes_changed = 0; + ulist_init(&changeset->range_changed); +} + +static inline struct extent_changeset *extent_changeset_alloc(void) +{ + struct extent_changeset *ret; + + ret = kmalloc(sizeof(*ret), GFP_KERNEL); + if (!ret) + return NULL; + + extent_changeset_init(ret); + return ret; +} + +static inline void extent_changeset_release(struct extent_changeset *changeset) +{ + if (!changeset) + return; + changeset->bytes_changed = 0; + ulist_release(&changeset->range_changed); +} + +static inline void extent_changeset_free(struct extent_changeset *changeset) +{ + if (!changeset) + return; + extent_changeset_release(changeset); + kfree(changeset); +} + static inline void extent_set_compress_type(unsigned long *bio_flags, int compress_type) { |