ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-NBD/NBD.xs
(Generate patch)

Comparing Linux-NBD/NBD.xs (file contents):
Revision 1.1 by root, Thu May 8 23:43:41 2003 UTC vs.
Revision 1.9 by root, Tue May 30 03:58:30 2017 UTC

10#include <netinet/in.h> 10#include <netinet/in.h>
11#include <byteswap.h> 11#include <byteswap.h>
12 12
13typedef uint32_t u32; 13typedef uint32_t u32;
14typedef uint64_t u64; 14typedef uint64_t u64;
15#include <linux/nbd.h> 15#include "nbd.h"
16 16
17#if __BYTE_ORDER == __BIG_ENDIAN 17#if __BYTE_ORDER == __BIG_ENDIAN
18#define ntohll(netlong) (netlong) 18#define ntohll(netlong) (netlong)
19#elif __BYTE_ORDER == __LITTLE_ENDIAN 19#elif __BYTE_ORDER == __LITTLE_ENDIAN
20#define ntohll(netlong) __bswap_64(netlong) 20#define ntohll(netlong) __bswap_64(netlong)
21#else 21#else
22error, you should not exist 22error, you should not exist
23#endif 23#endif
24 24
25struct rstate {
26 struct nbd_request req;
27 u32 req_read; /* how many octets of req are valid */
28 u32 data_read; /* how many octets of the data sv are valid */
29};
30
25MODULE = Linux::NBD PACKAGE = Linux::NBD::Client 31MODULE = Linux::NBD PACKAGE = Linux::NBD::Client
26 32
33PROTOTYPES: DISABLE
34
27void 35void
28_set_sock (int dev, int fd) 36_set_sock (int dev, int fd)
29 CODE: 37 CODE:
30 ioctl (dev, NBD_SET_SOCK, (unsigned long)fd); 38 ioctl (dev, NBD_SET_SOCK, (unsigned long)fd);
31 39
32void 40void
33_doit (int dev, int doexit = 0) 41_doit (int dev, int server = 0)
34 CODE: 42 CODE:
43 if (server)
44 for (server = 0; server < 4095; server++)
45 if (server != dev)
46 close (server);
47
35 ioctl (dev, NBD_DO_IT); 48 ioctl (dev, NBD_DO_IT);
36 if (doexit) 49
50 if (server)
37 _exit (0); 51 _exit (0);
38 52
39void 53void
40_disconnect (int dev) 54_disconnect (int dev)
41 CODE: 55 CODE:
42 ioctl (dev, NBD_DISCONNECT); 56 ioctl (dev, NBD_DISCONNECT);
43 57
44void 58void
45_clear_sock (int dev) 59_clear_sock (int dev)
60 ALIAS:
61 _clear_sock = NBD_CLEAR_SOCK
62 _clear_que = NBD_CLEAR_QUE
46 CODE: 63 CODE:
47 ioctl (dev, NBD_CLEAR_SOCK); 64 ioctl (dev, ix);
48 65
49void 66void
50_clear_que (int dev)
51 CODE:
52 ioctl (dev, NBD_CLEAR_QUE);
53
54void
55_set_blksize (int dev, unsigned long blocksize)
56 CODE:
57 ioctl (dev, NBD_SET_BLKSIZE, blocksize);
58
59void
60_set_size (int dev, unsigned long size) 67_set_blksize (int dev, unsigned long arg)
68 ALIAS:
69 _set_blksize = NBD_SET_BLKSIZE
70 _set_size = NBD_SET_SIZE
71 _set_size_blocks = NBD_SET_SIZE_BLOCKS
72 _set_timeout = NBD_SET_TIMEOUT
73 _set_flags = NBD_SET_FLAGS
61 CODE: 74 CODE:
62 ioctl (dev, NBD_SET_BLKSIZE, size); 75 ioctl (dev, ix, arg);
63 76
64void 77void
65_set_size_blocks (int dev, unsigned long nblocks) 78_print_debug (int dev)
66 CODE: 79 CODE:
67 ioctl (dev, NBD_SET_SIZE_BLOCKS, nblocks); 80 ioctl (dev, NBD_PRINT_DEBUG, 0);
68 81
69MODULE = Linux::NBD PACKAGE = Linux::NBD::Server 82MODULE = Linux::NBD PACKAGE = Linux::NBD::Server
70 83
71void 84void
72_one_request (SV *obj, int fd) 85_one_request (SV *obj, int fd)
73 CODE: 86 CODE:
74 struct nbd_request req; 87{
88 struct rstate *s;
89 u64 from;
90 u32 len;
91 char *method;
92 int cmd;
93 MAGIC *mg = mg_find (SvRV (obj), PERL_MAGIC_ext);
75 94
76 if (read (fd, &req, sizeof (req)) == sizeof (req)) 95 if (!mg)
77 { 96 {
97 mg = sv_magicext (SvRV (obj), 0, PERL_MAGIC_ext, 0, 0, 0);
98 mg->mg_len = sizeof (struct rstate);
99 New (0, mg->mg_ptr, mg->mg_len, char);
100
101 ((struct rstate *)mg->mg_ptr)->req_read = 0; /* initialise the state machine */
102 }
103
104 s = (struct rstate *)mg->mg_ptr;
105
106 if (s->req_read < sizeof (struct nbd_request))
107 {
108 int res = read (fd, s->req_read + (char *)&s->req, sizeof (struct nbd_request) - s->req_read);
109
110 if (res > 0)
111 s->req_read += res;
112 else if (res == 0)
113 XSRETURN_UNDEF; /* should req->eof */
114 else if (errno != EAGAIN && errno != EWOULDBLOCK)
115 XSRETURN_UNDEF; /* should req->error */
116
117 s->data_read = 0;
118
119 if (s->req_read < sizeof (struct nbd_request))
120 XSRETURN_NO;
121 }
122
123 /* now we have a full request, so check for data */
78 if (req.magic == htonl (NBD_REQUEST_MAGIC)) 124 if (s->req.magic != htonl (NBD_REQUEST_MAGIC))
125 croak ("Linux::NBD::Server received illegal request magic %08lx - protocol error.\n", ntohl (s->req.magic));
126
127 from = ntohll (s->req.from);
128 len = ntohl (s->req.len);
129 cmd = ntohl (s->req.type) & NBD_CMD_MASK_COMMAND;
130
131 switch (cmd)
79 { 132 {
80 if (req.type < 2) 133 case NBD_CMD_WRITE:
134 if (!mg->mg_obj)
81 { 135 {
82 u64 from = ntohll (req.from); 136 mg->mg_flags |= MGf_REFCOUNTED;
137 mg->mg_obj = NEWSV (0, len);
138 SvPOK_only (mg->mg_obj);
139 SvCUR_set (mg->mg_obj, len);
140 }
83 141
84 PUSHMARK (SP); 142 if (s->data_read < len)
85 EXTEND (SP, 3); 143 {
86 PUSHs (obj); 144 int res = read (fd, s->data_read + SvPVX (mg->mg_obj), len - s->data_read);
87 PUSHs (sv_2mortal (newSVpvn (req.handle, sizeof (req.handle))));
88 PUSHs (sv_2mortal (sizeof (UV) < 8 && from > (0xffffffffUL)
89 ? newSVnv (from)
90 : newSVuv (from)));
91 PUSHs (sv_2mortal (newSVuv (ntohl (req.len))));
92 PUTBACK;
93 call_method (req.type ? "req_write" : "req_read", G_DISCARD);
94 SPAGAIN;
95 145
146 if (res > 0)
147 s->data_read += res;
148 else if (res == 0)
149 XSRETURN_UNDEF; /* should req->eof */
150 else if (errno != EAGAIN && errno != EWOULDBLOCK)
151 XSRETURN_UNDEF; /* should req->error */
152
153 if (s->data_read < len)
96 XSRETURN_NO; 154 XSRETURN_NO;
97 } 155 }
156
157 /* fallthrough */
158 case NBD_CMD_READ:
159 case NBD_CMD_FLUSH:
160 case NBD_CMD_TRIM:
161 case NBD_CMD_WRITE_ZEROES:
162 s->req_read = 0;
163
164 PUSHMARK (SP);
165 EXTEND (SP, 4);
166 PUSHs (obj);
167 PUSHs (sv_2mortal (newSVpvn (s->req.handle, sizeof (s->req.handle))));
168 PUSHs (sv_2mortal (sizeof (UV) < 8 && from > 0xffffffffUL
169 ? newSVnv (from)
170 : newSVuv (from)));
171
172 if (mg->mg_obj)
173 {
174 PUSHs (sv_2mortal (mg->mg_obj));
175 mg->mg_obj = 0;
176 method = "req_write";
98 } 177 }
178 else
179 {
180 PUSHs (sv_2mortal (newSVuv (len)));
181 method = cmd == NBD_CMD_READ ? "req_read"
182 : cmd == NBD_CMD_FLUSH ? "req_flush"
183 : cmd == NBD_CMD_TRIM ? "req_trim"
184 : cmd == NBD_CMD_WRITE_ZEROES ? "req_write_zeroes"
185 : (abort (), "");
186 }
187
188 break;
189
190 case NBD_CMD_DISC:
191 s->req_read = 0;
192
193 method = "req_disc";
194
195 PUSHMARK (SP);
196 XPUSHs (obj);
197
198 break;
199
200 default:
201 croak ("Linux::NBD::Server received unsupported request type %d.\n", ntohl (s->req.type));
99 } 202 }
100 203
204 PUTBACK;
205 call_method (method, G_DISCARD);
206 SPAGAIN;
207
101 XSRETURN_YES; 208 XSRETURN_YES;
209}
102 210
103SV * 211SV *
104_format_reply (SV *handle, unsigned int error = 0, SV *data = 0) 212format_reply (SV *unused, SV *handle, unsigned int error = 0, SV *data = 0)
105 CODE: 213 CODE:
214{
106 struct nbd_reply rep; 215 struct nbd_reply rep;
107 STRLEN len; 216 STRLEN len;
108 char *h = SvPV (handle, len); 217 char *h = SvPV (handle, len);
109 218
110 if (len != sizeof (rep.handle)) 219 if (len != sizeof (rep.handle))
116 225
117 RETVAL = newSVpvn ((char *)&rep, sizeof (rep)); 226 RETVAL = newSVpvn ((char *)&rep, sizeof (rep));
118 227
119 if (data && !error) 228 if (data && !error)
120 sv_catsv (RETVAL, data); 229 sv_catsv (RETVAL, data);
121 230}
122 OUTPUT: 231 OUTPUT:
123 RETVAL 232 RETVAL
124 233

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines