source:
trunk/packages/xen-3.1/xen-3.1/patches/linux-2.6.18/blktap-aio-16_03_06.patch
@
34
Last change on this file since 34 was 34, checked in by hartmans, 18 years ago | |
---|---|
|
|
File size: 8.7 KB |
-
fs/aio.c
diff -pruN ../orig-linux-2.6.18/fs/aio.c ./fs/aio.c
old new 34 34 #include <asm/uaccess.h> 35 35 #include <asm/mmu_context.h> 36 36 37 #ifdef CONFIG_EPOLL 38 #include <linux/poll.h> 39 #include <linux/eventpoll.h> 40 #endif 41 37 42 #if DEBUG > 1 38 43 #define dprintk printk 39 44 #else … … put_rq: 1015 1020 if (waitqueue_active(&ctx->wait)) 1016 1021 wake_up(&ctx->wait); 1017 1022 1023 #ifdef CONFIG_EPOLL 1024 if (ctx->file && waitqueue_active(&ctx->poll_wait)) 1025 wake_up(&ctx->poll_wait); 1026 #endif 1018 1027 if (ret) 1019 1028 put_ioctx(ctx); 1020 1029 … … put_rq: 1024 1033 /* aio_read_evt 1025 1034 * Pull an event off of the ioctx's event ring. Returns the number of 1026 1035 * events fetched (0 or 1 ;-) 1036 * If ent parameter is 0, just returns the number of events that would 1037 * be fetched. 1027 1038 * FIXME: make this use cmpxchg. 1028 1039 * TODO: make the ringbuffer user mmap()able (requires FIXME). 1029 1040 */ … … static int aio_read_evt(struct kioctx *i 1046 1057 1047 1058 head = ring->head % info->nr; 1048 1059 if (head != ring->tail) { 1049 struct io_event *evp = aio_ring_event(info, head, KM_USER1); 1050 *ent = *evp; 1051 head = (head + 1) % info->nr; 1052 smp_mb(); /* finish reading the event before updatng the head */ 1053 ring->head = head; 1054 ret = 1; 1055 put_aio_ring_event(evp, KM_USER1); 1060 if (ent) { /* event requested */ 1061 struct io_event *evp = 1062 aio_ring_event(info, head, KM_USER1); 1063 *ent = *evp; 1064 head = (head + 1) % info->nr; 1065 /* finish reading the event before updatng the head */ 1066 smp_mb(); 1067 ring->head = head; 1068 ret = 1; 1069 put_aio_ring_event(evp, KM_USER1); 1070 } else /* only need to know availability */ 1071 ret = 1; 1056 1072 } 1057 1073 spin_unlock(&info->ring_lock); 1058 1074 … … static void io_destroy(struct kioctx *io 1235 1251 1236 1252 aio_cancel_all(ioctx); 1237 1253 wait_for_all_aios(ioctx); 1254 #ifdef CONFIG_EPOLL 1255 /* forget the poll file, but it's up to the user to close it */ 1256 if (ioctx->file) { 1257 ioctx->file->private_data = 0; 1258 ioctx->file = 0; 1259 } 1260 #endif 1238 1261 put_ioctx(ioctx); /* once for the lookup */ 1239 1262 } 1240 1263 1264 #ifdef CONFIG_EPOLL 1265 1266 static int aio_queue_fd_close(struct inode *inode, struct file *file) 1267 { 1268 struct kioctx *ioctx = file->private_data; 1269 if (ioctx) { 1270 file->private_data = 0; 1271 spin_lock_irq(&ioctx->ctx_lock); 1272 ioctx->file = 0; 1273 spin_unlock_irq(&ioctx->ctx_lock); 1274 } 1275 return 0; 1276 } 1277 1278 static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait) 1279 { unsigned int pollflags = 0; 1280 struct kioctx *ioctx = file->private_data; 1281 1282 if (ioctx) { 1283 1284 spin_lock_irq(&ioctx->ctx_lock); 1285 /* Insert inside our poll wait queue */ 1286 poll_wait(file, &ioctx->poll_wait, wait); 1287 1288 /* Check our condition */ 1289 if (aio_read_evt(ioctx, 0)) 1290 pollflags = POLLIN | POLLRDNORM; 1291 spin_unlock_irq(&ioctx->ctx_lock); 1292 } 1293 1294 return pollflags; 1295 } 1296 1297 static const struct file_operations aioq_fops = { 1298 .release = aio_queue_fd_close, 1299 .poll = aio_queue_fd_poll 1300 }; 1301 1302 /* make_aio_fd: 1303 * Create a file descriptor that can be used to poll the event queue. 1304 * Based and piggybacked on the excellent epoll code. 1305 */ 1306 1307 static int make_aio_fd(struct kioctx *ioctx) 1308 { 1309 int error, fd; 1310 struct inode *inode; 1311 struct file *file; 1312 1313 error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops); 1314 if (error) 1315 return error; 1316 1317 /* associate the file with the IO context */ 1318 file->private_data = ioctx; 1319 ioctx->file = file; 1320 init_waitqueue_head(&ioctx->poll_wait); 1321 return fd; 1322 } 1323 #endif 1324 1325 1241 1326 /* sys_io_setup: 1242 1327 * Create an aio_context capable of receiving at least nr_events. 1243 1328 * ctxp must not point to an aio_context that already exists, and … … static void io_destroy(struct kioctx *io 1250 1335 * resources are available. May fail with -EFAULT if an invalid 1251 1336 * pointer is passed for ctxp. Will fail with -ENOSYS if not 1252 1337 * implemented. 1338 * 1339 * To request a selectable fd, the user context has to be initialized 1340 * to 1, instead of 0, and the return value is the fd. 1341 * This keeps the system call compatible, since a non-zero value 1342 * was not allowed so far. 1253 1343 */ 1254 1344 asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp) 1255 1345 { 1256 1346 struct kioctx *ioctx = NULL; 1257 1347 unsigned long ctx; 1258 1348 long ret; 1349 int make_fd = 0; 1259 1350 1260 1351 ret = get_user(ctx, ctxp); 1261 1352 if (unlikely(ret)) 1262 1353 goto out; 1263 1354 1264 1355 ret = -EINVAL; 1356 #ifdef CONFIG_EPOLL 1357 if (ctx == 1) { 1358 make_fd = 1; 1359 ctx = 0; 1360 } 1361 #endif 1265 1362 if (unlikely(ctx || nr_events == 0)) { 1266 1363 pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n", 1267 1364 ctx, nr_events); … … asmlinkage long sys_io_setup(unsigned nr 1272 1369 ret = PTR_ERR(ioctx); 1273 1370 if (!IS_ERR(ioctx)) { 1274 1371 ret = put_user(ioctx->user_id, ctxp); 1275 if (!ret) 1276 return 0; 1372 #ifdef CONFIG_EPOLL 1373 if (make_fd && ret >= 0) 1374 ret = make_aio_fd(ioctx); 1375 #endif 1376 if (ret >= 0) 1377 return ret; 1277 1378 1278 1379 get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */ 1279 1380 io_destroy(ioctx); -
fs/eventpoll.c
diff -pruN ../orig-linux-2.6.18/fs/eventpoll.c ./fs/eventpoll.c
old new struct ep_pqueue { 236 236 237 237 static void ep_poll_safewake_init(struct poll_safewake *psw); 238 238 static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq); 239 static int ep_getfd(int *efd, struct inode **einode, struct file **efile,240 struct eventpoll *ep);241 239 static int ep_alloc(struct eventpoll **pep); 242 240 static void ep_free(struct eventpoll *ep); 243 241 static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd); … … static int ep_events_transfer(struct eve 267 265 static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, 268 266 int maxevents, long timeout); 269 267 static int eventpollfs_delete_dentry(struct dentry *dentry); 270 static struct inode *ep_eventpoll_inode( void);268 static struct inode *ep_eventpoll_inode(const struct file_operations *fops); 271 269 static int eventpollfs_get_sb(struct file_system_type *fs_type, 272 270 int flags, const char *dev_name, 273 271 void *data, struct vfsmount *mnt); … … asmlinkage long sys_epoll_create(int siz 517 515 * Creates all the items needed to setup an eventpoll file. That is, 518 516 * a file structure, and inode and a free file descriptor. 519 517 */ 520 error = ep_getfd(&fd, &inode, &file, ep );518 error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops); 521 519 if (error) 522 520 goto eexit_2; 523 521 … … eexit_1: 702 700 /* 703 701 * Creates the file descriptor to be used by the epoll interface. 704 702 */ 705 staticint ep_getfd(int *efd, struct inode **einode, struct file **efile,706 struct eventpoll *ep )703 int ep_getfd(int *efd, struct inode **einode, struct file **efile, 704 struct eventpoll *ep, const struct file_operations *fops) 707 705 { 708 706 struct qstr this; 709 707 char name[32]; … … static int ep_getfd(int *efd, struct ino 719 717 goto eexit_1; 720 718 721 719 /* Allocates an inode from the eventpoll file system */ 722 inode = ep_eventpoll_inode( );720 inode = ep_eventpoll_inode(fops); 723 721 error = PTR_ERR(inode); 724 722 if (IS_ERR(inode)) 725 723 goto eexit_2; … … static int ep_getfd(int *efd, struct ino 750 748 751 749 file->f_pos = 0; 752 750 file->f_flags = O_RDONLY; 753 file->f_op = &eventpoll_fops;751 file->f_op = fops; 754 752 file->f_mode = FMODE_READ; 755 753 file->f_version = 0; 756 754 file->private_data = ep; … … static int eventpollfs_delete_dentry(str 1569 1567 } 1570 1568 1571 1569 1572 static struct inode *ep_eventpoll_inode( void)1570 static struct inode *ep_eventpoll_inode(const struct file_operations *fops) 1573 1571 { 1574 1572 int error = -ENOMEM; 1575 1573 struct inode *inode = new_inode(eventpoll_mnt->mnt_sb); … … static struct inode *ep_eventpoll_inode( 1577 1575 if (!inode) 1578 1576 goto eexit_1; 1579 1577 1580 inode->i_fop = &eventpoll_fops;1578 inode->i_fop = fops; 1581 1579 1582 1580 /* 1583 1581 * Mark the inode dirty from the very beginning, -
include/linux/aio.h
diff -pruN ../orig-linux-2.6.18/include/linux/aio.h ./include/linux/aio.h
old new struct kioctx { 191 191 struct aio_ring_info ring_info; 192 192 193 193 struct work_struct wq; 194 #ifdef CONFIG_EPOLL 195 // poll integration 196 wait_queue_head_t poll_wait; 197 struct file *file; 198 #endif 194 199 }; 195 200 196 201 /* prototypes */ -
include/linux/eventpoll.h
diff -pruN ../orig-linux-2.6.18/include/linux/eventpoll.h ./include/linux/eventpoll.h
old new static inline void eventpoll_release(str 90 90 eventpoll_release_file(file); 91 91 } 92 92 93 /* 94 * called by aio code to create fd that can poll the aio event queueQ 95 */ 96 struct eventpoll; 97 int ep_getfd(int *efd, struct inode **einode, struct file **efile, 98 struct eventpoll *ep, const struct file_operations *fops); 93 99 #else 94 100 95 101 static inline void eventpoll_init_file(struct file *file) {}
Note: See TracBrowser
for help on using the repository browser.