diff options
Diffstat (limited to 'fs/fifo.c')
| -rw-r--r-- | fs/fifo.c | 65 |
1 files changed, 35 insertions, 30 deletions
| @@ -15,30 +15,35 @@ | |||
| 15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
| 16 | #include <linux/pipe_fs_i.h> | 16 | #include <linux/pipe_fs_i.h> |
| 17 | 17 | ||
| 18 | static void wait_for_partner(struct inode* inode, unsigned int* cnt) | 18 | static void wait_for_partner(struct inode* inode, unsigned int *cnt) |
| 19 | { | 19 | { |
| 20 | int cur = *cnt; | 20 | int cur = *cnt; |
| 21 | while(cur == *cnt) { | 21 | |
| 22 | pipe_wait(inode); | 22 | while (cur == *cnt) { |
| 23 | if(signal_pending(current)) | 23 | pipe_wait(inode->i_pipe); |
| 24 | if (signal_pending(current)) | ||
| 24 | break; | 25 | break; |
| 25 | } | 26 | } |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | static void wake_up_partner(struct inode* inode) | 29 | static void wake_up_partner(struct inode* inode) |
| 29 | { | 30 | { |
| 30 | wake_up_interruptible(PIPE_WAIT(*inode)); | 31 | wake_up_interruptible(&inode->i_pipe->wait); |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | static int fifo_open(struct inode *inode, struct file *filp) | 34 | static int fifo_open(struct inode *inode, struct file *filp) |
| 34 | { | 35 | { |
| 36 | struct pipe_inode_info *pipe; | ||
| 35 | int ret; | 37 | int ret; |
| 36 | 38 | ||
| 37 | mutex_lock(PIPE_MUTEX(*inode)); | 39 | mutex_lock(&inode->i_mutex); |
| 38 | if (!inode->i_pipe) { | 40 | pipe = inode->i_pipe; |
| 41 | if (!pipe) { | ||
| 39 | ret = -ENOMEM; | 42 | ret = -ENOMEM; |
| 40 | if(!pipe_new(inode)) | 43 | pipe = alloc_pipe_info(inode); |
| 44 | if (!pipe) | ||
| 41 | goto err_nocleanup; | 45 | goto err_nocleanup; |
| 46 | inode->i_pipe = pipe; | ||
| 42 | } | 47 | } |
| 43 | filp->f_version = 0; | 48 | filp->f_version = 0; |
| 44 | 49 | ||
| @@ -53,18 +58,18 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 53 | * opened, even when there is no process writing the FIFO. | 58 | * opened, even when there is no process writing the FIFO. |
| 54 | */ | 59 | */ |
| 55 | filp->f_op = &read_fifo_fops; | 60 | filp->f_op = &read_fifo_fops; |
| 56 | PIPE_RCOUNTER(*inode)++; | 61 | pipe->r_counter++; |
| 57 | if (PIPE_READERS(*inode)++ == 0) | 62 | if (pipe->readers++ == 0) |
| 58 | wake_up_partner(inode); | 63 | wake_up_partner(inode); |
| 59 | 64 | ||
| 60 | if (!PIPE_WRITERS(*inode)) { | 65 | if (!pipe->writers) { |
| 61 | if ((filp->f_flags & O_NONBLOCK)) { | 66 | if ((filp->f_flags & O_NONBLOCK)) { |
| 62 | /* suppress POLLHUP until we have | 67 | /* suppress POLLHUP until we have |
| 63 | * seen a writer */ | 68 | * seen a writer */ |
| 64 | filp->f_version = PIPE_WCOUNTER(*inode); | 69 | filp->f_version = pipe->w_counter; |
| 65 | } else | 70 | } else |
| 66 | { | 71 | { |
| 67 | wait_for_partner(inode, &PIPE_WCOUNTER(*inode)); | 72 | wait_for_partner(inode, &pipe->w_counter); |
| 68 | if(signal_pending(current)) | 73 | if(signal_pending(current)) |
| 69 | goto err_rd; | 74 | goto err_rd; |
| 70 | } | 75 | } |
| @@ -78,16 +83,16 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 78 | * errno=ENXIO when there is no process reading the FIFO. | 83 | * errno=ENXIO when there is no process reading the FIFO. |
| 79 | */ | 84 | */ |
| 80 | ret = -ENXIO; | 85 | ret = -ENXIO; |
| 81 | if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) | 86 | if ((filp->f_flags & O_NONBLOCK) && !pipe->readers) |
| 82 | goto err; | 87 | goto err; |
| 83 | 88 | ||
| 84 | filp->f_op = &write_fifo_fops; | 89 | filp->f_op = &write_fifo_fops; |
| 85 | PIPE_WCOUNTER(*inode)++; | 90 | pipe->w_counter++; |
| 86 | if (!PIPE_WRITERS(*inode)++) | 91 | if (!pipe->writers++) |
| 87 | wake_up_partner(inode); | 92 | wake_up_partner(inode); |
| 88 | 93 | ||
| 89 | if (!PIPE_READERS(*inode)) { | 94 | if (!pipe->readers) { |
| 90 | wait_for_partner(inode, &PIPE_RCOUNTER(*inode)); | 95 | wait_for_partner(inode, &pipe->r_counter); |
| 91 | if (signal_pending(current)) | 96 | if (signal_pending(current)) |
| 92 | goto err_wr; | 97 | goto err_wr; |
| 93 | } | 98 | } |
| @@ -102,11 +107,11 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 102 | */ | 107 | */ |
| 103 | filp->f_op = &rdwr_fifo_fops; | 108 | filp->f_op = &rdwr_fifo_fops; |
| 104 | 109 | ||
| 105 | PIPE_READERS(*inode)++; | 110 | pipe->readers++; |
| 106 | PIPE_WRITERS(*inode)++; | 111 | pipe->writers++; |
| 107 | PIPE_RCOUNTER(*inode)++; | 112 | pipe->r_counter++; |
| 108 | PIPE_WCOUNTER(*inode)++; | 113 | pipe->w_counter++; |
| 109 | if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1) | 114 | if (pipe->readers == 1 || pipe->writers == 1) |
| 110 | wake_up_partner(inode); | 115 | wake_up_partner(inode); |
| 111 | break; | 116 | break; |
| 112 | 117 | ||
| @@ -116,27 +121,27 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
| 116 | } | 121 | } |
| 117 | 122 | ||
| 118 | /* Ok! */ | 123 | /* Ok! */ |
| 119 | mutex_unlock(PIPE_MUTEX(*inode)); | 124 | mutex_unlock(&inode->i_mutex); |
| 120 | return 0; | 125 | return 0; |
| 121 | 126 | ||
| 122 | err_rd: | 127 | err_rd: |
| 123 | if (!--PIPE_READERS(*inode)) | 128 | if (!--pipe->readers) |
| 124 | wake_up_interruptible(PIPE_WAIT(*inode)); | 129 | wake_up_interruptible(&pipe->wait); |
| 125 | ret = -ERESTARTSYS; | 130 | ret = -ERESTARTSYS; |
| 126 | goto err; | 131 | goto err; |
| 127 | 132 | ||
| 128 | err_wr: | 133 | err_wr: |
| 129 | if (!--PIPE_WRITERS(*inode)) | 134 | if (!--pipe->writers) |
| 130 | wake_up_interruptible(PIPE_WAIT(*inode)); | 135 | wake_up_interruptible(&pipe->wait); |
| 131 | ret = -ERESTARTSYS; | 136 | ret = -ERESTARTSYS; |
| 132 | goto err; | 137 | goto err; |
| 133 | 138 | ||
| 134 | err: | 139 | err: |
| 135 | if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) | 140 | if (!pipe->readers && !pipe->writers) |
| 136 | free_pipe_info(inode); | 141 | free_pipe_info(inode); |
| 137 | 142 | ||
| 138 | err_nocleanup: | 143 | err_nocleanup: |
| 139 | mutex_unlock(PIPE_MUTEX(*inode)); | 144 | mutex_unlock(&inode->i_mutex); |
| 140 | return ret; | 145 | return ret; |
| 141 | } | 146 | } |
| 142 | 147 | ||
