1 /*
2 * Copyright (C) 2021 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o.
3 *
4 * This file is part of MooseFS.
5 *
6 * MooseFS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 2 (only).
9 *
10 * MooseFS is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with MooseFS; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA
18 * or visit http://www.gnu.org/licenses/gpl-2.0.html
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdio.h>
26 #include <stddef.h>
27 #include <time.h>
28 #include <sys/types.h>
29 #include <sys/time.h>
30 #include <sys/uio.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <syslog.h>
36 #include <errno.h>
37 #include <inttypes.h>
38 #include <netinet/in.h>
39 #include <sys/resource.h>
40 #ifdef HAVE_WRITEV
41 #include <sys/uio.h>
42 #endif
43
44 #include "MFSCommunication.h"
45
46 #include "datapack.h"
47 #include "matoclserv.h"
48 #include "matocsserv.h"
49 #include "matomlserv.h"
50 #include "sessions.h"
51 #include "csdb.h"
52 #include "chunks.h"
53 #include "filesystem.h"
54 #include "openfiles.h"
55 #include "flocklocks.h"
56 #include "posixlocks.h"
57 #include "metadata.h"
58 #include "random.h"
59 #include "exports.h"
60 #include "datacachemgr.h"
61 #include "charts.h"
62 #include "chartsdata.h"
63 #include "storageclass.h"
64 #include "cfg.h"
65 #include "main.h"
66 #include "sockets.h"
67 #include "slogger.h"
68 #include "massert.h"
69 #include "clocks.h"
70 #include "missinglog.h"
71 #include "mfsstrerr.h"
72 #include "iptosesid.h"
73 #include "mfsalloc.h"
74
75 #define MaxPacketSize CLTOMA_MAXPACKETSIZE
76
77 // matoclserventry.mode
78 enum {KILL,DATA,FINISH};
79 // chunklis.type
80 enum {FUSE_WRITE,FUSE_READ,FUSE_TRUNCATE,FUSE_CREATE};
81
82 struct matoclserventry;
83
84 typedef struct out_packetstruct {
85 struct out_packetstruct *next;
86 uint8_t *startptr;
87 uint32_t bytesleft;
88 uint8_t data[1];
89 } out_packetstruct;
90
91 typedef struct in_packetstruct {
92 struct in_packetstruct *next;
93 uint32_t type,leng;
94 uint8_t data[1];
95 } in_packetstruct;
96
97 typedef struct matoclserventry {
98 uint8_t registered;
99 uint8_t mode; //0 - not active, 1 - read header, 2 - read packet
100 int sock; //socket number
101 int32_t pdescpos;
102 double lastread,lastwrite; //time of last activity
103 uint8_t input_hdr[8];
104 uint8_t *input_startptr;
105 uint32_t input_bytesleft;
106 uint8_t input_end;
107 uint8_t asize;
108 in_packetstruct *input_packet;
109 in_packetstruct *inputhead,**inputtail;
110 out_packetstruct *outputhead,**outputtail;
111 uint32_t version;
112 uint32_t peerip;
113
114 uint8_t passwordrnd[32];
115
116 // extra data used for change session parameters after "reload"
117 uint8_t *path;
118 uint8_t *info;
119 uint32_t ileng;
120 uint8_t usepassword;
121 uint8_t passwordmd5[16];
122
123 void *sesdata;
124
125 struct matoclserventry *next;
126 } matoclserventry;
127
128 //static session *sessionshead=NULL;
129 static matoclserventry *matoclservhead=NULL;
130 static int lsock;
131 static int32_t lsockpdescpos;
132
133 #define CHUNKHASHSIZE 256
134 #define CHUNKHASH(chunkid) ((chunkid)&0xFF)
135
136 #define CHUNK_WAIT_TIMEOUT 30.0
137
138 // status waiting chunks
139 typedef struct _swchunks {
140 uint64_t chunkid;
141 uint64_t prevchunkid;
142 matoclserventry *eptr;
143 uint64_t fleng;
144 uint32_t msgid;
145 uint32_t inode;
146 uint32_t indx;
147 uint32_t uid;
148 uint32_t gid;
149 uint32_t auid;
150 uint32_t agid;
151 uint8_t flags;
152 uint8_t type;
153 struct _swchunks *next;
154 } swchunks;
155
156 // lock/busy waiting chunks
157 typedef struct _lwchunks {
158 uint64_t chunkid;
159 uint64_t fleng; // TRUNCATE
160 matoclserventry *eptr;
161 double time;
162 uint32_t msgid;
163 uint32_t inode;
164 uint32_t indx; // WRITE,READ
165 uint32_t uid; // TRUNCATE
166 uint32_t gids; // TRUNCATE
167 uint32_t *gid; // TRUNCATE
168 uint32_t auid; // TRUNCATE
169 uint32_t agid; // TRUNCATE
170 uint8_t chunkopflags; // WRITE,READ
171 uint8_t flags; // TRUNCATE
172 uint8_t type;
173 uint8_t status;
174 struct _lwchunks *next;
175 } lwchunks;
176
177 static lwchunks* lwchunkshashhead[CHUNKHASHSIZE];
178 static lwchunks** lwchunkshashtail[CHUNKHASHSIZE];
179 static swchunks* swchunkshash[CHUNKHASHSIZE];
180
181
182 // from config
183 static char *ListenHost;
184 static char *ListenPort;
185 static uint8_t CreateFirstChunk;
186
187 static uint32_t stats_prcvd = 0;
188 static uint32_t stats_psent = 0;
189 static uint64_t stats_brcvd = 0;
190 static uint64_t stats_bsent = 0;
191
matoclserv_stats(uint64_t stats[5])192 void matoclserv_stats(uint64_t stats[5]) {
193 stats[0] = stats_prcvd;
194 stats[1] = stats_psent;
195 stats[2] = stats_brcvd;
196 stats[3] = stats_bsent;
197 stats_prcvd = 0;
198 stats_psent = 0;
199 stats_brcvd = 0;
200 stats_bsent = 0;
201 }
202
matoclserv_createpacket(matoclserventry * eptr,uint32_t type,uint32_t size)203 uint8_t* matoclserv_createpacket(matoclserventry *eptr,uint32_t type,uint32_t size) {
204 out_packetstruct *outpacket;
205 uint8_t *ptr;
206 uint32_t psize;
207
208 psize = size+8;
209 outpacket = malloc(offsetof(out_packetstruct,data)+psize);
210 #ifndef __clang_analyzer__
211 passert(outpacket);
212 // clang analyzer has problem with testing for (void*)(-1) which is needed for memory allocated by mmap
213 #endif
214 outpacket->bytesleft = psize;
215 ptr = outpacket->data;
216 put32bit(&ptr,type);
217 put32bit(&ptr,size);
218 outpacket->startptr = outpacket->data;
219 outpacket->next = NULL;
220 *(eptr->outputtail) = outpacket;
221 eptr->outputtail = &(outpacket->next);
222 return ptr;
223 }
224
225 void matoclserv_fuse_chunk_has_changed(matoclserventry *eptr,uint32_t inode,uint32_t chindx,uint64_t chunkid,uint32_t version,uint64_t fleng,uint8_t truncateflag);
226
227 void matoclserv_fuse_fleng_has_changed(matoclserventry *eptr,uint32_t inode,uint64_t fleng);
228
matoclserv_fuse_write_chunk_common(matoclserventry * eptr,uint32_t msgid,uint32_t inode,uint32_t indx,uint8_t chunkopflags)229 static inline int matoclserv_fuse_write_chunk_common(matoclserventry *eptr,uint32_t msgid,uint32_t inode,uint32_t indx,uint8_t chunkopflags) {
230 uint8_t *ptr;
231 uint8_t status;
232 uint64_t fleng;
233 uint64_t prevchunkid;
234 uint64_t chunkid;
235 uint8_t opflag;
236 swchunks *swc;
237 lwchunks *lwc;
238 uint32_t i;
239 uint32_t version;
240 uint8_t count;
241 uint8_t cs_data[100*14];
242
243 if (sessions_get_disables(eptr->sesdata)&DISABLE_WRITE) {
244 status = MFS_ERROR_EPERM;
245 } else if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_READONLY) {
246 if (eptr->version>=VERSION2INT(3,0,101)) {
247 status = MFS_ERROR_EROFS;
248 } else {
249 status = MFS_ERROR_IO;
250 }
251 } else {
252 status = fs_writechunk(inode,indx,chunkopflags,&prevchunkid,&chunkid,&fleng,&opflag,eptr->peerip);
253 }
254 if (status!=MFS_STATUS_OK) {
255 if (status==MFS_ERROR_LOCKED || status==MFS_ERROR_CHUNKBUSY) {
256 i = CHUNKHASH(prevchunkid);
257 lwc = malloc(sizeof(lwchunks));
258 passert(lwc);
259 lwc->chunkid = prevchunkid;
260 lwc->eptr = eptr;
261 lwc->time = monotonic_seconds();
262 lwc->msgid = msgid;
263 lwc->inode = inode;
264 lwc->indx = indx;
265 lwc->chunkopflags = chunkopflags;
266 lwc->type = FUSE_WRITE;
267 lwc->status = status;
268 lwc->next = NULL;
269 *(lwchunkshashtail[i]) = lwc;
270 lwchunkshashtail[i] = &(lwc->next);
271 return 1;
272 }
273 if (status==MFS_ERROR_EAGAIN && eptr->version<VERSION2INT(3,0,8)) {
274 status = MFS_ERROR_LOCKED;
275 }
276 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
277 put32bit(&ptr,msgid);
278 put8bit(&ptr,status);
279 return 0;
280 } else {
281 sessions_inc_stats(eptr->sesdata,15);
282 }
283 if (opflag) { // wait for operation end
284 i = CHUNKHASH(chunkid);
285 swc = malloc(sizeof(swchunks));
286 passert(swc);
287 swc->eptr = eptr;
288 swc->inode = inode;
289 swc->indx = indx;
290 swc->prevchunkid = prevchunkid;
291 swc->chunkid = chunkid;
292 swc->msgid = msgid;
293 swc->fleng = fleng;
294 swc->type = FUSE_WRITE;
295 swc->next = swchunkshash[i];
296 swchunkshash[i] = swc;
297 } else { // return status immediately
298 dcm_modify(inode,sessions_get_id(eptr->sesdata));
299 if (eptr->version>=VERSION2INT(3,0,10)) {
300 status = chunk_get_version_and_csdata(2,chunkid,eptr->peerip,&version,&count,cs_data);
301 } else if (eptr->version>=VERSION2INT(1,7,32)) {
302 status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
303 } else {
304 status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
305 }
306 if (status!=MFS_STATUS_OK) {
307 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
308 put32bit(&ptr,msgid);
309 put8bit(&ptr,status);
310 fs_writeend(0,0,chunkid,0,NULL); // ignore status - just do it.
311 return 0;
312 }
313 if (eptr->version>=VERSION2INT(3,0,10)) {
314 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*14);
315 } else if (eptr->version>=VERSION2INT(1,7,32)) {
316 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*10);
317 } else {
318 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,24+count*6);
319 }
320 put32bit(&ptr,msgid);
321 if (eptr->version>=VERSION2INT(3,0,10)) {
322 put8bit(&ptr,2);
323 } else if (eptr->version>=VERSION2INT(1,7,32)) {
324 put8bit(&ptr,1);
325 }
326 put64bit(&ptr,fleng);
327 put64bit(&ptr,chunkid);
328 put32bit(&ptr,version);
329 if (count>0) {
330 if (eptr->version>=VERSION2INT(3,0,10)) {
331 memcpy(ptr,cs_data,count*14);
332 } else if (eptr->version>=VERSION2INT(1,7,32)) {
333 memcpy(ptr,cs_data,count*10);
334 } else {
335 memcpy(ptr,cs_data,count*6);
336 }
337 }
338 matoclserv_fuse_chunk_has_changed(eptr,inode,indx,chunkid,version,fleng,0);
339 }
340 return 0;
341 }
342
matoclserv_fuse_read_chunk_common(matoclserventry * eptr,uint32_t msgid,uint32_t inode,uint32_t indx,uint8_t chunkopflags)343 static inline int matoclserv_fuse_read_chunk_common(matoclserventry *eptr,uint32_t msgid,uint32_t inode,uint32_t indx,uint8_t chunkopflags) {
344 uint8_t *ptr;
345 uint8_t status;
346 uint64_t chunkid;
347 uint64_t fleng;
348 uint32_t version;
349 lwchunks *lwc;
350 uint32_t i;
351 uint8_t count;
352 uint8_t cs_data[100*14];
353
354 if (sessions_get_disables(eptr->sesdata)&DISABLE_READ) {
355 status = MFS_ERROR_EPERM;
356 } else {
357 status = fs_readchunk(inode,indx,chunkopflags,&chunkid,&fleng);
358 }
359 if (status!=MFS_STATUS_OK) {
360 if (status==MFS_ERROR_LOCKED || status==MFS_ERROR_CHUNKBUSY) {
361 i = CHUNKHASH(chunkid);
362 lwc = malloc(sizeof(lwchunks));
363 passert(lwc);
364 lwc->chunkid = chunkid;
365 lwc->eptr = eptr;
366 lwc->time = monotonic_seconds();
367 lwc->msgid = msgid;
368 lwc->inode = inode;
369 lwc->indx = indx;
370 lwc->chunkopflags = chunkopflags;
371 lwc->type = FUSE_READ;
372 lwc->status = status;
373 lwc->next = NULL;
374 *(lwchunkshashtail[i]) = lwc;
375 lwchunkshashtail[i] = &(lwc->next);
376 return 1;
377 }
378 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,5);
379 put32bit(&ptr,msgid);
380 put8bit(&ptr,status);
381 return 0;
382 } else {
383 sessions_inc_stats(eptr->sesdata,14);
384 if (chunkid>0) {
385 if (eptr->version>=VERSION2INT(3,0,10)) {
386 status = chunk_get_version_and_csdata(2,chunkid,eptr->peerip,&version,&count,cs_data);
387 } else if (eptr->version>=VERSION2INT(1,7,32)) {
388 status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
389 } else {
390 status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
391 }
392 } else {
393 version = 0;
394 count = 0;
395 }
396 }
397 if (status!=MFS_STATUS_OK) {
398 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,5);
399 put32bit(&ptr,msgid);
400 put8bit(&ptr,status);
401 return 0;
402 }
403 dcm_access(inode,sessions_get_id(eptr->sesdata));
404 if (eptr->version>=VERSION2INT(3,0,10)) {
405 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,25+count*14);
406 } else if (eptr->version>=VERSION2INT(1,7,32)) {
407 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,25+count*10);
408 } else {
409 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,24+count*6);
410 }
411 put32bit(&ptr,msgid);
412 if (eptr->version>=VERSION2INT(3,0,10)) {
413 put8bit(&ptr,2);
414 } else if (eptr->version>=VERSION2INT(1,7,32)) {
415 put8bit(&ptr,1);
416 }
417 put64bit(&ptr,fleng);
418 put64bit(&ptr,chunkid);
419 put32bit(&ptr,version);
420 if (count>0) {
421 if (eptr->version>=VERSION2INT(3,0,10)) {
422 memcpy(ptr,cs_data,count*14);
423 } else if (eptr->version>=VERSION2INT(1,7,32)) {
424 memcpy(ptr,cs_data,count*10);
425 } else {
426 memcpy(ptr,cs_data,count*6);
427 }
428 }
429 return 0;
430 }
431
matoclserv_fuse_truncate_common(matoclserventry * eptr,uint32_t msgid,uint32_t inode,uint8_t flags,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t auid,uint32_t agid,uint64_t fleng)432 static inline int matoclserv_fuse_truncate_common(matoclserventry *eptr,uint32_t msgid,uint32_t inode,uint8_t flags,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t auid,uint32_t agid,uint64_t fleng) {
433 uint32_t indx;
434 uint32_t i;
435 uint8_t attr[ATTR_RECORD_SIZE];
436 uint8_t *ptr;
437 uint8_t status;
438 uint64_t prevlength;
439 uint64_t prevchunkid;
440 uint32_t disables;
441 swchunks *swc;
442 lwchunks *lwc;
443 uint64_t chunkid;
444 // uint8_t locked;
445
446 status = MFS_STATUS_OK;
447 disables = sessions_get_disables(eptr->sesdata);
448 if (flags & (TRUNCATE_FLAG_RESERVE|TRUNCATE_FLAG_UPDATE)) { // part of write - not actual truncate
449 if (disables&DISABLE_WRITE) {
450 status = MFS_ERROR_EPERM;
451 }
452 } else {
453 if ((disables&(DISABLE_TRUNCATE|DISABLE_SETLENGTH))==(DISABLE_TRUNCATE|DISABLE_SETLENGTH)) {
454 status = MFS_ERROR_EPERM;
455 }
456 }
457 if (status==MFS_STATUS_OK) {
458 status = fs_try_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,flags,uid,gids,gid,((disables&DISABLE_TRUNCATE)?1:0)|((disables&DISABLE_SETLENGTH)?2:0),fleng,&indx,&prevchunkid,&chunkid);
459 }
460 if (status==MFS_ERROR_DELAYED) {
461 i = CHUNKHASH(chunkid);
462 swc = malloc(sizeof(swchunks));
463 passert(swc);
464 swc->chunkid = chunkid;
465 swc->prevchunkid = prevchunkid;
466 swc->eptr = eptr;
467 swc->msgid = msgid;
468 swc->inode = inode;
469 swc->indx = indx;
470 swc->uid = uid;
471 swc->gid = gid[0];
472 swc->auid = auid;
473 swc->agid = agid;
474 swc->fleng = fleng;
475 swc->flags = flags;
476 swc->type = FUSE_TRUNCATE;
477 swc->next = swchunkshash[i];
478 swchunkshash[i] = swc;
479 sessions_inc_stats(eptr->sesdata,2);
480 return 0;
481 }
482 if (status==MFS_ERROR_LOCKED || status==MFS_ERROR_CHUNKBUSY) {
483 // locked = 1;
484 i = CHUNKHASH(prevchunkid);
485 lwc = malloc(sizeof(lwchunks)+sizeof(uint32_t)*gids);
486 passert(lwc);
487 lwc->chunkid = prevchunkid;
488 lwc->fleng = fleng;
489 lwc->eptr = eptr;
490 lwc->status = status;
491 lwc->time = monotonic_seconds();
492 lwc->msgid = msgid;
493 lwc->inode = inode;
494 lwc->indx = indx;
495 lwc->uid = uid;
496 lwc->gids = gids;
497 lwc->gid = (uint32_t*)(((uint8_t*)lwc)+sizeof(lwchunks));
498 memcpy(lwc->gid,gid,sizeof(uint32_t)*gids);
499 lwc->auid = auid;
500 lwc->agid = agid;
501 lwc->flags = flags;
502 lwc->type = FUSE_TRUNCATE;
503 lwc->status = status;
504 lwc->next = NULL;
505 *(lwchunkshashtail[i]) = lwc;
506 lwchunkshashtail[i] = &(lwc->next);
507 return 1;
508 // } else {
509 // locked = 0;
510 }
511 if (status==MFS_STATUS_OK) {
512 status = fs_do_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,flags,uid,gid[0],auid,agid,fleng,attr,&prevlength);
513 }
514 if (status==MFS_STATUS_OK && (flags & TRUNCATE_FLAG_UPDATE)==0) {
515 dcm_modify(inode,sessions_get_id(eptr->sesdata));
516 }
517 if (status!=MFS_STATUS_OK) {
518 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,5);
519 put32bit(&ptr,msgid);
520 put8bit(&ptr,status);
521 } else {
522 if (eptr->version>=VERSION2INT(3,0,113)) {
523 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,(eptr->asize+12));
524 } else {
525 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,(eptr->asize+4));
526 }
527 put32bit(&ptr,msgid);
528 if (eptr->version>=VERSION2INT(3,0,113)) {
529 put64bit(&ptr,prevlength);
530 }
531 memcpy(ptr,attr,eptr->asize);
532 if (flags & TRUNCATE_FLAG_RESERVE) {
533 fleng += prevlength;
534 }
535 matoclserv_fuse_fleng_has_changed(eptr,inode,fleng);
536 }
537 sessions_inc_stats(eptr->sesdata,2);
538 return 0;
539 }
540
matoclserv_chunk_unlocked(uint64_t chunkid,void * cptr)541 void matoclserv_chunk_unlocked(uint64_t chunkid,void *cptr) {
542 lwchunks *lwc,**plwc;
543 uint8_t locked;
544
545 plwc = lwchunkshashhead + CHUNKHASH(chunkid);
546 while ((lwc = *plwc)) {
547 if (lwc->chunkid == chunkid && lwc->eptr->mode==DATA) {
548 if (lwc->type == FUSE_TRUNCATE) {
549 locked = matoclserv_fuse_truncate_common(lwc->eptr,lwc->msgid,lwc->inode,lwc->flags,lwc->uid,lwc->gids,lwc->gid,lwc->auid,lwc->agid,lwc->fleng);
550 } else if (lwc->type == FUSE_WRITE) {
551 locked = matoclserv_fuse_write_chunk_common(lwc->eptr,lwc->msgid,lwc->inode,lwc->indx,lwc->chunkopflags);
552 } else if (lwc->type == FUSE_READ) {
553 locked = matoclserv_fuse_read_chunk_common(lwc->eptr,lwc->msgid,lwc->inode,lwc->indx,lwc->chunkopflags);
554 } else {
555 locked = 0;
556 }
557 *plwc = lwc->next;
558 free(lwc);
559 if (locked || chunk_locked_or_busy(cptr)) {
560 break;
561 }
562 } else {
563 plwc = &(lwc->next);
564 }
565 }
566 if (*plwc==NULL) {
567 lwchunkshashtail[CHUNKHASH(chunkid)] = plwc;
568 }
569 }
570
matoclserv_timeout_waiting_ops(void)571 void matoclserv_timeout_waiting_ops(void) {
572 lwchunks *lwc,**plwc;
573 uint8_t *ptr;
574 uint32_t i;
575 double curtime;
576
577 curtime = monotonic_seconds();
578 for (i=0 ; i<CHUNKHASHSIZE ; i++) {
579 plwc = lwchunkshashhead + i;
580 while ((lwc = *plwc)) {
581 if (lwc->time + CHUNK_WAIT_TIMEOUT < curtime) {
582 if (lwc->type == FUSE_TRUNCATE) {
583 ptr = matoclserv_createpacket(lwc->eptr,MATOCL_FUSE_TRUNCATE,5);
584 put32bit(&ptr,lwc->msgid);
585 put8bit(&ptr,lwc->status);
586 } else if (lwc->type == FUSE_WRITE) {
587 ptr = matoclserv_createpacket(lwc->eptr,MATOCL_FUSE_WRITE_CHUNK,5);
588 put32bit(&ptr,lwc->msgid);
589 put8bit(&ptr,lwc->status);
590 } else if (lwc->type == FUSE_READ) {
591 ptr = matoclserv_createpacket(lwc->eptr,MATOCL_FUSE_READ_CHUNK,5);
592 put32bit(&ptr,lwc->msgid);
593 put8bit(&ptr,lwc->status);
594 }
595 *plwc = lwc->next;
596 free(lwc);
597 } else {
598 plwc = &(lwc->next);
599 }
600 }
601 lwchunkshashtail[i] = plwc;
602 }
603 }
604
matoclserv_chunk_status(uint64_t chunkid,uint8_t status)605 void matoclserv_chunk_status(uint64_t chunkid,uint8_t status) {
606 uint32_t msgid,inode,indx,uid,gid,auid,agid;
607 uint64_t fleng,prevchunkid,prevlength;
608 uint8_t flags,type,attr[ATTR_RECORD_SIZE];
609 uint32_t version;
610 uint8_t *ptr;
611 uint8_t count;
612 uint8_t cs_data[100*14];
613 matoclserventry *eptr;
614 swchunks *swc,**pswc;
615
616 eptr = NULL;
617 prevchunkid = 0;
618 msgid = 0;
619 fleng = 0;
620 type = 0;
621 inode = 0;
622 indx = 0;
623 uid = 0;
624 gid = 0;
625 auid = 0;
626 agid = 0;
627 flags = 0;
628 pswc = swchunkshash + CHUNKHASH(chunkid);
629 while ((swc = *pswc)) {
630 if (swc->chunkid == chunkid) {
631 eptr = swc->eptr;
632 prevchunkid = swc->prevchunkid;
633 msgid = swc->msgid;
634 fleng = swc->fleng;
635 type = swc->type;
636 flags = swc->flags;
637 inode = swc->inode;
638 indx = swc->indx;
639 uid = swc->uid;
640 gid = swc->gid;
641 auid = swc->auid;
642 agid = swc->agid;
643 *pswc = swc->next;
644 free(swc);
645 break;
646 } else {
647 pswc = &(swc->next);
648 }
649 }
650
651 if (!eptr) {
652 // syslog(LOG_WARNING,"got chunk status, but don't want it");
653 return;
654 }
655 if (eptr->mode!=DATA) {
656 return;
657 }
658 if (status==MFS_STATUS_OK && type!=FUSE_CREATE) {
659 dcm_modify(inode,sessions_get_id(eptr->sesdata));
660 }
661 switch (type) {
662 case FUSE_CREATE:
663 if (status==MFS_STATUS_OK) { // just unlock this chunk
664 fs_writeend(inode,0,chunkid,0,NULL);
665 }
666 return;
667 case FUSE_WRITE:
668 if (status==MFS_STATUS_OK) {
669 if (eptr->version>=VERSION2INT(3,0,10)) {
670 status = chunk_get_version_and_csdata(2,chunkid,eptr->peerip,&version,&count,cs_data);
671 } else if (eptr->version>=VERSION2INT(1,7,32)) {
672 status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
673 } else {
674 status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
675 }
676 //syslog(LOG_NOTICE,"get version for chunk %"PRIu64" -> %"PRIu32,chunkid,version);
677 }
678 if (status!=MFS_STATUS_OK) {
679 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
680 put32bit(&ptr,msgid);
681 put8bit(&ptr,status);
682 fs_rollback(inode,indx,prevchunkid,chunkid); // ignore status - it's error anyway
683 return;
684 }
685 if (eptr->version>=VERSION2INT(3,0,10)) {
686 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*14);
687 } else if (eptr->version>=VERSION2INT(1,7,32)) {
688 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*10);
689 } else {
690 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,24+count*6);
691 }
692 put32bit(&ptr,msgid);
693 if (eptr->version>=VERSION2INT(3,0,10)) {
694 put8bit(&ptr,2);
695 } else if (eptr->version>=VERSION2INT(1,7,32)) {
696 put8bit(&ptr,1);
697 }
698 put64bit(&ptr,fleng);
699 put64bit(&ptr,chunkid);
700 put32bit(&ptr,version);
701 if (count>0) {
702 if (eptr->version>=VERSION2INT(3,0,10)) {
703 memcpy(ptr,cs_data,count*14);
704 } else if (eptr->version>=VERSION2INT(1,7,32)) {
705 memcpy(ptr,cs_data,count*10);
706 } else {
707 memcpy(ptr,cs_data,count*6);
708 }
709 }
710 matoclserv_fuse_chunk_has_changed(eptr,inode,indx,chunkid,version,fleng,0);
711 // for (i=0 ; i<count ; i++) {
712 // if (matocsserv_getlocation(sptr[i],&ip,&port)<0) {
713 // put32bit(&ptr,0);
714 // put16bit(&ptr,0);
715 // } else {
716 // put32bit(&ptr,ip);
717 // put16bit(&ptr,port);
718 // }
719 // }
720 return;
721 case FUSE_TRUNCATE:
722 if (status!=MFS_STATUS_OK) {
723 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,5);
724 put32bit(&ptr,msgid);
725 put8bit(&ptr,status);
726 fs_rollback(inode,indx,prevchunkid,chunkid); // ignore status - it's error anyway
727 return;
728 }
729 fs_end_setlength(chunkid); // chunk unlock
730 status = fs_do_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,flags,uid,gid,auid,agid,fleng,attr,&prevlength);
731 if (status!=MFS_STATUS_OK) {
732 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,5);
733 put32bit(&ptr,msgid);
734 put8bit(&ptr,status);
735 return;
736 }
737 if (eptr->version>=VERSION2INT(3,0,113)) {
738 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,eptr->asize+12);
739 } else {
740 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,eptr->asize+4);
741 }
742 put32bit(&ptr,msgid);
743 if (eptr->version>=VERSION2INT(3,0,113)) {
744 put64bit(&ptr,prevlength);
745 }
746 memcpy(ptr,attr,eptr->asize);
747 chunk_get_version(chunkid,&version);
748 if (flags & TRUNCATE_FLAG_RESERVE) {
749 fleng += prevlength;
750 }
751 matoclserv_fuse_chunk_has_changed(eptr,inode,indx,chunkid,version,fleng,1);
752 return;
753 default:
754 syslog(LOG_WARNING,"got chunk status, but operation type is unknown");
755 }
756 }
757
matoclserv_cserv_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)758 void matoclserv_cserv_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
759 uint8_t *ptr;
760 (void)data;
761 if (length!=0) {
762 syslog(LOG_NOTICE,"CLTOMA_CSERV_LIST - wrong size (%"PRIu32"/0)",length);
763 eptr->mode = KILL;
764 return;
765 }
766 ptr = matoclserv_createpacket(eptr,MATOCL_CSERV_LIST,csdb_servlist_size());
767 csdb_servlist_data(ptr);
768 }
769
matoclserv_cserv_command(matoclserventry * eptr,const uint8_t * data,uint32_t length)770 void matoclserv_cserv_command(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
771 uint32_t ip;
772 uint16_t port;
773 uint8_t cmd,status;
774 uint8_t *ptr;
775 if (length!=6 && length!=7) {
776 syslog(LOG_NOTICE,"CLTOMA_CSSERV_COMMAND - wrong size (%"PRIu32"/6|7)",length);
777 eptr->mode = KILL;
778 return;
779 }
780 if (length==7) {
781 cmd = get8bit(&data);
782 } else {
783 cmd = MFS_CSSERV_COMMAND_REMOVE;
784 }
785 ip = get32bit(&data);
786 port = get16bit(&data);
787 status = MFS_ERROR_EINVAL;
788 if (cmd==MFS_CSSERV_COMMAND_REMOVE) {
789 status = csdb_remove_server(ip,port);
790 } else if (cmd==MFS_CSSERV_COMMAND_BACKTOWORK) {
791 status = csdb_back_to_work(ip,port);
792 } else if (cmd==MFS_CSSERV_COMMAND_MAINTENANCEON) {
793 status = csdb_maintenance(ip,port,1);
794 } else if (cmd==MFS_CSSERV_COMMAND_MAINTENANCEOFF) {
795 status = csdb_maintenance(ip,port,0);
796 }
797 if (length==6) {
798 matoclserv_createpacket(eptr,MATOCL_CSSERV_COMMAND,0);
799 } else {
800 ptr = matoclserv_createpacket(eptr,MATOCL_CSSERV_COMMAND,1);
801 put8bit(&ptr,status);
802 }
803 }
804
matoclserv_session_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)805 void matoclserv_session_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
806 uint8_t *ptr;
807 uint32_t size;
808 uint8_t vmode;
809 (void)data;
810 if (length!=0 && length!=1) {
811 syslog(LOG_NOTICE,"CLTOMA_SESSION_LIST - wrong size (%"PRIu32"/0)",length);
812 eptr->mode = KILL;
813 return;
814 }
815 if (length==0) {
816 vmode = 0;
817 } else {
818 vmode = get8bit(&data);
819 }
820 size = sessions_datasize(vmode);
821 ptr = matoclserv_createpacket(eptr,MATOCL_SESSION_LIST,size);
822 sessions_datafill(ptr,vmode);
823 }
824
matoclserv_session_command(matoclserventry * eptr,const uint8_t * data,uint32_t length)825 void matoclserv_session_command(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
826 uint32_t sessionid;
827 uint8_t cmd,status;
828 uint8_t *ptr;
829 if (length!=5) {
830 syslog(LOG_NOTICE,"CLTOMA_SESSION_COMMAND - wrong size (%"PRIu32"/5)",length);
831 eptr->mode = KILL;
832 return;
833 }
834 cmd = get8bit(&data);
835 sessionid = get32bit(&data);
836 if (cmd==MFS_SESSION_COMMAND_REMOVE) {
837 status = sessions_force_remove(sessionid);
838 } else {
839 status = MFS_ERROR_EINVAL;
840 }
841 ptr = matoclserv_createpacket(eptr,MATOCL_SESSION_COMMAND,1);
842 put8bit(&ptr,status);
843 }
844
matoclserv_chart(matoclserventry * eptr,const uint8_t * data,uint32_t length)845 void matoclserv_chart(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
846 uint32_t chartid;
847 uint8_t *ptr;
848 uint32_t l;
849 uint16_t w,h;
850
851 if (length!=4 && length!=8) {
852 syslog(LOG_NOTICE,"CLTOAN_CHART - wrong size (%"PRIu32"/4|8)",length);
853 eptr->mode = KILL;
854 return;
855 }
856 chartid = get32bit(&data);
857 if (length==8) {
858 w = get16bit(&data);
859 h = get16bit(&data);
860 } else {
861 w = 0;
862 h = 0;
863 }
864 l = charts_make_png(chartid,w,h);
865 ptr = matoclserv_createpacket(eptr,ANTOCL_CHART,l);
866 if (l>0) {
867 charts_get_png(ptr);
868 }
869 }
870
matoclserv_chart_data(matoclserventry * eptr,const uint8_t * data,uint32_t length)871 void matoclserv_chart_data(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
872 uint32_t chartid;
873 uint32_t maxentries;
874 uint8_t *ptr;
875 uint32_t l;
876
877 if (length!=4 && length!=8) {
878 syslog(LOG_NOTICE,"CLTOAN_CHART_DATA - wrong size (%"PRIu32"/4|8)",length);
879 eptr->mode = KILL;
880 return;
881 }
882 chartid = get32bit(&data);
883 if (length==8) {
884 maxentries = get32bit(&data);
885 } else {
886 maxentries = UINT32_C(0xFFFFFFFF);
887 }
888 l = charts_makedata(NULL,chartid,maxentries);
889 ptr = matoclserv_createpacket(eptr,ANTOCL_CHART_DATA,l);
890 if (l>0) {
891 charts_makedata(ptr,chartid,maxentries);
892 }
893 }
894
matoclserv_monotonic_data(matoclserventry * eptr,const uint8_t * data,uint32_t length)895 void matoclserv_monotonic_data(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
896 uint8_t *ptr;
897 uint32_t l;
898
899 (void)data;
900 if (length!=0) {
901 syslog(LOG_NOTICE,"CLTOAN_MONOTONIC_DATA - wrong size (%"PRIu32"/0)",length);
902 eptr->mode = KILL;
903 return;
904 }
905 l = charts_monotonic_data(NULL);
906 ptr = matoclserv_createpacket(eptr,ANTOCL_MONOTONIC_DATA,l);
907 if (l>0) {
908 charts_monotonic_data(ptr);
909 }
910 }
911
matoclserv_get_version(matoclserventry * eptr,const uint8_t * data,uint32_t length)912 void matoclserv_get_version(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
913 uint32_t msgid = 0;
914 uint8_t *ptr;
915 static const char vstring[] = VERSSTR;
916 if (length!=0 && length!=4) {
917 syslog(LOG_NOTICE,"ANTOAN_GET_VERSION - wrong size (%"PRIu32"/4|0)",length);
918 eptr->mode = KILL;
919 return;
920 }
921 if (length==4) {
922 msgid = get32bit(&data);
923 ptr = matoclserv_createpacket(eptr,ANTOAN_VERSION,4+4+strlen(vstring));
924 put32bit(&ptr,msgid);
925 } else {
926 ptr = matoclserv_createpacket(eptr,ANTOAN_VERSION,4+strlen(vstring));
927 }
928 put16bit(&ptr,VERSMAJ);
929 put8bit(&ptr,VERSMID);
930 put8bit(&ptr,VERSMIN);
931 memcpy(ptr,vstring,strlen(vstring));
932 }
933
matoclserv_get_config(matoclserventry * eptr,const uint8_t * data,uint32_t length)934 void matoclserv_get_config(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
935 uint32_t msgid;
936 char name[256];
937 uint8_t nleng;
938 uint32_t vleng;
939 char *val;
940 uint8_t *ptr;
941
942 if (length<5) {
943 syslog(LOG_NOTICE,"ANTOAN_GET_CONFIG - wrong size (%"PRIu32")",length);
944 eptr->mode = KILL;
945 return;
946 }
947 msgid = get32bit(&data);
948 nleng = get8bit(&data);
949 if (length!=5U+(uint32_t)nleng) {
950 syslog(LOG_NOTICE,"ANTOAN_GET_CONFIG - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
951 eptr->mode = KILL;
952 return;
953 }
954 memcpy(name,data,nleng);
955 name[nleng] = 0;
956 val = cfg_getstr(name,"");
957 vleng = strlen(val);
958 if (vleng>255) {
959 vleng=255;
960 }
961 ptr = matoclserv_createpacket(eptr,ANTOAN_CONFIG_VALUE,5+vleng);
962 put32bit(&ptr,msgid);
963 put8bit(&ptr,vleng);
964 memcpy(ptr,val,vleng);
965 }
966
matoclserv_module_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)967 void matoclserv_module_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
968 uint32_t msgid = 0;
969 uint8_t *ptr;
970
971 if (length!=0 && length!=4) {
972 syslog(LOG_NOTICE,"ANTOAN_GET_VERSION - wrong size (%"PRIu32"/4|0)",length);
973 eptr->mode = KILL;
974 return;
975 }
976 if (length==4) {
977 msgid = get32bit(&data);
978 ptr = matoclserv_createpacket(eptr,ANTOCL_MODULE_INFO,25);
979 put32bit(&ptr,msgid);
980 } else {
981 ptr = matoclserv_createpacket(eptr,ANTOCL_MODULE_INFO,21);
982 }
983 put8bit(&ptr,MODULE_TYPE_MASTER);
984 put16bit(&ptr,VERSMAJ);
985 put8bit(&ptr,VERSMID);
986 put8bit(&ptr,VERSMIN);
987 put16bit(&ptr,0);
988 put64bit(&ptr,meta_get_id());
989 put32bit(&ptr,0);
990 put16bit(&ptr,0);
991 }
992
matoclserv_list_open_files(matoclserventry * eptr,const uint8_t * data,uint32_t length)993 void matoclserv_list_open_files(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
994 uint32_t msgid = 0;
995 uint32_t sessionid;
996 uint32_t size;
997 uint8_t *ptr;
998
999 if (length!=4 && length!=8) {
1000 syslog(LOG_NOTICE,"CLTOMA_LIST_OPEN_FILES - wrong size (%"PRIu32"/4|8)",length);
1001 eptr->mode = KILL;
1002 return;
1003 }
1004 if (length==8) {
1005 msgid = get32bit(&data);
1006 }
1007 sessionid = get32bit(&data);
1008 size = of_lsof(sessionid,NULL);
1009 if (length==8) {
1010 ptr = matoclserv_createpacket(eptr,MATOCL_LIST_OPEN_FILES,4+size);
1011 put32bit(&ptr,msgid);
1012 } else {
1013 ptr = matoclserv_createpacket(eptr,MATOCL_LIST_OPEN_FILES,size);
1014 }
1015 of_lsof(sessionid,ptr);
1016 }
1017
matoclserv_list_acquired_locks(matoclserventry * eptr,const uint8_t * data,uint32_t length)1018 void matoclserv_list_acquired_locks(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1019 uint32_t msgid = 0;
1020 uint32_t inode;
1021 uint32_t size;
1022 uint8_t *ptr;
1023
1024 if (length!=4 && length!=8) {
1025 syslog(LOG_NOTICE,"CLTOMA_LIST_ACQUIRED_LOCKS - wrong size (%"PRIu32"/4|8)",length);
1026 eptr->mode = KILL;
1027 return;
1028 }
1029 if (length==8) {
1030 msgid = get32bit(&data);
1031 }
1032 inode = get32bit(&data);
1033 size = posix_lock_list(inode,NULL) + flock_list(inode,NULL);
1034 if (length==8) {
1035 ptr = matoclserv_createpacket(eptr,MATOCL_LIST_ACQUIRED_LOCKS,4+size);
1036 put32bit(&ptr,msgid);
1037 } else {
1038 ptr = matoclserv_createpacket(eptr,MATOCL_LIST_ACQUIRED_LOCKS,size);
1039 }
1040 posix_lock_list(inode,ptr);
1041 flock_list(inode,ptr);
1042 }
1043
matoclserv_mass_resolve_paths(matoclserventry * eptr,const uint8_t * data,uint32_t length)1044 void matoclserv_mass_resolve_paths(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1045 static uint32_t *inodetab = NULL;
1046 static uint32_t *psizetab = NULL;
1047 static uint32_t tabsleng = 0;
1048 uint32_t i,j;
1049 uint32_t totalsize;
1050 uint32_t psize;
1051 uint8_t *ptr;
1052
1053 if ((length%4)!=0) {
1054 syslog(LOG_NOTICE,"CLTOMA_MASS_RESOLVE_PATHS - wrong size (%"PRIu32"/N*4)",length);
1055 eptr->mode = KILL;
1056 return;
1057 }
1058 length>>=2;
1059 if (length>tabsleng) {
1060 if (inodetab) {
1061 free(inodetab);
1062 }
1063 if (psizetab) {
1064 free(psizetab);
1065 }
1066 tabsleng = ((length+0xFF)&0xFFFFFF00);
1067 inodetab = malloc(sizeof(uint32_t)*tabsleng);
1068 passert(inodetab);
1069 psizetab = malloc(sizeof(uint32_t)*tabsleng);
1070 passert(psizetab);
1071 }
1072 j = 0;
1073 totalsize = 0;
1074 while (length>0) {
1075 i = get32bit(&data);
1076 if (i>0) {
1077 fs_get_paths_size(MFS_ROOT_ID,i,&psize);
1078 inodetab[j] = i;
1079 psizetab[j] = psize;
1080 j++;
1081 totalsize += 8 + psize;
1082 }
1083 length--;
1084 }
1085 ptr = matoclserv_createpacket(eptr,MATOCL_MASS_RESOLVE_PATHS,totalsize);
1086 for (i=0 ; i<j ; i++) {
1087 put32bit(&ptr,inodetab[i]);
1088 put32bit(&ptr,psizetab[i]);
1089 fs_get_paths_data(MFS_ROOT_ID,inodetab[i],ptr);
1090 ptr+=psizetab[i];
1091 }
1092 }
1093
matoclserv_sclass_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1094 void matoclserv_sclass_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1095 uint8_t *ptr;
1096 if (length!=0) {
1097 syslog(LOG_NOTICE,"CLTOMA_SCLASS_INFO - wrong size (%"PRIu32"/0)",length);
1098 eptr->mode = KILL;
1099 return;
1100 }
1101 (void)data;
1102 ptr = matoclserv_createpacket(eptr,MATOCL_SCLASS_INFO,sclass_info(NULL));
1103 sclass_info(ptr);
1104 }
1105
matoclserv_missing_chunks(matoclserventry * eptr,const uint8_t * data,uint32_t length)1106 void matoclserv_missing_chunks(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1107 uint8_t *ptr;
1108 uint8_t mode;
1109 if (length!=0 && length!=1) {
1110 syslog(LOG_NOTICE,"CLTOMA_MISSING_CHUNKS - wrong size (%"PRIu32"/0|1)",length);
1111 eptr->mode = KILL;
1112 return;
1113 }
1114 if (length==1) {
1115 mode = get8bit(&data);
1116 } else {
1117 mode = 0;
1118 }
1119 ptr = matoclserv_createpacket(eptr,MATOCL_MISSING_CHUNKS,missing_log_getdata(NULL,mode));
1120 missing_log_getdata(ptr,mode);
1121 }
1122
matoclserv_node_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1123 void matoclserv_node_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1124 uint8_t *ptr;
1125 uint32_t inode;
1126 uint32_t maxentries;
1127 uint64_t continueid;
1128 uint32_t msgid;
1129
1130 if (length!=16 && length!=20) {
1131 syslog(LOG_NOTICE,"CLTOMA_NODE_INFO - wrong size (%"PRIu32"/16|20)",length);
1132 eptr->mode = KILL;
1133 return;
1134 }
1135 if (length==20) {
1136 msgid = get32bit(&data);
1137 } else {
1138 msgid = 0;
1139 }
1140 inode = get32bit(&data);
1141 maxentries = get32bit(&data);
1142 continueid = get64bit(&data);
1143 ptr = matoclserv_createpacket(eptr,MATOCL_NODE_INFO,fs_node_info(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,maxentries,continueid,NULL)+((length==20)?4:0));
1144 if (length==20) {
1145 put32bit(&ptr,msgid);
1146 }
1147 fs_node_info(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,maxentries,continueid,ptr);
1148 }
1149
matoclserv_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1150 void matoclserv_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1151 uint64_t totalspace,availspace,freespace,trspace,respace;
1152 uint64_t memusage,syscpu,usercpu;
1153 uint32_t trnodes,renodes,inodes,dnodes,fnodes;
1154 uint32_t chunks,chunkcopies,tdcopies;
1155 uint32_t lsstore,lstime;
1156 uint8_t lsstat;
1157 uint8_t *ptr;
1158 (void)data;
1159 if (length!=0) {
1160 syslog(LOG_NOTICE,"CLTOMA_INFO - wrong size (%"PRIu32"/0)",length);
1161 eptr->mode = KILL;
1162 return;
1163 }
1164 meta_info(&lsstore,&lstime,&lsstat);
1165 fs_info(&totalspace,&availspace,&freespace,&trspace,&trnodes,&respace,&renodes,&inodes,&dnodes,&fnodes);
1166 chunk_info(&chunks,&chunkcopies,&tdcopies);
1167 chartsdata_resusage(&memusage,&syscpu,&usercpu);
1168 ptr = matoclserv_createpacket(eptr,MATOCL_INFO,149);
1169 /* put32bit(&buff,VERSION): */
1170 put16bit(&ptr,VERSMAJ);
1171 put8bit(&ptr,VERSMID);
1172 put8bit(&ptr,VERSMIN);
1173 put64bit(&ptr,memusage);
1174 put64bit(&ptr,syscpu);
1175 put64bit(&ptr,usercpu);
1176 put64bit(&ptr,totalspace);
1177 put64bit(&ptr,availspace);
1178 put64bit(&ptr,freespace);
1179 put64bit(&ptr,trspace);
1180 put32bit(&ptr,trnodes);
1181 put64bit(&ptr,respace);
1182 put32bit(&ptr,renodes);
1183 put32bit(&ptr,inodes);
1184 put32bit(&ptr,dnodes);
1185 put32bit(&ptr,fnodes);
1186 put32bit(&ptr,chunks);
1187 put32bit(&ptr,chunkcopies);
1188 put32bit(&ptr,tdcopies);
1189 put32bit(&ptr,lsstore);
1190 put32bit(&ptr,lstime);
1191 put8bit(&ptr,lsstat);
1192 put8bit(&ptr,0xFF);
1193 put8bit(&ptr,0xFF);
1194 put8bit(&ptr,0xFF);
1195 put8bit(&ptr,0xFF);
1196 put32bit(&ptr,0);
1197 put32bit(&ptr,0);
1198 put64bit(&ptr,meta_version());
1199 put64bit(&ptr,exports_checksum());
1200 put64bit(&ptr,main_utime());
1201 put32bit(&ptr,0);
1202 }
1203
matoclserv_memory_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1204 void matoclserv_memory_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1205 uint8_t *ptr;
1206 uint64_t allocated[8];
1207 uint64_t used[8];
1208 (void)data;
1209 if (length!=0) {
1210 syslog(LOG_NOTICE,"CLTOMA_MEMORY_INFO - wrong size (%"PRIu32"/0)",length);
1211 eptr->mode = KILL;
1212 return;
1213 }
1214 ptr = matoclserv_createpacket(eptr,MATOCL_MEMORY_INFO,176);
1215 chunk_get_memusage(allocated,used);
1216 put64bit(&ptr,allocated[0]);
1217 put64bit(&ptr,used[0]);
1218 put64bit(&ptr,allocated[1]);
1219 put64bit(&ptr,used[1]);
1220 put64bit(&ptr,allocated[2]);
1221 put64bit(&ptr,used[2]);
1222 fs_get_memusage(allocated,used);
1223 put64bit(&ptr,allocated[0]);
1224 put64bit(&ptr,used[0]);
1225 put64bit(&ptr,allocated[1]);
1226 put64bit(&ptr,used[1]);
1227 put64bit(&ptr,allocated[2]);
1228 put64bit(&ptr,used[2]);
1229 put64bit(&ptr,allocated[3]);
1230 put64bit(&ptr,used[3]);
1231 put64bit(&ptr,allocated[4]);
1232 put64bit(&ptr,used[4]);
1233 put64bit(&ptr,allocated[5]);
1234 put64bit(&ptr,used[5]);
1235 put64bit(&ptr,allocated[6]);
1236 put64bit(&ptr,used[6]);
1237 put64bit(&ptr,allocated[7]);
1238 put64bit(&ptr,used[7]);
1239 }
1240
matoclserv_fstest_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1241 void matoclserv_fstest_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1242 uint32_t loopstart,loopend,files,ugfiles,mfiles,mtfiles,msfiles,chunks,ugchunks,mchunks,msgbuffleng;
1243 char *msgbuff;
1244 uint8_t *ptr;
1245 (void)data;
1246 if (length!=0 && length!=1) {
1247 syslog(LOG_NOTICE,"CLTOMA_FSTEST_INFO - wrong size (%"PRIu32"/0|1)",length);
1248 eptr->mode = KILL;
1249 return;
1250 }
1251 fs_test_getdata(&loopstart,&loopend,&files,&ugfiles,&mfiles,&mtfiles,&msfiles,&chunks,&ugchunks,&mchunks,&msgbuff,&msgbuffleng);
1252 ptr = matoclserv_createpacket(eptr,MATOCL_FSTEST_INFO,msgbuffleng+((length==1)?44:36));
1253 put32bit(&ptr,loopstart);
1254 put32bit(&ptr,loopend);
1255 put32bit(&ptr,files);
1256 put32bit(&ptr,ugfiles);
1257 put32bit(&ptr,mfiles);
1258 if (length==1) {
1259 put32bit(&ptr,mtfiles);
1260 put32bit(&ptr,msfiles);
1261 }
1262 put32bit(&ptr,chunks);
1263 put32bit(&ptr,ugchunks);
1264 put32bit(&ptr,mchunks);
1265 put32bit(&ptr,msgbuffleng);
1266 if (msgbuffleng>0) {
1267 memcpy(ptr,msgbuff,msgbuffleng);
1268 }
1269 }
1270
matoclserv_chunkstest_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1271 void matoclserv_chunkstest_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1272 uint8_t *ptr;
1273 (void)data;
1274 if (length!=0) {
1275 syslog(LOG_NOTICE,"CLTOMA_CHUNKSTEST_INFO - wrong size (%"PRIu32"/0)",length);
1276 eptr->mode = KILL;
1277 return;
1278 }
1279 ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKSTEST_INFO,72);
1280 chunk_store_info(ptr);
1281 }
1282
matoclserv_chunks_matrix(matoclserventry * eptr,const uint8_t * data,uint32_t length)1283 void matoclserv_chunks_matrix(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1284 uint8_t *ptr;
1285 (void)data;
1286 if (length>1) {
1287 syslog(LOG_NOTICE,"CLTOMA_CHUNKS_MATRIX - wrong size (%"PRIu32"/0|1)",length);
1288 eptr->mode = KILL;
1289 return;
1290 }
1291 if (length==1) {
1292 uint8_t matrixid;
1293 matrixid = get8bit(&data);
1294 ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKS_MATRIX,484);
1295 chunk_store_chunkcounters(ptr,matrixid);
1296 } else {
1297 uint8_t progressstatus;
1298 ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKS_MATRIX,969);
1299 progressstatus = chunk_counters_in_progress();
1300 // syslog(LOG_NOTICE,"progressstatus: %u",progressstatus);
1301 put8bit(&ptr,progressstatus);
1302 chunk_store_chunkcounters(ptr,0);
1303 chunk_store_chunkcounters(ptr+484,1);
1304 }
1305 }
1306
matoclserv_quota_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1307 void matoclserv_quota_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1308 uint8_t *ptr;
1309 (void)data;
1310 if (length!=0) {
1311 syslog(LOG_NOTICE,"CLTOMA_QUOTA_INFO - wrong size (%"PRIu32"/0)",length);
1312 eptr->mode = KILL;
1313 return;
1314 }
1315 ptr = matoclserv_createpacket(eptr,MATOCL_QUOTA_INFO,fs_getquotainfo(NULL));
1316 fs_getquotainfo(ptr);
1317 }
1318
matoclserv_exports_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1319 void matoclserv_exports_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1320 uint8_t *ptr;
1321 uint8_t vmode;
1322 if (length!=0 && length!=1) {
1323 syslog(LOG_NOTICE,"CLTOMA_EXPORTS_INFO - wrong size (%"PRIu32"/0|1)",length);
1324 eptr->mode = KILL;
1325 return;
1326 }
1327 if (length==0) {
1328 vmode = 0;
1329 } else {
1330 vmode = get8bit(&data);
1331 }
1332 ptr = matoclserv_createpacket(eptr,MATOCL_EXPORTS_INFO,exports_info_size(vmode));
1333 exports_info_data(vmode,ptr);
1334 }
1335
matoclserv_mlog_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)1336 void matoclserv_mlog_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1337 uint8_t *ptr;
1338 (void)data;
1339 if (length!=0) {
1340 syslog(LOG_NOTICE,"CLTOMA_MLOG_LIST - wrong size (%"PRIu32"/0)",length);
1341 eptr->mode = KILL;
1342 return;
1343 }
1344 ptr = matoclserv_createpacket(eptr,MATOCL_MLOG_LIST,matomlserv_mloglist_size());
1345 matomlserv_mloglist_data(ptr);
1346 }
1347
1348
matoclserv_fuse_register(matoclserventry * eptr,const uint8_t * data,uint32_t length)1349 void matoclserv_fuse_register(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1350 const uint8_t *rptr;
1351 uint8_t *wptr;
1352 uint32_t sessionid;
1353 uint8_t status;
1354
1355 if (length<64) {
1356 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER - wrong size (%"PRIu32"/<64)",length);
1357 eptr->mode = KILL;
1358 return;
1359 }
1360 if (memcmp(data,FUSE_REGISTER_BLOB_ACL,64)==0) {
1361 uint64_t expected_metaid;
1362 uint32_t rootinode;
1363 uint8_t sesflags;
1364 uint16_t umaskval;
1365 uint8_t mingoal,maxgoal;
1366 uint32_t mintrashtime,maxtrashtime;
1367 uint32_t disables;
1368 uint32_t rootuid,rootgid;
1369 uint32_t mapalluid,mapallgid;
1370 uint32_t ileng,pleng;
1371 uint8_t i,rcode,created;
1372
1373 if (length<65) {
1374 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong size (%"PRIu32"/<65)",length);
1375 eptr->mode = KILL;
1376 return;
1377 }
1378
1379 rptr = data+64;
1380 rcode = get8bit(&rptr);
1381
1382 if ((eptr->registered==0 && rcode==REGISTER_CLOSESESSION) || (eptr->registered && rcode!=REGISTER_CLOSESESSION)) {
1383 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong rcode (%d) for registered status (%d)",rcode,eptr->registered);
1384 eptr->mode = KILL;
1385 return;
1386 }
1387
1388 // printf("rcode: %d\n",rcode);
1389 //
1390 switch (rcode) {
1391 case REGISTER_GETRANDOM:
1392 if (length!=65) {
1393 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.1 - wrong size (%"PRIu32"/65)",length);
1394 eptr->mode = KILL;
1395 return;
1396 }
1397 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,32);
1398 for (i=0 ; i<32 ; i++) {
1399 eptr->passwordrnd[i]=rndu8();
1400 }
1401 memcpy(wptr,eptr->passwordrnd,32);
1402 return;
1403 case REGISTER_NEWSESSION:
1404 if (length<77) {
1405 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/>=77)",length);
1406 eptr->mode = KILL;
1407 return;
1408 }
1409 eptr->version = get32bit(&rptr);
1410 eptr->asize = (eptr->version>=VERSION2INT(3,0,93))?ATTR_RECORD_SIZE:35;
1411
1412 ileng = get32bit(&rptr);
1413 if (length<77+ileng) {
1414 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/>=77+ileng(%"PRIu32"))",length,ileng);
1415 eptr->mode = KILL;
1416 return;
1417 }
1418 if (eptr->info!=NULL) {
1419 free(eptr->info);
1420 }
1421 eptr->ileng = ileng;
1422 eptr->info = malloc(ileng);
1423 passert(eptr->info);
1424 memcpy(eptr->info,rptr,ileng);
1425 rptr+=ileng;
1426
1427 pleng = get32bit(&rptr);
1428 if (length!=77+ileng+pleng && length!=77+16+ileng+pleng && length!=77+4+ileng+pleng && length!=77+4+16+ileng+pleng && length!=77+12+ileng+pleng && length!=77+12+16+ileng+pleng) {
1429 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/77+ileng(%"PRIu32")+pleng(%"PRIu32")+[0|4|12]+[0|16])",length,ileng,pleng);
1430 eptr->mode = KILL;
1431 return;
1432 }
1433 if (eptr->path!=NULL) {
1434 free(eptr->path);
1435 }
1436 if (pleng>0) {
1437 eptr->path = malloc(pleng);
1438 passert(eptr->path);
1439 memcpy(eptr->path,rptr,pleng);
1440 rptr+=pleng;
1441 if (rptr[-1]!=0) {
1442 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - received path without ending zero");
1443 eptr->mode = KILL;
1444 return;
1445 }
1446 } else {
1447 eptr->path = malloc(1);
1448 passert(eptr->path);
1449 eptr->path[0] = 0;
1450 }
1451
1452 if (length==77+4+ileng+pleng || length==77+4+16+ileng+pleng) {
1453 sessionid = get32bit(&rptr);
1454 } else if (length==77+12+ileng+pleng || length==77+12+16+ileng+pleng) {
1455 sessionid = get32bit(&rptr);
1456 expected_metaid = get64bit(&rptr);
1457 if (expected_metaid != meta_get_id()) {
1458 sessionid = 0;
1459 }
1460 } else {
1461 sessionid = iptosesid_get(eptr->peerip); // patch for clients < 3.0
1462 }
1463 if (length>=77+16+ileng+pleng) {
1464 eptr->usepassword = 1;
1465 memcpy(eptr->passwordmd5,rptr,16);
1466 status = exports_check(eptr->peerip,eptr->version,eptr->path,eptr->passwordrnd,rptr,&sesflags,&umaskval,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime,&disables);
1467 } else {
1468 eptr->usepassword = 0;
1469 status = exports_check(eptr->peerip,eptr->version,eptr->path,NULL,NULL,&sesflags,&umaskval,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime,&disables);
1470 }
1471 if (status==MFS_STATUS_OK) {
1472 status = fs_getrootinode(&rootinode,eptr->path);
1473 }
1474 created = 0;
1475 if (status==MFS_STATUS_OK) {
1476 if (sessionid!=0) {
1477 eptr->sesdata = sessions_find_session(sessionid);
1478 if (eptr->sesdata==NULL) {
1479 sessionid=0;
1480 } else {
1481 sessions_chg_session(eptr->sesdata,exports_checksum(),rootinode,sesflags,umaskval,rootuid,rootgid,mapalluid,mapallgid,mingoal,maxgoal,mintrashtime,maxtrashtime,disables,eptr->peerip,eptr->info,eptr->ileng);
1482 }
1483 }
1484 if (sessionid==0) {
1485 eptr->sesdata = sessions_new_session(exports_checksum(),rootinode,sesflags,umaskval,rootuid,rootgid,mapalluid,mapallgid,mingoal,maxgoal,mintrashtime,maxtrashtime,disables,eptr->peerip,eptr->info,eptr->ileng);
1486 created = 1;
1487 }
1488 if (eptr->sesdata==NULL) {
1489 syslog(LOG_NOTICE,"can't allocate session record");
1490 eptr->mode = KILL;
1491 return;
1492 }
1493 }
1494 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,(status==MFS_STATUS_OK)?((eptr->version>=VERSION2INT(3,0,112))?49:(eptr->version>=VERSION2INT(3,0,72))?45:(eptr->version>=VERSION2INT(3,0,11))?43:(eptr->version>=VERSION2INT(1,6,26))?35:(eptr->version>=VERSION2INT(1,6,21))?25:(eptr->version>=VERSION2INT(1,6,1))?21:13):1);
1495 if (status!=MFS_STATUS_OK) {
1496 put8bit(&wptr,status);
1497 eptr->sesdata = NULL;
1498 return;
1499 }
1500 sessionid = sessions_get_id(eptr->sesdata);
1501 if (eptr->version==VERSION2INT(1,6,21)) {
1502 put32bit(&wptr,0);
1503 } else if (eptr->version>=VERSION2INT(1,6,22)) {
1504 put16bit(&wptr,VERSMAJ);
1505 put8bit(&wptr,VERSMID);
1506 put8bit(&wptr,VERSMIN);
1507 }
1508 put32bit(&wptr,sessionid);
1509 if (eptr->version>=VERSION2INT(3,0,11)) {
1510 put64bit(&wptr,meta_get_id());
1511 }
1512 put8bit(&wptr,sesflags);
1513 if (eptr->version>=VERSION2INT(3,0,72)) {
1514 put16bit(&wptr,umaskval);
1515 }
1516 put32bit(&wptr,rootuid);
1517 put32bit(&wptr,rootgid);
1518 if (eptr->version>=VERSION2INT(1,6,1)) {
1519 put32bit(&wptr,mapalluid);
1520 put32bit(&wptr,mapallgid);
1521 }
1522 if (eptr->version>=VERSION2INT(1,6,26)) {
1523 put8bit(&wptr,mingoal);
1524 put8bit(&wptr,maxgoal);
1525 put32bit(&wptr,mintrashtime);
1526 put32bit(&wptr,maxtrashtime);
1527 }
1528 if (eptr->version>=VERSION2INT(3,0,112)) {
1529 put32bit(&wptr,disables);
1530 }
1531 sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1532 eptr->registered = 1;
1533 if (created) {
1534 syslog(LOG_NOTICE,"created new sessionid:%"PRIu32,sessionid);
1535 }
1536 return;
1537 case REGISTER_NEWMETASESSION:
1538 if (length<73) {
1539 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.5 - wrong size (%"PRIu32"/>=73)",length);
1540 eptr->mode = KILL;
1541 return;
1542 }
1543 eptr->version = get32bit(&rptr);
1544 eptr->asize = (eptr->version>=VERSION2INT(3,0,93))?ATTR_RECORD_SIZE:35;
1545
1546 ileng = get32bit(&rptr);
1547 if (length!=73+ileng && length!=73+16+ileng && length!=73+4+ileng && length!=73+4+16+ileng && length!=73+12+ileng && length!=73+12+16+ileng) {
1548 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.5 - wrong size (%"PRIu32"/73+ileng(%"PRIu32")+[0|4|12]+[0|16])",length,ileng);
1549 eptr->mode = KILL;
1550 return;
1551 }
1552 if (eptr->info!=NULL) {
1553 free(eptr->info);
1554 }
1555 eptr->ileng = ileng;
1556 eptr->info = malloc(ileng);
1557 passert(eptr->info);
1558 memcpy(eptr->info,rptr,ileng);
1559 rptr+=ileng;
1560
1561 if (eptr->path!=NULL) {
1562 free(eptr->path);
1563 eptr->path = NULL;
1564 }
1565
1566 if (length==73+4+ileng || length==73+4+16+ileng) {
1567 sessionid = get32bit(&rptr);
1568 } else if (length==73+12+ileng || length==73+12+16+ileng) {
1569 sessionid = get32bit(&rptr);
1570 expected_metaid = get64bit(&rptr);
1571 if (expected_metaid != meta_get_id()) {
1572 sessionid = 0;
1573 }
1574 } else {
1575 sessionid = iptosesid_get(eptr->peerip); // patch for clients < 3.0
1576 }
1577 if (length>=73+16+ileng) {
1578 eptr->usepassword = 1;
1579 memcpy(eptr->passwordmd5,rptr,16);
1580 status = exports_check(eptr->peerip,eptr->version,NULL,eptr->passwordrnd,rptr,&sesflags,&umaskval,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime,&disables);
1581 } else {
1582 eptr->usepassword = 0;
1583 status = exports_check(eptr->peerip,eptr->version,NULL,NULL,NULL,&sesflags,&umaskval,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime,&disables);
1584 }
1585 if (status==MFS_STATUS_OK) {
1586 if (sessionid!=0) {
1587 eptr->sesdata = sessions_find_session(sessionid);
1588 if (eptr->sesdata==NULL) {
1589 sessionid=0;
1590 } else {
1591 sessions_chg_session(eptr->sesdata,exports_checksum(),0,sesflags,umaskval,0,0,0,0,mingoal,maxgoal,mintrashtime,maxtrashtime,disables,eptr->peerip,eptr->info,eptr->ileng);
1592 }
1593 }
1594 if (sessionid==0) {
1595 eptr->sesdata = sessions_new_session(exports_checksum(),0,sesflags,umaskval,0,0,0,0,mingoal,maxgoal,mintrashtime,maxtrashtime,disables,eptr->peerip,eptr->info,eptr->ileng);
1596 }
1597 if (eptr->sesdata==NULL) {
1598 syslog(LOG_NOTICE,"can't allocate session record");
1599 eptr->mode = KILL;
1600 return;
1601 }
1602 }
1603 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,(status==MFS_STATUS_OK)?((eptr->version>=VERSION2INT(3,0,11))?27:(eptr->version>=VERSION2INT(1,6,26))?19:(eptr->version>=VERSION2INT(1,6,21))?9:5):1);
1604 if (status!=MFS_STATUS_OK) {
1605 put8bit(&wptr,status);
1606 eptr->sesdata = NULL;
1607 return;
1608 }
1609 sessionid = sessions_get_id(eptr->sesdata);
1610 if (eptr->version>=VERSION2INT(1,6,21)) {
1611 put16bit(&wptr,VERSMAJ);
1612 put8bit(&wptr,VERSMID);
1613 put8bit(&wptr,VERSMIN);
1614 }
1615 put32bit(&wptr,sessionid);
1616 if (eptr->version>=VERSION2INT(3,0,11)) {
1617 put64bit(&wptr,meta_get_id());
1618 }
1619 put8bit(&wptr,sesflags);
1620 if (eptr->version>=VERSION2INT(1,6,26)) {
1621 put8bit(&wptr,mingoal);
1622 put8bit(&wptr,maxgoal);
1623 put32bit(&wptr,mintrashtime);
1624 put32bit(&wptr,maxtrashtime);
1625 }
1626 sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1627 eptr->registered = 1;
1628 return;
1629 case REGISTER_RECONNECT:
1630 case REGISTER_TOOLS:
1631 if (length<73) {
1632 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.%"PRIu8" - wrong size (%"PRIu32"/73)",rcode,length);
1633 eptr->mode = KILL;
1634 return;
1635 }
1636
1637 sessionid = get32bit(&rptr);
1638 if (iptosesid_check(eptr->peerip)) { // patch for clients < 3.0
1639 eptr->mode = KILL;
1640 return;
1641 }
1642
1643 eptr->version = get32bit(&rptr);
1644 eptr->asize = (eptr->version>=VERSION2INT(3,0,93))?ATTR_RECORD_SIZE:35;
1645
1646 status = MFS_STATUS_OK;
1647 if (length>=81) {
1648 expected_metaid = get64bit(&rptr);
1649 if (expected_metaid!=meta_get_id()) {
1650 status = MFS_ERROR_BADSESSIONID;
1651 }
1652 }
1653 if (status==MFS_STATUS_OK) {
1654 eptr->sesdata = sessions_find_session(sessionid);
1655 // syslog(LOG_WARNING,"session reconnect: ip:%u.%u.%u.%u ; version:%u.%u.%u ; sessionid: %u (%s)",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF,eptr->version>>16,(eptr->version>>8)&0xFF,(eptr->version>>1)&0x7F,sessionid,(eptr->sesdata)?"found":"not found");
1656 if (eptr->sesdata==NULL || sessions_get_peerip(eptr->sesdata)==0) { // no such session or session created by entries in metadata
1657 status = MFS_ERROR_BADSESSIONID;
1658 } else {
1659 // syslog(LOG_NOTICE,"session exports checksum: %016"PRIX64" ; current exports checksum: %016"PRIX64,sessions_get_exportscsum(eptr->sesdata),exports_checksum());
1660 // syslog(LOG_WARNING,"session reconnect: ip:%u.%u.%u.%u (%08X) ; session_peerip(%08X)",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF,eptr->peerip,sessions_get_peerip(eptr->sesdata));
1661 if (sessions_get_exportscsum(eptr->sesdata)!=exports_checksum() || ((sessions_get_sesflags(eptr->sesdata)&SESFLAG_DYNAMICIP)==0 && eptr->peerip!=sessions_get_peerip(eptr->sesdata))) {
1662 status = MFS_ERROR_EPERM; // masters < 2.1.0 returned MFS_ERROR_EACCES, so MFS_ERROR_EPERM means that client can use register with sessionid
1663 iptosesid_add(eptr->peerip,sessionid); // patch for clients < 3.0
1664 }
1665 }
1666 }
1667 if (rcode==REGISTER_RECONNECT && eptr->version>=VERSION2INT(3,0,95)) {
1668 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,5);
1669 put16bit(&wptr,VERSMAJ);
1670 put8bit(&wptr,VERSMID);
1671 put8bit(&wptr,VERSMIN);
1672 } else {
1673 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,1);
1674 }
1675 put8bit(&wptr,status);
1676 if (status!=MFS_STATUS_OK) {
1677 eptr->sesdata = NULL;
1678 return;
1679 }
1680 sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1681 eptr->registered = (rcode==3)?1:100;
1682 return;
1683 case REGISTER_CLOSESESSION:
1684 if (length<69) {
1685 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.6 - wrong size (%"PRIu32"/69)",length);
1686 eptr->mode = KILL;
1687 return;
1688 }
1689 sessionid = get32bit(&rptr);
1690 status = MFS_STATUS_OK;
1691 if (length>=77) {
1692 expected_metaid = get64bit(&rptr);
1693 if (expected_metaid!=meta_get_id()) {
1694 status = MFS_ERROR_BADSESSIONID;
1695 }
1696 }
1697 if (status==MFS_STATUS_OK) {
1698 sessions_close_session(sessionid);
1699 }
1700 if (eptr->version>=VERSION2INT(1,7,29)) {
1701 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,1);
1702 put8bit(&wptr,status);
1703 }
1704 eptr->mode = FINISH;
1705 return;
1706 }
1707 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong rcode (%"PRIu8")",rcode);
1708 eptr->mode = KILL;
1709 return;
1710 } else {
1711 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER - wrong register blob");
1712 eptr->mode = KILL;
1713 return;
1714 }
1715 }
1716
matoclserv_reload_sessions(void)1717 void matoclserv_reload_sessions(void) {
1718 matoclserventry *eptr;
1719
1720 exports_reload();
1721 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
1722 if (eptr->mode==DATA && eptr->registered==1 && eptr->sesdata!=NULL) {
1723 if (sessions_get_exportscsum(eptr->sesdata)!=exports_checksum()) {
1724 eptr->mode = KILL;
1725 }
1726 }
1727 }
1728 }
1729
matoclserv_fuse_sustained_inodes(matoclserventry * eptr,const uint8_t * data,uint32_t length)1730 void matoclserv_fuse_sustained_inodes(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1731 const uint8_t *rptr;
1732 static uint32_t *inodetab = NULL;
1733 static uint32_t inodetabsize = 0;
1734 uint32_t i,j;
1735
1736 if ((length&0x3)!=0) {
1737 syslog(LOG_NOTICE,"CLTOMA_FUSE_SUSTAINED_INODES - wrong size (%"PRIu32"/N*4)",length);
1738 eptr->mode = KILL;
1739 return;
1740 }
1741
1742 if (eptr->sesdata==NULL) {
1743 syslog(LOG_NOTICE,"CLTOMA_FUSE_SUSTAINED_INODES - session doesn't exist");
1744 eptr->mode = KILL;
1745 return;
1746 }
1747 length>>=2;
1748 if (length>inodetabsize) {
1749 if (inodetab) {
1750 free(inodetab);
1751 }
1752 inodetabsize = ((length+0xFF)&0xFFFFFF00);
1753 inodetab = malloc(sizeof(uint32_t)*inodetabsize);
1754 passert(inodetab);
1755 }
1756 rptr = data;
1757 j = 0;
1758 while (length>0) {
1759 i = get32bit(&rptr);
1760 if (i>0) {
1761 inodetab[j] = i;
1762 j++;
1763 }
1764 length--;
1765 }
1766 of_sync(sessions_get_id(eptr->sesdata),inodetab,j);
1767 // sessions_sync_open_files(eptr->sesdata,data,length>>2);
1768 }
1769
matoclserv_fuse_amtime_inodes(matoclserventry * eptr,const uint8_t * data,uint32_t length)1770 void matoclserv_fuse_amtime_inodes(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1771 const uint8_t *rptr;
1772 static uint32_t *inodetab=NULL,*atimetab=NULL,*mtimetab=NULL;
1773 static uint32_t tabsizes = 0;
1774 uint32_t i,a,m,j;
1775
1776 if ((length%12)!=0) {
1777 syslog(LOG_NOTICE,"CLTOMA_FUSE_AMTIME_INODES - wrong size (%"PRIu32"/N*12)",length);
1778 eptr->mode = KILL;
1779 return;
1780 }
1781
1782 if (eptr->sesdata==NULL) {
1783 syslog(LOG_NOTICE,"CLTOMA_FUSE_AMTIME_INODES - session doesn't exist");
1784 eptr->mode = KILL;
1785 return;
1786 }
1787 length/=12;
1788 if (length>tabsizes) {
1789 if (inodetab) {
1790 free(inodetab);
1791 }
1792 if (atimetab) {
1793 free(atimetab);
1794 }
1795 if (mtimetab) {
1796 free(mtimetab);
1797 }
1798 tabsizes = ((length+0xFF)&0xFFFFFF00);
1799 inodetab = malloc(sizeof(uint32_t)*tabsizes);
1800 passert(inodetab);
1801 atimetab = malloc(sizeof(uint32_t)*tabsizes);
1802 passert(atimetab);
1803 mtimetab = malloc(sizeof(uint32_t)*tabsizes);
1804 passert(mtimetab);
1805 }
1806 rptr = data;
1807 j = 0;
1808 while (length>0) {
1809 i = get32bit(&rptr);
1810 a = get32bit(&rptr);
1811 m = get32bit(&rptr);
1812 if (i>0 && (a>0 || m>0)) {
1813 inodetab[j] = i;
1814 atimetab[j] = a;
1815 mtimetab[j] = m;
1816 j++;
1817 }
1818 length--;
1819 }
1820 fs_amtime_update(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inodetab,atimetab,mtimetab,j);
1821 }
1822
matoclserv_fuse_time_sync(matoclserventry * eptr,const uint8_t * data,uint32_t length)1823 void matoclserv_fuse_time_sync(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1824 uint8_t *ptr;
1825 uint32_t msgid;
1826
1827 if (length!=0 && length!=4) {
1828 syslog(LOG_NOTICE,"CLTOMA_FUSE_TIME_SYNC - wrong size (%"PRIu32"/0)",length);
1829 eptr->mode = KILL;
1830 return;
1831 }
1832
1833 if (length==4) {
1834 msgid = get32bit(&data);
1835 } else {
1836 msgid = 0;
1837 }
1838
1839 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TIME_SYNC,8+length);
1840 if (length==4) {
1841 put32bit(&ptr,msgid);
1842 }
1843 put64bit(&ptr,main_utime());
1844 }
1845
matoclserv_gid_storage(uint32_t gids)1846 uint32_t* matoclserv_gid_storage(uint32_t gids) {
1847 static uint32_t *gid=NULL;
1848 static uint32_t gidleng=0;
1849 if (gids==0) {
1850 if (gid!=NULL) {
1851 free(gid);
1852 }
1853 gidleng=0;
1854 return NULL;
1855 } else {
1856 if (gidleng<gids) {
1857 gidleng = (gids+255)&UINT32_C(0xFFFFFF00);
1858 if (gid!=NULL) {
1859 free(gid);
1860 }
1861 gid = malloc(sizeof(uint32_t)*gidleng);
1862 passert(gid);
1863 }
1864 return gid;
1865 }
1866 }
1867
matoclserv_fuse_statfs(matoclserventry * eptr,const uint8_t * data,uint32_t length)1868 void matoclserv_fuse_statfs(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1869 uint64_t totalspace,availspace,freespace,trashspace,sustainedspace;
1870 uint32_t msgid,inodes;
1871 uint8_t addfreespace;
1872 uint8_t *ptr;
1873 if (length!=4) {
1874 syslog(LOG_NOTICE,"CLTOMA_FUSE_STATFS - wrong size (%"PRIu32"/4)",length);
1875 eptr->mode = KILL;
1876 return;
1877 }
1878 addfreespace = ((eptr->version>=VERSION2INT(3,0,102) && eptr->version<VERSION2INT(4,0,0)) || eptr->version>=VERSION2INT(4,9,0))?1:0;
1879 msgid = get32bit(&data);
1880 fs_statfs(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&totalspace,&availspace,&freespace,&trashspace,&sustainedspace,&inodes);
1881 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_STATFS,addfreespace?48:40);
1882 put32bit(&ptr,msgid);
1883 put64bit(&ptr,totalspace);
1884 put64bit(&ptr,availspace);
1885 if (addfreespace) {
1886 put64bit(&ptr,freespace);
1887 }
1888 put64bit(&ptr,trashspace);
1889 put64bit(&ptr,sustainedspace);
1890 put32bit(&ptr,inodes);
1891 sessions_inc_stats(eptr->sesdata,0);
1892 }
1893
matoclserv_fuse_access(matoclserventry * eptr,const uint8_t * data,uint32_t length)1894 void matoclserv_fuse_access(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1895 uint32_t *gid;
1896 uint32_t i;
1897 uint32_t inode,uid,gids;
1898 uint16_t modemask;
1899 uint32_t msgid;
1900 uint8_t *ptr;
1901 uint8_t status;
1902 if ((length&1)==1) {
1903 if (length!=17) {
1904 syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/17)",length);
1905 eptr->mode = KILL;
1906 return;
1907 }
1908 msgid = get32bit(&data);
1909 inode = get32bit(&data);
1910 uid = get32bit(&data);
1911 gid = matoclserv_gid_storage(1);
1912 gid[0] = get32bit(&data);
1913 gids = 1;
1914 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1915 modemask = get8bit(&data);
1916 } else {
1917 if (length<18) {
1918 syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/18+4*N)",length);
1919 eptr->mode = KILL;
1920 return;
1921 }
1922 msgid = get32bit(&data);
1923 inode = get32bit(&data);
1924 uid = get32bit(&data);
1925 gids = get32bit(&data);
1926 if (length!=18+gids*4) {
1927 syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/18+4*N)",length);
1928 eptr->mode = KILL;
1929 return;
1930 }
1931 gid = matoclserv_gid_storage(gids);
1932 for (i=0 ; i<gids ; i++) {
1933 gid[i] = get32bit(&data);
1934 }
1935 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1936 modemask = get16bit(&data);
1937 }
1938 status = fs_access(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,modemask);
1939 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_ACCESS,5);
1940 put32bit(&ptr,msgid);
1941 put8bit(&ptr,status);
1942 }
1943
matoclserv_fuse_lookup(matoclserventry * eptr,const uint8_t * data,uint32_t length)1944 void matoclserv_fuse_lookup(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1945 uint32_t inode,uid,gids,auid,agid;
1946 uint32_t *gid;
1947 uint32_t i;
1948 uint8_t nleng;
1949 const uint8_t *name;
1950 uint32_t newinode;
1951 uint8_t attr[ATTR_RECORD_SIZE];
1952 uint16_t lflags;
1953 uint16_t accmode;
1954 uint8_t filenode;
1955 uint8_t validchunk;
1956 uint64_t chunkid;
1957 uint32_t msgid;
1958 uint8_t *ptr;
1959 uint8_t status;
1960 if (length<17) {
1961 syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32")",length);
1962 eptr->mode = KILL;
1963 return;
1964 }
1965 msgid = get32bit(&data);
1966 inode = get32bit(&data);
1967 nleng = get8bit(&data);
1968 if (length<17U+nleng) {
1969 syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
1970 eptr->mode = KILL;
1971 return;
1972 }
1973 name = data;
1974 data += nleng;
1975 auid = uid = get32bit(&data);
1976 if (length==17U+nleng) {
1977 gids = 1;
1978 gid = matoclserv_gid_storage(gids);
1979 agid = gid[0] = get32bit(&data);
1980 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1981 } else {
1982 gids = get32bit(&data);
1983 if (length!=17U+nleng+4*gids) {
1984 syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
1985 eptr->mode = KILL;
1986 return;
1987 }
1988 gid = matoclserv_gid_storage(gids);
1989 for (i=0 ; i<gids ; i++) {
1990 gid[i] = get32bit(&data);
1991 }
1992 agid = gid[0];
1993 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1994 }
1995 if (eptr->version>=VERSION2INT(3,0,40)) {
1996 uint8_t sesflags = sessions_get_sesflags(eptr->sesdata);
1997 status = fs_lookup(sessions_get_rootinode(eptr->sesdata),sesflags,inode,nleng,name,uid,gids,gid,auid,agid,&newinode,attr,&accmode,&filenode,&validchunk,&chunkid);
1998 if (status==MFS_STATUS_OK) {
1999 uint32_t version;
2000 uint8_t count;
2001 uint8_t cs_data[100*14];
2002 lflags = (accmode & LOOKUP_ACCESS_BITS);
2003 count = 0;
2004 version = 0;
2005 if (eptr->version<VERSION2INT(3,0,113) && lflags&LOOKUP_APPENDONLY) { // this mount doesn't support append only, so remove 'W' access
2006 lflags &= LOOKUP_ACCESS_MODES_RO;
2007 }
2008 if (filenode && (lflags&LOOKUP_ACCESS_MODES_IO)!=0) { // can be read and/or written
2009 if (eptr->version>=VERSION2INT(3,0,113)) {
2010 if ((lflags&LOOKUP_DIRECTMODE)==0) {
2011 if (dcm_open(newinode,sessions_get_id(eptr->sesdata))) {
2012 lflags |= LOOKUP_KEEPCACHE;
2013 } else { // just fix for old clients
2014 if (sesflags&SESFLAG_ATTRBIT) {
2015 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2016 } else {
2017 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2018 }
2019 }
2020 }
2021 } else {
2022 if ((sesflags&SESFLAG_ATTRBIT)==0 || (attr[0]&MATTR_DIRECTMODE)==0) {
2023 if (dcm_open(newinode,sessions_get_id(eptr->sesdata))==0) {
2024 if (sesflags&SESFLAG_ATTRBIT) {
2025 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2026 } else {
2027 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2028 }
2029 }
2030 }
2031 }
2032 if (validchunk && (sessions_get_disables(eptr->sesdata)&DISABLE_READ)==0) {
2033 if (chunkid>0) {
2034 if (chunk_get_version_and_csdata(2,chunkid,eptr->peerip,&version,&count,cs_data)==MFS_STATUS_OK) {
2035 lflags |= LOOKUP_CHUNK_ZERO_DATA;
2036 }
2037 } else {
2038 version = 0;
2039 count = 0;
2040 lflags |= LOOKUP_CHUNK_ZERO_DATA;
2041 }
2042 }
2043 }
2044 if (sesflags&SESFLAG_READONLY) {
2045 lflags |= LOOKUP_RO_FILESYSTEM;
2046 }
2047 if (lflags & LOOKUP_CHUNK_ZERO_DATA) {
2048 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LOOKUP,eptr->asize+23+count*14);
2049 put32bit(&ptr,msgid);
2050 put32bit(&ptr,newinode);
2051 memcpy(ptr,attr,eptr->asize);
2052 ptr+=eptr->asize;
2053 put16bit(&ptr,lflags);
2054 put8bit(&ptr,2);
2055 put64bit(&ptr,chunkid);
2056 put32bit(&ptr,version);
2057 if (count>0) {
2058 memcpy(ptr,cs_data,count*14);
2059 }
2060 } else {
2061 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LOOKUP,eptr->asize+10);
2062 put32bit(&ptr,msgid);
2063 put32bit(&ptr,newinode);
2064 memcpy(ptr,attr,eptr->asize);
2065 ptr+=eptr->asize;
2066 put16bit(&ptr,lflags);
2067 }
2068 }
2069 } else {
2070 status = fs_lookup(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid,auid,agid,&newinode,attr,NULL,NULL,NULL,NULL);
2071 if (status==MFS_ERROR_ENOENT_NOCACHE && eptr->version<VERSION2INT(3,0,25)) {
2072 status = MFS_ERROR_ENOENT;
2073 }
2074 if (status==MFS_STATUS_OK) {
2075 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LOOKUP,eptr->asize+8);
2076 put32bit(&ptr,msgid);
2077 put32bit(&ptr,newinode);
2078 memcpy(ptr,attr,eptr->asize);
2079 }
2080 }
2081 if (status!=MFS_STATUS_OK) {
2082 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LOOKUP,5);
2083 put32bit(&ptr,msgid);
2084 put8bit(&ptr,status);
2085 }
2086 sessions_inc_stats(eptr->sesdata,3);
2087 }
2088
matoclserv_fuse_getattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)2089 void matoclserv_fuse_getattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2090 uint32_t inode,uid,gid,auid,agid;
2091 uint8_t opened;
2092 uint8_t attr[ATTR_RECORD_SIZE];
2093 uint32_t msgid;
2094 uint8_t *ptr;
2095 uint8_t status;
2096 if (length!=8 && length!=16 && length!=17) {
2097 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETATTR - wrong size (%"PRIu32"/8|16|17)",length);
2098 eptr->mode = KILL;
2099 return;
2100 }
2101 msgid = get32bit(&data);
2102 inode = get32bit(&data);
2103 if (length==17) {
2104 opened = get8bit(&data);
2105 } else {
2106 opened = 0;
2107 }
2108 if (length>=16) {
2109 auid = uid = get32bit(&data);
2110 agid = gid = get32bit(&data);
2111 sessions_ugid_remap(eptr->sesdata,&uid,&gid);
2112 } else {
2113 auid = uid = 12345;
2114 agid = gid = 12345;
2115 }
2116 status = fs_getattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gid,auid,agid,attr);
2117 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETATTR,(status!=MFS_STATUS_OK)?5:(eptr->asize+4));
2118 put32bit(&ptr,msgid);
2119 if (status!=MFS_STATUS_OK) {
2120 put8bit(&ptr,status);
2121 } else {
2122 memcpy(ptr,attr,eptr->asize);
2123 }
2124 sessions_inc_stats(eptr->sesdata,1);
2125 }
2126
matoclserv_fuse_setattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)2127 void matoclserv_fuse_setattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2128 uint32_t inode,uid,gids,auid,agid;
2129 uint32_t *gid;
2130 uint32_t i;
2131 uint8_t opened;
2132 uint16_t setmask;
2133 uint8_t attr[ATTR_RECORD_SIZE];
2134 uint32_t msgid;
2135 uint8_t *ptr;
2136 uint8_t status;
2137 uint8_t sugidclearmode;
2138 uint16_t attrmode;
2139 uint32_t attruid,attrgid,attratime,attrmtime;
2140 uint32_t disables;
2141 uint8_t winattr,basesize;
2142
2143 basesize = (eptr->version>=VERSION2INT(3,0,93))?38:37;
2144 if (length!=35 && length!=36 && length<basesize) {
2145 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETATTR - wrong size (%"PRIu32"/35|36|37|37+N*4|38+N*4)",length);
2146 eptr->mode = KILL;
2147 return;
2148 }
2149 msgid = get32bit(&data);
2150 inode = get32bit(&data);
2151 if (length>=37) {
2152 opened = get8bit(&data);
2153 } else {
2154 opened = 0;
2155 }
2156 auid = uid = get32bit(&data);
2157 if (length<=37) {
2158 gids = 1;
2159 gid = matoclserv_gid_storage(gids);
2160 agid = gid[0] = get32bit(&data);
2161 } else {
2162 gids = get32bit(&data);
2163 if (length!=basesize+4*gids) {
2164 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETATTR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2165 eptr->mode = KILL;
2166 return;
2167 }
2168 gid = matoclserv_gid_storage(gids);
2169 for (i=0 ; i<gids ; i++) {
2170 gid[i] = get32bit(&data);
2171 }
2172 agid = gid[0];
2173 }
2174 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2175 setmask = get8bit(&data);
2176 attrmode = get16bit(&data);
2177 attruid = get32bit(&data);
2178 attrgid = get32bit(&data);
2179 attratime = get32bit(&data);
2180 attrmtime = get32bit(&data);
2181 if (basesize==38) {
2182 winattr = get8bit(&data);
2183 } else {
2184 winattr = 0;
2185 }
2186 if (length>=36) {
2187 sugidclearmode = get8bit(&data);
2188 } else {
2189 sugidclearmode = SUGID_CLEAR_MODE_ALWAYS; // this is safest option
2190 }
2191 disables = sessions_get_disables(eptr->sesdata);
2192 if (((disables&DISABLE_CHOWN) && (setmask&(SET_UID_FLAG|SET_GID_FLAG))) || ((disables&DISABLE_CHMOD) && (setmask&SET_MODE_FLAG))) {
2193 status = MFS_ERROR_EPERM;
2194 } else if (setmask&SET_WINATTR_FLAG && basesize==37) {
2195 status = MFS_ERROR_EINVAL;
2196 } else {
2197 status = fs_setattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,auid,agid,setmask,attrmode,attruid,attrgid,attratime,attrmtime,winattr,sugidclearmode,attr);
2198 }
2199 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETATTR,(status!=MFS_STATUS_OK)?5:(eptr->asize+4));
2200 put32bit(&ptr,msgid);
2201 if (status!=MFS_STATUS_OK) {
2202 put8bit(&ptr,status);
2203 } else {
2204 memcpy(ptr,attr,eptr->asize);
2205 }
2206 sessions_inc_stats(eptr->sesdata,2);
2207 }
2208
matoclserv_fuse_truncate(matoclserventry * eptr,const uint8_t * data,uint32_t length)2209 void matoclserv_fuse_truncate(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2210 uint32_t inode,uid,gids,auid,agid;
2211 uint32_t *gid;
2212 uint32_t i;
2213 uint32_t msgid;
2214 uint8_t flags;
2215 uint64_t fleng;
2216 if (length!=24 && length<25) {
2217 syslog(LOG_NOTICE,"CLTOMA_FUSE_TRUNCATE - wrong size (%"PRIu32"/24|25+N*4)",length);
2218 eptr->mode = KILL;
2219 return;
2220 }
2221 flags = 0;
2222 msgid = get32bit(&data);
2223 inode = get32bit(&data);
2224 if (length>=25) {
2225 flags = get8bit(&data);
2226 }
2227 auid = uid = get32bit(&data);
2228 if (length<=25) {
2229 gids = 1;
2230 gid = matoclserv_gid_storage(gids);
2231 agid = gid[0] = get32bit(&data);
2232 if (length==24) {
2233 if (uid==0 && gid[0]!=0) { // stupid "flags" patch for old clients
2234 flags = TRUNCATE_FLAG_OPENED;
2235 }
2236 }
2237 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2238 } else {
2239 gids = get32bit(&data);
2240 if (length!=25+4*gids) {
2241 syslog(LOG_NOTICE,"CLTOMA_FUSE_TRUNCATE - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2242 eptr->mode = KILL;
2243 return;
2244 }
2245 gid = matoclserv_gid_storage(gids);
2246 for (i=0 ; i<gids ; i++) {
2247 gid[i] = get32bit(&data);
2248 }
2249 agid = gid[0];
2250 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2251 }
2252 fleng = get64bit(&data);
2253 matoclserv_fuse_truncate_common(eptr,msgid,inode,flags,uid,gids,gid,auid,agid,fleng);
2254 }
2255
matoclserv_fuse_readlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2256 void matoclserv_fuse_readlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2257 uint32_t inode;
2258 uint32_t pleng;
2259 uint8_t *path;
2260 uint32_t msgid;
2261 uint8_t *ptr;
2262 uint8_t status;
2263 if (length!=8) {
2264 syslog(LOG_NOTICE,"CLTOMA_FUSE_READLINK - wrong size (%"PRIu32"/8)",length);
2265 eptr->mode = KILL;
2266 return;
2267 }
2268 msgid = get32bit(&data);
2269 inode = get32bit(&data);
2270 status = fs_readlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&pleng,&path);
2271 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READLINK,(status!=MFS_STATUS_OK)?5:8+pleng+1);
2272 put32bit(&ptr,msgid);
2273 if (status!=MFS_STATUS_OK) {
2274 put8bit(&ptr,status);
2275 } else {
2276 put32bit(&ptr,pleng+1);
2277 if (pleng>0) {
2278 memcpy(ptr,path,pleng);
2279 }
2280 ptr[pleng]=0;
2281 }
2282 sessions_inc_stats(eptr->sesdata,7);
2283 }
2284
matoclserv_fuse_symlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2285 void matoclserv_fuse_symlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2286 uint32_t inode;
2287 uint8_t nleng;
2288 const uint8_t *name,*path;
2289 uint32_t uid,gids,auid,agid;
2290 uint32_t *gid;
2291 uint32_t i;
2292 uint32_t pleng;
2293 uint32_t newinode;
2294 uint8_t attr[ATTR_RECORD_SIZE];
2295 uint32_t msgid;
2296 uint8_t status;
2297 uint8_t *ptr;
2298 if (length<21) {
2299 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32")",length);
2300 eptr->mode = KILL;
2301 return;
2302 }
2303 msgid = get32bit(&data);
2304 inode = get32bit(&data);
2305 nleng = get8bit(&data);
2306 if (length<21U+nleng) {
2307 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2308 eptr->mode = KILL;
2309 return;
2310 }
2311 name = data;
2312 data += nleng;
2313 pleng = get32bit(&data);
2314 if (length<21U+nleng+pleng) {
2315 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8":pleng=%"PRIu32")",length,nleng,pleng);
2316 eptr->mode = KILL;
2317 return;
2318 }
2319 path = data;
2320 data += pleng;
2321 auid = uid = get32bit(&data);
2322 if (length==21U+nleng+pleng) {
2323 gids = 1;
2324 gid = matoclserv_gid_storage(gids);
2325 agid = gid[0] = get32bit(&data);
2326 } else {
2327 gids = get32bit(&data);
2328 if (length!=21U+nleng+pleng+4*gids) {
2329 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8":pleng=%"PRIu32":gids=%"PRIu32")",length,nleng,pleng,gids);
2330 eptr->mode = KILL;
2331 return;
2332 }
2333 gid = matoclserv_gid_storage(gids);
2334 for (i=0 ; i<gids ; i++) {
2335 gid[i] = get32bit(&data);
2336 }
2337 agid = gid[0];
2338 }
2339 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2340 while (pleng>0 && path[pleng-1]==0) {
2341 pleng--;
2342 }
2343 if (sessions_get_disables(eptr->sesdata)&DISABLE_SYMLINK) {
2344 status = MFS_ERROR_EPERM;
2345 } else {
2346 status = fs_symlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,pleng,path,uid,gids,gid,auid,agid,&newinode,attr);
2347 }
2348 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SYMLINK,(status!=MFS_STATUS_OK)?5:(eptr->asize+8));
2349 put32bit(&ptr,msgid);
2350 if (status!=MFS_STATUS_OK) {
2351 put8bit(&ptr,status);
2352 } else {
2353 put32bit(&ptr,newinode);
2354 memcpy(ptr,attr,eptr->asize);
2355 }
2356 sessions_inc_stats(eptr->sesdata,6);
2357 }
2358
matoclserv_fuse_mknod(matoclserventry * eptr,const uint8_t * data,uint32_t length)2359 void matoclserv_fuse_mknod(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2360 uint32_t inode,uid,gids,auid,agid,rdev;
2361 uint32_t *gid;
2362 uint32_t i;
2363 uint8_t nleng;
2364 const uint8_t *name;
2365 uint8_t type;
2366 uint16_t mode,cumask;
2367 uint32_t disables;
2368 uint32_t newinode;
2369 uint8_t attr[ATTR_RECORD_SIZE];
2370 uint32_t msgid;
2371 uint8_t *ptr;
2372 uint8_t status;
2373 if (length<24) {
2374 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32")",length);
2375 eptr->mode = KILL;
2376 return;
2377 }
2378 msgid = get32bit(&data);
2379 inode = get32bit(&data);
2380 nleng = get8bit(&data);
2381 if (length!=24U+nleng && length<26U+nleng) {
2382 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2383 eptr->mode = KILL;
2384 return;
2385 }
2386 name = data;
2387 data += nleng;
2388 type = get8bit(&data);
2389 mode = get16bit(&data);
2390 if (length>=26U+nleng) {
2391 cumask = get16bit(&data);
2392 } else {
2393 cumask = 0;
2394 }
2395 cumask |= sessions_get_umask(eptr->sesdata);
2396 auid = uid = get32bit(&data);
2397 if (length<=26U+nleng) {
2398 gids = 1;
2399 gid = matoclserv_gid_storage(gids);
2400 agid = gid[0] = get32bit(&data);
2401 } else {
2402 gids = get32bit(&data);
2403 if (length!=26U+nleng+4*gids) {
2404 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2405 eptr->mode = KILL;
2406 return;
2407 }
2408 gid = matoclserv_gid_storage(gids);
2409 for (i=0 ; i<gids ; i++) {
2410 gid[i] = get32bit(&data);
2411 }
2412 agid = gid[0];
2413 }
2414 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2415 rdev = get32bit(&data);
2416 disables = sessions_get_disables(eptr->sesdata);
2417 if (((disables&DISABLE_MKFIFO) && (type==TYPE_FIFO)) || ((disables&DISABLE_MKDEV) && (type==TYPE_BLOCKDEV || type==TYPE_CHARDEV)) || ((disables&DISABLE_MKSOCK) && (type==TYPE_SOCKET)) || ((disables&DISABLE_CREATE) && (type==TYPE_FILE))) {
2418 status = MFS_ERROR_EPERM;
2419 } else {
2420 status = fs_mknod(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,type,mode,cumask,uid,gids,gid,auid,agid,rdev,&newinode,attr,NULL);
2421 }
2422 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_MKNOD,(status!=MFS_STATUS_OK)?5:(eptr->asize+8));
2423 put32bit(&ptr,msgid);
2424 if (status!=MFS_STATUS_OK) {
2425 put8bit(&ptr,status);
2426 } else {
2427 put32bit(&ptr,newinode);
2428 memcpy(ptr,attr,eptr->asize);
2429 }
2430 sessions_inc_stats(eptr->sesdata,8);
2431 }
2432
matoclserv_fuse_mkdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2433 void matoclserv_fuse_mkdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2434 uint32_t inode,uid,gids,auid,agid;
2435 uint32_t *gid;
2436 uint32_t i;
2437 uint8_t nleng;
2438 const uint8_t *name;
2439 uint16_t mode,cumask;
2440 uint32_t newinode;
2441 uint8_t attr[ATTR_RECORD_SIZE];
2442 uint32_t msgid;
2443 uint8_t *ptr;
2444 uint8_t status;
2445 uint8_t copysgid;
2446 if (length<19) {
2447 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32")",length);
2448 eptr->mode = KILL;
2449 return;
2450 }
2451 msgid = get32bit(&data);
2452 inode = get32bit(&data);
2453 nleng = get8bit(&data);
2454 if (length!=19U+nleng && length!=20U+nleng && length<22U+nleng) {
2455 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2456 eptr->mode = KILL;
2457 return;
2458 }
2459 name = data;
2460 data += nleng;
2461 mode = get16bit(&data);
2462 if (length>=22U+nleng) {
2463 cumask = get16bit(&data);
2464 } else {
2465 cumask = 0;
2466 }
2467 cumask |= sessions_get_umask(eptr->sesdata);
2468 auid = uid = get32bit(&data);
2469 if (length<=22U+nleng) {
2470 gids = 1;
2471 gid = matoclserv_gid_storage(gids);
2472 agid = gid[0] = get32bit(&data);
2473 } else {
2474 gids = get32bit(&data);
2475 if (length!=22U+nleng+4*gids) {
2476 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2477 eptr->mode = KILL;
2478 return;
2479 }
2480 gid = matoclserv_gid_storage(gids);
2481 for (i=0 ; i<gids ; i++) {
2482 gid[i] = get32bit(&data);
2483 }
2484 agid = gid[0];
2485 }
2486 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2487 if (length>20U+nleng) {
2488 copysgid = get8bit(&data);
2489 } else {
2490 copysgid = 0; // by default do not copy sgid bit
2491 }
2492 if (sessions_get_disables(eptr->sesdata)&DISABLE_MKDIR) {
2493 status = MFS_ERROR_EPERM;
2494 } else {
2495 status = fs_mkdir(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,mode,cumask,uid,gids,gid,auid,agid,copysgid,&newinode,attr);
2496 }
2497 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_MKDIR,(status!=MFS_STATUS_OK)?5:(eptr->asize+8));
2498 put32bit(&ptr,msgid);
2499 if (status!=MFS_STATUS_OK) {
2500 put8bit(&ptr,status);
2501 } else {
2502 put32bit(&ptr,newinode);
2503 memcpy(ptr,attr,eptr->asize);
2504 }
2505 sessions_inc_stats(eptr->sesdata,4);
2506 }
2507
matoclserv_fuse_unlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2508 void matoclserv_fuse_unlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2509 uint32_t inode,uid,gids,uinode;
2510 uint32_t *gid;
2511 uint32_t i;
2512 uint8_t nleng;
2513 const uint8_t *name;
2514 uint32_t msgid;
2515 uint8_t *ptr;
2516 uint8_t status;
2517 if (length<17) {
2518 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32")",length);
2519 eptr->mode = KILL;
2520 return;
2521 }
2522 msgid = get32bit(&data);
2523 inode = get32bit(&data);
2524 nleng = get8bit(&data);
2525 if (length<17U+nleng) {
2526 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2527 eptr->mode = KILL;
2528 return;
2529 }
2530 name = data;
2531 data += nleng;
2532 uid = get32bit(&data);
2533 if (length==17U+nleng) {
2534 gids = 1;
2535 gid = matoclserv_gid_storage(gids);
2536 gid[0] = get32bit(&data);
2537 } else {
2538 gids = get32bit(&data);
2539 if (length!=17U+nleng+4*gids) {
2540 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2541 eptr->mode = KILL;
2542 return;
2543 }
2544 gid = matoclserv_gid_storage(gids);
2545 for (i=0 ; i<gids ; i++) {
2546 gid[i] = get32bit(&data);
2547 }
2548 }
2549 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2550 if (sessions_get_disables(eptr->sesdata)&DISABLE_UNLINK) {
2551 status = MFS_ERROR_EPERM;
2552 } else {
2553 status = fs_unlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid,&uinode);
2554 }
2555 if (((eptr->version>=VERSION2INT(3,0,107) && eptr->version<VERSION2INT(4,0,0)) || eptr->version>=VERSION2INT(4,18,0)) && status==MFS_STATUS_OK) {
2556 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_UNLINK,8);
2557 put32bit(&ptr,msgid);
2558 put32bit(&ptr,uinode);
2559 } else {
2560 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_UNLINK,5);
2561 put32bit(&ptr,msgid);
2562 put8bit(&ptr,status);
2563 }
2564 sessions_inc_stats(eptr->sesdata,9);
2565 }
2566
matoclserv_fuse_rmdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2567 void matoclserv_fuse_rmdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2568 uint32_t inode,uid,gids,uinode;
2569 uint32_t *gid;
2570 uint32_t i;
2571 uint8_t nleng;
2572 const uint8_t *name;
2573 uint32_t msgid;
2574 uint8_t *ptr;
2575 uint8_t status;
2576 if (length<17) {
2577 syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32")",length);
2578 eptr->mode = KILL;
2579 return;
2580 }
2581 msgid = get32bit(&data);
2582 inode = get32bit(&data);
2583 nleng = get8bit(&data);
2584 if (length<17U+nleng) {
2585 syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2586 eptr->mode = KILL;
2587 return;
2588 }
2589 name = data;
2590 data += nleng;
2591 uid = get32bit(&data);
2592 if (length==17U+nleng) {
2593 gids = 1;
2594 gid = matoclserv_gid_storage(gids);
2595 gid[0] = get32bit(&data);
2596 } else {
2597 gids = get32bit(&data);
2598 if (length!=17U+nleng+4*gids) {
2599 syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2600 eptr->mode = KILL;
2601 return;
2602 }
2603 gid = matoclserv_gid_storage(gids);
2604 for (i=0 ; i<gids ; i++) {
2605 gid[i] = get32bit(&data);
2606 }
2607 }
2608 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2609 if (sessions_get_disables(eptr->sesdata)&DISABLE_RMDIR) {
2610 status = MFS_ERROR_EPERM;
2611 } else {
2612 status = fs_rmdir(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid,&uinode);
2613 }
2614 if (((eptr->version>=VERSION2INT(3,0,107) && eptr->version<VERSION2INT(4,0,0)) || eptr->version>=VERSION2INT(4,18,0)) && status==MFS_STATUS_OK) {
2615 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RMDIR,8);
2616 put32bit(&ptr,msgid);
2617 put32bit(&ptr,uinode);
2618 } else {
2619 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RMDIR,5);
2620 put32bit(&ptr,msgid);
2621 put8bit(&ptr,status);
2622 }
2623 sessions_inc_stats(eptr->sesdata,5);
2624 }
2625
matoclserv_fuse_rename(matoclserventry * eptr,const uint8_t * data,uint32_t length)2626 void matoclserv_fuse_rename(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2627 uint32_t inode,inode_src,inode_dst;
2628 uint8_t nleng_src,nleng_dst;
2629 const uint8_t *name_src,*name_dst;
2630 uint32_t uid,gids,auid,agid;
2631 uint32_t *gid;
2632 uint32_t i;
2633 uint32_t disables;
2634 uint8_t attr[ATTR_RECORD_SIZE];
2635 uint32_t msgid;
2636 uint8_t status;
2637 uint8_t *ptr;
2638 if (length<22) {
2639 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32")",length);
2640 eptr->mode = KILL;
2641 return;
2642 }
2643 msgid = get32bit(&data);
2644 inode_src = get32bit(&data);
2645 nleng_src = get8bit(&data);
2646 if (length<22U+nleng_src) {
2647 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8")",length,nleng_src);
2648 eptr->mode = KILL;
2649 return;
2650 }
2651 name_src = data;
2652 data += nleng_src;
2653 inode_dst = get32bit(&data);
2654 nleng_dst = get8bit(&data);
2655 if (length<22U+nleng_src+nleng_dst) {
2656 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8":nleng_dst=%"PRIu8")",length,nleng_src,nleng_dst);
2657 eptr->mode = KILL;
2658 return;
2659 }
2660 name_dst = data;
2661 data += nleng_dst;
2662 auid = uid = get32bit(&data);
2663 if (length==22U+nleng_src+nleng_dst) {
2664 gids = 1;
2665 gid = matoclserv_gid_storage(gids);
2666 agid = gid[0] = get32bit(&data);
2667 } else {
2668 gids = get32bit(&data);
2669 if (length!=22U+nleng_src+nleng_dst+4*gids) {
2670 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_src,nleng_dst,gids);
2671 eptr->mode = KILL;
2672 return;
2673 }
2674 gid = matoclserv_gid_storage(gids);
2675 for (i=0 ; i<gids ; i++) {
2676 gid[i] = get32bit(&data);
2677 }
2678 agid = gid[0];
2679 }
2680 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2681 disables = sessions_get_disables(eptr->sesdata);
2682 if ((disables&(DISABLE_RENAME|DISABLE_MOVE))==(DISABLE_RENAME|DISABLE_MOVE) || ((disables&DISABLE_RENAME) && (nleng_src!=nleng_dst || memcmp(name_src,name_dst,nleng_src)!=0)) || ((disables&DISABLE_MOVE) && inode_src!=inode_dst)) {
2683 status = MFS_ERROR_EPERM;
2684 } else {
2685 status = fs_rename(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode_src,nleng_src,name_src,inode_dst,nleng_dst,name_dst,uid,gids,gid,auid,agid,((disables&DISABLE_UNLINK)?1:0)|((disables&DISABLE_RMDIR)?2:0),&inode,attr);
2686 }
2687 if (eptr->version>=VERSION2INT(1,6,21) && status==MFS_STATUS_OK) {
2688 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RENAME,eptr->asize+8);
2689 } else {
2690 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RENAME,5);
2691 }
2692 put32bit(&ptr,msgid);
2693 if (eptr->version>=VERSION2INT(1,6,21) && status==MFS_STATUS_OK) {
2694 put32bit(&ptr,inode);
2695 memcpy(ptr,attr,eptr->asize);
2696 } else {
2697 put8bit(&ptr,status);
2698 }
2699 sessions_inc_stats(eptr->sesdata,10);
2700 }
2701
matoclserv_fuse_link(matoclserventry * eptr,const uint8_t * data,uint32_t length)2702 void matoclserv_fuse_link(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2703 uint32_t inode,inode_dst;
2704 uint8_t nleng_dst;
2705 const uint8_t *name_dst;
2706 uint32_t uid,gids,auid,agid;
2707 uint32_t *gid;
2708 uint32_t i;
2709 uint32_t newinode;
2710 uint8_t attr[ATTR_RECORD_SIZE];
2711 uint32_t msgid;
2712 uint8_t *ptr;
2713 uint8_t status;
2714 if (length<21) {
2715 syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32")",length);
2716 eptr->mode = KILL;
2717 return;
2718 }
2719 msgid = get32bit(&data);
2720 inode = get32bit(&data);
2721 inode_dst = get32bit(&data);
2722 nleng_dst = get8bit(&data);
2723 if (length<21U+nleng_dst) {
2724 syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32":nleng_dst=%"PRIu8")",length,nleng_dst);
2725 eptr->mode = KILL;
2726 return;
2727 }
2728 name_dst = data;
2729 data += nleng_dst;
2730 auid = uid = get32bit(&data);
2731 if (length==21U+nleng_dst) {
2732 gids = 1;
2733 gid = matoclserv_gid_storage(gids);
2734 agid = gid[0] = get32bit(&data);
2735 } else {
2736 gids = get32bit(&data);
2737 if (length!=21U+nleng_dst+4*gids) {
2738 syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_dst,gids);
2739 eptr->mode = KILL;
2740 return;
2741 }
2742 gid = matoclserv_gid_storage(gids);
2743 for (i=0 ; i<gids ; i++) {
2744 gid[i] = get32bit(&data);
2745 }
2746 agid = gid[0];
2747 }
2748 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2749 if (sessions_get_disables(eptr->sesdata)&DISABLE_LINK) {
2750 status = MFS_ERROR_EPERM;
2751 } else {
2752 status = fs_link(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,inode_dst,nleng_dst,name_dst,uid,gids,gid,auid,agid,&newinode,attr);
2753 }
2754 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LINK,(status!=MFS_STATUS_OK)?5:(eptr->asize+8));
2755 put32bit(&ptr,msgid);
2756 if (status!=MFS_STATUS_OK) {
2757 put8bit(&ptr,status);
2758 } else {
2759 put32bit(&ptr,newinode);
2760 memcpy(ptr,attr,eptr->asize);
2761 }
2762 sessions_inc_stats(eptr->sesdata,11);
2763 }
2764
matoclserv_fuse_readdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2765 void matoclserv_fuse_readdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2766 uint32_t inode,uid,gids,auid,agid;
2767 uint32_t *gid;
2768 uint32_t i;
2769 uint8_t flags;
2770 uint32_t msgid;
2771 uint8_t *ptr;
2772 uint8_t status;
2773 uint32_t dleng;
2774 uint32_t maxentries;
2775 uint64_t nedgeid;
2776 uint8_t attrmode;
2777 void *c1,*c2;
2778
2779 if (eptr->asize==35) {
2780 attrmode = 1;
2781 } else if (eptr->asize==ATTR_RECORD_SIZE) {
2782 attrmode = 2;
2783 } else {
2784 syslog(LOG_NOTICE,"CLTOMA_FUSE_READDIR - requested attr size not implemented");
2785 eptr->mode = KILL;
2786 return;
2787 }
2788 if (length!=16 && length!=17 && length<29) {
2789 syslog(LOG_NOTICE,"CLTOMA_FUSE_READDIR - wrong size (%"PRIu32"/16|17|29+N*4)",length);
2790 eptr->mode = KILL;
2791 return;
2792 }
2793 msgid = get32bit(&data);
2794 inode = get32bit(&data);
2795 auid = uid = get32bit(&data);
2796 if (length<=29) {
2797 gids = 1;
2798 gid = matoclserv_gid_storage(gids);
2799 agid = gid[0] = get32bit(&data);
2800 } else {
2801 gids = get32bit(&data);
2802 if (length!=29+4*gids) {
2803 syslog(LOG_NOTICE,"CLTOMA_FUSE_READDIR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2804 eptr->mode = KILL;
2805 return;
2806 }
2807 gid = matoclserv_gid_storage(gids);
2808 for (i=0 ; i<gids ; i++) {
2809 gid[i] = get32bit(&data);
2810 }
2811 agid = gid[0];
2812 }
2813 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2814 if (length>=17) {
2815 flags = get8bit(&data);
2816 } else {
2817 flags = 0;
2818 }
2819 if (length>=29) {
2820 maxentries = get32bit(&data);
2821 nedgeid = get64bit(&data);
2822 } else {
2823 maxentries = 0xFFFFFFFF;
2824 nedgeid = 0;
2825 }
2826 if (sessions_get_disables(eptr->sesdata)&DISABLE_READDIR) {
2827 status = MFS_ERROR_EPERM;
2828 } else {
2829 status = fs_readdir_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,flags,maxentries,nedgeid,&c1,&c2,&dleng,attrmode);
2830 }
2831 if (status!=MFS_STATUS_OK) {
2832 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,5);
2833 } else if (length>=29) {
2834 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,12+dleng);
2835 } else {
2836 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,4+dleng);
2837 }
2838 put32bit(&ptr,msgid);
2839 if (status!=MFS_STATUS_OK) {
2840 put8bit(&ptr,status);
2841 } else {
2842 if (length>=29) {
2843 put64bit(&ptr,nedgeid);
2844 }
2845 fs_readdir_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),uid,gid[0],auid,agid,flags,maxentries,&nedgeid,c1,c2,ptr,attrmode);
2846 }
2847 sessions_inc_stats(eptr->sesdata,12);
2848 }
2849
matoclserv_fuse_open(matoclserventry * eptr,const uint8_t * data,uint32_t length)2850 void matoclserv_fuse_open(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2851 uint32_t inode,uid,gids,auid,agid;
2852 uint32_t *gid;
2853 uint32_t i;
2854 uint8_t flags;
2855 uint8_t oflags;
2856 uint8_t sesflags;
2857 uint8_t attr[ATTR_RECORD_SIZE];
2858 uint32_t msgid;
2859 uint8_t *ptr;
2860 uint8_t status;
2861 if (length<17) {
2862 syslog(LOG_NOTICE,"CLTOMA_FUSE_OPEN - wrong size (%"PRIu32"/17+N*4)",length);
2863 eptr->mode = KILL;
2864 return;
2865 }
2866 msgid = get32bit(&data);
2867 inode = get32bit(&data);
2868 if (length==17) {
2869 gids = 1;
2870 gid = matoclserv_gid_storage(gids);
2871 auid = uid = get32bit(&data);
2872 agid = gid[0] = get32bit(&data);
2873 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2874 } else {
2875 auid = uid = get32bit(&data);
2876 gids = get32bit(&data);
2877 if (length!=17+gids*4) {
2878 syslog(LOG_NOTICE,"CLTOMA_FUSE_OPEN - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2879 eptr->mode = KILL;
2880 return;
2881 }
2882 gid = matoclserv_gid_storage(gids);
2883 for (i=0 ; i<gids ; i++) {
2884 gid[i] = get32bit(&data);
2885 }
2886 agid = gid[0];
2887 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2888 }
2889 flags = get8bit(&data);
2890 oflags = 0;
2891 sesflags = sessions_get_sesflags(eptr->sesdata);
2892 if ((flags&OPEN_TRUNCATE) && sessions_get_disables(eptr->sesdata)&DISABLE_TRUNCATE) {
2893 status = MFS_ERROR_EPERM;
2894 } else {
2895 status = fs_opencheck(sessions_get_rootinode(eptr->sesdata),sesflags,inode,uid,gids,gid,auid,agid,flags,attr,&oflags);
2896 }
2897 if (status==MFS_STATUS_OK && eptr->version<VERSION2INT(3,0,113) && (oflags&OPEN_APPENDONLY) && (flags&OPEN_WRITE)) {
2898 // this mount doesn't support append only, so we should deny access to any write
2899 status=MFS_ERROR_EACCES;
2900 }
2901 if (status==MFS_STATUS_OK) {
2902 of_openfile(sessions_get_id(eptr->sesdata),inode);
2903 if (flags&OPEN_CACHE_CLEARED) {
2904 dcm_access(inode,sessions_get_id(eptr->sesdata));
2905 }
2906 }
2907 if (eptr->version>=VERSION2INT(1,6,9) && status==MFS_STATUS_OK) {
2908 if (eptr->version>=VERSION2INT(3,0,113)) {
2909 if ((oflags&OPEN_DIRECTMODE)==0) {
2910 if (dcm_open(inode,sessions_get_id(eptr->sesdata))) {
2911 oflags |= OPEN_KEEPCACHE;
2912 } else { // just fix for old clients
2913 if (sesflags&SESFLAG_ATTRBIT) {
2914 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2915 } else {
2916 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2917 }
2918 }
2919 }
2920 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_OPEN,(eptr->asize+5));
2921 put32bit(&ptr,msgid);
2922 put8bit(&ptr,oflags);
2923 memcpy(ptr,attr,eptr->asize);
2924 } else {
2925 if ((sesflags&SESFLAG_ATTRBIT)==0 || (attr[0]&MATTR_DIRECTMODE)==0) {
2926 if (dcm_open(inode,sessions_get_id(eptr->sesdata))==0) {
2927 if (sesflags&SESFLAG_ATTRBIT) {
2928 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2929 } else {
2930 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2931 }
2932 }
2933 }
2934 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_OPEN,(eptr->asize+4));
2935 put32bit(&ptr,msgid);
2936 memcpy(ptr,attr,eptr->asize);
2937 }
2938 } else {
2939 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_OPEN,5);
2940 put32bit(&ptr,msgid);
2941 put8bit(&ptr,status);
2942 }
2943 sessions_inc_stats(eptr->sesdata,13);
2944 }
2945
matoclserv_fuse_create(matoclserventry * eptr,const uint8_t * data,uint32_t length)2946 void matoclserv_fuse_create(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2947 uint32_t inode,uid,gids,auid,agid;
2948 uint32_t *gid;
2949 uint32_t i;
2950 uint8_t nleng;
2951 const uint8_t *name;
2952 uint16_t mode,cumask;
2953 uint32_t newinode;
2954 uint8_t attr[ATTR_RECORD_SIZE];
2955 uint32_t msgid;
2956 uint8_t *ptr;
2957 uint8_t status;
2958 uint8_t oflags;
2959 uint8_t sesflags;
2960 if (length<19) {
2961 syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32")",length);
2962 eptr->mode = KILL;
2963 return;
2964 }
2965 msgid = get32bit(&data);
2966 inode = get32bit(&data);
2967 nleng = get8bit(&data);
2968 if (length!=19U+nleng && length<21U+nleng) {
2969 syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2970 eptr->mode = KILL;
2971 return;
2972 }
2973 name = data;
2974 data += nleng;
2975 mode = get16bit(&data);
2976 if (length>=21U+nleng) {
2977 cumask = get16bit(&data);
2978 } else {
2979 cumask = 0;
2980 }
2981 cumask |= sessions_get_umask(eptr->sesdata);
2982 auid = uid = get32bit(&data);
2983 if (length<=21U+nleng) {
2984 gids = 1;
2985 gid = matoclserv_gid_storage(gids);
2986 agid = gid[0] = get32bit(&data);
2987 } else {
2988 gids = get32bit(&data);
2989 if (length!=21U+nleng+4*gids) {
2990 syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2991 eptr->mode = KILL;
2992 return;
2993 }
2994 gid = matoclserv_gid_storage(gids);
2995 for (i=0 ; i<gids ; i++) {
2996 gid[i] = get32bit(&data);
2997 }
2998 agid = gid[0];
2999 }
3000 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3001 sesflags = sessions_get_sesflags(eptr->sesdata);
3002 if (sessions_get_disables(eptr->sesdata)&DISABLE_CREATE) {
3003 status = MFS_ERROR_EPERM;
3004 } else {
3005 status = fs_mknod(sessions_get_rootinode(eptr->sesdata),sesflags,inode,nleng,name,TYPE_FILE,mode,cumask,uid,gids,gid,auid,agid,0,&newinode,attr,&oflags);
3006 }
3007 if (status==MFS_STATUS_OK) {
3008 if (CreateFirstChunk) {
3009 uint64_t prevchunkid,chunkid,fleng;
3010 uint8_t opflag;
3011 swchunks *swc;
3012 /* create first chunk */
3013 if (fs_writechunk(newinode,0,0,&prevchunkid,&chunkid,&fleng,&opflag,eptr->peerip)==MFS_STATUS_OK) {
3014 massert(prevchunkid==0,"chunk created after mknod - prevchunkid should be always zero");
3015 if (opflag) {
3016 i = CHUNKHASH(chunkid);
3017 swc = malloc(sizeof(swchunks));
3018 passert(swc);
3019 swc->eptr = eptr;
3020 swc->inode = newinode;
3021 swc->indx = 0;
3022 swc->prevchunkid = prevchunkid;
3023 swc->chunkid = chunkid;
3024 swc->msgid = 0;
3025 swc->fleng = fleng;
3026 swc->type = FUSE_CREATE;
3027 swc->next = swchunkshash[i];
3028 swchunkshash[i] = swc;
3029 } else {
3030 fs_writeend(newinode,0,chunkid,0,NULL); // no operation? - just unlock this chunk
3031 }
3032 }
3033 }
3034 /* open file */
3035 of_openfile(sessions_get_id(eptr->sesdata),newinode);
3036 if (eptr->version>=VERSION2INT(3,0,113)) {
3037 if ((oflags&OPEN_DIRECTMODE)==0) {
3038 // testing dcm_open doesn't make sense here - this is new inode
3039 // if (dcm_open(newinode,sessions_get_id(eptr->sesdata))) {
3040 // oflags |= OPEN_KEEPCACHE;
3041 // } else { // just fix for old clients
3042 if (sesflags&SESFLAG_ATTRBIT) {
3043 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
3044 } else {
3045 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
3046 }
3047 // }
3048 }
3049 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CREATE,eptr->asize+9);
3050 put32bit(&ptr,msgid);
3051 put8bit(&ptr,oflags);
3052 put32bit(&ptr,newinode);
3053 memcpy(ptr,attr,eptr->asize);
3054 } else {
3055 if ((sesflags&SESFLAG_ATTRBIT)==0 || (attr[0]&MATTR_DIRECTMODE)==0) {
3056 // if (dcm_open(newinode,sessions_get_id(eptr->sesdata))==0) {
3057 if (sesflags&SESFLAG_ATTRBIT) {
3058 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
3059 } else {
3060 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
3061 }
3062 // }
3063 }
3064 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CREATE,eptr->asize+8);
3065 put32bit(&ptr,msgid);
3066 put32bit(&ptr,newinode);
3067 memcpy(ptr,attr,eptr->asize);
3068 }
3069 } else {
3070 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CREATE,5);
3071 put32bit(&ptr,msgid);
3072 put8bit(&ptr,status);
3073 }
3074 sessions_inc_stats(eptr->sesdata,8);
3075 sessions_inc_stats(eptr->sesdata,13);
3076 }
3077
matoclserv_fuse_read_chunk(matoclserventry * eptr,const uint8_t * data,uint32_t length)3078 void matoclserv_fuse_read_chunk(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3079 uint32_t inode;
3080 uint32_t indx;
3081 uint8_t chunkopflags;
3082 uint32_t msgid;
3083
3084 if (length!=12 && length!=13) {
3085 syslog(LOG_NOTICE,"CLTOMA_FUSE_READ_CHUNK - wrong size (%"PRIu32"/12|13)",length);
3086 eptr->mode = KILL;
3087 return;
3088 }
3089 msgid = get32bit(&data);
3090 inode = get32bit(&data);
3091 indx = get32bit(&data);
3092 if (length==13) {
3093 chunkopflags = get8bit(&data);
3094 } else {
3095 chunkopflags = CHUNKOPFLAG_CANMODTIME;
3096 }
3097 if (eptr->version>=VERSION2INT(3,0,74)) {
3098 chunkopflags &= ~CHUNKOPFLAG_CANMODTIME;
3099 }
3100 matoclserv_fuse_read_chunk_common(eptr,msgid,inode,indx,chunkopflags);
3101 }
3102
matoclserv_fuse_write_chunk(matoclserventry * eptr,const uint8_t * data,uint32_t length)3103 void matoclserv_fuse_write_chunk(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3104 uint32_t inode;
3105 uint32_t indx;
3106 uint32_t msgid;
3107 uint8_t chunkopflags;
3108
3109 if (length!=12 && length!=13) {
3110 syslog(LOG_NOTICE,"CLTOMA_FUSE_WRITE_CHUNK - wrong size (%"PRIu32"/12|13)",length);
3111 eptr->mode = KILL;
3112 return;
3113 }
3114 msgid = get32bit(&data);
3115 inode = get32bit(&data);
3116 indx = get32bit(&data);
3117 if (length>=13) {
3118 chunkopflags = get8bit(&data);
3119 } else {
3120 chunkopflags = CHUNKOPFLAG_CANMODTIME;
3121 }
3122 if (eptr->version>=VERSION2INT(3,0,74)) {
3123 chunkopflags &= ~CHUNKOPFLAG_CANMODTIME;
3124 }
3125 matoclserv_fuse_write_chunk_common(eptr,msgid,inode,indx,chunkopflags);
3126 }
3127
matoclserv_fuse_write_chunk_end(matoclserventry * eptr,const uint8_t * data,uint32_t length)3128 void matoclserv_fuse_write_chunk_end(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3129 uint8_t *ptr;
3130 uint32_t msgid;
3131 uint32_t inode;
3132 uint64_t fleng;
3133 uint32_t indx;
3134 uint32_t version;
3135 uint64_t chunkid;
3136 uint8_t status;
3137 uint8_t chunkopflags;
3138 uint8_t flenghaschanged;
3139 // chunklist *cl,**acl;
3140 if (length!=24 && length!=25 && length!=29) {
3141 syslog(LOG_NOTICE,"CLTOMA_FUSE_WRITE_CHUNK_END - wrong size (%"PRIu32"/24|25|29)",length);
3142 eptr->mode = KILL;
3143 return;
3144 }
3145 msgid = get32bit(&data);
3146 chunkid = get64bit(&data);
3147 inode = get32bit(&data);
3148 if (length>=29) {
3149 indx = get32bit(&data);
3150 } else {
3151 indx = 0;
3152 }
3153 fleng = get64bit(&data);
3154 if (length>=25) {
3155 chunkopflags = get8bit(&data);
3156 } else {
3157 chunkopflags = CHUNKOPFLAG_CANMODTIME;
3158 }
3159 if (eptr->version>=VERSION2INT(3,0,74)) {
3160 chunkopflags &= ~CHUNKOPFLAG_CANMODTIME;
3161 }
3162 flenghaschanged = 0;
3163 if (sessions_get_disables(eptr->sesdata)&DISABLE_WRITE) {
3164 status = MFS_ERROR_EPERM;
3165 } else if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_READONLY) {
3166 if (eptr->version>=VERSION2INT(3,0,101)) {
3167 status = MFS_ERROR_EROFS;
3168 } else {
3169 status = MFS_ERROR_IO;
3170 }
3171 } else {
3172 status = fs_writeend(inode,fleng,chunkid,chunkopflags,&flenghaschanged);
3173 }
3174 dcm_modify(inode,sessions_get_id(eptr->sesdata));
3175 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK_END,5);
3176 put32bit(&ptr,msgid);
3177 put8bit(&ptr,status);
3178 if (length==29) {
3179 chunk_get_version(chunkid,&version);
3180 matoclserv_fuse_chunk_has_changed(eptr,inode,indx,chunkid,version,fleng,0);
3181 } else if (flenghaschanged) {
3182 matoclserv_fuse_fleng_has_changed(eptr,inode,fleng);
3183 }
3184 }
3185
matoclserv_fuse_chunk_has_changed(matoclserventry * eptr,uint32_t inode,uint32_t chindx,uint64_t chunkid,uint32_t version,uint64_t fleng,uint8_t truncateflag)3186 void matoclserv_fuse_chunk_has_changed(matoclserventry *eptr,uint32_t inode,uint32_t chindx,uint64_t chunkid,uint32_t version,uint64_t fleng,uint8_t truncateflag) {
3187 matoclserventry *xeptr;
3188 uint8_t *ptr;
3189 for (xeptr=matoclservhead ; xeptr ; xeptr=xeptr->next) {
3190 if (xeptr!=eptr && xeptr->mode==DATA && xeptr->registered==1 && xeptr->sesdata!=NULL && xeptr->version>=VERSION2INT(3,0,74)) {
3191 if (of_isfileopened_by_session(inode,sessions_get_id(xeptr->sesdata))) {
3192 ptr = matoclserv_createpacket(xeptr,MATOCL_FUSE_CHUNK_HAS_CHANGED,33);
3193 put32bit(&ptr,0);
3194 put32bit(&ptr,inode);
3195 put32bit(&ptr,chindx);
3196 put64bit(&ptr,chunkid);
3197 put32bit(&ptr,version);
3198 put64bit(&ptr,fleng);
3199 put8bit(&ptr,truncateflag);
3200 }
3201 }
3202 }
3203 }
3204
matoclserv_fuse_fleng_has_changed(matoclserventry * eptr,uint32_t inode,uint64_t fleng)3205 void matoclserv_fuse_fleng_has_changed(matoclserventry *eptr,uint32_t inode,uint64_t fleng) {
3206 matoclserventry *xeptr;
3207 uint8_t *ptr;
3208 for (xeptr=matoclservhead ; xeptr ; xeptr=xeptr->next) {
3209 if (xeptr!=eptr && xeptr->mode==DATA && xeptr->registered==1 && xeptr->sesdata!=NULL && xeptr->version>=VERSION2INT(3,0,74)) {
3210 if (of_isfileopened_by_session(inode,sessions_get_id(xeptr->sesdata))) {
3211 ptr = matoclserv_createpacket(xeptr,MATOCL_FUSE_FLENG_HAS_CHANGED,16);
3212 put32bit(&ptr,0);
3213 put32bit(&ptr,inode);
3214 put64bit(&ptr,fleng);
3215 }
3216 }
3217 }
3218 }
3219
matoclserv_fuse_invalidate_chunk_cache(void)3220 void matoclserv_fuse_invalidate_chunk_cache(void) {
3221 matoclserventry *xeptr;
3222 uint8_t *ptr;
3223 for (xeptr=matoclservhead ; xeptr ; xeptr=xeptr->next) {
3224 if (xeptr->mode==DATA && xeptr->registered==1 && xeptr->sesdata!=NULL && (xeptr->version>=VERSION2INT(4,3,0) || (xeptr->version>=VERSION2INT(3,0,100) && xeptr->version<VERSION2INT(4,0,0)))) {
3225 ptr = matoclserv_createpacket(xeptr,MATOCL_FUSE_INVALIDATE_CHUNK_CACHE,4);
3226 put32bit(&ptr,0);
3227 }
3228 }
3229 }
3230
matoclserv_find_connection(uint32_t sessionid)3231 static inline matoclserventry* matoclserv_find_connection(uint32_t sessionid) {
3232 matoclserventry *eptr;
3233 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
3234 if (eptr->mode==DATA && eptr->registered==1 && eptr->sesdata!=NULL) {
3235 if (sessions_get_id(eptr->sesdata)==sessionid) {
3236 return eptr;
3237 }
3238 }
3239 }
3240 return NULL;
3241 }
3242
matoclserv_fuse_flock_wake_up(uint32_t sessionid,uint32_t msgid,uint8_t status)3243 void matoclserv_fuse_flock_wake_up(uint32_t sessionid,uint32_t msgid,uint8_t status) {
3244 matoclserventry *eptr;
3245 uint8_t *ptr;
3246 eptr = matoclserv_find_connection(sessionid);
3247 if (eptr==NULL) {
3248 return;
3249 }
3250 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_FLOCK,5);
3251 put32bit(&ptr,msgid);
3252 put8bit(&ptr,status);
3253 }
3254
matoclserv_fuse_flock(matoclserventry * eptr,const uint8_t * data,uint32_t length)3255 void matoclserv_fuse_flock(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3256 uint32_t msgid;
3257 uint32_t inode;
3258 uint32_t reqid;
3259 uint64_t owner;
3260 uint8_t cmd;
3261 uint8_t *ptr;
3262 uint8_t status;
3263 if (length!=21) {
3264 syslog(LOG_NOTICE,"CLTOMA_FUSE_FLOCK - wrong size (%"PRIu32"/21)",length);
3265 eptr->mode = KILL;
3266 return;
3267 }
3268 msgid = get32bit(&data);
3269 inode = get32bit(&data);
3270 reqid = get32bit(&data);
3271 owner = get64bit(&data);
3272 cmd = get8bit(&data);
3273 status = flock_locks_cmd(sessions_get_id(eptr->sesdata),msgid,reqid,inode,owner,cmd);
3274 if (status==MFS_ERROR_WAITING) {
3275 return;
3276 }
3277 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_FLOCK,5);
3278 put32bit(&ptr,msgid);
3279 put8bit(&ptr,status);
3280 }
3281
matoclserv_fuse_posix_lock_wake_up(uint32_t sessionid,uint32_t msgid,uint8_t status)3282 void matoclserv_fuse_posix_lock_wake_up(uint32_t sessionid,uint32_t msgid,uint8_t status) {
3283 matoclserventry *eptr;
3284 uint8_t *ptr;
3285 eptr = matoclserv_find_connection(sessionid);
3286 if (eptr==NULL) {
3287 return;
3288 }
3289 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_POSIX_LOCK,5);
3290 put32bit(&ptr,msgid);
3291 put8bit(&ptr,status);
3292 }
3293
matoclserv_fuse_posix_lock(matoclserventry * eptr,const uint8_t * data,uint32_t length)3294 void matoclserv_fuse_posix_lock(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3295 uint32_t msgid;
3296 uint32_t inode;
3297 uint32_t reqid;
3298 uint32_t pid;
3299 uint64_t owner;
3300 uint64_t start,end;
3301 uint8_t cmd,type;
3302 uint8_t *ptr;
3303 uint8_t status;
3304 if (length!=42) {
3305 syslog(LOG_NOTICE,"CLTOMA_FUSE_POSIX_LOCK - wrong size (%"PRIu32"/42)",length);
3306 eptr->mode = KILL;
3307 return;
3308 }
3309 msgid = get32bit(&data);
3310 inode = get32bit(&data);
3311 reqid = get32bit(&data);
3312 owner = get64bit(&data);
3313 pid = get32bit(&data);
3314 cmd = get8bit(&data);
3315 type = get8bit(&data);
3316 start = get64bit(&data);
3317 end = get64bit(&data);
3318 status = posix_lock_cmd(sessions_get_id(eptr->sesdata),msgid,reqid,inode,owner,cmd,&type,&start,&end,&pid);
3319 if (status==MFS_ERROR_WAITING) {
3320 return;
3321 }
3322 if (cmd==POSIX_LOCK_CMD_GET && status==MFS_STATUS_OK) {
3323 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_POSIX_LOCK,25);
3324 put32bit(&ptr,msgid);
3325 put32bit(&ptr,pid);
3326 put8bit(&ptr,type);
3327 put64bit(&ptr,start);
3328 put64bit(&ptr,end);
3329 } else {
3330 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_POSIX_LOCK,5);
3331 put32bit(&ptr,msgid);
3332 put8bit(&ptr,status);
3333 }
3334 }
3335
matoclserv_fuse_repair(matoclserventry * eptr,const uint8_t * data,uint32_t length)3336 void matoclserv_fuse_repair(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3337 uint32_t inode,uid,gids;
3338 uint32_t *gid;
3339 uint32_t i;
3340 uint32_t msgid;
3341 uint32_t chunksnotchanged,chunkserased,chunksrepaired;
3342 uint8_t *ptr;
3343 uint8_t status;
3344 if (length<16) {
3345 syslog(LOG_NOTICE,"CLTOMA_FUSE_REPAIR - wrong size (%"PRIu32"/16+N*4)",length);
3346 eptr->mode = KILL;
3347 return;
3348 }
3349 msgid = get32bit(&data);
3350 inode = get32bit(&data);
3351 uid = get32bit(&data);
3352 if (length==16) {
3353 gids = 1;
3354 gid = matoclserv_gid_storage(gids);
3355 gid[0] = get32bit(&data);
3356 } else {
3357 gids = get32bit(&data);
3358 if (length!=16+4*gids) {
3359 syslog(LOG_NOTICE,"CLTOMA_FUSE_REPAIR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
3360 eptr->mode = KILL;
3361 return;
3362 }
3363 gid = matoclserv_gid_storage(gids);
3364 for (i=0 ; i<gids ; i++) {
3365 gid[i] = get32bit(&data);
3366 }
3367 }
3368 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3369 status = fs_repair(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,&chunksnotchanged,&chunkserased,&chunksrepaired);
3370 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REPAIR,(status!=MFS_STATUS_OK)?5:16);
3371 put32bit(&ptr,msgid);
3372 if (status!=0) {
3373 put8bit(&ptr,status);
3374 } else {
3375 put32bit(&ptr,chunksnotchanged);
3376 put32bit(&ptr,chunkserased);
3377 put32bit(&ptr,chunksrepaired);
3378 }
3379 }
3380
matoclserv_fuse_check(matoclserventry * eptr,const uint8_t * data,uint32_t length)3381 void matoclserv_fuse_check(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3382 uint32_t inode;
3383 uint32_t indx;
3384 uint64_t chunkid;
3385 uint32_t version;
3386 uint8_t cs_data[100*7];
3387 uint8_t count;
3388 uint32_t i,chunkcount[12];
3389 uint32_t msgid;
3390 uint8_t *ptr;
3391 uint8_t status;
3392 if (length!=8 && length!=12) {
3393 syslog(LOG_NOTICE,"CLTOMA_FUSE_CHECK - wrong size (%"PRIu32"/8|12)",length);
3394 eptr->mode = KILL;
3395 return;
3396 }
3397 msgid = get32bit(&data);
3398 inode = get32bit(&data);
3399 if (length==12) {
3400 indx = get32bit(&data);
3401 status = fs_filechunk(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,indx,&chunkid);
3402 if (status!=MFS_STATUS_OK) {
3403 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,5);
3404 put32bit(&ptr,msgid);
3405 put8bit(&ptr,status);
3406 return;
3407 }
3408 if (chunkid>0) {
3409 status = chunk_get_version_and_copies(chunkid,&version,&count,cs_data);
3410 if (status!=MFS_STATUS_OK) {
3411 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,5);
3412 put32bit(&ptr,msgid);
3413 put8bit(&ptr,status);
3414 return;
3415 }
3416 } else {
3417 version = 0;
3418 count = 0;
3419 }
3420 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,16+count*7);
3421 put32bit(&ptr,msgid);
3422 put64bit(&ptr,chunkid);
3423 put32bit(&ptr,version);
3424 if (count>0) {
3425 memcpy(ptr,cs_data,count*7);
3426 }
3427 } else {
3428 status = fs_checkfile(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,chunkcount);
3429 if (status!=MFS_STATUS_OK) {
3430 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,5);
3431 put32bit(&ptr,msgid);
3432 put8bit(&ptr,status);
3433 return;
3434 }
3435 if (eptr->version>=VERSION2INT(3,0,30)) {
3436 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,52);
3437 put32bit(&ptr,msgid);
3438 for (i=0 ; i<12 ; i++) {
3439 put32bit(&ptr,chunkcount[i]);
3440 }
3441 } else if (eptr->version>=VERSION2INT(1,6,23)) {
3442 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,48);
3443 put32bit(&ptr,msgid);
3444 for (i=0 ; i<11 ; i++) {
3445 put32bit(&ptr,chunkcount[i]);
3446 }
3447 } else {
3448 uint8_t j;
3449 j=0;
3450 for (i=0 ; i<11 ; i++) {
3451 if (chunkcount[i]>0) {
3452 j++;
3453 }
3454 }
3455 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,4+3*j);
3456 put32bit(&ptr,msgid);
3457 for (i=0 ; i<11 ; i++) {
3458 if (chunkcount[i]>0) {
3459 put8bit(&ptr,i);
3460 if (chunkcount[i]<=65535) {
3461 put16bit(&ptr,chunkcount[i]);
3462 } else {
3463 put16bit(&ptr,65535);
3464 }
3465 }
3466 }
3467 }
3468 }
3469 }
3470
3471
matoclserv_fuse_gettrashtime(matoclserventry * eptr,const uint8_t * data,uint32_t length)3472 void matoclserv_fuse_gettrashtime(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3473 uint32_t inode;
3474 uint8_t gmode;
3475 void *fptr,*dptr;
3476 uint32_t fnodes,dnodes;
3477 uint32_t msgid;
3478 uint8_t *ptr;
3479 uint8_t status;
3480 if (length!=9) {
3481 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASHTIME - wrong size (%"PRIu32"/9)",length);
3482 eptr->mode = KILL;
3483 return;
3484 }
3485 msgid = get32bit(&data);
3486 inode = get32bit(&data);
3487 gmode = get8bit(&data);
3488 status = fs_gettrashtime_prepare(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,&fptr,&dptr,&fnodes,&dnodes);
3489 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASHTIME,(status!=MFS_STATUS_OK)?5:12+8*(fnodes+dnodes));
3490 put32bit(&ptr,msgid);
3491 if (status!=MFS_STATUS_OK) {
3492 put8bit(&ptr,status);
3493 } else {
3494 put32bit(&ptr,fnodes);
3495 put32bit(&ptr,dnodes);
3496 fs_gettrashtime_store(fptr,dptr,ptr);
3497 }
3498 }
3499
matoclserv_fuse_settrashtime(matoclserventry * eptr,const uint8_t * data,uint32_t length)3500 void matoclserv_fuse_settrashtime(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3501 uint32_t inode,uid,trashtime;
3502 uint32_t msgid;
3503 uint8_t smode;
3504 uint32_t changed,notchanged,notpermitted;
3505 uint8_t *ptr;
3506 uint8_t status;
3507 if (length!=17) {
3508 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHTIME - wrong size (%"PRIu32"/17)",length);
3509 eptr->mode = KILL;
3510 return;
3511 }
3512 msgid = get32bit(&data);
3513 inode = get32bit(&data);
3514 uid = get32bit(&data);
3515 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3516 trashtime = get32bit(&data);
3517 smode = get8bit(&data);
3518 if (sessions_get_disables(eptr->sesdata)&DISABLE_SETTRASH) {
3519 status = MFS_ERROR_EPERM;
3520 } else {
3521 status = sessions_check_trashtime(eptr->sesdata,smode&SMODE_TMASK,trashtime);
3522 }
3523 if (status==MFS_STATUS_OK) {
3524 status = fs_settrashtime(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,trashtime,smode,&changed,¬changed,¬permitted);
3525 }
3526 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETTRASHTIME,(status!=MFS_STATUS_OK)?5:16);
3527 put32bit(&ptr,msgid);
3528 if (status!=MFS_STATUS_OK) {
3529 put8bit(&ptr,status);
3530 } else {
3531 put32bit(&ptr,changed);
3532 put32bit(&ptr,notchanged);
3533 put32bit(&ptr,notpermitted);
3534 }
3535 }
3536
matoclserv_fuse_getsclass(matoclserventry * eptr,const uint8_t * data,uint32_t length)3537 void matoclserv_fuse_getsclass(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3538 uint32_t inode;
3539 uint32_t msgid;
3540 uint32_t fgtab[MAXSCLASS],dgtab[MAXSCLASS];
3541 uint8_t nleng;
3542 uint16_t i;
3543 uint8_t fn,dn,gmode;
3544 uint32_t psize;
3545 uint8_t *ptr;
3546 uint8_t status;
3547 if (length!=9) {
3548 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETSCLASS - wrong size (%"PRIu32"/9)",length);
3549 eptr->mode = KILL;
3550 return;
3551 }
3552 msgid = get32bit(&data);
3553 inode = get32bit(&data);
3554 gmode = get8bit(&data);
3555 status = fs_getsclass(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,fgtab,dgtab);
3556 fn = 0;
3557 dn = 0;
3558 psize = 6;
3559 if (status==MFS_STATUS_OK) {
3560 for (i=1 ; i<MAXSCLASS ; i++) {
3561 if (sclass_is_simple_goal(i)) {
3562 if (fgtab[i]) {
3563 fn++;
3564 psize += 5;
3565 }
3566 if (dgtab[i]) {
3567 dn++;
3568 psize += 5;
3569 }
3570 } else if (eptr->version>=VERSION2INT(3,0,75)) {
3571 if (fgtab[i]) {
3572 fn++;
3573 psize += 6 + sclass_get_nleng(i);
3574 }
3575 if (dgtab[i]) {
3576 dn++;
3577 psize += 6 + sclass_get_nleng(i);
3578 }
3579 }
3580 }
3581 }
3582 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETSCLASS,(status!=MFS_STATUS_OK)?5:psize);
3583 put32bit(&ptr,msgid);
3584 if (status!=MFS_STATUS_OK) {
3585 put8bit(&ptr,status);
3586 } else {
3587 put8bit(&ptr,fn);
3588 put8bit(&ptr,dn);
3589 for (i=1 ; i<MAXSCLASS ; i++) {
3590 if (fgtab[i]) {
3591 if (sclass_is_simple_goal(i)) {
3592 put8bit(&ptr,i);
3593 put32bit(&ptr,fgtab[i]);
3594 } else if (eptr->version>=VERSION2INT(3,0,75)) {
3595 put8bit(&ptr,0xFF);
3596 nleng = sclass_get_nleng(i);
3597 put8bit(&ptr,nleng);
3598 memcpy(ptr,sclass_get_name(i),nleng);
3599 ptr+=nleng;
3600 put32bit(&ptr,fgtab[i]);
3601 }
3602 }
3603 }
3604 for (i=1 ; i<MAXSCLASS ; i++) {
3605 if (dgtab[i]) {
3606 if (sclass_is_simple_goal(i)) {
3607 put8bit(&ptr,i);
3608 put32bit(&ptr,dgtab[i]);
3609 } else if (eptr->version>=VERSION2INT(3,0,9)) {
3610 put8bit(&ptr,0xFF);
3611 nleng = sclass_get_nleng(i);
3612 put8bit(&ptr,nleng);
3613 memcpy(ptr,sclass_get_name(i),nleng);
3614 ptr+=nleng;
3615 put32bit(&ptr,dgtab[i]);
3616 }
3617 }
3618 }
3619 }
3620 }
3621
matoclserv_fuse_setsclass(matoclserventry * eptr,const uint8_t * data,uint32_t length)3622 void matoclserv_fuse_setsclass(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3623 uint32_t inode,uid;
3624 uint32_t msgid;
3625 uint8_t setid,smode;
3626 uint32_t changed,notchanged,notpermitted;
3627 uint8_t scnleng;
3628 uint8_t src_sclassid,dst_sclassid;
3629 uint32_t pskip;
3630 uint8_t *ptr;
3631 uint8_t status;
3632 if (length<14) {
3633 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETSCLASS - wrong size (%"PRIu32"/<14)",length);
3634 eptr->mode = KILL;
3635 return;
3636 }
3637 msgid = get32bit(&data);
3638 inode = get32bit(&data);
3639 uid = get32bit(&data);
3640 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3641 setid = get8bit(&data);
3642 smode = get8bit(&data);
3643 if (setid==0xFF) {
3644 if ((smode&SMODE_TMASK)==SMODE_EXCHANGE) {
3645 if (length<15) {
3646 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETSCLASS - wrong size (%"PRIu32"/<15)",length);
3647 eptr->mode = KILL;
3648 return;
3649 }
3650 scnleng = get8bit(&data);
3651 src_sclassid = sclass_find_by_name(scnleng,data);
3652 data += scnleng;
3653 pskip = 15+scnleng;
3654 } else {
3655 pskip = 14;
3656 src_sclassid = 0x1; // any non 0 value
3657 }
3658 if (length<pskip+1) {
3659 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETSCLASS - wrong size (%"PRIu32")",length);
3660 eptr->mode = KILL;
3661 return;
3662 }
3663 scnleng = get8bit(&data);
3664 dst_sclassid = sclass_find_by_name(scnleng,data);
3665 data += scnleng;
3666 if (length<pskip+1+scnleng) {
3667 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETSCLASS - wrong size (%"PRIu32")",length);
3668 eptr->mode = KILL;
3669 return;
3670 }
3671 if (sessions_get_disables(eptr->sesdata)&DISABLE_SETSCLASS) {
3672 status = MFS_ERROR_EPERM;
3673 } else if (src_sclassid==0 || dst_sclassid==0) {
3674 status = MFS_ERROR_EINVAL; // new status ? NOSUCHSCLASS ?
3675 } else {
3676 if (sclass_is_simple_goal(dst_sclassid)) {
3677 status = sessions_check_goal(eptr->sesdata,smode&SMODE_TMASK,dst_sclassid);
3678 } else {
3679 status = MFS_STATUS_OK;
3680 }
3681 }
3682 } else { // setid == goal
3683 if (sessions_get_disables(eptr->sesdata)&DISABLE_SETSCLASS) {
3684 status = MFS_ERROR_EPERM;
3685 } else if (setid<1 || setid>9) {
3686 status = MFS_ERROR_EINVAL;
3687 } else {
3688 src_sclassid = setid;
3689 dst_sclassid = setid;
3690 if (length!=14) {
3691 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETSCLASS (classic version) - wrong size (%"PRIu32"/14)",length);
3692 eptr->mode = KILL;
3693 return;
3694 }
3695 status = sessions_check_goal(eptr->sesdata,smode&SMODE_TMASK,setid);
3696 }
3697 }
3698 if (status==MFS_STATUS_OK) {
3699 status = fs_setsclass(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,src_sclassid,dst_sclassid,smode,&changed,¬changed,¬permitted);
3700 }
3701 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETSCLASS,(status!=MFS_STATUS_OK)?5:16);
3702 put32bit(&ptr,msgid);
3703 if (status!=MFS_STATUS_OK) {
3704 put8bit(&ptr,status);
3705 } else {
3706 put32bit(&ptr,changed);
3707 put32bit(&ptr,notchanged);
3708 put32bit(&ptr,notpermitted);
3709 }
3710 }
3711
matoclserv_fuse_geteattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3712 void matoclserv_fuse_geteattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3713 uint32_t inode;
3714 uint32_t msgid;
3715 uint32_t feattrtab[1<<EATTR_BITS],deattrtab[1<<EATTR_BITS];
3716 uint8_t gmode;
3717 uint16_t i,fn,dn;
3718 uint8_t *ptr;
3719 uint8_t status;
3720 if (length!=9) {
3721 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETEATTR - wrong size (%"PRIu32"/9)",length);
3722 eptr->mode = KILL;
3723 return;
3724 }
3725 msgid = get32bit(&data);
3726 inode = get32bit(&data);
3727 gmode = get8bit(&data);
3728 status = fs_geteattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,feattrtab,deattrtab);
3729 if (eptr->version < VERSION2INT(3,0,30)) {
3730 for (i=16 ; i<(1<<EATTR_BITS) ; i++) {
3731 feattrtab[i&0xF] += feattrtab[i];
3732 feattrtab[i] = 0;
3733 deattrtab[i&0xF] += deattrtab[i];
3734 deattrtab[i] = 0;
3735 }
3736 } else if (eptr->version < VERSION2INT(3,0,113)) {
3737 for (i=32 ; i<(1<<EATTR_BITS) ; i++) {
3738 feattrtab[i&0x1F] += feattrtab[i];
3739 feattrtab[i] = 0;
3740 deattrtab[i&0x1F] += deattrtab[i];
3741 deattrtab[i] = 0;
3742 }
3743 }
3744 fn=0;
3745 dn=0;
3746 if (status==MFS_STATUS_OK) {
3747 for (i=0 ; i<(1<<EATTR_BITS) ; i++) {
3748 if (feattrtab[i] && fn<255) {
3749 fn++;
3750 } else {
3751 feattrtab[i]=0; // TODO increase fn and dn in packets
3752 }
3753 if (deattrtab[i] && dn<255) {
3754 dn++;
3755 } else {
3756 deattrtab[i]=0;
3757 }
3758 }
3759 }
3760 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETEATTR,(status!=MFS_STATUS_OK)?5:6+5*(fn+dn));
3761 put32bit(&ptr,msgid);
3762 if (status!=MFS_STATUS_OK) {
3763 put8bit(&ptr,status);
3764 } else {
3765 put8bit(&ptr,fn);
3766 put8bit(&ptr,dn);
3767 for (i=0 ; i<(1<<EATTR_BITS) ; i++) {
3768 if (feattrtab[i]) {
3769 put8bit(&ptr,i);
3770 put32bit(&ptr,feattrtab[i]);
3771 }
3772 }
3773 for (i=0 ; i<(1<<EATTR_BITS) ; i++) {
3774 if (deattrtab[i]) {
3775 put8bit(&ptr,i);
3776 put32bit(&ptr,deattrtab[i]);
3777 }
3778 }
3779 }
3780 }
3781
matoclserv_fuse_seteattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3782 void matoclserv_fuse_seteattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3783 uint32_t inode,uid;
3784 uint32_t msgid;
3785 uint8_t eattr,smode;
3786 uint32_t changed,notchanged,notpermitted;
3787 uint8_t *ptr;
3788 uint8_t status;
3789 if (length!=14) {
3790 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETEATTR - wrong size (%"PRIu32"/14)",length);
3791 eptr->mode = KILL;
3792 return;
3793 }
3794 msgid = get32bit(&data);
3795 inode = get32bit(&data);
3796 uid = get32bit(&data);
3797 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3798 eattr = get8bit(&data);
3799 smode = get8bit(&data);
3800 if (sessions_get_disables(eptr->sesdata)&DISABLE_SETEATTR) {
3801 status = MFS_ERROR_EPERM;
3802 } else {
3803 status = fs_seteattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,eattr,smode,&changed,¬changed,¬permitted);
3804 }
3805 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETEATTR,(status!=MFS_STATUS_OK)?5:16);
3806 put32bit(&ptr,msgid);
3807 if (status!=MFS_STATUS_OK) {
3808 put8bit(&ptr,status);
3809 } else {
3810 put32bit(&ptr,changed);
3811 put32bit(&ptr,notchanged);
3812 put32bit(&ptr,notpermitted);
3813 }
3814 }
3815
matoclserv_fuse_parents(matoclserventry * eptr,const uint8_t * data,uint32_t length)3816 void matoclserv_fuse_parents(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3817 uint32_t inode;
3818 uint32_t msgid;
3819 uint32_t pcount;
3820 uint8_t *ptr;
3821 uint8_t status;
3822 if (length!=8) {
3823 syslog(LOG_NOTICE,"CLTOMA_FUSE_PARENTS - wrong size (%"PRIu32"/8)",length);
3824 eptr->mode = KILL;
3825 return;
3826 }
3827 msgid = get32bit(&data);
3828 inode = get32bit(&data);
3829 status = fs_get_parents_count(sessions_get_rootinode(eptr->sesdata),inode,&pcount);
3830 if (status!=MFS_STATUS_OK) {
3831 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PARENTS,5);
3832 put32bit(&ptr,msgid);
3833 put8bit(&ptr,status);
3834 } else {
3835 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PARENTS,4+4*pcount);
3836 put32bit(&ptr,msgid);
3837 fs_get_parents_data(sessions_get_rootinode(eptr->sesdata),inode,ptr);
3838 }
3839 }
3840
matoclserv_fuse_paths(matoclserventry * eptr,const uint8_t * data,uint32_t length)3841 void matoclserv_fuse_paths(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3842 uint32_t inode;
3843 uint32_t msgid;
3844 uint32_t psize;
3845 uint8_t *ptr;
3846 uint8_t status;
3847 if (length!=8) {
3848 syslog(LOG_NOTICE,"CLTOMA_FUSE_PATHS - wrong size (%"PRIu32"/8)",length);
3849 eptr->mode = KILL;
3850 return;
3851 }
3852 msgid = get32bit(&data);
3853 inode = get32bit(&data);
3854 status = fs_get_paths_size(sessions_get_rootinode(eptr->sesdata),inode,&psize);
3855 if (status!=MFS_STATUS_OK) {
3856 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PATHS,5);
3857 put32bit(&ptr,msgid);
3858 put8bit(&ptr,status);
3859 } else {
3860 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PATHS,4+psize);
3861 put32bit(&ptr,msgid);
3862 fs_get_paths_data(sessions_get_rootinode(eptr->sesdata),inode,ptr);
3863 }
3864 }
3865
matoclserv_fuse_getxattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3866 void matoclserv_fuse_getxattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3867 uint32_t inode,uid,gids;
3868 uint32_t *gid;
3869 uint32_t i;
3870 uint32_t msgid;
3871 uint8_t opened;
3872 uint8_t mode;
3873 uint8_t *ptr;
3874 uint8_t status;
3875 uint8_t anleng;
3876 const uint8_t *attrname;
3877 if (length<19) {
3878 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32")",length);
3879 eptr->mode = KILL;
3880 return;
3881 }
3882 opened = 0; // makes gcc happy
3883 gid = NULL; // makes gcc happy
3884 msgid = get32bit(&data);
3885 inode = get32bit(&data);
3886 if (eptr->version<VERSION2INT(2,0,0)) {
3887 opened = get8bit(&data);
3888 uid = get32bit(&data);
3889 gids = 1;
3890 gid = matoclserv_gid_storage(gids);
3891 gid[0] = get32bit(&data);
3892 }
3893 anleng = get8bit(&data);
3894 attrname = data;
3895 data+=anleng;
3896 if (length<19U+anleng) {
3897 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8")",length,anleng);
3898 eptr->mode = KILL;
3899 return;
3900 }
3901 mode = get8bit(&data);
3902 if (eptr->version>=VERSION2INT(2,0,0)) {
3903 opened = get8bit(&data);
3904 uid = get32bit(&data);
3905 if (length==19U+anleng) {
3906 gids = 1;
3907 gid = matoclserv_gid_storage(gids);
3908 gid[0] = get32bit(&data);
3909 } else {
3910 gids = get32bit(&data);
3911 if (length!=19U+anleng+4*gids) {
3912 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":gids=%"PRIu32")",length,anleng,gids);
3913 eptr->mode = KILL;
3914 return;
3915 }
3916 gid = matoclserv_gid_storage(gids);
3917 for (i=0 ; i<gids ; i++) {
3918 gid[i] = get32bit(&data);
3919 }
3920 }
3921 }
3922 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3923 if (mode!=MFS_XATTR_GETA_DATA && mode!=MFS_XATTR_LENGTH_ONLY) {
3924 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,5);
3925 put32bit(&ptr,msgid);
3926 put8bit(&ptr,MFS_ERROR_EINVAL);
3927 } else if (anleng==0) {
3928 void *xanode;
3929 uint32_t xasize;
3930 status = fs_listxattr_leng(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,&xanode,&xasize);
3931 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,(status!=MFS_STATUS_OK)?5:8+((mode==MFS_XATTR_GETA_DATA)?xasize:0));
3932 put32bit(&ptr,msgid);
3933 if (status!=MFS_STATUS_OK) {
3934 put8bit(&ptr,status);
3935 } else {
3936 put32bit(&ptr,xasize);
3937 if (mode==MFS_XATTR_GETA_DATA && xasize>0) {
3938 fs_listxattr_data(xanode,ptr);
3939 }
3940 }
3941 } else {
3942 const uint8_t *attrvalue;
3943 uint32_t avleng;
3944 status = fs_getxattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,anleng,attrname,&avleng,&attrvalue);
3945 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,(status!=MFS_STATUS_OK)?5:8+((mode==MFS_XATTR_GETA_DATA)?avleng:0));
3946 put32bit(&ptr,msgid);
3947 if (status!=MFS_STATUS_OK) {
3948 put8bit(&ptr,status);
3949 } else {
3950 put32bit(&ptr,avleng);
3951 if (mode==MFS_XATTR_GETA_DATA && avleng>0) {
3952 memcpy(ptr,attrvalue,avleng);
3953 }
3954 }
3955 }
3956 }
3957
matoclserv_fuse_setxattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3958 void matoclserv_fuse_setxattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3959 uint32_t inode,uid,gids;
3960 uint32_t *gid;
3961 uint32_t i;
3962 uint32_t msgid;
3963 const uint8_t *attrname,*attrvalue;
3964 uint8_t opened;
3965 uint8_t anleng;
3966 uint32_t avleng;
3967 uint8_t mode;
3968 uint8_t *ptr;
3969 uint8_t status;
3970 if (length<23) {
3971 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32")",length);
3972 eptr->mode = KILL;
3973 return;
3974 }
3975 opened = 0; // makes gcc happy
3976 gid = NULL; // makes gcc happy
3977 msgid = get32bit(&data);
3978 inode = get32bit(&data);
3979 if (eptr->version<VERSION2INT(2,0,0)) {
3980 opened = get8bit(&data);
3981 uid = get32bit(&data);
3982 gids = 1;
3983 gid = matoclserv_gid_storage(gids);
3984 gid[0] = get32bit(&data);
3985 }
3986 anleng = get8bit(&data);
3987 if (length<23U+anleng) {
3988 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8")",length,anleng);
3989 eptr->mode = KILL;
3990 return;
3991 }
3992 attrname = data;
3993 data += anleng;
3994 avleng = get32bit(&data);
3995 if (length<23U+anleng+avleng) {
3996 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":avleng=%"PRIu32")",length,anleng,avleng);
3997 eptr->mode = KILL;
3998 return;
3999 }
4000 attrvalue = data;
4001 data += avleng;
4002 mode = get8bit(&data);
4003 if (eptr->version>=VERSION2INT(2,0,0)) {
4004 opened = get8bit(&data);
4005 uid = get32bit(&data);
4006 if (length==23U+anleng+avleng) {
4007 gids = 1;
4008 gid = matoclserv_gid_storage(gids);
4009 gid[0] = get32bit(&data);
4010 } else {
4011 gids = get32bit(&data);
4012 if (length!=23U+anleng+avleng+4*gids) {
4013 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":avleng=%"PRIu32":gids=%"PRIu32")",length,anleng,avleng,gids);
4014 eptr->mode = KILL;
4015 return;
4016 }
4017 gid = matoclserv_gid_storage(gids);
4018 for (i=0 ; i<gids ; i++) {
4019 gid[i] = get32bit(&data);
4020 }
4021 }
4022 }
4023 sessions_ugid_remap(eptr->sesdata,&uid,gid);
4024 if (sessions_get_disables(eptr->sesdata)&DISABLE_SETXATTR) {
4025 status = MFS_ERROR_EPERM;
4026 } else {
4027 status = fs_setxattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,anleng,attrname,avleng,attrvalue,mode);
4028 }
4029 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETXATTR,5);
4030 put32bit(&ptr,msgid);
4031 put8bit(&ptr,status);
4032 }
4033
matoclserv_fuse_getfacl(matoclserventry * eptr,const uint8_t * data,uint32_t length)4034 void matoclserv_fuse_getfacl(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4035 uint32_t inode;
4036 // uint32_t uid,gids;
4037 // uint32_t *gid;
4038 // uint32_t i;
4039 // uint8_t opened;
4040 uint32_t msgid;
4041 uint8_t acltype;
4042 uint8_t *ptr;
4043 uint8_t status;
4044 void *c;
4045 uint16_t userperm;
4046 uint16_t groupperm;
4047 uint16_t otherperm;
4048 uint16_t mask;
4049 uint16_t namedusers;
4050 uint16_t namedgroups;
4051 uint32_t aclleng;
4052 if (length<9) {
4053 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETFACL - wrong size (%"PRIu32")",length);
4054 eptr->mode = KILL;
4055 return;
4056 }
4057 msgid = get32bit(&data);
4058 inode = get32bit(&data);
4059 acltype = get8bit(&data);
4060 if (length>9) { // just sanity length check
4061 if (length<18) {
4062 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETFACL - wrong size (%"PRIu32")",length);
4063 eptr->mode = KILL;
4064 return;
4065 } else if (length>18) {
4066 uint32_t gids;
4067 data+=5;
4068 gids = get32bit(&data);
4069 if (length!=18+4*gids) {
4070 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETFACL - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
4071 eptr->mode = KILL;
4072 return;
4073 }
4074 }
4075 }
4076 #if 0
4077 // for future use (rich acl)
4078 opened = get8bit(&data);
4079 uid = get32bit(&data);
4080 if (length==18) {
4081 gids = 1;
4082 gid = matoclserv_gid_storage(gids);
4083 gid[0] = get32bit(&data);
4084 } else {
4085 gids = get32bit(&data);
4086 if (length!=18+4*gids) {
4087 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETFACL - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
4088 eptr->mode = KILL;
4089 return;
4090 }
4091 gid = matoclserv_gid_storage(gids);
4092 for (i=0 ; i<gids ; i++) {
4093 gid[i] = get32bit(&data);
4094 }
4095 }
4096 sessions_ugid_remap(eptr->sesdata,&uid,gid);
4097 #endif
4098 status = fs_getfacl_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,/*opened,uid,gids,gid,*/acltype,&c,&aclleng);
4099 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETFACL,(status!=MFS_STATUS_OK)?5:16+aclleng);
4100 if (status!=MFS_STATUS_OK) {
4101 put32bit(&ptr,msgid);
4102 put8bit(&ptr,status);
4103 } else {
4104 fs_getfacl_data(c,&userperm,&groupperm,&otherperm,&mask,&namedusers,&namedgroups,ptr+16);
4105 put32bit(&ptr,msgid);
4106 put16bit(&ptr,userperm);
4107 put16bit(&ptr,groupperm);
4108 put16bit(&ptr,otherperm);
4109 put16bit(&ptr,mask);
4110 put16bit(&ptr,namedusers);
4111 put16bit(&ptr,namedgroups);
4112 }
4113 }
4114
matoclserv_fuse_setfacl(matoclserventry * eptr,const uint8_t * data,uint32_t length)4115 void matoclserv_fuse_setfacl(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4116 uint32_t inode;
4117 uint32_t uid;
4118 uint32_t msgid;
4119 uint8_t acltype;
4120 uint16_t userperm;
4121 uint16_t groupperm;
4122 uint16_t otherperm;
4123 uint16_t mask;
4124 uint16_t namedusers;
4125 uint16_t namedgroups;
4126 uint8_t *ptr;
4127 uint8_t status;
4128 if (length<25) {
4129 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETFACL - wrong size (%"PRIu32")",length);
4130 eptr->mode = KILL;
4131 return;
4132 }
4133 msgid = get32bit(&data);
4134 inode = get32bit(&data);
4135 uid = get32bit(&data);
4136 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
4137 acltype = get8bit(&data);
4138 userperm = get16bit(&data);
4139 groupperm = get16bit(&data);
4140 otherperm = get16bit(&data);
4141 mask = get16bit(&data);
4142 namedusers = get16bit(&data);
4143 namedgroups = get16bit(&data);
4144 if (length!=(namedusers+namedgroups)*6U+25U) {
4145 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETFACL - wrong size (%"PRIu32":namedusers=%"PRIu16":namedgroups=%"PRIu16")",length,namedusers,namedgroups);
4146 eptr->mode = KILL;
4147 return;
4148 }
4149 // uid = get32bit(&data);
4150 // gid = get32bit(&data);
4151 // sessions_ugid_remap(eptr->sesdata,&uid,&gid);
4152 if (sessions_get_disables(eptr->sesdata)&DISABLE_SETFACL) {
4153 status = MFS_ERROR_EPERM;
4154 } else {
4155 status = fs_setfacl(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,acltype,userperm,groupperm,otherperm,mask,namedusers,namedgroups,data);
4156 }
4157 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETFACL,5);
4158 put32bit(&ptr,msgid);
4159 put8bit(&ptr,status);
4160 }
4161
matoclserv_fuse_append_slice(matoclserventry * eptr,const uint8_t * data,uint32_t length)4162 void matoclserv_fuse_append_slice(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4163 uint32_t inode,inode_src,uid,gids;
4164 uint32_t slice_from,slice_to;
4165 uint32_t *gid;
4166 uint32_t i;
4167 uint32_t msgid;
4168 uint64_t fleng;
4169 uint8_t *ptr;
4170 uint8_t status;
4171 uint8_t flags;
4172 if (length<20 || ((length&1)==1 && length<29)) {
4173 syslog(LOG_NOTICE,"CLTOMA_FUSE_APPEND_SLICE - wrong size (%"PRIu32"/20+|29+)",length);
4174 eptr->mode = KILL;
4175 return;
4176 }
4177 msgid = get32bit(&data);
4178 if (length&1) {
4179 flags = get8bit(&data);
4180 } else {
4181 flags = 0;
4182 }
4183 inode = get32bit(&data);
4184 inode_src = get32bit(&data);
4185 if (length&1) {
4186 slice_from = get32bit(&data);
4187 slice_to = get32bit(&data);
4188 } else {
4189 slice_from = 0;
4190 slice_to = 0;
4191 }
4192 uid = get32bit(&data);
4193 if (length==20) {
4194 gids = 1;
4195 gid = matoclserv_gid_storage(gids);
4196 gid[0] = get32bit(&data);
4197 } else {
4198 gids = get32bit(&data);
4199 if (length!=20+4*gids && length!=29+4*gids) {
4200 syslog(LOG_NOTICE,"CLTOMA_FUSE_APPEND_SLICE - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
4201 eptr->mode = KILL;
4202 return;
4203 }
4204 gid = matoclserv_gid_storage(gids);
4205 for (i=0 ; i<gids ; i++) {
4206 gid[i] = get32bit(&data);
4207 }
4208 }
4209 sessions_ugid_remap(eptr->sesdata,&uid,gid);
4210 if (sessions_get_disables(eptr->sesdata)&DISABLE_APPENDCHUNKS) {
4211 status = MFS_ERROR_EPERM;
4212 } else {
4213 status = fs_append_slice(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),flags,inode,inode_src,slice_from,slice_to,uid,gids,gid,&fleng);
4214 }
4215 if (status==MFS_STATUS_OK) {
4216 matoclserv_fuse_fleng_has_changed(NULL,inode,fleng);
4217 }
4218 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_APPEND_SLICE,5);
4219 put32bit(&ptr,msgid);
4220 put8bit(&ptr,status);
4221 }
4222
matoclserv_fuse_snapshot(matoclserventry * eptr,const uint8_t * data,uint32_t length)4223 void matoclserv_fuse_snapshot(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4224 uint32_t inode,inode_dst;
4225 uint8_t nleng_dst;
4226 const uint8_t *name_dst;
4227 uint32_t uid,gids;
4228 uint32_t *gid;
4229 uint32_t i;
4230 uint8_t smode;
4231 uint16_t requmask;
4232 uint32_t msgid;
4233 uint8_t *ptr;
4234 uint8_t status;
4235 if (length<22) {
4236 syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32")",length);
4237 eptr->mode = KILL;
4238 return;
4239 }
4240 msgid = get32bit(&data);
4241 inode = get32bit(&data);
4242 inode_dst = get32bit(&data);
4243 nleng_dst = get8bit(&data);
4244 if (length!=22U+nleng_dst && length<24U+nleng_dst) {
4245 syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32":nleng_dst=%"PRIu8")",length,nleng_dst);
4246 eptr->mode = KILL;
4247 return;
4248 }
4249 name_dst = data;
4250 data += nleng_dst;
4251 uid = get32bit(&data);
4252 if (length<=24U+nleng_dst) {
4253 gids = 1;
4254 gid = matoclserv_gid_storage(gids);
4255 gid[0] = get32bit(&data);
4256 } else {
4257 gids = get32bit(&data);
4258 if (length!=24U+nleng_dst+4*gids) {
4259 syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_dst,gids);
4260 eptr->mode = KILL;
4261 return;
4262 }
4263 gid = matoclserv_gid_storage(gids);
4264 for (i=0 ; i<gids ; i++) {
4265 gid[i] = get32bit(&data);
4266 }
4267 }
4268 sessions_ugid_remap(eptr->sesdata,&uid,gid);
4269 smode = get8bit(&data);
4270 if (length>=24U+nleng_dst) {
4271 requmask = get16bit(&data);
4272 } else {
4273 smode &= ~SNAPSHOT_MODE_CPLIKE_ATTR;
4274 requmask = 0;
4275 }
4276 requmask |= sessions_get_umask(eptr->sesdata);
4277 status = MFS_STATUS_OK;
4278 if (smode & SNAPSHOT_MODE_DELETE) {
4279 if (sessions_get_disables(eptr->sesdata)&(DISABLE_UNLINK|DISABLE_RMDIR)) {
4280 status = MFS_ERROR_EPERM;
4281 }
4282 } else {
4283 if (sessions_get_disables(eptr->sesdata)&DISABLE_SNAPSHOT) {
4284 status = MFS_ERROR_EPERM;
4285 }
4286 }
4287 if (status==MFS_STATUS_OK) {
4288 status = fs_snapshot(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,inode_dst,nleng_dst,name_dst,uid,gids,gid,smode,requmask);
4289 }
4290 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SNAPSHOT,5);
4291 put32bit(&ptr,msgid);
4292 put8bit(&ptr,status);
4293 }
4294
matoclserv_fuse_quotacontrol(matoclserventry * eptr,const uint8_t * data,uint32_t length)4295 void matoclserv_fuse_quotacontrol(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4296 uint8_t flags,del;
4297 uint32_t sinodes,hinodes,curinodes;
4298 uint64_t slength,ssize,srealsize,hlength,hsize,hrealsize,curlength,cursize,currealsize;
4299 uint32_t msgid,inode,graceperiod;
4300 uint8_t *ptr;
4301 uint8_t status;
4302 if (length!=65 && length!=69 && length!=9) {
4303 syslog(LOG_NOTICE,"CLTOMA_FUSE_QUOTACONTROL - wrong size (%"PRIu32")",length);
4304 eptr->mode = KILL;
4305 return;
4306 }
4307 msgid = get32bit(&data);
4308 inode = get32bit(&data);
4309 flags = get8bit(&data);
4310 if (length==65 || length==69) {
4311 if (length==69) {
4312 graceperiod = get32bit(&data);
4313 } else {
4314 graceperiod = 0;
4315 }
4316 sinodes = get32bit(&data);
4317 slength = get64bit(&data);
4318 ssize = get64bit(&data);
4319 srealsize = get64bit(&data);
4320 hinodes = get32bit(&data);
4321 hlength = get64bit(&data);
4322 hsize = get64bit(&data);
4323 hrealsize = get64bit(&data);
4324 del=0;
4325 } else {
4326 del=1;
4327 }
4328 if (flags && sessions_is_root_remapped(eptr->sesdata)) {
4329 status = MFS_ERROR_EACCES;
4330 } else {
4331 status = fs_quotacontrol(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,del,&flags,&graceperiod,&sinodes,&slength,&ssize,&srealsize,&hinodes,&hlength,&hsize,&hrealsize,&curinodes,&curlength,&cursize,&currealsize);
4332 }
4333 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_QUOTACONTROL,(status!=MFS_STATUS_OK)?5:(eptr->version>=VERSION2INT(3,0,9))?93:89);
4334 put32bit(&ptr,msgid);
4335 if (status!=MFS_STATUS_OK) {
4336 put8bit(&ptr,status);
4337 } else {
4338 put8bit(&ptr,flags);
4339 if (eptr->version>=VERSION2INT(3,0,9)) {
4340 put32bit(&ptr,graceperiod);
4341 }
4342 put32bit(&ptr,sinodes);
4343 put64bit(&ptr,slength);
4344 put64bit(&ptr,ssize);
4345 put64bit(&ptr,srealsize);
4346 put32bit(&ptr,hinodes);
4347 put64bit(&ptr,hlength);
4348 put64bit(&ptr,hsize);
4349 put64bit(&ptr,hrealsize);
4350 put32bit(&ptr,curinodes);
4351 put64bit(&ptr,curlength);
4352 put64bit(&ptr,cursize);
4353 put64bit(&ptr,currealsize);
4354 }
4355 }
4356
matoclserv_fuse_archctl(matoclserventry * eptr,const uint8_t * data,uint32_t length)4357 void matoclserv_fuse_archctl(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4358 uint32_t inode;
4359 uint32_t msgid;
4360 uint8_t cmd,status;
4361 uint8_t *ptr;
4362 if (length!=13 && length!=9) {
4363 syslog(LOG_NOTICE,"CLTOMA_FUSE_ARCHCTL - wrong size (%"PRIu32"/9|13)",length);
4364 eptr->mode = KILL;
4365 return;
4366 }
4367 msgid = get32bit(&data);
4368 inode = get32bit(&data);
4369 cmd = get8bit(&data);
4370 if (cmd==ARCHCTL_GET) {
4371 uint32_t archinodes,partinodes,notarchinodes;
4372 uint64_t archchunks,notarchchunks;
4373 if (length!=9) {
4374 syslog(LOG_NOTICE,"CLTOMA_FUSE_ARCHCTL (GET) - wrong size (%"PRIu32"/9)",length);
4375 eptr->mode = KILL;
4376 return;
4377 }
4378 status = fs_archget(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&archchunks,¬archchunks,&archinodes,&partinodes,¬archinodes);
4379 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_ARCHCTL,(status!=MFS_STATUS_OK)?5:32);
4380 put32bit(&ptr,msgid);
4381 if (status!=MFS_STATUS_OK) {
4382 put8bit(&ptr,status);
4383 } else {
4384 put64bit(&ptr,archchunks);
4385 put64bit(&ptr,notarchchunks);
4386 put32bit(&ptr,archinodes);
4387 put32bit(&ptr,partinodes);
4388 put32bit(&ptr,notarchinodes);
4389 }
4390 } else {
4391 uint32_t uid;
4392 uint64_t changed,notchanged;
4393 uint32_t notpermitted;
4394 if (length!=13) {
4395 syslog(LOG_NOTICE,"CLTOMA_FUSE_ARCHCTL (SET/CLR) - wrong size (%"PRIu32"/13)",length);
4396 eptr->mode = KILL;
4397 return;
4398 }
4399 uid = get32bit(&data);
4400 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
4401 if (sessions_get_disables(eptr->sesdata)&DISABLE_SETEATTR) {
4402 status = MFS_ERROR_EPERM;
4403 } else {
4404 status = fs_archchg(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,cmd,&changed,¬changed,¬permitted);
4405 }
4406 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_ARCHCTL,(status!=MFS_STATUS_OK)?5:24);
4407 put32bit(&ptr,msgid);
4408 if (status!=MFS_STATUS_OK) {
4409 put8bit(&ptr,status);
4410 } else {
4411 put64bit(&ptr,changed);
4412 put64bit(&ptr,notchanged);
4413 put32bit(&ptr,notpermitted);
4414 }
4415 }
4416 }
4417
matoclserv_sclass_create(matoclserventry * eptr,const uint8_t * data,uint32_t length)4418 void matoclserv_sclass_create(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4419 uint32_t msgid;
4420 uint8_t nleng;
4421 uint8_t fver;
4422 uint8_t i;
4423 uint32_t create_labelmasks[9*MASKORGROUP];
4424 uint32_t keep_labelmasks[9*MASKORGROUP];
4425 uint32_t arch_labelmasks[9*MASKORGROUP];
4426 uint8_t mode;
4427 uint8_t create_labelscnt;
4428 uint8_t keep_labelscnt;
4429 uint8_t arch_labelscnt;
4430 uint16_t arch_delay;
4431 uint8_t admin_only;
4432 const uint8_t *name;
4433 uint8_t *ptr;
4434 uint8_t status;
4435
4436 if (length<5U) {
4437 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CREATE - wrong size (%"PRIu32")",length);
4438 eptr->mode = KILL;
4439 return;
4440 }
4441 msgid = get32bit(&data);
4442 if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_ADMIN) {
4443 nleng = get8bit(&data);
4444 name = data;
4445 data += nleng;
4446 if (length<6U+nleng) {
4447 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
4448 eptr->mode = KILL;
4449 return;
4450 }
4451 fver = get8bit(&data);
4452 if (fver==0) {
4453 if (length<13U+nleng) {
4454 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
4455 eptr->mode = KILL;
4456 return;
4457 }
4458 admin_only = get8bit(&data);
4459 mode = get8bit(&data);
4460 arch_delay = get16bit(&data);
4461 create_labelscnt = get8bit(&data);
4462 keep_labelscnt = get8bit(&data);
4463 arch_labelscnt = get8bit(&data);
4464 if (length!=13U+nleng+(create_labelscnt+keep_labelscnt+arch_labelscnt)*4U*MASKORGROUP) {
4465 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8":labels C=%"PRIu8";K=%"PRIu8";A=%"PRIu8")",length,nleng,create_labelscnt,keep_labelscnt,arch_labelscnt);
4466 eptr->mode = KILL;
4467 return;
4468 }
4469 for (i = 0 ; i < create_labelscnt*MASKORGROUP ; i++) {
4470 create_labelmasks[i] = get32bit(&data);
4471 }
4472 for (i = 0 ; i < keep_labelscnt*MASKORGROUP ; i++) {
4473 keep_labelmasks[i] = get32bit(&data);
4474 }
4475 for (i = 0 ; i < arch_labelscnt*MASKORGROUP ; i++) {
4476 arch_labelmasks[i] = get32bit(&data);
4477 }
4478 status = sclass_create_entry(nleng,name,admin_only,mode,create_labelscnt,create_labelmasks,keep_labelscnt,keep_labelmasks,arch_labelscnt,arch_labelmasks,arch_delay);
4479 } else {
4480 status = MFS_ERROR_EINVAL;
4481 }
4482 } else {
4483 status = MFS_ERROR_EPERM_NOTADMIN;
4484 }
4485 ptr = matoclserv_createpacket(eptr,MATOCL_SCLASS_CREATE,5);
4486 put32bit(&ptr,msgid);
4487 put8bit(&ptr,status);
4488 }
4489
matoclserv_sclass_change(matoclserventry * eptr,const uint8_t * data,uint32_t length)4490 void matoclserv_sclass_change(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4491 uint32_t msgid;
4492 uint8_t nleng;
4493 uint8_t fver;
4494 uint8_t i;
4495 uint16_t chgmask;
4496 uint32_t create_labelmasks[9*MASKORGROUP];
4497 uint32_t keep_labelmasks[9*MASKORGROUP];
4498 uint32_t arch_labelmasks[9*MASKORGROUP];
4499 uint8_t mode;
4500 uint8_t create_labelscnt;
4501 uint8_t keep_labelscnt;
4502 uint8_t arch_labelscnt;
4503 uint16_t arch_delay;
4504 uint8_t admin_only;
4505 const uint8_t *name;
4506 uint8_t *ptr;
4507 uint8_t status;
4508
4509 if (length<5U) {
4510 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CHANGE - wrong size (%"PRIu32")",length);
4511 eptr->mode = KILL;
4512 return;
4513 }
4514 msgid = get32bit(&data);
4515 nleng = get8bit(&data);
4516 name = data;
4517 data += nleng;
4518 if (length<6U+nleng) {
4519 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CHANGE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
4520 eptr->mode = KILL;
4521 return;
4522 }
4523 create_labelscnt = 0; // silence cppcheck false warnings
4524 keep_labelscnt = 0; // silence cppcheck false warnings
4525 arch_labelscnt = 0; // silence cppcheck false warnings
4526 fver = get8bit(&data);
4527 if (fver==0) {
4528 if (length<15U+nleng) {
4529 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CHANGE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
4530 eptr->mode = KILL;
4531 return;
4532 }
4533 chgmask = get16bit(&data);
4534 if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_ADMIN || chgmask==0) {
4535 admin_only = get8bit(&data);
4536 mode = get8bit(&data);
4537 arch_delay = get16bit(&data);
4538 create_labelscnt = get8bit(&data);
4539 keep_labelscnt = get8bit(&data);
4540 arch_labelscnt = get8bit(&data);
4541 if (length!=15U+nleng+(create_labelscnt+keep_labelscnt+arch_labelscnt)*4U*MASKORGROUP) {
4542 syslog(LOG_NOTICE,"CLTOMA_SCLASS_CHANGE - wrong size (%"PRIu32":nleng=%"PRIu8":labels C=%"PRIu8";K=%"PRIu8";A=%"PRIu8")",length,nleng,create_labelscnt,keep_labelscnt,arch_labelscnt);
4543 eptr->mode = KILL;
4544 return;
4545 }
4546 for (i = 0 ; i < create_labelscnt*MASKORGROUP ; i++) {
4547 create_labelmasks[i] = get32bit(&data);
4548 }
4549 for (i = 0 ; i < keep_labelscnt*MASKORGROUP ; i++) {
4550 keep_labelmasks[i] = get32bit(&data);
4551 }
4552 for (i = 0 ; i < arch_labelscnt*MASKORGROUP ; i++) {
4553 arch_labelmasks[i] = get32bit(&data);
4554 }
4555 status = sclass_change_entry(nleng,name,chgmask,&admin_only,&mode,&create_labelscnt,create_labelmasks,&keep_labelscnt,keep_labelmasks,&arch_labelscnt,arch_labelmasks,&arch_delay);
4556 } else {
4557 status = MFS_ERROR_EPERM_NOTADMIN;
4558 }
4559 } else {
4560 status = MFS_ERROR_EINVAL;
4561 }
4562 ptr = matoclserv_createpacket(eptr,MATOCL_SCLASS_CHANGE,(status!=MFS_STATUS_OK)?5:(12U+4U*MASKORGROUP*(create_labelscnt+keep_labelscnt+arch_labelscnt)));
4563 put32bit(&ptr,msgid);
4564 if (status!=MFS_STATUS_OK) {
4565 put8bit(&ptr,status);
4566 } else {
4567 put8bit(&ptr,0); // fver
4568 put8bit(&ptr,admin_only);
4569 put8bit(&ptr,mode);
4570 put16bit(&ptr,arch_delay);
4571 put8bit(&ptr,create_labelscnt);
4572 put8bit(&ptr,keep_labelscnt);
4573 put8bit(&ptr,arch_labelscnt);
4574 for (i = 0 ; i < create_labelscnt*MASKORGROUP ; i++) {
4575 put32bit(&ptr,create_labelmasks[i]);
4576 }
4577 for (i = 0 ; i < keep_labelscnt*MASKORGROUP ; i++) {
4578 put32bit(&ptr,keep_labelmasks[i]);
4579 }
4580 for (i = 0 ; i < arch_labelscnt*MASKORGROUP ; i++) {
4581 put32bit(&ptr,arch_labelmasks[i]);
4582 }
4583 }
4584 }
4585
matoclserv_sclass_delete(matoclserventry * eptr,const uint8_t * data,uint32_t length)4586 void matoclserv_sclass_delete(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4587 uint32_t msgid;
4588 uint8_t nleng;
4589 const uint8_t *name;
4590 uint8_t *ptr;
4591 uint8_t status;
4592
4593 if (length<5) {
4594 syslog(LOG_NOTICE,"CLTOMA_SCLASS_DELETE - wrong size (%"PRIu32")",length);
4595 eptr->mode = KILL;
4596 return;
4597 }
4598 msgid = get32bit(&data);
4599 if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_ADMIN) {
4600 nleng = get8bit(&data);
4601 name = data;
4602 data += nleng;
4603 if (length!=5U+nleng) {
4604 syslog(LOG_NOTICE,"CLTOMA_SCLASS_DELETE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
4605 eptr->mode = KILL;
4606 return;
4607 }
4608 status = sclass_delete_entry(nleng,name);
4609 } else {
4610 status = MFS_ERROR_EPERM_NOTADMIN;
4611 }
4612 ptr = matoclserv_createpacket(eptr,MATOCL_SCLASS_DELETE,5);
4613 put32bit(&ptr,msgid);
4614 put8bit(&ptr,status);
4615 }
4616
matoclserv_sclass_duplicate(matoclserventry * eptr,const uint8_t * data,uint32_t length)4617 void matoclserv_sclass_duplicate(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4618 uint32_t msgid;
4619 uint8_t snleng,dnleng;
4620 const uint8_t *sname,*dname;
4621 uint8_t *ptr;
4622 uint8_t status;
4623
4624 if (length<5) {
4625 syslog(LOG_NOTICE,"CLTOMA_SCLASS_DUPLICATE - wrong size (%"PRIu32")",length);
4626 eptr->mode = KILL;
4627 return;
4628 }
4629 msgid = get32bit(&data);
4630 if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_ADMIN) {
4631 snleng = get8bit(&data);
4632 sname = data;
4633 data += snleng;
4634 if (length<6U+snleng) {
4635 syslog(LOG_NOTICE,"CLTOMA_SCLASS_DUPLICATE - wrong size (%"PRIu32":snleng=%"PRIu8")",length,snleng);
4636 eptr->mode = KILL;
4637 return;
4638 }
4639 dnleng = get8bit(&data);
4640 dname = data;
4641 data += dnleng;
4642 if (length!=6U+snleng+dnleng) {
4643 syslog(LOG_NOTICE,"CLTOMA_SCLASS_DUPLICATE - wrong size (%"PRIu32":snleng=%"PRIu8":dnleng=%"PRIu8")",length,snleng,dnleng);
4644 eptr->mode = KILL;
4645 return;
4646 }
4647 status = sclass_duplicate_entry(snleng,sname,dnleng,dname);
4648 } else {
4649 status = MFS_ERROR_EPERM_NOTADMIN;
4650 }
4651 ptr = matoclserv_createpacket(eptr,MATOCL_SCLASS_DUPLICATE,5);
4652 put32bit(&ptr,msgid);
4653 put8bit(&ptr,status);
4654 }
4655
matoclserv_sclass_rename(matoclserventry * eptr,const uint8_t * data,uint32_t length)4656 void matoclserv_sclass_rename(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4657 uint32_t msgid;
4658 uint8_t snleng,dnleng;
4659 const uint8_t *sname,*dname;
4660 uint8_t *ptr;
4661 uint8_t status;
4662
4663 if (length<5) {
4664 syslog(LOG_NOTICE,"CLTOMA_SCLASS_RENAME - wrong size (%"PRIu32")",length);
4665 eptr->mode = KILL;
4666 return;
4667 }
4668 msgid = get32bit(&data);
4669 if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_ADMIN) {
4670 snleng = get8bit(&data);
4671 sname = data;
4672 data += snleng;
4673 if (length<6U+snleng) {
4674 syslog(LOG_NOTICE,"CLTOMA_SCLASS_RENAME - wrong size (%"PRIu32":snleng=%"PRIu8")",length,snleng);
4675 eptr->mode = KILL;
4676 return;
4677 }
4678 dnleng = get8bit(&data);
4679 dname = data;
4680 data += dnleng;
4681 if (length!=6U+snleng+dnleng) {
4682 syslog(LOG_NOTICE,"CLTOMA_SCLASS_RENAME - wrong size (%"PRIu32":snleng=%"PRIu8":dnleng=%"PRIu8")",length,snleng,dnleng);
4683 eptr->mode = KILL;
4684 return;
4685 }
4686 status = sclass_rename_entry(snleng,sname,dnleng,dname);
4687 } else {
4688 status = MFS_ERROR_EPERM_NOTADMIN;
4689 }
4690 ptr = matoclserv_createpacket(eptr,MATOCL_SCLASS_RENAME,5);
4691 put32bit(&ptr,msgid);
4692 put8bit(&ptr,status);
4693 }
4694
matoclserv_sclass_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)4695 void matoclserv_sclass_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4696 uint32_t msgid;
4697 uint8_t *ptr;
4698 uint32_t rsize;
4699 uint8_t longmode;
4700
4701 if (length!=5) {
4702 syslog(LOG_NOTICE,"CLTOMA_SCLASS_LIST - wrong size (%"PRIu32")",length);
4703 eptr->mode = KILL;
4704 return;
4705 }
4706 msgid = get32bit(&data);
4707 longmode = get8bit(&data);
4708 rsize = sclass_list_entries(NULL,longmode);
4709 ptr = matoclserv_createpacket(eptr,MATOCL_SCLASS_LIST,4+rsize);
4710 put32bit(&ptr,msgid);
4711 sclass_list_entries(ptr,longmode);
4712 }
4713
matoclserv_fuse_getdirstats_old(matoclserventry * eptr,const uint8_t * data,uint32_t length)4714 void matoclserv_fuse_getdirstats_old(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4715 uint32_t inode,inodes,files,dirs,chunks;
4716 uint64_t leng,size,rsize;
4717 uint32_t msgid;
4718 uint8_t *ptr;
4719 uint8_t status;
4720 if (length!=8) {
4721 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDIRSTATS - wrong size (%"PRIu32"/8)",length);
4722 eptr->mode = KILL;
4723 return;
4724 }
4725 msgid = get32bit(&data);
4726 inode = get32bit(&data);
4727 status = fs_get_dir_stats(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&inodes,&dirs,&files,&chunks,&leng,&size,&rsize);
4728 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDIRSTATS,(status!=MFS_STATUS_OK)?5:60);
4729 put32bit(&ptr,msgid);
4730 if (status!=MFS_STATUS_OK) {
4731 put8bit(&ptr,status);
4732 } else {
4733 put32bit(&ptr,inodes);
4734 put32bit(&ptr,dirs);
4735 put32bit(&ptr,files);
4736 put32bit(&ptr,0);
4737 put32bit(&ptr,0);
4738 put32bit(&ptr,chunks);
4739 put32bit(&ptr,0);
4740 put32bit(&ptr,0);
4741 put64bit(&ptr,leng);
4742 put64bit(&ptr,size);
4743 put64bit(&ptr,rsize);
4744 }
4745 }
4746
matoclserv_fuse_getdirstats(matoclserventry * eptr,const uint8_t * data,uint32_t length)4747 void matoclserv_fuse_getdirstats(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4748 uint32_t inode,inodes,files,dirs,chunks;
4749 uint64_t leng,size,rsize;
4750 uint32_t msgid;
4751 uint8_t *ptr;
4752 uint8_t status;
4753 if (length!=8) {
4754 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDIRSTATS - wrong size (%"PRIu32"/8)",length);
4755 eptr->mode = KILL;
4756 return;
4757 }
4758 msgid = get32bit(&data);
4759 inode = get32bit(&data);
4760 status = fs_get_dir_stats(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&inodes,&dirs,&files,&chunks,&leng,&size,&rsize);
4761 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDIRSTATS,(status!=MFS_STATUS_OK)?5:44);
4762 put32bit(&ptr,msgid);
4763 if (status!=MFS_STATUS_OK) {
4764 put8bit(&ptr,status);
4765 } else {
4766 put32bit(&ptr,inodes);
4767 put32bit(&ptr,dirs);
4768 put32bit(&ptr,files);
4769 put32bit(&ptr,chunks);
4770 put64bit(&ptr,leng);
4771 put64bit(&ptr,size);
4772 put64bit(&ptr,rsize);
4773 }
4774 }
4775
matoclserv_fuse_gettrash(matoclserventry * eptr,const uint8_t * data,uint32_t length)4776 void matoclserv_fuse_gettrash(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4777 uint32_t msgid;
4778 uint8_t *ptr;
4779 uint8_t status;
4780 uint32_t dleng;
4781 uint32_t tid;
4782 if (length!=4 && length!=8) {
4783 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASH - wrong size (%"PRIu32"/4)",length);
4784 eptr->mode = KILL;
4785 return;
4786 }
4787 msgid = get32bit(&data);
4788 if (length==8) {
4789 tid = get32bit(&data);
4790 } else {
4791 tid = 0xFFFFFFFF;
4792 }
4793 status = fs_readtrash_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),tid,&dleng);
4794 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASH,(status!=MFS_STATUS_OK)?5:(4+dleng));
4795 put32bit(&ptr,msgid);
4796 if (status!=MFS_STATUS_OK) {
4797 put8bit(&ptr,status);
4798 } else {
4799 fs_readtrash_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),tid,ptr);
4800 }
4801 }
4802
matoclserv_fuse_getdetachedattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)4803 void matoclserv_fuse_getdetachedattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4804 uint32_t inode;
4805 uint8_t attr[ATTR_RECORD_SIZE];
4806 uint32_t msgid;
4807 uint8_t dtype;
4808 uint8_t *ptr;
4809 uint8_t status;
4810 if (length<8 || length>9) {
4811 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDETACHEDATTR - wrong size (%"PRIu32"/8,9)",length);
4812 eptr->mode = KILL;
4813 return;
4814 }
4815 msgid = get32bit(&data);
4816 inode = get32bit(&data);
4817 if (length==9) {
4818 dtype = get8bit(&data);
4819 } else {
4820 dtype = DTYPE_UNKNOWN;
4821 }
4822 status = fs_getdetachedattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,attr,dtype);
4823 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDETACHEDATTR,(status!=MFS_STATUS_OK)?5:(eptr->asize+4));
4824 put32bit(&ptr,msgid);
4825 if (status!=MFS_STATUS_OK) {
4826 put8bit(&ptr,status);
4827 } else {
4828 memcpy(ptr,attr,eptr->asize);
4829 }
4830 }
4831
matoclserv_fuse_gettrashpath(matoclserventry * eptr,const uint8_t * data,uint32_t length)4832 void matoclserv_fuse_gettrashpath(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4833 uint32_t inode;
4834 uint32_t pleng;
4835 const uint8_t *path;
4836 uint32_t msgid;
4837 uint8_t *ptr;
4838 uint8_t status;
4839 if (length!=8) {
4840 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASHPATH - wrong size (%"PRIu32"/8)",length);
4841 eptr->mode = KILL;
4842 return;
4843 }
4844 msgid = get32bit(&data);
4845 inode = get32bit(&data);
4846 status = fs_gettrashpath(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&pleng,&path);
4847 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASHPATH,(status!=MFS_STATUS_OK)?5:8+pleng+1);
4848 put32bit(&ptr,msgid);
4849 if (status!=MFS_STATUS_OK) {
4850 put8bit(&ptr,status);
4851 } else {
4852 put32bit(&ptr,pleng+1);
4853 if (pleng>0) {
4854 memcpy(ptr,path,pleng);
4855 }
4856 ptr[pleng]=0;
4857 }
4858 }
4859
matoclserv_fuse_settrashpath(matoclserventry * eptr,const uint8_t * data,uint32_t length)4860 void matoclserv_fuse_settrashpath(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4861 uint32_t inode;
4862 const uint8_t *path;
4863 uint32_t pleng;
4864 uint32_t msgid;
4865 uint8_t status;
4866 uint8_t *ptr;
4867 if (length<12) {
4868 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHPATH - wrong size (%"PRIu32"/>=12)",length);
4869 eptr->mode = KILL;
4870 return;
4871 }
4872 msgid = get32bit(&data);
4873 inode = get32bit(&data);
4874 pleng = get32bit(&data);
4875 if (length!=12+pleng) {
4876 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHPATH - wrong size (%"PRIu32"/%"PRIu32")",length,12+pleng);
4877 eptr->mode = KILL;
4878 return;
4879 }
4880 path = data;
4881 data += pleng;
4882 while (pleng>0 && path[pleng-1]==0) {
4883 pleng--;
4884 }
4885 status = fs_settrashpath(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,pleng,path);
4886 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETTRASHPATH,5);
4887 put32bit(&ptr,msgid);
4888 put8bit(&ptr,status);
4889 }
4890
matoclserv_fuse_undel(matoclserventry * eptr,const uint8_t * data,uint32_t length)4891 void matoclserv_fuse_undel(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4892 uint32_t inode;
4893 uint32_t msgid;
4894 uint8_t status;
4895 uint8_t *ptr;
4896 if (length!=8) {
4897 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNDEL - wrong size (%"PRIu32"/8)",length);
4898 eptr->mode = KILL;
4899 return;
4900 }
4901 msgid = get32bit(&data);
4902 inode = get32bit(&data);
4903 status = fs_undel(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode);
4904 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_UNDEL,5);
4905 put32bit(&ptr,msgid);
4906 put8bit(&ptr,status);
4907 }
4908
matoclserv_fuse_purge(matoclserventry * eptr,const uint8_t * data,uint32_t length)4909 void matoclserv_fuse_purge(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4910 uint32_t inode;
4911 uint32_t msgid;
4912 uint8_t *ptr;
4913 uint8_t status;
4914 if (length!=8) {
4915 syslog(LOG_NOTICE,"CLTOMA_FUSE_PURGE - wrong size (%"PRIu32"/8)",length);
4916 eptr->mode = KILL;
4917 return;
4918 }
4919 msgid = get32bit(&data);
4920 inode = get32bit(&data);
4921 status = fs_purge(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode);
4922 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PURGE,5);
4923 put32bit(&ptr,msgid);
4924 put8bit(&ptr,status);
4925 }
4926
4927
matoclserv_fuse_getsustained(matoclserventry * eptr,const uint8_t * data,uint32_t length)4928 void matoclserv_fuse_getsustained(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4929 uint32_t msgid;
4930 uint8_t *ptr;
4931 uint8_t status;
4932 uint32_t dleng;
4933 if (length!=4) {
4934 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETSUSTAINED - wrong size (%"PRIu32"/4)",length);
4935 eptr->mode = KILL;
4936 return;
4937 }
4938 msgid = get32bit(&data);
4939 status = fs_readsustained_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&dleng);
4940 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETSUSTAINED,(status!=MFS_STATUS_OK)?5:(4+dleng));
4941 put32bit(&ptr,msgid);
4942 if (status!=MFS_STATUS_OK) {
4943 put8bit(&ptr,status);
4944 } else {
4945 fs_readsustained_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),ptr);
4946 }
4947 }
4948
matoclserv_beforedisconnect(matoclserventry * eptr)4949 void matoclserv_beforedisconnect(matoclserventry *eptr) {
4950 swchunks *swc,**pswc;
4951 lwchunks *lwc,**plwc;
4952 uint32_t i;
4953
4954 for (i=0 ; i<CHUNKHASHSIZE ; i++) {
4955 pswc = swchunkshash + i;
4956 while ((swc = *pswc)) {
4957 if (swc->eptr == eptr) {
4958 fs_rollback(swc->inode,swc->indx,swc->prevchunkid,swc->chunkid);
4959 *pswc = swc->next;
4960 free(swc);
4961 } else {
4962 pswc = &(swc->next);
4963 }
4964 }
4965 plwc = lwchunkshashhead + i;
4966 while ((lwc = *plwc)) {
4967 if (lwc->eptr == eptr) {
4968 *plwc = lwc->next;
4969 free(lwc);
4970 } else {
4971 plwc = &(lwc->next);
4972 }
4973 }
4974 lwchunkshashtail[i] = plwc;
4975 }
4976 if (eptr->path!=NULL) {
4977 free(eptr->path);
4978 eptr->path = NULL;
4979 }
4980 if (eptr->info!=NULL) {
4981 free(eptr->info);
4982 eptr->info = NULL;
4983 }
4984 sessions_disconnection(eptr->sesdata);
4985 }
4986
matoclserv_gotpacket(matoclserventry * eptr,uint32_t type,const uint8_t * data,uint32_t length)4987 void matoclserv_gotpacket(matoclserventry *eptr,uint32_t type,const uint8_t *data,uint32_t length) {
4988 if (type==ANTOAN_NOP) {
4989 return;
4990 }
4991 if (type==ANTOAN_UNKNOWN_COMMAND) { // for future use
4992 return;
4993 }
4994 if (type==ANTOAN_BAD_COMMAND_SIZE) { // for future use
4995 return;
4996 }
4997 // printf("AQQ\n");
4998 if (eptr->registered==0) { // unregistered clients - beware that in this context sesdata is NULL
4999 switch (type) {
5000 case ANTOAN_GET_VERSION:
5001 matoclserv_get_version(eptr,data,length);
5002 break;
5003 case ANTOAN_GET_CONFIG:
5004 matoclserv_get_config(eptr,data,length);
5005 break;
5006 case CLTOMA_FUSE_REGISTER:
5007 // printf("REGISTER\n");
5008 matoclserv_fuse_register(eptr,data,length);
5009 break;
5010 case CLTOMA_CSERV_LIST:
5011 matoclserv_cserv_list(eptr,data,length);
5012 break;
5013 case CLTOMA_SESSION_LIST:
5014 matoclserv_session_list(eptr,data,length);
5015 break;
5016 case CLTOAN_CHART:
5017 matoclserv_chart(eptr,data,length);
5018 break;
5019 case CLTOAN_CHART_DATA:
5020 matoclserv_chart_data(eptr,data,length);
5021 break;
5022 case CLTOAN_MONOTONIC_DATA:
5023 matoclserv_monotonic_data(eptr,data,length);
5024 break;
5025 case CLTOMA_INFO:
5026 matoclserv_info(eptr,data,length);
5027 break;
5028 case CLTOMA_FSTEST_INFO:
5029 matoclserv_fstest_info(eptr,data,length);
5030 break;
5031 case CLTOMA_CHUNKSTEST_INFO:
5032 matoclserv_chunkstest_info(eptr,data,length);
5033 break;
5034 case CLTOMA_CHUNKS_MATRIX:
5035 matoclserv_chunks_matrix(eptr,data,length);
5036 break;
5037 case CLTOMA_QUOTA_INFO:
5038 matoclserv_quota_info(eptr,data,length);
5039 break;
5040 case CLTOMA_EXPORTS_INFO:
5041 matoclserv_exports_info(eptr,data,length);
5042 break;
5043 case CLTOMA_MLOG_LIST:
5044 matoclserv_mlog_list(eptr,data,length);
5045 break;
5046 case CLTOMA_CSSERV_COMMAND:
5047 matoclserv_cserv_command(eptr,data,length);
5048 break;
5049 case CLTOMA_SESSION_COMMAND:
5050 matoclserv_session_command(eptr,data,length);
5051 break;
5052 case CLTOMA_MEMORY_INFO:
5053 matoclserv_memory_info(eptr,data,length);
5054 break;
5055 case CLTOAN_MODULE_INFO:
5056 matoclserv_module_info(eptr,data,length);
5057 break;
5058 case CLTOMA_LIST_OPEN_FILES:
5059 matoclserv_list_open_files(eptr,data,length);
5060 break;
5061 case CLTOMA_LIST_ACQUIRED_LOCKS:
5062 matoclserv_list_acquired_locks(eptr,data,length);
5063 break;
5064 case CLTOMA_MASS_RESOLVE_PATHS:
5065 matoclserv_mass_resolve_paths(eptr,data,length);
5066 break;
5067 case CLTOMA_SCLASS_INFO:
5068 matoclserv_sclass_info(eptr,data,length);
5069 break;
5070 case CLTOMA_MISSING_CHUNKS:
5071 matoclserv_missing_chunks(eptr,data,length);
5072 break;
5073 case CLTOMA_NODE_INFO:
5074 matoclserv_node_info(eptr,data,length);
5075 break;
5076 default:
5077 syslog(LOG_NOTICE,"main master server module: got unknown message from unregistered (type:%"PRIu32")",type);
5078 eptr->mode=KILL;
5079 }
5080 } else if (eptr->registered<100) { // mounts and new tools
5081 if (eptr->sesdata==NULL) {
5082 syslog(LOG_ERR,"registered connection without sesdata !!!");
5083 eptr->mode=KILL;
5084 return;
5085 }
5086 switch (type) {
5087 case ANTOAN_GET_VERSION:
5088 matoclserv_get_version(eptr,data,length);
5089 break;
5090 case ANTOAN_GET_CONFIG:
5091 matoclserv_get_config(eptr,data,length);
5092 break;
5093 case CLTOMA_FUSE_REGISTER:
5094 matoclserv_fuse_register(eptr,data,length);
5095 break;
5096 case CLTOMA_FUSE_SUSTAINED_INODES_DEPRECATED:
5097 case CLTOMA_FUSE_SUSTAINED_INODES:
5098 matoclserv_fuse_sustained_inodes(eptr,data,length);
5099 break;
5100 case CLTOMA_FUSE_AMTIME_INODES:
5101 matoclserv_fuse_amtime_inodes(eptr,data,length);
5102 break;
5103 case CLTOMA_FUSE_TIME_SYNC:
5104 matoclserv_fuse_time_sync(eptr,data,length);
5105 break;
5106 case CLTOMA_FUSE_STATFS:
5107 matoclserv_fuse_statfs(eptr,data,length);
5108 break;
5109 case CLTOMA_FUSE_ACCESS:
5110 matoclserv_fuse_access(eptr,data,length);
5111 break;
5112 case CLTOMA_FUSE_LOOKUP:
5113 matoclserv_fuse_lookup(eptr,data,length);
5114 break;
5115 case CLTOMA_FUSE_GETATTR:
5116 matoclserv_fuse_getattr(eptr,data,length);
5117 break;
5118 case CLTOMA_FUSE_SETATTR:
5119 matoclserv_fuse_setattr(eptr,data,length);
5120 break;
5121 case CLTOMA_FUSE_READLINK:
5122 matoclserv_fuse_readlink(eptr,data,length);
5123 break;
5124 case CLTOMA_FUSE_SYMLINK:
5125 matoclserv_fuse_symlink(eptr,data,length);
5126 break;
5127 case CLTOMA_FUSE_MKNOD:
5128 matoclserv_fuse_mknod(eptr,data,length);
5129 break;
5130 case CLTOMA_FUSE_MKDIR:
5131 matoclserv_fuse_mkdir(eptr,data,length);
5132 break;
5133 case CLTOMA_FUSE_UNLINK:
5134 matoclserv_fuse_unlink(eptr,data,length);
5135 break;
5136 case CLTOMA_FUSE_RMDIR:
5137 matoclserv_fuse_rmdir(eptr,data,length);
5138 break;
5139 case CLTOMA_FUSE_RENAME:
5140 matoclserv_fuse_rename(eptr,data,length);
5141 break;
5142 case CLTOMA_FUSE_LINK:
5143 matoclserv_fuse_link(eptr,data,length);
5144 break;
5145 case CLTOMA_FUSE_READDIR:
5146 matoclserv_fuse_readdir(eptr,data,length);
5147 break;
5148 case CLTOMA_FUSE_OPEN:
5149 matoclserv_fuse_open(eptr,data,length);
5150 break;
5151 case CLTOMA_FUSE_CREATE:
5152 matoclserv_fuse_create(eptr,data,length);
5153 break;
5154 case CLTOMA_FUSE_READ_CHUNK:
5155 matoclserv_fuse_read_chunk(eptr,data,length);
5156 break;
5157 case CLTOMA_FUSE_WRITE_CHUNK:
5158 matoclserv_fuse_write_chunk(eptr,data,length);
5159 break;
5160 case CLTOMA_FUSE_WRITE_CHUNK_END:
5161 matoclserv_fuse_write_chunk_end(eptr,data,length);
5162 break;
5163 case CLTOMA_FUSE_FLOCK:
5164 matoclserv_fuse_flock(eptr,data,length);
5165 break;
5166 case CLTOMA_FUSE_POSIX_LOCK:
5167 matoclserv_fuse_posix_lock(eptr,data,length);
5168 break;
5169 // fuse - meta
5170 case CLTOMA_FUSE_GETTRASH:
5171 matoclserv_fuse_gettrash(eptr,data,length);
5172 break;
5173 case CLTOMA_FUSE_GETDETACHEDATTR:
5174 matoclserv_fuse_getdetachedattr(eptr,data,length);
5175 break;
5176 case CLTOMA_FUSE_GETTRASHPATH:
5177 matoclserv_fuse_gettrashpath(eptr,data,length);
5178 break;
5179 case CLTOMA_FUSE_SETTRASHPATH:
5180 matoclserv_fuse_settrashpath(eptr,data,length);
5181 break;
5182 case CLTOMA_FUSE_UNDEL:
5183 matoclserv_fuse_undel(eptr,data,length);
5184 break;
5185 case CLTOMA_FUSE_PURGE:
5186 matoclserv_fuse_purge(eptr,data,length);
5187 break;
5188 case CLTOMA_FUSE_GETSUSTAINED:
5189 matoclserv_fuse_getsustained(eptr,data,length);
5190 break;
5191 case CLTOMA_FUSE_CHECK:
5192 matoclserv_fuse_check(eptr,data,length);
5193 break;
5194 case CLTOMA_FUSE_GETTRASHTIME:
5195 matoclserv_fuse_gettrashtime(eptr,data,length);
5196 break;
5197 case CLTOMA_FUSE_SETTRASHTIME:
5198 matoclserv_fuse_settrashtime(eptr,data,length);
5199 break;
5200 case CLTOMA_FUSE_GETSCLASS:
5201 matoclserv_fuse_getsclass(eptr,data,length);
5202 break;
5203 case CLTOMA_FUSE_SETSCLASS:
5204 matoclserv_fuse_setsclass(eptr,data,length);
5205 break;
5206 case CLTOMA_FUSE_APPEND_SLICE:
5207 matoclserv_fuse_append_slice(eptr,data,length);
5208 break;
5209 case CLTOMA_FUSE_GETDIRSTATS:
5210 matoclserv_fuse_getdirstats_old(eptr,data,length);
5211 break;
5212 case CLTOMA_FUSE_TRUNCATE:
5213 matoclserv_fuse_truncate(eptr,data,length);
5214 break;
5215 case CLTOMA_FUSE_REPAIR:
5216 matoclserv_fuse_repair(eptr,data,length);
5217 break;
5218 case CLTOMA_FUSE_SNAPSHOT:
5219 matoclserv_fuse_snapshot(eptr,data,length);
5220 break;
5221 case CLTOMA_FUSE_GETEATTR:
5222 matoclserv_fuse_geteattr(eptr,data,length);
5223 break;
5224 case CLTOMA_FUSE_SETEATTR:
5225 matoclserv_fuse_seteattr(eptr,data,length);
5226 break;
5227 case CLTOMA_FUSE_PARENTS:
5228 matoclserv_fuse_parents(eptr,data,length);
5229 break;
5230 case CLTOMA_FUSE_PATHS:
5231 matoclserv_fuse_paths(eptr,data,length);
5232 break;
5233 case CLTOMA_FUSE_GETXATTR:
5234 matoclserv_fuse_getxattr(eptr,data,length);
5235 break;
5236 case CLTOMA_FUSE_SETXATTR:
5237 matoclserv_fuse_setxattr(eptr,data,length);
5238 break;
5239 case CLTOMA_FUSE_GETFACL:
5240 matoclserv_fuse_getfacl(eptr,data,length);
5241 break;
5242 case CLTOMA_FUSE_SETFACL:
5243 matoclserv_fuse_setfacl(eptr,data,length);
5244 break;
5245 case CLTOMA_FUSE_QUOTACONTROL:
5246 matoclserv_fuse_quotacontrol(eptr,data,length);
5247 break;
5248 case CLTOMA_FUSE_ARCHCTL:
5249 matoclserv_fuse_archctl(eptr,data,length);
5250 break;
5251 case CLTOMA_SCLASS_CREATE:
5252 matoclserv_sclass_create(eptr,data,length);
5253 break;
5254 case CLTOMA_SCLASS_CHANGE:
5255 matoclserv_sclass_change(eptr,data,length);
5256 break;
5257 case CLTOMA_SCLASS_DELETE:
5258 matoclserv_sclass_delete(eptr,data,length);
5259 break;
5260 case CLTOMA_SCLASS_DUPLICATE:
5261 matoclserv_sclass_duplicate(eptr,data,length);
5262 break;
5263 case CLTOMA_SCLASS_RENAME:
5264 matoclserv_sclass_rename(eptr,data,length);
5265 break;
5266 case CLTOMA_SCLASS_LIST:
5267 matoclserv_sclass_list(eptr,data,length);
5268 break;
5269
5270 /* for tools - also should be available for registered clients */
5271 case CLTOMA_CSERV_LIST:
5272 matoclserv_cserv_list(eptr,data,length);
5273 break;
5274 case CLTOMA_SESSION_LIST:
5275 matoclserv_session_list(eptr,data,length);
5276 break;
5277 case CLTOAN_CHART:
5278 matoclserv_chart(eptr,data,length);
5279 break;
5280 case CLTOAN_CHART_DATA:
5281 matoclserv_chart_data(eptr,data,length);
5282 break;
5283 case CLTOAN_MONOTONIC_DATA:
5284 matoclserv_monotonic_data(eptr,data,length);
5285 break;
5286 case CLTOMA_INFO:
5287 matoclserv_info(eptr,data,length);
5288 break;
5289 case CLTOMA_FSTEST_INFO:
5290 matoclserv_fstest_info(eptr,data,length);
5291 break;
5292 case CLTOMA_CHUNKSTEST_INFO:
5293 matoclserv_chunkstest_info(eptr,data,length);
5294 break;
5295 case CLTOMA_CHUNKS_MATRIX:
5296 matoclserv_chunks_matrix(eptr,data,length);
5297 break;
5298 case CLTOMA_QUOTA_INFO:
5299 matoclserv_quota_info(eptr,data,length);
5300 break;
5301 case CLTOMA_EXPORTS_INFO:
5302 matoclserv_exports_info(eptr,data,length);
5303 break;
5304 case CLTOMA_MLOG_LIST:
5305 matoclserv_mlog_list(eptr,data,length);
5306 break;
5307 case CLTOMA_CSSERV_COMMAND:
5308 matoclserv_cserv_command(eptr,data,length);
5309 break;
5310 case CLTOMA_SESSION_COMMAND:
5311 matoclserv_session_command(eptr,data,length);
5312 break;
5313 case CLTOMA_MEMORY_INFO:
5314 matoclserv_memory_info(eptr,data,length);
5315 break;
5316 case CLTOAN_MODULE_INFO:
5317 matoclserv_module_info(eptr,data,length);
5318 break;
5319 case CLTOMA_LIST_OPEN_FILES:
5320 matoclserv_list_open_files(eptr,data,length);
5321 break;
5322 case CLTOMA_LIST_ACQUIRED_LOCKS:
5323 matoclserv_list_acquired_locks(eptr,data,length);
5324 break;
5325 case CLTOMA_MASS_RESOLVE_PATHS:
5326 matoclserv_mass_resolve_paths(eptr,data,length);
5327 break;
5328 case CLTOMA_SCLASS_INFO:
5329 matoclserv_sclass_info(eptr,data,length);
5330 break;
5331 case CLTOMA_MISSING_CHUNKS:
5332 matoclserv_missing_chunks(eptr,data,length);
5333 break;
5334 case CLTOMA_NODE_INFO:
5335 matoclserv_node_info(eptr,data,length);
5336 break;
5337 default:
5338 syslog(LOG_NOTICE,"main master server module: got unknown message from mfsmount (type:%"PRIu32")",type);
5339 eptr->mode=KILL;
5340 }
5341 } else { // old mfstools
5342 if (eptr->sesdata==NULL) {
5343 syslog(LOG_ERR,"registered connection (tools) without sesdata !!!");
5344 eptr->mode=KILL;
5345 return;
5346 }
5347 switch (type) {
5348 // extra (external tools)
5349 case ANTOAN_GET_VERSION:
5350 matoclserv_get_version(eptr,data,length);
5351 break;
5352 case ANTOAN_GET_CONFIG:
5353 matoclserv_get_config(eptr,data,length);
5354 break;
5355 case CLTOMA_FUSE_REGISTER:
5356 matoclserv_fuse_register(eptr,data,length);
5357 break;
5358 case CLTOMA_FUSE_READ_CHUNK: // used in mfsfileinfo
5359 matoclserv_fuse_read_chunk(eptr,data,length);
5360 break;
5361 case CLTOMA_FUSE_CHECK:
5362 matoclserv_fuse_check(eptr,data,length);
5363 break;
5364 case CLTOMA_FUSE_GETTRASHTIME:
5365 matoclserv_fuse_gettrashtime(eptr,data,length);
5366 break;
5367 case CLTOMA_FUSE_SETTRASHTIME:
5368 matoclserv_fuse_settrashtime(eptr,data,length);
5369 break;
5370 case CLTOMA_FUSE_GETSCLASS:
5371 matoclserv_fuse_getsclass(eptr,data,length);
5372 break;
5373 case CLTOMA_FUSE_SETSCLASS:
5374 matoclserv_fuse_setsclass(eptr,data,length);
5375 break;
5376 case CLTOMA_FUSE_APPEND_SLICE:
5377 matoclserv_fuse_append_slice(eptr,data,length);
5378 break;
5379 case CLTOMA_FUSE_GETDIRSTATS:
5380 matoclserv_fuse_getdirstats(eptr,data,length);
5381 break;
5382 case CLTOMA_FUSE_TRUNCATE:
5383 matoclserv_fuse_truncate(eptr,data,length);
5384 break;
5385 case CLTOMA_FUSE_REPAIR:
5386 matoclserv_fuse_repair(eptr,data,length);
5387 break;
5388 case CLTOMA_FUSE_SNAPSHOT:
5389 matoclserv_fuse_snapshot(eptr,data,length);
5390 break;
5391 case CLTOMA_FUSE_GETEATTR:
5392 matoclserv_fuse_geteattr(eptr,data,length);
5393 break;
5394 case CLTOMA_FUSE_SETEATTR:
5395 matoclserv_fuse_seteattr(eptr,data,length);
5396 break;
5397 case CLTOMA_FUSE_QUOTACONTROL:
5398 matoclserv_fuse_quotacontrol(eptr,data,length);
5399 break;
5400 case CLTOMA_FUSE_ARCHCTL:
5401 matoclserv_fuse_archctl(eptr,data,length);
5402 break;
5403 case CLTOMA_SCLASS_CREATE:
5404 matoclserv_sclass_create(eptr,data,length);
5405 break;
5406 case CLTOMA_SCLASS_CHANGE:
5407 matoclserv_sclass_change(eptr,data,length);
5408 break;
5409 case CLTOMA_SCLASS_DELETE:
5410 matoclserv_sclass_delete(eptr,data,length);
5411 break;
5412 case CLTOMA_SCLASS_DUPLICATE:
5413 matoclserv_sclass_duplicate(eptr,data,length);
5414 break;
5415 case CLTOMA_SCLASS_RENAME:
5416 matoclserv_sclass_rename(eptr,data,length);
5417 break;
5418 case CLTOMA_SCLASS_LIST:
5419 matoclserv_sclass_list(eptr,data,length);
5420 break;
5421 default:
5422 syslog(LOG_NOTICE,"main master server module: got unknown message from mfstools (type:%"PRIu32")",type);
5423 eptr->mode=KILL;
5424 }
5425 }
5426 }
5427
matoclserv_read(matoclserventry * eptr,double now)5428 void matoclserv_read(matoclserventry *eptr,double now) {
5429 int32_t i;
5430 uint32_t type,leng;
5431 const uint8_t *ptr;
5432 uint32_t rbleng,rbpos;
5433 uint8_t err,hup,errmsg;
5434 static uint8_t *readbuff = NULL;
5435 static uint32_t readbuffsize = 0;
5436
5437 if (eptr == NULL) {
5438 if (readbuff != NULL) {
5439 free(readbuff);
5440 }
5441 readbuff = NULL;
5442 readbuffsize = 0;
5443 return;
5444 }
5445
5446 if (readbuffsize==0) {
5447 readbuffsize = 65536;
5448 readbuff = malloc(readbuffsize);
5449 passert(readbuff);
5450 }
5451
5452 rbleng = 0;
5453 err = 0;
5454 hup = 0;
5455 errmsg = 0;
5456 for (;;) {
5457 i = read(eptr->sock,readbuff+rbleng,readbuffsize-rbleng);
5458 if (i==0) {
5459 hup = 1;
5460 break;
5461 } else if (i<0) {
5462 if (ERRNO_ERROR) {
5463 err = 1;
5464 #ifdef ECONNRESET
5465 if (errno!=ECONNRESET || eptr->registered<100) {
5466 #endif
5467 errmsg = 1;
5468 #ifdef ECONNRESET
5469 }
5470 #endif
5471 }
5472 break;
5473 } else {
5474 stats_brcvd += i;
5475 rbleng += i;
5476 if (rbleng==readbuffsize) {
5477 readbuffsize*=2;
5478 readbuff = mfsrealloc(readbuff,readbuffsize);
5479 passert(readbuff);
5480 } else {
5481 break;
5482 }
5483 }
5484 }
5485
5486 if (rbleng>0) {
5487 eptr->lastread = now;
5488 }
5489
5490 rbpos = 0;
5491 while (rbpos<rbleng) {
5492 if ((rbleng-rbpos)>=eptr->input_bytesleft) {
5493 memcpy(eptr->input_startptr,readbuff+rbpos,eptr->input_bytesleft);
5494 i = eptr->input_bytesleft;
5495 } else {
5496 memcpy(eptr->input_startptr,readbuff+rbpos,rbleng-rbpos);
5497 i = rbleng-rbpos;
5498 }
5499 rbpos += i;
5500 eptr->input_startptr+=i;
5501 eptr->input_bytesleft-=i;
5502
5503 if (eptr->input_bytesleft>0) {
5504 break;
5505 }
5506
5507 if (eptr->input_packet == NULL) {
5508 ptr = eptr->input_hdr;
5509 type = get32bit(&ptr);
5510 leng = get32bit(&ptr);
5511
5512 if (leng>MaxPacketSize) {
5513 syslog(LOG_WARNING,"main master server module: packet too long (%"PRIu32"/%u) ; command:%"PRIu32,leng,MaxPacketSize,type);
5514 eptr->input_end = 1;
5515 return;
5516 }
5517
5518 stats_prcvd++;
5519 eptr->input_packet = malloc(offsetof(in_packetstruct,data)+leng);
5520 passert(eptr->input_packet);
5521 eptr->input_packet->next = NULL;
5522 eptr->input_packet->type = type;
5523 eptr->input_packet->leng = leng;
5524
5525 eptr->input_startptr = eptr->input_packet->data;
5526 eptr->input_bytesleft = leng;
5527 }
5528
5529 if (eptr->input_bytesleft>0) {
5530 continue;
5531 }
5532
5533 if (eptr->input_packet != NULL) {
5534 *(eptr->inputtail) = eptr->input_packet;
5535 eptr->inputtail = &(eptr->input_packet->next);
5536 eptr->input_packet = NULL;
5537 eptr->input_bytesleft = 8;
5538 eptr->input_startptr = eptr->input_hdr;
5539 }
5540 }
5541
5542 if (hup) {
5543 if (eptr->registered>0 && eptr->registered<100) { // show this message only for standard, registered clients
5544 syslog(LOG_NOTICE,"connection with client(ip:%u.%u.%u.%u) has been closed by peer",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
5545 }
5546 eptr->input_end = 1;
5547 } else if (err) {
5548 if (errmsg) {
5549 mfs_arg_errlog_silent(LOG_NOTICE,"main master server module: (ip:%u.%u.%u.%u) read error",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
5550 }
5551 eptr->input_end = 1;
5552 }
5553 }
5554
matoclserv_parse(matoclserventry * eptr)5555 void matoclserv_parse(matoclserventry *eptr) {
5556 in_packetstruct *ipack;
5557 uint64_t starttime;
5558 uint64_t currtime;
5559
5560 starttime = monotonic_useconds();
5561 currtime = starttime;
5562 while (eptr->mode==DATA && (ipack = eptr->inputhead)!=NULL && starttime+10000>currtime) {
5563 matoclserv_gotpacket(eptr,ipack->type,ipack->data,ipack->leng);
5564 eptr->inputhead = ipack->next;
5565 free(ipack);
5566 if (eptr->inputhead==NULL) {
5567 eptr->inputtail = &(eptr->inputhead);
5568 } else {
5569 currtime = monotonic_useconds();
5570 }
5571 }
5572 if (eptr->mode==DATA && eptr->inputhead==NULL && eptr->input_end) {
5573 eptr->mode = KILL;
5574 }
5575 }
5576
matoclserv_write(matoclserventry * eptr,double now)5577 void matoclserv_write(matoclserventry *eptr,double now) {
5578 out_packetstruct *opack;
5579 int32_t i;
5580 #ifdef HAVE_WRITEV
5581 struct iovec iovtab[100];
5582 uint32_t iovdata;
5583 uint32_t leng;
5584 uint32_t left;
5585
5586 for (;;) {
5587 leng = 0;
5588 for (iovdata=0,opack=eptr->outputhead ; iovdata<100 && opack!=NULL ; iovdata++,opack=opack->next) {
5589 iovtab[iovdata].iov_base = opack->startptr;
5590 iovtab[iovdata].iov_len = opack->bytesleft;
5591 leng += opack->bytesleft;
5592 }
5593 if (iovdata==0) {
5594 return;
5595 }
5596 i = writev(eptr->sock,iovtab,iovdata);
5597 if (i<0) {
5598 if (ERRNO_ERROR) {
5599 mfs_arg_errlog_silent(LOG_NOTICE,"main master server module: (ip:%u.%u.%u.%u) write error",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
5600 eptr->mode = KILL;
5601 }
5602 return;
5603 }
5604 if (i>0) {
5605 eptr->lastwrite = now;
5606 }
5607 stats_bsent+=i;
5608 left = i;
5609 while (left>0 && eptr->outputhead!=NULL) {
5610 opack = eptr->outputhead;
5611 if (opack->bytesleft>left) {
5612 opack->startptr+=left;
5613 opack->bytesleft-=left;
5614 left = 0;
5615 } else {
5616 left -= opack->bytesleft;
5617 eptr->outputhead = opack->next;
5618 if (eptr->outputhead==NULL) {
5619 eptr->outputtail = &(eptr->outputhead);
5620 }
5621 free(opack);
5622 stats_psent++;
5623 }
5624 }
5625 if ((uint32_t)i < leng) {
5626 return;
5627 }
5628 }
5629 #else
5630 for (;;) {
5631 opack = eptr->outputhead;
5632 if (opack==NULL) {
5633 return;
5634 }
5635 i=write(eptr->sock,opack->startptr,opack->bytesleft);
5636 if (i<0) {
5637 if (ERRNO_ERROR) {
5638 mfs_arg_errlog_silent(LOG_NOTICE,"main master server module: (ip:%u.%u.%u.%u) write error",(eptr->peerip>>24)&0xFF,(eptr->peerip>>16)&0xFF,(eptr->peerip>>8)&0xFF,eptr->peerip&0xFF);
5639 eptr->mode = KILL;
5640 }
5641 return;
5642 }
5643 if (i>0) {
5644 eptr->lastwrite = now;
5645 }
5646 opack->startptr+=i;
5647 opack->bytesleft-=i;
5648 stats_bsent+=i;
5649 if (opack->bytesleft>0) {
5650 return;
5651 }
5652 stats_psent++;
5653 eptr->outputhead = opack->next;
5654 if (eptr->outputhead==NULL) {
5655 eptr->outputtail = &(eptr->outputhead);
5656 }
5657 free(opack);
5658 }
5659 #endif
5660 }
5661
matoclserv_desc(struct pollfd * pdesc,uint32_t * ndesc)5662 void matoclserv_desc(struct pollfd *pdesc,uint32_t *ndesc) {
5663 uint32_t pos = *ndesc;
5664 matoclserventry *eptr;
5665
5666 pdesc[pos].fd = lsock;
5667 pdesc[pos].events = POLLIN;
5668 lsockpdescpos = pos;
5669 pos++;
5670 // FD_SET(lsock,rset);
5671 // max = lsock;
5672 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5673 pdesc[pos].fd = eptr->sock;
5674 pdesc[pos].events = 0;
5675 eptr->pdescpos = pos;
5676 // i=eptr->sock;
5677 pdesc[pos].events |= POLLIN;
5678 // FD_SET(i,rset);
5679 // if (i>max) {
5680 // max=i;
5681 // }
5682 if (eptr->outputhead!=NULL) {
5683 pdesc[pos].events |= POLLOUT;
5684 // FD_SET(i,wset);
5685 // if (i>max) {
5686 // max=i;
5687 // }
5688 }
5689 pos++;
5690 }
5691 *ndesc = pos;
5692 // return max;
5693 }
5694
matoclserv_disconnection_loop(void)5695 void matoclserv_disconnection_loop(void) {
5696 matoclserventry *eptr,**kptr;
5697 in_packetstruct *ipptr,*ipaptr;
5698 out_packetstruct *opptr,*opaptr;
5699
5700 kptr = &matoclservhead;
5701 while ((eptr=*kptr)) {
5702 if (eptr->mode == KILL) {
5703 matoclserv_beforedisconnect(eptr);
5704 tcpclose(eptr->sock);
5705 if (eptr->input_packet) {
5706 free(eptr->input_packet);
5707 }
5708 ipptr = eptr->inputhead;
5709 while (ipptr) {
5710 ipaptr = ipptr;
5711 ipptr = ipptr->next;
5712 free(ipaptr);
5713 }
5714 opptr = eptr->outputhead;
5715 while (opptr) {
5716 opaptr = opptr;
5717 opptr = opptr->next;
5718 free(opaptr);
5719 }
5720 *kptr = eptr->next;
5721 free(eptr);
5722 } else {
5723 kptr = &(eptr->next);
5724 }
5725 }
5726 }
5727
matoclserv_serve(struct pollfd * pdesc)5728 void matoclserv_serve(struct pollfd *pdesc) {
5729 double now;
5730 matoclserventry *eptr;
5731 int ns;
5732 static double lastaction = 0.0;
5733 double timeoutadd;
5734
5735 now = monotonic_seconds();
5736 // timeout fix
5737 if (lastaction>0.0) {
5738 timeoutadd = now-lastaction;
5739 if (timeoutadd>1.0) {
5740 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5741 eptr->lastread += timeoutadd;
5742 }
5743 }
5744 }
5745 lastaction = now;
5746
5747 if (lsockpdescpos>=0 && (pdesc[lsockpdescpos].revents & POLLIN)) {
5748 // if (FD_ISSET(lsock,rset)) {
5749 ns=tcpaccept(lsock);
5750 if (ns<0) {
5751 mfs_errlog_silent(LOG_NOTICE,"main master server module: accept error");
5752 } else {
5753 tcpnonblock(ns);
5754 tcpnodelay(ns);
5755 eptr = malloc(sizeof(matoclserventry));
5756 passert(eptr);
5757 eptr->next = matoclservhead;
5758 matoclservhead = eptr;
5759 eptr->sock = ns;
5760 eptr->pdescpos = -1;
5761 tcpgetpeer(ns,&(eptr->peerip),NULL);
5762 eptr->registered = 0;
5763 eptr->version = 0;
5764 eptr->asize = 0;
5765 eptr->mode = DATA;
5766 eptr->lastread = now;
5767 eptr->lastwrite = now;
5768 eptr->input_bytesleft = 8;
5769 eptr->input_startptr = eptr->input_hdr;
5770 eptr->input_end = 0;
5771 eptr->input_packet = NULL;
5772 eptr->inputhead = NULL;
5773 eptr->inputtail = &(eptr->inputhead);
5774 eptr->outputhead = NULL;
5775 eptr->outputtail = &(eptr->outputhead);
5776
5777 eptr->path = NULL;
5778 eptr->info = NULL;
5779 eptr->ileng = 0;
5780 eptr->usepassword = 0;
5781
5782 eptr->sesdata = NULL;
5783 memset(eptr->passwordrnd,0,32);
5784 }
5785 }
5786
5787 // read
5788 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5789 if (eptr->pdescpos>=0) {
5790 if ((pdesc[eptr->pdescpos].revents & (POLLERR|POLLIN))==POLLIN && eptr->mode!=KILL) {
5791 matoclserv_read(eptr,now);
5792 }
5793 if (pdesc[eptr->pdescpos].revents & (POLLERR|POLLHUP)) {
5794 eptr->input_end = 1;
5795 }
5796 }
5797 matoclserv_parse(eptr);
5798 }
5799
5800 // write
5801 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5802 if (eptr->lastwrite+1.0<now && eptr->registered<100 && eptr->outputhead==NULL) {
5803 uint8_t *ptr = matoclserv_createpacket(eptr,ANTOAN_NOP,4); // 4 byte length because of 'msgid'
5804 *((uint32_t*)ptr) = 0;
5805 }
5806 if (eptr->pdescpos>=0) {
5807 if ((((pdesc[eptr->pdescpos].events & POLLOUT)==0 && (eptr->outputhead)) || (pdesc[eptr->pdescpos].revents & POLLOUT)) && eptr->mode!=KILL) {
5808 matoclserv_write(eptr,now);
5809 }
5810 }
5811 if (eptr->lastread+10.0<now) {
5812 eptr->mode = KILL;
5813 }
5814 if (eptr->mode==FINISH && eptr->outputhead==NULL) {
5815 eptr->mode = KILL;
5816 }
5817 }
5818
5819 matoclserv_disconnection_loop();
5820 }
5821
matoclserv_keep_alive(void)5822 void matoclserv_keep_alive(void) {
5823 double now;
5824 matoclserventry *eptr;
5825
5826 now = monotonic_seconds();
5827 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5828 if (eptr->mode == DATA && eptr->input_end==0) {
5829 matoclserv_read(eptr,now);
5830 }
5831 }
5832 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5833 if (eptr->lastwrite+1.0<now && eptr->registered<100 && eptr->outputhead==NULL) {
5834 uint8_t *ptr = matoclserv_createpacket(eptr,ANTOAN_NOP,4); // 4 byte length because of 'msgid'
5835 *((uint32_t*)ptr) = 0;
5836 }
5837 if (eptr->mode == DATA && eptr->outputhead) {
5838 matoclserv_write(eptr,now);
5839 }
5840 }
5841 }
5842
matoclserv_close_lsock(void)5843 void matoclserv_close_lsock(void) { // after fork
5844 if (lsock>=0) {
5845 close(lsock);
5846 }
5847 }
5848
matoclserv_term(void)5849 void matoclserv_term(void) {
5850 matoclserventry *eptr,*eaptr;
5851 in_packetstruct *ipptr,*ipaptr;
5852 out_packetstruct *opptr,*opaptr;
5853 swchunks *swc,*swcn;
5854 lwchunks *lwc,*lwcn;
5855 uint32_t i;
5856
5857 syslog(LOG_NOTICE,"main master server module: closing %s:%s",ListenHost,ListenPort);
5858 tcpclose(lsock);
5859
5860 eptr = matoclservhead;
5861 while (eptr) {
5862 if (eptr->input_packet) {
5863 free(eptr->input_packet);
5864 }
5865 ipptr = eptr->inputhead;
5866 while (ipptr) {
5867 ipaptr = ipptr;
5868 ipptr = ipptr->next;
5869 free(ipaptr);
5870 }
5871 opptr = eptr->outputhead;
5872 while (opptr) {
5873 opaptr = opptr;
5874 opptr = opptr->next;
5875 free(opaptr);
5876 }
5877 eaptr = eptr;
5878 eptr = eptr->next;
5879 free(eaptr);
5880 }
5881 matoclservhead=NULL;
5882
5883 for (i=0 ; i<CHUNKHASHSIZE ; i++) {
5884 for (swc = swchunkshash[i] ; swc ; swc = swcn) {
5885 // fs_rollback(swc->inode,swc->indx,swc->prevchunkid,swc->chunkid);
5886 swcn = swc->next;
5887 free(swc);
5888 }
5889 for (lwc = lwchunkshashhead[i] ; lwc ; lwc = lwcn) {
5890 lwcn = lwc->next;
5891 free(lwc);
5892 }
5893 swchunkshash[i] = NULL;
5894 lwchunkshashhead[i] = NULL;
5895 lwchunkshashtail[i] = NULL;
5896 }
5897
5898 matoclserv_read(NULL,0.0); // free internal read buffer
5899 matoclserv_gid_storage(0); // free supplementary groups buffer
5900
5901 free(ListenHost);
5902 free(ListenPort);
5903 }
5904
matoclserv_no_more_pending_jobs(void)5905 int matoclserv_no_more_pending_jobs(void) {
5906 matoclserventry *eptr;
5907 uint32_t i;
5908 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5909 if (eptr->outputhead!=NULL) {
5910 return 0;
5911 }
5912 }
5913 for (i=0 ; i<CHUNKHASHSIZE ; i++) {
5914 if (swchunkshash[i]!=NULL) {
5915 return 0;
5916 }
5917 }
5918 return 1;
5919 }
5920
matoclserv_disconnect_all(void)5921 void matoclserv_disconnect_all(void) {
5922 matoclserventry *eptr;
5923 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5924 eptr->mode = KILL;
5925 }
5926 matoclserv_disconnection_loop();
5927 }
5928
matoclserv_reload(void)5929 void matoclserv_reload(void) {
5930 char *oldListenHost,*oldListenPort;
5931 int newlsock;
5932
5933 matoclserv_reload_sessions();
5934
5935 oldListenHost = ListenHost;
5936 oldListenPort = ListenPort;
5937 if (cfg_isdefined("MATOCL_LISTEN_HOST") || cfg_isdefined("MATOCL_LISTEN_PORT") || !(cfg_isdefined("MATOCU_LISTEN_HOST") || cfg_isdefined("MATOCU_LISTEN_PORT"))) {
5938 ListenHost = cfg_getstr("MATOCL_LISTEN_HOST","*");
5939 ListenPort = cfg_getstr("MATOCL_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT);
5940 } else {
5941 ListenHost = cfg_getstr("MATOCU_LISTEN_HOST","*"); // deprecated option
5942 ListenPort = cfg_getstr("MATOCU_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT); // deprecated option
5943 }
5944 if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) {
5945 free(oldListenHost);
5946 free(oldListenPort);
5947 mfs_arg_syslog(LOG_NOTICE,"main master server module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort);
5948 return;
5949 }
5950
5951 newlsock = tcpsocket();
5952 if (newlsock<0) {
5953 mfs_errlog(LOG_WARNING,"main master server module: socket address has changed, but can't create new socket");
5954 free(ListenHost);
5955 free(ListenPort);
5956 ListenHost = oldListenHost;
5957 ListenPort = oldListenPort;
5958 return;
5959 }
5960 tcpnonblock(newlsock);
5961 tcpnodelay(newlsock);
5962 tcpreuseaddr(newlsock);
5963 if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) {
5964 mfs_arg_errlog(LOG_ERR,"main master server module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort);
5965 free(ListenHost);
5966 free(ListenPort);
5967 ListenHost = oldListenHost;
5968 ListenPort = oldListenPort;
5969 tcpclose(newlsock);
5970 return;
5971 }
5972 if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) {
5973 mfs_errlog_silent(LOG_NOTICE,"main master server module: can't set accept filter");
5974 }
5975 mfs_arg_syslog(LOG_NOTICE,"main master server module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort);
5976 free(oldListenHost);
5977 free(oldListenPort);
5978 tcpclose(lsock);
5979 lsock = newlsock;
5980 }
5981
matoclserv_init(void)5982 int matoclserv_init(void) {
5983 if (cfg_isdefined("MATOCL_LISTEN_HOST") || cfg_isdefined("MATOCL_LISTEN_PORT") || !(cfg_isdefined("MATOCU_LISTEN_HOST") || cfg_isdefined("MATOCU_LISTEN_HOST"))) {
5984 ListenHost = cfg_getstr("MATOCL_LISTEN_HOST","*");
5985 ListenPort = cfg_getstr("MATOCL_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT);
5986 } else {
5987 fprintf(stderr,"change MATOCU_LISTEN_* option names to MATOCL_LISTEN_* !!!\n");
5988 ListenHost = cfg_getstr("MATOCU_LISTEN_HOST","*"); // deprecated option
5989 ListenPort = cfg_getstr("MATOCU_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT); // deprecated option
5990 }
5991
5992 CreateFirstChunk = 0;
5993
5994 lsock = tcpsocket();
5995 if (lsock<0) {
5996 mfs_errlog(LOG_ERR,"main master server module: can't create socket");
5997 return -1;
5998 }
5999 tcpnonblock(lsock);
6000 tcpnodelay(lsock);
6001 tcpreuseaddr(lsock);
6002 if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
6003 mfs_arg_errlog(LOG_ERR,"main master server module: can't listen on %s:%s",ListenHost,ListenPort);
6004 return -1;
6005 }
6006 if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
6007 mfs_errlog_silent(LOG_NOTICE,"main master server module: can't set accept filter");
6008 }
6009 mfs_arg_syslog(LOG_NOTICE,"main master server module: listen on %s:%s",ListenHost,ListenPort);
6010
6011 matoclservhead = NULL;
6012
6013 main_time_register(1,0,matoclserv_timeout_waiting_ops);
6014 main_reload_register(matoclserv_reload);
6015 main_destruct_register(matoclserv_term);
6016 main_poll_register(matoclserv_desc,matoclserv_serve);
6017 main_keepalive_register(matoclserv_keep_alive);
6018 return 0;
6019 }
6020