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 | ||