ext4: convert from atomic_t to refcount_t on ext4_io_end->count
refcount_t type and corresponding API can protect refcounters from accidental underflow and overflow and further use-after-free situations. Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn> Signed-off-by: Xin Tan <tanxin.ctf@gmail.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/1626674355-55795-1-git-send-email-xiyuyang19@fudan.edu.cn Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
1811bc401a
commit
31d21d219b
@ -17,6 +17,7 @@
|
|||||||
#ifndef _EXT4_H
|
#ifndef _EXT4_H
|
||||||
#define _EXT4_H
|
#define _EXT4_H
|
||||||
|
|
||||||
|
#include <linux/refcount.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/magic.h>
|
#include <linux/magic.h>
|
||||||
@ -241,7 +242,7 @@ typedef struct ext4_io_end {
|
|||||||
struct bio *bio; /* Linked list of completed
|
struct bio *bio; /* Linked list of completed
|
||||||
* bios covering the extent */
|
* bios covering the extent */
|
||||||
unsigned int flag; /* unwritten or not */
|
unsigned int flag; /* unwritten or not */
|
||||||
atomic_t count; /* reference counter */
|
refcount_t count; /* reference counter */
|
||||||
struct list_head list_vec; /* list of ext4_io_end_vec */
|
struct list_head list_vec; /* list of ext4_io_end_vec */
|
||||||
} ext4_io_end_t;
|
} ext4_io_end_t;
|
||||||
|
|
||||||
|
@ -279,14 +279,14 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
|
|||||||
io_end->inode = inode;
|
io_end->inode = inode;
|
||||||
INIT_LIST_HEAD(&io_end->list);
|
INIT_LIST_HEAD(&io_end->list);
|
||||||
INIT_LIST_HEAD(&io_end->list_vec);
|
INIT_LIST_HEAD(&io_end->list_vec);
|
||||||
atomic_set(&io_end->count, 1);
|
refcount_set(&io_end->count, 1);
|
||||||
}
|
}
|
||||||
return io_end;
|
return io_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ext4_put_io_end_defer(ext4_io_end_t *io_end)
|
void ext4_put_io_end_defer(ext4_io_end_t *io_end)
|
||||||
{
|
{
|
||||||
if (atomic_dec_and_test(&io_end->count)) {
|
if (refcount_dec_and_test(&io_end->count)) {
|
||||||
if (!(io_end->flag & EXT4_IO_END_UNWRITTEN) ||
|
if (!(io_end->flag & EXT4_IO_END_UNWRITTEN) ||
|
||||||
list_empty(&io_end->list_vec)) {
|
list_empty(&io_end->list_vec)) {
|
||||||
ext4_release_io_end(io_end);
|
ext4_release_io_end(io_end);
|
||||||
@ -300,7 +300,7 @@ int ext4_put_io_end(ext4_io_end_t *io_end)
|
|||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (atomic_dec_and_test(&io_end->count)) {
|
if (refcount_dec_and_test(&io_end->count)) {
|
||||||
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
|
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
|
||||||
err = ext4_convert_unwritten_io_end_vec(io_end->handle,
|
err = ext4_convert_unwritten_io_end_vec(io_end->handle,
|
||||||
io_end);
|
io_end);
|
||||||
@ -314,7 +314,7 @@ int ext4_put_io_end(ext4_io_end_t *io_end)
|
|||||||
|
|
||||||
ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
|
ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
|
||||||
{
|
{
|
||||||
atomic_inc(&io_end->count);
|
refcount_inc(&io_end->count);
|
||||||
return io_end;
|
return io_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user