1
2
3
4
5
6
7#include <linux/mm.h>
8
9static int fifo_open(struct inode * inode,struct file * filp)
10{
11 int retval = 0;
12 unsigned long page;
13
14 switch( filp->f_mode ) {
15
16 case 1:
17
18
19
20
21
22 filp->f_op = &connecting_fifo_fops;
23 if (!PIPE_READERS(*inode)++)
24 wake_up_interruptible(&PIPE_WAIT(*inode));
25 if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
26 PIPE_RD_OPENERS(*inode)++;
27 while (!PIPE_WRITERS(*inode)) {
28 if (signal_pending(current)) {
29 retval = -ERESTARTSYS;
30 break;
31 }
32 interruptible_sleep_on(&PIPE_WAIT(*inode));
33 }
34 if (!--PIPE_RD_OPENERS(*inode))
35 wake_up_interruptible(&PIPE_WAIT(*inode));
36 }
37 while (PIPE_WR_OPENERS(*inode))
38 interruptible_sleep_on(&PIPE_WAIT(*inode));
39 if (PIPE_WRITERS(*inode))
40 filp->f_op = &read_fifo_fops;
41 if (retval && !--PIPE_READERS(*inode))
42 wake_up_interruptible(&PIPE_WAIT(*inode));
43 break;
44
45 case 2:
46
47
48
49
50
51 if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
52 retval = -ENXIO;
53 break;
54 }
55 filp->f_op = &write_fifo_fops;
56 if (!PIPE_WRITERS(*inode)++)
57 wake_up_interruptible(&PIPE_WAIT(*inode));
58 if (!PIPE_READERS(*inode)) {
59 PIPE_WR_OPENERS(*inode)++;
60 while (!PIPE_READERS(*inode)) {
61 if (signal_pending(current)) {
62 retval = -ERESTARTSYS;
63 break;
64 }
65 interruptible_sleep_on(&PIPE_WAIT(*inode));
66 }
67 if (!--PIPE_WR_OPENERS(*inode))
68 wake_up_interruptible(&PIPE_WAIT(*inode));
69 }
70 while (PIPE_RD_OPENERS(*inode))
71 interruptible_sleep_on(&PIPE_WAIT(*inode));
72 if (retval && !--PIPE_WRITERS(*inode))
73 wake_up_interruptible(&PIPE_WAIT(*inode));
74 break;
75
76 case 3:
77
78
79
80
81
82
83 filp->f_op = &rdwr_fifo_fops;
84 if (!PIPE_READERS(*inode)++)
85 wake_up_interruptible(&PIPE_WAIT(*inode));
86 while (PIPE_WR_OPENERS(*inode))
87 interruptible_sleep_on(&PIPE_WAIT(*inode));
88 if (!PIPE_WRITERS(*inode)++)
89 wake_up_interruptible(&PIPE_WAIT(*inode));
90 while (PIPE_RD_OPENERS(*inode))
91 interruptible_sleep_on(&PIPE_WAIT(*inode));
92 break;
93
94 default:
95 retval = -EINVAL;
96 }
97 if (retval || PIPE_BASE(*inode))
98 return retval;
99 page = __get_free_page(GFP_KERNEL);
100 if (PIPE_BASE(*inode)) {
101 free_page(page);
102 return 0;
103 }
104 if (!page)
105 return -ENOMEM;
106 PIPE_LOCK(*inode) = 0;
107 PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
108 PIPE_BASE(*inode) = (char *) page;
109 return 0;
110}
111
112
113
114
115
116
117static struct file_operations def_fifo_fops = {
118 NULL,
119 NULL,
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 fifo_open,
126 NULL,
127 NULL,
128 NULL,
129 NULL
130};
131
132struct inode_operations fifo_inode_operations = {
133 &def_fifo_fops,
134 NULL,
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 NULL,
140 NULL,
141 NULL,
142 NULL,
143 NULL,
144 NULL,
145 NULL,
146 NULL,
147 NULL,
148 NULL
149};
150
151void init_fifo(struct inode * inode)
152{
153 inode->i_op = &fifo_inode_operations;
154 PIPE_LOCK(*inode) = 0;
155 PIPE_BASE(*inode) = NULL;
156 PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
157 PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
158 PIPE_WAIT(*inode) = NULL;
159 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
160}
161