Import 2.3.12pre9
[davej-history.git] / fs / fifo.c
blob3e641a6fe891696f820ecb8f7175709aafce42c5
1 /*
2 * linux/fs/fifo.c
4 * written by Paul H. Hargrove
6 * Fixes:
7 * 10-06-1999, AV: fixed OOM handling in fifo_open(), moved
8 * initialization there, switched to external
9 * allocation of pipe_inode_info.
12 #include <linux/mm.h>
13 #include <linux/malloc.h>
15 static int fifo_open(struct inode * inode,struct file * filp)
17 int retval = 0;
18 unsigned long page = 0;
19 struct pipe_inode_info *info, *tmp = NULL;
21 if (inode->i_pipe)
22 goto got_it;
23 tmp = kmalloc(sizeof(struct pipe_inode_info),GFP_KERNEL);
24 if (inode->i_pipe)
25 goto got_it;
26 if (!tmp)
27 goto oom;
28 page = __get_free_page(GFP_KERNEL);
29 if (inode->i_pipe)
30 goto got_it;
31 if (!page)
32 goto oom;
33 inode->i_pipe = tmp;
34 PIPE_LOCK(*inode) = 0;
35 PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
36 PIPE_BASE(*inode) = (char *) page;
37 PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
38 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
39 init_waitqueue_head(&PIPE_WAIT(*inode));
40 tmp = NULL; /* no need to free it */
41 page = 0;
43 got_it:
45 switch( filp->f_mode ) {
47 case 1:
49 * O_RDONLY
50 * POSIX.1 says that O_NONBLOCK means return with the FIFO
51 * opened, even when there is no process writing the FIFO.
53 filp->f_op = &connecting_fifo_fops;
54 if (!PIPE_READERS(*inode)++)
55 wake_up_interruptible(&PIPE_WAIT(*inode));
56 if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
57 PIPE_RD_OPENERS(*inode)++;
58 while (!PIPE_WRITERS(*inode)) {
59 if (signal_pending(current)) {
60 retval = -ERESTARTSYS;
61 break;
63 interruptible_sleep_on(&PIPE_WAIT(*inode));
65 if (!--PIPE_RD_OPENERS(*inode))
66 wake_up_interruptible(&PIPE_WAIT(*inode));
68 while (PIPE_WR_OPENERS(*inode))
69 interruptible_sleep_on(&PIPE_WAIT(*inode));
70 if (PIPE_WRITERS(*inode))
71 filp->f_op = &read_fifo_fops;
72 if (retval && !--PIPE_READERS(*inode))
73 wake_up_interruptible(&PIPE_WAIT(*inode));
74 break;
76 case 2:
78 * O_WRONLY
79 * POSIX.1 says that O_NONBLOCK means return -1 with
80 * errno=ENXIO when there is no process reading the FIFO.
82 if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
83 retval = -ENXIO;
84 break;
86 filp->f_op = &write_fifo_fops;
87 if (!PIPE_WRITERS(*inode)++)
88 wake_up_interruptible(&PIPE_WAIT(*inode));
89 if (!PIPE_READERS(*inode)) {
90 PIPE_WR_OPENERS(*inode)++;
91 while (!PIPE_READERS(*inode)) {
92 if (signal_pending(current)) {
93 retval = -ERESTARTSYS;
94 break;
96 interruptible_sleep_on(&PIPE_WAIT(*inode));
98 if (!--PIPE_WR_OPENERS(*inode))
99 wake_up_interruptible(&PIPE_WAIT(*inode));
101 while (PIPE_RD_OPENERS(*inode))
102 interruptible_sleep_on(&PIPE_WAIT(*inode));
103 if (retval && !--PIPE_WRITERS(*inode))
104 wake_up_interruptible(&PIPE_WAIT(*inode));
105 break;
107 case 3:
109 * O_RDWR
110 * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
111 * This implementation will NEVER block on a O_RDWR open, since
112 * the process can at least talk to itself.
114 filp->f_op = &rdwr_fifo_fops;
115 if (!PIPE_READERS(*inode)++)
116 wake_up_interruptible(&PIPE_WAIT(*inode));
117 while (PIPE_WR_OPENERS(*inode))
118 interruptible_sleep_on(&PIPE_WAIT(*inode));
119 if (!PIPE_WRITERS(*inode)++)
120 wake_up_interruptible(&PIPE_WAIT(*inode));
121 while (PIPE_RD_OPENERS(*inode))
122 interruptible_sleep_on(&PIPE_WAIT(*inode));
123 break;
125 default:
126 retval = -EINVAL;
128 if (retval)
129 goto cleanup;
130 out:
131 if (tmp)
132 kfree(tmp);
133 if (page)
134 free_page(page);
135 return retval;
137 cleanup:
138 if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
139 info = inode->i_pipe;
140 inode->i_pipe = NULL;
141 free_page((unsigned long)info->base);
142 kfree(info);
144 goto out;
145 oom:
146 retval = -ENOMEM;
147 goto out;
151 * Dummy default file-operations: the only thing this does
152 * is contain the open that then fills in the correct operations
153 * depending on the access mode of the file...
155 static struct file_operations def_fifo_fops = {
156 NULL,
157 NULL,
158 NULL,
159 NULL,
160 NULL,
161 NULL,
162 NULL,
163 fifo_open, /* will set read or write pipe_fops */
164 NULL,
165 NULL,
166 NULL,
167 NULL
170 struct inode_operations fifo_inode_operations = {
171 &def_fifo_fops, /* default file operations */
172 NULL, /* create */
173 NULL, /* lookup */
174 NULL, /* link */
175 NULL, /* unlink */
176 NULL, /* symlink */
177 NULL, /* mkdir */
178 NULL, /* rmdir */
179 NULL, /* mknod */
180 NULL, /* rename */
181 NULL, /* readlink */
182 NULL, /* follow_link */
183 NULL, /* get_block */
184 NULL, /* readpage */
185 NULL, /* writepage */
186 NULL, /* flushpage */
187 NULL, /* truncate */
188 NULL, /* permission */
189 NULL, /* smap */
190 NULL /* revalidate */
194 /* Goner. Filesystems do not use it anymore. */
196 void init_fifo(struct inode * inode)
198 inode->i_op = &fifo_inode_operations;