Whamcloud - gitweb
import libsysio for b_newsysio
[fs/lustre-release.git] / libsysio / dev / stdfd / stdfd.c
1 /*
2  *    This Cplant(TM) source code is the property of Sandia National
3  *    Laboratories.
4  *
5  *    This Cplant(TM) source code is copyrighted by Sandia National
6  *    Laboratories.
7  *
8  *    The redistribution of this Cplant(TM) source code is subject to the
9  *    terms of the GNU Lesser General Public License
10  *    (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html)
11  *
12  *    Cplant(TM) Copyright 1998-2003 Sandia Corporation. 
13  *    Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
14  *    license for use of this work by or on behalf of the US Government.
15  *    Export of this program may require a license from the United States
16  *    Government.
17  */
18
19 /*
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  * 
25  * This library is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  * 
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33  *
34  * Questions or comments about this library should be sent to:
35  *
36  * Lee Ward
37  * Sandia National Laboratories, New Mexico
38  * P.O. Box 5800
39  * Albuquerque, NM 87185-1110
40  *
41  * lee@sandia.gov
42  */
43
44 #ifdef __linux__
45 #define _BSD_SOURCE
46 #endif
47
48 #include <errno.h>
49 #include <sys/syscall.h>
50 #include <unistd.h>
51 #include <sys/types.h>
52 #include <sys/queue.h>
53
54 #include "xtio.h"
55 #include "sysio.h"
56 #include "inode.h"
57 #include "dev.h"
58
59 #include "stdfd.h"
60
61 #ifdef CPLANT_YOD
62 #include <sys/statfs.h>
63 #include "cplant-yod.h"
64 #define dowrite(f, b, n) write_yod(f, b, n)
65 #define doread(f, b, n) read_yod(f, b, n)
66 #else
67 #define dowrite(f, b, n) syscall(SYS_write, f, b, n)
68 #define doread(f, b, n) syscall(SYS_read, f, b, n)
69 #endif
70
71 /*
72  * Pre-opened standard file descriptors driver.
73  */
74
75 static int stdfd_open(struct pnode *pno, int flags, mode_t mode);
76 static int stdfd_close(struct inode *ino);
77 static int stdfd_read(struct inode *ino, struct ioctx *ioctx);
78 static int stdfd_write(struct inode *ino, struct ioctx *ioctx);
79 static int stdfd_iodone(struct ioctx *ioctx);
80 static int stdfd_datasync(struct inode *ino);
81 static int stdfd_ioctl(struct inode *ino,
82                        unsigned long int request,
83                        va_list ap);
84
85 int
86 _sysio_stdfd_init()
87 {
88         struct inode_ops stdfd_operations;
89
90         stdfd_operations = _sysio_nodev_ops;
91         stdfd_operations.inop_open = stdfd_open;
92         stdfd_operations.inop_close = stdfd_close;
93         stdfd_operations.inop_read = stdfd_read;
94         stdfd_operations.inop_write = stdfd_write;
95         stdfd_operations.inop_iodone = stdfd_iodone;
96         stdfd_operations.inop_datasync = stdfd_datasync;
97         stdfd_operations.inop_ioctl = stdfd_ioctl;
98
99         return _sysio_char_dev_register(SYSIO_C_STDFD_MAJOR,
100                                         "stdfd",
101                                         &stdfd_operations);
102 }
103
104 static int
105 stdfd_open(struct pnode *pno __IS_UNUSED,
106            int flags __IS_UNUSED,
107            mode_t mode __IS_UNUSED)
108 {
109
110         return 0;
111 }
112
113 static int
114 stdfd_close(struct inode *ino __IS_UNUSED)
115 {
116
117         return 0;
118 }
119
120 static int
121 doio(ssize_t (*f)(void *, size_t, _SYSIO_OFF_T, struct inode *),
122      struct inode *ino,
123      struct ioctx *ioctx)
124 {
125
126         if (ioctx->ioctx_xtvlen != 1) {
127                 /*
128                  * No scatter/gather to "file" address space (we're not
129                  * seekable) and "nowhere" makes no sense.
130                  */
131                 return -EINVAL;
132         }
133         ioctx->ioctx_cc =
134             _sysio_doio(ioctx->ioctx_xtv, ioctx->ioctx_xtvlen,
135                         ioctx->ioctx_iov, ioctx->ioctx_iovlen,
136                         (ssize_t (*)(void *, size_t, _SYSIO_OFF_T, void *))f,
137                         ino);
138         if (ioctx->ioctx_cc < 0) {
139                 ioctx->ioctx_errno = -ioctx->ioctx_cc;
140                 ioctx->ioctx_cc = -1;
141         }
142         return 0;
143 }
144
145 static ssize_t
146 stdfd_read_simple(void *buf,
147                   size_t nbytes,
148                   _SYSIO_OFF_T off __IS_UNUSED,
149                   struct inode *ino)
150 {
151
152         int     fd = SYSIO_MINOR_DEV(ino->i_rdev);
153
154         return doread(fd, buf, nbytes);
155 }
156
157 static int
158 stdfd_read(struct inode *ino, struct ioctx *ioctx)
159 {
160
161         return doio(stdfd_read_simple, ino, ioctx);
162 }
163
164 static ssize_t
165 stdfd_write_simple(const void *buf,
166                    size_t nbytes,
167                    _SYSIO_OFF_T off __IS_UNUSED,
168                    struct inode *ino)
169 {
170         int     fd = SYSIO_MINOR_DEV(ino->i_rdev);
171
172         return dowrite(fd, buf, nbytes);
173 }
174
175 static int
176 stdfd_write(struct inode *ino, struct ioctx *ioctx)
177 {
178
179         return doio((ssize_t (*)(void *,
180                                  size_t,
181                                  _SYSIO_OFF_T,
182                                  struct inode *))stdfd_write_simple,
183                     ino,
184                     ioctx);
185 }
186
187 static int
188 stdfd_iodone(struct ioctx *iocp __IS_UNUSED)
189 {
190
191         /*
192          * It's always done in this driver. It completed when posted.
193          */
194         return 1;
195 }
196
197 static int
198 stdfd_datasync(struct inode *ino __IS_UNUSED)
199 {
200
201         /*
202          * We don't buffer, so nothing to do.
203          */
204         return 0;
205 }
206
207 static int
208 stdfd_ioctl(struct inode *ino __IS_UNUSED,
209             unsigned long int request __IS_UNUSED,
210             va_list ap __IS_UNUSED)
211 {
212
213         return -ENOTTY;
214 }