OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [LINUX_2_4_26_OR32/] [linux/] [linux-2.4/] [fs/] [fifo.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 
16
static void wait_for_partner(struct inode* inode, unsigned int* cnt)
17
{
18
        int cur = *cnt;
19
        while(cur == *cnt) {
20
                pipe_wait(inode);
21
                if(signal_pending(current))
22
                        break;
23
        }
24
}
25
 
26
static void wake_up_partner(struct inode* inode)
27
{
28
        wake_up_interruptible(PIPE_WAIT(*inode));
29
}
30
 
31
static int fifo_open(struct inode *inode, struct file *filp)
32
{
33
        int ret;
34
 
35
        ret = -ERESTARTSYS;
36
        lock_kernel();
37
        if (down_interruptible(PIPE_SEM(*inode)))
38
                goto err_nolock_nocleanup;
39
 
40
        if (!inode->i_pipe) {
41
                ret = -ENOMEM;
42
                if(!pipe_new(inode))
43
                        goto err_nocleanup;
44
        }
45
        filp->f_version = 0;
46
 
47
        switch (filp->f_mode) {
48
        case 1:
49
        /*
50
         *  O_RDONLY
51
         *  POSIX.1 says that O_NONBLOCK means return with the FIFO
52
         *  opened, even when there is no process writing the FIFO.
53
         */
54
                filp->f_op = &read_fifo_fops;
55
                PIPE_RCOUNTER(*inode)++;
56
                if (PIPE_READERS(*inode)++ == 0)
57
                        wake_up_partner(inode);
58
 
59
                if (!PIPE_WRITERS(*inode)) {
60
                        if ((filp->f_flags & O_NONBLOCK)) {
61
                                /* suppress POLLHUP until we have
62
                                 * seen a writer */
63
                                filp->f_version = PIPE_WCOUNTER(*inode);
64
                        } else
65
                        {
66
                                wait_for_partner(inode, &PIPE_WCOUNTER(*inode));
67
                                if(signal_pending(current))
68
                                        goto err_rd;
69
                        }
70
                }
71
                break;
72
 
73
        case 2:
74
        /*
75
         *  O_WRONLY
76
         *  POSIX.1 says that O_NONBLOCK means return -1 with
77
         *  errno=ENXIO when there is no process reading the FIFO.
78
         */
79
                ret = -ENXIO;
80
                if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode))
81
                        goto err;
82
 
83
                filp->f_op = &write_fifo_fops;
84
                PIPE_WCOUNTER(*inode)++;
85
                if (!PIPE_WRITERS(*inode)++)
86
                        wake_up_partner(inode);
87
 
88
                if (!PIPE_READERS(*inode)) {
89
                        wait_for_partner(inode, &PIPE_RCOUNTER(*inode));
90
                        if (signal_pending(current))
91
                                goto err_wr;
92
                }
93
                break;
94
 
95
        case 3:
96
        /*
97
         *  O_RDWR
98
         *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
99
         *  This implementation will NEVER block on a O_RDWR open, since
100
         *  the process can at least talk to itself.
101
         */
102
                filp->f_op = &rdwr_fifo_fops;
103
 
104
                PIPE_READERS(*inode)++;
105
                PIPE_WRITERS(*inode)++;
106
                PIPE_RCOUNTER(*inode)++;
107
                PIPE_WCOUNTER(*inode)++;
108
                if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)
109
                        wake_up_partner(inode);
110
                break;
111
 
112
        default:
113
                ret = -EINVAL;
114
                goto err;
115
        }
116
 
117
        /* Ok! */
118
        up(PIPE_SEM(*inode));
119
        unlock_kernel();
120
        return 0;
121
 
122
err_rd:
123
        if (!--PIPE_READERS(*inode))
124
                wake_up_interruptible(PIPE_WAIT(*inode));
125
        ret = -ERESTARTSYS;
126
        goto err;
127
 
128
err_wr:
129
        if (!--PIPE_WRITERS(*inode))
130
                wake_up_interruptible(PIPE_WAIT(*inode));
131
        ret = -ERESTARTSYS;
132
        goto err;
133
 
134
err:
135
        if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
136
                struct pipe_inode_info *info = inode->i_pipe;
137
                inode->i_pipe = NULL;
138
                free_page((unsigned long)info->base);
139
                kfree(info);
140
        }
141
 
142
err_nocleanup:
143
        up(PIPE_SEM(*inode));
144
 
145
err_nolock_nocleanup:
146
        unlock_kernel();
147
        return ret;
148
}
149
 
150
/*
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...
154
 */
155
struct file_operations def_fifo_fops = {
156
        open:           fifo_open,      /* will set read or write pipe_fops */
157
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.