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 #define MMAP_ALLOC 1
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/poll.h>
32 #include <syslog.h>
33 #include <time.h>
34 #include <limits.h>
35 #include <errno.h>
36 #include <pthread.h>
37 #ifdef MMAP_ALLOC
38 #include <sys/types.h>
39 #include <sys/mman.h>
40 #endif
41 #include <pwd.h>
42 #include <grp.h>
43
44 #include "MFSCommunication.h"
45 #include "stats.h"
46 #include "sockets.h"
47 #include "strerr.h"
48 #include "md5.h"
49 #include "datapack.h"
50 // #include "dircache.h"
51
52 #define CONNECT_TIMEOUT 2000
53
54 typedef struct _threc {
55 pthread_t thid;
56 pthread_mutex_t mutex;
57 pthread_cond_t cond;
58 uint8_t *obuff;
59 uint32_t obuffsize;
60 uint32_t odataleng;
61 uint8_t *ibuff;
62 uint32_t ibuffsize;
63 uint32_t idataleng;
64
65 uint8_t sent; // packet was sent
66 uint8_t status; // receive status
67 uint8_t rcvd; // packet was received
68 uint8_t waiting; // thread is waiting for answer
69
70 uint32_t rcvd_cmd;
71
72 uint32_t packetid; // thread number
73 struct _threc *next;
74 } threc;
75
76 /*
77 typedef struct _threc {
78 pthread_t thid;
79 pthread_mutex_t mutex;
80 pthread_cond_t cond;
81 uint8_t *buff;
82 uint32_t buffsize;
83 uint8_t sent;
84 uint8_t status;
85 uint8_t release; // cond variable
86 uint8_t waiting;
87 uint32_t size;
88 uint32_t cmd;
89 uint32_t packetid;
90 struct _threc *next;
91 } threc;
92 */
93
94
95 typedef struct _acquired_file {
96 uint32_t inode;
97 unsigned cnt:31; // open/close count
98 unsigned dentry:1; // inode exists in dentry cache (can't be removed/reused)
99 struct _acquired_file *next;
100 } acquired_file;
101
102 #define DEFAULT_OUTPUT_BUFFSIZE 0x1000
103 #define DEFAULT_INPUT_BUFFSIZE 0x10000
104
105 #define RECEIVE_TIMEOUT 10
106
107 static threc *threchead=NULL;
108
109 static acquired_file *afhead=NULL;
110
111 static int fd;
112 static int disconnect;
113 static int donotsendsustainedinodes;
114 static time_t lastwrite;
115 static int sessionlost;
116
117 static uint32_t maxretries;
118
119 static pthread_t rpthid,npthid;
120 static pthread_mutex_t fdlock,reclock,aflock;
121
122 static uint32_t sessionid;
123 static uint32_t masterversion;
124
125 static char masterstrip[17];
126 static uint32_t masterip=0;
127 static uint16_t masterport=0;
128 static char srcstrip[17];
129 static uint32_t srcip=0;
130
131 static uint8_t fterm;
132
fs_getmasterlocation(uint8_t loc[14])133 void fs_getmasterlocation(uint8_t loc[14]) {
134 pthread_mutex_lock(&fdlock);
135 put32bit(&loc,masterip);
136 put16bit(&loc,masterport);
137 put32bit(&loc,sessionid);
138 put32bit(&loc,masterversion);
139 pthread_mutex_unlock(&fdlock);
140 }
141
master_version(void)142 uint32_t master_version(void) {
143 uint32_t mver;
144 pthread_mutex_lock(&fdlock);
145 mver = masterversion;
146 pthread_mutex_unlock(&fdlock);
147 return mver;
148 }
149
fs_getsrcip()150 uint32_t fs_getsrcip() {
151 uint32_t sip;
152 pthread_mutex_lock(&fdlock);
153 sip = srcip;
154 pthread_mutex_unlock(&fdlock);
155 return sip;
156 }
157
158 enum {
159 MASTER_CONNECTS = 0,
160 MASTER_BYTESSENT,
161 MASTER_BYTESRCVD,
162 MASTER_PACKETSSENT,
163 MASTER_PACKETSRCVD,
164 STATNODES
165 };
166
167 static void *statsptr[STATNODES];
168
169 struct connect_args_t {
170 char *bindhostname;
171 char *masterhostname;
172 char *masterportname;
173 uint8_t meta;
174 uint8_t clearpassword;
175 char *info;
176 char *subfolder;
177 uint8_t *passworddigest;
178 };
179
180 static struct connect_args_t connect_args;
181
master_statsptr_init(void)182 void master_statsptr_init(void) {
183 void *s;
184 s = stats_get_subnode(NULL,"master",0,0);
185 statsptr[MASTER_PACKETSRCVD] = stats_get_subnode(s,"packets_received",0,1);
186 statsptr[MASTER_PACKETSSENT] = stats_get_subnode(s,"packets_sent",0,1);
187 statsptr[MASTER_BYTESRCVD] = stats_get_subnode(s,"bytes_received",0,1);
188 statsptr[MASTER_BYTESSENT] = stats_get_subnode(s,"bytes_sent",0,1);
189 statsptr[MASTER_CONNECTS] = stats_get_subnode(s,"reconnects",0,1);
190 }
191
master_stats_inc(uint8_t id)192 void master_stats_inc(uint8_t id) {
193 if (id<STATNODES) {
194 stats_counter_inc(statsptr[id]);
195 }
196 }
197
master_stats_add(uint8_t id,uint64_t s)198 void master_stats_add(uint8_t id,uint64_t s) {
199 if (id<STATNODES) {
200 stats_counter_add(statsptr[id],s);
201 }
202 }
203
204 const char* errtab[]={ERROR_STRINGS};
205
mfs_strerror(uint8_t status)206 static inline const char* mfs_strerror(uint8_t status) {
207 if (status>ERROR_MAX) {
208 status=ERROR_MAX;
209 }
210 return errtab[status];
211 }
212
fs_add_entry(uint32_t inode)213 void fs_add_entry(uint32_t inode) {
214 acquired_file *afptr,**afpptr;
215 pthread_mutex_lock(&aflock);
216 afpptr = &afhead;
217 while ((afptr=*afpptr)) {
218 if (afptr->inode == inode) {
219 afptr->dentry = 1;
220 pthread_mutex_unlock(&aflock);
221 return;
222 }
223 if (afptr->inode > inode) {
224 break;
225 }
226 afpptr = &(afptr->next);
227 }
228 afptr = (acquired_file*)malloc(sizeof(acquired_file));
229 afptr->inode = inode;
230 afptr->cnt = 0;
231 afptr->dentry = 1;
232 afptr->next = *afpptr;
233 *afpptr = afptr;
234 pthread_mutex_unlock(&aflock);
235 }
236
fs_forget_entry(uint32_t inode)237 void fs_forget_entry(uint32_t inode) {
238 acquired_file *afptr,**afpptr;
239 pthread_mutex_lock(&aflock);
240 afpptr = &afhead;
241 while ((afptr=*afpptr)) {
242 if (afptr->inode == inode) {
243 afptr->dentry = 0;
244 if (afptr->cnt==0) {
245 *afpptr = afptr->next;
246 free(afptr);
247 }
248 pthread_mutex_unlock(&aflock);
249 return;
250 }
251 afpptr = &(afptr->next);
252 }
253 pthread_mutex_unlock(&aflock);
254 }
255
fs_inc_acnt(uint32_t inode)256 void fs_inc_acnt(uint32_t inode) {
257 acquired_file *afptr,**afpptr;
258 pthread_mutex_lock(&aflock);
259 afpptr = &afhead;
260 while ((afptr=*afpptr)) {
261 if (afptr->inode==inode) {
262 afptr->cnt++;
263 pthread_mutex_unlock(&aflock);
264 return;
265 }
266 if (afptr->inode>inode) {
267 break;
268 }
269 afpptr = &(afptr->next);
270 }
271 afptr = (acquired_file*)malloc(sizeof(acquired_file));
272 afptr->inode = inode;
273 afptr->cnt = 1;
274 afptr->dentry = 0;
275 afptr->next = *afpptr;
276 *afpptr = afptr;
277 pthread_mutex_unlock(&aflock);
278 }
279
fs_dec_acnt(uint32_t inode)280 void fs_dec_acnt(uint32_t inode) {
281 acquired_file *afptr,**afpptr;
282 pthread_mutex_lock(&aflock);
283 afpptr = &afhead;
284 while ((afptr=*afpptr)) {
285 if (afptr->inode == inode) {
286 if (afptr->cnt>0) {
287 afptr->cnt--;
288 }
289 if (afptr->cnt==0 && afptr->dentry==0) {
290 *afpptr = afptr->next;
291 free(afptr);
292 }
293 pthread_mutex_unlock(&aflock);
294 return;
295 }
296 afpptr = &(afptr->next);
297 }
298 pthread_mutex_unlock(&aflock);
299 }
300
fs_get_my_threc()301 threc* fs_get_my_threc() {
302 pthread_t mythid = pthread_self();
303 threc *rec;
304 pthread_mutex_lock(&reclock);
305 for (rec = threchead ; rec ; rec=rec->next) {
306 if (pthread_equal(rec->thid,mythid)) {
307 pthread_mutex_unlock(&reclock);
308 return rec;
309 }
310 }
311 rec = malloc(sizeof(threc));
312 rec->thid = mythid;
313 pthread_mutex_init(&(rec->mutex),NULL);
314 pthread_cond_init(&(rec->cond),NULL);
315 rec->obuff = NULL;
316 rec->ibuff = NULL;
317 rec->obuffsize = 0;
318 rec->ibuffsize = 0;
319 rec->odataleng = 0;
320 rec->idataleng = 0;
321 rec->sent = 0;
322 rec->status = 0;
323 rec->rcvd = 0;
324 rec->waiting = 0;
325 rec->rcvd_cmd = 0;
326 if (threchead==NULL) {
327 rec->packetid = 1;
328 } else {
329 rec->packetid = threchead->packetid+1;
330 }
331 rec->next = threchead;
332 //syslog(LOG_NOTICE,"mastercomm: create new threc (%"PRIu32")",rec->packetid);
333 threchead = rec;
334 pthread_mutex_unlock(&reclock);
335 return rec;
336 }
337
fs_get_threc_by_id(uint32_t packetid)338 threc* fs_get_threc_by_id(uint32_t packetid) {
339 threc *rec;
340 pthread_mutex_lock(&reclock);
341 for (rec = threchead ; rec ; rec=rec->next) {
342 if (rec->packetid==packetid) {
343 pthread_mutex_unlock(&reclock);
344 return rec;
345 }
346 }
347 pthread_mutex_unlock(&reclock);
348 return NULL;
349 }
350
fs_output_buffer_init(threc * rec,uint32_t size)351 void fs_output_buffer_init(threc *rec,uint32_t size) {
352 if (size>DEFAULT_OUTPUT_BUFFSIZE) {
353 #ifdef MMAP_ALLOC
354 if (rec->obuff) {
355 munmap((void*)(rec->obuff),rec->obuffsize);
356 }
357 rec->obuff = (void*)mmap(NULL,size,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
358 #else
359 if (rec->obuff) {
360 free(rec->obuff);
361 }
362 rec->obuff = malloc(size);
363 #endif
364 rec->obuffsize = size;
365 } else if (rec->obuffsize!=DEFAULT_OUTPUT_BUFFSIZE) {
366 #ifdef MMAP_ALLOC
367 if (rec->obuff) {
368 munmap((void*)(rec->obuff),rec->obuffsize);
369 }
370 rec->obuff = (void*)mmap(NULL,DEFAULT_OUTPUT_BUFFSIZE,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
371 #else
372 if (rec->obuff) {
373 free(rec->obuff);
374 }
375 rec->obuff = malloc(DEFAULT_OUTPUT_BUFFSIZE);
376 #endif
377 rec->obuffsize = DEFAULT_OUTPUT_BUFFSIZE;
378 }
379 if (rec->obuff==NULL) {
380 rec->obuffsize = 0;
381 }
382 }
383
fs_input_buffer_init(threc * rec,uint32_t size)384 void fs_input_buffer_init(threc *rec,uint32_t size) {
385 if (size>DEFAULT_INPUT_BUFFSIZE) {
386 #ifdef MMAP_ALLOC
387 if (rec->ibuff) {
388 munmap((void*)(rec->ibuff),rec->ibuffsize);
389 }
390 rec->ibuff = (void*)mmap(NULL,size,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
391 #else
392 if (rec->ibuff) {
393 free(rec->ibuff);
394 }
395 rec->ibuff = malloc(size);
396 #endif
397 rec->ibuffsize = size;
398 } else if (rec->ibuffsize!=DEFAULT_INPUT_BUFFSIZE) {
399 #ifdef MMAP_ALLOC
400 if (rec->ibuff) {
401 munmap((void*)(rec->ibuff),rec->ibuffsize);
402 }
403 rec->ibuff = (void*)mmap(NULL,DEFAULT_INPUT_BUFFSIZE,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
404 #else
405 if (rec->ibuff) {
406 free(rec->ibuff);
407 }
408 rec->ibuff = malloc(DEFAULT_INPUT_BUFFSIZE);
409 #endif
410 rec->ibuffsize = DEFAULT_INPUT_BUFFSIZE;
411 }
412 if (rec->ibuff==NULL) {
413 rec->ibuffsize = 0;
414 }
415 }
416
fs_createpacket(threc * rec,uint32_t cmd,uint32_t size)417 uint8_t* fs_createpacket(threc *rec,uint32_t cmd,uint32_t size) {
418 uint8_t *ptr;
419 uint32_t hdrsize = size+4;
420 pthread_mutex_lock(&(rec->mutex)); // make helgrind happy
421 fs_output_buffer_init(rec,size+12);
422 if (rec->obuff==NULL) {
423 return NULL;
424 }
425 ptr = rec->obuff;
426 put32bit(&ptr,cmd);
427 put32bit(&ptr,hdrsize);
428 put32bit(&ptr,rec->packetid);
429 rec->odataleng = size+12;
430 pthread_mutex_unlock(&(rec->mutex)); // make helgrind happy
431 return ptr;
432 }
433
fs_sendandreceive(threc * rec,uint32_t expected_cmd,uint32_t * answer_leng)434 const uint8_t* fs_sendandreceive(threc *rec,uint32_t expected_cmd,uint32_t *answer_leng) {
435 uint32_t cnt;
436 static uint8_t notsup = ERROR_ENOTSUP;
437 // uint32_t size = rec->size;
438
439 for (cnt=0 ; cnt<maxretries ; cnt++) {
440 pthread_mutex_lock(&fdlock);
441 if (sessionlost) {
442 pthread_mutex_unlock(&fdlock);
443 return NULL;
444 }
445 if (fd==-1) {
446 pthread_mutex_unlock(&fdlock);
447 sleep(1+((cnt<30)?(cnt/3):10));
448 continue;
449 }
450 //syslog(LOG_NOTICE,"threc(%"PRIu32") - sending ...",rec->packetid);
451 pthread_mutex_lock(&(rec->mutex)); // make helgrind happy
452 if (tcptowrite(fd,rec->obuff,rec->odataleng,1000)!=(int32_t)(rec->odataleng)) {
453 syslog(LOG_WARNING,"tcp send error: %s",strerr(errno));
454 disconnect = 1;
455 pthread_mutex_unlock(&(rec->mutex));
456 pthread_mutex_unlock(&fdlock);
457 sleep(1+((cnt<30)?(cnt/3):10));
458 continue;
459 }
460 rec->rcvd = 0;
461 rec->sent = 1;
462 pthread_mutex_unlock(&(rec->mutex)); // make helgrind happy
463 master_stats_add(MASTER_BYTESSENT,rec->odataleng);
464 master_stats_inc(MASTER_PACKETSSENT);
465 lastwrite = time(NULL);
466 pthread_mutex_unlock(&fdlock);
467 // syslog(LOG_NOTICE,"master: lock: %"PRIu32,rec->packetid);
468 pthread_mutex_lock(&(rec->mutex));
469 while (rec->rcvd==0) {
470 rec->waiting = 1;
471 pthread_cond_wait(&(rec->cond),&(rec->mutex));
472 rec->waiting = 0;
473 }
474 *answer_leng = rec->idataleng;
475 // syslog(LOG_NOTICE,"master: unlocked: %"PRIu32,rec->packetid);
476 // syslog(LOG_NOTICE,"master: command_info: %"PRIu32" ; reccmd: %"PRIu32,command_info,rec->cmd);
477 if (rec->status!=0) {
478 pthread_mutex_unlock(&(rec->mutex));
479 sleep(1+((cnt<30)?(cnt/3):10));
480 continue;
481 }
482 if (rec->rcvd_cmd==ANTOAN_UNKNOWN_COMMAND || rec->rcvd_cmd==ANTOAN_BAD_COMMAND_SIZE) {
483 pthread_mutex_unlock(&(rec->mutex));
484 *answer_leng = 1; // simulate error
485 return ¬sup; // return ERROR_ENOTSUP in this case
486 }
487 if (rec->rcvd_cmd!=expected_cmd) {
488 pthread_mutex_unlock(&(rec->mutex));
489 pthread_mutex_lock(&fdlock);
490 disconnect = 1;
491 pthread_mutex_unlock(&fdlock);
492 sleep(1+((cnt<30)?(cnt/3):10));
493 continue;
494 }
495 pthread_mutex_unlock(&(rec->mutex));
496 //syslog(LOG_NOTICE,"threc(%"PRIu32") - received",rec->packetid);
497 return rec->ibuff;
498 }
499 return NULL;
500 }
501
fs_sendandreceive_any(threc * rec,uint32_t * received_cmd,uint32_t * answer_leng)502 const uint8_t* fs_sendandreceive_any(threc *rec,uint32_t *received_cmd,uint32_t *answer_leng) {
503 uint32_t cnt;
504 // uint32_t size = rec->size;
505
506 for (cnt=0 ; cnt<maxretries ; cnt++) {
507 pthread_mutex_lock(&fdlock);
508 if (sessionlost) {
509 pthread_mutex_unlock(&fdlock);
510 return NULL;
511 }
512 if (fd==-1) {
513 pthread_mutex_unlock(&fdlock);
514 sleep(1+((cnt<30)?(cnt/3):10));
515 continue;
516 }
517 //syslog(LOG_NOTICE,"threc(%"PRIu32") - sending ...",rec->packetid);
518 pthread_mutex_lock(&(rec->mutex)); // make helgrind happy
519 if (tcptowrite(fd,rec->obuff,rec->odataleng,1000)!=(int32_t)(rec->odataleng)) {
520 syslog(LOG_WARNING,"tcp send error: %s",strerr(errno));
521 disconnect = 1;
522 pthread_mutex_unlock(&(rec->mutex));
523 pthread_mutex_unlock(&fdlock);
524 sleep(1+((cnt<30)?(cnt/3):10));
525 continue;
526 }
527 rec->rcvd = 0;
528 rec->sent = 1;
529 pthread_mutex_unlock(&(rec->mutex)); // make helgrind happy
530 master_stats_add(MASTER_BYTESSENT,rec->odataleng);
531 master_stats_inc(MASTER_PACKETSSENT);
532 lastwrite = time(NULL);
533 pthread_mutex_unlock(&fdlock);
534 // syslog(LOG_NOTICE,"master: lock: %"PRIu32,rec->packetid);
535 pthread_mutex_lock(&(rec->mutex));
536 while (rec->rcvd==0) {
537 rec->waiting = 1;
538 pthread_cond_wait(&(rec->cond),&(rec->mutex));
539 rec->waiting = 0;
540 }
541 *answer_leng = rec->idataleng;
542 // syslog(LOG_NOTICE,"master: unlocked: %"PRIu32,rec->packetid);
543 // syslog(LOG_NOTICE,"master: command_info: %"PRIu32" ; reccmd: %"PRIu32,command_info,rec->cmd);
544 if (rec->status!=0) {
545 pthread_mutex_unlock(&(rec->mutex));
546 sleep(1+((cnt<30)?(cnt/3):10));
547 continue;
548 }
549 *received_cmd = rec->rcvd_cmd;
550 pthread_mutex_unlock(&(rec->mutex));
551 //syslog(LOG_NOTICE,"threc(%"PRIu32") - received",rec->packetid);
552 return rec->ibuff;
553 }
554 return NULL;
555 }
556
557 //static inline const uint8_t* fs_sendandreceive(threc *rec,uint32_t expected_cmd,uint32_t *answer_leng) {
558 // uint32_t *rcmd;
559 // const uint8_t *rptr;
560 // rptr = fs_commwithmaster(rec,&rcmd,answer_leng);
561 // if (
562 //}
563
564 /*
565 int fs_direct_connect() {
566 int rfd;
567 rfd = tcpsocket();
568 if (tcpnumconnect(rfd,masterip,masterport)<0) {
569 tcpclose(rfd);
570 return -1;
571 }
572 master_stats_inc(MASTER_TCONNECTS);
573 return rfd;
574 }
575
576 void fs_direct_close(int rfd) {
577 tcpclose(rfd);
578 }
579
580 int fs_direct_write(int rfd,const uint8_t *buff,uint32_t size) {
581 int rsize = tcptowrite(rfd,buff,size,60000);
582 if (rsize==(int)size) {
583 master_stats_add(MASTER_BYTESSENT,size);
584 }
585 return rsize;
586 }
587
588 int fs_direct_read(int rfd,uint8_t *buff,uint32_t size) {
589 int rsize = tcptoread(rfd,buff,size,60000);
590 if (rsize>0) {
591 master_stats_add(MASTER_BYTESRCVD,rsize);
592 }
593 return rsize;
594 }
595 */
596
fs_resolve(uint8_t oninit,const char * bindhostname,const char * masterhostname,const char * masterportname)597 int fs_resolve(uint8_t oninit,const char *bindhostname,const char *masterhostname,const char *masterportname) {
598 if (bindhostname) {
599 if (tcpresolve(bindhostname,NULL,&srcip,NULL,1)<0) {
600 if (oninit) {
601 fprintf(stderr,"can't resolve source hostname (%s)\n",bindhostname);
602 } else {
603 syslog(LOG_WARNING,"can't resolve source hostname (%s)",bindhostname);
604 }
605 return -1;
606 }
607 } else {
608 srcip=0;
609 }
610 snprintf(srcstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(srcip>>24)&0xFF,(srcip>>16)&0xFF,(srcip>>8)&0xFF,srcip&0xFF);
611 srcstrip[16]=0;
612
613 if (tcpresolve(masterhostname,masterportname,&masterip,&masterport,0)<0) {
614 if (oninit) {
615 fprintf(stderr,"can't resolve master hostname and/or portname (%s:%s)\n",masterhostname,masterportname);
616 } else {
617 syslog(LOG_WARNING,"can't resolve master hostname and/or portname (%s:%s)",masterhostname,masterportname);
618 }
619 return -1;
620 }
621 snprintf(masterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(masterip>>24)&0xFF,(masterip>>16)&0xFF,(masterip>>8)&0xFF,masterip&0xFF);
622 masterstrip[16]=0;
623
624 return 0;
625 }
626
627 // int fs_connect(uint8_t oninit,const char *bindhostname,const char *masterhostname,const char *masterportname,uint8_t meta,const char *info,const char *subfolder,const uint8_t passworddigest[16],uint8_t *sesflags,uint32_t *rootuid,uint32_t *rootgid,uint32_t *mapalluid,uint32_t *mapallgid,uint8_t *mingoal,uint8_t *maxgoal,uint32_t *mintrashtime,uint32_t *maxtrashtime) {
fs_connect(uint8_t oninit,struct connect_args_t * cargs)628 int fs_connect(uint8_t oninit,struct connect_args_t *cargs) {
629 uint32_t i,j;
630 uint8_t *wptr,*regbuff;
631 md5ctx ctx;
632 uint8_t digest[16];
633 const uint8_t *rptr;
634 uint32_t newmasterip;
635 uint8_t havepassword;
636 uint32_t pleng,ileng;
637 uint8_t sesflags;
638 uint32_t rootuid,rootgid,mapalluid,mapallgid;
639 uint8_t mingoal,maxgoal;
640 uint32_t mintrashtime,maxtrashtime;
641 const char *sesflagposstrtab[]={SESFLAG_POS_STRINGS};
642 const char *sesflagnegstrtab[]={SESFLAG_NEG_STRINGS};
643 struct passwd pwd,*pw;
644 struct group grp,*gr;
645 char pwdgrpbuff[16384];
646 static uint32_t trycnt=0;
647
648 if (fs_resolve(oninit,cargs->bindhostname,cargs->masterhostname,cargs->masterportname)<0) {
649 return -1;
650 }
651
652 havepassword=(cargs->passworddigest==NULL)?0:1;
653 ileng=strlen(cargs->info)+1;
654 if (cargs->meta) {
655 pleng=0;
656 regbuff = malloc(8+64+9+ileng+16);
657 } else {
658 pleng=strlen(cargs->subfolder)+1;
659 regbuff = malloc(8+64+13+pleng+ileng+16);
660 }
661
662 do {
663 fd = tcpsocket();
664 if (fd<0) {
665 free(regbuff);
666 return -1;
667 }
668 if (tcpnodelay(fd)<0) {
669 if (oninit) {
670 fprintf(stderr,"can't set TCP_NODELAY\n");
671 } else {
672 syslog(LOG_WARNING,"can't set TCP_NODELAY");
673 }
674 }
675 if (srcip>0) {
676 if (tcpnumbind(fd,srcip,0)<0) {
677 if (oninit) {
678 fprintf(stderr,"can't bind socket to given ip (\"%s\")\n",srcstrip);
679 } else {
680 syslog(LOG_WARNING,"can't bind socket to given ip (\"%s\")",srcstrip);
681 }
682 tcpclose(fd);
683 fd=-1;
684 free(regbuff);
685 return -1;
686 }
687 }
688 if (tcpnumtoconnect(fd,masterip,masterport,CONNECT_TIMEOUT)<0) {
689 tcpclose(fd);
690 fd=-1;
691 if (oninit) {
692 if (trycnt<10) {
693 trycnt++;
694 if (fs_resolve(oninit,cargs->bindhostname,cargs->masterhostname,cargs->masterportname)<0) {
695 free(regbuff);
696 return -1;
697 }
698 i=4;
699 continue;
700 } else {
701 fprintf(stderr,"can't connect to mfsmaster (\"%s\":\"%"PRIu16"\")\n",masterstrip,masterport);
702 free(regbuff);
703 return -1;
704 }
705 } else {
706 syslog(LOG_WARNING,"can't connect to mfsmaster (\"%s\":\"%"PRIu16"\")",masterstrip,masterport);
707 free(regbuff);
708 return -1;
709 }
710 }
711 if (havepassword) {
712 wptr = regbuff;
713 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
714 put32bit(&wptr,65);
715 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
716 wptr+=64;
717 put8bit(&wptr,REGISTER_GETRANDOM);
718 if (tcptowrite(fd,regbuff,8+65,1000)!=8+65) {
719 if (oninit) {
720 fprintf(stderr,"error sending data to mfsmaster\n");
721 } else {
722 syslog(LOG_WARNING,"error sending data to mfsmaster");
723 }
724 tcpclose(fd);
725 fd=-1;
726 free(regbuff);
727 return -1;
728 }
729 if (tcptoread(fd,regbuff,8,1000)!=8) {
730 if (oninit) {
731 fprintf(stderr,"error receiving data from mfsmaster\n");
732 } else {
733 syslog(LOG_WARNING,"error receiving data from mfsmaster");
734 }
735 tcpclose(fd);
736 fd=-1;
737 free(regbuff);
738 return -1;
739 }
740 rptr = regbuff;
741 i = get32bit(&rptr);
742 if (i!=MATOCL_FUSE_REGISTER) {
743 if (oninit) {
744 fprintf(stderr,"got incorrect answer from mfsmaster\n");
745 } else {
746 syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
747 }
748 tcpclose(fd);
749 fd=-1;
750 free(regbuff);
751 return -1;
752 }
753 i = get32bit(&rptr);
754 if (i!=32) {
755 if (oninit) {
756 fprintf(stderr,"got incorrect answer from mfsmaster\n");
757 } else {
758 syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
759 }
760 tcpclose(fd);
761 fd=-1;
762 free(regbuff);
763 return -1;
764 }
765 if (tcptoread(fd,regbuff,32,1000)!=32) {
766 if (oninit) {
767 fprintf(stderr,"error receiving data from mfsmaster\n");
768 } else {
769 syslog(LOG_WARNING,"error receiving data from mfsmaster");
770 }
771 tcpclose(fd);
772 fd=-1;
773 free(regbuff);
774 return -1;
775 }
776 md5_init(&ctx);
777 md5_update(&ctx,regbuff,16);
778 md5_update(&ctx,cargs->passworddigest,16);
779 md5_update(&ctx,regbuff+16,16);
780 md5_final(digest,&ctx);
781 }
782 wptr = regbuff;
783 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
784 if (cargs->meta) {
785 if (havepassword) {
786 put32bit(&wptr,64+9+ileng+16);
787 } else {
788 put32bit(&wptr,64+9+ileng);
789 }
790 } else {
791 if (havepassword) {
792 put32bit(&wptr,64+13+ileng+pleng+16);
793 } else {
794 put32bit(&wptr,64+13+ileng+pleng);
795 }
796 }
797 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
798 wptr+=64;
799 put8bit(&wptr,(cargs->meta)?REGISTER_NEWMETASESSION:REGISTER_NEWSESSION);
800 put16bit(&wptr,VERSMAJ);
801 put8bit(&wptr,VERSMID);
802 put8bit(&wptr,VERSMIN);
803 put32bit(&wptr,ileng);
804 memcpy(wptr,cargs->info,ileng);
805 wptr+=ileng;
806 if (!cargs->meta) {
807 put32bit(&wptr,pleng);
808 memcpy(wptr,cargs->subfolder,pleng);
809 }
810 if (havepassword) {
811 memcpy(wptr+pleng,digest,16);
812 }
813 if (tcptowrite(fd,regbuff,8+64+(cargs->meta?9:13)+ileng+pleng+(havepassword?16:0),1000)!=(int32_t)(8+64+(cargs->meta?9:13)+ileng+pleng+(havepassword?16:0))) {
814 if (oninit) {
815 fprintf(stderr,"error sending data to mfsmaster: %s\n",strerr(errno));
816 } else {
817 syslog(LOG_WARNING,"error sending data to mfsmaster: %s",strerr(errno));
818 }
819 tcpclose(fd);
820 fd=-1;
821 free(regbuff);
822 return -1;
823 }
824 if (tcptoread(fd,regbuff,8,1000)!=8) {
825 if (oninit) {
826 fprintf(stderr,"error receiving data from mfsmaster: %s\n",strerr(errno));
827 } else {
828 syslog(LOG_WARNING,"error receiving data from mfsmaster: %s",strerr(errno));
829 }
830 tcpclose(fd);
831 fd=-1;
832 free(regbuff);
833 return -1;
834 }
835 rptr = regbuff;
836 i = get32bit(&rptr);
837 if (i!=MATOCL_FUSE_REGISTER) {
838 if (oninit) {
839 fprintf(stderr,"got incorrect answer from mfsmaster\n");
840 } else {
841 syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
842 }
843 tcpclose(fd);
844 fd=-1;
845 free(regbuff);
846 return -1;
847 }
848 i = get32bit(&rptr);
849 if (!(i==1 || i==4 || (cargs->meta && (i==5 || i==9 || i==19)) || (cargs->meta==0 && (i==13 || i==21 || i==25 || i==35)))) {
850 if (oninit) {
851 fprintf(stderr,"got incorrect answer from mfsmaster\n");
852 } else {
853 syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
854 }
855 tcpclose(fd);
856 fd=-1;
857 free(regbuff);
858 return -1;
859 }
860 if (tcptoread(fd,regbuff,i,1000)!=(int32_t)i) {
861 if (oninit) {
862 fprintf(stderr,"error receiving data from mfsmaster: %s\n",strerr(errno));
863 } else {
864 syslog(LOG_WARNING,"error receiving data from mfsmaster: %s",strerr(errno));
865 }
866 tcpclose(fd);
867 fd=-1;
868 free(regbuff);
869 return -1;
870 }
871 rptr = regbuff;
872 if (i==1) {
873 if (oninit) {
874 fprintf(stderr,"mfsmaster register error: %s\n",mfs_strerror(rptr[0]));
875 } else {
876 syslog(LOG_WARNING,"mfsmaster register error: %s",mfs_strerror(rptr[0]));
877 }
878 tcpclose(fd);
879 fd=-1;
880 free(regbuff);
881 return -1;
882 }
883 if (i==4) {
884 // redirect
885 newmasterip = get32bit(&rptr);
886 if (newmasterip==0 || newmasterip==masterip) {
887 if (trycnt<10) {
888 trycnt++;
889 if (oninit) {
890 fprintf(stderr,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying\n",masterstrip);
891 } else {
892 syslog(LOG_WARNING,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying",masterstrip);
893 }
894 tcpclose(fd);
895 fd = -1;
896 if (oninit) {
897 sleep(2);
898 } else {
899 free(regbuff);
900 return -1;
901 }
902 } else {
903 trycnt=0;
904 if (oninit) {
905 fprintf(stderr,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying using different IP\n",masterstrip);
906 } else {
907 syslog(LOG_WARNING,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying using different IP",masterstrip);
908 }
909 if (oninit) {
910 if (fs_resolve(oninit,cargs->bindhostname,cargs->masterhostname,cargs->masterportname)<0) {
911 free(regbuff);
912 return -1;
913 }
914 sleep(2);
915 } else {
916 free(regbuff);
917 return -1;
918 }
919 }
920 } else {
921 char newmasterstrip[17];
922 snprintf(newmasterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(newmasterip>>24)&0xFF,(newmasterip>>16)&0xFF,(newmasterip>>8)&0xFF,newmasterip&0xFF);
923 newmasterstrip[16]=0;
924 if (oninit) {
925 fprintf(stderr,"mfsmaster %s - found leader: %s\n",masterstrip,newmasterstrip);
926 } else {
927 syslog(LOG_WARNING,"mfsmaster %s - found leader: %s",masterstrip,newmasterstrip);
928 }
929 masterip = newmasterip;
930 strcpy(masterstrip,newmasterstrip);
931 tcpclose(fd);
932 fd = -1;
933 }
934 }
935 } while (i==4);
936 if (i==9 || i==19 || i==25 || i==35) {
937 masterversion = get32bit(&rptr);
938 // dir_cache_master_switch((masterversion<VERSION2INT(1,6,21))?0:(masterversion<VERSION2INT(1,6,22))?1:2);
939 } else {
940 masterversion = 0;
941 // dir_cache_master_switch(0);
942 }
943 sessionid = get32bit(&rptr);
944 sesflags = get8bit(&rptr);
945 if (!cargs->meta) {
946 rootuid = get32bit(&rptr);
947 rootgid = get32bit(&rptr);
948 if (i>=21) {
949 mapalluid = get32bit(&rptr);
950 mapallgid = get32bit(&rptr);
951 } else {
952 mapalluid = 0;
953 mapallgid = 0;
954 }
955 } else {
956 rootuid = 0;
957 rootgid = 0;
958 mapalluid = 0;
959 mapallgid = 0;
960 }
961 if (i==19 || i==35) {
962 mingoal = get8bit(&rptr);
963 maxgoal = get8bit(&rptr);
964 mintrashtime = get32bit(&rptr);
965 maxtrashtime = get32bit(&rptr);
966 } else {
967 mingoal = 0;
968 maxgoal = 0;
969 mintrashtime = 0;
970 maxtrashtime = 0;
971 }
972 free(regbuff);
973 lastwrite=time(NULL);
974 if (oninit==0) {
975 syslog(LOG_NOTICE,"registered to master with new session");
976 }
977 if (cargs->clearpassword && cargs->passworddigest!=NULL) {
978 memset(cargs->passworddigest,0,16);
979 free(cargs->passworddigest);
980 cargs->passworddigest = NULL;
981 }
982 if (oninit==1) {
983 fprintf(stderr,"mfsmaster accepted connection with parameters: ");
984 j=0;
985 for (i=0 ; i<8 ; i++) {
986 if (sesflags&(1<<i)) {
987 fprintf(stderr,"%s%s",j?",":"",sesflagposstrtab[i]);
988 j=1;
989 } else if (sesflagnegstrtab[i]) {
990 fprintf(stderr,"%s%s",j?",":"",sesflagnegstrtab[i]);
991 j=1;
992 }
993 }
994 if (j==0) {
995 fprintf(stderr,"-");
996 }
997 if (!cargs->meta) {
998 fprintf(stderr," ; root mapped to ");
999 getpwuid_r(rootuid,&pwd,pwdgrpbuff,16384,&pw);
1000 // pw = getpwuid(rootuid);
1001 if (pw) {
1002 fprintf(stderr,"%s:",pw->pw_name);
1003 } else {
1004 fprintf(stderr,"%"PRIu32":",rootuid);
1005 }
1006 getgrgid_r(rootgid,&grp,pwdgrpbuff,16384,&gr);
1007 // gr = getgrgid(rootgid);
1008 if (gr) {
1009 fprintf(stderr,"%s",gr->gr_name);
1010 } else {
1011 fprintf(stderr,"%"PRIu32,rootgid);
1012 }
1013 if (sesflags&SESFLAG_MAPALL) {
1014 fprintf(stderr," ; users mapped to ");
1015 pw = getpwuid(mapalluid);
1016 if (pw) {
1017 fprintf(stderr,"%s:",pw->pw_name);
1018 } else {
1019 fprintf(stderr,"%"PRIu32":",mapalluid);
1020 }
1021 gr = getgrgid(mapallgid);
1022 if (gr) {
1023 fprintf(stderr,"%s",gr->gr_name);
1024 } else {
1025 fprintf(stderr,"%"PRIu32,mapallgid);
1026 }
1027 }
1028 }
1029 if (mingoal>0 && maxgoal>0) {
1030 if (mingoal>1 || maxgoal<9) {
1031 fprintf(stderr," ; setgoal limited to (%u:%u)",mingoal,maxgoal);
1032 }
1033 if (mintrashtime>0 || maxtrashtime<UINT32_C(0xFFFFFFFF)) {
1034 fprintf(stderr," ; settrashtime limited to (");
1035 if (mintrashtime>0) {
1036 if (mintrashtime>604800) {
1037 fprintf(stderr,"%uw",mintrashtime/604800);
1038 mintrashtime %= 604800;
1039 }
1040 if (mintrashtime>86400) {
1041 fprintf(stderr,"%ud",mintrashtime/86400);
1042 mintrashtime %= 86400;
1043 }
1044 if (mintrashtime>3600) {
1045 fprintf(stderr,"%uh",mintrashtime/3600);
1046 mintrashtime %= 3600;
1047 }
1048 if (mintrashtime>60) {
1049 fprintf(stderr,"%um",mintrashtime/60);
1050 mintrashtime %= 60;
1051 }
1052 if (mintrashtime>0) {
1053 fprintf(stderr,"%us",mintrashtime);
1054 }
1055 } else {
1056 fprintf(stderr,"0s");
1057 }
1058 fprintf(stderr,":");
1059 if (maxtrashtime>0) {
1060 if (maxtrashtime>604800) {
1061 fprintf(stderr,"%uw",maxtrashtime/604800);
1062 maxtrashtime %= 604800;
1063 }
1064 if (maxtrashtime>86400) {
1065 fprintf(stderr,"%ud",maxtrashtime/86400);
1066 maxtrashtime %= 86400;
1067 }
1068 if (maxtrashtime>3600) {
1069 fprintf(stderr,"%uh",maxtrashtime/3600);
1070 maxtrashtime %= 3600;
1071 }
1072 if (maxtrashtime>60) {
1073 fprintf(stderr,"%um",maxtrashtime/60);
1074 maxtrashtime %= 60;
1075 }
1076 if (maxtrashtime>0) {
1077 fprintf(stderr,"%us",maxtrashtime);
1078 }
1079 } else {
1080 fprintf(stderr,"0s");
1081 }
1082 fprintf(stderr,")");
1083 }
1084 }
1085 fprintf(stderr,"\n");
1086 }
1087 return 0;
1088 }
1089
fs_reconnect()1090 void fs_reconnect() {
1091 uint32_t newmasterip;
1092 uint32_t i;
1093 uint8_t *wptr,regbuff[8+64+9];
1094 const uint8_t *rptr;
1095
1096 if (sessionid==0) {
1097 syslog(LOG_WARNING,"can't register: session not created");
1098 return;
1099 }
1100
1101 snprintf(masterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(masterip>>24)&0xFF,(masterip>>16)&0xFF,(masterip>>8)&0xFF,masterip&0xFF);
1102 masterstrip[16]=0;
1103
1104 do {
1105 fd = tcpsocket();
1106 if (fd<0) {
1107 return;
1108 }
1109 if (tcpnodelay(fd)<0) {
1110 syslog(LOG_WARNING,"can't set TCP_NODELAY: %s",strerr(errno));
1111 }
1112 if (srcip>0) {
1113 if (tcpnumbind(fd,srcip,0)<0) {
1114 syslog(LOG_WARNING,"can't bind socket to given ip (\"%s\")",srcstrip);
1115 tcpclose(fd);
1116 fd=-1;
1117 return;
1118 }
1119 }
1120 if (tcpnumtoconnect(fd,masterip,masterport,CONNECT_TIMEOUT)<0) {
1121 syslog(LOG_WARNING,"can't connect to master (\"%s\":\"%"PRIu16"\")",masterstrip,masterport);
1122 tcpclose(fd);
1123 fd=-1;
1124 return;
1125 }
1126 master_stats_inc(MASTER_CONNECTS);
1127 wptr = regbuff;
1128 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
1129 put32bit(&wptr,73);
1130 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
1131 wptr+=64;
1132 put8bit(&wptr,REGISTER_RECONNECT);
1133 put32bit(&wptr,sessionid);
1134 put16bit(&wptr,VERSMAJ);
1135 put8bit(&wptr,VERSMID);
1136 put8bit(&wptr,VERSMIN);
1137 if (tcptowrite(fd,regbuff,8+64+9,1000)!=8+64+9) {
1138 syslog(LOG_WARNING,"master: register error (write: %s)",strerr(errno));
1139 tcpclose(fd);
1140 fd=-1;
1141 return;
1142 }
1143 master_stats_add(MASTER_BYTESSENT,16+64);
1144 master_stats_inc(MASTER_PACKETSSENT);
1145 if (tcptoread(fd,regbuff,8,1000)!=8) {
1146 syslog(LOG_WARNING,"master: register error (read header: %s)",strerr(errno));
1147 tcpclose(fd);
1148 fd=-1;
1149 return;
1150 }
1151 master_stats_add(MASTER_BYTESRCVD,8);
1152 rptr = regbuff;
1153 i = get32bit(&rptr);
1154 if (i!=MATOCL_FUSE_REGISTER) {
1155 syslog(LOG_WARNING,"master: register error (bad answer: %"PRIu32")",i);
1156 tcpclose(fd);
1157 fd=-1;
1158 return;
1159 }
1160 i = get32bit(&rptr);
1161 if (i!=1 && i!=4) {
1162 syslog(LOG_WARNING,"master: register error (bad length: %"PRIu32")",i);
1163 tcpclose(fd);
1164 fd=-1;
1165 return;
1166 }
1167 if (tcptoread(fd,regbuff,i,1000)!=(int32_t)i) {
1168 syslog(LOG_WARNING,"master: register error (read data: %s)",strerr(errno));
1169 tcpclose(fd);
1170 fd=-1;
1171 return;
1172 }
1173 master_stats_add(MASTER_BYTESRCVD,i);
1174 master_stats_inc(MASTER_PACKETSRCVD);
1175 rptr = regbuff;
1176 if (i==4) {
1177 // redirect
1178 newmasterip = get32bit(&rptr);
1179 if (newmasterip==0) {
1180 syslog(LOG_WARNING,"mfsmaster %s - doesn't know his leader, waiting a moment and retrying using different IP",masterstrip);
1181 tcpclose(fd);
1182 fd = -1;
1183 return;
1184 } else {
1185 if (newmasterip==masterip) { // this is ELECT
1186 syslog(LOG_WARNING,"mfsmaster %s - this is ELECT waitng for being LEADER, waiting a moment and retrying",masterstrip);
1187 tcpclose(fd);
1188 fd = -1;
1189 return;
1190 } else {
1191 masterip = newmasterip;
1192 snprintf(masterstrip,17,"%"PRIu32".%"PRIu32".%"PRIu32".%"PRIu32,(masterip>>24)&0xFF,(masterip>>16)&0xFF,(masterip>>8)&0xFF,masterip&0xFF);
1193 masterstrip[16]=0;
1194 syslog(LOG_WARNING,"mfsmaster found leader: %s",masterstrip);
1195 tcpclose(fd);
1196 fd = -1;
1197 }
1198 }
1199 }
1200 } while (i==4);
1201 if (rptr[0]!=0) {
1202 sessionlost=1;
1203 syslog(LOG_WARNING,"master: register status: %s",mfs_strerror(rptr[0]));
1204 tcpclose(fd);
1205 fd=-1;
1206 return;
1207 }
1208 lastwrite=time(NULL);
1209 syslog(LOG_NOTICE,"registered to master");
1210 }
1211
fs_close_session(void)1212 void fs_close_session(void) {
1213 uint8_t *wptr,regbuff[8+64+5];
1214
1215 if (sessionid==0) {
1216 return;
1217 }
1218
1219 wptr = regbuff;
1220 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
1221 put32bit(&wptr,69);
1222 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
1223 wptr+=64;
1224 put8bit(&wptr,REGISTER_CLOSESESSION);
1225 put32bit(&wptr,sessionid);
1226 if (tcptowrite(fd,regbuff,8+64+5,1000)!=8+64+5) {
1227 syslog(LOG_WARNING,"master: close session error (write: %s)",strerr(errno));
1228 }
1229 if (masterversion>=VERSION2INT(1,7,29)) {
1230 if (tcptoread(fd,regbuff,9,500)!=9) {
1231 syslog(LOG_WARNING,"master: close session error (read: %s)",strerr(errno));
1232 }
1233 }
1234 }
1235
fs_send_open_inodes(void)1236 void fs_send_open_inodes(void) {
1237 uint8_t *ptr,*inodespacket;
1238 int32_t inodesleng;
1239 acquired_file *afptr;
1240
1241 pthread_mutex_lock(&aflock);
1242 //inodesleng=24;
1243 inodesleng=8;
1244 for (afptr=afhead ; afptr ; afptr=afptr->next) {
1245 //syslog(LOG_NOTICE,"sustained inode: %"PRIu32,afptr->inode);
1246 inodesleng+=4;
1247 }
1248 inodespacket = malloc(inodesleng);
1249 ptr = inodespacket;
1250 put32bit(&ptr,CLTOMA_FUSE_SUSTAINED_INODES);
1251 put32bit(&ptr,inodesleng-8);
1252 //put32bit(&ptr,inodesleng-24);
1253 //put64bit(&ptr,0); // readbytes
1254 //put64bit(&ptr,0); // writebytes
1255 // readbytes = 0;
1256 // writebytes = 0;
1257 for (afptr=afhead ; afptr ; afptr=afptr->next) {
1258 put32bit(&ptr,afptr->inode);
1259 }
1260 if (tcptowrite(fd,inodespacket,inodesleng,1000)!=inodesleng) {
1261 disconnect=1;
1262 } else {
1263 master_stats_add(MASTER_BYTESSENT,inodesleng);
1264 master_stats_inc(MASTER_PACKETSSENT);
1265 }
1266 free(inodespacket);
1267 pthread_mutex_unlock(&aflock);
1268 }
1269
fs_nop_thread(void * arg)1270 void* fs_nop_thread(void *arg) {
1271 uint8_t *ptr,hdr[12];
1272 int now;
1273 int inodeswritecnt=0;
1274 (void)arg;
1275 for (;;) {
1276 now = time(NULL);
1277 pthread_mutex_lock(&fdlock);
1278 if (fterm==2 && donotsendsustainedinodes==0) {
1279 if (fd>=0) {
1280 fs_send_open_inodes();
1281 fs_close_session();
1282 tcpclose(fd);
1283 fd = -1;
1284 }
1285 pthread_mutex_unlock(&fdlock);
1286 return NULL;
1287 }
1288 if (disconnect==0 && fd>=0) {
1289 if (lastwrite+2<now) { // NOP
1290 ptr = hdr;
1291 put32bit(&ptr,ANTOAN_NOP);
1292 put32bit(&ptr,4);
1293 put32bit(&ptr,0);
1294 if (tcptowrite(fd,hdr,12,1000)!=12) {
1295 disconnect=1;
1296 } else {
1297 master_stats_add(MASTER_BYTESSENT,12);
1298 master_stats_inc(MASTER_PACKETSSENT);
1299 }
1300 lastwrite=now;
1301 }
1302 if (inodeswritecnt<=0 || inodeswritecnt>60) {
1303 inodeswritecnt=60;
1304 } else {
1305 inodeswritecnt--;
1306 }
1307 if (inodeswritecnt==0) { // HELD INODES
1308 if (donotsendsustainedinodes) {
1309 inodeswritecnt=1;
1310 } else {
1311 fs_send_open_inodes();
1312 }
1313 }
1314 }
1315 pthread_mutex_unlock(&fdlock);
1316 sleep(1);
1317 }
1318 }
1319
fs_receive_thread(void * arg)1320 void* fs_receive_thread(void *arg) {
1321 const uint8_t *ptr;
1322 uint8_t hdr[12];
1323 threc *rec;
1324 uint32_t cmd,size,packetid;
1325 uint32_t rcvd;
1326 // static uint8_t *notify_buff=NULL;
1327 // static uint32_t notify_buff_size=0;
1328 int r;
1329
1330 (void)arg;
1331 for (;;) {
1332 pthread_mutex_lock(&fdlock);
1333 if (fterm) {
1334 fterm=2;
1335 pthread_mutex_unlock(&fdlock);
1336 return NULL;
1337 }
1338 if (disconnect) {
1339 // dir_cache_remove_all();
1340 tcpclose(fd);
1341 fd=-1;
1342 disconnect=0;
1343 // send to any threc status error and unlock them
1344 pthread_mutex_lock(&reclock);
1345 for (rec=threchead ; rec ; rec=rec->next) {
1346 pthread_mutex_lock(&(rec->mutex));
1347 if (rec->sent) {
1348 rec->status = 1;
1349 rec->rcvd = 1;
1350 if (rec->waiting) {
1351 pthread_cond_signal(&(rec->cond));
1352 }
1353 }
1354 pthread_mutex_unlock(&(rec->mutex));
1355 }
1356 pthread_mutex_unlock(&reclock);
1357 }
1358 if (fd==-1 && sessionid!=0) {
1359 fs_reconnect(); // try to register using the same session id
1360 }
1361 if (fd==-1) { // still not connected
1362 if (sessionlost) { // if previous session is lost then try to register as a new session
1363 if (fs_connect(0,&connect_args)==0) {
1364 sessionlost=0;
1365 }
1366 } else { // if other problem occurred then try to resolve hostname and portname then try to reconnect using the same session id
1367 if (fs_resolve(0,connect_args.bindhostname,connect_args.masterhostname,connect_args.masterportname)==0) {
1368 fs_reconnect();
1369 }
1370 }
1371 }
1372 if (fd==-1) {
1373 pthread_mutex_unlock(&fdlock);
1374 sleep(2); // reconnect every 2 seconds
1375 continue;
1376 }
1377 pthread_mutex_unlock(&fdlock);
1378 r = tcptoread(fd,hdr,12,RECEIVE_TIMEOUT*1000); // read timeout
1379 // syslog(LOG_NOTICE,"master: header size: %d",r);
1380 if (r==0) {
1381 syslog(LOG_WARNING,"master: connection lost (header)");
1382 disconnect=1;
1383 continue;
1384 }
1385 if (r!=12) {
1386 syslog(LOG_WARNING,"master: tcp recv error: %s (header)",strerr(errno));
1387 disconnect=1;
1388 continue;
1389 }
1390 master_stats_add(MASTER_BYTESRCVD,12);
1391 master_stats_inc(MASTER_PACKETSRCVD);
1392
1393 ptr = hdr;
1394 cmd = get32bit(&ptr);
1395 size = get32bit(&ptr);
1396 packetid = get32bit(&ptr);
1397 if (size<4) {
1398 syslog(LOG_WARNING,"master: packet too small");
1399 disconnect=1;
1400 continue;
1401 }
1402 size -= 4;
1403 if (packetid==0) {
1404 if (cmd==ANTOAN_NOP && size==0) {
1405 // syslog(LOG_NOTICE,"master: got nop");
1406 continue;
1407 }
1408 if (cmd==ANTOAN_UNKNOWN_COMMAND || cmd==ANTOAN_BAD_COMMAND_SIZE) { // just ignore these packets with packetid==0
1409 continue;
1410 }
1411 /*
1412 if (cmd==MATOCL_FUSE_NOTIFY_END && size==0) {
1413 dir_cache_transaction_end();
1414 continue;
1415 }
1416 if (cmd==MATOCL_FUSE_NOTIFY_ATTR || cmd==MATOCL_FUSE_NOTIFY_LINK || cmd==MATOCL_FUSE_NOTIFY_UNLINK || cmd==MATOCL_FUSE_NOTIFY_REMOVE || cmd==MATOCL_FUSE_NOTIFY_PARENT) {
1417 if (size>DEFAULT_INPUT_BUFFSIZE) {
1418 #ifdef MMAP_ALLOC
1419 if (notify_buff) {
1420 munmap(notify_buff,notify_buff_size);
1421 }
1422 notify_buff = mmap(NULL,size,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
1423 #else
1424 if (notify_buff) {
1425 free(notify_buff);
1426 }
1427 notify_buff = malloc(size);
1428 #endif
1429 notify_buff_size = size;
1430 } else if (notify_buff_size!=DEFAULT_INPUT_BUFFSIZE) {
1431 #ifdef MMAP_ALLOC
1432 if (notify_buff) {
1433 munmap(notify_buff,notify_buff_size);
1434 }
1435 notify_buff = mmap(NULL,DEFAULT_INPUT_BUFFSIZE,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0);
1436 #else
1437 if (notify_buff) {
1438 free(notify_buff);
1439 }
1440 notify_buff = malloc(DEFAULT_INPUT_BUFFSIZE);
1441 #endif
1442 notify_buff_size = DEFAULT_INPUT_BUFFSIZE;
1443 }
1444 if (notify_buff==NULL) {
1445 notify_buff_size = 0;
1446 disconnect=1;
1447 continue;
1448 }
1449 if (size>0) {
1450 r = tcptoread(fd,notify_buff,size,1000);
1451 // syslog(LOG_NOTICE,"master: data size: %d",r);
1452 if (r==0) {
1453 syslog(LOG_WARNING,"master: connection lost (2)");
1454 disconnect=1;
1455 continue;
1456 }
1457 if (r!=(int32_t)(size)) {
1458 syslog(LOG_WARNING,"master: tcp recv error: %s (2)",strerr(errno));
1459 disconnect=1;
1460 continue;
1461 }
1462 master_stats_add(MASTER_BYTESRCVD,size);
1463 }
1464 switch (cmd) {
1465 case MATOCL_FUSE_NOTIFY_ATTR:
1466 fs_notify_attr(notify_buff,size);
1467 break;
1468 case MATOCL_FUSE_NOTIFY_LINK:
1469 fs_notify_link(notify_buff,size);
1470 break;
1471 case MATOCL_FUSE_NOTIFY_UNLINK:
1472 fs_notify_unlink(notify_buff,size);
1473 break;
1474 case MATOCL_FUSE_NOTIFY_REMOVE:
1475 fs_notify_remove(notify_buff,size);
1476 break;
1477 case MATOCL_FUSE_NOTIFY_PARENT:
1478 fs_notify_parent(notify_buff,size);
1479 break;
1480 }
1481 continue;
1482 }
1483 */
1484 }
1485 rec = fs_get_threc_by_id(packetid);
1486 if (rec==NULL) {
1487 syslog(LOG_WARNING,"master: got unexpected queryid");
1488 disconnect=1;
1489 continue;
1490 }
1491 pthread_mutex_lock(&(rec->mutex)); // make helgrind happy
1492 fs_input_buffer_init(rec,size);
1493 if (rec->ibuff==NULL) {
1494 pthread_mutex_unlock(&(rec->mutex));
1495 disconnect=1;
1496 continue;
1497 }
1498 // syslog(LOG_NOTICE,"master: expected data size: %"PRIu32,size);
1499 rcvd = 0;
1500 while (size-rcvd>65536) {
1501 r = tcptoread(fd,rec->ibuff+rcvd,65536,RECEIVE_TIMEOUT*1000);
1502 // syslog(LOG_NOTICE,"master: data size: %d",r);
1503 if (r==0) {
1504 syslog(LOG_WARNING,"master: connection lost (data)");
1505 pthread_mutex_unlock(&(rec->mutex));
1506 disconnect=1;
1507 break;
1508 }
1509 if (r!=65536) {
1510 syslog(LOG_WARNING,"master: tcp recv error: %s (data)",strerr(errno));
1511 pthread_mutex_unlock(&(rec->mutex));
1512 disconnect=1;
1513 break;
1514 }
1515 master_stats_add(MASTER_BYTESRCVD,65536);
1516 rcvd += 65536;
1517 }
1518 if (disconnect) {
1519 continue;
1520 }
1521 if (size-rcvd>0) {
1522 r = tcptoread(fd,rec->ibuff+rcvd,size-rcvd,RECEIVE_TIMEOUT*1000);
1523 // syslog(LOG_NOTICE,"master: data size: %d",r);
1524 if (r==0) {
1525 syslog(LOG_WARNING,"master: connection lost (data)");
1526 pthread_mutex_unlock(&(rec->mutex));
1527 disconnect=1;
1528 continue;
1529 }
1530 if (r!=(int32_t)(size-rcvd)) {
1531 syslog(LOG_WARNING,"master: tcp recv error: %s (data)",strerr(errno));
1532 pthread_mutex_unlock(&(rec->mutex));
1533 disconnect=1;
1534 continue;
1535 }
1536 master_stats_add(MASTER_BYTESRCVD,size-rcvd);
1537 }
1538 rec->sent = 0;
1539 rec->status = 0;
1540 rec->idataleng = size;
1541 rec->rcvd_cmd = cmd;
1542 // syslog(LOG_NOTICE,"master: unlock: %"PRIu32,rec->packetid);
1543 rec->rcvd = 1;
1544 if (rec->waiting) {
1545 pthread_cond_signal(&(rec->cond));
1546 }
1547 pthread_mutex_unlock(&(rec->mutex));
1548 }
1549 }
1550
1551 // called before fork
fs_init_master_connection(const char * bindhostname,const char * masterhostname,const char * masterportname,uint8_t meta,const char * info,const char * subfolder,const uint8_t passworddigest[16],uint8_t donotrememberpassword,uint8_t bgregister)1552 int fs_init_master_connection(const char *bindhostname,const char *masterhostname,const char *masterportname,uint8_t meta,const char *info,const char *subfolder,const uint8_t passworddigest[16],uint8_t donotrememberpassword,uint8_t bgregister) {
1553 master_statsptr_init();
1554
1555 fd = -1;
1556 sessionlost = bgregister;
1557 sessionid = 0;
1558 disconnect = 0;
1559 donotsendsustainedinodes = 0;
1560
1561 if (bindhostname) {
1562 connect_args.bindhostname = strdup(bindhostname);
1563 } else {
1564 connect_args.bindhostname = NULL;
1565 }
1566 connect_args.masterhostname = strdup(masterhostname);
1567 connect_args.masterportname = strdup(masterportname);
1568 connect_args.meta = meta;
1569 connect_args.clearpassword = donotrememberpassword;
1570 connect_args.info = strdup(info);
1571 connect_args.subfolder = strdup(subfolder);
1572 if (passworddigest==NULL) {
1573 connect_args.passworddigest = NULL;
1574 } else {
1575 connect_args.passworddigest = malloc(16);
1576 memcpy(connect_args.passworddigest,passworddigest,16);
1577 }
1578
1579 if (bgregister) {
1580 return 1;
1581 }
1582 return fs_connect(1,&connect_args);
1583 }
1584
1585 // called after fork
fs_init_threads(uint32_t retries)1586 void fs_init_threads(uint32_t retries) {
1587 pthread_attr_t thattr;
1588 maxretries = retries;
1589 fterm = 0;
1590 pthread_mutex_init(&reclock,NULL);
1591 pthread_mutex_init(&fdlock,NULL);
1592 pthread_mutex_init(&aflock,NULL);
1593 pthread_attr_init(&thattr);
1594 pthread_attr_setstacksize(&thattr,0x100000);
1595 pthread_create(&rpthid,&thattr,fs_receive_thread,NULL);
1596 pthread_create(&npthid,&thattr,fs_nop_thread,NULL);
1597 pthread_attr_destroy(&thattr);
1598 }
1599
fs_term(void)1600 void fs_term(void) {
1601 threc *tr,*trn;
1602 acquired_file *af,*afn;
1603
1604 pthread_mutex_lock(&fdlock);
1605 fterm = 1;
1606 pthread_mutex_unlock(&fdlock);
1607 pthread_join(npthid,NULL);
1608 pthread_join(rpthid,NULL);
1609 pthread_mutex_destroy(&aflock);
1610 pthread_mutex_destroy(&fdlock);
1611 pthread_mutex_destroy(&reclock);
1612 for (tr = threchead ; tr ; tr = trn) {
1613 trn = tr->next;
1614 if (tr->obuff) {
1615 #ifdef MMAP_ALLOC
1616 munmap((void*)(tr->obuff),tr->obuffsize);
1617 #else
1618 free(tr->obuff);
1619 #endif
1620 }
1621 if (tr->ibuff) {
1622 #ifdef MMAP_ALLOC
1623 munmap((void*)(tr->ibuff),tr->ibuffsize);
1624 #else
1625 free(tr->ibuff);
1626 #endif
1627 }
1628 pthread_mutex_destroy(&(tr->mutex));
1629 pthread_cond_destroy(&(tr->cond));
1630 free(tr);
1631 }
1632 for (af = afhead ; af ; af = afn) {
1633 afn = af->next;
1634 free(af);
1635 }
1636 if (fd>=0) {
1637 tcpclose(fd);
1638 }
1639 if (connect_args.bindhostname) {
1640 free(connect_args.bindhostname);
1641 }
1642 free(connect_args.masterhostname);
1643 free(connect_args.masterportname);
1644 free(connect_args.info);
1645 free(connect_args.subfolder);
1646 if (connect_args.passworddigest) {
1647 free(connect_args.passworddigest);
1648 }
1649 }
1650
fs_statfs(uint64_t * totalspace,uint64_t * availspace,uint64_t * trashspace,uint64_t * sustainedspace,uint32_t * inodes)1651 void fs_statfs(uint64_t *totalspace,uint64_t *availspace,uint64_t *trashspace,uint64_t *sustainedspace,uint32_t *inodes) {
1652 uint8_t *wptr;
1653 const uint8_t *rptr;
1654 uint32_t i;
1655 threc *rec = fs_get_my_threc();
1656 wptr = fs_createpacket(rec,CLTOMA_FUSE_STATFS,0);
1657 if (wptr==NULL) {
1658 *totalspace = 0;
1659 *availspace = 0;
1660 *trashspace = 0;
1661 *sustainedspace = 0;
1662 *inodes = 0;
1663 return;
1664 }
1665 rptr = fs_sendandreceive(rec,MATOCL_FUSE_STATFS,&i);
1666 if (rptr==NULL || i!=36) {
1667 *totalspace = 0;
1668 *availspace = 0;
1669 *trashspace = 0;
1670 *sustainedspace = 0;
1671 *inodes = 0;
1672 } else {
1673 *totalspace = get64bit(&rptr);
1674 *availspace = get64bit(&rptr);
1675 *trashspace = get64bit(&rptr);
1676 *sustainedspace = get64bit(&rptr);
1677 *inodes = get32bit(&rptr);
1678 }
1679 }
1680
fs_access(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t * gid,uint16_t modemask)1681 uint8_t fs_access(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t *gid,uint16_t modemask) {
1682 uint8_t *wptr;
1683 const uint8_t *rptr;
1684 uint32_t i;
1685 uint8_t ret;
1686 threc *rec = fs_get_my_threc();
1687 if (masterversion<VERSION2INT(2,0,0) || gids==0) {
1688 wptr = fs_createpacket(rec,CLTOMA_FUSE_ACCESS,13);
1689 if (wptr==NULL) {
1690 return ERROR_IO;
1691 }
1692 put32bit(&wptr,inode);
1693 put32bit(&wptr,uid);
1694 if (gids>0) {
1695 put32bit(&wptr,gid[0]);
1696 } else {
1697 put32bit(&wptr,0xFFFFFFFF);
1698 }
1699 put8bit(&wptr,modemask);
1700 } else {
1701 wptr = fs_createpacket(rec,CLTOMA_FUSE_ACCESS,14+4*gids);
1702 if (wptr==NULL) {
1703 return ERROR_IO;
1704 }
1705 put32bit(&wptr,inode);
1706 put32bit(&wptr,uid);
1707 put32bit(&wptr,gids);
1708 for (i=0 ; i<gids ; i++) {
1709 put32bit(&wptr,gid[i]);
1710 }
1711 put16bit(&wptr,modemask);
1712 }
1713 rptr = fs_sendandreceive(rec,MATOCL_FUSE_ACCESS,&i);
1714 if (!rptr || i!=1) {
1715 ret = ERROR_IO;
1716 } else {
1717 ret = rptr[0];
1718 }
1719 return ret;
1720 }
1721
fs_lookup(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])1722 uint8_t fs_lookup(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
1723 uint8_t *wptr;
1724 const uint8_t *rptr;
1725 uint32_t i;
1726 uint8_t ret;
1727 uint8_t packetver;
1728 threc *rec = fs_get_my_threc();
1729 if (masterversion<VERSION2INT(2,0,0)) {
1730 wptr = fs_createpacket(rec,CLTOMA_FUSE_LOOKUP,13+nleng);
1731 packetver = 0;
1732 } else {
1733 wptr = fs_createpacket(rec,CLTOMA_FUSE_LOOKUP,13+4*gids+nleng);
1734 packetver = 1;
1735 }
1736 if (wptr==NULL) {
1737 return ERROR_IO;
1738 }
1739 put32bit(&wptr,parent);
1740 put8bit(&wptr,nleng);
1741 memcpy(wptr,name,nleng);
1742 wptr+=nleng;
1743 put32bit(&wptr,uid);
1744 if (packetver==0) {
1745 if (gids>0) {
1746 put32bit(&wptr,gid[0]);
1747 } else {
1748 put32bit(&wptr,0xFFFFFFFF);
1749 }
1750 } else {
1751 if (gids>0) {
1752 put32bit(&wptr,gids);
1753 for (i=0 ; i<gids ; i++) {
1754 put32bit(&wptr,gid[i]);
1755 }
1756 } else {
1757 put32bit(&wptr,0xFFFFFFFF);
1758 }
1759 }
1760 rptr = fs_sendandreceive(rec,MATOCL_FUSE_LOOKUP,&i);
1761 if (rptr==NULL) {
1762 ret = ERROR_IO;
1763 } else if (i==1) {
1764 ret = rptr[0];
1765 } else if (i!=39) {
1766 pthread_mutex_lock(&fdlock);
1767 disconnect = 1;
1768 pthread_mutex_unlock(&fdlock);
1769 ret = ERROR_IO;
1770 } else {
1771 *inode = get32bit(&rptr);
1772 memcpy(attr,rptr,35);
1773 ret = STATUS_OK;
1774 }
1775 return ret;
1776 }
1777
fs_getattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t attr[35])1778 uint8_t fs_getattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t attr[35]) {
1779 uint8_t *wptr;
1780 const uint8_t *rptr;
1781 uint32_t i;
1782 uint8_t ret;
1783 uint8_t packetver;
1784 threc *rec = fs_get_my_threc();
1785 if (masterversion<VERSION2INT(1,6,28)) {
1786 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETATTR,12);
1787 packetver = 0;
1788 } else {
1789 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETATTR,13);
1790 packetver = 1;
1791 }
1792 if (wptr==NULL) {
1793 return ERROR_IO;
1794 }
1795 put32bit(&wptr,inode);
1796 if (packetver>=1) {
1797 put8bit(&wptr,opened);
1798 }
1799 put32bit(&wptr,uid);
1800 put32bit(&wptr,gid);
1801 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETATTR,&i);
1802 if (rptr==NULL) {
1803 ret = ERROR_IO;
1804 } else if (i==1) {
1805 ret = rptr[0];
1806 } else if (i!=35) {
1807 pthread_mutex_lock(&fdlock);
1808 disconnect = 1;
1809 pthread_mutex_unlock(&fdlock);
1810 ret = ERROR_IO;
1811 } else {
1812 memcpy(attr,rptr,35);
1813 ret = STATUS_OK;
1814 }
1815 return ret;
1816 }
1817
fs_setattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t setmask,uint16_t attrmode,uint32_t attruid,uint32_t attrgid,uint32_t attratime,uint32_t attrmtime,uint8_t sugidclearmode,uint8_t attr[35])1818 uint8_t fs_setattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t setmask,uint16_t attrmode,uint32_t attruid,uint32_t attrgid,uint32_t attratime,uint32_t attrmtime,uint8_t sugidclearmode,uint8_t attr[35]) {
1819 uint8_t *wptr;
1820 const uint8_t *rptr;
1821 uint32_t i;
1822 uint8_t ret;
1823 uint8_t packetver;
1824 threc *rec = fs_get_my_threc();
1825 if (masterversion<VERSION2INT(1,6,25)) {
1826 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,31);
1827 packetver = 0;
1828 } else if (masterversion<VERSION2INT(1,6,28)) {
1829 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,32);
1830 packetver = 1;
1831 } else if (masterversion<VERSION2INT(2,0,0)) {
1832 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,33);
1833 packetver = 2;
1834 } else {
1835 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,33+gids*4);
1836 packetver = 3;
1837 }
1838 if (wptr==NULL) {
1839 return ERROR_IO;
1840 }
1841 put32bit(&wptr,inode);
1842 if (packetver>=2) {
1843 put8bit(&wptr,opened);
1844 }
1845 put32bit(&wptr,uid);
1846 if (packetver<=2) {
1847 if (gids>0) {
1848 put32bit(&wptr,gid[0]);
1849 } else {
1850 put32bit(&wptr,0xFFFFFFFF);
1851 }
1852 } else {
1853 if (gids>0) {
1854 put32bit(&wptr,gids);
1855 for (i=0 ; i<gids ; i++) {
1856 put32bit(&wptr,gid[i]);
1857 }
1858 } else {
1859 put32bit(&wptr,0xFFFFFFFF);
1860 }
1861 }
1862 put8bit(&wptr,setmask);
1863 put16bit(&wptr,attrmode);
1864 put32bit(&wptr,attruid);
1865 put32bit(&wptr,attrgid);
1866 put32bit(&wptr,attratime);
1867 put32bit(&wptr,attrmtime);
1868 if (packetver>=1) {
1869 put8bit(&wptr,sugidclearmode);
1870 }
1871 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETATTR,&i);
1872 if (rptr==NULL) {
1873 ret = ERROR_IO;
1874 } else if (i==1) {
1875 ret = rptr[0];
1876 } else if (i!=35) {
1877 pthread_mutex_lock(&fdlock);
1878 disconnect = 1;
1879 pthread_mutex_unlock(&fdlock);
1880 ret = ERROR_IO;
1881 } else {
1882 memcpy(attr,rptr,35);
1883 ret = STATUS_OK;
1884 }
1885 return ret;
1886 }
1887
fs_truncate(uint32_t inode,uint8_t flags,uint32_t uid,uint32_t gids,uint32_t * gid,uint64_t attrlength,uint8_t attr[35])1888 uint8_t fs_truncate(uint32_t inode,uint8_t flags,uint32_t uid,uint32_t gids,uint32_t *gid,uint64_t attrlength,uint8_t attr[35]) {
1889 uint8_t *wptr;
1890 const uint8_t *rptr;
1891 uint32_t i;
1892 uint8_t ret;
1893 uint8_t packetver;
1894 threc *rec = fs_get_my_threc();
1895 if (masterversion<VERSION2INT(2,0,0)) {
1896 wptr = fs_createpacket(rec,CLTOMA_FUSE_TRUNCATE,21);
1897 packetver = 0;
1898 } else {
1899 wptr = fs_createpacket(rec,CLTOMA_FUSE_TRUNCATE,21+4*gids);
1900 packetver = 1;
1901 }
1902 if (wptr==NULL) {
1903 return ERROR_IO;
1904 }
1905 put32bit(&wptr,inode);
1906 put8bit(&wptr,flags);
1907 put32bit(&wptr,uid);
1908 if (packetver==0) {
1909 if (gids>0) {
1910 put32bit(&wptr,gid[0]);
1911 } else {
1912 put32bit(&wptr,0xFFFFFFFF);
1913 }
1914 } else {
1915 if (gids>0) {
1916 put32bit(&wptr,gids);
1917 for (i=0 ; i<gids ; i++) {
1918 put32bit(&wptr,gid[i]);
1919 }
1920 } else {
1921 put32bit(&wptr,0xFFFFFFFF);
1922 }
1923 }
1924 put64bit(&wptr,attrlength);
1925 rptr = fs_sendandreceive(rec,MATOCL_FUSE_TRUNCATE,&i);
1926 if (rptr==NULL) {
1927 ret = ERROR_IO;
1928 } else if (i==1) {
1929 ret = rptr[0];
1930 } else if (i!=35) {
1931 pthread_mutex_lock(&fdlock);
1932 disconnect = 1;
1933 pthread_mutex_unlock(&fdlock);
1934 ret = ERROR_IO;
1935 } else {
1936 memcpy(attr,rptr,35);
1937 ret = STATUS_OK;
1938 }
1939 return ret;
1940 }
1941
fs_readlink(uint32_t inode,const uint8_t ** path)1942 uint8_t fs_readlink(uint32_t inode,const uint8_t **path) {
1943 uint8_t *wptr;
1944 const uint8_t *rptr;
1945 uint32_t i;
1946 uint32_t pleng;
1947 uint8_t ret;
1948 threc *rec = fs_get_my_threc();
1949 wptr = fs_createpacket(rec,CLTOMA_FUSE_READLINK,4);
1950 if (wptr==NULL) {
1951 return ERROR_IO;
1952 }
1953 put32bit(&wptr,inode);
1954 rptr = fs_sendandreceive(rec,MATOCL_FUSE_READLINK,&i);
1955 if (rptr==NULL) {
1956 ret = ERROR_IO;
1957 } else if (i==1) {
1958 ret = rptr[0];
1959 } else if (i<4) {
1960 pthread_mutex_lock(&fdlock);
1961 disconnect = 1;
1962 pthread_mutex_unlock(&fdlock);
1963 ret = ERROR_IO;
1964 } else {
1965 pleng = get32bit(&rptr);
1966 if (i!=4+pleng || pleng==0 || rptr[pleng-1]!=0) {
1967 pthread_mutex_lock(&fdlock);
1968 disconnect = 1;
1969 pthread_mutex_unlock(&fdlock);
1970 ret = ERROR_IO;
1971 } else {
1972 *path = rptr;
1973 //*path = malloc(pleng);
1974 //memcpy(*path,ptr,pleng);
1975 ret = STATUS_OK;
1976 }
1977 }
1978 return ret;
1979 }
1980
fs_symlink(uint32_t parent,uint8_t nleng,const uint8_t * name,const uint8_t * path,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])1981 uint8_t fs_symlink(uint32_t parent,uint8_t nleng,const uint8_t *name,const uint8_t *path,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
1982 uint8_t *wptr;
1983 const uint8_t *rptr;
1984 uint32_t i;
1985 uint32_t pleng;
1986 uint8_t ret;
1987 uint8_t packetver;
1988 threc *rec = fs_get_my_threc();
1989 pleng = strlen((const char *)path)+1;
1990 if (masterversion<VERSION2INT(2,0,0)) {
1991 wptr = fs_createpacket(rec,CLTOMA_FUSE_SYMLINK,pleng+nleng+17);
1992 packetver = 0;
1993 } else {
1994 wptr = fs_createpacket(rec,CLTOMA_FUSE_SYMLINK,pleng+nleng+17+4*gids);
1995 packetver = 1;
1996 }
1997 if (wptr==NULL) {
1998 return ERROR_IO;
1999 }
2000 put32bit(&wptr,parent);
2001 put8bit(&wptr,nleng);
2002 memcpy(wptr,name,nleng);
2003 wptr+=nleng;
2004 put32bit(&wptr,pleng);
2005 memcpy(wptr,path,pleng);
2006 wptr+=pleng;
2007 put32bit(&wptr,uid);
2008 if (packetver==0) {
2009 if (gids>0) {
2010 put32bit(&wptr,gid[0]);
2011 } else {
2012 put32bit(&wptr,0xFFFFFFFF);
2013 }
2014 } else {
2015 if (gids>0) {
2016 put32bit(&wptr,gids);
2017 for (i=0 ; i<gids ; i++) {
2018 put32bit(&wptr,gid[i]);
2019 }
2020 } else {
2021 put32bit(&wptr,0xFFFFFFFF);
2022 }
2023 }
2024 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SYMLINK,&i);
2025 if (rptr==NULL) {
2026 ret = ERROR_IO;
2027 } else if (i==1) {
2028 ret = rptr[0];
2029 } else if (i!=39) {
2030 pthread_mutex_lock(&fdlock);
2031 disconnect = 1;
2032 pthread_mutex_unlock(&fdlock);
2033 ret = ERROR_IO;
2034 } else {
2035 *inode = get32bit(&rptr);
2036 memcpy(attr,rptr,35);
2037 ret = STATUS_OK;
2038 }
2039 return ret;
2040 }
2041
fsnodes_type_back_convert(uint8_t type)2042 static inline uint8_t fsnodes_type_back_convert(uint8_t type) {
2043 switch (type) {
2044 case TYPE_FILE:
2045 return DISP_TYPE_FILE;
2046 case TYPE_DIRECTORY:
2047 return DISP_TYPE_DIRECTORY;
2048 case TYPE_SYMLINK:
2049 return DISP_TYPE_SYMLINK;
2050 case TYPE_FIFO:
2051 return DISP_TYPE_FIFO;
2052 case TYPE_BLOCKDEV:
2053 return DISP_TYPE_BLOCKDEV;
2054 case TYPE_CHARDEV:
2055 return DISP_TYPE_CHARDEV;
2056 case TYPE_SOCKET:
2057 return DISP_TYPE_SOCKET;
2058 case TYPE_TRASH:
2059 return DISP_TYPE_TRASH;
2060 case TYPE_SUSTAINED:
2061 return DISP_TYPE_SUSTAINED;
2062 }
2063 return type;
2064 }
2065
fs_mknod(uint32_t parent,uint8_t nleng,const uint8_t * name,uint8_t type,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t rdev,uint32_t * inode,uint8_t attr[35])2066 uint8_t fs_mknod(uint32_t parent,uint8_t nleng,const uint8_t *name,uint8_t type,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t rdev,uint32_t *inode,uint8_t attr[35]) {
2067 uint8_t *wptr;
2068 const uint8_t *rptr;
2069 uint32_t i;
2070 uint8_t ret;
2071 uint8_t packetver;
2072 threc *rec = fs_get_my_threc();
2073
2074 if (masterversion<VERSION2INT(2,0,0)) {
2075 mode &= ~cumask;
2076 wptr = fs_createpacket(rec,CLTOMA_FUSE_MKNOD,20+nleng);
2077 packetver = 0;
2078 } else {
2079 wptr = fs_createpacket(rec,CLTOMA_FUSE_MKNOD,22+nleng+4*gids);
2080 packetver = 1;
2081 }
2082 if (wptr==NULL) {
2083 return ERROR_IO;
2084 }
2085 put32bit(&wptr,parent);
2086 put8bit(&wptr,nleng);
2087 memcpy(wptr,name,nleng);
2088 wptr+=nleng;
2089 if (masterversion<VERSION2INT(1,7,32)) {
2090 type = fsnodes_type_back_convert(type);
2091 }
2092 put8bit(&wptr,type);
2093 put16bit(&wptr,mode);
2094 if (packetver>=1) {
2095 put16bit(&wptr,cumask);
2096 }
2097 put32bit(&wptr,uid);
2098 if (packetver==0) {
2099 if (gids>0) {
2100 put32bit(&wptr,gid[0]);
2101 } else {
2102 put32bit(&wptr,0xFFFFFFFF);
2103 }
2104 } else {
2105 if (gids>0) {
2106 put32bit(&wptr,gids);
2107 for (i=0 ; i<gids ; i++) {
2108 put32bit(&wptr,gid[i]);
2109 }
2110 } else {
2111 put32bit(&wptr,0xFFFFFFFF);
2112 }
2113 }
2114 put32bit(&wptr,rdev);
2115 rptr = fs_sendandreceive(rec,MATOCL_FUSE_MKNOD,&i);
2116 if (rptr==NULL) {
2117 ret = ERROR_IO;
2118 } else if (i==1) {
2119 ret = rptr[0];
2120 } else if (i!=39) {
2121 pthread_mutex_lock(&fdlock);
2122 disconnect = 1;
2123 pthread_mutex_unlock(&fdlock);
2124 ret = ERROR_IO;
2125 } else {
2126 *inode = get32bit(&rptr);
2127 memcpy(attr,rptr,35);
2128 ret = STATUS_OK;
2129 }
2130 return ret;
2131 }
2132
fs_mkdir(uint32_t parent,uint8_t nleng,const uint8_t * name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t copysgid,uint32_t * inode,uint8_t attr[35])2133 uint8_t fs_mkdir(uint32_t parent,uint8_t nleng,const uint8_t *name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t copysgid,uint32_t *inode,uint8_t attr[35]) {
2134 uint8_t *wptr;
2135 const uint8_t *rptr;
2136 uint32_t i;
2137 uint8_t ret;
2138 uint8_t packetver;
2139 threc *rec = fs_get_my_threc();
2140 if (masterversion<VERSION2INT(1,6,25)) {
2141 mode &= ~cumask;
2142 wptr = fs_createpacket(rec,CLTOMA_FUSE_MKDIR,15+nleng);
2143 packetver = 0;
2144 } else if (masterversion<VERSION2INT(2,0,0)) {
2145 mode &= ~cumask;
2146 wptr = fs_createpacket(rec,CLTOMA_FUSE_MKDIR,16+nleng);
2147 packetver = 1;
2148 } else {
2149 wptr = fs_createpacket(rec,CLTOMA_FUSE_MKDIR,18+nleng+4*gids);
2150 packetver = 2;
2151 }
2152 if (wptr==NULL) {
2153 return ERROR_IO;
2154 }
2155 put32bit(&wptr,parent);
2156 put8bit(&wptr,nleng);
2157 memcpy(wptr,name,nleng);
2158 wptr+=nleng;
2159 put16bit(&wptr,mode);
2160 if (packetver>=2) {
2161 put16bit(&wptr,cumask);
2162 }
2163 put32bit(&wptr,uid);
2164 if (packetver<2) {
2165 if (gids>0) {
2166 put32bit(&wptr,gid[0]);
2167 } else {
2168 put32bit(&wptr,0xFFFFFFFF);
2169 }
2170 } else {
2171 if (gids>0) {
2172 put32bit(&wptr,gids);
2173 for (i=0 ; i<gids ; i++) {
2174 put32bit(&wptr,gid[i]);
2175 }
2176 } else {
2177 put32bit(&wptr,0xFFFFFFFF);
2178 }
2179 }
2180 if (packetver>=1) {
2181 put8bit(&wptr,copysgid);
2182 }
2183 rptr = fs_sendandreceive(rec,MATOCL_FUSE_MKDIR,&i);
2184 if (rptr==NULL) {
2185 ret = ERROR_IO;
2186 } else if (i==1) {
2187 ret = rptr[0];
2188 } else if (i!=39) {
2189 pthread_mutex_lock(&fdlock);
2190 disconnect = 1;
2191 pthread_mutex_unlock(&fdlock);
2192 ret = ERROR_IO;
2193 } else {
2194 *inode = get32bit(&rptr);
2195 memcpy(attr,rptr,35);
2196 ret = STATUS_OK;
2197 }
2198 return ret;
2199 }
2200
fs_unlink(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gids,uint32_t * gid)2201 uint8_t fs_unlink(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gids,uint32_t *gid) {
2202 uint8_t *wptr;
2203 const uint8_t *rptr;
2204 uint32_t i;
2205 uint8_t ret;
2206 uint8_t packetver;
2207 threc *rec = fs_get_my_threc();
2208 if (masterversion<VERSION2INT(2,0,0)) {
2209 wptr = fs_createpacket(rec,CLTOMA_FUSE_UNLINK,13+nleng);
2210 packetver = 0;
2211 } else {
2212 wptr = fs_createpacket(rec,CLTOMA_FUSE_UNLINK,13+nleng+4*gids);
2213 packetver = 1;
2214 }
2215 if (wptr==NULL) {
2216 return ERROR_IO;
2217 }
2218 put32bit(&wptr,parent);
2219 put8bit(&wptr,nleng);
2220 memcpy(wptr,name,nleng);
2221 wptr+=nleng;
2222 put32bit(&wptr,uid);
2223 if (packetver==0) {
2224 if (gids>0) {
2225 put32bit(&wptr,gid[0]);
2226 } else {
2227 put32bit(&wptr,0xFFFFFFFF);
2228 }
2229 } else {
2230 if (gids>0) {
2231 put32bit(&wptr,gids);
2232 for (i=0 ; i<gids ; i++) {
2233 put32bit(&wptr,gid[i]);
2234 }
2235 } else {
2236 put32bit(&wptr,0xFFFFFFFF);
2237 }
2238 }
2239 rptr = fs_sendandreceive(rec,MATOCL_FUSE_UNLINK,&i);
2240 if (rptr==NULL) {
2241 ret = ERROR_IO;
2242 } else if (i==1) {
2243 ret = rptr[0];
2244 } else {
2245 pthread_mutex_lock(&fdlock);
2246 disconnect = 1;
2247 pthread_mutex_unlock(&fdlock);
2248 ret = ERROR_IO;
2249 }
2250 return ret;
2251 }
2252
fs_rmdir(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gids,uint32_t * gid)2253 uint8_t fs_rmdir(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gids,uint32_t *gid) {
2254 uint8_t *wptr;
2255 const uint8_t *rptr;
2256 uint32_t i;
2257 uint8_t ret;
2258 uint8_t packetver;
2259 threc *rec = fs_get_my_threc();
2260 if (masterversion<VERSION2INT(2,0,0)) {
2261 wptr = fs_createpacket(rec,CLTOMA_FUSE_RMDIR,13+nleng);
2262 packetver = 0;
2263 } else {
2264 wptr = fs_createpacket(rec,CLTOMA_FUSE_RMDIR,13+nleng+4*gids);
2265 packetver = 1;
2266 }
2267 if (wptr==NULL) {
2268 return ERROR_IO;
2269 }
2270 put32bit(&wptr,parent);
2271 put8bit(&wptr,nleng);
2272 memcpy(wptr,name,nleng);
2273 wptr+=nleng;
2274 put32bit(&wptr,uid);
2275 if (packetver==0) {
2276 if (gids>0) {
2277 put32bit(&wptr,gid[0]);
2278 } else {
2279 put32bit(&wptr,0xFFFFFFFF);
2280 }
2281 } else {
2282 if (gids>0) {
2283 put32bit(&wptr,gids);
2284 for (i=0 ; i<gids ; i++) {
2285 put32bit(&wptr,gid[i]);
2286 }
2287 } else {
2288 put32bit(&wptr,0xFFFFFFFF);
2289 }
2290 }
2291 rptr = fs_sendandreceive(rec,MATOCL_FUSE_RMDIR,&i);
2292 if (rptr==NULL) {
2293 ret = ERROR_IO;
2294 } else if (i==1) {
2295 ret = rptr[0];
2296 } else {
2297 pthread_mutex_lock(&fdlock);
2298 disconnect = 1;
2299 pthread_mutex_unlock(&fdlock);
2300 ret = ERROR_IO;
2301 }
2302 return ret;
2303 }
2304
fs_rename(uint32_t parent_src,uint8_t nleng_src,const uint8_t * name_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t * name_dst,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])2305 uint8_t fs_rename(uint32_t parent_src,uint8_t nleng_src,const uint8_t *name_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t *name_dst,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
2306 uint8_t *wptr;
2307 const uint8_t *rptr;
2308 uint32_t i;
2309 uint8_t ret;
2310 uint8_t packetver;
2311 threc *rec = fs_get_my_threc();
2312 if (masterversion<VERSION2INT(2,0,0)) {
2313 wptr = fs_createpacket(rec,CLTOMA_FUSE_RENAME,18+nleng_src+nleng_dst);
2314 packetver = 0;
2315 } else {
2316 wptr = fs_createpacket(rec,CLTOMA_FUSE_RENAME,18+nleng_src+nleng_dst+4*gids);
2317 packetver = 1;
2318 }
2319 if (wptr==NULL) {
2320 return ERROR_IO;
2321 }
2322 put32bit(&wptr,parent_src);
2323 put8bit(&wptr,nleng_src);
2324 memcpy(wptr,name_src,nleng_src);
2325 wptr+=nleng_src;
2326 put32bit(&wptr,parent_dst);
2327 put8bit(&wptr,nleng_dst);
2328 memcpy(wptr,name_dst,nleng_dst);
2329 wptr+=nleng_dst;
2330 put32bit(&wptr,uid);
2331 if (packetver==0) {
2332 if (gids>0) {
2333 put32bit(&wptr,gid[0]);
2334 } else {
2335 put32bit(&wptr,0xFFFFFFFF);
2336 }
2337 } else {
2338 if (gids>0) {
2339 put32bit(&wptr,gids);
2340 for (i=0 ; i<gids ; i++) {
2341 put32bit(&wptr,gid[i]);
2342 }
2343 } else {
2344 put32bit(&wptr,0xFFFFFFFF);
2345 }
2346 }
2347 rptr = fs_sendandreceive(rec,MATOCL_FUSE_RENAME,&i);
2348 if (rptr==NULL) {
2349 ret = ERROR_IO;
2350 } else if (i==1) {
2351 ret = rptr[0];
2352 *inode = 0;
2353 memset(attr,0,35);
2354 } else if (i!=39) {
2355 pthread_mutex_lock(&fdlock);
2356 disconnect = 1;
2357 pthread_mutex_unlock(&fdlock);
2358 ret = ERROR_IO;
2359 } else {
2360 *inode = get32bit(&rptr);
2361 memcpy(attr,rptr,35);
2362 ret = STATUS_OK;
2363 }
2364 return ret;
2365 }
2366
fs_link(uint32_t inode_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t * name_dst,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])2367 uint8_t fs_link(uint32_t inode_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t *name_dst,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
2368 uint8_t *wptr;
2369 const uint8_t *rptr;
2370 uint32_t i;
2371 uint8_t ret;
2372 uint8_t packetver;
2373 threc *rec = fs_get_my_threc();
2374 if (masterversion<VERSION2INT(2,0,0)) {
2375 wptr = fs_createpacket(rec,CLTOMA_FUSE_LINK,17+nleng_dst);
2376 packetver = 0;
2377 } else {
2378 wptr = fs_createpacket(rec,CLTOMA_FUSE_LINK,17+nleng_dst+4*gids);
2379 packetver = 1;
2380 }
2381 if (wptr==NULL) {
2382 return ERROR_IO;
2383 }
2384 put32bit(&wptr,inode_src);
2385 put32bit(&wptr,parent_dst);
2386 put8bit(&wptr,nleng_dst);
2387 memcpy(wptr,name_dst,nleng_dst);
2388 wptr+=nleng_dst;
2389 put32bit(&wptr,uid);
2390 if (packetver==0) {
2391 if (gids>0) {
2392 put32bit(&wptr,gid[0]);
2393 } else {
2394 put32bit(&wptr,0xFFFFFFFF);
2395 }
2396 } else {
2397 if (gids>0) {
2398 put32bit(&wptr,gids);
2399 for (i=0 ; i<gids ; i++) {
2400 put32bit(&wptr,gid[i]);
2401 }
2402 } else {
2403 put32bit(&wptr,0xFFFFFFFF);
2404 }
2405 }
2406 rptr = fs_sendandreceive(rec,MATOCL_FUSE_LINK,&i);
2407 if (rptr==NULL) {
2408 ret = ERROR_IO;
2409 } else if (i==1) {
2410 ret = rptr[0];
2411 } else if (i!=39) {
2412 pthread_mutex_lock(&fdlock);
2413 disconnect = 1;
2414 pthread_mutex_unlock(&fdlock);
2415 ret = ERROR_IO;
2416 } else {
2417 *inode = get32bit(&rptr);
2418 memcpy(attr,rptr,35);
2419 ret = STATUS_OK;
2420 }
2421 return ret;
2422 }
2423 /*
2424 uint8_t fs_getdir(uint32_t inode,uint32_t uid,uint32_t gid,const uint8_t **dbuff,uint32_t *dbuffsize) {
2425 uint8_t *wptr;
2426 const uint8_t *rptr;
2427 uint32_t i;
2428 uint8_t ret;
2429 threc *rec = fs_get_my_threc();
2430 wptr = fs_createpacket(rec,CLTOMA_FUSE_READDIR,12);
2431 if (wptr==NULL) {
2432 return ERROR_IO;
2433 }
2434 put32bit(&wptr,inode);
2435 put32bit(&wptr,uid);
2436 put32bit(&wptr,gid);
2437 rptr = fs_sendandreceive(rec,MATOCL_FUSE_READDIR,&i);
2438 if (rptr==NULL) {
2439 ret = ERROR_IO;
2440 } else if (i==1) {
2441 ret = rptr[0];
2442 } else {
2443 *dbuff = rptr;
2444 *dbuffsize = i;
2445 ret = STATUS_OK;
2446 }
2447 return ret;
2448 }
2449 */
2450
fs_readdir(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t wantattr,uint8_t addtocache,const uint8_t ** dbuff,uint32_t * dbuffsize)2451 uint8_t fs_readdir(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t wantattr,uint8_t addtocache,const uint8_t **dbuff,uint32_t *dbuffsize) {
2452 uint8_t *wptr;
2453 const uint8_t *rptr;
2454 uint32_t i;
2455 uint8_t ret;
2456 uint8_t packetver;
2457 uint8_t flags;
2458 threc *rec = fs_get_my_threc();
2459 if (masterversion<VERSION2INT(2,0,0)) {
2460 wptr = fs_createpacket(rec,CLTOMA_FUSE_READDIR,13);
2461 packetver = 0;
2462 } else {
2463 wptr = fs_createpacket(rec,CLTOMA_FUSE_READDIR,25+4*gids);
2464 packetver = 1;
2465 }
2466 if (wptr==NULL) {
2467 return ERROR_IO;
2468 }
2469 put32bit(&wptr,inode);
2470 put32bit(&wptr,uid);
2471 if (packetver==0) {
2472 if (gids>0) {
2473 put32bit(&wptr,gid[0]);
2474 } else {
2475 put32bit(&wptr,0xFFFFFFFF);
2476 }
2477 } else {
2478 if (gids>0) {
2479 put32bit(&wptr,gids);
2480 for (i=0 ; i<gids ; i++) {
2481 put32bit(&wptr,gid[i]);
2482 }
2483 } else {
2484 put32bit(&wptr,0xFFFFFFFF);
2485 }
2486 }
2487 flags = 0;
2488 if (wantattr) {
2489 flags |= GETDIR_FLAG_WITHATTR;
2490 }
2491 if (addtocache) {
2492 flags |= GETDIR_FLAG_ADDTOCACHE;
2493 }
2494 put8bit(&wptr,flags);
2495 if (packetver>=1) {
2496 put32bit(&wptr,0xFFFFFFFFU);
2497 put64bit(&wptr,0);
2498 }
2499 rptr = fs_sendandreceive(rec,MATOCL_FUSE_READDIR,&i);
2500 if (rptr==NULL) {
2501 ret = ERROR_IO;
2502 } else if (i==1) {
2503 ret = rptr[0];
2504 } else {
2505 if (packetver>=1) { // skip 'read-next' handler
2506 rptr+=8;
2507 i-=8;
2508 }
2509 *dbuff = rptr;
2510 *dbuffsize = i;
2511 ret = STATUS_OK;
2512 }
2513 return ret;
2514 }
2515
2516 /*
2517 uint8_t fs_check(uint32_t inode,uint8_t dbuff[22]) {
2518 uint8_t *wptr;
2519 const uint8_t *rptr;
2520 uint32_t i;
2521 uint8_t ret;
2522 uint16_t cbuff[11];
2523 uint8_t copies;
2524 uint16_t chunks;
2525 threc *rec = fs_get_my_threc();
2526 wptr = fs_createpacket(rec,CLTOMA_FUSE_CHECK,4);
2527 if (wptr==NULL) {
2528 return ERROR_IO;
2529 }
2530 put32bit(&wptr,inode);
2531 rptr = fs_sendandreceive(rec,MATOCL_FUSE_CHECK,&i);
2532 if (rptr==NULL) {
2533 ret = ERROR_IO;
2534 } else if (i==1) {
2535 ret = rptr[0];
2536 } else if (i%3!=0) {
2537 pthread_mutex_lock(&fdlock);
2538 disconnect = 1;
2539 pthread_mutex_unlock(&fdlock);
2540 ret = ERROR_IO;
2541 } else {
2542 for (copies=0 ; copies<11 ; copies++) {
2543 cbuff[copies]=0;
2544 }
2545 while (i>0) {
2546 copies = get8bit(&rptr);
2547 chunks = get16bit(&rptr);
2548 if (copies<10) {
2549 cbuff[copies]+=chunks;
2550 } else {
2551 cbuff[10]+=chunks;
2552 }
2553 i-=3;
2554 }
2555 wptr = dbuff;
2556 for (copies=0 ; copies<11 ; copies++) {
2557 chunks = cbuff[copies];
2558 put16bit(&wptr,chunks);
2559 }
2560 ret = STATUS_OK;
2561 }
2562 return ret;
2563 }
2564 */
2565 // FUSE - I/O
2566
fs_create(uint32_t parent,uint8_t nleng,const uint8_t * name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t * gid,uint32_t * inode,uint8_t attr[35])2567 uint8_t fs_create(uint32_t parent,uint8_t nleng,const uint8_t *name,uint16_t mode,uint16_t cumask,uint32_t uid,uint32_t gids,uint32_t *gid,uint32_t *inode,uint8_t attr[35]) {
2568 uint8_t *wptr;
2569 const uint8_t *rptr;
2570 uint32_t i;
2571 uint8_t ret;
2572 uint8_t packetver;
2573 threc *rec = fs_get_my_threc();
2574 if (masterversion<VERSION2INT(1,7,25)) {
2575 return ERROR_ENOTSUP;
2576 }
2577 if (masterversion<VERSION2INT(2,0,0)) {
2578 mode &= ~cumask;
2579 wptr = fs_createpacket(rec,CLTOMA_FUSE_CREATE,15+nleng);
2580 packetver = 0;
2581 } else {
2582 wptr = fs_createpacket(rec,CLTOMA_FUSE_CREATE,17+nleng+4*gids);
2583 packetver = 1;
2584 }
2585 if (wptr==NULL) {
2586 return ERROR_IO;
2587 }
2588 put32bit(&wptr,parent);
2589 put8bit(&wptr,nleng);
2590 memcpy(wptr,name,nleng);
2591 wptr+=nleng;
2592 put16bit(&wptr,mode);
2593 if (packetver>=1) {
2594 put16bit(&wptr,cumask);
2595 }
2596 put32bit(&wptr,uid);
2597 if (packetver==0) {
2598 if (gids>0) {
2599 put32bit(&wptr,gid[0]);
2600 } else {
2601 put32bit(&wptr,0xFFFFFFFF);
2602 }
2603 } else {
2604 if (gids>0) {
2605 put32bit(&wptr,gids);
2606 for (i=0 ; i<gids ; i++) {
2607 put32bit(&wptr,gid[i]);
2608 }
2609 } else {
2610 put32bit(&wptr,0xFFFFFFFF);
2611 }
2612 }
2613 pthread_mutex_lock(&fdlock);
2614 donotsendsustainedinodes = 1;
2615 pthread_mutex_unlock(&fdlock);
2616 rptr = fs_sendandreceive(rec,MATOCL_FUSE_CREATE,&i);
2617 if (rptr==NULL) {
2618 ret = ERROR_IO;
2619 } else if (i==1) {
2620 ret = rptr[0];
2621 } else if (i!=39) {
2622 pthread_mutex_lock(&fdlock);
2623 disconnect = 1;
2624 pthread_mutex_unlock(&fdlock);
2625 ret = ERROR_IO;
2626 } else {
2627 fs_inc_acnt((*inode = get32bit(&rptr)));
2628 memcpy(attr,rptr,35);
2629 ret = STATUS_OK;
2630 }
2631 pthread_mutex_lock(&fdlock);
2632 donotsendsustainedinodes = 0;
2633 pthread_mutex_unlock(&fdlock);
2634 return ret;
2635 }
2636
fs_opencheck(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t flags,uint8_t attr[35])2637 uint8_t fs_opencheck(uint32_t inode,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t flags,uint8_t attr[35]) {
2638 uint8_t *wptr;
2639 const uint8_t *rptr;
2640 uint32_t i;
2641 uint8_t ret;
2642 uint8_t packetver;
2643 threc *rec = fs_get_my_threc();
2644 if (masterversion<VERSION2INT(2,0,0) || gids==0) {
2645 wptr = fs_createpacket(rec,CLTOMA_FUSE_OPEN,13);
2646 packetver = 0;
2647 } else {
2648 wptr = fs_createpacket(rec,CLTOMA_FUSE_OPEN,13+4*gids);
2649 packetver = 1;
2650 }
2651 if (wptr==NULL) {
2652 return ERROR_IO;
2653 }
2654 put32bit(&wptr,inode);
2655 put32bit(&wptr,uid);
2656 if (packetver==0) {
2657 if (gids>0) { // should be always true)
2658 put32bit(&wptr,gid[0]);
2659 } else {
2660 put32bit(&wptr,0xFFFFFFFF);
2661 }
2662 } else {
2663 put32bit(&wptr,gids);
2664 for (i=0 ; i<gids ; i++) {
2665 put32bit(&wptr,gid[i]);
2666 }
2667 }
2668 put8bit(&wptr,flags);
2669 fs_inc_acnt(inode);
2670 rptr = fs_sendandreceive(rec,MATOCL_FUSE_OPEN,&i);
2671 if (rptr==NULL) {
2672 ret = ERROR_IO;
2673 } else if (i==1) {
2674 if (attr) {
2675 memset(attr,0,35);
2676 }
2677 ret = rptr[0];
2678 } else if (i==35) {
2679 if (attr) {
2680 memcpy(attr,rptr,35);
2681 }
2682 ret = STATUS_OK;
2683 } else {
2684 pthread_mutex_lock(&fdlock);
2685 disconnect = 1;
2686 pthread_mutex_unlock(&fdlock);
2687 ret = ERROR_IO;
2688 }
2689 if (ret) { // release on error
2690 fs_dec_acnt(inode);
2691 }
2692 return ret;
2693 }
2694
fs_release(uint32_t inode)2695 void fs_release(uint32_t inode) {
2696 fs_dec_acnt(inode);
2697 }
2698
2699 // release - decrease acquire cnt - if reach 0 send CLTOMA_FUSE_RELEASE
2700 /*
2701 uint8_t fs_release(uint32_t inode) {
2702 uint8_t *ptr;
2703 uint32_t i;
2704 uint8_t ret;
2705 ptr = fs_createpacket(rec,CLTOMA_FUSE_RELEASE,4);
2706 if (wptr==NULL) {
2707 return ERROR_IO;
2708 }
2709 put32bit(&ptr,inode);
2710 ptr = fs_sendandreceive(rec,MATOCL_FUSE_RELEASE,&i);
2711 if (ptr==NULL) {
2712 ret = ERROR_IO;
2713 } else if (i==1) {
2714 ret = ptr[0];
2715 } else {
2716 pthread_mutex_lock(&fdlock);
2717 disconnect = 1;
2718 pthread_mutex_unlock(&fdlock);
2719 ret = ERROR_IO;
2720 }
2721 return ret;
2722 }
2723 */
2724
fs_readchunk(uint32_t inode,uint32_t indx,uint8_t * csdataver,uint64_t * length,uint64_t * chunkid,uint32_t * version,const uint8_t ** csdata,uint32_t * csdatasize)2725 uint8_t fs_readchunk(uint32_t inode,uint32_t indx,uint8_t *csdataver,uint64_t *length,uint64_t *chunkid,uint32_t *version,const uint8_t **csdata,uint32_t *csdatasize) {
2726 uint8_t *wptr;
2727 const uint8_t *rptr;
2728 uint32_t i;
2729 uint8_t ret;
2730 threc *rec = fs_get_my_threc();
2731
2732 *csdata = NULL;
2733 *csdatasize = 0;
2734
2735 wptr = fs_createpacket(rec,CLTOMA_FUSE_READ_CHUNK,8);
2736 if (wptr==NULL) {
2737 return ERROR_IO;
2738 }
2739 put32bit(&wptr,inode);
2740 put32bit(&wptr,indx);
2741 rptr = fs_sendandreceive(rec,MATOCL_FUSE_READ_CHUNK,&i);
2742 if (rptr==NULL) {
2743 ret = ERROR_IO;
2744 } else if (i==1) {
2745 ret = rptr[0];
2746 } else {
2747 if (i&1) {
2748 *csdataver = get8bit(&rptr);
2749 if (i<21 || ((i-21)%10)!=0) {
2750 ret = ERROR_IO;
2751 } else {
2752 *csdatasize = i-21;
2753 ret = STATUS_OK;
2754 }
2755 } else {
2756 *csdataver = 0;
2757 if (i<20 || ((i-20)%6)!=0) {
2758 ret = ERROR_IO;
2759 } else {
2760 *csdatasize = i-20;
2761 ret = STATUS_OK;
2762 }
2763 }
2764 if (ret!=STATUS_OK) {
2765 pthread_mutex_lock(&fdlock);
2766 disconnect = 1;
2767 pthread_mutex_unlock(&fdlock);
2768 } else {
2769 *length = get64bit(&rptr);
2770 *chunkid = get64bit(&rptr);
2771 *version = get32bit(&rptr);
2772 *csdata = rptr;
2773 }
2774 }
2775 return ret;
2776 }
2777
fs_writechunk(uint32_t inode,uint32_t indx,uint8_t * csdataver,uint64_t * length,uint64_t * chunkid,uint32_t * version,const uint8_t ** csdata,uint32_t * csdatasize)2778 uint8_t fs_writechunk(uint32_t inode,uint32_t indx,uint8_t *csdataver,uint64_t *length,uint64_t *chunkid,uint32_t *version,const uint8_t **csdata,uint32_t *csdatasize) {
2779 uint8_t *wptr;
2780 const uint8_t *rptr;
2781 uint32_t i;
2782 uint8_t ret;
2783 threc *rec = fs_get_my_threc();
2784
2785 *csdata = NULL;
2786 *csdatasize = 0;
2787
2788 wptr = fs_createpacket(rec,CLTOMA_FUSE_WRITE_CHUNK,8);
2789 if (wptr==NULL) {
2790 return ERROR_IO;
2791 }
2792 put32bit(&wptr,inode);
2793 put32bit(&wptr,indx);
2794 rptr = fs_sendandreceive(rec,MATOCL_FUSE_WRITE_CHUNK,&i);
2795 if (rptr==NULL) {
2796 ret = ERROR_IO;
2797 } else if (i==1) {
2798 ret = rptr[0];
2799 } else {
2800 if (i&1) {
2801 *csdataver = get8bit(&rptr);
2802 if (i<21 || ((i-21)%10)!=0) {
2803 ret = ERROR_IO;
2804 } else {
2805 *csdatasize = i-21;
2806 ret = STATUS_OK;
2807 }
2808 } else {
2809 *csdataver = 0;
2810 if (i<20 || ((i-20)%6)!=0) {
2811 ret = ERROR_IO;
2812 } else {
2813 *csdatasize = i-20;
2814 ret = STATUS_OK;
2815 }
2816 }
2817 if (ret!=STATUS_OK) {
2818 pthread_mutex_lock(&fdlock);
2819 disconnect = 1;
2820 pthread_mutex_unlock(&fdlock);
2821 } else {
2822 *length = get64bit(&rptr);
2823 *chunkid = get64bit(&rptr);
2824 *version = get32bit(&rptr);
2825 *csdata = rptr;
2826 }
2827 }
2828 return ret;
2829 }
2830
fs_writeend(uint64_t chunkid,uint32_t inode,uint64_t length)2831 uint8_t fs_writeend(uint64_t chunkid,uint32_t inode,uint64_t length) {
2832 uint8_t *wptr;
2833 const uint8_t *rptr;
2834 uint32_t i;
2835 uint8_t ret;
2836 threc *rec = fs_get_my_threc();
2837 wptr = fs_createpacket(rec,CLTOMA_FUSE_WRITE_CHUNK_END,20);
2838 if (wptr==NULL) {
2839 return ERROR_IO;
2840 }
2841 put64bit(&wptr,chunkid);
2842 put32bit(&wptr,inode);
2843 put64bit(&wptr,length);
2844 rptr = fs_sendandreceive(rec,MATOCL_FUSE_WRITE_CHUNK_END,&i);
2845 if (rptr==NULL) {
2846 ret = ERROR_IO;
2847 } else if (i==1) {
2848 ret = rptr[0];
2849 } else {
2850 pthread_mutex_lock(&fdlock);
2851 disconnect = 1;
2852 pthread_mutex_unlock(&fdlock);
2853 ret = ERROR_IO;
2854 }
2855 return ret;
2856 }
2857
2858
2859 // FUSE - META
2860
2861
fs_getsustained(const uint8_t ** dbuff,uint32_t * dbuffsize)2862 uint8_t fs_getsustained(const uint8_t **dbuff,uint32_t *dbuffsize) {
2863 uint8_t *wptr;
2864 const uint8_t *rptr;
2865 uint32_t i;
2866 uint8_t ret;
2867 threc *rec = fs_get_my_threc();
2868 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETSUSTAINED,0);
2869 if (wptr==NULL) {
2870 return ERROR_IO;
2871 }
2872 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETSUSTAINED,&i);
2873 if (rptr==NULL) {
2874 ret = ERROR_IO;
2875 } else if (i==1) {
2876 ret = rptr[0];
2877 } else {
2878 *dbuff = rptr;
2879 *dbuffsize = i;
2880 ret = STATUS_OK;
2881 }
2882 return ret;
2883 }
2884
fs_gettrash(const uint8_t ** dbuff,uint32_t * dbuffsize)2885 uint8_t fs_gettrash(const uint8_t **dbuff,uint32_t *dbuffsize) {
2886 uint8_t *wptr;
2887 const uint8_t *rptr;
2888 uint32_t i;
2889 uint8_t ret;
2890 threc *rec = fs_get_my_threc();
2891 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETTRASH,0);
2892 if (wptr==NULL) {
2893 return ERROR_IO;
2894 }
2895 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETTRASH,&i);
2896 if (rptr==NULL) {
2897 ret = ERROR_IO;
2898 } else if (i==1) {
2899 ret = rptr[0];
2900 } else {
2901 *dbuff = rptr;
2902 *dbuffsize = i;
2903 ret = STATUS_OK;
2904 }
2905 return ret;
2906 }
2907
fs_getdetachedattr(uint32_t inode,uint8_t attr[35])2908 uint8_t fs_getdetachedattr(uint32_t inode,uint8_t attr[35]) {
2909 uint8_t *wptr;
2910 const uint8_t *rptr;
2911 uint32_t i;
2912 uint8_t ret;
2913 threc *rec = fs_get_my_threc();
2914 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETDETACHEDATTR,4);
2915 if (wptr==NULL) {
2916 return ERROR_IO;
2917 }
2918 put32bit(&wptr,inode);
2919 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETDETACHEDATTR,&i);
2920 if (rptr==NULL) {
2921 ret = ERROR_IO;
2922 } else if (i==1) {
2923 ret = rptr[0];
2924 } else if (i!=35) {
2925 pthread_mutex_lock(&fdlock);
2926 disconnect = 1;
2927 pthread_mutex_unlock(&fdlock);
2928 ret = ERROR_IO;
2929 } else {
2930 memcpy(attr,rptr,35);
2931 ret = STATUS_OK;
2932 }
2933 return ret;
2934 }
2935
fs_gettrashpath(uint32_t inode,const uint8_t ** path)2936 uint8_t fs_gettrashpath(uint32_t inode,const uint8_t **path) {
2937 uint8_t *wptr;
2938 const uint8_t *rptr;
2939 uint32_t i;
2940 uint32_t pleng;
2941 uint8_t ret;
2942 threc *rec = fs_get_my_threc();
2943 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETTRASHPATH,4);
2944 if (wptr==NULL) {
2945 return ERROR_IO;
2946 }
2947 put32bit(&wptr,inode);
2948 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETTRASHPATH,&i);
2949 if (rptr==NULL) {
2950 ret = ERROR_IO;
2951 } else if (i==1) {
2952 ret = rptr[0];
2953 } else if (i<4) {
2954 pthread_mutex_lock(&fdlock);
2955 disconnect = 1;
2956 pthread_mutex_unlock(&fdlock);
2957 ret = ERROR_IO;
2958 } else {
2959 pleng = get32bit(&rptr);
2960 if (i!=4+pleng || pleng==0 || rptr[pleng-1]!=0) {
2961 pthread_mutex_lock(&fdlock);
2962 disconnect = 1;
2963 pthread_mutex_unlock(&fdlock);
2964 ret = ERROR_IO;
2965 } else {
2966 *path = rptr;
2967 ret = STATUS_OK;
2968 }
2969 }
2970 return ret;
2971 }
2972
fs_settrashpath(uint32_t inode,const uint8_t * path)2973 uint8_t fs_settrashpath(uint32_t inode,const uint8_t *path) {
2974 uint8_t *wptr;
2975 const uint8_t *rptr;
2976 uint32_t i;
2977 uint32_t pleng;
2978 uint8_t ret;
2979 threc *rec = fs_get_my_threc();
2980 pleng = strlen((const char *)path)+1;
2981 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETTRASHPATH,pleng+8);
2982 if (wptr==NULL) {
2983 return ERROR_IO;
2984 }
2985 put32bit(&wptr,inode);
2986 put32bit(&wptr,pleng);
2987 memcpy(wptr,path,pleng);
2988 // ptr+=pleng;
2989 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETTRASHPATH,&i);
2990 if (rptr==NULL) {
2991 ret = ERROR_IO;
2992 } else if (i==1) {
2993 ret = rptr[0];
2994 } else {
2995 pthread_mutex_lock(&fdlock);
2996 disconnect = 1;
2997 pthread_mutex_unlock(&fdlock);
2998 ret = ERROR_IO;
2999 }
3000 return ret;
3001 }
3002
fs_undel(uint32_t inode)3003 uint8_t fs_undel(uint32_t inode) {
3004 uint8_t *wptr;
3005 const uint8_t *rptr;
3006 uint32_t i;
3007 uint8_t ret;
3008 threc *rec = fs_get_my_threc();
3009 wptr = fs_createpacket(rec,CLTOMA_FUSE_UNDEL,4);
3010 if (wptr==NULL) {
3011 return ERROR_IO;
3012 }
3013 put32bit(&wptr,inode);
3014 rptr = fs_sendandreceive(rec,MATOCL_FUSE_UNDEL,&i);
3015 if (rptr==NULL) {
3016 ret = ERROR_IO;
3017 } else if (i==1) {
3018 ret = rptr[0];
3019 } else {
3020 pthread_mutex_lock(&fdlock);
3021 disconnect = 1;
3022 pthread_mutex_unlock(&fdlock);
3023 ret = ERROR_IO;
3024 }
3025 return ret;
3026 }
3027
fs_purge(uint32_t inode)3028 uint8_t fs_purge(uint32_t inode) {
3029 uint8_t *wptr;
3030 const uint8_t *rptr;
3031 uint32_t i;
3032 uint8_t ret;
3033 threc *rec = fs_get_my_threc();
3034 wptr = fs_createpacket(rec,CLTOMA_FUSE_PURGE,4);
3035 if (wptr==NULL) {
3036 return ERROR_IO;
3037 }
3038 put32bit(&wptr,inode);
3039 rptr = fs_sendandreceive(rec,MATOCL_FUSE_PURGE,&i);
3040 if (rptr==NULL) {
3041 ret = ERROR_IO;
3042 } else if (i==1) {
3043 ret = rptr[0];
3044 } else {
3045 pthread_mutex_lock(&fdlock);
3046 disconnect = 1;
3047 pthread_mutex_unlock(&fdlock);
3048 ret = ERROR_IO;
3049 }
3050 return ret;
3051 }
3052
fs_getacl(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t acltype,uint16_t * userperm,uint16_t * groupperm,uint16_t * otherperm,uint16_t * maskperm,uint16_t * namedusers,uint16_t * namedgroups,const uint8_t ** namedacls,uint32_t * namedaclssize)3053 uint8_t fs_getacl(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t acltype,uint16_t *userperm,uint16_t *groupperm,uint16_t *otherperm,uint16_t *maskperm,uint16_t *namedusers,uint16_t *namedgroups,const uint8_t **namedacls,uint32_t *namedaclssize) {
3054 uint8_t *wptr;
3055 const uint8_t *rptr;
3056 uint32_t i;
3057 uint8_t ret;
3058 threc *rec = fs_get_my_threc();
3059 *namedacls = NULL;
3060 *namedaclssize = 0;
3061 if (masterversion<VERSION2INT(2,0,0)) {
3062 return ERROR_ENOTSUP;
3063 }
3064 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETACL,14+4*gids);
3065 if (wptr==NULL) {
3066 return ERROR_IO;
3067 }
3068 put32bit(&wptr,inode);
3069 put8bit(&wptr,acltype);
3070 put8bit(&wptr,opened);
3071 put32bit(&wptr,uid);
3072 if (gids>0) {
3073 put32bit(&wptr,gids);
3074 for (i=0 ; i<gids ; i++) {
3075 put32bit(&wptr,gid[i]);
3076 }
3077 } else {
3078 put32bit(&wptr,0xFFFFFFFFU);
3079 }
3080 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETACL,&i);
3081 if (rptr==NULL) {
3082 ret = ERROR_IO;
3083 } else if (i==1) {
3084 ret = rptr[0];
3085 } else if (i<12) {
3086 pthread_mutex_lock(&fdlock);
3087 disconnect = 1;
3088 pthread_mutex_unlock(&fdlock);
3089 ret = ERROR_IO;
3090 } else {
3091 *userperm = get16bit(&rptr);
3092 *groupperm = get16bit(&rptr);
3093 *otherperm = get16bit(&rptr);
3094 *maskperm = get16bit(&rptr);
3095 *namedusers = get16bit(&rptr);
3096 *namedgroups = get16bit(&rptr);
3097 *namedacls = rptr;
3098 *namedaclssize = i-12;
3099 ret = STATUS_OK;
3100 }
3101 return ret;
3102 }
3103
fs_setacl(uint32_t inode,uint32_t uid,uint8_t acltype,uint16_t userperm,uint16_t groupperm,uint16_t otherperm,uint16_t maskperm,uint16_t namedusers,uint16_t namedgroups,uint8_t * namedacls,uint32_t namedaclssize)3104 uint8_t fs_setacl(uint32_t inode,uint32_t uid,uint8_t acltype,uint16_t userperm,uint16_t groupperm,uint16_t otherperm,uint16_t maskperm,uint16_t namedusers,uint16_t namedgroups,uint8_t *namedacls,uint32_t namedaclssize) {
3105 uint8_t *wptr;
3106 const uint8_t *rptr;
3107 uint32_t i;
3108 uint8_t ret;
3109 threc *rec = fs_get_my_threc();
3110 if (masterversion<VERSION2INT(2,0,0)) {
3111 return ERROR_ENOTSUP;
3112 }
3113 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETACL,21+namedaclssize);
3114 if (wptr==NULL) {
3115 return ERROR_IO;
3116 }
3117 put32bit(&wptr,inode);
3118 put32bit(&wptr,uid);
3119 put8bit(&wptr,acltype);
3120 put16bit(&wptr,userperm);
3121 put16bit(&wptr,groupperm);
3122 put16bit(&wptr,otherperm);
3123 put16bit(&wptr,maskperm);
3124 put16bit(&wptr,namedusers);
3125 put16bit(&wptr,namedgroups);
3126 memcpy(wptr,namedacls,namedaclssize);
3127 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETACL,&i);
3128 if (rptr==NULL) {
3129 ret = ERROR_IO;
3130 } else if (i==1) {
3131 ret = rptr[0];
3132 } else {
3133 pthread_mutex_lock(&fdlock);
3134 disconnect = 1;
3135 pthread_mutex_unlock(&fdlock);
3136 ret = ERROR_IO;
3137 }
3138 return ret;
3139 }
3140
fs_getxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t nleng,const uint8_t * name,uint8_t mode,const uint8_t ** vbuff,uint32_t * vleng)3141 uint8_t fs_getxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t nleng,const uint8_t *name,uint8_t mode,const uint8_t **vbuff,uint32_t *vleng) {
3142 uint8_t *wptr;
3143 const uint8_t *rptr;
3144 uint32_t i;
3145 uint8_t ret;
3146 uint8_t packetver;
3147 threc *rec = fs_get_my_threc();
3148 *vbuff = NULL;
3149 *vleng = 0;
3150 if (masterversion<VERSION2INT(1,7,0)) {
3151 return ERROR_ENOTSUP;
3152 }
3153 if (masterversion<VERSION2INT(2,0,0)) {
3154 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15+nleng);
3155 packetver = 0;
3156 } else {
3157 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15+nleng+4*gids);
3158 packetver = 1;
3159 }
3160 if (wptr==NULL) {
3161 return ERROR_IO;
3162 }
3163 put32bit(&wptr,inode);
3164 if (packetver==0) {
3165 put8bit(&wptr,opened);
3166 put32bit(&wptr,uid);
3167 if (gids>0) {
3168 put32bit(&wptr,gid[0]);
3169 } else {
3170 put32bit(&wptr,0xFFFFFFFFU);
3171 }
3172 }
3173 put8bit(&wptr,nleng);
3174 memcpy(wptr,name,nleng);
3175 wptr+=nleng;
3176 put8bit(&wptr,mode);
3177 if (packetver>=1) {
3178 put8bit(&wptr,opened);
3179 put32bit(&wptr,uid);
3180 if (gids>0) {
3181 put32bit(&wptr,gids);
3182 for (i=0 ; i<gids ; i++) {
3183 put32bit(&wptr,gid[i]);
3184 }
3185 } else {
3186 put32bit(&wptr,0xFFFFFFFFU);
3187 }
3188 }
3189 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETXATTR,&i);
3190 if (rptr==NULL) {
3191 ret = ERROR_IO;
3192 } else if (i==1) {
3193 ret = rptr[0];
3194 } else if (i<4) {
3195 pthread_mutex_lock(&fdlock);
3196 disconnect = 1;
3197 pthread_mutex_unlock(&fdlock);
3198 ret = ERROR_IO;
3199 } else {
3200 *vleng = get32bit(&rptr);
3201 *vbuff = (mode==MFS_XATTR_GETA_DATA)?rptr:NULL;
3202 if ((mode==MFS_XATTR_GETA_DATA && i!=(*vleng)+4) || (mode==MFS_XATTR_LENGTH_ONLY && i!=4)) {
3203 pthread_mutex_lock(&fdlock);
3204 disconnect = 1;
3205 pthread_mutex_unlock(&fdlock);
3206 ret = ERROR_IO;
3207 } else {
3208 ret = STATUS_OK;
3209 }
3210 }
3211 return ret;
3212 }
3213
fs_listxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t mode,const uint8_t ** dbuff,uint32_t * dleng)3214 uint8_t fs_listxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t mode,const uint8_t **dbuff,uint32_t *dleng) {
3215 uint8_t *wptr;
3216 const uint8_t *rptr;
3217 uint32_t i;
3218 uint8_t ret;
3219 uint8_t packetver;
3220 threc *rec = fs_get_my_threc();
3221 if (masterversion<VERSION2INT(1,7,0)) {
3222 return ERROR_ENOTSUP;
3223 }
3224 if (masterversion<VERSION2INT(2,0,0)) {
3225 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15);
3226 packetver = 0;
3227 } else {
3228 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15+4*gids);
3229 packetver = 1;
3230 }
3231 if (wptr==NULL) {
3232 return ERROR_IO;
3233 }
3234 put32bit(&wptr,inode);
3235 if (packetver==0) {
3236 put8bit(&wptr,opened);
3237 put32bit(&wptr,uid);
3238 if (gids>0) {
3239 put32bit(&wptr,gid[0]);
3240 } else {
3241 put32bit(&wptr,0xFFFFFFFFU);
3242 }
3243 }
3244 put8bit(&wptr,0);
3245 put8bit(&wptr,mode);
3246 if (packetver>=1) {
3247 put8bit(&wptr,opened);
3248 put32bit(&wptr,uid);
3249 if (gids>0) {
3250 put32bit(&wptr,gids);
3251 for (i=0 ; i<gids ; i++) {
3252 put32bit(&wptr,gid[i]);
3253 }
3254 } else {
3255 put32bit(&wptr,0xFFFFFFFFU);
3256 }
3257 }
3258 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETXATTR,&i);
3259 if (rptr==NULL) {
3260 ret = ERROR_IO;
3261 } else if (i==1) {
3262 ret = rptr[0];
3263 } else if (i<4) {
3264 pthread_mutex_lock(&fdlock);
3265 disconnect = 1;
3266 pthread_mutex_unlock(&fdlock);
3267 ret = ERROR_IO;
3268 } else {
3269 *dleng = get32bit(&rptr);
3270 *dbuff = (mode==MFS_XATTR_GETA_DATA)?rptr:NULL;
3271 if ((mode==MFS_XATTR_GETA_DATA && i!=(*dleng)+4) || (mode==MFS_XATTR_LENGTH_ONLY && i!=4)) {
3272 pthread_mutex_lock(&fdlock);
3273 disconnect = 1;
3274 pthread_mutex_unlock(&fdlock);
3275 ret = ERROR_IO;
3276 } else {
3277 ret = STATUS_OK;
3278 }
3279 }
3280 return ret;
3281 }
3282
fs_setxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t nleng,const uint8_t * name,uint32_t vleng,const uint8_t * value,uint8_t mode)3283 uint8_t fs_setxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t nleng,const uint8_t *name,uint32_t vleng,const uint8_t *value,uint8_t mode) {
3284 uint8_t *wptr;
3285 const uint8_t *rptr;
3286 uint32_t i;
3287 uint8_t ret;
3288 uint8_t packetver;
3289 threc *rec = fs_get_my_threc();
3290 if (masterversion<VERSION2INT(1,7,0)) {
3291 return ERROR_ENOTSUP;
3292 }
3293 if (mode>=MFS_XATTR_REMOVE) {
3294 return ERROR_EINVAL;
3295 }
3296 if (masterversion<VERSION2INT(2,0,0)) {
3297 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng+vleng);
3298 packetver = 0;
3299 } else {
3300 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng+vleng+4*gids);
3301 packetver = 1;
3302 }
3303 if (wptr==NULL) {
3304 return ERROR_IO;
3305 }
3306 put32bit(&wptr,inode);
3307 if (packetver==0) {
3308 put8bit(&wptr,opened);
3309 put32bit(&wptr,uid);
3310 if (gids>0) {
3311 put32bit(&wptr,gid[0]);
3312 } else {
3313 put32bit(&wptr,0xFFFFFFFFU);
3314 }
3315 }
3316 put8bit(&wptr,nleng);
3317 memcpy(wptr,name,nleng);
3318 wptr+=nleng;
3319 put32bit(&wptr,vleng);
3320 memcpy(wptr,value,vleng);
3321 wptr+=vleng;
3322 put8bit(&wptr,mode);
3323 if (packetver>=1) {
3324 put8bit(&wptr,opened);
3325 put32bit(&wptr,uid);
3326 if (gids>0) {
3327 put32bit(&wptr,gids);
3328 for (i=0 ; i<gids ; i++) {
3329 put32bit(&wptr,gid[i]);
3330 }
3331 } else {
3332 put32bit(&wptr,0xFFFFFFFFU);
3333 }
3334 }
3335 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETXATTR,&i);
3336 if (rptr==NULL) {
3337 ret = ERROR_IO;
3338 } else if (i==1) {
3339 ret = rptr[0];
3340 } else {
3341 pthread_mutex_lock(&fdlock);
3342 disconnect = 1;
3343 pthread_mutex_unlock(&fdlock);
3344 ret = ERROR_IO;
3345 }
3346 return ret;
3347 }
3348
fs_removexattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t * gid,uint8_t nleng,const uint8_t * name)3349 uint8_t fs_removexattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gids,uint32_t *gid,uint8_t nleng,const uint8_t *name) {
3350 uint8_t *wptr;
3351 const uint8_t *rptr;
3352 uint32_t i;
3353 uint8_t ret;
3354 uint8_t packetver;
3355 threc *rec = fs_get_my_threc();
3356 if (masterversion<VERSION2INT(1,7,0)) {
3357 return ERROR_ENOTSUP;
3358 }
3359 if (masterversion<VERSION2INT(2,0,0)) {
3360 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng);
3361 packetver = 0;
3362 } else {
3363 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng+4*gids);
3364 packetver = 1;
3365 }
3366 if (wptr==NULL) {
3367 return ERROR_IO;
3368 }
3369 put32bit(&wptr,inode);
3370 if (packetver==0) {
3371 put8bit(&wptr,opened);
3372 put32bit(&wptr,uid);
3373 if (gids>0) {
3374 put32bit(&wptr,gid[0]);
3375 } else {
3376 put32bit(&wptr,0xFFFFFFFFU);
3377 }
3378 }
3379 put8bit(&wptr,nleng);
3380 memcpy(wptr,name,nleng);
3381 wptr+=nleng;
3382 put32bit(&wptr,0);
3383 put8bit(&wptr,MFS_XATTR_REMOVE);
3384 if (packetver>=1) {
3385 put8bit(&wptr,opened);
3386 put32bit(&wptr,uid);
3387 if (gids>0) {
3388 put32bit(&wptr,gids);
3389 for (i=0 ; i<gids ; i++) {
3390 put32bit(&wptr,gid[i]);
3391 }
3392 } else {
3393 put32bit(&wptr,0xFFFFFFFFU);
3394 }
3395 }
3396 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETXATTR,&i);
3397 if (rptr==NULL) {
3398 ret = ERROR_IO;
3399 } else if (i==1) {
3400 ret = rptr[0];
3401 } else {
3402 pthread_mutex_lock(&fdlock);
3403 disconnect = 1;
3404 pthread_mutex_unlock(&fdlock);
3405 ret = ERROR_IO;
3406 }
3407 return ret;
3408 }
3409
fs_custom(uint32_t qcmd,const uint8_t * query,uint32_t queryleng,uint32_t * acmd,uint8_t * answer,uint32_t * answerleng)3410 uint8_t fs_custom(uint32_t qcmd,const uint8_t *query,uint32_t queryleng,uint32_t *acmd,uint8_t *answer,uint32_t *answerleng) {
3411 uint8_t *wptr;
3412 const uint8_t *rptr;
3413 uint32_t i;
3414 uint8_t ret;
3415 threc *rec = fs_get_my_threc();
3416 wptr = fs_createpacket(rec,qcmd,queryleng);
3417 if (wptr==NULL) {
3418 return ERROR_IO;
3419 }
3420 memcpy(wptr,query,queryleng);
3421 rptr = fs_sendandreceive_any(rec,acmd,&i);
3422 if (rptr==NULL) {
3423 ret = ERROR_IO;
3424 } else {
3425 if (*answerleng<i) {
3426 ret = ERROR_EINVAL;
3427 } else {
3428 *answerleng = i;
3429 memcpy(answer,rptr,i);
3430 ret = STATUS_OK;
3431 }
3432 }
3433 return ret;
3434 }
3435
3436 /*
3437 uint8_t fs_append(uint32_t inode,uint32_t ainode,uint32_t uid,uint32_t gid) {
3438 uint8_t *wptr;
3439 const uint8_t *rptr;
3440 uint32_t i;
3441 uint8_t ret;
3442 threc *rec = fs_get_my_threc();
3443 wptr = fs_createpacket(rec,CLTOMA_FUSE_APPEND,16);
3444 if (wptr==NULL) {
3445 return ERROR_IO;
3446 }
3447 put32bit(&wptr,inode);
3448 put32bit(&wptr,ainode);
3449 put32bit(&wptr,uid);
3450 put32bit(&wptr,gid);
3451 rptr = fs_sendandreceive(rec,MATOCL_FUSE_APPEND,&i);
3452 if (rptr==NULL) {
3453 ret = ERROR_IO;
3454 } else if (i==1) {
3455 ret = rptr[0];
3456 } else {
3457 pthread_mutex_lock(&fdlock);
3458 disconnect = 1;
3459 pthread_mutex_unlock(&fdlock);
3460 ret = ERROR_IO;
3461 }
3462 return ret;
3463 }
3464 */
3465