Commit ed484030 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix a dio bug

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent d0cc3def
...@@ -57,7 +57,7 @@ struct bch_writepage_io { ...@@ -57,7 +57,7 @@ struct bch_writepage_io {
struct dio_write { struct dio_write {
struct closure cl; struct closure cl;
struct kiocb *req; struct kiocb *req;
struct task_struct *task; struct mm_struct *mm;
unsigned loop:1, unsigned loop:1,
sync:1, sync:1,
free_iov:1; free_iov:1;
...@@ -1775,6 +1775,7 @@ static void bch2_dio_write_loop_async(struct closure *); ...@@ -1775,6 +1775,7 @@ static void bch2_dio_write_loop_async(struct closure *);
static long bch2_dio_write_loop(struct dio_write *dio) static long bch2_dio_write_loop(struct dio_write *dio)
{ {
bool kthread = (current->flags & PF_KTHREAD) != 0;
struct kiocb *req = dio->req; struct kiocb *req = dio->req;
struct address_space *mapping = req->ki_filp->f_mapping; struct address_space *mapping = req->ki_filp->f_mapping;
struct bch_inode_info *inode = dio->iop.inode; struct bch_inode_info *inode = dio->iop.inode;
...@@ -1797,16 +1798,16 @@ static long bch2_dio_write_loop(struct dio_write *dio) ...@@ -1797,16 +1798,16 @@ static long bch2_dio_write_loop(struct dio_write *dio)
goto err; goto err;
while (1) { while (1) {
if (current != dio->task) if (kthread)
kthread_use_mm(dio->task->mm); kthread_use_mm(dio->mm);
BUG_ON(current->faults_disabled_mapping); BUG_ON(current->faults_disabled_mapping);
current->faults_disabled_mapping = mapping; current->faults_disabled_mapping = mapping;
ret = bio_iov_iter_get_pages(bio, &dio->iter); ret = bio_iov_iter_get_pages(bio, &dio->iter);
current->faults_disabled_mapping = NULL; current->faults_disabled_mapping = NULL;
if (current != dio->task) if (kthread)
kthread_unuse_mm(dio->task->mm); kthread_unuse_mm(dio->mm);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
goto err; goto err;
...@@ -1906,7 +1907,7 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter) ...@@ -1906,7 +1907,7 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
dio = container_of(bio, struct dio_write, iop.op.wbio.bio); dio = container_of(bio, struct dio_write, iop.op.wbio.bio);
closure_init(&dio->cl, NULL); closure_init(&dio->cl, NULL);
dio->req = req; dio->req = req;
dio->task = current; dio->mm = current->mm;
dio->loop = false; dio->loop = false;
dio->sync = is_sync_kiocb(req) || dio->sync = is_sync_kiocb(req) ||
offset + iter->count > inode->v.i_size; offset + iter->count > inode->v.i_size;
...@@ -1914,7 +1915,7 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter) ...@@ -1914,7 +1915,7 @@ ssize_t bch2_direct_write(struct kiocb *req, struct iov_iter *iter)
dio->quota_res.sectors = 0; dio->quota_res.sectors = 0;
dio->iter = *iter; dio->iter = *iter;
bch2_fswrite_op_init(&dio->iop, c, inode, io_opts(c, inode), true); bch2_fswrite_op_init(&dio->iop, c, inode, io_opts(c, inode), true);
dio->iop.op.write_point = writepoint_hashed((unsigned long) dio->task); dio->iop.op.write_point = writepoint_hashed((unsigned long) current);
dio->iop.op.flags |= BCH_WRITE_NOPUT_RESERVATION; dio->iop.op.flags |= BCH_WRITE_NOPUT_RESERVATION;
if ((req->ki_flags & IOCB_DSYNC) && if ((req->ki_flags & IOCB_DSYNC) &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment