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.2 by root, Fri May 9 00:15:14 2003 UTC vs.
Revision 1.8 by root, Tue May 30 01:07:29 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
32
33PROTOTYPES: DISABLE
26 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);
47 CODE: 55 CODE:
48 ioctl (dev, NBD_DISCONNECT); 56 ioctl (dev, NBD_DISCONNECT);
49 57
50void 58void
51_clear_sock (int dev) 59_clear_sock (int dev)
60 ALIAS:
61 _clear_sock = NBD_CLEAR_SOCK
62 _clear_que = NBD_CLEAR_QUE
52 CODE: 63 CODE:
53 ioctl (dev, NBD_CLEAR_SOCK); 64 ioctl (dev, ix);
54 65
55void 66void
56_clear_que (int dev)
57 CODE:
58 ioctl (dev, NBD_CLEAR_QUE);
59
60void
61_set_blksize (int dev, unsigned long blocksize)
62 CODE:
63 ioctl (dev, NBD_SET_BLKSIZE, blocksize);
64
65void
66_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
67 CODE: 74 CODE:
68 ioctl (dev, NBD_SET_BLKSIZE, size); 75 ioctl (dev, ix, arg);
69 76
70void 77void
71_set_size_blocks (int dev, unsigned long nblocks) 78_print_debug (int dev)
72 CODE: 79 CODE:
73 ioctl (dev, NBD_SET_SIZE_BLOCKS, nblocks); 80 ioctl (dev, NBD_PRINT_DEBUG, 0);
74 81
75MODULE = Linux::NBD PACKAGE = Linux::NBD::Server 82MODULE = Linux::NBD PACKAGE = Linux::NBD::Server
76 83
77void 84void
78_one_request (SV *obj, int fd) 85_one_request (SV *obj, int fd)
79 CODE: 86 CODE:
80 struct nbd_request req; 87{
88 struct rstate *s;
89 u64 from;
90 u32 len;
91 char *method;
92 MAGIC *mg = mg_find (SvRV (obj), PERL_MAGIC_ext);
81 93
82 if (read (fd, &req, sizeof (req)) == sizeof (req)) 94 if (!mg)
83 { 95 {
96 mg = sv_magicext (SvRV (obj), 0, PERL_MAGIC_ext, 0, 0, 0);
97 mg->mg_len = sizeof (struct rstate);
98 New (0, mg->mg_ptr, mg->mg_len, char);
99
100 ((struct rstate *)mg->mg_ptr)->req_read = 0; /* initialise the state machine */
101 }
102
103 s = (struct rstate *)mg->mg_ptr;
104
105 if (s->req_read < sizeof (struct nbd_request))
106 {
107 int res = read (fd, s->req_read + (char *)&s->req, sizeof (struct nbd_request) - s->req_read);
108
109 if (res > 0)
110 s->req_read += res;
111 else if (res == 0)
112 XSRETURN_UNDEF; /* should req->eof */
113 else if (errno != EAGAIN && errno != EWOULDBLOCK)
114 XSRETURN_UNDEF; /* should req->error */
115
116 s->data_read = 0;
117
118 if (s->req_read < sizeof (struct nbd_request))
119 XSRETURN_NO;
120 }
121
122 /* now we have a full request, so check for data */
84 if (req.magic == htonl (NBD_REQUEST_MAGIC)) 123 if (s->req.magic != htonl (NBD_REQUEST_MAGIC))
124 croak ("Linux::NBD::Server received illegal request magic %08lx - protocol error.\n", ntohl (s->req.magic));
125
126 from = ntohll (s->req.from);
127 len = ntohl (s->req.len);
128
129 switch (ntohl (s->req.type))
85 { 130 {
86 if (req.type < 2) 131 case NBD_CMD_WRITE:
132 if (!mg->mg_obj)
87 { 133 {
88 u64 from = ntohll (req.from); 134 mg->mg_flags |= MGf_REFCOUNTED;
135 mg->mg_obj = NEWSV (0, len);
136 SvPOK_only (mg->mg_obj);
137 SvCUR_set (mg->mg_obj, len);
138 }
89 139
90 PUSHMARK (SP); 140 if (s->data_read < len)
91 EXTEND (SP, 3); 141 {
92 PUSHs (obj); 142 int res = read (fd, s->data_read + SvPVX (mg->mg_obj), len - s->data_read);
93 PUSHs (sv_2mortal (newSVpvn (req.handle, sizeof (req.handle))));
94 PUSHs (sv_2mortal (sizeof (UV) < 8 && from > (0xffffffffUL)
95 ? newSVnv (from)
96 : newSVuv (from)));
97 PUSHs (sv_2mortal (newSVuv (ntohl (req.len))));
98 PUTBACK;
99 call_method (req.type ? "req_write" : "req_read", G_DISCARD);
100 SPAGAIN;
101 143
144 if (res > 0)
145 s->data_read += res;
146 else if (res == 0)
147 XSRETURN_UNDEF; /* should req->eof */
148 else if (errno != EAGAIN && errno != EWOULDBLOCK)
149 XSRETURN_UNDEF; /* should req->error */
150
151 if (s->data_read < len)
102 XSRETURN_NO; 152 XSRETURN_NO;
103 } 153 }
154
155 /* fallthrough */
156 case NBD_CMD_READ:
157 case NBD_CMD_FLUSH:
158 case NBD_CMD_TRIM:
159 case NBD_CMD_WRITE_ZEROES:
160 s->req_read = 0;
161
162 PUSHMARK (SP);
163 EXTEND (SP, 4);
164 PUSHs (obj);
165 PUSHs (sv_2mortal (newSVpvn (s->req.handle, sizeof (s->req.handle))));
166 PUSHs (sv_2mortal (sizeof (UV) < 8 && from > 0xffffffffUL
167 ? newSVnv (from)
168 : newSVuv (from)));
169
170 if (mg->mg_obj)
171 {
172 PUSHs (sv_2mortal (mg->mg_obj));
173 mg->mg_obj = 0;
174 method = "req_write";
104 } 175 }
176 else
177 {
178 PUSHs (sv_2mortal (newSVuv (len)));
179 method = s->req.type == NBD_CMD_READ ? "req_read"
180 : s->req.type == NBD_CMD_FLUSH ? "req_flush"
181 : s->req.type == NBD_CMD_TRIM ? "req_trim"
182 : s->req.type == NBD_CMD_WRITE_ZEROES ? "req_write_zeroes"
183 : (abort (), "");
184 }
185
186 break;
187
188 case NBD_CMD_DISC:
189 s->req_read = 0;
190
191 method = "req_disc";
192
193 PUSHMARK (SP);
194 XPUSHs (obj);
195
196 break;
197
198 default:
199 croak ("Linux::NBD::Server received unsupported request type %d.\n", ntohl (s->req.type));
105 } 200 }
106 201
202 PUTBACK;
203 call_method (method, G_DISCARD);
204 SPAGAIN;
205
107 XSRETURN_YES; 206 XSRETURN_YES;
207}
108 208
109SV * 209SV *
110_format_reply (SV *handle, unsigned int error = 0, SV *data = 0) 210format_reply (SV *unused, SV *handle, unsigned int error = 0, SV *data = 0)
111 CODE: 211 CODE:
212{
112 struct nbd_reply rep; 213 struct nbd_reply rep;
113 STRLEN len; 214 STRLEN len;
114 char *h = SvPV (handle, len); 215 char *h = SvPV (handle, len);
115 216
116 if (len != sizeof (rep.handle)) 217 if (len != sizeof (rep.handle))
122 223
123 RETVAL = newSVpvn ((char *)&rep, sizeof (rep)); 224 RETVAL = newSVpvn ((char *)&rep, sizeof (rep));
124 225
125 if (data && !error) 226 if (data && !error)
126 sv_catsv (RETVAL, data); 227 sv_catsv (RETVAL, data);
127 228}
128 OUTPUT: 229 OUTPUT:
129 RETVAL 230 RETVAL
130 231

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines