direct_io mopup
Subsystems (5)
PATCH 9/13 direct_io mopup
Some cleanup from the surprise direct-to-bio for O_DIRECT merge.
- Remove bits and pieces from the kiobuf implementation
- Replace the waitqueue in struct dio with just a task_struct pointer and use wake_up_process. (Ben).
- Only take mmap_sem around the individual calls to get_user_pages(). (It pins the vmas, yes?)
- Remove some debug code.
- Fix JFS.
fs/buffer.c | 49 ------------------------------- fs/direct-io.c | 31 +++++-------------- fs/fcntl.c | 17 ---------- fs/file_table.c | 3 - fs/jfs/inode.c | 7 +--- fs/open.c | 11 ------- include/linux/fs.h | 5 --- mm/filemap.c | 83 ----------------------------------------------------- 8 files changed, 12 insertions(+), 194 deletions(-)
fs/direct-io.c renamed from fs/direct-io.c~direct-io-wrapup +9 -22
@@ -1,5 +1,5 @@/* -* mm/direct-io.c +* fs/direct-io.c * * Copyright (C) 2002, Linus Torvalds. *
@@ -61,7 +61,7 @@ struct dio {atomic_t bio_count;spinlock_t bio_list_lock;struct bio *bio_list;/* singly linked via bi_private */ -wait_queue_head_t wait_q; +struct task_struct *waiter; };/*
@@ -81,6 +81,7 @@ static int dio_refill_pages(struct dio *int nr_pages; nr_pages =min (dio->total_pages - dio->curr_page,DIO_PAGES ); +down_read (¤t->mm->mmap_sem); ret = get_user_pages( current, /* Task for fault acounting */ current->mm, /* whose pages? */
@@ -90,6 +91,7 @@ static int dio_refill_pages(struct dio *0 ,/* force (?) */ &dio->pages[0 ], NULL); /* vmas */ +up_read (¤t->mm->mmap_sem);if (ret >=0 ) { dio->curr_user_address += ret *PAGE_SIZE ;
@@ -139,7 +141,7 @@ static void dio_bio_end_io(struct bio *b bio->bi_private = dio->bio_list; dio->bio_list = bio;spin_unlock_irqrestore (&dio->bio_list_lock, flags); -wake_up (&dio->wait_q); +wake_up_process (dio->waiter); } static int
@@ -193,13 +195,11 @@ static void dio_cleanup(struct dio *dio)*/ static struct bio *dio_await_one (struct dio *dio) { -DECLARE_WAITQUEUE (wait, current);unsigned long flags;struct bio *bio;spin_lock_irqsave (&dio->bio_list_lock, flags);while (dio->bio_list ==NULL ) { -add_wait_queue (&dio->wait_q, &wait);set_current_state (TASK_UNINTERRUPTIBLE );if (dio->bio_list ==NULL ) {spin_unlock_irqrestore (&dio->bio_list_lock, flags);
@@ -208,7 +208,6 @@ static struct bio *dio_await_one(structspin_lock_irqsave (&dio->bio_list_lock, flags); }set_current_state (TASK_RUNNING ); -remove_wait_queue (&dio->wait_q, &wait); } bio = dio->bio_list; dio->bio_list = bio->bi_private;
@@ -224,23 +223,17 @@ static int dio_bio_complete(struct dio *const int uptodate =test_bit (BIO_UPTODATE , &bio->bi_flags);struct bio_vec *bvec = bio->bi_io_vec;int page_no; -int ret =0 ;for (page_no =0 ; page_no < bio->bi_vcnt; page_no++) {struct page *page = bvec[page_no].bv_page; -if (!uptodate) { -if (ret ==0 ) - ret = -EIO ; - } -if (dio->rw ==READ )set_page_dirty (page);page_cache_release (page); }atomic_dec (&dio->bio_count);bio_put (bio); -return ret; +return uptodate ?0 : -EIO ; }/*
@@ -265,7 +258,7 @@ static int dio_await_completion(struct d* to keep the memory consumption sane we periodically reap any completed BIOs * during the BIO generation phase. * -* This also helps to limis the peak amount of pinned userspace memory. +* This also helps to limit the peak amount of pinned userspace memory. */ static int dio_bio_reap (struct dio *dio) {
@@ -388,15 +381,13 @@ out:return ret; } -struct dio *g_dio; -int generic_direct_IO (int rw,struct inode *inode,char *buf,loff_t offset,size_t count,get_block_t get_block) {const unsigned blocksize_mask = (1 << inode->i_blkbits) -1 ;const unsigned long user_addr = (unsigned long )buf; -int ret =0 ; +int ret;int ret2;struct dio dio;size_t bytes;
@@ -407,8 +398,6 @@ generic_direct_IO(int rw, struct inode * goto out; } - g_dio = &dio; -/* BIO submission state */ dio.bio =NULL ; dio.bvec =NULL ;
@@ -444,11 +433,9 @@ generic_direct_IO(int rw, struct inode *atomic_set (&dio.bio_count,0 );spin_lock_init (&dio.bio_list_lock); dio.bio_list =NULL ; -init_waitqueue_head (&dio.wait_q); + dio.waiter = current; -down_read (¤t->mm->mmap_sem); ret =do_direct_IO (&dio); -up_read (¤t->mm->mmap_sem);if (dio.bio)dio_bio_submit (&dio);
fs/buffer.c renamed from fs/buffer.c~direct-io-wrapup +0 -49
55 lines not on this page · raw message
include/linux/fs.h renamed from include/linux/fs.h~direct-io-wrapup +0 -5
@@ -274,7 +274,6 @@ struct iattr {*/ struct page ;struct address_space ; -struct kiobuf ;struct address_space_operations {int (*writepage)(struct page *);
@@ -493,10 +492,6 @@ struct file {/* needed for tty driver, and maybe others */ void *private_data; - -/* preallocated helper kiobuf to speedup O_DIRECT */ -struct kiobuf *f_iobuf; -long f_iobuf_lock; };extern spinlock_t files_lock;#define file_list_lock () spin_lock(&files_lock);
fs/fcntl.c renamed from fs/fcntl.c~direct-io-wrapup +0 -17
@@ -248,23 +248,6 @@ static int setfl(int fd, struct file * fif (!inode->i_mapping || !inode->i_mapping->a_ops || !inode->i_mapping->a_ops->direct_IO)return -EINVAL ; - -/* -* alloc_kiovec() can sleep and we are only serialized by -* the big kernel lock here, so abuse the i_sem to serialize -* this case too. We of course wouldn't need to go deep down -* to the inode layer, we could stay at the file layer, but -* we don't want to pay for the memory of a semaphore in each -* file structure too and we use the inode semaphore that we just -* pay for anyways. -*/ - error =0 ; -down (&inode->i_sem); -if (!filp->f_iobuf) - error =alloc_kiovec (1 , &filp->f_iobuf); -up (&inode->i_sem); -if (error <0 ) -return error; }/* required for strict SunOS emulation */
fs/file_table.c renamed from fs/file_table.c~direct-io-wrapup +0 -3
@@ -115,9 +115,6 @@ void __fput(struct file * file)locks_remove_flock (file); -if (file->f_iobuf) -free_kiovec (1 , &file->f_iobuf); -if (file->f_op && file->f_op->release) file->f_op->release (inode, file);fops_put (file->f_op);
fs/open.c renamed from fs/open.c~direct-io-wrapup +0 -11
@@ -647,15 +647,6 @@ struct file *dentry_open(struct dentry * f->f_op =fops_get (inode->i_fop);file_move (f, &inode->i_sb->s_files); -/* preallocate kiobuf for O_DIRECT */ - f->f_iobuf =NULL ; - f->f_iobuf_lock =0 ; -if (f->f_flags &O_DIRECT ) { - error =alloc_kiovec (1 , &f->f_iobuf); -if (error) - goto cleanup_all; - } -if (f->f_op && f->f_op->open) { error = f->f_op->open (inode,f);if (error)
@@ -675,8 +666,6 @@ struct file *dentry_open(struct dentry *return f; cleanup_all: -if (f->f_iobuf) -free_kiovec (1 , &f->f_iobuf);fops_put (f->f_op);if (f->f_mode &FMODE_WRITE )put_write_access (inode);
mm/filemap.c renamed from mm/filemap.c~direct-io-wrapup +0 -83
89 lines not on this page · raw message
fs/jfs/inode.c renamed from fs/jfs/inode.c~direct-io-wrapup +3 -4
@@ -293,11 +293,10 @@ static int jfs_bmap(struct address_spacereturn generic_block_bmap (mapping, block, jfs_get_block); } -static int jfs_direct_IO (int rw,struct inode *inode,struct kiobuf *iobuf, -unsigned long blocknr,int blocksize) +static int jfs_direct_IO (int rw,struct inode *inode,char *buf, +loff_t offset,size_t count) { -return generic_direct_IO (rw, inode, iobuf, blocknr, - blocksize, jfs_get_block); +return generic_direct_IO (rw, inode, buf, offset, count, jfs_get_block); }struct address_space_operations jfs_aops = {
.