diff options
| author | Benjamin LaHaise <bcrl@toomuch.toronto.redhat.com> | 2002-08-21 09:43:30 -0400 |
|---|---|---|
| committer | Benjamin LaHaise <bcrl@toomuch.toronto.redhat.com> | 2002-08-21 09:43:30 -0400 |
| commit | 4b34c68e519dd1b6163b900f08819c23b3650d89 (patch) | |
| tree | 5d425eeda588539f5849295401a116e150c8120c /include | |
| parent | ea5097be4e814a2a9457e60653052306295941e8 (diff) | |
add aio core
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-i386/kmap_types.h | 4 | ||||
| -rw-r--r-- | include/linux/aio.h | 127 | ||||
| -rw-r--r-- | include/linux/errno.h | 1 | ||||
| -rw-r--r-- | include/linux/fs.h | 4 | ||||
| -rw-r--r-- | include/linux/sched.h | 5 |
5 files changed, 140 insertions, 1 deletions
diff --git a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h index 0ae7bb3c2b8d..5d875871190a 100644 --- a/include/asm-i386/kmap_types.h +++ b/include/asm-i386/kmap_types.h @@ -19,7 +19,9 @@ D(5) KM_BIO_SRC_IRQ, D(6) KM_BIO_DST_IRQ, D(7) KM_PTE0, D(8) KM_PTE1, -D(9) KM_TYPE_NR +D(9) KM_IRQ0, +D(10) KM_IRQ1, +D(11) KM_TYPE_NR }; #undef D diff --git a/include/linux/aio.h b/include/linux/aio.h new file mode 100644 index 000000000000..04f710ac0cc2 --- /dev/null +++ b/include/linux/aio.h @@ -0,0 +1,127 @@ +#ifndef __LINUX__AIO_H +#define __LINUX__AIO_H + +#include <linux/tqueue.h> +#include <linux/list.h> +#include <asm/atomic.h> + +#include <linux/aio_abi.h> + +#define AIO_MAXSEGS 4 +#define AIO_KIOGRP_NR_ATOMIC 8 + +struct kioctx; + +/* Notes on cancelling a kiocb: + * If a kiocb is cancelled, aio_complete may return 0 to indicate + * that cancel has not yet disposed of the kiocb. All cancel + * operations *must* call aio_put_req to dispose of the kiocb + * to guard against races with the completion code. + */ +#define KIOCB_C_CANCELLED 0x01 +#define KIOCB_C_COMPLETE 0x02 + +#define KIOCB_PRIVATE_SIZE (16 * sizeof(long)) + +struct kiocb { + int ki_users; + struct file *ki_filp; + struct kioctx *ki_ctx; /* may be NULL for sync ops */ + int (*ki_cancel)(struct kiocb *, struct io_event *); + + struct list_head ki_list; + + void *ki_data; /* for use by the the file */ + void *ki_user_obj; /* pointer to userland's iocb */ + __u64 ki_user_data; /* user's data for completion */ + unsigned ki_key; /* id of this request */ + + long private[KIOCB_PRIVATE_SIZE/sizeof(long)]; +}; + +#define init_sync_kiocb(x, filp) \ + do { \ + (x)->ki_users = 1; \ + (x)->ki_filp = (filp); \ + (x)->ki_ctx = 0; \ + (x)->ki_cancel = NULL; \ + } while (0) + +#define AIO_RING_MAGIC 0xa10a10a1 +#define AIO_RING_COMPAT_FEATURES 1 +#define AIO_RING_INCOMPAT_FEATURES 0 +struct aio_ring { + unsigned id; /* kernel internal index number */ + unsigned nr; /* number of io_events */ + unsigned head; + unsigned tail; + + unsigned magic; + unsigned compat_features; + unsigned incompat_features; + unsigned header_length; /* size of aio_ring */ + + + struct io_event io_events[0]; +}; /* 128 bytes + ring size */ + +#define aio_ring_avail(info, ring) (((ring)->head + (info)->nr - 1 - (ring)->tail) % (info)->nr) + +#define AIO_RING_PAGES 8 +struct aio_ring_info { + unsigned long mmap_base; + unsigned long mmap_size; + + struct page **ring_pages; + spinlock_t ring_lock; + long nr_pages; + + unsigned nr, tail; + + struct page *internal_pages[AIO_RING_PAGES]; +}; + +struct kioctx { + atomic_t users; + int dead; + struct mm_struct *mm; + + /* This needs improving */ + unsigned long user_id; + struct kioctx *next; + + wait_queue_head_t wait; + + spinlock_t ctx_lock; + + int reqs_active; + struct list_head active_reqs; /* used for cancellation */ + + unsigned max_reqs; + + struct aio_ring_info ring_info; +}; + +/* prototypes */ +extern unsigned aio_max_size; + +extern int FASTCALL(aio_put_req(struct kiocb *iocb)); +extern int FASTCALL(aio_complete(struct kiocb *iocb, long res, long res2)); +extern void FASTCALL(__put_ioctx(struct kioctx *ctx)); +struct mm_struct; +extern void FASTCALL(exit_aio(struct mm_struct *mm)); + +#define get_ioctx(kioctx) do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0) +#define put_ioctx(kioctx) do { if (unlikely(atomic_dec_and_test(&(kioctx)->users))) __put_ioctx(kioctx); else if (unlikely(atomic_read(&(kioctx)->users) < 0)) BUG(); } while (0) + +#include <linux/aio_abi.h> + +static inline struct kiocb *list_kiocb(struct list_head *h) +{ + return list_entry(h, struct kiocb, ki_list); +} + +/* for sysctl: */ +extern unsigned aio_max_nr, aio_max_size, aio_max_pinned; + +#endif /* __LINUX__AIO_H */ diff --git a/include/linux/errno.h b/include/linux/errno.h index 653227803ea4..d17a7bf67000 100644 --- a/include/linux/errno.h +++ b/include/linux/errno.h @@ -20,6 +20,7 @@ #define ESERVERFAULT 526 /* An untranslatable error occurred */ #define EBADTYPE 527 /* Type not supported by server */ #define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */ +#define EIOCBQUEUED 529 /* iocb queued, will get completion event */ #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index ec0f6edac31b..1327fc5abb48 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -744,11 +744,14 @@ struct block_device_operations { * read, write, poll, fsync, readv, writev can be called * without the big kernel lock held in all filesystems. */ +struct kiocb; struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char *, size_t, loff_t *); + ssize_t (*aio_read) (struct kiocb *, char *, size_t, loff_t); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); + ssize_t (*aio_write) (struct kiocb *, char *, size_t, loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); @@ -757,6 +760,7 @@ struct file_operations { int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); + int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *); diff --git a/include/linux/sched.h b/include/linux/sched.h index 5afeecb164b9..5d99e569af25 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -170,6 +170,7 @@ struct namespace; /* Maximum number of active map areas.. This is a random (large) number */ #define MAX_MAP_COUNT (65536) +struct kioctx; struct mm_struct { struct vm_area_struct * mmap; /* list of VMAs */ rb_root_t mm_rb; @@ -198,6 +199,10 @@ struct mm_struct { /* Architecture-specific MM context */ mm_context_t context; + + /* aio bits */ + rwlock_t ioctx_list_lock; + struct kioctx *ioctx_list; }; extern int mmlist_nr; |
