Contents of /alx-src/tags/kernel26-2.6.12-alx-r9/fs/fifo.c
Parent Directory | Revision Log
Revision 630 -
(show annotations)
(download)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 3326 byte(s)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 3326 byte(s)
Tag kernel26-2.6.12-alx-r9
1 | /* |
2 | * linux/fs/fifo.c |
3 | * |
4 | * written by Paul H. Hargrove |
5 | * |
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. |
10 | */ |
11 | |
12 | #include <linux/mm.h> |
13 | #include <linux/slab.h> |
14 | #include <linux/smp_lock.h> |
15 | #include <linux/fs.h> |
16 | #include <linux/pipe_fs_i.h> |
17 | |
18 | static void wait_for_partner(struct inode* inode, unsigned int* cnt) |
19 | { |
20 | int cur = *cnt; |
21 | while(cur == *cnt) { |
22 | pipe_wait(inode); |
23 | if(signal_pending(current)) |
24 | break; |
25 | } |
26 | } |
27 | |
28 | static void wake_up_partner(struct inode* inode) |
29 | { |
30 | wake_up_interruptible(PIPE_WAIT(*inode)); |
31 | } |
32 | |
33 | static int fifo_open(struct inode *inode, struct file *filp) |
34 | { |
35 | int ret; |
36 | |
37 | ret = -ERESTARTSYS; |
38 | if (down_interruptible(PIPE_SEM(*inode))) |
39 | goto err_nolock_nocleanup; |
40 | |
41 | if (!inode->i_pipe) { |
42 | ret = -ENOMEM; |
43 | if(!pipe_new(inode)) |
44 | goto err_nocleanup; |
45 | } |
46 | filp->f_version = 0; |
47 | |
48 | /* We can only do regular read/write on fifos */ |
49 | filp->f_mode &= (FMODE_READ | FMODE_WRITE); |
50 | |
51 | switch (filp->f_mode) { |
52 | case 1: |
53 | /* |
54 | * O_RDONLY |
55 | * POSIX.1 says that O_NONBLOCK means return with the FIFO |
56 | * opened, even when there is no process writing the FIFO. |
57 | */ |
58 | filp->f_op = &read_fifo_fops; |
59 | PIPE_RCOUNTER(*inode)++; |
60 | if (PIPE_READERS(*inode)++ == 0) |
61 | wake_up_partner(inode); |
62 | |
63 | if (!PIPE_WRITERS(*inode)) { |
64 | if ((filp->f_flags & O_NONBLOCK)) { |
65 | /* suppress POLLHUP until we have |
66 | * seen a writer */ |
67 | filp->f_version = PIPE_WCOUNTER(*inode); |
68 | } else |
69 | { |
70 | wait_for_partner(inode, &PIPE_WCOUNTER(*inode)); |
71 | if(signal_pending(current)) |
72 | goto err_rd; |
73 | } |
74 | } |
75 | break; |
76 | |
77 | case 2: |
78 | /* |
79 | * O_WRONLY |
80 | * POSIX.1 says that O_NONBLOCK means return -1 with |
81 | * errno=ENXIO when there is no process reading the FIFO. |
82 | */ |
83 | ret = -ENXIO; |
84 | if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) |
85 | goto err; |
86 | |
87 | filp->f_op = &write_fifo_fops; |
88 | PIPE_WCOUNTER(*inode)++; |
89 | if (!PIPE_WRITERS(*inode)++) |
90 | wake_up_partner(inode); |
91 | |
92 | if (!PIPE_READERS(*inode)) { |
93 | wait_for_partner(inode, &PIPE_RCOUNTER(*inode)); |
94 | if (signal_pending(current)) |
95 | goto err_wr; |
96 | } |
97 | break; |
98 | |
99 | case 3: |
100 | /* |
101 | * O_RDWR |
102 | * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. |
103 | * This implementation will NEVER block on a O_RDWR open, since |
104 | * the process can at least talk to itself. |
105 | */ |
106 | filp->f_op = &rdwr_fifo_fops; |
107 | |
108 | PIPE_READERS(*inode)++; |
109 | PIPE_WRITERS(*inode)++; |
110 | PIPE_RCOUNTER(*inode)++; |
111 | PIPE_WCOUNTER(*inode)++; |
112 | if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1) |
113 | wake_up_partner(inode); |
114 | break; |
115 | |
116 | default: |
117 | ret = -EINVAL; |
118 | goto err; |
119 | } |
120 | |
121 | /* Ok! */ |
122 | up(PIPE_SEM(*inode)); |
123 | return 0; |
124 | |
125 | err_rd: |
126 | if (!--PIPE_READERS(*inode)) |
127 | wake_up_interruptible(PIPE_WAIT(*inode)); |
128 | ret = -ERESTARTSYS; |
129 | goto err; |
130 | |
131 | err_wr: |
132 | if (!--PIPE_WRITERS(*inode)) |
133 | wake_up_interruptible(PIPE_WAIT(*inode)); |
134 | ret = -ERESTARTSYS; |
135 | goto err; |
136 | |
137 | err: |
138 | if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) |
139 | free_pipe_info(inode); |
140 | |
141 | err_nocleanup: |
142 | up(PIPE_SEM(*inode)); |
143 | |
144 | err_nolock_nocleanup: |
145 | return ret; |
146 | } |
147 | |
148 | /* |
149 | * Dummy default file-operations: the only thing this does |
150 | * is contain the open that then fills in the correct operations |
151 | * depending on the access mode of the file... |
152 | */ |
153 | struct file_operations def_fifo_fops = { |
154 | .open = fifo_open, /* will set read or write pipe_fops */ |
155 | }; |