1 /*
2 * Copyright (C) 2016 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/uio.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <syslog.h>
35 #include <errno.h>
36 #include <inttypes.h>
37 #include <netinet/in.h>
38 #include <sys/resource.h>
39 #ifdef HAVE_WRITEV
40 #include <sys/uio.h>
41 #endif
42
43 #include "MFSCommunication.h"
44
45 #include "datapack.h"
46 #include "matoclserv.h"
47 #include "matocsserv.h"
48 #include "matomlserv.h"
49 #include "sessions.h"
50 #include "csdb.h"
51 #include "chunks.h"
52 #include "filesystem.h"
53 #include "openfiles.h"
54 #include "metadata.h"
55 #include "random.h"
56 #include "exports.h"
57 #include "datacachemgr.h"
58 #include "charts.h"
59 #include "chartsdata.h"
60 #include "cfg.h"
61 #include "main.h"
62 #include "sockets.h"
63 #include "slogger.h"
64 #include "massert.h"
65 #include "clocks.h"
66 #include "missinglog.h"
67
68 #define MaxPacketSize CLTOMA_MAXPACKETSIZE
69
70 // matoclserventry.mode
71 enum {KILL,DATA,FINISH};
72 // chunklis.type
73 enum {FUSE_WRITE,FUSE_TRUNCATE};
74
75 // #define SESSION_STATS 16
76
77 /* CACHENOTIFY
78 // hash size should be at least 1.5 * 10000 * # of connected mounts
79 // it also should be the prime number
80 // const 10000 is defined in mfsmount/dircache.c file as DIRS_REMOVE_THRESHOLD_MAX
81 // current const is calculated as nextprime(1.5 * 10000 * 500) and is enough for up to about 500 mounts
82 #define DIRINODE_HASH_SIZE 7500013
83 */
84
85 struct matoclserventry;
86
87 /* CACHENOTIFY
88 // directories in external caches
89 typedef struct dirincache {
90 struct matoclserventry *eptr;
91 uint32_t dirinode;
92 struct dirincache *nextnode,**prevnode;
93 struct dirincache *nextcu,**prevcu;
94 } dirincache;
95
96 static dirincache **dirinodehash;
97 */
98
99 // locked chunks
100 typedef struct chunklist {
101 uint64_t chunkid;
102 uint64_t fleng; // file length
103 uint32_t qid; // queryid for answer
104 uint32_t inode; // inode
105 uint32_t uid;
106 uint32_t gid;
107 uint32_t auid;
108 uint32_t agid;
109 uint8_t type;
110 struct chunklist *next;
111 } chunklist;
112
113 // opened files
114 /*
115 typedef struct filelist {
116 uint32_t inode;
117 struct filelist *next;
118 } filelist;
119
120 typedef struct session {
121 uint32_t sessionid;
122 char *info;
123 uint32_t peerip;
124 uint8_t newsession;
125 uint8_t sesflags;
126 uint8_t mingoal;
127 uint8_t maxgoal;
128 uint32_t mintrashtime;
129 uint32_t maxtrashtime;
130 uint32_t rootuid;
131 uint32_t rootgid;
132 uint32_t mapalluid;
133 uint32_t mapallgid;
134 uint32_t rootinode;
135 uint32_t disconnected; // 0 = connected ; other = disconnection timestamp
136 uint32_t nsocks; // >0 - connected (number of active connections) ; 0 - not connected
137 uint32_t currentopstats[SESSION_STATS];
138 uint32_t lasthouropstats[SESSION_STATS];
139 filelist *openedfiles;
140 struct session *next;
141 } session;
142 */
143
144 typedef struct out_packetstruct {
145 struct out_packetstruct *next;
146 uint8_t *startptr;
147 uint32_t bytesleft;
148 uint8_t data[1];
149 } out_packetstruct;
150
151 typedef struct in_packetstruct {
152 struct in_packetstruct *next;
153 uint32_t type,leng;
154 uint8_t data[1];
155 } in_packetstruct;
156
157 typedef struct matoclserventry {
158 uint8_t registered;
159 uint8_t mode; //0 - not active, 1 - read header, 2 - read packet
160 /* CACHENOTIFY
161 uint8_t notifications;
162 */
163 int sock; //socket number
164 int32_t pdescpos;
165 double lastread,lastwrite; //time of last activity
166 uint8_t input_hdr[8];
167 uint8_t *input_startptr;
168 uint32_t input_bytesleft;
169 uint8_t input_end;
170 in_packetstruct *input_packet;
171 in_packetstruct *inputhead,**inputtail;
172 out_packetstruct *outputhead,**outputtail;
173 uint32_t version;
174 uint32_t peerip;
175
176 uint8_t passwordrnd[32];
177 // session *sesdata;
178 void *sesdata;
179 chunklist *chunkdelayedops;
180 /* CACHENOTIFY
181 dirincache *cacheddirs;
182 */
183 // filelist *openedfiles;
184
185 struct matoclserventry *next;
186 } matoclserventry;
187
188 //static session *sessionshead=NULL;
189 static matoclserventry *matoclservhead=NULL;
190 static int lsock;
191 static int32_t lsockpdescpos;
192 static int starting;
193
194 // from config
195 static char *ListenHost;
196 static char *ListenPort;
197 //static uint32_t SessionSustainTime;
198 //static uint32_t Timeout;
199
200 static uint32_t stats_prcvd = 0;
201 static uint32_t stats_psent = 0;
202 static uint64_t stats_brcvd = 0;
203 static uint64_t stats_bsent = 0;
204
matoclserv_stats(uint64_t stats[5])205 void matoclserv_stats(uint64_t stats[5]) {
206 stats[0] = stats_prcvd;
207 stats[1] = stats_psent;
208 stats[2] = stats_brcvd;
209 stats[3] = stats_bsent;
210 stats_prcvd = 0;
211 stats_psent = 0;
212 stats_brcvd = 0;
213 stats_bsent = 0;
214 }
215
216 /* CACHENOTIFY
217 // cache notification routines
218
219 static inline void matoclserv_dircache_init(void) {
220 dirinodehash = (dirincache**)malloc(sizeof(dirincache*)*DIRINODE_HASH_SIZE);
221 passert(dirinodehash);
222 }
223
224 static inline void matoclserv_dircache_remove_entry(dirincache *dc) {
225 *(dc->prevnode) = dc->nextnode;
226 if (dc->nextnode) {
227 dc->nextnode->prevnode = dc->prevnode;
228 }
229 *(dc->prevcu) = dc->nextcu;
230 if (dc->nextcu) {
231 dc->nextcu->prevcu = dc->prevcu;
232 }
233 free(dc);
234 }
235
236 static inline void matoclserv_notify_add_dir(matoclserventry *eptr,uint32_t inode) {
237 uint32_t hash = (inode*0x5F2318BD)%DIRINODE_HASH_SIZE;
238 dirincache *dc;
239
240 dc = (dirincache*)malloc(sizeof(dirincache));
241 passert(dc);
242 dc->eptr = eptr;
243 dc->dirinode = inode;
244 // by inode
245 dc->nextnode = dirinodehash[hash];
246 dc->prevnode = (dirinodehash+hash);
247 if (dirinodehash[hash]) {
248 dirinodehash[hash]->prevnode = &(dc->nextnode);
249 }
250 dirinodehash[hash] = dc;
251 // by eptr
252 dc->nextcu = eptr->cacheddirs;
253 dc->prevcu = &(eptr->cacheddirs);
254 if (eptr->cacheddirs) {
255 eptr->cacheddirs->prevcu = &(dc->nextcu);
256 }
257 eptr->cacheddirs = dc;
258
259 // syslog(LOG_NOTICE,"rcvd from: '%s' ; add inode: %"PRIu32,eptr->sesdata->info,inode);
260 }
261
262 static inline void matoclserv_notify_remove_dir(matoclserventry *eptr,uint32_t inode) {
263 uint32_t hash = (inode*0x5F2318BD)%DIRINODE_HASH_SIZE;
264 dirincache *dc,*ndc;
265
266 for (dc=dirinodehash[hash] ; dc ; dc=ndc) {
267 ndc = dc->nextnode;
268 if (dc->eptr==eptr && dc->dirinode==inode) {
269 matoclserv_dircache_remove_entry(dc);
270 }
271 }
272 // syslog(LOG_NOTICE,"rcvd from: '%s' ; remove inode: %"PRIu32,eptr->sesdata->info,inode);
273 }
274
275 static inline void matoclserv_notify_disconnected(matoclserventry *eptr) {
276 while (eptr->cacheddirs) {
277 matoclserv_dircache_remove_entry(eptr->cacheddirs);
278 }
279 }
280
281 static inline void matoclserv_show_notification_dirs(void) {
282 uint32_t hash;
283 dirincache *dc;
284
285 for (hash=0 ; hash<DIRINODE_HASH_SIZE ; hash++) {
286 for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
287 syslog(LOG_NOTICE,"session: %u ; dir inode: %u",dc->eptr->sesdata->sessionid,dc->dirinode);
288 }
289 }
290 }
291 */
292
293 /* new registration procedure */
294 /*
295 session* matoclserv_new_session(uint8_t newsession,uint8_t nonewid) {
296 session *asesdata;
297 asesdata = (session*)malloc(sizeof(session));
298 passert(asesdata);
299 if (newsession==0 && nonewid) {
300 asesdata->sessionid = 0;
301 } else {
302 asesdata->sessionid = fs_newsessionid();
303 }
304 asesdata->info = NULL;
305 asesdata->peerip = 0;
306 asesdata->sesflags = 0;
307 asesdata->rootuid = 0;
308 asesdata->rootgid = 0;
309 asesdata->mapalluid = 0;
310 asesdata->mapallgid = 0;
311 asesdata->newsession = newsession;
312 asesdata->rootinode = MFS_ROOT_ID;
313 asesdata->openedfiles = NULL;
314 asesdata->disconnected = 0;
315 asesdata->nsocks = 1;
316 memset(asesdata->currentopstats,0,4*SESSION_STATS);
317 memset(asesdata->lasthouropstats,0,4*SESSION_STATS);
318 asesdata->next = sessionshead;
319 sessionshead = asesdata;
320 return asesdata;
321 }
322
323 void matoclserv_attach_session(session* sesdata) {
324 // syslog(LOG_NOTICE,"found: %u ; before ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
325 if (sesdata->newsession>=2) {
326 sesdata->newsession-=2;
327 }
328 sesdata->nsocks++;
329 // syslog(LOG_NOTICE,"found: %u ; after ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
330 sesdata->disconnected = 0;
331 }
332
333 session* matoclserv_find_session(uint32_t sessionid) {
334 session *asesdata;
335 if (sessionid==0) {
336 return NULL;
337 }
338 for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
339 if (asesdata->sessionid==sessionid) {
340 return asesdata;
341 }
342 }
343 return NULL;
344 }
345
346 void matoclserv_close_session(uint32_t sessionid) {
347 session *asesdata;
348 if (sessionid==0) {
349 return;
350 }
351 for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
352 if (asesdata->sessionid==sessionid) {
353 // syslog(LOG_NOTICE,"close: %u ; before ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
354 if (asesdata->nsocks==1 && asesdata->newsession<2) {
355 asesdata->newsession+=2;
356 }
357 // syslog(LOG_NOTICE,"close: %u ; after ; nsocks: %u ; state: %u",sessionid,asesdata->nsocks,asesdata->newsession);
358 }
359 }
360 return;
361 }
362
363 void matoclserv_store_sessions() {
364 session *asesdata;
365 uint32_t ileng;
366 uint8_t fsesrecord[43+SESSION_STATS*8]; // 4+4+4+4+1+1+1+4+4+4+4+4+4+SESSION_STATS*4+SESSION_STATS*4
367 uint8_t *ptr;
368 int i;
369 FILE *fd;
370
371 fd = fopen("sessions.mfs.tmp","w");
372 if (fd==NULL) {
373 mfs_errlog_silent(LOG_WARNING,"can't store sessions, open error");
374 return;
375 }
376 memcpy(fsesrecord,MFSSIGNATURE "S \001\006\004",8);
377 ptr = fsesrecord+8;
378 put16bit(&ptr,SESSION_STATS);
379 if (fwrite(fsesrecord,10,1,fd)!=1) {
380 syslog(LOG_WARNING,"can't store sessions, fwrite error");
381 fclose(fd);
382 return;
383 }
384 for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
385 if (asesdata->newsession==1) {
386 ptr = fsesrecord;
387 if (asesdata->info) {
388 ileng = strlen(asesdata->info);
389 } else {
390 ileng = 0;
391 }
392 put32bit(&ptr,asesdata->sessionid);
393 put32bit(&ptr,ileng);
394 put32bit(&ptr,asesdata->peerip);
395 put32bit(&ptr,asesdata->rootinode);
396 put8bit(&ptr,asesdata->sesflags);
397 put8bit(&ptr,asesdata->mingoal);
398 put8bit(&ptr,asesdata->maxgoal);
399 put32bit(&ptr,asesdata->mintrashtime);
400 put32bit(&ptr,asesdata->maxtrashtime);
401 put32bit(&ptr,asesdata->rootuid);
402 put32bit(&ptr,asesdata->rootgid);
403 put32bit(&ptr,asesdata->mapalluid);
404 put32bit(&ptr,asesdata->mapallgid);
405 for (i=0 ; i<SESSION_STATS ; i++) {
406 put32bit(&ptr,asesdata->currentopstats[i]);
407 }
408 for (i=0 ; i<SESSION_STATS ; i++) {
409 put32bit(&ptr,asesdata->lasthouropstats[i]);
410 }
411 if (fwrite(fsesrecord,(43+SESSION_STATS*8),1,fd)!=1) {
412 syslog(LOG_WARNING,"can't store sessions, fwrite error");
413 fclose(fd);
414 return;
415 }
416 if (ileng>0) {
417 if (fwrite(asesdata->info,ileng,1,fd)!=1) {
418 syslog(LOG_WARNING,"can't store sessions, fwrite error");
419 fclose(fd);
420 return;
421 }
422 }
423 }
424 }
425 if (fclose(fd)!=0) {
426 mfs_errlog_silent(LOG_WARNING,"can't store sessions, fclose error");
427 return;
428 }
429 if (rename("sessions.mfs.tmp","sessions.mfs")<0) {
430 mfs_errlog_silent(LOG_WARNING,"can't store sessions, rename error");
431 }
432 }
433
434 int matoclserv_load_sessions() {
435 session *asesdata;
436 uint32_t ileng;
437 // uint8_t fsesrecord[33+SESSION_STATS*8]; // 4+4+4+4+1+4+4+4+4+SESSION_STATS*4+SESSION_STATS*4
438 uint8_t hdr[8];
439 uint8_t *fsesrecord;
440 const uint8_t *ptr;
441 uint8_t mapalldata;
442 uint8_t goaltrashdata;
443 uint32_t i,statsinfile;
444 int r;
445 FILE *fd;
446
447 fd = fopen("sessions.mfs","r");
448 if (fd==NULL) {
449 mfs_errlog_silent(LOG_WARNING,"can't load sessions, fopen error");
450 if (errno==ENOENT) { // it's ok if file does not exist
451 return 0;
452 } else {
453 return -1;
454 }
455 }
456 if (fread(hdr,8,1,fd)!=1) {
457 syslog(LOG_WARNING,"can't load sessions, fread error");
458 fclose(fd);
459 return -1;
460 }
461 if (memcmp(hdr,MFSSIGNATURE "S 1.5",8)==0) {
462 mapalldata = 0;
463 goaltrashdata = 0;
464 statsinfile = 16;
465 } else if (memcmp(hdr,MFSSIGNATURE "S \001\006\001",8)==0) {
466 mapalldata = 1;
467 goaltrashdata = 0;
468 statsinfile = 16;
469 } else if (memcmp(hdr,MFSSIGNATURE "S \001\006\002",8)==0) {
470 mapalldata = 1;
471 goaltrashdata = 0;
472 statsinfile = 21;
473 } else if (memcmp(hdr,MFSSIGNATURE "S \001\006\003",8)==0) {
474 mapalldata = 1;
475 goaltrashdata = 0;
476 if (fread(hdr,2,1,fd)!=1) {
477 syslog(LOG_WARNING,"can't load sessions, fread error");
478 fclose(fd);
479 return -1;
480 }
481 ptr = hdr;
482 statsinfile = get16bit(&ptr);
483 } else if (memcmp(hdr,MFSSIGNATURE "S \001\006\004",8)==0) {
484 mapalldata = 1;
485 goaltrashdata = 1;
486 if (fread(hdr,2,1,fd)!=1) {
487 syslog(LOG_WARNING,"can't load sessions, fread error");
488 fclose(fd);
489 return -1;
490 }
491 ptr = hdr;
492 statsinfile = get16bit(&ptr);
493 } else {
494 syslog(LOG_WARNING,"can't load sessions, bad header");
495 fclose(fd);
496 return -1;
497 }
498
499 if (mapalldata==0) {
500 fsesrecord = malloc(25+statsinfile*8);
501 } else if (goaltrashdata==0) {
502 fsesrecord = malloc(33+statsinfile*8);
503 } else {
504 fsesrecord = malloc(43+statsinfile*8);
505 }
506 passert(fsesrecord);
507
508 while (!feof(fd)) {
509 if (mapalldata==0) {
510 r = fread(fsesrecord,25+statsinfile*8,1,fd);
511 } else if (goaltrashdata==0) {
512 r = fread(fsesrecord,33+statsinfile*8,1,fd);
513 } else {
514 r = fread(fsesrecord,43+statsinfile*8,1,fd);
515 }
516 if (r==1) {
517 ptr = fsesrecord;
518 asesdata = (session*)malloc(sizeof(session));
519 passert(asesdata);
520 asesdata->sessionid = get32bit(&ptr);
521 ileng = get32bit(&ptr);
522 asesdata->peerip = get32bit(&ptr);
523 asesdata->rootinode = get32bit(&ptr);
524 asesdata->sesflags = get8bit(&ptr);
525 if (goaltrashdata) {
526 asesdata->mingoal = get8bit(&ptr);
527 asesdata->maxgoal = get8bit(&ptr);
528 asesdata->mintrashtime = get32bit(&ptr);
529 asesdata->maxtrashtime = get32bit(&ptr);
530 } else { // set defaults (no limits)
531 asesdata->mingoal = 1;
532 asesdata->maxgoal = 9;
533 asesdata->mintrashtime = 0;
534 asesdata->maxtrashtime = UINT32_C(0xFFFFFFFF);
535 }
536 asesdata->rootuid = get32bit(&ptr);
537 asesdata->rootgid = get32bit(&ptr);
538 if (mapalldata) {
539 asesdata->mapalluid = get32bit(&ptr);
540 asesdata->mapallgid = get32bit(&ptr);
541 } else {
542 asesdata->mapalluid = 0;
543 asesdata->mapallgid = 0;
544 }
545 asesdata->info = NULL;
546 asesdata->newsession = 1;
547 asesdata->openedfiles = NULL;
548 asesdata->disconnected = main_time();
549 asesdata->nsocks = 0;
550 for (i=0 ; i<SESSION_STATS ; i++) {
551 asesdata->currentopstats[i] = (i<statsinfile)?get32bit(&ptr):0;
552 }
553 if (statsinfile>SESSION_STATS) {
554 ptr+=4*(statsinfile-SESSION_STATS);
555 }
556 for (i=0 ; i<SESSION_STATS ; i++) {
557 asesdata->lasthouropstats[i] = (i<statsinfile)?get32bit(&ptr):0;
558 }
559 if (ileng>0) {
560 asesdata->info = malloc(ileng+1);
561 passert(asesdata->info);
562 if (fread(asesdata->info,ileng,1,fd)!=1) {
563 free(asesdata->info);
564 free(asesdata);
565 free(fsesrecord);
566 syslog(LOG_WARNING,"can't load sessions, fread error");
567 fclose(fd);
568 return -1;
569 }
570 asesdata->info[ileng]=0;
571 }
572 asesdata->next = sessionshead;
573 sessionshead = asesdata;
574 }
575 if (ferror(fd)) {
576 free(fsesrecord);
577 syslog(LOG_WARNING,"can't load sessions, fread error");
578 fclose(fd);
579 return -1;
580 }
581 }
582 free(fsesrecord);
583 syslog(LOG_NOTICE,"sessions have been loaded");
584 fclose(fd);
585 return 1;
586 }
587 */
588 /* old registration procedure */
589 /*
590 session* matoclserv_get_session(uint32_t sessionid) {
591 // if sessionid==0 - create new record with next id
592 session *asesdata;
593
594 if (sessionid>0) {
595 for (asesdata = sessionshead ; asesdata ; asesdata=asesdata->next) {
596 if (asesdata->sessionid==sessionid) {
597 asesdata->nsocks++;
598 asesdata->disconnected = 0;
599 return asesdata;
600 }
601 }
602 }
603 asesdata = (session*)malloc(sizeof(session));
604 passert(asesdata);
605 if (sessionid==0) {
606 asesdata->sessionid = fs_newsessionid();
607 } else {
608 asesdata->sessionid = sessionid;
609 }
610 asesdata->openedfiles = NULL;
611 asesdata->disconnected = 0;
612 asesdata->nsocks = 1;
613 memset(asesdata->currentopstats,0,4*SESSION_STATS);
614 memset(asesdata->lasthouropstats,0,4*SESSION_STATS);
615 asesdata->next = sessionshead;
616 sessionshead = asesdata;
617 return asesdata;
618 }
619 */
620
621 #if 0
622 int matoclserv_insert_openfile(session* cr,uint32_t inode) {
623 filelist *ofptr,**ofpptr;
624 int status;
625
626 ofpptr = &(cr->openedfiles);
627 while ((ofptr=*ofpptr)) {
628 if (ofptr->inode==inode) {
629 return STATUS_OK; // file already acquired - nothing to do
630 }
631 if (ofptr->inode>inode) {
632 break;
633 }
634 ofpptr = &(ofptr->next);
635 }
636 status = fs_acquire(inode,cr->sessionid);
637 if (status==STATUS_OK) {
638 ofptr = (filelist*)malloc(sizeof(filelist));
639 passert(ofptr);
640 ofptr->inode = inode;
641 ofptr->next = *ofpptr;
642 *ofpptr = ofptr;
643 }
644 return status;
645 }
646
647 void matoclserv_init_sessions(uint32_t sessionid,uint32_t inode) {
648 session *asesdata;
649 filelist *ofptr,**ofpptr;
650
651 for (asesdata = sessionshead ; asesdata && asesdata->sessionid!=sessionid; asesdata=asesdata->next) ;
652 if (asesdata==NULL) {
653 asesdata = (session*)malloc(sizeof(session));
654 passert(asesdata);
655 asesdata->sessionid = sessionid;
656 /* session created by filesystem - only for old clients (pre 1.5.13) */
657 asesdata->info = NULL;
658 asesdata->peerip = 0;
659 asesdata->sesflags = 0;
660 asesdata->mingoal = 1;
661 asesdata->maxgoal = 9;
662 asesdata->mintrashtime = 0;
663 asesdata->maxtrashtime = UINT32_C(0xFFFFFFFF);
664 asesdata->rootuid = 0;
665 asesdata->rootgid = 0;
666 asesdata->mapalluid = 0;
667 asesdata->mapallgid = 0;
668 asesdata->newsession = 0;
669 asesdata->rootinode = MFS_ROOT_ID;
670 asesdata->openedfiles = NULL;
671 asesdata->disconnected = main_time();
672 asesdata->nsocks = 0;
673 memset(asesdata->currentopstats,0,4*SESSION_STATS);
674 memset(asesdata->lasthouropstats,0,4*SESSION_STATS);
675 asesdata->next = sessionshead;
676 sessionshead = asesdata;
677 }
678
679 ofpptr = &(asesdata->openedfiles);
680 while ((ofptr=*ofpptr)) {
681 if (ofptr->inode==inode) {
682 return;
683 }
684 if (ofptr->inode>inode) {
685 break;
686 }
687 ofpptr = &(ofptr->next);
688 }
689 ofptr = (filelist*)malloc(sizeof(filelist));
690 passert(ofptr);
691 ofptr->inode = inode;
692 ofptr->next = *ofpptr;
693 *ofpptr = ofptr;
694 }
695 #endif
696
matoclserv_createpacket(matoclserventry * eptr,uint32_t type,uint32_t size)697 uint8_t* matoclserv_createpacket(matoclserventry *eptr,uint32_t type,uint32_t size) {
698 out_packetstruct *outpacket;
699 uint8_t *ptr;
700 uint32_t psize;
701
702 psize = size+8;
703 outpacket=malloc(offsetof(out_packetstruct,data)+psize);
704 passert(outpacket);
705 outpacket->bytesleft = psize;
706 ptr = outpacket->data;
707 put32bit(&ptr,type);
708 put32bit(&ptr,size);
709 outpacket->startptr = outpacket->data;
710 outpacket->next = NULL;
711 *(eptr->outputtail) = outpacket;
712 eptr->outputtail = &(outpacket->next);
713 return ptr;
714 }
715
716 /*
717 int matoclserv_open_check(matoclserventry *eptr,uint32_t fid) {
718 filelist *fl;
719 for (fl=eptr->openedfiles ; fl ; fl=fl->next) {
720 if (fl->fid==fid) {
721 return 0;
722 }
723 }
724 return -1;
725 }
726 */
727
matoclserv_chunk_status(uint64_t chunkid,uint8_t status)728 void matoclserv_chunk_status(uint64_t chunkid,uint8_t status) {
729 uint32_t qid,inode,uid,gid,auid,agid;
730 uint64_t fleng;
731 uint8_t type,attr[35];
732 uint32_t version;
733 // uint8_t rstat;
734 // uint32_t ip;
735 // uint16_t port;
736 uint8_t *ptr;
737 uint8_t count;
738 uint8_t cs_data[100*10];
739 chunklist *cl,**acl;
740 matoclserventry *eptr,*eaptr;
741
742 eptr=NULL;
743 qid=0;
744 fleng=0;
745 type=0;
746 inode=0;
747 uid=0;
748 gid=0;
749 auid=0;
750 agid=0;
751 for (eaptr = matoclservhead ; eaptr && eptr==NULL ; eaptr=eaptr->next) {
752 if (eaptr->mode!=KILL) {
753 acl = &(eaptr->chunkdelayedops);
754 while (*acl && eptr==NULL) {
755 cl = *acl;
756 if (cl->chunkid==chunkid) {
757 eptr = eaptr;
758 qid = cl->qid;
759 fleng = cl->fleng;
760 type = cl->type;
761 inode = cl->inode;
762 uid = cl->uid;
763 gid = cl->gid;
764 auid = cl->auid;
765 agid = cl->agid;
766
767 *acl = cl->next;
768 free(cl);
769 } else {
770 acl = &(cl->next);
771 }
772 }
773 }
774 }
775
776 if (!eptr) {
777 syslog(LOG_WARNING,"got chunk status, but don't want it");
778 return;
779 }
780 if (status==STATUS_OK) {
781 dcm_modify(inode,sessions_get_id(eptr->sesdata));
782 }
783 switch (type) {
784 case FUSE_WRITE:
785 if (status==STATUS_OK) {
786 if (eptr->version>=VERSION2INT(1,7,32)) {
787 status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
788 } else {
789 status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
790 }
791 //syslog(LOG_NOTICE,"get version for chunk %"PRIu64" -> %"PRIu32,chunkid,version);
792 }
793 if (status!=STATUS_OK) {
794 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
795 put32bit(&ptr,qid);
796 put8bit(&ptr,status);
797 fs_writeend(0,0,chunkid); // ignore status - just do it.
798 return;
799 }
800 if (eptr->version>=VERSION2INT(1,7,32)) {
801 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*10);
802 } else {
803 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,24+count*6);
804 }
805 put32bit(&ptr,qid);
806 if (eptr->version>=VERSION2INT(1,7,32)) {
807 put8bit(&ptr,1);
808 }
809 put64bit(&ptr,fleng);
810 put64bit(&ptr,chunkid);
811 put32bit(&ptr,version);
812 if (count>0) {
813 if (eptr->version>=VERSION2INT(1,7,32)) {
814 memcpy(ptr,cs_data,count*10);
815 } else {
816 memcpy(ptr,cs_data,count*6);
817 }
818 }
819 // for (i=0 ; i<count ; i++) {
820 // if (matocsserv_getlocation(sptr[i],&ip,&port)<0) {
821 // put32bit(&ptr,0);
822 // put16bit(&ptr,0);
823 // } else {
824 // put32bit(&ptr,ip);
825 // put16bit(&ptr,port);
826 // }
827 // }
828 return;
829 case FUSE_TRUNCATE:
830 fs_end_setlength(chunkid);
831
832 if (status!=STATUS_OK) {
833 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,5);
834 put32bit(&ptr,qid);
835 put8bit(&ptr,status);
836 return;
837 }
838 fs_do_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,0,uid,gid,auid,agid,fleng,attr);
839 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,39);
840 put32bit(&ptr,qid);
841 memcpy(ptr,attr,35);
842 return;
843 default:
844 syslog(LOG_WARNING,"got chunk status, but operation type is unknown");
845 }
846 }
847
matoclserv_cserv_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)848 void matoclserv_cserv_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
849 uint8_t *ptr;
850 (void)data;
851 if (length!=0) {
852 syslog(LOG_NOTICE,"CLTOMA_CSERV_LIST - wrong size (%"PRIu32"/0)",length);
853 eptr->mode = KILL;
854 return;
855 }
856 ptr = matoclserv_createpacket(eptr,MATOCL_CSERV_LIST,csdb_servlist_size());
857 csdb_servlist_data(ptr);
858 }
859
matoclserv_cserv_command(matoclserventry * eptr,const uint8_t * data,uint32_t length)860 void matoclserv_cserv_command(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
861 uint32_t ip;
862 uint16_t port;
863 uint8_t cmd,status;
864 uint8_t *ptr;
865 if (length!=6 && length!=7) {
866 syslog(LOG_NOTICE,"CLTOMA_CSSERV_COMMAND - wrong size (%"PRIu32"/6|7)",length);
867 eptr->mode = KILL;
868 return;
869 }
870 if (length==7) {
871 cmd = get8bit(&data);
872 } else {
873 cmd = MFS_CSSERV_COMMAND_REMOVE;
874 }
875 ip = get32bit(&data);
876 port = get16bit(&data);
877 if (cmd==MFS_CSSERV_COMMAND_REMOVE) {
878 status = csdb_remove_server(ip,port);
879 } else if (cmd==MFS_CSSERV_COMMAND_BACKTOWORK) {
880 status = csdb_back_to_work(ip,port);
881 } else if (cmd==MFS_CSSERV_COMMAND_MAINTENANCEON) {
882 status = csdb_maintenance(ip,port,1);
883 } else if (cmd==MFS_CSSERV_COMMAND_MAINTENANCEOFF) {
884 status = csdb_maintenance(ip,port,0);
885 } else {
886 status = ERROR_EINVAL;
887 }
888 if (length==6) {
889 matoclserv_createpacket(eptr,MATOCL_CSSERV_COMMAND,0);
890 } else {
891 ptr = matoclserv_createpacket(eptr,MATOCL_CSSERV_COMMAND,1);
892 put8bit(&ptr,status);
893 }
894 }
895
matoclserv_session_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)896 void matoclserv_session_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
897 uint8_t *ptr;
898 // matoclserventry *eaptr;
899 uint32_t size; //,sessionid;
900 // uint16_t statscnt;
901 uint8_t vmode;
902 (void)data;
903 if (length!=0 && length!=1) {
904 syslog(LOG_NOTICE,"CLTOMA_SESSION_LIST - wrong size (%"PRIu32"/0)",length);
905 eptr->mode = KILL;
906 return;
907 }
908 if (length==0) {
909 vmode = 0;
910 } else {
911 vmode = get8bit(&data);
912 }
913 size = sessions_datasize(vmode);
914 /*
915 size = 2;
916 for (eaptr = matoclservhead ; eaptr ; eaptr=eaptr->next) {
917 if (eaptr->mode!=KILL && eaptr->sesdata && eaptr->registered>0 && eaptr->registered<100) {
918 size += 12+sessions_datasize(eaptr->sesdata,vmode);
919 }
920 }
921 */
922 ptr = matoclserv_createpacket(eptr,MATOCL_SESSION_LIST,size);
923 sessions_datafill(ptr,vmode);
924 /*
925 statscnt = sessions_get_statscnt();
926 put16bit(&ptr,statscnt);
927 for (eaptr = matoclservhead ; eaptr ; eaptr=eaptr->next) {
928 if (eaptr->mode!=KILL && eaptr->sesdata && eaptr->registered>0 && eaptr->registered<100) {
929 sessionid = sessions_get_id(eaptr->sesdata);
930 // tcpgetpeer(eaptr->sock,&ip,NULL);
931 put32bit(&ptr,sessionid);
932 put32bit(&ptr,eaptr->peerip);
933 put32bit(&ptr,eaptr->version);
934 size = sessions_datafill(ptr,eaptr->sesdata,vmode);
935 ptr += size;
936 }
937 }
938 */
939 }
940
matoclserv_session_command(matoclserventry * eptr,const uint8_t * data,uint32_t length)941 void matoclserv_session_command(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
942 uint32_t sessionid;
943 uint8_t cmd,status;
944 uint8_t *ptr;
945 if (length!=5) {
946 syslog(LOG_NOTICE,"CLTOMA_SESSION_COMMAND - wrong size (%"PRIu32"/5)",length);
947 eptr->mode = KILL;
948 return;
949 }
950 cmd = get8bit(&data);
951 sessionid = get32bit(&data);
952 if (cmd==MFS_SESSION_COMMAND_REMOVE) {
953 status = sessions_force_remove(sessionid);
954 } else {
955 status = ERROR_EINVAL;
956 }
957 ptr = matoclserv_createpacket(eptr,MATOCL_SESSION_COMMAND,1);
958 put8bit(&ptr,status);
959 }
960
matoclserv_chart(matoclserventry * eptr,const uint8_t * data,uint32_t length)961 void matoclserv_chart(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
962 uint32_t chartid;
963 uint8_t *ptr;
964 uint32_t l;
965 uint16_t w,h;
966
967 if (length!=4 && length!=8) {
968 syslog(LOG_NOTICE,"CLTOAN_CHART - wrong size (%"PRIu32"/4|8)",length);
969 eptr->mode = KILL;
970 return;
971 }
972 chartid = get32bit(&data);
973 if (length==8) {
974 w = get16bit(&data);
975 h = get16bit(&data);
976 } else {
977 w = 0;
978 h = 0;
979 }
980 l = charts_make_png(chartid,w,h);
981 ptr = matoclserv_createpacket(eptr,ANTOCL_CHART,l);
982 if (l>0) {
983 charts_get_png(ptr);
984 }
985 }
986
matoclserv_chart_data(matoclserventry * eptr,const uint8_t * data,uint32_t length)987 void matoclserv_chart_data(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
988 uint32_t chartid;
989 uint32_t maxentries;
990 uint8_t *ptr;
991 uint32_t l;
992
993 if (length!=4 && length!=8) {
994 syslog(LOG_NOTICE,"CLTOAN_CHART_DATA - wrong size (%"PRIu32"/4|8)",length);
995 eptr->mode = KILL;
996 return;
997 }
998 chartid = get32bit(&data);
999 if (length==8) {
1000 maxentries = get32bit(&data);
1001 } else {
1002 maxentries = UINT32_C(0xFFFFFFFF);
1003 }
1004 l = charts_datasize(chartid,maxentries);
1005 ptr = matoclserv_createpacket(eptr,ANTOCL_CHART_DATA,l);
1006 if (l>0) {
1007 charts_makedata(ptr,chartid,maxentries);
1008 }
1009 }
1010
matoclserv_get_version(matoclserventry * eptr,const uint8_t * data,uint32_t length)1011 void matoclserv_get_version(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1012 uint32_t msgid = 0;
1013 uint8_t *ptr;
1014 static const char vstring[] = VERSSTR;
1015 if (length!=0 && length!=4) {
1016 syslog(LOG_NOTICE,"ANTOAN_GET_VERSION - wrong size (%"PRIu32"/4|0)",length);
1017 eptr->mode = KILL;
1018 return;
1019 }
1020 if (length==4) {
1021 msgid = get32bit(&data);
1022 ptr = matoclserv_createpacket(eptr,ANTOAN_VERSION,4+4+strlen(vstring));
1023 put32bit(&ptr,msgid);
1024 } else {
1025 ptr = matoclserv_createpacket(eptr,ANTOAN_VERSION,4+strlen(vstring));
1026 }
1027 put16bit(&ptr,VERSMAJ);
1028 put8bit(&ptr,VERSMID);
1029 put8bit(&ptr,VERSMIN);
1030 memcpy(ptr,vstring,strlen(vstring));
1031 }
1032
matoclserv_module_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1033 void matoclserv_module_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1034 uint32_t msgid = 0;
1035 uint8_t *ptr;
1036
1037 if (length!=0 && length!=4) {
1038 syslog(LOG_NOTICE,"ANTOAN_GET_VERSION - wrong size (%"PRIu32"/4|0)",length);
1039 eptr->mode = KILL;
1040 return;
1041 }
1042 if (length==4) {
1043 msgid = get32bit(&data);
1044 ptr = matoclserv_createpacket(eptr,ANTOCL_MODULE_INFO,25);
1045 put32bit(&ptr,msgid);
1046 } else {
1047 ptr = matoclserv_createpacket(eptr,ANTOCL_MODULE_INFO,21);
1048 }
1049 put8bit(&ptr,MODULE_TYPE_MASTER);
1050 put16bit(&ptr,VERSMAJ);
1051 put8bit(&ptr,VERSMID);
1052 put8bit(&ptr,VERSMIN);
1053 put16bit(&ptr,0);
1054 put64bit(&ptr,meta_get_fileid());
1055 put32bit(&ptr,0);
1056 put16bit(&ptr,0);
1057 }
1058
matoclserv_mass_resolve_paths(matoclserventry * eptr,const uint8_t * data,uint32_t length)1059 void matoclserv_mass_resolve_paths(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1060 static uint32_t *inodetab = NULL;
1061 static uint32_t *psizetab = NULL;
1062 static uint32_t tabsleng = 0;
1063 uint32_t i,j;
1064 uint32_t totalsize;
1065 uint32_t psize;
1066 uint8_t *ptr;
1067 uint8_t status;
1068 if ((length%4)!=0) {
1069 syslog(LOG_NOTICE,"CLTOMA_MASS_RESOLVE_PATHS - wrong size (%"PRIu32"/N*4)",length);
1070 eptr->mode = KILL;
1071 return;
1072 }
1073 length>>=2;
1074 if (length>tabsleng) {
1075 if (inodetab) {
1076 free(inodetab);
1077 }
1078 if (psizetab) {
1079 free(psizetab);
1080 }
1081 tabsleng = ((length+0xFF)&0xFFFFFF00);
1082 inodetab = malloc(sizeof(uint32_t)*tabsleng);
1083 passert(inodetab);
1084 psizetab = malloc(sizeof(uint32_t)*tabsleng);
1085 passert(psizetab);
1086 }
1087 j = 0;
1088 totalsize = 0;
1089 while (length>0) {
1090 i = get32bit(&data);
1091 if (i>0) {
1092 status = fs_get_paths_size(MFS_ROOT_ID,i,&psize);
1093 if (status==STATUS_OK) {
1094 inodetab[j] = i;
1095 psizetab[j] = psize;
1096 j++;
1097 totalsize += 8 + psize;
1098 }
1099 }
1100 length--;
1101 }
1102 ptr = matoclserv_createpacket(eptr,MATOCL_MASS_RESOLVE_PATHS,totalsize);
1103 for (i=0 ; i<j ; i++) {
1104 put32bit(&ptr,inodetab[i]);
1105 put32bit(&ptr,psizetab[i]);
1106 fs_get_paths_data(MFS_ROOT_ID,inodetab[i],ptr);
1107 ptr+=psizetab[i];
1108 }
1109 }
1110
matoclserv_missing_chunks(matoclserventry * eptr,const uint8_t * data,uint32_t length)1111 void matoclserv_missing_chunks(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1112 uint8_t *ptr;
1113 uint8_t mode;
1114 if (length!=0 && length!=1) {
1115 syslog(LOG_NOTICE,"CLTOMA_MISSING_CHUNKS - wrong size (%"PRIu32"/0|1)",length);
1116 eptr->mode = KILL;
1117 return;
1118 }
1119 if (length==1) {
1120 mode = get8bit(&data);
1121 } else {
1122 mode = 0;
1123 }
1124 ptr = matoclserv_createpacket(eptr,MATOCL_MISSING_CHUNKS,missing_log_getdata(NULL,mode));
1125 missing_log_getdata(ptr,mode);
1126 }
1127
matoclserv_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1128 void matoclserv_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1129 uint64_t totalspace,availspace,trspace,respace;
1130 uint64_t memusage,syscpu,usercpu;
1131 uint32_t trnodes,renodes,inodes,dnodes,fnodes;
1132 uint32_t chunks,chunkcopies,tdcopies;
1133 uint32_t lsstore,lstime;
1134 uint8_t lsstat;
1135 uint8_t *ptr;
1136 (void)data;
1137 if (length!=0) {
1138 syslog(LOG_NOTICE,"CLTOMA_INFO - wrong size (%"PRIu32"/0)",length);
1139 eptr->mode = KILL;
1140 return;
1141 }
1142 meta_info(&lsstore,&lstime,&lsstat);
1143 fs_info(&totalspace,&availspace,&trspace,&trnodes,&respace,&renodes,&inodes,&dnodes,&fnodes);
1144 chunk_info(&chunks,&chunkcopies,&tdcopies);
1145 chartsdata_resusage(&memusage,&syscpu,&usercpu);
1146 ptr = matoclserv_createpacket(eptr,MATOCL_INFO,121);
1147 /* put32bit(&buff,VERSION): */
1148 put16bit(&ptr,VERSMAJ);
1149 put8bit(&ptr,VERSMID);
1150 put8bit(&ptr,VERSMIN);
1151 put64bit(&ptr,memusage);
1152 put64bit(&ptr,syscpu);
1153 put64bit(&ptr,usercpu);
1154 put64bit(&ptr,totalspace);
1155 put64bit(&ptr,availspace);
1156 put64bit(&ptr,trspace);
1157 put32bit(&ptr,trnodes);
1158 put64bit(&ptr,respace);
1159 put32bit(&ptr,renodes);
1160 put32bit(&ptr,inodes);
1161 put32bit(&ptr,dnodes);
1162 put32bit(&ptr,fnodes);
1163 put32bit(&ptr,chunks);
1164 put32bit(&ptr,chunkcopies);
1165 put32bit(&ptr,tdcopies);
1166 put32bit(&ptr,lsstore);
1167 put32bit(&ptr,lstime);
1168 put8bit(&ptr,lsstat);
1169 put8bit(&ptr,0xFF);
1170 put8bit(&ptr,0xFF);
1171 put8bit(&ptr,0xFF);
1172 put8bit(&ptr,0xFF);
1173 put32bit(&ptr,0);
1174 put32bit(&ptr,0);
1175 put64bit(&ptr,meta_version());
1176 }
1177
matoclserv_memory_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1178 void matoclserv_memory_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1179 uint8_t *ptr;
1180 uint64_t allocated[8];
1181 uint64_t used[8];
1182 (void)data;
1183 if (length!=0) {
1184 syslog(LOG_NOTICE,"CLTOMA_MEMORY_INFO - wrong size (%"PRIu32"/0)",length);
1185 eptr->mode = KILL;
1186 return;
1187 }
1188 ptr = matoclserv_createpacket(eptr,MATOCL_MEMORY_INFO,176);
1189 chunk_get_memusage(allocated,used);
1190 put64bit(&ptr,allocated[0]);
1191 put64bit(&ptr,used[0]);
1192 put64bit(&ptr,allocated[1]);
1193 put64bit(&ptr,used[1]);
1194 put64bit(&ptr,allocated[2]);
1195 put64bit(&ptr,used[2]);
1196 fs_get_memusage(allocated,used);
1197 put64bit(&ptr,allocated[0]);
1198 put64bit(&ptr,used[0]);
1199 put64bit(&ptr,allocated[1]);
1200 put64bit(&ptr,used[1]);
1201 put64bit(&ptr,allocated[2]);
1202 put64bit(&ptr,used[2]);
1203 put64bit(&ptr,allocated[3]);
1204 put64bit(&ptr,used[3]);
1205 put64bit(&ptr,allocated[4]);
1206 put64bit(&ptr,used[4]);
1207 put64bit(&ptr,allocated[5]);
1208 put64bit(&ptr,used[5]);
1209 put64bit(&ptr,allocated[6]);
1210 put64bit(&ptr,used[6]);
1211 put64bit(&ptr,allocated[7]);
1212 put64bit(&ptr,used[7]);
1213 }
1214
matoclserv_fstest_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1215 void matoclserv_fstest_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1216 uint32_t loopstart,loopend,files,ugfiles,mfiles,mtfiles,msfiles,chunks,ugchunks,mchunks,msgbuffleng;
1217 char *msgbuff;
1218 uint8_t *ptr;
1219 (void)data;
1220 if (length!=0 && length!=1) {
1221 syslog(LOG_NOTICE,"CLTOMA_FSTEST_INFO - wrong size (%"PRIu32"/0|1)",length);
1222 eptr->mode = KILL;
1223 return;
1224 }
1225 fs_test_getdata(&loopstart,&loopend,&files,&ugfiles,&mfiles,&mtfiles,&msfiles,&chunks,&ugchunks,&mchunks,&msgbuff,&msgbuffleng);
1226 ptr = matoclserv_createpacket(eptr,MATOCL_FSTEST_INFO,msgbuffleng+((length==1)?44:36));
1227 put32bit(&ptr,loopstart);
1228 put32bit(&ptr,loopend);
1229 put32bit(&ptr,files);
1230 put32bit(&ptr,ugfiles);
1231 put32bit(&ptr,mfiles);
1232 if (length==1) {
1233 put32bit(&ptr,mtfiles);
1234 put32bit(&ptr,msfiles);
1235 }
1236 put32bit(&ptr,chunks);
1237 put32bit(&ptr,ugchunks);
1238 put32bit(&ptr,mchunks);
1239 put32bit(&ptr,msgbuffleng);
1240 if (msgbuffleng>0) {
1241 memcpy(ptr,msgbuff,msgbuffleng);
1242 }
1243 }
1244
matoclserv_chunkstest_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1245 void matoclserv_chunkstest_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1246 uint8_t *ptr;
1247 (void)data;
1248 if (length!=0) {
1249 syslog(LOG_NOTICE,"CLTOMA_CHUNKSTEST_INFO - wrong size (%"PRIu32"/0)",length);
1250 eptr->mode = KILL;
1251 return;
1252 }
1253 ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKSTEST_INFO,60);
1254 chunk_store_info(ptr);
1255 }
1256
matoclserv_chunks_matrix(matoclserventry * eptr,const uint8_t * data,uint32_t length)1257 void matoclserv_chunks_matrix(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1258 uint8_t *ptr;
1259 (void)data;
1260 if (length>1) {
1261 syslog(LOG_NOTICE,"CLTOMA_CHUNKS_MATRIX - wrong size (%"PRIu32"/0|1)",length);
1262 eptr->mode = KILL;
1263 return;
1264 }
1265 if (length==1) {
1266 uint8_t matrixid;
1267 matrixid = get8bit(&data);
1268 ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKS_MATRIX,484);
1269 chunk_store_chunkcounters(ptr,matrixid);
1270 } else {
1271 uint8_t progressstatus;
1272 ptr = matoclserv_createpacket(eptr,MATOCL_CHUNKS_MATRIX,969);
1273 progressstatus = chunk_counters_in_progress();
1274 // syslog(LOG_NOTICE,"progressstatus: %u",progressstatus);
1275 put8bit(&ptr,progressstatus);
1276 chunk_store_chunkcounters(ptr,0);
1277 chunk_store_chunkcounters(ptr+484,1);
1278 }
1279 }
1280
matoclserv_quota_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1281 void matoclserv_quota_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1282 uint8_t *ptr;
1283 (void)data;
1284 if (length!=0) {
1285 syslog(LOG_NOTICE,"CLTOMA_QUOTA_INFO - wrong size (%"PRIu32"/0)",length);
1286 eptr->mode = KILL;
1287 return;
1288 }
1289 ptr = matoclserv_createpacket(eptr,MATOCL_QUOTA_INFO,fs_getquotainfo_size());
1290 fs_getquotainfo_data(ptr);
1291 }
1292
matoclserv_exports_info(matoclserventry * eptr,const uint8_t * data,uint32_t length)1293 void matoclserv_exports_info(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1294 uint8_t *ptr;
1295 uint8_t vmode;
1296 if (length!=0 && length!=1) {
1297 syslog(LOG_NOTICE,"CLTOMA_EXPORTS_INFO - wrong size (%"PRIu32"/0|1)",length);
1298 eptr->mode = KILL;
1299 return;
1300 }
1301 if (length==0) {
1302 vmode = 0;
1303 } else {
1304 vmode = get8bit(&data);
1305 }
1306 ptr = matoclserv_createpacket(eptr,MATOCL_EXPORTS_INFO,exports_info_size(vmode));
1307 exports_info_data(vmode,ptr);
1308 }
1309
matoclserv_mlog_list(matoclserventry * eptr,const uint8_t * data,uint32_t length)1310 void matoclserv_mlog_list(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1311 uint8_t *ptr;
1312 (void)data;
1313 if (length!=0) {
1314 syslog(LOG_NOTICE,"CLTOMA_MLOG_LIST - wrong size (%"PRIu32"/0)",length);
1315 eptr->mode = KILL;
1316 return;
1317 }
1318 ptr = matoclserv_createpacket(eptr,MATOCL_MLOG_LIST,matomlserv_mloglist_size());
1319 matomlserv_mloglist_data(ptr);
1320 }
1321
1322
1323 /* CACHENOTIFY
1324 void matoclserv_notify_attr(uint32_t dirinode,uint32_t inode,const uint8_t attr[35]) {
1325 uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1326 dirincache *dc;
1327 uint8_t *ptr;
1328
1329 for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1330 if (dc->dirinode==dirinode) {
1331 // syslog(LOG_NOTICE,"send to: '%s' ; attrs of inode: %"PRIu32,dc->eptr->sesdata->info,inode);
1332 ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_ATTR,43);
1333 stats_notify++;
1334 put32bit(&ptr,0);
1335 put32bit(&ptr,inode);
1336 memcpy(ptr,attr,35);
1337 if (dc->eptr->sesdata) {
1338 dc->eptr->sesdata->currentopstats[16]++;
1339 }
1340 dc->eptr->notifications = 1;
1341 }
1342 }
1343 }
1344
1345 void matoclserv_notify_link(uint32_t dirinode,uint8_t nleng,const uint8_t *name,uint32_t inode,const uint8_t attr[35],uint32_t ts) {
1346 uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1347 dirincache *dc;
1348 uint8_t *ptr;
1349
1350 for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1351 if (dc->dirinode==dirinode) {
1352 // {
1353 // char strname[256];
1354 // memcpy(strname,name,nleng);
1355 // strname[nleng]=0;
1356 // syslog(LOG_NOTICE,"send to: '%s' ; new link (%"PRIu32",%s)->%"PRIu32,dc->eptr->sesdata->info,dirinode,strname,inode);
1357 // }
1358 ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_LINK,52+nleng);
1359 stats_notify++;
1360 put32bit(&ptr,0);
1361 put32bit(&ptr,ts);
1362 if (dirinode==dc->eptr->sesdata->rootinode) {
1363 put32bit(&ptr,MFS_ROOT_ID);
1364 } else {
1365 put32bit(&ptr,dirinode);
1366 }
1367 put8bit(&ptr,nleng);
1368 memcpy(ptr,name,nleng);
1369 ptr+=nleng;
1370 put32bit(&ptr,inode);
1371 memcpy(ptr,attr,35);
1372 if (dc->eptr->sesdata) {
1373 dc->eptr->sesdata->currentopstats[17]++;
1374 }
1375 dc->eptr->notifications = 1;
1376 }
1377 }
1378 }
1379
1380 void matoclserv_notify_unlink(uint32_t dirinode,uint8_t nleng,const uint8_t *name,uint32_t ts) {
1381 uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1382 dirincache *dc;
1383 uint8_t *ptr;
1384
1385 for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1386 if (dc->dirinode==dirinode) {
1387 // {
1388 // char strname[256];
1389 // memcpy(strname,name,nleng);
1390 // strname[nleng]=0;
1391 // syslog(LOG_NOTICE,"send to: '%s' ; remove link (%"PRIu32",%s)",dc->eptr->sesdata->info,dirinode,strname);
1392 // }
1393 ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_UNLINK,13+nleng);
1394 stats_notify++;
1395 put32bit(&ptr,0);
1396 put32bit(&ptr,ts);
1397 if (dirinode==dc->eptr->sesdata->rootinode) {
1398 put32bit(&ptr,MFS_ROOT_ID);
1399 } else {
1400 put32bit(&ptr,dirinode);
1401 }
1402 put8bit(&ptr,nleng);
1403 memcpy(ptr,name,nleng);
1404 if (dc->eptr->sesdata) {
1405 dc->eptr->sesdata->currentopstats[18]++;
1406 }
1407 dc->eptr->notifications = 1;
1408 }
1409 }
1410 }
1411
1412 void matoclserv_notify_remove(uint32_t dirinode) {
1413 uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1414 dirincache *dc;
1415 uint8_t *ptr;
1416
1417 for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1418 if (dc->dirinode==dirinode) {
1419 // syslog(LOG_NOTICE,"send to: '%s' ; removed inode: %"PRIu32,dc->eptr->sesdata->info,dirinode);
1420 ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_REMOVE,8);
1421 stats_notify++;
1422 put32bit(&ptr,0);
1423 if (dirinode==dc->eptr->sesdata->rootinode) {
1424 put32bit(&ptr,MFS_ROOT_ID);
1425 } else {
1426 put32bit(&ptr,dirinode);
1427 }
1428 if (dc->eptr->sesdata) {
1429 dc->eptr->sesdata->currentopstats[19]++;
1430 }
1431 dc->eptr->notifications = 1;
1432 }
1433 }
1434 }
1435
1436 void matoclserv_notify_parent(uint32_t dirinode,uint32_t parent) {
1437 uint32_t hash = (dirinode*0x5F2318BD)%DIRINODE_HASH_SIZE;
1438 dirincache *dc;
1439 uint8_t *ptr;
1440
1441 for (dc=dirinodehash[hash] ; dc ; dc=dc->nextnode) {
1442 if (dc->dirinode==dirinode && dirinode!=dc->eptr->sesdata->rootinode) {
1443 // syslog(LOG_NOTICE,"send to: '%s' ; new parent: %"PRIu32"->%"PRIu32,dc->eptr->sesdata->info,dirinode,parent);
1444 ptr = matoclserv_createpacket(dc->eptr,MATOCL_FUSE_NOTIFY_PARENT,12);
1445 stats_notify++;
1446 put32bit(&ptr,0);
1447 put32bit(&ptr,dirinode);
1448 if (parent==dc->eptr->sesdata->rootinode) {
1449 put32bit(&ptr,MFS_ROOT_ID);
1450 } else {
1451 put32bit(&ptr,parent);
1452 }
1453 if (dc->eptr->sesdata) {
1454 dc->eptr->sesdata->currentopstats[20]++;
1455 }
1456 dc->eptr->notifications = 1;
1457 }
1458 }
1459 }
1460 */
1461
matoclserv_fuse_register(matoclserventry * eptr,const uint8_t * data,uint32_t length)1462 void matoclserv_fuse_register(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1463 const uint8_t *rptr;
1464 uint8_t *wptr;
1465 uint32_t sessionid;
1466 uint8_t status;
1467
1468 if (length<64) {
1469 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER - wrong size (%"PRIu32"/<64)",length);
1470 eptr->mode = KILL;
1471 return;
1472 }
1473 if (memcmp(data,FUSE_REGISTER_BLOB_ACL,64)==0) {
1474 uint32_t rootinode;
1475 uint8_t sesflags;
1476 uint8_t mingoal,maxgoal;
1477 uint32_t mintrashtime,maxtrashtime;
1478 uint32_t rootuid,rootgid;
1479 uint32_t mapalluid,mapallgid;
1480 uint32_t ileng,pleng;
1481 uint8_t i,rcode;
1482 const uint8_t *path;
1483 const char *info;
1484
1485 if (length<65) {
1486 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong size (%"PRIu32"/<65)",length);
1487 eptr->mode = KILL;
1488 return;
1489 }
1490
1491 rptr = data+64;
1492 rcode = get8bit(&rptr);
1493
1494 if ((eptr->registered==0 && rcode==REGISTER_CLOSESESSION) || (eptr->registered && rcode!=REGISTER_CLOSESESSION)) {
1495 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong rcode (%d) for registered status (%d)",rcode,eptr->registered);
1496 eptr->mode = KILL;
1497 return;
1498 }
1499
1500 // printf("rcode: %d\n",rcode);
1501 //
1502 switch (rcode) {
1503 case REGISTER_GETRANDOM:
1504 if (length!=65) {
1505 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.1 - wrong size (%"PRIu32"/65)",length);
1506 eptr->mode = KILL;
1507 return;
1508 }
1509 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,32);
1510 for (i=0 ; i<32 ; i++) {
1511 eptr->passwordrnd[i]=rndu8();
1512 }
1513 memcpy(wptr,eptr->passwordrnd,32);
1514 return;
1515 case REGISTER_NEWSESSION:
1516 if (length<77) {
1517 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/>=77)",length);
1518 eptr->mode = KILL;
1519 return;
1520 }
1521 if (starting) {
1522 eptr->mode = KILL;
1523 return;
1524 }
1525
1526 eptr->version = get32bit(&rptr);
1527 ileng = get32bit(&rptr);
1528 if (length<77+ileng) {
1529 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/>=77+ileng(%"PRIu32"))",length,ileng);
1530 eptr->mode = KILL;
1531 return;
1532 }
1533 info = (const char*)rptr;
1534 rptr+=ileng;
1535 pleng = get32bit(&rptr);
1536 if (length!=77+ileng+pleng && length!=77+16+ileng+pleng) {
1537 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - wrong size (%"PRIu32"/77+ileng(%"PRIu32")+pleng(%"PRIu32")[+16])",length,ileng,pleng);
1538 eptr->mode = KILL;
1539 return;
1540 }
1541 path = rptr;
1542 rptr+=pleng;
1543 if (pleng>0 && rptr[-1]!=0) {
1544 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.2 - received path without ending zero");
1545 eptr->mode = KILL;
1546 return;
1547 }
1548 if (pleng==0) {
1549 path = (const uint8_t*)"";
1550 }
1551 if (length==77+16+ileng+pleng) {
1552 status = exports_check(eptr->peerip,eptr->version,0,path,eptr->passwordrnd,rptr,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1553 } else {
1554 status = exports_check(eptr->peerip,eptr->version,0,path,NULL,NULL,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1555 }
1556 if (status==STATUS_OK) {
1557 status = fs_getrootinode(&rootinode,path);
1558 }
1559 if (status==STATUS_OK) {
1560 eptr->sesdata = sessions_new_session(rootinode,sesflags,rootuid,rootgid,mapalluid,mapallgid,mingoal,maxgoal,mintrashtime,maxtrashtime,eptr->peerip,info,ileng);
1561 if (eptr->sesdata==NULL) {
1562 syslog(LOG_NOTICE,"can't allocate session record");
1563 eptr->mode = KILL;
1564 return;
1565 }
1566 }
1567 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,(status==STATUS_OK)?((eptr->version>=VERSION2INT(1,6,26))?35:(eptr->version>=VERSION2INT(1,6,21))?25:(eptr->version>=VERSION2INT(1,6,1))?21:13):1);
1568 if (status!=STATUS_OK) {
1569 put8bit(&wptr,status);
1570 eptr->sesdata = NULL;
1571 return;
1572 }
1573 sessionid = sessions_get_id(eptr->sesdata);
1574 if (eptr->version==VERSION2INT(1,6,21)) {
1575 put32bit(&wptr,0);
1576 } else if (eptr->version>=VERSION2INT(1,6,22)) {
1577 put16bit(&wptr,VERSMAJ);
1578 put8bit(&wptr,VERSMID);
1579 put8bit(&wptr,VERSMIN);
1580 }
1581 put32bit(&wptr,sessionid);
1582 put8bit(&wptr,sesflags);
1583 put32bit(&wptr,rootuid);
1584 put32bit(&wptr,rootgid);
1585 if (eptr->version>=VERSION2INT(1,6,1)) {
1586 put32bit(&wptr,mapalluid);
1587 put32bit(&wptr,mapallgid);
1588 }
1589 if (eptr->version>=VERSION2INT(1,6,26)) {
1590 put8bit(&wptr,mingoal);
1591 put8bit(&wptr,maxgoal);
1592 put32bit(&wptr,mintrashtime);
1593 put32bit(&wptr,maxtrashtime);
1594 }
1595 sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1596 eptr->registered = 1;
1597 syslog(LOG_NOTICE,"created new sessionid:%"PRIu32,sessionid);
1598 return;
1599 case REGISTER_NEWMETASESSION:
1600 if (length<73) {
1601 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.5 - wrong size (%"PRIu32"/>=73)",length);
1602 eptr->mode = KILL;
1603 return;
1604 }
1605 if (starting) {
1606 eptr->mode = KILL;
1607 return;
1608 }
1609
1610 eptr->version = get32bit(&rptr);
1611 ileng = get32bit(&rptr);
1612 if (length!=73+ileng && length!=73+16+ileng) {
1613 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.5 - wrong size (%"PRIu32"/73+ileng(%"PRIu32")[+16])",length,ileng);
1614 eptr->mode = KILL;
1615 return;
1616 }
1617 info = (const char*)rptr;
1618 rptr+=ileng;
1619 if (length==73+16+ileng) {
1620 status = exports_check(eptr->peerip,eptr->version,1,NULL,eptr->passwordrnd,rptr,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1621 } else {
1622 status = exports_check(eptr->peerip,eptr->version,1,NULL,NULL,NULL,&sesflags,&rootuid,&rootgid,&mapalluid,&mapallgid,&mingoal,&maxgoal,&mintrashtime,&maxtrashtime);
1623 }
1624 if (status==STATUS_OK) {
1625 eptr->sesdata = sessions_new_session(0,sesflags,0,0,0,0,mingoal,maxgoal,mintrashtime,maxtrashtime,eptr->peerip,info,ileng);
1626 if (eptr->sesdata==NULL) {
1627 syslog(LOG_NOTICE,"can't allocate session record");
1628 eptr->mode = KILL;
1629 return;
1630 }
1631 }
1632 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,(status==STATUS_OK)?((eptr->version>=VERSION2INT(1,6,26))?19:(eptr->version>=VERSION2INT(1,6,21))?9:5):1);
1633 if (status!=STATUS_OK) {
1634 put8bit(&wptr,status);
1635 eptr->sesdata = NULL;
1636 return;
1637 }
1638 sessionid = sessions_get_id(eptr->sesdata);
1639 if (eptr->version>=VERSION2INT(1,6,21)) {
1640 put16bit(&wptr,VERSMAJ);
1641 put8bit(&wptr,VERSMID);
1642 put8bit(&wptr,VERSMIN);
1643 }
1644 put32bit(&wptr,sessionid);
1645 put8bit(&wptr,sesflags);
1646 if (eptr->version>=VERSION2INT(1,6,26)) {
1647 put8bit(&wptr,mingoal);
1648 put8bit(&wptr,maxgoal);
1649 put32bit(&wptr,mintrashtime);
1650 put32bit(&wptr,maxtrashtime);
1651 }
1652 sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1653 eptr->registered = 1;
1654 return;
1655 case REGISTER_RECONNECT:
1656 case REGISTER_TOOLS:
1657 if (length<73) {
1658 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.%"PRIu8" - wrong size (%"PRIu32"/73)",rcode,length);
1659 eptr->mode = KILL;
1660 return;
1661 }
1662
1663 sessionid = get32bit(&rptr);
1664 if (starting) {
1665 eptr->mode = KILL;
1666 return;
1667 }
1668
1669 eptr->version = get32bit(&rptr);
1670 eptr->sesdata = sessions_find_session(sessionid);
1671 if (eptr->sesdata==NULL || sessions_get_peerip(eptr->sesdata)==0) { // no such session or session created by entries in metadata
1672 status = ERROR_BADSESSIONID;
1673 } else {
1674 if ((sessions_get_sesflags(eptr->sesdata)&SESFLAG_DYNAMICIP)==0 && eptr->peerip!=sessions_get_peerip(eptr->sesdata)) {
1675 status = ERROR_EACCES;
1676 } else {
1677 status = STATUS_OK;
1678 }
1679 }
1680 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,1);
1681 put8bit(&wptr,status);
1682 if (status!=STATUS_OK) {
1683 eptr->sesdata = NULL;
1684 return;
1685 }
1686 sessions_attach_session(eptr->sesdata,eptr->peerip,eptr->version);
1687 eptr->registered = (rcode==3)?1:100;
1688 return;
1689 case REGISTER_CLOSESESSION:
1690 if (length<69) {
1691 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL.6 - wrong size (%"PRIu32"/69)",length);
1692 eptr->mode = KILL;
1693 return;
1694 }
1695 sessionid = get32bit(&rptr);
1696 sessions_close_session(sessionid);
1697 if (eptr->version>=VERSION2INT(1,7,29)) {
1698 wptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REGISTER,1);
1699 put8bit(&wptr,0);
1700 }
1701 eptr->mode = FINISH;
1702 return;
1703 }
1704 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER/ACL - wrong rcode (%"PRIu8")",rcode);
1705 eptr->mode = KILL;
1706 return;
1707 } else {
1708 syslog(LOG_NOTICE,"CLTOMA_FUSE_REGISTER - wrong register blob");
1709 eptr->mode = KILL;
1710 return;
1711 }
1712 }
1713
matoclserv_fuse_sustained_inodes(matoclserventry * eptr,const uint8_t * data,uint32_t length)1714 void matoclserv_fuse_sustained_inodes(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1715 const uint8_t *rptr;
1716 static uint32_t *inodetab = NULL;
1717 static uint32_t inodetabsize = 0;
1718 uint32_t i,j;
1719
1720 if ((length&0x3)!=0) {
1721 syslog(LOG_NOTICE,"CLTOMA_FUSE_SUSTAINED_INODES - wrong size (%"PRIu32"/N*4)",length);
1722 eptr->mode = KILL;
1723 return;
1724 }
1725
1726 if (eptr->sesdata==NULL) {
1727 syslog(LOG_NOTICE,"CLTOMA_FUSE_SUSTAINED_INODES - session doesn't exist");
1728 eptr->mode = KILL;
1729 return;
1730 }
1731 length>>=2;
1732 if (length>inodetabsize) {
1733 if (inodetab) {
1734 free(inodetab);
1735 }
1736 inodetabsize = ((length+0xFF)&0xFFFFFF00);
1737 inodetab = malloc(sizeof(uint32_t)*inodetabsize);
1738 passert(inodetab);
1739 }
1740 rptr = data;
1741 j = 0;
1742 while (length>0) {
1743 i = get32bit(&rptr);
1744 if (i>0) {
1745 inodetab[j] = i;
1746 j++;
1747 }
1748 length--;
1749 }
1750 of_sync(sessions_get_id(eptr->sesdata),inodetab,j);
1751 // sessions_sync_open_files(eptr->sesdata,data,length>>2);
1752 }
1753
matoclserv_gid_storage(uint32_t gids)1754 uint32_t* matoclserv_gid_storage(uint32_t gids) {
1755 static uint32_t *gid=NULL;
1756 static uint32_t gidleng=0;
1757 if (gids==0) {
1758 if (gid!=NULL) {
1759 free(gid);
1760 }
1761 gidleng=0;
1762 return NULL;
1763 } else {
1764 if (gidleng<gids) {
1765 gidleng = (gids+255)&UINT32_C(0xFFFFFF00);
1766 if (gid!=NULL) {
1767 free(gid);
1768 }
1769 gid = malloc(sizeof(uint32_t)*gidleng);
1770 passert(gid);
1771 }
1772 return gid;
1773 }
1774 }
1775
1776 /*
1777 static inline void matoclserv_ugid_remap(matoclserventry *eptr,uint32_t *auid,uint32_t *agid) {
1778 if (*auid==0) {
1779 *auid = eptr->sesdata->rootuid;
1780 if (agid) {
1781 *agid = eptr->sesdata->rootgid;
1782 }
1783 } else if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_MAPALL) {
1784 *auid = eptr->sesdata->mapalluid;
1785 if (agid) {
1786 *agid = eptr->sesdata->mapallgid;
1787 }
1788 }
1789 }
1790 */
1791 /*
1792 static inline void matoclserv_ugid_attr_remap(matoclserventry *eptr,uint8_t attr[35],uint32_t auid,uint32_t agid) {
1793 uint8_t *wptr;
1794 const uint8_t *rptr;
1795 uint32_t fuid,fgid;
1796 if (auid!=0 && (sessions_get_sesflags(eptr->sesdata)&SESFLAG_MAPALL)) {
1797 rptr = attr+3;
1798 fuid = get32bit(&rptr);
1799 fgid = get32bit(&rptr);
1800 fuid = (fuid==eptr->sesdata->mapalluid)?auid:0;
1801 fgid = (fgid==eptr->sesdata->mapallgid)?agid:0;
1802 wptr = attr+3;
1803 put32bit(&wptr,fuid);
1804 put32bit(&wptr,fgid);
1805 }
1806 }
1807 */
matoclserv_fuse_statfs(matoclserventry * eptr,const uint8_t * data,uint32_t length)1808 void matoclserv_fuse_statfs(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1809 uint64_t totalspace,availspace,trashspace,sustainedspace;
1810 uint32_t msgid,inodes;
1811 uint8_t *ptr;
1812 if (length!=4) {
1813 syslog(LOG_NOTICE,"CLTOMA_FUSE_STATFS - wrong size (%"PRIu32"/4)",length);
1814 eptr->mode = KILL;
1815 return;
1816 }
1817 msgid = get32bit(&data);
1818 fs_statfs(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&totalspace,&availspace,&trashspace,&sustainedspace,&inodes);
1819 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_STATFS,40);
1820 put32bit(&ptr,msgid);
1821 put64bit(&ptr,totalspace);
1822 put64bit(&ptr,availspace);
1823 put64bit(&ptr,trashspace);
1824 put64bit(&ptr,sustainedspace);
1825 put32bit(&ptr,inodes);
1826 sessions_inc_stats(eptr->sesdata,0);
1827 }
1828
matoclserv_fuse_access(matoclserventry * eptr,const uint8_t * data,uint32_t length)1829 void matoclserv_fuse_access(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1830 uint32_t *gid;
1831 uint32_t i;
1832 uint32_t inode,uid,gids;
1833 uint16_t modemask;
1834 uint32_t msgid;
1835 uint8_t *ptr;
1836 uint8_t status;
1837 if ((length&1)==1) {
1838 if (length!=17) {
1839 syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/17)",length);
1840 eptr->mode = KILL;
1841 return;
1842 }
1843 msgid = get32bit(&data);
1844 inode = get32bit(&data);
1845 uid = get32bit(&data);
1846 gid = matoclserv_gid_storage(1);
1847 gid[0] = get32bit(&data);
1848 gids = 1;
1849 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1850 modemask = get8bit(&data);
1851 } else {
1852 if (length<18) {
1853 syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/18+4*N)",length);
1854 eptr->mode = KILL;
1855 return;
1856 }
1857 msgid = get32bit(&data);
1858 inode = get32bit(&data);
1859 uid = get32bit(&data);
1860 gids = get32bit(&data);
1861 if (length!=18+gids*4) {
1862 syslog(LOG_NOTICE,"CLTOMA_FUSE_ACCESS - wrong size (%"PRIu32"/18+4*N)",length);
1863 eptr->mode = KILL;
1864 return;
1865 }
1866 gid = matoclserv_gid_storage(gids);
1867 for (i=0 ; i<gids ; i++) {
1868 gid[i] = get32bit(&data);
1869 }
1870 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1871 modemask = get16bit(&data);
1872 }
1873 status = fs_access(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,modemask);
1874 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_ACCESS,5);
1875 put32bit(&ptr,msgid);
1876 put8bit(&ptr,status);
1877 }
1878
matoclserv_fuse_lookup(matoclserventry * eptr,const uint8_t * data,uint32_t length)1879 void matoclserv_fuse_lookup(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1880 uint32_t inode,uid,gids,auid,agid;
1881 uint32_t *gid;
1882 uint32_t i;
1883 uint8_t nleng;
1884 const uint8_t *name;
1885 uint32_t newinode;
1886 uint8_t attr[35];
1887 uint32_t msgid;
1888 uint8_t *ptr;
1889 uint8_t status;
1890 if (length<17) {
1891 syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32")",length);
1892 eptr->mode = KILL;
1893 return;
1894 }
1895 msgid = get32bit(&data);
1896 inode = get32bit(&data);
1897 nleng = get8bit(&data);
1898 if (length<17U+nleng) {
1899 syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
1900 eptr->mode = KILL;
1901 return;
1902 }
1903 name = data;
1904 data += nleng;
1905 auid = uid = get32bit(&data);
1906 if (length==17U+nleng) {
1907 gids = 1;
1908 gid = matoclserv_gid_storage(gids);
1909 agid = gid[0] = get32bit(&data);
1910 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1911 } else {
1912 gids = get32bit(&data);
1913 if (length!=17U+nleng+4*gids) {
1914 syslog(LOG_NOTICE,"CLTOMA_FUSE_LOOKUP - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
1915 eptr->mode = KILL;
1916 return;
1917 }
1918 gid = matoclserv_gid_storage(gids);
1919 for (i=0 ; i<gids ; i++) {
1920 gid[i] = get32bit(&data);
1921 }
1922 agid = gid[0];
1923 sessions_ugid_remap(eptr->sesdata,&uid,gid);
1924 }
1925 status = fs_lookup(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid,auid,agid,&newinode,attr);
1926 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LOOKUP,(status!=STATUS_OK)?5:43);
1927 put32bit(&ptr,msgid);
1928 if (status!=STATUS_OK) {
1929 put8bit(&ptr,status);
1930 } else {
1931 put32bit(&ptr,newinode);
1932 memcpy(ptr,attr,35);
1933 }
1934 sessions_inc_stats(eptr->sesdata,3);
1935 }
1936
matoclserv_fuse_getattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)1937 void matoclserv_fuse_getattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1938 uint32_t inode,uid,gid,auid,agid;
1939 uint8_t opened;
1940 uint8_t attr[35];
1941 uint32_t msgid;
1942 uint8_t *ptr;
1943 uint8_t status;
1944 if (length!=8 && length!=16 && length!=17) {
1945 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETATTR - wrong size (%"PRIu32"/8|16|17)",length);
1946 eptr->mode = KILL;
1947 return;
1948 }
1949 msgid = get32bit(&data);
1950 inode = get32bit(&data);
1951 if (length==17) {
1952 opened = get8bit(&data);
1953 } else {
1954 opened = 0;
1955 }
1956 if (length>=16) {
1957 auid = uid = get32bit(&data);
1958 agid = gid = get32bit(&data);
1959 sessions_ugid_remap(eptr->sesdata,&uid,&gid);
1960 } else {
1961 auid = uid = 12345;
1962 agid = gid = 12345;
1963 }
1964 status = fs_getattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gid,auid,agid,attr);
1965 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETATTR,(status!=STATUS_OK)?5:39);
1966 put32bit(&ptr,msgid);
1967 if (status!=STATUS_OK) {
1968 put8bit(&ptr,status);
1969 } else {
1970 memcpy(ptr,attr,35);
1971 }
1972 sessions_inc_stats(eptr->sesdata,1);
1973 }
1974
matoclserv_fuse_setattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)1975 void matoclserv_fuse_setattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
1976 uint32_t inode,uid,gids,auid,agid;
1977 uint32_t *gid;
1978 uint32_t i;
1979 uint8_t opened;
1980 uint16_t setmask;
1981 uint8_t attr[35];
1982 uint32_t msgid;
1983 uint8_t *ptr;
1984 uint8_t status;
1985 uint8_t sugidclearmode;
1986 uint16_t attrmode;
1987 uint32_t attruid,attrgid,attratime,attrmtime;
1988 if (length!=35 && length!=36 && length<37) {
1989 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETATTR - wrong size (%"PRIu32"/35|36|37+N*4)",length);
1990 eptr->mode = KILL;
1991 return;
1992 }
1993 msgid = get32bit(&data);
1994 inode = get32bit(&data);
1995 if (length>=37) {
1996 opened = get8bit(&data);
1997 } else {
1998 opened = 0;
1999 }
2000 auid = uid = get32bit(&data);
2001 if (length<=37) {
2002 gids = 1;
2003 gid = matoclserv_gid_storage(gids);
2004 agid = gid[0] = get32bit(&data);
2005 } else {
2006 gids = get32bit(&data);
2007 if (length!=37+4*gids) {
2008 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETATTR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2009 eptr->mode = KILL;
2010 return;
2011 }
2012 gid = matoclserv_gid_storage(gids);
2013 for (i=0 ; i<gids ; i++) {
2014 gid[i] = get32bit(&data);
2015 }
2016 agid = gid[0];
2017 }
2018 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2019 setmask = get8bit(&data);
2020 attrmode = get16bit(&data);
2021 attruid = get32bit(&data);
2022 attrgid = get32bit(&data);
2023 attratime = get32bit(&data);
2024 attrmtime = get32bit(&data);
2025 if (length>=36) {
2026 sugidclearmode = get8bit(&data);
2027 } else {
2028 sugidclearmode = SUGID_CLEAR_MODE_ALWAYS; // this is safest option
2029 }
2030 if (setmask&(SET_GOAL_FLAG|SET_LENGTH_FLAG|SET_OPENED_FLAG)) {
2031 status = ERROR_EINVAL;
2032 } else {
2033 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,sugidclearmode,attr);
2034 }
2035 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETATTR,(status!=STATUS_OK)?5:39);
2036 put32bit(&ptr,msgid);
2037 if (status!=STATUS_OK) {
2038 put8bit(&ptr,status);
2039 } else {
2040 memcpy(ptr,attr,35);
2041 }
2042 sessions_inc_stats(eptr->sesdata,2);
2043 }
2044
matoclserv_fuse_truncate(matoclserventry * eptr,const uint8_t * data,uint32_t length)2045 void matoclserv_fuse_truncate(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2046 uint32_t inode,uid,gids,auid,agid;
2047 uint32_t *gid;
2048 uint32_t i;
2049 uint8_t attr[35];
2050 uint32_t msgid;
2051 uint8_t *ptr;
2052 uint8_t flags;
2053 uint8_t status;
2054 uint64_t attrlength;
2055 chunklist *cl;
2056 uint64_t chunkid;
2057 if (length!=24 && length<25) {
2058 syslog(LOG_NOTICE,"CLTOMA_FUSE_TRUNCATE - wrong size (%"PRIu32"/24|25+N*4)",length);
2059 eptr->mode = KILL;
2060 return;
2061 }
2062 flags = 0;
2063 msgid = get32bit(&data);
2064 inode = get32bit(&data);
2065 if (length>=25) {
2066 flags = get8bit(&data);
2067 }
2068 auid = uid = get32bit(&data);
2069 if (length<=25) {
2070 gids = 1;
2071 gid = matoclserv_gid_storage(gids);
2072 agid = gid[0] = get32bit(&data);
2073 if (length==24) {
2074 if (uid==0 && gid[0]!=0) { // stupid "opened" patch for old clients
2075 flags |= TRUNCATE_FLAG_OPENED;
2076 }
2077 }
2078 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2079 } else {
2080 gids = get32bit(&data);
2081 if (length!=25+4*gids) {
2082 syslog(LOG_NOTICE,"CLTOMA_FUSE_TRUNCATE - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2083 eptr->mode = KILL;
2084 return;
2085 }
2086 gid = matoclserv_gid_storage(gids);
2087 for (i=0 ; i<gids ; i++) {
2088 gid[i] = get32bit(&data);
2089 }
2090 agid = gid[0];
2091 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2092 }
2093 attrlength = get64bit(&data);
2094 status = fs_try_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,flags,uid,gids,gid,auid,agid,attrlength,attr,&chunkid);
2095 if (status==ERROR_DELAYED) {
2096 cl = (chunklist*)malloc(sizeof(chunklist));
2097 passert(cl);
2098 cl->chunkid = chunkid;
2099 cl->qid = msgid;
2100 cl->inode = inode;
2101 cl->uid = uid;
2102 cl->gid = gid[0];
2103 cl->auid = auid;
2104 cl->agid = agid;
2105 cl->fleng = attrlength;
2106 cl->type = FUSE_TRUNCATE;
2107 cl->next = eptr->chunkdelayedops;
2108 eptr->chunkdelayedops = cl;
2109 sessions_inc_stats(eptr->sesdata,2);
2110 return;
2111 }
2112 if (status==STATUS_OK) {
2113 status = fs_do_setlength(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,flags,uid,gid[0],auid,agid,attrlength,attr);
2114 }
2115 if (status==STATUS_OK) {
2116 dcm_modify(inode,sessions_get_id(eptr->sesdata));
2117 }
2118 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_TRUNCATE,(status!=STATUS_OK)?5:39);
2119 put32bit(&ptr,msgid);
2120 if (status!=STATUS_OK) {
2121 put8bit(&ptr,status);
2122 } else {
2123 memcpy(ptr,attr,35);
2124 }
2125 sessions_inc_stats(eptr->sesdata,2);
2126 }
2127
matoclserv_fuse_readlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2128 void matoclserv_fuse_readlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2129 uint32_t inode;
2130 uint32_t pleng;
2131 uint8_t *path;
2132 uint32_t msgid;
2133 uint8_t *ptr;
2134 uint8_t status;
2135 if (length!=8) {
2136 syslog(LOG_NOTICE,"CLTOMA_FUSE_READLINK - wrong size (%"PRIu32"/8)",length);
2137 eptr->mode = KILL;
2138 return;
2139 }
2140 msgid = get32bit(&data);
2141 inode = get32bit(&data);
2142 status = fs_readlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&pleng,&path);
2143 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READLINK,(status!=STATUS_OK)?5:8+pleng+1);
2144 put32bit(&ptr,msgid);
2145 if (status!=STATUS_OK) {
2146 put8bit(&ptr,status);
2147 } else {
2148 put32bit(&ptr,pleng+1);
2149 if (pleng>0) {
2150 memcpy(ptr,path,pleng);
2151 }
2152 ptr[pleng]=0;
2153 }
2154 sessions_inc_stats(eptr->sesdata,7);
2155 }
2156
matoclserv_fuse_symlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2157 void matoclserv_fuse_symlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2158 uint32_t inode;
2159 uint8_t nleng;
2160 const uint8_t *name,*path;
2161 uint32_t uid,gids,auid,agid;
2162 uint32_t *gid;
2163 uint32_t i;
2164 uint32_t pleng;
2165 uint32_t newinode;
2166 uint8_t attr[35];
2167 uint32_t msgid;
2168 uint8_t status;
2169 uint8_t *ptr;
2170 if (length<21) {
2171 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32")",length);
2172 eptr->mode = KILL;
2173 return;
2174 }
2175 msgid = get32bit(&data);
2176 inode = get32bit(&data);
2177 nleng = get8bit(&data);
2178 if (length<21U+nleng) {
2179 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2180 eptr->mode = KILL;
2181 return;
2182 }
2183 name = data;
2184 data += nleng;
2185 pleng = get32bit(&data);
2186 if (length<21U+nleng+pleng) {
2187 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8":pleng=%"PRIu32")",length,nleng,pleng);
2188 eptr->mode = KILL;
2189 return;
2190 }
2191 path = data;
2192 data += pleng;
2193 auid = uid = get32bit(&data);
2194 if (length==21U+nleng+pleng) {
2195 gids = 1;
2196 gid = matoclserv_gid_storage(gids);
2197 agid = gid[0] = get32bit(&data);
2198 } else {
2199 gids = get32bit(&data);
2200 if (length!=21U+nleng+pleng+4*gids) {
2201 syslog(LOG_NOTICE,"CLTOMA_FUSE_SYMLINK - wrong size (%"PRIu32":nleng=%"PRIu8":pleng=%"PRIu32":gids=%"PRIu32")",length,nleng,pleng,gids);
2202 eptr->mode = KILL;
2203 return;
2204 }
2205 gid = matoclserv_gid_storage(gids);
2206 for (i=0 ; i<gids ; i++) {
2207 gid[i] = get32bit(&data);
2208 }
2209 agid = gid[0];
2210 }
2211 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2212 while (pleng>0 && path[pleng-1]==0) {
2213 pleng--;
2214 }
2215 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);
2216 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SYMLINK,(status!=STATUS_OK)?5:43);
2217 put32bit(&ptr,msgid);
2218 if (status!=STATUS_OK) {
2219 put8bit(&ptr,status);
2220 } else {
2221 put32bit(&ptr,newinode);
2222 memcpy(ptr,attr,35);
2223 }
2224 sessions_inc_stats(eptr->sesdata,6);
2225 }
2226
matoclserv_fuse_mknod(matoclserventry * eptr,const uint8_t * data,uint32_t length)2227 void matoclserv_fuse_mknod(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2228 uint32_t inode,uid,gids,auid,agid,rdev;
2229 uint32_t *gid;
2230 uint32_t i;
2231 uint8_t nleng;
2232 const uint8_t *name;
2233 uint8_t type;
2234 uint16_t mode,cumask;
2235 uint32_t newinode;
2236 uint8_t attr[35];
2237 uint32_t msgid;
2238 uint8_t *ptr;
2239 uint8_t status;
2240 if (length<24) {
2241 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32")",length);
2242 eptr->mode = KILL;
2243 return;
2244 }
2245 msgid = get32bit(&data);
2246 inode = get32bit(&data);
2247 nleng = get8bit(&data);
2248 if (length!=24U+nleng && length<26U+nleng) {
2249 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2250 eptr->mode = KILL;
2251 return;
2252 }
2253 name = data;
2254 data += nleng;
2255 type = get8bit(&data);
2256 mode = get16bit(&data);
2257 if (length>=26U+nleng) {
2258 cumask = get16bit(&data);
2259 } else {
2260 cumask = 0;
2261 }
2262 auid = uid = get32bit(&data);
2263 if (length<=26U+nleng) {
2264 gids = 1;
2265 gid = matoclserv_gid_storage(gids);
2266 agid = gid[0] = get32bit(&data);
2267 } else {
2268 gids = get32bit(&data);
2269 if (length!=26U+nleng+4*gids) {
2270 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKNOD - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2271 eptr->mode = KILL;
2272 return;
2273 }
2274 gid = matoclserv_gid_storage(gids);
2275 for (i=0 ; i<gids ; i++) {
2276 gid[i] = get32bit(&data);
2277 }
2278 agid = gid[0];
2279 }
2280 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2281 rdev = get32bit(&data);
2282 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);
2283 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_MKNOD,(status!=STATUS_OK)?5:43);
2284 put32bit(&ptr,msgid);
2285 if (status!=STATUS_OK) {
2286 put8bit(&ptr,status);
2287 } else {
2288 put32bit(&ptr,newinode);
2289 memcpy(ptr,attr,35);
2290 }
2291 sessions_inc_stats(eptr->sesdata,8);
2292 }
2293
matoclserv_fuse_mkdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2294 void matoclserv_fuse_mkdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2295 uint32_t inode,uid,gids,auid,agid;
2296 uint32_t *gid;
2297 uint32_t i;
2298 uint8_t nleng;
2299 const uint8_t *name;
2300 uint16_t mode,cumask;
2301 uint32_t newinode;
2302 uint8_t attr[35];
2303 uint32_t msgid;
2304 uint8_t *ptr;
2305 uint8_t status;
2306 uint8_t copysgid;
2307 if (length<19) {
2308 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32")",length);
2309 eptr->mode = KILL;
2310 return;
2311 }
2312 msgid = get32bit(&data);
2313 inode = get32bit(&data);
2314 nleng = get8bit(&data);
2315 if (length!=19U+nleng && length!=20U+nleng && length<22U+nleng) {
2316 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2317 eptr->mode = KILL;
2318 return;
2319 }
2320 name = data;
2321 data += nleng;
2322 mode = get16bit(&data);
2323 if (length>=22U+nleng) {
2324 cumask = get16bit(&data);
2325 } else {
2326 cumask = 0;
2327 }
2328 auid = uid = get32bit(&data);
2329 if (length<=22U+nleng) {
2330 gids = 1;
2331 gid = matoclserv_gid_storage(gids);
2332 agid = gid[0] = get32bit(&data);
2333 } else {
2334 gids = get32bit(&data);
2335 if (length!=22U+nleng+4*gids) {
2336 syslog(LOG_NOTICE,"CLTOMA_FUSE_MKDIR - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2337 eptr->mode = KILL;
2338 return;
2339 }
2340 gid = matoclserv_gid_storage(gids);
2341 for (i=0 ; i<gids ; i++) {
2342 gid[i] = get32bit(&data);
2343 }
2344 agid = gid[0];
2345 }
2346 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2347 if (length>20U+nleng) {
2348 copysgid = get8bit(&data);
2349 } else {
2350 copysgid = 0; // by default do not copy sgid bit
2351 }
2352 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);
2353 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_MKDIR,(status!=STATUS_OK)?5:43);
2354 put32bit(&ptr,msgid);
2355 if (status!=STATUS_OK) {
2356 put8bit(&ptr,status);
2357 } else {
2358 put32bit(&ptr,newinode);
2359 memcpy(ptr,attr,35);
2360 }
2361 sessions_inc_stats(eptr->sesdata,4);
2362 }
2363
matoclserv_fuse_unlink(matoclserventry * eptr,const uint8_t * data,uint32_t length)2364 void matoclserv_fuse_unlink(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2365 uint32_t inode,uid,gids;
2366 uint32_t *gid;
2367 uint32_t i;
2368 uint8_t nleng;
2369 const uint8_t *name;
2370 uint32_t msgid;
2371 uint8_t *ptr;
2372 uint8_t status;
2373 if (length<17) {
2374 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - 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<17U+nleng) {
2382 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2383 eptr->mode = KILL;
2384 return;
2385 }
2386 name = data;
2387 data += nleng;
2388 uid = get32bit(&data);
2389 if (length==17U+nleng) {
2390 gids = 1;
2391 gid = matoclserv_gid_storage(gids);
2392 gid[0] = get32bit(&data);
2393 } else {
2394 gids = get32bit(&data);
2395 if (length!=17U+nleng+4*gids) {
2396 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNLINK - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2397 eptr->mode = KILL;
2398 return;
2399 }
2400 gid = matoclserv_gid_storage(gids);
2401 for (i=0 ; i<gids ; i++) {
2402 gid[i] = get32bit(&data);
2403 }
2404 }
2405 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2406 status = fs_unlink(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid);
2407 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_UNLINK,5);
2408 put32bit(&ptr,msgid);
2409 put8bit(&ptr,status);
2410 sessions_inc_stats(eptr->sesdata,9);
2411 }
2412
matoclserv_fuse_rmdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2413 void matoclserv_fuse_rmdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2414 uint32_t inode,uid,gids;
2415 uint32_t *gid;
2416 uint32_t i;
2417 uint8_t nleng;
2418 const uint8_t *name;
2419 uint32_t msgid;
2420 uint8_t *ptr;
2421 uint8_t status;
2422 if (length<17) {
2423 syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32")",length);
2424 eptr->mode = KILL;
2425 return;
2426 }
2427 msgid = get32bit(&data);
2428 inode = get32bit(&data);
2429 nleng = get8bit(&data);
2430 if (length<17U+nleng) {
2431 syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2432 eptr->mode = KILL;
2433 return;
2434 }
2435 name = data;
2436 data += nleng;
2437 uid = get32bit(&data);
2438 if (length==17U+nleng) {
2439 gids = 1;
2440 gid = matoclserv_gid_storage(gids);
2441 gid[0] = get32bit(&data);
2442 } else {
2443 gids = get32bit(&data);
2444 if (length!=17U+nleng+4*gids) {
2445 syslog(LOG_NOTICE,"CLTOMA_FUSE_RMDIR - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2446 eptr->mode = KILL;
2447 return;
2448 }
2449 gid = matoclserv_gid_storage(gids);
2450 for (i=0 ; i<gids ; i++) {
2451 gid[i] = get32bit(&data);
2452 }
2453 }
2454 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2455 status = fs_rmdir(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,nleng,name,uid,gids,gid);
2456 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RMDIR,5);
2457 put32bit(&ptr,msgid);
2458 put8bit(&ptr,status);
2459 sessions_inc_stats(eptr->sesdata,5);
2460 }
2461
matoclserv_fuse_rename(matoclserventry * eptr,const uint8_t * data,uint32_t length)2462 void matoclserv_fuse_rename(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2463 uint32_t inode,inode_src,inode_dst;
2464 uint8_t nleng_src,nleng_dst;
2465 const uint8_t *name_src,*name_dst;
2466 uint32_t uid,gids,auid,agid;
2467 uint32_t *gid;
2468 uint32_t i;
2469 uint8_t attr[35];
2470 uint32_t msgid;
2471 uint8_t status;
2472 uint8_t *ptr;
2473 if (length<22) {
2474 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32")",length);
2475 eptr->mode = KILL;
2476 return;
2477 }
2478 msgid = get32bit(&data);
2479 inode_src = get32bit(&data);
2480 nleng_src = get8bit(&data);
2481 if (length<22U+nleng_src) {
2482 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8")",length,nleng_src);
2483 eptr->mode = KILL;
2484 return;
2485 }
2486 name_src = data;
2487 data += nleng_src;
2488 inode_dst = get32bit(&data);
2489 nleng_dst = get8bit(&data);
2490 if (length<22U+nleng_src+nleng_dst) {
2491 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8":nleng_dst=%"PRIu8")",length,nleng_src,nleng_dst);
2492 eptr->mode = KILL;
2493 return;
2494 }
2495 name_dst = data;
2496 data += nleng_dst;
2497 auid = uid = get32bit(&data);
2498 if (length==22U+nleng_src+nleng_dst) {
2499 gids = 1;
2500 gid = matoclserv_gid_storage(gids);
2501 agid = gid[0] = get32bit(&data);
2502 } else {
2503 gids = get32bit(&data);
2504 if (length!=22U+nleng_src+nleng_dst+4*gids) {
2505 syslog(LOG_NOTICE,"CLTOMA_FUSE_RENAME - wrong size (%"PRIu32":nleng_src=%"PRIu8":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_src,nleng_dst,gids);
2506 eptr->mode = KILL;
2507 return;
2508 }
2509 gid = matoclserv_gid_storage(gids);
2510 for (i=0 ; i<gids ; i++) {
2511 gid[i] = get32bit(&data);
2512 }
2513 agid = gid[0];
2514 }
2515 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2516 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,&inode,attr);
2517 if (eptr->version>=VERSION2INT(1,6,21) && status==STATUS_OK) {
2518 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RENAME,43);
2519 } else {
2520 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_RENAME,5);
2521 }
2522 put32bit(&ptr,msgid);
2523 if (eptr->version>=VERSION2INT(1,6,21) && status==STATUS_OK) {
2524 put32bit(&ptr,inode);
2525 memcpy(ptr,attr,35);
2526 } else {
2527 put8bit(&ptr,status);
2528 }
2529 sessions_inc_stats(eptr->sesdata,10);
2530 }
2531
matoclserv_fuse_link(matoclserventry * eptr,const uint8_t * data,uint32_t length)2532 void matoclserv_fuse_link(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2533 uint32_t inode,inode_dst;
2534 uint8_t nleng_dst;
2535 const uint8_t *name_dst;
2536 uint32_t uid,gids,auid,agid;
2537 uint32_t *gid;
2538 uint32_t i;
2539 uint32_t newinode;
2540 uint8_t attr[35];
2541 uint32_t msgid;
2542 uint8_t *ptr;
2543 uint8_t status;
2544 if (length<21) {
2545 syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32")",length);
2546 eptr->mode = KILL;
2547 return;
2548 }
2549 msgid = get32bit(&data);
2550 inode = get32bit(&data);
2551 inode_dst = get32bit(&data);
2552 nleng_dst = get8bit(&data);
2553 if (length<21U+nleng_dst) {
2554 syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32":nleng_dst=%"PRIu8")",length,nleng_dst);
2555 eptr->mode = KILL;
2556 return;
2557 }
2558 name_dst = data;
2559 data += nleng_dst;
2560 auid = uid = get32bit(&data);
2561 if (length==21U+nleng_dst) {
2562 gids = 1;
2563 gid = matoclserv_gid_storage(gids);
2564 agid = gid[0] = get32bit(&data);
2565 } else {
2566 gids = get32bit(&data);
2567 if (length!=21U+nleng_dst+4*gids) {
2568 syslog(LOG_NOTICE,"CLTOMA_FUSE_LINK - wrong size (%"PRIu32":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_dst,gids);
2569 eptr->mode = KILL;
2570 return;
2571 }
2572 gid = matoclserv_gid_storage(gids);
2573 for (i=0 ; i<gids ; i++) {
2574 gid[i] = get32bit(&data);
2575 }
2576 agid = gid[0];
2577 }
2578 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2579 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);
2580 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_LINK,(status!=STATUS_OK)?5:43);
2581 put32bit(&ptr,msgid);
2582 if (status!=STATUS_OK) {
2583 put8bit(&ptr,status);
2584 } else {
2585 put32bit(&ptr,newinode);
2586 memcpy(ptr,attr,35);
2587 }
2588 sessions_inc_stats(eptr->sesdata,11);
2589 }
2590
matoclserv_fuse_readdir(matoclserventry * eptr,const uint8_t * data,uint32_t length)2591 void matoclserv_fuse_readdir(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2592 uint32_t inode,uid,gids,auid,agid;
2593 uint32_t *gid;
2594 uint32_t i;
2595 uint8_t flags;
2596 uint32_t msgid;
2597 uint8_t *ptr;
2598 uint8_t status;
2599 uint32_t dleng;
2600 uint32_t maxentries;
2601 uint64_t nedgeid;
2602 void *c1,*c2;
2603 if (length!=16 && length!=17 && length<29) {
2604 syslog(LOG_NOTICE,"CLTOMA_FUSE_READDIR - wrong size (%"PRIu32"/16|17|29+N*4)",length);
2605 eptr->mode = KILL;
2606 return;
2607 }
2608 msgid = get32bit(&data);
2609 inode = get32bit(&data);
2610 auid = uid = get32bit(&data);
2611 if (length<=29) {
2612 gids = 1;
2613 gid = matoclserv_gid_storage(gids);
2614 agid = gid[0] = get32bit(&data);
2615 } else {
2616 gids = get32bit(&data);
2617 if (length!=29+4*gids) {
2618 syslog(LOG_NOTICE,"CLTOMA_FUSE_READDIR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2619 eptr->mode = KILL;
2620 return;
2621 }
2622 gid = matoclserv_gid_storage(gids);
2623 for (i=0 ; i<gids ; i++) {
2624 gid[i] = get32bit(&data);
2625 }
2626 agid = gid[0];
2627 }
2628 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2629 if (length>=17) {
2630 flags = get8bit(&data);
2631 } else {
2632 flags = 0;
2633 }
2634 if (length>=29) {
2635 maxentries = get32bit(&data);
2636 nedgeid = get64bit(&data);
2637 } else {
2638 maxentries = 0xFFFFFFFF;
2639 nedgeid = 0;
2640 }
2641 status = fs_readdir_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,flags,maxentries,nedgeid,&c1,&c2,&dleng);
2642 if (status!=STATUS_OK) {
2643 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,5);
2644 } else if (length>=29) {
2645 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,12+dleng);
2646 } else {
2647 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READDIR,4+dleng);
2648 }
2649 put32bit(&ptr,msgid);
2650 if (status!=STATUS_OK) {
2651 put8bit(&ptr,status);
2652 } else {
2653 if (length>=29) {
2654 put64bit(&ptr,nedgeid);
2655 }
2656 fs_readdir_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),uid,gid[0],auid,agid,flags,maxentries,&nedgeid,c1,c2,ptr);
2657 /* CACHENOTIFY
2658 if (flags&GETDIR_FLAG_ADDTOCACHE) {
2659 if (inode==MFS_ROOT_ID) {
2660 matoclserv_notify_add_dir(eptr,sessions_get_rootinode(eptr->sesdata));
2661 } else {
2662 matoclserv_notify_add_dir(eptr,inode);
2663 }
2664 }
2665 */
2666 }
2667 sessions_inc_stats(eptr->sesdata,12);
2668 }
2669
2670 /* CACHENOTIFY
2671 void matoclserv_fuse_dir_removed(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2672 uint32_t inode;
2673 if (length%4!=0) {
2674 syslog(LOG_NOTICE,"CLTOMA_FUSE_DIR_REMOVED - wrong size (%"PRIu32"/N*4)",length);
2675 eptr->mode = KILL;
2676 return;
2677 }
2678 if (get32bit(&data)) {
2679 syslog(LOG_NOTICE,"CLTOMA_FUSE_DIR_REMOVED - wrong msgid");
2680 eptr->mode = KILL;
2681 return;
2682 }
2683 length-=4;
2684 while (length) {
2685 inode = get32bit(&data);
2686 length-=4;
2687 if (inode==MFS_ROOT_ID) {
2688 matoclserv_notify_remove_dir(eptr,sessions_get_rootinode(eptr->sesdata));
2689 } else {
2690 matoclserv_notify_remove_dir(eptr,inode);
2691 }
2692 }
2693 }
2694 */
2695
matoclserv_fuse_open(matoclserventry * eptr,const uint8_t * data,uint32_t length)2696 void matoclserv_fuse_open(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2697 uint32_t inode,uid,gids,auid,agid;
2698 uint32_t *gid;
2699 uint32_t i;
2700 uint8_t flags;
2701 uint8_t sesflags;
2702 uint8_t attr[35];
2703 uint32_t msgid;
2704 uint8_t *ptr;
2705 uint8_t status;
2706 int allowcache;
2707 if (length<17) {
2708 syslog(LOG_NOTICE,"CLTOMA_FUSE_OPEN - wrong size (%"PRIu32"/17+N*4)",length);
2709 eptr->mode = KILL;
2710 return;
2711 }
2712 msgid = get32bit(&data);
2713 inode = get32bit(&data);
2714 if (length==17) {
2715 gids = 1;
2716 gid = matoclserv_gid_storage(gids);
2717 auid = uid = get32bit(&data);
2718 agid = gid[0] = get32bit(&data);
2719 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2720 } else {
2721 auid = uid = get32bit(&data);
2722 gids = get32bit(&data);
2723 if (length!=17+gids*4) {
2724 syslog(LOG_NOTICE,"CLTOMA_FUSE_OPEN - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
2725 eptr->mode = KILL;
2726 return;
2727 }
2728 gid = matoclserv_gid_storage(gids);
2729 for (i=0 ; i<gids ; i++) {
2730 gid[i] = get32bit(&data);
2731 }
2732 agid = gid[0];
2733 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2734 }
2735 flags = get8bit(&data);
2736 sesflags = sessions_get_sesflags(eptr->sesdata);
2737 status = fs_opencheck(sessions_get_rootinode(eptr->sesdata),sesflags,inode,uid,gids,gid,auid,agid,flags,attr);
2738 if (status==STATUS_OK) {
2739 of_openfile(sessions_get_id(eptr->sesdata),inode);
2740 }
2741 if (eptr->version>=VERSION2INT(1,6,9) && status==STATUS_OK) {
2742 allowcache = dcm_open(inode,sessions_get_id(eptr->sesdata));
2743 if (allowcache==0) {
2744 if (sesflags&SESFLAG_ATTRBIT) {
2745 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2746 } else {
2747 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2748 }
2749 }
2750 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_OPEN,39);
2751 } else {
2752 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_OPEN,5);
2753 }
2754 put32bit(&ptr,msgid);
2755 if (eptr->version>=VERSION2INT(1,6,9) && status==STATUS_OK) {
2756 memcpy(ptr,attr,35);
2757 } else {
2758 put8bit(&ptr,status);
2759 }
2760 sessions_inc_stats(eptr->sesdata,13);
2761 }
2762
matoclserv_fuse_create(matoclserventry * eptr,const uint8_t * data,uint32_t length)2763 void matoclserv_fuse_create(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2764 uint32_t inode,uid,gids,auid,agid;
2765 uint32_t *gid;
2766 uint32_t i;
2767 uint8_t nleng;
2768 const uint8_t *name;
2769 uint16_t mode,cumask;
2770 uint32_t newinode;
2771 uint8_t attr[35];
2772 uint32_t msgid;
2773 uint8_t *ptr;
2774 uint8_t status;
2775 uint8_t sesflags;
2776 int allowcache;
2777 if (length<19) {
2778 syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32")",length);
2779 eptr->mode = KILL;
2780 return;
2781 }
2782 msgid = get32bit(&data);
2783 inode = get32bit(&data);
2784 nleng = get8bit(&data);
2785 if (length!=19U+nleng && length<21U+nleng) {
2786 syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8")",length,nleng);
2787 eptr->mode = KILL;
2788 return;
2789 }
2790 name = data;
2791 data += nleng;
2792 mode = get16bit(&data);
2793 if (length>=21U+nleng) {
2794 cumask = get16bit(&data);
2795 } else {
2796 cumask = 0;
2797 }
2798 auid = uid = get32bit(&data);
2799 if (length<=21U+nleng) {
2800 gids = 1;
2801 gid = matoclserv_gid_storage(gids);
2802 agid = gid[0] = get32bit(&data);
2803 } else {
2804 gids = get32bit(&data);
2805 if (length!=21U+nleng+4*gids) {
2806 syslog(LOG_NOTICE,"CLTOMA_FUSE_CREATE - wrong size (%"PRIu32":nleng=%"PRIu8":gids=%"PRIu32")",length,nleng,gids);
2807 eptr->mode = KILL;
2808 return;
2809 }
2810 gid = matoclserv_gid_storage(gids);
2811 for (i=0 ; i<gids ; i++) {
2812 gid[i] = get32bit(&data);
2813 }
2814 agid = gid[0];
2815 }
2816 sessions_ugid_remap(eptr->sesdata,&uid,gid);
2817 sesflags = sessions_get_sesflags(eptr->sesdata);
2818 status = fs_mknod(sessions_get_rootinode(eptr->sesdata),sesflags,inode,nleng,name,TYPE_FILE,mode,cumask,uid,gids,gid,auid,agid,0,&newinode,attr);
2819 if (status==STATUS_OK) {
2820 of_openfile(sessions_get_id(eptr->sesdata),newinode);
2821 allowcache = dcm_open(newinode,sessions_get_id(eptr->sesdata));
2822 if (allowcache==0) {
2823 if (sesflags&SESFLAG_ATTRBIT) {
2824 attr[0]&=(0xFF^MATTR_ALLOWDATACACHE);
2825 } else {
2826 attr[1]&=(0xFF^(MATTR_ALLOWDATACACHE<<4));
2827 }
2828 }
2829 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CREATE,43);
2830 } else {
2831 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CREATE,5);
2832 }
2833 put32bit(&ptr,msgid);
2834 if (status!=STATUS_OK) {
2835 put8bit(&ptr,status);
2836 } else {
2837 put32bit(&ptr,newinode);
2838 memcpy(ptr,attr,35);
2839 }
2840 sessions_inc_stats(eptr->sesdata,8);
2841 sessions_inc_stats(eptr->sesdata,13);
2842 }
2843
matoclserv_fuse_read_chunk(matoclserventry * eptr,const uint8_t * data,uint32_t length)2844 void matoclserv_fuse_read_chunk(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2845 uint8_t *ptr;
2846 uint8_t status;
2847 uint32_t inode;
2848 uint32_t indx;
2849 uint64_t chunkid;
2850 uint64_t fleng;
2851 uint32_t version;
2852 // uint32_t ip;
2853 // uint16_t port;
2854 uint8_t count;
2855 uint8_t cs_data[100*10];
2856 uint32_t msgid;
2857 if (length!=12) {
2858 syslog(LOG_NOTICE,"CLTOMA_FUSE_READ_CHUNK - wrong size (%"PRIu32"/12)",length);
2859 eptr->mode = KILL;
2860 return;
2861 }
2862 msgid = get32bit(&data);
2863 inode = get32bit(&data);
2864 indx = get32bit(&data);
2865 // if (matoclserv_open_check(eptr,inode)<0) {
2866 // status = ERROR_NOTOPENED;
2867 // } else {
2868 status = fs_readchunk(inode,indx,&chunkid,&fleng);
2869 // }
2870 if (status==STATUS_OK) {
2871 if (chunkid>0) {
2872 if (eptr->version>=VERSION2INT(1,7,32)) {
2873 status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
2874 } else {
2875 status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
2876 }
2877 } else {
2878 version = 0;
2879 count = 0;
2880 }
2881 }
2882 if (status!=STATUS_OK) {
2883 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,5);
2884 put32bit(&ptr,msgid);
2885 put8bit(&ptr,status);
2886 return;
2887 }
2888 dcm_access(inode,sessions_get_id(eptr->sesdata));
2889 if (eptr->version>=VERSION2INT(1,7,32)) {
2890 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,25+count*10);
2891 } else {
2892 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_READ_CHUNK,24+count*6);
2893 }
2894 put32bit(&ptr,msgid);
2895 if (eptr->version>=VERSION2INT(1,7,32)) {
2896 put8bit(&ptr,1);
2897 }
2898 put64bit(&ptr,fleng);
2899 put64bit(&ptr,chunkid);
2900 put32bit(&ptr,version);
2901 if (count>0) {
2902 if (eptr->version>=VERSION2INT(1,7,32)) {
2903 memcpy(ptr,cs_data,count*10);
2904 } else {
2905 memcpy(ptr,cs_data,count*6);
2906 }
2907 }
2908 sessions_inc_stats(eptr->sesdata,14);
2909 }
2910
matoclserv_fuse_write_chunk(matoclserventry * eptr,const uint8_t * data,uint32_t length)2911 void matoclserv_fuse_write_chunk(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2912 uint8_t *ptr;
2913 uint8_t status;
2914 uint32_t inode;
2915 uint32_t indx;
2916 uint64_t fleng;
2917 uint64_t chunkid;
2918 uint32_t msgid;
2919 uint8_t opflag;
2920 chunklist *cl;
2921 uint32_t version;
2922 uint8_t count;
2923 uint8_t cs_data[100*10];
2924
2925 if (length!=12) {
2926 syslog(LOG_NOTICE,"CLTOMA_FUSE_WRITE_CHUNK - wrong size (%"PRIu32"/12)",length);
2927 eptr->mode = KILL;
2928 return;
2929 }
2930 msgid = get32bit(&data);
2931 inode = get32bit(&data);
2932 indx = get32bit(&data);
2933 if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_READONLY) {
2934 status = ERROR_EROFS;
2935 } else {
2936 status = fs_writechunk(inode,indx,&chunkid,&fleng,&opflag);
2937 }
2938 if (status!=STATUS_OK) {
2939 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
2940 put32bit(&ptr,msgid);
2941 put8bit(&ptr,status);
2942 return;
2943 }
2944 if (opflag) { // wait for operation end
2945 cl = (chunklist*)malloc(sizeof(chunklist));
2946 passert(cl);
2947 cl->inode = inode;
2948 cl->chunkid = chunkid;
2949 cl->qid = msgid;
2950 cl->fleng = fleng;
2951 cl->type = FUSE_WRITE;
2952 cl->next = eptr->chunkdelayedops;
2953 eptr->chunkdelayedops = cl;
2954 } else { // return status immediately
2955 dcm_modify(inode,sessions_get_id(eptr->sesdata));
2956 if (eptr->version>=VERSION2INT(1,7,32)) {
2957 status = chunk_get_version_and_csdata(1,chunkid,eptr->peerip,&version,&count,cs_data);
2958 } else {
2959 status = chunk_get_version_and_csdata(0,chunkid,eptr->peerip,&version,&count,cs_data);
2960 }
2961 if (status!=STATUS_OK) {
2962 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,5);
2963 put32bit(&ptr,msgid);
2964 put8bit(&ptr,status);
2965 fs_writeend(0,0,chunkid); // ignore status - just do it.
2966 return;
2967 }
2968 if (eptr->version>=VERSION2INT(1,7,32)) {
2969 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,25+count*10);
2970 } else {
2971 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK,24+count*6);
2972 }
2973 put32bit(&ptr,msgid);
2974 if (eptr->version>=VERSION2INT(1,7,32)) {
2975 put8bit(&ptr,1);
2976 }
2977 put64bit(&ptr,fleng);
2978 put64bit(&ptr,chunkid);
2979 put32bit(&ptr,version);
2980 if (count>0) {
2981 if (eptr->version>=VERSION2INT(1,7,32)) {
2982 memcpy(ptr,cs_data,count*10);
2983 } else {
2984 memcpy(ptr,cs_data,count*6);
2985 }
2986 }
2987 }
2988 sessions_inc_stats(eptr->sesdata,15);
2989 }
2990
matoclserv_fuse_write_chunk_end(matoclserventry * eptr,const uint8_t * data,uint32_t length)2991 void matoclserv_fuse_write_chunk_end(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
2992 uint8_t *ptr;
2993 uint32_t msgid;
2994 uint32_t inode;
2995 uint64_t fleng;
2996 uint64_t chunkid;
2997 uint8_t status;
2998 // chunklist *cl,**acl;
2999 if (length!=24) {
3000 syslog(LOG_NOTICE,"CLTOMA_FUSE_WRITE_CHUNK_END - wrong size (%"PRIu32"/24)",length);
3001 eptr->mode = KILL;
3002 return;
3003 }
3004 msgid = get32bit(&data);
3005 chunkid = get64bit(&data);
3006 inode = get32bit(&data);
3007 fleng = get64bit(&data);
3008 if (sessions_get_sesflags(eptr->sesdata)&SESFLAG_READONLY) {
3009 status = ERROR_EROFS;
3010 } else {
3011 status = fs_writeend(inode,fleng,chunkid);
3012 }
3013 dcm_modify(inode,sessions_get_id(eptr->sesdata));
3014 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_WRITE_CHUNK_END,5);
3015 put32bit(&ptr,msgid);
3016 put8bit(&ptr,status);
3017 }
3018
matoclserv_fuse_repair(matoclserventry * eptr,const uint8_t * data,uint32_t length)3019 void matoclserv_fuse_repair(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3020 uint32_t inode,uid,gids;
3021 uint32_t *gid;
3022 uint32_t i;
3023 uint32_t msgid;
3024 uint32_t chunksnotchanged,chunkserased,chunksrepaired;
3025 uint8_t *ptr;
3026 uint8_t status;
3027 if (length<16) {
3028 syslog(LOG_NOTICE,"CLTOMA_FUSE_REPAIR - wrong size (%"PRIu32"/16+N*4)",length);
3029 eptr->mode = KILL;
3030 return;
3031 }
3032 msgid = get32bit(&data);
3033 inode = get32bit(&data);
3034 uid = get32bit(&data);
3035 if (length==16) {
3036 gids = 1;
3037 gid = matoclserv_gid_storage(gids);
3038 gid[0] = get32bit(&data);
3039 } else {
3040 gids = get32bit(&data);
3041 if (length!=16+4*gids) {
3042 syslog(LOG_NOTICE,"CLTOMA_FUSE_REPAIR - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
3043 eptr->mode = KILL;
3044 return;
3045 }
3046 gid = matoclserv_gid_storage(gids);
3047 for (i=0 ; i<gids ; i++) {
3048 gid[i] = get32bit(&data);
3049 }
3050 }
3051 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3052 status = fs_repair(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gids,gid,&chunksnotchanged,&chunkserased,&chunksrepaired);
3053 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_REPAIR,(status!=STATUS_OK)?5:16);
3054 put32bit(&ptr,msgid);
3055 if (status!=0) {
3056 put8bit(&ptr,status);
3057 } else {
3058 put32bit(&ptr,chunksnotchanged);
3059 put32bit(&ptr,chunkserased);
3060 put32bit(&ptr,chunksrepaired);
3061 }
3062 }
3063
matoclserv_fuse_check(matoclserventry * eptr,const uint8_t * data,uint32_t length)3064 void matoclserv_fuse_check(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3065 uint32_t inode;
3066 uint32_t i,chunkcount[11];
3067 uint32_t msgid;
3068 uint8_t *ptr;
3069 uint8_t status;
3070 if (length!=8) {
3071 syslog(LOG_NOTICE,"CLTOMA_FUSE_CHECK - wrong size (%"PRIu32"/8)",length);
3072 eptr->mode = KILL;
3073 return;
3074 }
3075 msgid = get32bit(&data);
3076 inode = get32bit(&data);
3077 status = fs_checkfile(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,chunkcount);
3078 if (status!=STATUS_OK) {
3079 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,5);
3080 put32bit(&ptr,msgid);
3081 put8bit(&ptr,status);
3082 } else {
3083 if (eptr->version>=VERSION2INT(1,6,23)) {
3084 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,48);
3085 put32bit(&ptr,msgid);
3086 for (i=0 ; i<11 ; i++) {
3087 put32bit(&ptr,chunkcount[i]);
3088 }
3089 } else {
3090 uint8_t j;
3091 j=0;
3092 for (i=0 ; i<11 ; i++) {
3093 if (chunkcount[i]>0) {
3094 j++;
3095 }
3096 }
3097 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_CHECK,4+3*j);
3098 put32bit(&ptr,msgid);
3099 for (i=0 ; i<11 ; i++) {
3100 if (chunkcount[i]>0) {
3101 put8bit(&ptr,i);
3102 if (chunkcount[i]<=65535) {
3103 put16bit(&ptr,chunkcount[i]);
3104 } else {
3105 put16bit(&ptr,65535);
3106 }
3107 }
3108 }
3109 }
3110 }
3111 }
3112
3113
matoclserv_fuse_gettrashtime(matoclserventry * eptr,const uint8_t * data,uint32_t length)3114 void matoclserv_fuse_gettrashtime(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3115 uint32_t inode;
3116 uint8_t gmode;
3117 void *fptr,*dptr;
3118 uint32_t fnodes,dnodes;
3119 uint32_t msgid;
3120 uint8_t *ptr;
3121 uint8_t status;
3122 if (length!=9) {
3123 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASHTIME - wrong size (%"PRIu32"/9)",length);
3124 eptr->mode = KILL;
3125 return;
3126 }
3127 msgid = get32bit(&data);
3128 inode = get32bit(&data);
3129 gmode = get8bit(&data);
3130 status = fs_gettrashtime_prepare(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,&fptr,&dptr,&fnodes,&dnodes);
3131 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASHTIME,(status!=STATUS_OK)?5:12+8*(fnodes+dnodes));
3132 put32bit(&ptr,msgid);
3133 if (status!=STATUS_OK) {
3134 put8bit(&ptr,status);
3135 } else {
3136 put32bit(&ptr,fnodes);
3137 put32bit(&ptr,dnodes);
3138 fs_gettrashtime_store(fptr,dptr,ptr);
3139 }
3140 }
3141
matoclserv_fuse_settrashtime(matoclserventry * eptr,const uint8_t * data,uint32_t length)3142 void matoclserv_fuse_settrashtime(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3143 uint32_t inode,uid,trashtime;
3144 uint32_t msgid;
3145 uint8_t smode;
3146 uint32_t changed,notchanged,notpermitted;
3147 uint8_t *ptr;
3148 uint8_t status;
3149 if (length!=17) {
3150 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHTIME - wrong size (%"PRIu32"/17)",length);
3151 eptr->mode = KILL;
3152 return;
3153 }
3154 msgid = get32bit(&data);
3155 inode = get32bit(&data);
3156 uid = get32bit(&data);
3157 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3158 trashtime = get32bit(&data);
3159 smode = get8bit(&data);
3160 status = sessions_check_trashtime(eptr->sesdata,smode&SMODE_TMASK,trashtime);
3161 if (status==STATUS_OK) {
3162 status = fs_settrashtime(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,trashtime,smode,&changed,¬changed,¬permitted);
3163 }
3164 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETTRASHTIME,(status!=STATUS_OK)?5:16);
3165 put32bit(&ptr,msgid);
3166 if (status!=STATUS_OK) {
3167 put8bit(&ptr,status);
3168 } else {
3169 put32bit(&ptr,changed);
3170 put32bit(&ptr,notchanged);
3171 put32bit(&ptr,notpermitted);
3172 }
3173 }
3174
matoclserv_fuse_getgoal(matoclserventry * eptr,const uint8_t * data,uint32_t length)3175 void matoclserv_fuse_getgoal(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3176 uint32_t inode;
3177 uint32_t msgid;
3178 uint32_t fgtab[10],dgtab[10];
3179 uint8_t i,fn,dn,gmode;
3180 uint8_t *ptr;
3181 uint8_t status;
3182 if (length!=9) {
3183 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETGOAL - wrong size (%"PRIu32"/9)",length);
3184 eptr->mode = KILL;
3185 return;
3186 }
3187 msgid = get32bit(&data);
3188 inode = get32bit(&data);
3189 gmode = get8bit(&data);
3190 status = fs_getgoal(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,fgtab,dgtab);
3191 fn=0;
3192 dn=0;
3193 if (status==STATUS_OK) {
3194 for (i=1 ; i<10 ; i++) {
3195 if (fgtab[i]) {
3196 fn++;
3197 }
3198 if (dgtab[i]) {
3199 dn++;
3200 }
3201 }
3202 }
3203 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETGOAL,(status!=STATUS_OK)?5:6+5*(fn+dn));
3204 put32bit(&ptr,msgid);
3205 if (status!=STATUS_OK) {
3206 put8bit(&ptr,status);
3207 } else {
3208 put8bit(&ptr,fn);
3209 put8bit(&ptr,dn);
3210 for (i=1 ; i<10 ; i++) {
3211 if (fgtab[i]) {
3212 put8bit(&ptr,i);
3213 put32bit(&ptr,fgtab[i]);
3214 }
3215 }
3216 for (i=1 ; i<10 ; i++) {
3217 if (dgtab[i]) {
3218 put8bit(&ptr,i);
3219 put32bit(&ptr,dgtab[i]);
3220 }
3221 }
3222 }
3223 }
3224
matoclserv_fuse_setgoal(matoclserventry * eptr,const uint8_t * data,uint32_t length)3225 void matoclserv_fuse_setgoal(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3226 uint32_t inode,uid;
3227 uint32_t msgid;
3228 uint8_t goal,smode;
3229 uint32_t changed,notchanged,notpermitted;
3230 uint8_t *ptr;
3231 uint8_t status;
3232 if (length!=14) {
3233 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETGOAL - wrong size (%"PRIu32"/14)",length);
3234 eptr->mode = KILL;
3235 return;
3236 }
3237 msgid = get32bit(&data);
3238 inode = get32bit(&data);
3239 uid = get32bit(&data);
3240 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3241 goal = get8bit(&data);
3242 smode = get8bit(&data);
3243 status = sessions_check_goal(eptr->sesdata,smode&SMODE_TMASK,goal);
3244 if (goal<1 || goal>9) {
3245 status = ERROR_EINVAL;
3246 }
3247 if (status==STATUS_OK) {
3248 status = fs_setgoal(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,goal,smode,&changed,¬changed,¬permitted);
3249 }
3250 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETGOAL,(status!=STATUS_OK)?5:16);
3251 put32bit(&ptr,msgid);
3252 if (status!=STATUS_OK) {
3253 put8bit(&ptr,status);
3254 } else {
3255 put32bit(&ptr,changed);
3256 put32bit(&ptr,notchanged);
3257 put32bit(&ptr,notpermitted);
3258 }
3259 }
3260
matoclserv_fuse_geteattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3261 void matoclserv_fuse_geteattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3262 uint32_t inode;
3263 uint32_t msgid;
3264 uint32_t feattrtab[16],deattrtab[16];
3265 uint8_t i,fn,dn,gmode;
3266 uint8_t *ptr;
3267 uint8_t status;
3268 if (length!=9) {
3269 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETEATTR - wrong size (%"PRIu32"/9)",length);
3270 eptr->mode = KILL;
3271 return;
3272 }
3273 msgid = get32bit(&data);
3274 inode = get32bit(&data);
3275 gmode = get8bit(&data);
3276 status = fs_geteattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,gmode,feattrtab,deattrtab);
3277 fn=0;
3278 dn=0;
3279 if (status==STATUS_OK) {
3280 for (i=0 ; i<16 ; i++) {
3281 if (feattrtab[i]) {
3282 fn++;
3283 }
3284 if (deattrtab[i]) {
3285 dn++;
3286 }
3287 }
3288 }
3289 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETEATTR,(status!=STATUS_OK)?5:6+5*(fn+dn));
3290 put32bit(&ptr,msgid);
3291 if (status!=STATUS_OK) {
3292 put8bit(&ptr,status);
3293 } else {
3294 put8bit(&ptr,fn);
3295 put8bit(&ptr,dn);
3296 for (i=0 ; i<16 ; i++) {
3297 if (feattrtab[i]) {
3298 put8bit(&ptr,i);
3299 put32bit(&ptr,feattrtab[i]);
3300 }
3301 }
3302 for (i=0 ; i<16 ; i++) {
3303 if (deattrtab[i]) {
3304 put8bit(&ptr,i);
3305 put32bit(&ptr,deattrtab[i]);
3306 }
3307 }
3308 }
3309 }
3310
matoclserv_fuse_seteattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3311 void matoclserv_fuse_seteattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3312 uint32_t inode,uid;
3313 uint32_t msgid;
3314 uint8_t eattr,smode;
3315 uint32_t changed,notchanged,notpermitted;
3316 uint8_t *ptr;
3317 uint8_t status;
3318 if (length!=14) {
3319 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETEATTR - wrong size (%"PRIu32"/14)",length);
3320 eptr->mode = KILL;
3321 return;
3322 }
3323 msgid = get32bit(&data);
3324 inode = get32bit(&data);
3325 uid = get32bit(&data);
3326 sessions_ugid_remap(eptr->sesdata,&uid,NULL);
3327 eattr = get8bit(&data);
3328 smode = get8bit(&data);
3329 status = fs_seteattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,eattr,smode,&changed,¬changed,¬permitted);
3330 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETEATTR,(status!=STATUS_OK)?5:16);
3331 put32bit(&ptr,msgid);
3332 if (status!=STATUS_OK) {
3333 put8bit(&ptr,status);
3334 } else {
3335 put32bit(&ptr,changed);
3336 put32bit(&ptr,notchanged);
3337 put32bit(&ptr,notpermitted);
3338 }
3339 }
3340
matoclserv_fuse_parents(matoclserventry * eptr,const uint8_t * data,uint32_t length)3341 void matoclserv_fuse_parents(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3342 uint32_t inode;
3343 uint32_t msgid;
3344 uint32_t pcount;
3345 uint8_t *ptr;
3346 uint8_t status;
3347 if (length!=8) {
3348 syslog(LOG_NOTICE,"CLTOMA_FUSE_PARENTS - wrong size (%"PRIu32"/8)",length);
3349 eptr->mode = KILL;
3350 return;
3351 }
3352 msgid = get32bit(&data);
3353 inode = get32bit(&data);
3354 status = fs_get_parents_count(sessions_get_rootinode(eptr->sesdata),inode,&pcount);
3355 if (status!=STATUS_OK) {
3356 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PARENTS,5);
3357 put32bit(&ptr,msgid);
3358 put8bit(&ptr,status);
3359 } else {
3360 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PARENTS,4+4*pcount);
3361 put32bit(&ptr,msgid);
3362 fs_get_parents_data(sessions_get_rootinode(eptr->sesdata),inode,ptr);
3363 }
3364 }
3365
matoclserv_fuse_paths(matoclserventry * eptr,const uint8_t * data,uint32_t length)3366 void matoclserv_fuse_paths(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3367 uint32_t inode;
3368 uint32_t msgid;
3369 uint32_t psize;
3370 uint8_t *ptr;
3371 uint8_t status;
3372 if (length!=8) {
3373 syslog(LOG_NOTICE,"CLTOMA_FUSE_PATHS - wrong size (%"PRIu32"/8)",length);
3374 eptr->mode = KILL;
3375 return;
3376 }
3377 msgid = get32bit(&data);
3378 inode = get32bit(&data);
3379 status = fs_get_paths_size(sessions_get_rootinode(eptr->sesdata),inode,&psize);
3380 if (status!=STATUS_OK) {
3381 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PATHS,5);
3382 put32bit(&ptr,msgid);
3383 put8bit(&ptr,status);
3384 } else {
3385 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PATHS,4+psize);
3386 put32bit(&ptr,msgid);
3387 fs_get_paths_data(sessions_get_rootinode(eptr->sesdata),inode,ptr);
3388 }
3389 }
3390
matoclserv_fuse_getxattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3391 void matoclserv_fuse_getxattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3392 uint32_t inode,uid,gids;
3393 uint32_t *gid;
3394 uint32_t i;
3395 uint32_t msgid;
3396 uint8_t opened;
3397 uint8_t mode;
3398 uint8_t *ptr;
3399 uint8_t status;
3400 uint8_t anleng;
3401 const uint8_t *attrname;
3402 if (length<19) {
3403 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32")",length);
3404 eptr->mode = KILL;
3405 return;
3406 }
3407 opened = 0; // makes gcc happy
3408 gid = NULL; // makes gcc happy
3409 msgid = get32bit(&data);
3410 inode = get32bit(&data);
3411 if (eptr->version<VERSION2INT(2,0,0)) {
3412 opened = get8bit(&data);
3413 uid = get32bit(&data);
3414 gids = 1;
3415 gid = matoclserv_gid_storage(gids);
3416 gid[0] = get32bit(&data);
3417 }
3418 anleng = get8bit(&data);
3419 attrname = data;
3420 data+=anleng;
3421 if (length<19U+anleng) {
3422 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8")",length,anleng);
3423 eptr->mode = KILL;
3424 return;
3425 }
3426 mode = get8bit(&data);
3427 if (eptr->version>=VERSION2INT(2,0,0)) {
3428 opened = get8bit(&data);
3429 uid = get32bit(&data);
3430 if (length==19U+anleng) {
3431 gids = 1;
3432 gid = matoclserv_gid_storage(gids);
3433 gid[0] = get32bit(&data);
3434 } else {
3435 gids = get32bit(&data);
3436 if (length!=19U+anleng+4*gids) {
3437 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":gids=%"PRIu32")",length,anleng,gids);
3438 eptr->mode = KILL;
3439 return;
3440 }
3441 gid = matoclserv_gid_storage(gids);
3442 for (i=0 ; i<gids ; i++) {
3443 gid[i] = get32bit(&data);
3444 }
3445 }
3446 }
3447 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3448 if (mode!=MFS_XATTR_GETA_DATA && mode!=MFS_XATTR_LENGTH_ONLY) {
3449 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,5);
3450 put32bit(&ptr,msgid);
3451 put8bit(&ptr,ERROR_EINVAL);
3452 } else if (anleng==0) {
3453 void *xanode;
3454 uint32_t xasize;
3455 status = fs_listxattr_leng(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,&xanode,&xasize);
3456 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,(status!=STATUS_OK)?5:8+((mode==MFS_XATTR_GETA_DATA)?xasize:0));
3457 put32bit(&ptr,msgid);
3458 if (status!=STATUS_OK) {
3459 put8bit(&ptr,status);
3460 } else {
3461 put32bit(&ptr,xasize);
3462 if (mode==MFS_XATTR_GETA_DATA && xasize>0) {
3463 fs_listxattr_data(xanode,ptr);
3464 }
3465 }
3466 } else {
3467 uint8_t *attrvalue;
3468 uint32_t avleng;
3469 status = fs_getxattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,anleng,attrname,&avleng,&attrvalue);
3470 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETXATTR,(status!=STATUS_OK)?5:8+((mode==MFS_XATTR_GETA_DATA)?avleng:0));
3471 put32bit(&ptr,msgid);
3472 if (status!=STATUS_OK) {
3473 put8bit(&ptr,status);
3474 } else {
3475 put32bit(&ptr,avleng);
3476 if (mode==MFS_XATTR_GETA_DATA && avleng>0) {
3477 memcpy(ptr,attrvalue,avleng);
3478 }
3479 }
3480 }
3481 }
3482
matoclserv_fuse_setxattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3483 void matoclserv_fuse_setxattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3484 uint32_t inode,uid,gids;
3485 uint32_t *gid;
3486 uint32_t i;
3487 uint32_t msgid;
3488 const uint8_t *attrname,*attrvalue;
3489 uint8_t opened;
3490 uint8_t anleng;
3491 uint32_t avleng;
3492 uint8_t mode;
3493 uint8_t *ptr;
3494 uint8_t status;
3495 if (length<23) {
3496 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32")",length);
3497 eptr->mode = KILL;
3498 return;
3499 }
3500 opened = 0; // makes gcc happy
3501 gid = NULL; // makes gcc happy
3502 msgid = get32bit(&data);
3503 inode = get32bit(&data);
3504 if (eptr->version<VERSION2INT(2,0,0)) {
3505 opened = get8bit(&data);
3506 uid = get32bit(&data);
3507 gids = 1;
3508 gid = matoclserv_gid_storage(gids);
3509 gid[0] = get32bit(&data);
3510 }
3511 anleng = get8bit(&data);
3512 if (length<23U+anleng) {
3513 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8")",length,anleng);
3514 eptr->mode = KILL;
3515 return;
3516 }
3517 attrname = data;
3518 data += anleng;
3519 avleng = get32bit(&data);
3520 if (length<23U+anleng+avleng) {
3521 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":avleng=%"PRIu32")",length,anleng,avleng);
3522 eptr->mode = KILL;
3523 return;
3524 }
3525 attrvalue = data;
3526 data += avleng;
3527 mode = get8bit(&data);
3528 if (eptr->version>=VERSION2INT(2,0,0)) {
3529 opened = get8bit(&data);
3530 uid = get32bit(&data);
3531 if (length==23U+anleng+avleng) {
3532 gids = 1;
3533 gid = matoclserv_gid_storage(gids);
3534 gid[0] = get32bit(&data);
3535 } else {
3536 gids = get32bit(&data);
3537 if (length!=23U+anleng+avleng+4*gids) {
3538 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETXATTR - wrong size (%"PRIu32":anleng=%"PRIu8":avleng=%"PRIu32":gids=%"PRIu32")",length,anleng,avleng,gids);
3539 eptr->mode = KILL;
3540 return;
3541 }
3542 gid = matoclserv_gid_storage(gids);
3543 for (i=0 ; i<gids ; i++) {
3544 gid[i] = get32bit(&data);
3545 }
3546 }
3547 }
3548 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3549 status = fs_setxattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,anleng,attrname,avleng,attrvalue,mode);
3550 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETXATTR,5);
3551 put32bit(&ptr,msgid);
3552 put8bit(&ptr,status);
3553 }
3554
matoclserv_fuse_getacl(matoclserventry * eptr,const uint8_t * data,uint32_t length)3555 void matoclserv_fuse_getacl(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3556 uint32_t inode,uid,gids;
3557 uint32_t *gid;
3558 uint32_t i;
3559 uint8_t opened;
3560 uint32_t msgid;
3561 uint8_t acltype;
3562 uint8_t *ptr;
3563 uint8_t status;
3564 void *c;
3565 uint16_t userperm;
3566 uint16_t groupperm;
3567 uint16_t otherperm;
3568 uint16_t mask;
3569 uint16_t namedusers;
3570 uint16_t namedgroups;
3571 uint32_t aclleng;
3572 if (length<18) {
3573 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETACL - wrong size (%"PRIu32")",length);
3574 eptr->mode = KILL;
3575 return;
3576 }
3577 msgid = get32bit(&data);
3578 inode = get32bit(&data);
3579 acltype = get8bit(&data);
3580 opened = get8bit(&data);
3581 uid = get32bit(&data);
3582 if (length==18) {
3583 gids = 1;
3584 gid = matoclserv_gid_storage(gids);
3585 gid[0] = get32bit(&data);
3586 } else {
3587 gids = get32bit(&data);
3588 if (length!=18+4*gids) {
3589 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETACL - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
3590 eptr->mode = KILL;
3591 return;
3592 }
3593 gid = matoclserv_gid_storage(gids);
3594 for (i=0 ; i<gids ; i++) {
3595 gid[i] = get32bit(&data);
3596 }
3597 }
3598 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3599 status = fs_getacl_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,opened,uid,gids,gid,acltype,&c,&aclleng);
3600 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETACL,(status!=STATUS_OK)?5:16+aclleng);
3601 if (status!=STATUS_OK) {
3602 put32bit(&ptr,msgid);
3603 put8bit(&ptr,status);
3604 } else {
3605 fs_getacl_data(c,&userperm,&groupperm,&otherperm,&mask,&namedusers,&namedgroups,ptr+16);
3606 put32bit(&ptr,msgid);
3607 put16bit(&ptr,userperm);
3608 put16bit(&ptr,groupperm);
3609 put16bit(&ptr,otherperm);
3610 put16bit(&ptr,mask);
3611 put16bit(&ptr,namedusers);
3612 put16bit(&ptr,namedgroups);
3613 }
3614 }
3615
matoclserv_fuse_setacl(matoclserventry * eptr,const uint8_t * data,uint32_t length)3616 void matoclserv_fuse_setacl(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3617 uint32_t inode;
3618 uint32_t uid;
3619 uint32_t msgid;
3620 uint8_t acltype;
3621 uint16_t userperm;
3622 uint16_t groupperm;
3623 uint16_t otherperm;
3624 uint16_t mask;
3625 uint16_t namedusers;
3626 uint16_t namedgroups;
3627 uint8_t *ptr;
3628 uint8_t status;
3629 if (length<25) {
3630 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETACL - wrong size (%"PRIu32")",length);
3631 eptr->mode = KILL;
3632 return;
3633 }
3634 msgid = get32bit(&data);
3635 inode = get32bit(&data);
3636 uid = get32bit(&data);
3637 acltype = get8bit(&data);
3638 userperm = get16bit(&data);
3639 groupperm = get16bit(&data);
3640 otherperm = get16bit(&data);
3641 mask = get16bit(&data);
3642 namedusers = get16bit(&data);
3643 namedgroups = get16bit(&data);
3644 if (length!=(namedusers+namedgroups)*6U+25U) {
3645 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETACL - wrong size (%"PRIu32":namedusers=%"PRIu16":namedgroups=%"PRIu16")",length,namedusers,namedgroups);
3646 eptr->mode = KILL;
3647 return;
3648 }
3649 // uid = get32bit(&data);
3650 // gid = get32bit(&data);
3651 // sessions_ugid_remap(eptr->sesdata,&uid,&gid);
3652 status = fs_setacl(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,acltype,userperm,groupperm,otherperm,mask,namedusers,namedgroups,data);
3653 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETACL,5);
3654 put32bit(&ptr,msgid);
3655 put8bit(&ptr,status);
3656 }
3657
3658 /*
3659 void matoclserv_fuse_setfilechunks(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3660 uint32_t inode,uid,gid,indx;
3661 uint32_t msgid;
3662 uint64_t leng;
3663 uint8_t *ptr;
3664 uint8_t status;
3665 if (length<28U || ((length-28)%8)!=0) {
3666 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETFILECHUNKS - wrong size (%"PRIu32"/28+N*8)",length);
3667 eptr->mode = KILL;
3668 return;
3669 }
3670 msgid = get32bit(&data);
3671 inode = get32bit(&data);
3672 uid = get32bit(&data);
3673 gid = get32bit(&data);
3674 leng = get64bit(&data);
3675 indx = get32bit(&data);
3676 sessions_ugid_remap(eptr->sesdata,&uid,&gid);
3677 status = fs_setfilechunks(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,gid,leng,indx,(length-28)/8,data);
3678 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETFILECHUNKS,5);
3679 put32bit(&ptr,msgid);
3680 put8bit(&ptr,status);
3681 }
3682 */
3683
matoclserv_fuse_append(matoclserventry * eptr,const uint8_t * data,uint32_t length)3684 void matoclserv_fuse_append(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3685 uint32_t inode,inode_src,uid,gids;
3686 uint32_t *gid;
3687 uint32_t i;
3688 uint32_t msgid;
3689 uint8_t *ptr;
3690 uint8_t status;
3691 if (length<20) {
3692 syslog(LOG_NOTICE,"CLTOMA_FUSE_APPEND - wrong size (%"PRIu32"/20)",length);
3693 eptr->mode = KILL;
3694 return;
3695 }
3696 msgid = get32bit(&data);
3697 inode = get32bit(&data);
3698 inode_src = get32bit(&data);
3699 uid = get32bit(&data);
3700 if (length==20) {
3701 gids = 1;
3702 gid = matoclserv_gid_storage(gids);
3703 gid[0] = get32bit(&data);
3704 } else {
3705 gids = get32bit(&data);
3706 if (length!=20+4*gids) {
3707 syslog(LOG_NOTICE,"CLTOMA_FUSE_APPEND - wrong size (%"PRIu32":gids=%"PRIu32")",length,gids);
3708 eptr->mode = KILL;
3709 return;
3710 }
3711 gid = matoclserv_gid_storage(gids);
3712 for (i=0 ; i<gids ; i++) {
3713 gid[i] = get32bit(&data);
3714 }
3715 }
3716 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3717 status = fs_append(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,inode_src,uid,gids,gid);
3718 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_APPEND,5);
3719 put32bit(&ptr,msgid);
3720 put8bit(&ptr,status);
3721 }
3722
matoclserv_fuse_snapshot(matoclserventry * eptr,const uint8_t * data,uint32_t length)3723 void matoclserv_fuse_snapshot(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3724 uint32_t inode,inode_dst;
3725 uint8_t nleng_dst;
3726 const uint8_t *name_dst;
3727 uint32_t uid,gids;
3728 uint32_t *gid;
3729 uint32_t i;
3730 uint8_t smode;
3731 uint16_t requmask;
3732 uint32_t msgid;
3733 uint8_t *ptr;
3734 uint8_t status;
3735 if (length<22) {
3736 syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32")",length);
3737 eptr->mode = KILL;
3738 return;
3739 }
3740 msgid = get32bit(&data);
3741 inode = get32bit(&data);
3742 inode_dst = get32bit(&data);
3743 nleng_dst = get8bit(&data);
3744 if (length!=22U+nleng_dst && length<24U+nleng_dst) {
3745 syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32":nleng_dst=%"PRIu8")",length,nleng_dst);
3746 eptr->mode = KILL;
3747 return;
3748 }
3749 name_dst = data;
3750 data += nleng_dst;
3751 uid = get32bit(&data);
3752 if (length<=24U+nleng_dst) {
3753 gids = 1;
3754 gid = matoclserv_gid_storage(gids);
3755 gid[0] = get32bit(&data);
3756 } else {
3757 gids = get32bit(&data);
3758 if (length!=24U+nleng_dst+4*gids) {
3759 syslog(LOG_NOTICE,"CLTOMA_FUSE_SNAPSHOT - wrong size (%"PRIu32":nleng_dst=%"PRIu8":gids=%"PRIu32")",length,nleng_dst,gids);
3760 eptr->mode = KILL;
3761 return;
3762 }
3763 gid = matoclserv_gid_storage(gids);
3764 for (i=0 ; i<gids ; i++) {
3765 gid[i] = get32bit(&data);
3766 }
3767 }
3768 sessions_ugid_remap(eptr->sesdata,&uid,gid);
3769 smode = get8bit(&data);
3770 if (length>=24U+nleng_dst) {
3771 requmask = get16bit(&data);
3772 } else {
3773 smode &= ~SNAPSHOT_MODE_CPLIKE_ATTR;
3774 requmask = 0;
3775 }
3776 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);
3777 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SNAPSHOT,5);
3778 put32bit(&ptr,msgid);
3779 put8bit(&ptr,status);
3780 }
3781
matoclserv_fuse_quotacontrol(matoclserventry * eptr,const uint8_t * data,uint32_t length)3782 void matoclserv_fuse_quotacontrol(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3783 uint8_t flags,del;
3784 uint32_t sinodes,hinodes,curinodes;
3785 uint64_t slength,ssize,srealsize,hlength,hsize,hrealsize,curlength,cursize,currealsize;
3786 uint32_t msgid,inode;
3787 uint8_t *ptr;
3788 uint8_t status;
3789 if (length!=65 && length!=9) {
3790 syslog(LOG_NOTICE,"CLTOMA_FUSE_QUOTACONTROL - wrong size (%"PRIu32")",length);
3791 eptr->mode = KILL;
3792 return;
3793 }
3794 msgid = get32bit(&data);
3795 inode = get32bit(&data);
3796 flags = get8bit(&data);
3797 if (length==65) {
3798 sinodes = get32bit(&data);
3799 slength = get64bit(&data);
3800 ssize = get64bit(&data);
3801 srealsize = get64bit(&data);
3802 hinodes = get32bit(&data);
3803 hlength = get64bit(&data);
3804 hsize = get64bit(&data);
3805 hrealsize = get64bit(&data);
3806 del=0;
3807 } else {
3808 del=1;
3809 }
3810 if (flags && sessions_is_root_remapped(eptr->sesdata)) {
3811 status = ERROR_EACCES;
3812 } else {
3813 status = fs_quotacontrol(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,del,&flags,&sinodes,&slength,&ssize,&srealsize,&hinodes,&hlength,&hsize,&hrealsize,&curinodes,&curlength,&cursize,&currealsize);
3814 }
3815 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_QUOTACONTROL,(status!=STATUS_OK)?5:89);
3816 put32bit(&ptr,msgid);
3817 if (status!=STATUS_OK) {
3818 put8bit(&ptr,status);
3819 } else {
3820 put8bit(&ptr,flags);
3821 put32bit(&ptr,sinodes);
3822 put64bit(&ptr,slength);
3823 put64bit(&ptr,ssize);
3824 put64bit(&ptr,srealsize);
3825 put32bit(&ptr,hinodes);
3826 put64bit(&ptr,hlength);
3827 put64bit(&ptr,hsize);
3828 put64bit(&ptr,hrealsize);
3829 put32bit(&ptr,curinodes);
3830 put64bit(&ptr,curlength);
3831 put64bit(&ptr,cursize);
3832 put64bit(&ptr,currealsize);
3833 }
3834 }
3835
3836 /*
3837 void matoclserv_fuse_eattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3838 uint8_t mode,eattr,fneattr;
3839 uint32_t msgid,inode,uid;
3840 uint8_t *ptr;
3841 uint8_t status;
3842 if (length!=14) {
3843 syslog(LOG_NOTICE,"CLTOMA_FUSE_EATTR - wrong size (%"PRIu32")",length);
3844 eptr->mode = KILL;
3845 return;
3846 }
3847 msgid = get32bit(&data);
3848 inode = get32bit(&data);
3849 uid = get32bit(&data);
3850 mode = get8bit(&data);
3851 eattr = get8bit(&data);
3852 status = fs_eattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,uid,mode,&eattr,&fneattr);
3853 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_EATTR,(status!=STATUS_OK)?5:6);
3854 put32bit(&ptr,msgid);
3855 if (status!=STATUS_OK) {
3856 put8bit(&ptr,status);
3857 } else {
3858 put8bit(&ptr,eattr);
3859 put8bit(&ptr,fneattr);
3860 }
3861 }
3862 */
3863
matoclserv_fuse_getdirstats_old(matoclserventry * eptr,const uint8_t * data,uint32_t length)3864 void matoclserv_fuse_getdirstats_old(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3865 uint32_t inode,inodes,files,dirs,chunks;
3866 uint64_t leng,size,rsize;
3867 uint32_t msgid;
3868 uint8_t *ptr;
3869 uint8_t status;
3870 if (length!=8) {
3871 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDIRSTATS - wrong size (%"PRIu32"/8)",length);
3872 eptr->mode = KILL;
3873 return;
3874 }
3875 msgid = get32bit(&data);
3876 inode = get32bit(&data);
3877 status = fs_get_dir_stats(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&inodes,&dirs,&files,&chunks,&leng,&size,&rsize);
3878 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDIRSTATS,(status!=STATUS_OK)?5:60);
3879 put32bit(&ptr,msgid);
3880 if (status!=STATUS_OK) {
3881 put8bit(&ptr,status);
3882 } else {
3883 put32bit(&ptr,inodes);
3884 put32bit(&ptr,dirs);
3885 put32bit(&ptr,files);
3886 put32bit(&ptr,0);
3887 put32bit(&ptr,0);
3888 put32bit(&ptr,chunks);
3889 put32bit(&ptr,0);
3890 put32bit(&ptr,0);
3891 put64bit(&ptr,leng);
3892 put64bit(&ptr,size);
3893 put64bit(&ptr,rsize);
3894 }
3895 }
3896
matoclserv_fuse_getdirstats(matoclserventry * eptr,const uint8_t * data,uint32_t length)3897 void matoclserv_fuse_getdirstats(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3898 uint32_t inode,inodes,files,dirs,chunks;
3899 uint64_t leng,size,rsize;
3900 uint32_t msgid;
3901 uint8_t *ptr;
3902 uint8_t status;
3903 if (length!=8) {
3904 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDIRSTATS - wrong size (%"PRIu32"/8)",length);
3905 eptr->mode = KILL;
3906 return;
3907 }
3908 msgid = get32bit(&data);
3909 inode = get32bit(&data);
3910 status = fs_get_dir_stats(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&inodes,&dirs,&files,&chunks,&leng,&size,&rsize);
3911 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDIRSTATS,(status!=STATUS_OK)?5:44);
3912 put32bit(&ptr,msgid);
3913 if (status!=STATUS_OK) {
3914 put8bit(&ptr,status);
3915 } else {
3916 put32bit(&ptr,inodes);
3917 put32bit(&ptr,dirs);
3918 put32bit(&ptr,files);
3919 put32bit(&ptr,chunks);
3920 put64bit(&ptr,leng);
3921 put64bit(&ptr,size);
3922 put64bit(&ptr,rsize);
3923 }
3924 }
3925
matoclserv_fuse_gettrash(matoclserventry * eptr,const uint8_t * data,uint32_t length)3926 void matoclserv_fuse_gettrash(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3927 uint32_t msgid;
3928 uint8_t *ptr;
3929 uint8_t status;
3930 uint32_t dleng;
3931 if (length!=4) {
3932 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASH - wrong size (%"PRIu32"/4)",length);
3933 eptr->mode = KILL;
3934 return;
3935 }
3936 msgid = get32bit(&data);
3937 status = fs_readtrash_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&dleng);
3938 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASH,(status!=STATUS_OK)?5:(4+dleng));
3939 put32bit(&ptr,msgid);
3940 if (status!=STATUS_OK) {
3941 put8bit(&ptr,status);
3942 } else {
3943 fs_readtrash_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),ptr);
3944 }
3945 }
3946
matoclserv_fuse_getdetachedattr(matoclserventry * eptr,const uint8_t * data,uint32_t length)3947 void matoclserv_fuse_getdetachedattr(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3948 uint32_t inode;
3949 uint8_t attr[35];
3950 uint32_t msgid;
3951 uint8_t dtype;
3952 uint8_t *ptr;
3953 uint8_t status;
3954 if (length<8 || length>9) {
3955 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETDETACHEDATTR - wrong size (%"PRIu32"/8,9)",length);
3956 eptr->mode = KILL;
3957 return;
3958 }
3959 msgid = get32bit(&data);
3960 inode = get32bit(&data);
3961 if (length==9) {
3962 dtype = get8bit(&data);
3963 } else {
3964 dtype = DTYPE_UNKNOWN;
3965 }
3966 status = fs_getdetachedattr(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,attr,dtype);
3967 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETDETACHEDATTR,(status!=STATUS_OK)?5:39);
3968 put32bit(&ptr,msgid);
3969 if (status!=STATUS_OK) {
3970 put8bit(&ptr,status);
3971 } else {
3972 memcpy(ptr,attr,35);
3973 }
3974 }
3975
matoclserv_fuse_gettrashpath(matoclserventry * eptr,const uint8_t * data,uint32_t length)3976 void matoclserv_fuse_gettrashpath(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
3977 uint32_t inode;
3978 uint32_t pleng;
3979 const uint8_t *path;
3980 uint32_t msgid;
3981 uint8_t *ptr;
3982 uint8_t status;
3983 if (length!=8) {
3984 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETTRASHPATH - wrong size (%"PRIu32"/8)",length);
3985 eptr->mode = KILL;
3986 return;
3987 }
3988 msgid = get32bit(&data);
3989 inode = get32bit(&data);
3990 status = fs_gettrashpath(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,&pleng,&path);
3991 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETTRASHPATH,(status!=STATUS_OK)?5:8+pleng+1);
3992 put32bit(&ptr,msgid);
3993 if (status!=STATUS_OK) {
3994 put8bit(&ptr,status);
3995 } else {
3996 put32bit(&ptr,pleng+1);
3997 if (pleng>0) {
3998 memcpy(ptr,path,pleng);
3999 }
4000 ptr[pleng]=0;
4001 }
4002 }
4003
matoclserv_fuse_settrashpath(matoclserventry * eptr,const uint8_t * data,uint32_t length)4004 void matoclserv_fuse_settrashpath(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4005 uint32_t inode;
4006 const uint8_t *path;
4007 uint32_t pleng;
4008 uint32_t msgid;
4009 uint8_t status;
4010 uint8_t *ptr;
4011 if (length<12) {
4012 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHPATH - wrong size (%"PRIu32"/>=12)",length);
4013 eptr->mode = KILL;
4014 return;
4015 }
4016 msgid = get32bit(&data);
4017 inode = get32bit(&data);
4018 pleng = get32bit(&data);
4019 if (length!=12+pleng) {
4020 syslog(LOG_NOTICE,"CLTOMA_FUSE_SETTRASHPATH - wrong size (%"PRIu32"/%"PRIu32")",length,12+pleng);
4021 eptr->mode = KILL;
4022 return;
4023 }
4024 path = data;
4025 data += pleng;
4026 while (pleng>0 && path[pleng-1]==0) {
4027 pleng--;
4028 }
4029 status = fs_settrashpath(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode,pleng,path);
4030 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_SETTRASHPATH,5);
4031 put32bit(&ptr,msgid);
4032 put8bit(&ptr,status);
4033 }
4034
matoclserv_fuse_undel(matoclserventry * eptr,const uint8_t * data,uint32_t length)4035 void matoclserv_fuse_undel(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4036 uint32_t inode;
4037 uint32_t msgid;
4038 uint8_t status;
4039 uint8_t *ptr;
4040 if (length!=8) {
4041 syslog(LOG_NOTICE,"CLTOMA_FUSE_UNDEL - wrong size (%"PRIu32"/8)",length);
4042 eptr->mode = KILL;
4043 return;
4044 }
4045 msgid = get32bit(&data);
4046 inode = get32bit(&data);
4047 status = fs_undel(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode);
4048 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_UNDEL,5);
4049 put32bit(&ptr,msgid);
4050 put8bit(&ptr,status);
4051 }
4052
matoclserv_fuse_purge(matoclserventry * eptr,const uint8_t * data,uint32_t length)4053 void matoclserv_fuse_purge(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4054 uint32_t inode;
4055 uint32_t msgid;
4056 uint8_t *ptr;
4057 uint8_t status;
4058 if (length!=8) {
4059 syslog(LOG_NOTICE,"CLTOMA_FUSE_PURGE - wrong size (%"PRIu32"/8)",length);
4060 eptr->mode = KILL;
4061 return;
4062 }
4063 msgid = get32bit(&data);
4064 inode = get32bit(&data);
4065 status = fs_purge(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),inode);
4066 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_PURGE,5);
4067 put32bit(&ptr,msgid);
4068 put8bit(&ptr,status);
4069 }
4070
4071
matoclserv_fuse_getsustained(matoclserventry * eptr,const uint8_t * data,uint32_t length)4072 void matoclserv_fuse_getsustained(matoclserventry *eptr,const uint8_t *data,uint32_t length) {
4073 uint32_t msgid;
4074 uint8_t *ptr;
4075 uint8_t status;
4076 uint32_t dleng;
4077 if (length!=4) {
4078 syslog(LOG_NOTICE,"CLTOMA_FUSE_GETSUSTAINED - wrong size (%"PRIu32"/4)",length);
4079 eptr->mode = KILL;
4080 return;
4081 }
4082 msgid = get32bit(&data);
4083 status = fs_readsustained_size(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),&dleng);
4084 ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_GETSUSTAINED,(status!=STATUS_OK)?5:(4+dleng));
4085 put32bit(&ptr,msgid);
4086 if (status!=STATUS_OK) {
4087 put8bit(&ptr,status);
4088 } else {
4089 fs_readsustained_data(sessions_get_rootinode(eptr->sesdata),sessions_get_sesflags(eptr->sesdata),ptr);
4090 }
4091 }
4092
4093
4094 /*
4095 void matocl_session_timedout(session *sesdata) {
4096 filelist *fl,*afl;
4097 fl=sesdata->openedfiles;
4098 while (fl) {
4099 afl = fl;
4100 fl=fl->next;
4101 fs_release(afl->inode,sesdata->sessionid);
4102 free(afl);
4103 }
4104 sesdata->openedfiles=NULL;
4105 if (sesdata->info) {
4106 free(sesdata->info);
4107 }
4108 }
4109
4110 void matocl_session_check(void) {
4111 session **sesdata,*asesdata;
4112 uint32_t now;
4113
4114 now = main_time();
4115 sesdata = &(sessionshead);
4116 while ((asesdata=*sesdata)) {
4117 // syslog(LOG_NOTICE,"session: %u ; nsocks: %u ; state: %u ; disconnected: %u",asesdata->sessionid,asesdata->nsocks,asesdata->newsession,asesdata->disconnected);
4118 if (asesdata->nsocks==0 && ((asesdata->newsession>1 && asesdata->disconnected<now) || (asesdata->newsession==1 && asesdata->disconnected+SessionSustainTime<now) || (asesdata->newsession==0 && asesdata->disconnected+120<now))) {
4119 syslog(LOG_NOTICE,"remove session: %u",asesdata->sessionid);
4120 matocl_session_timedout(asesdata);
4121 *sesdata = asesdata->next;
4122 free(asesdata);
4123 } else {
4124 sesdata = &(asesdata->next);
4125 }
4126 }
4127 // matoclserv_show_notification_dirs();
4128 }
4129
4130 void matocl_session_statsmove(void) {
4131 session *sesdata;
4132 for (sesdata = sessionshead ; sesdata ; sesdata=sesdata->next) {
4133 memcpy(sesdata->lasthouropstats,sesdata->currentopstats,4*SESSION_STATS);
4134 memset(sesdata->currentopstats,0,4*SESSION_STATS);
4135 }
4136 matoclserv_store_sessions();
4137 }
4138 */
matocl_beforedisconnect(matoclserventry * eptr)4139 void matocl_beforedisconnect(matoclserventry *eptr) {
4140 chunklist *cl,*acl;
4141 // unlock locked chunks
4142 cl=eptr->chunkdelayedops;
4143 while (cl) {
4144 acl = cl;
4145 cl=cl->next;
4146 if (acl->type == FUSE_TRUNCATE) {
4147 fs_end_setlength(acl->chunkid);
4148 }
4149 free(acl);
4150 }
4151 eptr->chunkdelayedops=NULL;
4152 sessions_disconnection(eptr->sesdata);
4153 /*
4154 if (eptr->sesdata) {
4155
4156 if (eptr->sesdata->nsocks>0) {
4157 eptr->sesdata->nsocks--;
4158 }
4159 if (eptr->sesdata->nsocks==0) {
4160 eptr->sesdata->disconnected = main_time();
4161 }
4162 }
4163 */
4164 /* CACHENOTIFY
4165 matoclserv_notify_disconnected(eptr);
4166 */
4167 }
4168
matoclserv_gotpacket(matoclserventry * eptr,uint32_t type,const uint8_t * data,uint32_t length)4169 void matoclserv_gotpacket(matoclserventry *eptr,uint32_t type,const uint8_t *data,uint32_t length) {
4170 if (type==ANTOAN_NOP) {
4171 return;
4172 }
4173 if (type==ANTOAN_UNKNOWN_COMMAND) { // for future use
4174 return;
4175 }
4176 if (type==ANTOAN_BAD_COMMAND_SIZE) { // for future use
4177 return;
4178 }
4179 // printf("AQQ\n");
4180 if (eptr->registered==0) { // unregistered clients - beware that in this context sesdata is NULL
4181 switch (type) {
4182 case ANTOAN_GET_VERSION:
4183 matoclserv_get_version(eptr,data,length);
4184 break;
4185 case CLTOMA_FUSE_REGISTER:
4186 // printf("REGISTER\n");
4187 matoclserv_fuse_register(eptr,data,length);
4188 break;
4189 case CLTOMA_CSERV_LIST:
4190 matoclserv_cserv_list(eptr,data,length);
4191 break;
4192 case CLTOMA_SESSION_LIST:
4193 matoclserv_session_list(eptr,data,length);
4194 break;
4195 case CLTOAN_CHART:
4196 matoclserv_chart(eptr,data,length);
4197 break;
4198 case CLTOAN_CHART_DATA:
4199 matoclserv_chart_data(eptr,data,length);
4200 break;
4201 case CLTOMA_INFO:
4202 matoclserv_info(eptr,data,length);
4203 break;
4204 case CLTOMA_FSTEST_INFO:
4205 matoclserv_fstest_info(eptr,data,length);
4206 break;
4207 case CLTOMA_CHUNKSTEST_INFO:
4208 matoclserv_chunkstest_info(eptr,data,length);
4209 break;
4210 case CLTOMA_CHUNKS_MATRIX:
4211 matoclserv_chunks_matrix(eptr,data,length);
4212 break;
4213 case CLTOMA_QUOTA_INFO:
4214 matoclserv_quota_info(eptr,data,length);
4215 break;
4216 case CLTOMA_EXPORTS_INFO:
4217 matoclserv_exports_info(eptr,data,length);
4218 break;
4219 case CLTOMA_MLOG_LIST:
4220 matoclserv_mlog_list(eptr,data,length);
4221 break;
4222 case CLTOMA_CSSERV_COMMAND:
4223 matoclserv_cserv_command(eptr,data,length);
4224 break;
4225 case CLTOMA_SESSION_COMMAND:
4226 matoclserv_session_command(eptr,data,length);
4227 break;
4228 case CLTOMA_MEMORY_INFO:
4229 matoclserv_memory_info(eptr,data,length);
4230 break;
4231 case CLTOAN_MODULE_INFO:
4232 matoclserv_module_info(eptr,data,length);
4233 break;
4234 case CLTOMA_MASS_RESOLVE_PATHS:
4235 matoclserv_mass_resolve_paths(eptr,data,length);
4236 break;
4237 case CLTOMA_MISSING_CHUNKS:
4238 matoclserv_missing_chunks(eptr,data,length);
4239 break;
4240 default:
4241 syslog(LOG_NOTICE,"main master server module: got unknown message from unregistered (type:%"PRIu32")",type);
4242 eptr->mode=KILL;
4243 }
4244 } else if (eptr->registered<100) { // mounts and new tools
4245 if (eptr->sesdata==NULL) {
4246 syslog(LOG_ERR,"registered connection without sesdata !!!");
4247 eptr->mode=KILL;
4248 return;
4249 }
4250 switch (type) {
4251 case ANTOAN_GET_VERSION:
4252 matoclserv_get_version(eptr,data,length);
4253 break;
4254 case CLTOMA_FUSE_REGISTER:
4255 matoclserv_fuse_register(eptr,data,length);
4256 break;
4257 case CLTOMA_FUSE_SUSTAINED_INODES:
4258 matoclserv_fuse_sustained_inodes(eptr,data,length);
4259 break;
4260 case CLTOMA_FUSE_STATFS:
4261 matoclserv_fuse_statfs(eptr,data,length);
4262 break;
4263 case CLTOMA_FUSE_ACCESS:
4264 matoclserv_fuse_access(eptr,data,length);
4265 break;
4266 case CLTOMA_FUSE_LOOKUP:
4267 matoclserv_fuse_lookup(eptr,data,length);
4268 break;
4269 case CLTOMA_FUSE_GETATTR:
4270 matoclserv_fuse_getattr(eptr,data,length);
4271 break;
4272 case CLTOMA_FUSE_SETATTR:
4273 matoclserv_fuse_setattr(eptr,data,length);
4274 break;
4275 case CLTOMA_FUSE_READLINK:
4276 matoclserv_fuse_readlink(eptr,data,length);
4277 break;
4278 case CLTOMA_FUSE_SYMLINK:
4279 matoclserv_fuse_symlink(eptr,data,length);
4280 break;
4281 case CLTOMA_FUSE_MKNOD:
4282 matoclserv_fuse_mknod(eptr,data,length);
4283 break;
4284 case CLTOMA_FUSE_MKDIR:
4285 matoclserv_fuse_mkdir(eptr,data,length);
4286 break;
4287 case CLTOMA_FUSE_UNLINK:
4288 matoclserv_fuse_unlink(eptr,data,length);
4289 break;
4290 case CLTOMA_FUSE_RMDIR:
4291 matoclserv_fuse_rmdir(eptr,data,length);
4292 break;
4293 case CLTOMA_FUSE_RENAME:
4294 matoclserv_fuse_rename(eptr,data,length);
4295 break;
4296 case CLTOMA_FUSE_LINK:
4297 matoclserv_fuse_link(eptr,data,length);
4298 break;
4299 case CLTOMA_FUSE_READDIR:
4300 matoclserv_fuse_readdir(eptr,data,length);
4301 break;
4302 /* CACHENOTIFY
4303 case CLTOMA_FUSE_DIR_REMOVED:
4304 matoclserv_fuse_dir_removed(eptr,data,length);
4305 break;
4306 */
4307 case CLTOMA_FUSE_OPEN:
4308 matoclserv_fuse_open(eptr,data,length);
4309 break;
4310 case CLTOMA_FUSE_CREATE:
4311 matoclserv_fuse_create(eptr,data,length);
4312 break;
4313 case CLTOMA_FUSE_READ_CHUNK:
4314 matoclserv_fuse_read_chunk(eptr,data,length);
4315 break;
4316 case CLTOMA_FUSE_WRITE_CHUNK:
4317 matoclserv_fuse_write_chunk(eptr,data,length);
4318 break;
4319 case CLTOMA_FUSE_WRITE_CHUNK_END:
4320 matoclserv_fuse_write_chunk_end(eptr,data,length);
4321 break;
4322 // fuse - meta
4323 case CLTOMA_FUSE_GETTRASH:
4324 matoclserv_fuse_gettrash(eptr,data,length);
4325 break;
4326 case CLTOMA_FUSE_GETDETACHEDATTR:
4327 matoclserv_fuse_getdetachedattr(eptr,data,length);
4328 break;
4329 case CLTOMA_FUSE_GETTRASHPATH:
4330 matoclserv_fuse_gettrashpath(eptr,data,length);
4331 break;
4332 case CLTOMA_FUSE_SETTRASHPATH:
4333 matoclserv_fuse_settrashpath(eptr,data,length);
4334 break;
4335 case CLTOMA_FUSE_UNDEL:
4336 matoclserv_fuse_undel(eptr,data,length);
4337 break;
4338 case CLTOMA_FUSE_PURGE:
4339 matoclserv_fuse_purge(eptr,data,length);
4340 break;
4341 case CLTOMA_FUSE_GETSUSTAINED:
4342 matoclserv_fuse_getsustained(eptr,data,length);
4343 break;
4344 case CLTOMA_FUSE_CHECK:
4345 matoclserv_fuse_check(eptr,data,length);
4346 break;
4347 case CLTOMA_FUSE_GETTRASHTIME:
4348 matoclserv_fuse_gettrashtime(eptr,data,length);
4349 break;
4350 case CLTOMA_FUSE_SETTRASHTIME:
4351 matoclserv_fuse_settrashtime(eptr,data,length);
4352 break;
4353 case CLTOMA_FUSE_GETGOAL:
4354 matoclserv_fuse_getgoal(eptr,data,length);
4355 break;
4356 case CLTOMA_FUSE_SETGOAL:
4357 matoclserv_fuse_setgoal(eptr,data,length);
4358 break;
4359 case CLTOMA_FUSE_APPEND:
4360 matoclserv_fuse_append(eptr,data,length);
4361 break;
4362 // case CLTOMA_FUSE_SETFILECHUNKS:
4363 // matoclserv_fuse_setfilechunks(eptr,data,length);
4364 // break;
4365 case CLTOMA_FUSE_GETDIRSTATS:
4366 matoclserv_fuse_getdirstats_old(eptr,data,length);
4367 break;
4368 case CLTOMA_FUSE_TRUNCATE:
4369 matoclserv_fuse_truncate(eptr,data,length);
4370 break;
4371 case CLTOMA_FUSE_REPAIR:
4372 matoclserv_fuse_repair(eptr,data,length);
4373 break;
4374 case CLTOMA_FUSE_SNAPSHOT:
4375 matoclserv_fuse_snapshot(eptr,data,length);
4376 break;
4377 case CLTOMA_FUSE_GETEATTR:
4378 matoclserv_fuse_geteattr(eptr,data,length);
4379 break;
4380 case CLTOMA_FUSE_SETEATTR:
4381 matoclserv_fuse_seteattr(eptr,data,length);
4382 break;
4383 case CLTOMA_FUSE_PARENTS:
4384 matoclserv_fuse_parents(eptr,data,length);
4385 break;
4386 case CLTOMA_FUSE_PATHS:
4387 matoclserv_fuse_paths(eptr,data,length);
4388 break;
4389 case CLTOMA_FUSE_GETXATTR:
4390 matoclserv_fuse_getxattr(eptr,data,length);
4391 break;
4392 case CLTOMA_FUSE_SETXATTR:
4393 matoclserv_fuse_setxattr(eptr,data,length);
4394 break;
4395 case CLTOMA_FUSE_GETACL:
4396 matoclserv_fuse_getacl(eptr,data,length);
4397 break;
4398 case CLTOMA_FUSE_SETACL:
4399 matoclserv_fuse_setacl(eptr,data,length);
4400 break;
4401 case CLTOMA_FUSE_QUOTACONTROL:
4402 matoclserv_fuse_quotacontrol(eptr,data,length);
4403 break;
4404
4405 /* for tools - also should be available for registered clients */
4406 case CLTOMA_CSERV_LIST:
4407 matoclserv_cserv_list(eptr,data,length);
4408 break;
4409 case CLTOMA_SESSION_LIST:
4410 matoclserv_session_list(eptr,data,length);
4411 break;
4412 case CLTOAN_CHART:
4413 matoclserv_chart(eptr,data,length);
4414 break;
4415 case CLTOAN_CHART_DATA:
4416 matoclserv_chart_data(eptr,data,length);
4417 break;
4418 case CLTOMA_INFO:
4419 matoclserv_info(eptr,data,length);
4420 break;
4421 case CLTOMA_FSTEST_INFO:
4422 matoclserv_fstest_info(eptr,data,length);
4423 break;
4424 case CLTOMA_CHUNKSTEST_INFO:
4425 matoclserv_chunkstest_info(eptr,data,length);
4426 break;
4427 case CLTOMA_CHUNKS_MATRIX:
4428 matoclserv_chunks_matrix(eptr,data,length);
4429 break;
4430 case CLTOMA_QUOTA_INFO:
4431 matoclserv_quota_info(eptr,data,length);
4432 break;
4433 case CLTOMA_EXPORTS_INFO:
4434 matoclserv_exports_info(eptr,data,length);
4435 break;
4436 case CLTOMA_MLOG_LIST:
4437 matoclserv_mlog_list(eptr,data,length);
4438 break;
4439 case CLTOMA_CSSERV_COMMAND:
4440 matoclserv_cserv_command(eptr,data,length);
4441 break;
4442 case CLTOMA_SESSION_COMMAND:
4443 matoclserv_session_command(eptr,data,length);
4444 break;
4445 case CLTOMA_MEMORY_INFO:
4446 matoclserv_memory_info(eptr,data,length);
4447 break;
4448 case CLTOAN_MODULE_INFO:
4449 matoclserv_module_info(eptr,data,length);
4450 break;
4451 case CLTOMA_MASS_RESOLVE_PATHS:
4452 matoclserv_mass_resolve_paths(eptr,data,length);
4453 break;
4454 case CLTOMA_MISSING_CHUNKS:
4455 matoclserv_missing_chunks(eptr,data,length);
4456 break;
4457 default:
4458 syslog(LOG_NOTICE,"main master server module: got unknown message from mfsmount (type:%"PRIu32")",type);
4459 eptr->mode=KILL;
4460 }
4461 } else { // old mfstools
4462 if (eptr->sesdata==NULL) {
4463 syslog(LOG_ERR,"registered connection (tools) without sesdata !!!");
4464 eptr->mode=KILL;
4465 return;
4466 }
4467 switch (type) {
4468 // extra (external tools)
4469 case ANTOAN_GET_VERSION:
4470 matoclserv_get_version(eptr,data,length);
4471 break;
4472 case CLTOMA_FUSE_REGISTER:
4473 matoclserv_fuse_register(eptr,data,length);
4474 break;
4475 case CLTOMA_FUSE_READ_CHUNK: // used in mfsfileinfo
4476 matoclserv_fuse_read_chunk(eptr,data,length);
4477 break;
4478 case CLTOMA_FUSE_CHECK:
4479 matoclserv_fuse_check(eptr,data,length);
4480 break;
4481 case CLTOMA_FUSE_GETTRASHTIME:
4482 matoclserv_fuse_gettrashtime(eptr,data,length);
4483 break;
4484 case CLTOMA_FUSE_SETTRASHTIME:
4485 matoclserv_fuse_settrashtime(eptr,data,length);
4486 break;
4487 case CLTOMA_FUSE_GETGOAL:
4488 matoclserv_fuse_getgoal(eptr,data,length);
4489 break;
4490 case CLTOMA_FUSE_SETGOAL:
4491 matoclserv_fuse_setgoal(eptr,data,length);
4492 break;
4493 case CLTOMA_FUSE_APPEND:
4494 matoclserv_fuse_append(eptr,data,length);
4495 break;
4496 // case CLTOMA_FUSE_SETFILECHUNKS:
4497 // matoclserv_fuse_setfilechunks(eptr,data,length);
4498 // break;
4499 case CLTOMA_FUSE_GETDIRSTATS:
4500 matoclserv_fuse_getdirstats(eptr,data,length);
4501 break;
4502 case CLTOMA_FUSE_TRUNCATE:
4503 matoclserv_fuse_truncate(eptr,data,length);
4504 break;
4505 case CLTOMA_FUSE_REPAIR:
4506 matoclserv_fuse_repair(eptr,data,length);
4507 break;
4508 case CLTOMA_FUSE_SNAPSHOT:
4509 matoclserv_fuse_snapshot(eptr,data,length);
4510 break;
4511 case CLTOMA_FUSE_GETEATTR:
4512 matoclserv_fuse_geteattr(eptr,data,length);
4513 break;
4514 case CLTOMA_FUSE_SETEATTR:
4515 matoclserv_fuse_seteattr(eptr,data,length);
4516 break;
4517 /* do not use in version before 1.7.x */
4518 case CLTOMA_FUSE_QUOTACONTROL:
4519 matoclserv_fuse_quotacontrol(eptr,data,length);
4520 break;
4521 /* ------ */
4522 default:
4523 syslog(LOG_NOTICE,"main master server module: got unknown message from mfstools (type:%"PRIu32")",type);
4524 eptr->mode=KILL;
4525 }
4526 }
4527 }
4528
matoclserv_read(matoclserventry * eptr,double now)4529 void matoclserv_read(matoclserventry *eptr,double now) {
4530 int32_t i;
4531 uint32_t type,leng;
4532 const uint8_t *ptr;
4533 uint32_t rbleng,rbpos;
4534 uint8_t err,hup,errmsg;
4535 static uint8_t *readbuff = NULL;
4536 static uint32_t readbuffsize = 0;
4537
4538 if (eptr == NULL) {
4539 if (readbuff != NULL) {
4540 free(readbuff);
4541 }
4542 readbuff = NULL;
4543 readbuffsize = 0;
4544 return;
4545 }
4546
4547 if (readbuffsize==0) {
4548 readbuffsize = 65536;
4549 readbuff = malloc(readbuffsize);
4550 passert(readbuff);
4551 }
4552
4553 rbleng = 0;
4554 err = 0;
4555 hup = 0;
4556 errmsg = 0;
4557 for (;;) {
4558 i = read(eptr->sock,readbuff+rbleng,readbuffsize-rbleng);
4559 if (i==0) {
4560 hup = 1;
4561 break;
4562 } else if (i<0) {
4563 if (ERRNO_ERROR) {
4564 err = 1;
4565 #ifdef ECONNRESET
4566 if (errno!=ECONNRESET || eptr->registered<100) {
4567 #endif
4568 errmsg = 1;
4569 #ifdef ECONNRESET
4570 }
4571 #endif
4572 }
4573 break;
4574 } else {
4575 stats_brcvd += i;
4576 rbleng += i;
4577 if (rbleng==readbuffsize) {
4578 readbuffsize*=2;
4579 readbuff = realloc(readbuff,readbuffsize);
4580 passert(readbuff);
4581 } else {
4582 break;
4583 }
4584 }
4585 }
4586
4587 if (rbleng>0) {
4588 eptr->lastread = now;
4589 }
4590
4591 rbpos = 0;
4592 while (rbpos<rbleng) {
4593 if ((rbleng-rbpos)>=eptr->input_bytesleft) {
4594 memcpy(eptr->input_startptr,readbuff+rbpos,eptr->input_bytesleft);
4595 i = eptr->input_bytesleft;
4596 } else {
4597 memcpy(eptr->input_startptr,readbuff+rbpos,rbleng-rbpos);
4598 i = rbleng-rbpos;
4599 }
4600 rbpos += i;
4601 eptr->input_startptr+=i;
4602 eptr->input_bytesleft-=i;
4603
4604 if (eptr->input_bytesleft>0) {
4605 break;
4606 }
4607
4608 if (eptr->input_packet == NULL) {
4609 ptr = eptr->input_hdr;
4610 type = get32bit(&ptr);
4611 leng = get32bit(&ptr);
4612
4613 if (leng>MaxPacketSize) {
4614 syslog(LOG_WARNING,"main master server module: packet too long (%"PRIu32"/%u)",leng,MaxPacketSize);
4615 eptr->input_end = 1;
4616 return;
4617 }
4618
4619 stats_prcvd++;
4620 eptr->input_packet = malloc(offsetof(in_packetstruct,data)+leng);
4621 passert(eptr->input_packet);
4622 eptr->input_packet->next = NULL;
4623 eptr->input_packet->type = type;
4624 eptr->input_packet->leng = leng;
4625
4626 eptr->input_startptr = eptr->input_packet->data;
4627 eptr->input_bytesleft = leng;
4628 }
4629
4630 if (eptr->input_bytesleft>0) {
4631 continue;
4632 }
4633
4634 if (eptr->input_packet != NULL) {
4635 *(eptr->inputtail) = eptr->input_packet;
4636 eptr->inputtail = &(eptr->input_packet->next);
4637 eptr->input_packet = NULL;
4638 eptr->input_bytesleft = 8;
4639 eptr->input_startptr = eptr->input_hdr;
4640 }
4641 }
4642
4643 if (hup) {
4644 if (eptr->registered>0 && eptr->registered<100) { // show this message only for standard, registered clients
4645 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);
4646 }
4647 eptr->input_end = 1;
4648 } else if (err) {
4649 if (errmsg) {
4650 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);
4651 }
4652 eptr->input_end = 1;
4653 }
4654 }
4655
matoclserv_parse(matoclserventry * eptr)4656 void matoclserv_parse(matoclserventry *eptr) {
4657 in_packetstruct *ipack;
4658 uint64_t starttime;
4659 uint64_t currtime;
4660
4661 starttime = monotonic_useconds();
4662 currtime = starttime;
4663 while (eptr->mode==DATA && (ipack = eptr->inputhead)!=NULL && starttime+10000>currtime) {
4664 matoclserv_gotpacket(eptr,ipack->type,ipack->data,ipack->leng);
4665 eptr->inputhead = ipack->next;
4666 free(ipack);
4667 if (eptr->inputhead==NULL) {
4668 eptr->inputtail = &(eptr->inputhead);
4669 } else {
4670 currtime = monotonic_useconds();
4671 }
4672 }
4673 if (eptr->mode==DATA && eptr->inputhead==NULL && eptr->input_end) {
4674 eptr->mode = KILL;
4675 }
4676 }
4677
matoclserv_write(matoclserventry * eptr,double now)4678 void matoclserv_write(matoclserventry *eptr,double now) {
4679 out_packetstruct *opack;
4680 int32_t i;
4681 #ifdef HAVE_WRITEV
4682 struct iovec iovtab[100];
4683 uint32_t iovdata;
4684 uint32_t leng;
4685 uint32_t left;
4686
4687 for (;;) {
4688 leng = 0;
4689 for (iovdata=0,opack=eptr->outputhead ; iovdata<100 && opack!=NULL ; iovdata++,opack=opack->next) {
4690 iovtab[iovdata].iov_base = opack->startptr;
4691 iovtab[iovdata].iov_len = opack->bytesleft;
4692 leng += opack->bytesleft;
4693 }
4694 if (iovdata==0) {
4695 return;
4696 }
4697 i = writev(eptr->sock,iovtab,iovdata);
4698 if (i<0) {
4699 if (ERRNO_ERROR) {
4700 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);
4701 eptr->mode = KILL;
4702 }
4703 return;
4704 }
4705 if (i>0) {
4706 eptr->lastwrite = now;
4707 }
4708 stats_bsent+=i;
4709 left = i;
4710 while (left>0 && eptr->outputhead!=NULL) {
4711 opack = eptr->outputhead;
4712 if (opack->bytesleft>left) {
4713 opack->startptr+=left;
4714 opack->bytesleft-=left;
4715 left = 0;
4716 } else {
4717 left -= opack->bytesleft;
4718 eptr->outputhead = opack->next;
4719 if (eptr->outputhead==NULL) {
4720 eptr->outputtail = &(eptr->outputhead);
4721 }
4722 free(opack);
4723 stats_psent++;
4724 }
4725 }
4726 if ((uint32_t)i < leng) {
4727 return;
4728 }
4729 }
4730 #else
4731 for (;;) {
4732 opack = eptr->outputhead;
4733 if (opack==NULL) {
4734 return;
4735 }
4736 i=write(eptr->sock,opack->startptr,opack->bytesleft);
4737 if (i<0) {
4738 if (ERRNO_ERROR) {
4739 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);
4740 eptr->mode = KILL;
4741 }
4742 return;
4743 }
4744 if (i>0) {
4745 eptr->lastwrite = now;
4746 }
4747 opack->startptr+=i;
4748 opack->bytesleft-=i;
4749 stats_bsent+=i;
4750 if (opack->bytesleft>0) {
4751 return;
4752 }
4753 stats_psent++;
4754 eptr->outputhead = opack->next;
4755 if (eptr->outputhead==NULL) {
4756 eptr->outputtail = &(eptr->outputhead);
4757 }
4758 free(opack);
4759 }
4760 #endif
4761 }
4762
matoclserv_desc(struct pollfd * pdesc,uint32_t * ndesc)4763 void matoclserv_desc(struct pollfd *pdesc,uint32_t *ndesc) {
4764 uint32_t pos = *ndesc;
4765 matoclserventry *eptr;
4766
4767 pdesc[pos].fd = lsock;
4768 pdesc[pos].events = POLLIN;
4769 lsockpdescpos = pos;
4770 pos++;
4771 // FD_SET(lsock,rset);
4772 // max = lsock;
4773 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4774 pdesc[pos].fd = eptr->sock;
4775 pdesc[pos].events = 0;
4776 eptr->pdescpos = pos;
4777 // i=eptr->sock;
4778 pdesc[pos].events |= POLLIN;
4779 // FD_SET(i,rset);
4780 // if (i>max) {
4781 // max=i;
4782 // }
4783 if (eptr->outputhead!=NULL) {
4784 pdesc[pos].events |= POLLOUT;
4785 // FD_SET(i,wset);
4786 // if (i>max) {
4787 // max=i;
4788 // }
4789 }
4790 pos++;
4791 }
4792 *ndesc = pos;
4793 // return max;
4794 }
4795
matoclserv_disconnection_loop(void)4796 void matoclserv_disconnection_loop(void) {
4797 matoclserventry *eptr,**kptr;
4798 in_packetstruct *ipptr,*ipaptr;
4799 out_packetstruct *opptr,*opaptr;
4800
4801 kptr = &matoclservhead;
4802 while ((eptr=*kptr)) {
4803 if (eptr->mode == KILL) {
4804 matocl_beforedisconnect(eptr);
4805 tcpclose(eptr->sock);
4806 if (eptr->input_packet) {
4807 free(eptr->input_packet);
4808 }
4809 ipptr = eptr->inputhead;
4810 while (ipptr) {
4811 ipaptr = ipptr;
4812 ipptr = ipptr->next;
4813 free(ipaptr);
4814 }
4815 opptr = eptr->outputhead;
4816 while (opptr) {
4817 opaptr = opptr;
4818 opptr = opptr->next;
4819 free(opaptr);
4820 }
4821 *kptr = eptr->next;
4822 free(eptr);
4823 } else {
4824 kptr = &(eptr->next);
4825 }
4826 }
4827 }
4828
matoclserv_serve(struct pollfd * pdesc)4829 void matoclserv_serve(struct pollfd *pdesc) {
4830 double now;
4831 matoclserventry *eptr;
4832 int ns;
4833 static double lastaction = 0.0;
4834 double timeoutadd;
4835
4836 now = monotonic_seconds();
4837 // timeout fix
4838 if (lastaction>0.0) {
4839 timeoutadd = now-lastaction;
4840 if (timeoutadd>1.0) {
4841 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4842 eptr->lastread += timeoutadd;
4843 }
4844 }
4845 }
4846 lastaction = now;
4847
4848 if (lsockpdescpos>=0 && (pdesc[lsockpdescpos].revents & POLLIN)) {
4849 // if (FD_ISSET(lsock,rset)) {
4850 ns=tcpaccept(lsock);
4851 if (ns<0) {
4852 mfs_errlog_silent(LOG_NOTICE,"main master server module: accept error");
4853 } else {
4854 tcpnonblock(ns);
4855 tcpnodelay(ns);
4856 eptr = malloc(sizeof(matoclserventry));
4857 passert(eptr);
4858 eptr->next = matoclservhead;
4859 matoclservhead = eptr;
4860 eptr->sock = ns;
4861 eptr->pdescpos = -1;
4862 tcpgetpeer(ns,&(eptr->peerip),NULL);
4863 eptr->registered = 0;
4864 /* CACHENOTIFY
4865 eptr->notifications = 0;
4866 */
4867 eptr->version = 0;
4868 eptr->mode = DATA;
4869 eptr->lastread = now;
4870 eptr->lastwrite = now;
4871 eptr->input_bytesleft = 8;
4872 eptr->input_startptr = eptr->input_hdr;
4873 eptr->input_end = 0;
4874 eptr->input_packet = NULL;
4875 eptr->inputhead = NULL;
4876 eptr->inputtail = &(eptr->inputhead);
4877 eptr->outputhead = NULL;
4878 eptr->outputtail = &(eptr->outputhead);
4879
4880 eptr->chunkdelayedops = NULL;
4881 eptr->sesdata = NULL;
4882 /* CACHENOTIFY
4883 eptr->cacheddirs = NULL;
4884 */
4885 memset(eptr->passwordrnd,0,32);
4886 // eptr->openedfiles = NULL;
4887 }
4888 }
4889
4890 // read
4891 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4892 if (eptr->pdescpos>=0) {
4893 if ((pdesc[eptr->pdescpos].revents & (POLLERR|POLLIN))==POLLIN && eptr->mode!=KILL) {
4894 matoclserv_read(eptr,now);
4895 }
4896 if (pdesc[eptr->pdescpos].revents & (POLLERR|POLLHUP)) {
4897 eptr->input_end = 1;
4898 }
4899 }
4900 matoclserv_parse(eptr);
4901 }
4902
4903 // write
4904 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4905 if (eptr->lastwrite+1.0<now && eptr->registered<100 && eptr->outputhead==NULL) {
4906 uint8_t *ptr = matoclserv_createpacket(eptr,ANTOAN_NOP,4); // 4 byte length because of 'msgid'
4907 *((uint32_t*)ptr) = 0;
4908 }
4909 if (eptr->pdescpos>=0) {
4910 /* CACHENOTIFY
4911 if (eptr->notifications) {
4912 if (eptr->version>=VERSION2INT(1,6,22)) {
4913 uint8_t *ptr = matoclserv_createpacket(eptr,MATOCL_FUSE_NOTIFY_END,4); // transaction end
4914 *((uint32_t*)ptr) = 0;
4915 }
4916 eptr->notifications = 0;
4917 }
4918 */
4919 if ((((pdesc[eptr->pdescpos].events & POLLOUT)==0 && (eptr->outputhead)) || (pdesc[eptr->pdescpos].revents & POLLOUT)) && eptr->mode!=KILL) {
4920 matoclserv_write(eptr,now);
4921 }
4922 }
4923 if (eptr->lastread+10.0<now) {
4924 eptr->mode = KILL;
4925 }
4926 if (eptr->mode==FINISH && eptr->outputhead==NULL) {
4927 eptr->mode = KILL;
4928 }
4929 }
4930
4931 matoclserv_disconnection_loop();
4932 }
4933
matoclserv_keep_alive(void)4934 void matoclserv_keep_alive(void) {
4935 double now;
4936 matoclserventry *eptr;
4937
4938 now = monotonic_seconds();
4939 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4940 if (eptr->mode == DATA && eptr->input_end==0) {
4941 matoclserv_read(eptr,now);
4942 }
4943 }
4944 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
4945 if (eptr->lastwrite+1.0<now && eptr->registered<100 && eptr->outputhead==NULL) {
4946 uint8_t *ptr = matoclserv_createpacket(eptr,ANTOAN_NOP,4); // 4 byte length because of 'msgid'
4947 *((uint32_t*)ptr) = 0;
4948 }
4949 if (eptr->mode == DATA && eptr->outputhead) {
4950 matoclserv_write(eptr,now);
4951 }
4952 }
4953 }
4954
matoclserv_term(void)4955 void matoclserv_term(void) {
4956 matoclserventry *eptr,*eaptr;
4957 in_packetstruct *ipptr,*ipaptr;
4958 out_packetstruct *opptr,*opaptr;
4959 chunklist *cl,*cln;
4960 // session *ss,*ssn;
4961 // filelist *of,*ofn;
4962
4963 syslog(LOG_NOTICE,"main master server module: closing %s:%s",ListenHost,ListenPort);
4964 tcpclose(lsock);
4965
4966 eptr = matoclservhead;
4967 while (eptr) {
4968 if (eptr->input_packet) {
4969 free(eptr->input_packet);
4970 }
4971 ipptr = eptr->inputhead;
4972 while (ipptr) {
4973 ipaptr = ipptr;
4974 ipptr = ipptr->next;
4975 free(ipaptr);
4976 }
4977 opptr = eptr->outputhead;
4978 while (opptr) {
4979 opaptr = opptr;
4980 opptr = opptr->next;
4981 free(opaptr);
4982 }
4983 for (cl = eptr->chunkdelayedops ; cl ; cl = cln) {
4984 cln = cl->next;
4985 free(cl);
4986 }
4987 eaptr = eptr;
4988 eptr = eptr->next;
4989 free(eaptr);
4990 }
4991 matoclservhead=NULL;
4992
4993 matoclserv_read(NULL,0.0); // free internal read buffer
4994 matoclserv_gid_storage(0); // free supplementary groups buffer
4995
4996 free(ListenHost);
4997 free(ListenPort);
4998 }
4999
matoclserv_no_more_pending_jobs(void)5000 int matoclserv_no_more_pending_jobs(void) {
5001 matoclserventry *eptr;
5002 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5003 if (eptr->outputhead!=NULL) {
5004 return 0;
5005 }
5006 if (eptr->chunkdelayedops!=NULL) {
5007 return 0;
5008 }
5009 }
5010 return 1;
5011 }
5012
matoclserv_disconnect_all(void)5013 void matoclserv_disconnect_all(void) {
5014 matoclserventry *eptr;
5015 for (eptr=matoclservhead ; eptr ; eptr=eptr->next) {
5016 eptr->mode = KILL;
5017 }
5018 matoclserv_disconnection_loop();
5019 }
5020
matoclserv_start_cond_check(void)5021 void matoclserv_start_cond_check(void) {
5022 if (starting) {
5023 // very simple condition checking if all chunkservers have been connected
5024 // in the future master will know his chunkservers list and then this condition will be changed
5025 if (chunk_get_missing_count()<100) {
5026 starting=0;
5027 } else {
5028 starting--;
5029 }
5030 }
5031 }
5032
5033 /*
5034 int matoclserv_sessionsinit(void) {
5035 fprintf(stderr,"loading sessions ... ");
5036 fflush(stderr);
5037 sessionshead = NULL;
5038 switch (matoclserv_load_sessions()) {
5039 case 0: // no file
5040 fprintf(stderr,"file not found\n");
5041 fprintf(stderr,"if it is not fresh installation then you have to restart all active mounts !!!\n");
5042 matoclserv_store_sessions();
5043 break;
5044 case 1: // file loaded
5045 fprintf(stderr,"ok\n");
5046 fprintf(stderr,"sessions file has been loaded\n");
5047 break;
5048 default:
5049 fprintf(stderr,"error\n");
5050 fprintf(stderr,"due to missing sessions you have to restart all active mounts !!!\n");
5051 break;
5052 }
5053 SessionSustainTime = cfg_getuint32("SESSION_SUSTAIN_TIME",86400);
5054 if (SessionSustainTime>7*86400) {
5055 SessionSustainTime=7*86400;
5056 mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too big (more than week) - setting this value to one week");
5057 }
5058 if (SessionSustainTime<60) {
5059 SessionSustainTime=60;
5060 mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too low (less than minute) - setting this value to one minute");
5061 }
5062 return 0;
5063 }
5064 */
5065
matoclserv_reload(void)5066 void matoclserv_reload(void) {
5067 char *oldListenHost,*oldListenPort;
5068 int newlsock;
5069 /*
5070 SessionSustainTime = cfg_getuint32("SESSION_SUSTAIN_TIME",86400);
5071 if (SessionSustainTime>7*86400) {
5072 SessionSustainTime=7*86400;
5073 mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too big (more than week) - setting this value to one week");
5074 }
5075 if (SessionSustainTime<60) {
5076 SessionSustainTime=60;
5077 mfs_syslog(LOG_WARNING,"SESSION_SUSTAIN_TIME too low (less than minute) - setting this value to one minute");
5078 }
5079 */
5080 oldListenHost = ListenHost;
5081 oldListenPort = ListenPort;
5082 if (cfg_isdefined("MATOCL_LISTEN_HOST") || cfg_isdefined("MATOCL_LISTEN_PORT") || !(cfg_isdefined("MATOCU_LISTEN_HOST") || cfg_isdefined("MATOCU_LISTEN_HOST"))) {
5083 ListenHost = cfg_getstr("MATOCL_LISTEN_HOST","*");
5084 ListenPort = cfg_getstr("MATOCL_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT);
5085 } else {
5086 ListenHost = cfg_getstr("MATOCU_LISTEN_HOST","*"); // deprecated option
5087 ListenPort = cfg_getstr("MATOCU_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT); // deprecated option
5088 }
5089 if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) {
5090 free(oldListenHost);
5091 free(oldListenPort);
5092 mfs_arg_syslog(LOG_NOTICE,"main master server module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort);
5093 return;
5094 }
5095
5096 newlsock = tcpsocket();
5097 if (newlsock<0) {
5098 mfs_errlog(LOG_WARNING,"main master server module: socket address has changed, but can't create new socket");
5099 free(ListenHost);
5100 free(ListenPort);
5101 ListenHost = oldListenHost;
5102 ListenPort = oldListenPort;
5103 return;
5104 }
5105 tcpnonblock(newlsock);
5106 tcpnodelay(newlsock);
5107 tcpreuseaddr(newlsock);
5108 if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) {
5109 mfs_arg_errlog(LOG_ERR,"main master server module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort);
5110 free(ListenHost);
5111 free(ListenPort);
5112 ListenHost = oldListenHost;
5113 ListenPort = oldListenPort;
5114 tcpclose(newlsock);
5115 return;
5116 }
5117 if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) {
5118 mfs_errlog_silent(LOG_NOTICE,"main master server module: can't set accept filter");
5119 }
5120 mfs_arg_syslog(LOG_NOTICE,"main master server module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort);
5121 free(oldListenHost);
5122 free(oldListenPort);
5123 tcpclose(lsock);
5124 lsock = newlsock;
5125 }
5126
matoclserv_init(void)5127 int matoclserv_init(void) {
5128 if (cfg_isdefined("MATOCL_LISTEN_HOST") || cfg_isdefined("MATOCL_LISTEN_PORT") || !(cfg_isdefined("MATOCU_LISTEN_HOST") || cfg_isdefined("MATOCU_LISTEN_HOST"))) {
5129 ListenHost = cfg_getstr("MATOCL_LISTEN_HOST","*");
5130 ListenPort = cfg_getstr("MATOCL_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT);
5131 } else {
5132 fprintf(stderr,"change MATOCU_LISTEN_* option names to MATOCL_LISTEN_* !!!\n");
5133 ListenHost = cfg_getstr("MATOCU_LISTEN_HOST","*"); // deprecated option
5134 ListenPort = cfg_getstr("MATOCU_LISTEN_PORT",DEFAULT_MASTER_CLIENT_PORT); // deprecated option
5135 }
5136
5137 starting = 12;
5138 lsock = tcpsocket();
5139 if (lsock<0) {
5140 mfs_errlog(LOG_ERR,"main master server module: can't create socket");
5141 return -1;
5142 }
5143 tcpnonblock(lsock);
5144 tcpnodelay(lsock);
5145 tcpreuseaddr(lsock);
5146 if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) {
5147 mfs_arg_errlog(LOG_ERR,"main master server module: can't listen on %s:%s",ListenHost,ListenPort);
5148 return -1;
5149 }
5150 if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) {
5151 mfs_errlog_silent(LOG_NOTICE,"main master server module: can't set accept filter");
5152 }
5153 mfs_arg_syslog(LOG_NOTICE,"main master server module: listen on %s:%s",ListenHost,ListenPort);
5154
5155 matoclservhead = NULL;
5156 /* CACHENOTIFY
5157 matoclserv_dircache_init();
5158 */
5159
5160 main_time_register(10,0,matoclserv_start_cond_check);
5161 // main_time_register(10,0,matocl_session_check);
5162 // main_time_register(3600,0,matocl_session_statsmove);
5163 main_reload_register(matoclserv_reload);
5164 main_destruct_register(matoclserv_term);
5165 main_poll_register(matoclserv_desc,matoclserv_serve);
5166 main_keepalive_register(matoclserv_keep_alive);
5167 // main_wantexit_register(matoclserv_wantexit);
5168 // main_canexit_register(matoclserv_canexit);
5169 return 0;
5170 }
5171