1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27 /* Something unusual: Lyrics
28 *
29 * That file contains only one useful function:
30 *
31 * XFS_Private_InitOperations
32 *
33 * it needed to fill fuse_operations structure.
34 *
35 * I put here all possible ( for 2.5 ) stubs to fuse_operations
36 * functions. However, I will use only several of them while
37 * structure initialisation. So, if You want to extend functionality,
38 * please edit already ready stub and add new function to structure
39 * initialized .
40 *
41 */
42
43 #include <klib/out.h>
44 #include <klib/namelist.h>
45 #include <klib/refcount.h>
46 #include <klib/defs.h>
47 #include <klib/log.h>
48 #include <vfs/path.h>
49 #include <vfs/manager.h>
50
51
52 #include <xfs/tree.h>
53 #include <xfs/node.h>
54 #include <xfs/handle.h>
55 #include <xfs/editors.h>
56 #include <xfs/perm.h>
57 #include <xfs/path.h>
58
59 #include "schwarzschraube.h"
60
61 #include <sysalloc.h>
62 #include <string.h> /* we are using memset() */
63 #include <dirent.h>
64 #include <unistd.h>
65
66 #include <errno.h>
67 #include <sys/types.h>
68 #include <sys/stat.h>
69 #include <sys/statvfs.h>
70
71 #include "operations.h"
72
73
74 /****************************************************************
75 * Something weird, but it could simplify somebody's life
76 *
77 * FUSE method Use/Not Implemented Comment
78 ****************************************************************/
79 #define USE_XFS_FUSE_GETATTR 1 /* + */
80 #define USE_XFS_FUSE_READLINK 0 /* - */ /* ? */
81 #define USE_XFS_FUSE_GETDIR 0 /* - */ /* Obsolete method */
82 #define USE_XFS_FUSE_MKNOD 0 /* - */ /* Do not need */
83 #define USE_XFS_FUSE_MKDIR 1 /* + */
84 #define USE_XFS_FUSE_UNLINK 1 /* + */
85 #define USE_XFS_FUSE_RMDIR 1 /* + */
86 #define USE_XFS_FUSE_SYMLINK 0 /* - */ /* ? */
87 #define USE_XFS_FUSE_RENAME 1 /* + */
88 #define USE_XFS_FUSE_LINK 0 /* - */ /* ? */
89 #define USE_XFS_FUSE_CHMOD 1 /* - */ /* ? */
90 #define USE_XFS_FUSE_CHOWN 0 /* - */ /* Do not need */
91 #define USE_XFS_FUSE_TRUNCATE 1 /* + */
92 #define USE_XFS_FUSE_UTIME 1 /* + */
93 #define USE_XFS_FUSE_OPEN 1 /* + */
94 #define USE_XFS_FUSE_READ 1 /* + */
95 #define USE_XFS_FUSE_WRITE 1 /* + */
96 #define USE_XFS_FUSE_STATFS 0 /* - */ /* ? */
97 #define USE_XFS_FUSE_FLUSH 0 /* - */ /* Dummy ... ? */
98 #define USE_XFS_FUSE_RELEASE 1 /* + */
99 #define USE_XFS_FUSE_FSYNC 1 /* + */ /* ? */
100 #define USE_XFS_FUSE_SETXATTR 0 /* - */ /* Do not need */
101 #define USE_XFS_FUSE_GETXATTR 0 /* - */ /* Do not need */
102 #define USE_XFS_FUSE_LISTXATTR 0 /* - */ /* Do not need */
103 #define USE_XFS_FUSE_REMOVEXATTR 0 /* - */ /* Do not need */
104 #define USE_XFS_FUSE_OPENDIR 1 /* + */
105 #define USE_XFS_FUSE_READDIR 1 /* + */
106 #define USE_XFS_FUSE_RELEASEDIR 1 /* + */
107 #define USE_XFS_FUSE_FSYNCDIR 0 /* - */ /* ? */
108 #define USE_XFS_FUSE_INIT 1 /* + */ /* Dummy ??? */
109 #define USE_XFS_FUSE_DESTROY 1 /* + */ /* Dummy ??? */
110 #define USE_XFS_FUSE_ACCESS 1 /* + */
111 #define USE_XFS_FUSE_CREATE 1 /* + */
112 #define USE_XFS_FUSE_FTRUNCATE 1 /* + */ /* ? */
113 #define USE_XFS_FUSE_FGETATTR 1 /* + */
114 #define USE_XFS_FUSE_LOCK 0 /* - */ /* Do not need */
115 #define USE_XFS_FUSE_UTIMENS 0 /* - */ /* Do not need */
116 #define USE_XFS_FUSE_BMAP 0 /* - */ /* Do not need */
117 #define USE_XFS_FUSE_IOCTL 0 /* - */ /* Do not need */
118 #define USE_XFS_FUSE_POLL 0 /* - */ /* Do not need */
119
120
121 /*****************************************************
122 * Something unusual
123 * NOTE: that procedure is getting presetted peer from
124 * fuse_context structure and context is valid
125 * only while operation call. So, do not use that
126 * method withoud being harmed
127 *****************************************************/
128 static
129 rc_t
_FUSE_tree_depot(const struct XFSTreeDepot ** Depot)130 _FUSE_tree_depot ( const struct XFSTreeDepot ** Depot )
131 {
132 struct fuse_context * TheContext = NULL;
133
134 XFS_CSAN ( Depot )
135 XFS_CAN ( Depot )
136
137 TheContext = fuse_get_context();
138 if ( TheContext == NULL ) {
139 LogErr (
140 klogErr,
141 XFS_RC ( rcNull ),
142 "ERROR: improper usage of 'fuse_get_context()'"
143 );
144 return XFS_RC ( rcNull );
145 }
146
147 * Depot = ( const struct XFSTreeDepot * ) TheContext -> private_data;
148 XFS_CAN ( * Depot )
149
150 return 0;
151 } /* _FUSE_tree_depot () */
152
153 static
154 rc_t
_FUSE_make_v_path(const char * ThePath,const struct VPath ** DasPath)155 _FUSE_make_v_path (
156 const char * ThePath,
157 const struct VPath ** DasPath
158 )
159 {
160 rc_t RCt;
161 struct VPath * Pth;
162
163 RCt = 0;
164 Pth = NULL;
165
166 XFS_CSAN ( DasPath )
167 XFS_CAN ( ThePath )
168 XFS_CAN ( DasPath )
169
170 RCt = VFSManagerMakePath ( XFS_VfsManager (), & Pth, ThePath );
171 if ( RCt == 0 ) {
172 * DasPath = Pth;
173 }
174
175 return RCt;
176 } /* _FUSE_make_v_path () */
177
178 static
179 rc_t
_FUSE_get_node(const struct VPath * Path,const struct XFSNode ** Node)180 _FUSE_get_node (
181 const struct VPath * Path,
182 const struct XFSNode ** Node
183 )
184 {
185 rc_t RCt;
186 const struct XFSTreeDepot * Depot;
187 const struct XFSNode * TheNode;
188
189 RCt = 0;
190 Depot = NULL;
191 TheNode = NULL;
192
193 XFS_CSAN ( Node )
194 XFS_CAN ( Path )
195 XFS_CAN ( Node )
196
197 RCt = _FUSE_tree_depot ( & Depot );
198 if ( RCt == 0 ) {
199 if ( Depot == NULL ) {
200 RCt = XFS_RC ( rcInvalid );
201 }
202 else {
203 RCt = XFSTreeDepotFindNodeForPath (
204 Depot,
205 Path,
206 & TheNode
207 );
208 if ( RCt == 0 ) {
209 * Node = TheNode;
210 }
211 }
212 }
213
214 return RCt;
215 } /* _FUSE_get_node () */
216
217 static
218 rc_t
_FUSE_get_path_and_node(const char * ThePath,const struct VPath ** DasPath,const struct XFSNode ** Node,XFSNType * NodeType)219 _FUSE_get_path_and_node (
220 const char * ThePath,
221 const struct VPath ** DasPath,
222 const struct XFSNode ** Node,
223 XFSNType * NodeType
224 )
225 {
226 rc_t RCt;
227 const struct XFSNode * RNode;
228 const struct VPath * RPath;
229 XFSNType Type;
230 const struct XFSAttrEditor * Editor;
231
232 RCt = 0;
233 RNode = NULL;
234 RPath = NULL;
235 Type = kxfsNotFound;
236 Editor = NULL;
237
238 XFS_CSAN ( DasPath )
239 XFS_CSAN ( Node )
240 XFS_CAN ( ThePath )
241
242 RCt = _FUSE_make_v_path ( ThePath, & RPath );
243 if ( RCt == 0 ) {
244
245 RCt = _FUSE_get_node ( RPath, & RNode );
246 if ( RCt == 0 ) {
247 if ( NodeType != NULL ) {
248 RCt = XFSNodeAttrEditor ( RNode, & Editor );
249 if ( RCt == 0 ) {
250 RCt = XFSAttrEditorType ( Editor, & Type );
251
252 XFSEditorDispose ( & ( Editor -> Papahen ) );
253 }
254 }
255 }
256 }
257
258 if ( RCt == 0 ) {
259 if ( DasPath != NULL ) {
260 * DasPath = RPath;
261 }
262 else {
263 VPathRelease ( RPath );
264 }
265
266 if ( Node != NULL ) {
267 * Node = RNode;
268 }
269 else {
270 XFSNodeRelease ( RNode );
271 }
272
273 if ( NodeType != NULL ) {
274 * NodeType = Type;
275 }
276 }
277 else {
278 if ( RPath != NULL ) {
279 VPathRelease ( RPath );
280 }
281
282 if ( RNode != NULL ) {
283 XFSNodeRelease ( RNode );
284 }
285 }
286
287 return RCt;
288 } /* _FUSE_get_path_and_node () */
289
290 static
291 rc_t
_FUSE_get_parent_node(const char * Path,const struct XFSNode ** Parent,XFSNType * ParentType,char ** ChildName)292 _FUSE_get_parent_node (
293 const char * Path,
294 const struct XFSNode ** Parent,
295 XFSNType * ParentType, /* Could be NULL */
296 char ** ChildName /* Could be NULL */
297 )
298 {
299 rc_t RCt;
300 const struct XFSTreeDepot * Depot;
301 const struct XFSPath * xPath;
302 uint32_t xPathQ;
303 const struct XFSNode * xNode;
304 const struct XFSAttrEditor * xEditor;
305 char * xName;
306 const struct XFSPath * xParent;
307
308 RCt = 0;
309 Depot = NULL;
310 xPath = NULL;
311 xPathQ = 0;
312 xNode = NULL;
313 xEditor = NULL;
314 xName = NULL;
315 xParent = NULL;
316
317 XFS_CSAN ( Parent )
318 XFS_CSA ( ParentType, kxfsNotFound )
319 XFS_CSAN ( ChildName )
320 XFS_CAN ( Path )
321 XFS_CAN ( Parent )
322
323 /* TreeDepot is a key */
324 RCt = _FUSE_tree_depot ( & Depot );
325 if ( RCt != 0 ) {
326 return RCt;
327 }
328
329 /* Path to parent node is ... */
330 RCt = XFSPathMake ( & xPath, true, Path );
331 if ( RCt == 0 ) {
332 xPathQ = XFSPathPartCount ( xPath );
333 if ( xPathQ < 2 ) {
334 RCt = XFS_RC ( rcInvalid );
335 }
336 else {
337 /* So, there is a path to parent */
338 RCt = XFSPathParent ( xPath, & xParent );
339 if ( RCt == 0 ) {
340 /* Looking for node */
341 RCt = XFSTreeDepotFindNode (
342 Depot,
343 XFSPathGet ( xParent ),
344 & xNode
345 );
346 if ( RCt == 0 ) {
347 if ( ParentType != NULL ) {
348 RCt = XFSNodeAttrEditor ( xNode, & xEditor );
349 if ( RCt == 0 ) {
350 RCt = XFSAttrEditorType ( xEditor, ParentType );
351 XFSEditorDispose ( & ( xEditor -> Papahen ) );
352 }
353 }
354
355 if ( RCt == 0 ) {
356 if ( ChildName != NULL ) {
357 RCt = XFS_StrDup (
358 XFSPathName ( xPath ),
359 ( const char ** ) & xName
360 );
361 if ( RCt == 0 ) {
362 * ChildName = xName;
363 }
364 }
365 }
366
367 if ( RCt == 0 ) {
368 * Parent = xNode;
369 }
370 }
371
372 XFSPathRelease ( xParent );
373 }
374 }
375
376 XFSPathRelease ( xPath );
377 }
378
379 if ( RCt != 0 ) {
380 * Parent = NULL;
381 if ( ParentType != NULL ) {
382 * ParentType = kxfsNotFound;
383 }
384 if ( ChildName != NULL ) {
385 * ChildName = NULL;
386 }
387 if ( xNode != NULL ) {
388 XFSNodeRelease ( xNode );
389 }
390 if ( xName != NULL ) {
391 free ( xName );
392 }
393 }
394
395 return RCt;
396 } /* _FUSE_get_parent_node () */
397
398 static
399 rc_t
_FUSE_delete_file_dir(const char * Path)400 _FUSE_delete_file_dir ( const char * Path )
401 {
402 rc_t RCt;
403 const struct XFSNode * Parent;
404 char * Child;
405 const struct XFSDirEditor * Editor;
406
407 RCt = 0;
408 Parent = NULL;
409 Child = NULL;
410 Editor = NULL;
411
412 XFS_CAN ( Path )
413
414 RCt = _FUSE_get_parent_node ( Path, & Parent, NULL, & Child );
415 if ( RCt == 0 ) {
416 RCt = XFSNodeDirEditor ( Parent, & Editor );
417 if ( RCt == 0 ) {
418 RCt = XFSDirEditorDelete ( Editor, Child );
419
420 XFSEditorDispose ( & ( Editor -> Papahen ) );
421 }
422
423 XFSNodeRelease ( Parent );
424 free ( Child );
425 }
426
427 return RCt;
428 } /* _FUSE_delete_file_dir () */
429
430 /*****************************************************
431 * Here are convertors
432 *****************************************************/
433 /*)
434 |*| Converts permission string to stat mode_t
435 (*/
436 static
437 rc_t
_FUSE_char_to_perm(const char * Perm,XFSNType Type,mode_t * Mode)438 _FUSE_char_to_perm ( const char * Perm, XFSNType Type, mode_t * Mode )
439 {
440 rc_t RCt;
441 uint32_t Temp;
442
443 RCt = 0;
444 Temp = 0;
445
446 XFS_CSA ( Mode, 0 )
447 XFS_CAN ( Mode )
448
449 if ( Perm == NULL ) {
450 Temp = Type == kxfsFile ? 0644 : 0744;
451 }
452 else {
453 RCt = XFSPermToNum ( Perm, & Temp );
454 }
455
456 if ( RCt == 0 ) {
457 switch ( Type ) {
458 case kxfsFile : Temp |= S_IFREG; break;
459 case kxfsDir: Temp |= S_IFDIR; break;
460 case kxfsLink: Temp |= S_IFLNK; break;
461 default: Temp = 0; break;
462 }
463
464 if ( Temp == 0 ) {
465 RCt = XFS_RC ( rcInvalid );
466 }
467 else {
468 * Mode = Temp;
469 }
470 }
471
472 return RCt;
473 } /* _FUSE_char_to_perm () */
474
475 static
476 rc_t
_FUSE_stat_for_node(const struct XFSNode * Node,struct stat * Stat,const struct XFSFileEditor * FileEditor)477 _FUSE_stat_for_node (
478 const struct XFSNode * Node,
479 struct stat * Stat,
480 const struct XFSFileEditor * FileEditor
481 )
482 {
483 rc_t RCt;
484 XFSNType Type;
485 KTime_t Time;
486 uint64_t Size;
487 const struct XFSAttrEditor * AttrEditor;
488 const char * Perm;
489
490 RCt = 0;
491 Type = kxfsNotFound;
492 Time = 0;
493 Size = 0;
494 AttrEditor = NULL;
495 Perm = NULL;
496
497 XFS_CAN ( Node )
498 XFS_CAN ( Stat )
499
500 RCt = XFSNodeAttrEditor ( Node, & AttrEditor );
501 if ( RCt != 0 || AttrEditor == NULL ) {
502 return XFS_RC ( rcInvalid );
503 }
504
505 /*) Here we are doing security ... later
506 / TODO Stat -> st_mode = SomeAccess
507 (*/
508
509 RCt = XFSAttrEditorType ( AttrEditor, & Type );
510 if ( RCt == 0 ) {
511 Stat -> st_mode = 0;
512 Stat -> st_uid = getuid();
513 Stat -> st_gid = getgid();
514
515 if ( XFSAttrEditorPermissions ( AttrEditor, & Perm ) == 0 ) {
516 _FUSE_char_to_perm ( Perm, Type, & ( Stat -> st_mode ) );
517 }
518
519 if ( XFSAttrEditorDate ( AttrEditor, & Time ) == 0 ) {
520 Stat -> st_atime = Time;
521 Stat -> st_mtime = Time;
522 Stat -> st_ctime = Time;
523 }
524
525 Stat -> st_blksize = XFS_SIZE_4096 * 8;
526 Stat -> st_size = 0;
527 if ( Type != kxfsDir ) {
528 if ( FileEditor != NULL ) {
529 if ( XFSFileEditorSize ( FileEditor, & Size ) == 0 ) {
530 Stat -> st_size = Size;
531 }
532 }
533 else {
534 if ( XFSNodeFileEditor ( Node, & FileEditor ) == 0 ) {
535 if ( FileEditor != NULL ) {
536 if ( XFSFileEditorSize ( FileEditor, & Size ) == 0 ) {
537 Stat -> st_size = Size;
538 }
539 XFSEditorDispose ( & ( FileEditor -> Papahen ) );
540 }
541 }
542 }
543 }
544 }
545
546 XFSEditorDispose ( & ( AttrEditor -> Papahen ) );
547
548 return RCt;
549 } /* _FUSE_stat_for_node () */
550
551 /*
552 $ Cache for less :)
553 $ Apparently, I can not to interpret all errors correctly, and
554 $ I will to the same thing as Anton: return EBADF.
555 */
556 static
557 int
XFS_FUSE_rc_to_errno(rc_t RCt)558 XFS_FUSE_rc_to_errno ( rc_t RCt )
559 {
560 uint32_t Target, Object, State;
561
562 Target = Object = State = 0;
563
564 State = GetRCState ( RCt );
565 if ( State == rcNoErr ) {
566 return 0;
567 }
568
569 Target = GetRCTarget ( RCt );
570 Object = GetRCObject ( RCt );
571
572 if ( State == rcUnknown && Object == rcTransfer ) {
573 return EIO;
574 }
575
576 if ( Target == rcNoTarg && Object == rcNoObj ) {
577 switch ( State ) {
578 /* Missed Peer method */
579 case rcUnsupported : return ENOSYS;
580 /* Some of peer parametes was NULL */
581 case rcNull : return EFAULT;
582 /* Something is wrong */
583 case rcUnknown : return EBADF;
584 }
585
586 return EBADF;
587 }
588
589 if ( Target == rcDirectory ) {
590 switch ( State ) {
591 case rcUnauthorized : return EACCES;
592 case rcExhausted : return Object == rcStorage
593 ? ENOSPC
594 : ENOMEM
595 ;
596 case rcNotFound : return ENOENT;
597 case rcInvalid :
598 case rcIncorrect : return EINVAL;
599 case rcExcessive : return Object == rcParam
600 ? EFBIG
601 : ENAMETOOLONG
602 ;
603 case rcExists : return EEXIST;
604 case rcBusy : return EBUSY;
605 case rcIncomplete : return EINTR;
606 }
607
608 return EBADF;
609 }
610
611 if ( Target == rcFile ) {
612 switch ( State ) {
613 case rcExhausted : return Object == rcStorage
614 ? ENOSPC
615 : ENOMEM
616 ;
617 case rcIncomplete : return EINTR;
618 case rcExcessive : return EFBIG;
619 case rcIncorrect : return EISDIR;
620 case rcReadonly : return EROFS;
621 case rcInvalid : return EINVAL;
622 }
623
624 return EBADF;
625 }
626
627 if ( Object == rcMemMap ) {
628 switch ( State ) {
629 case rcNoPerm : return EACCES;
630 case rcInvalid : return EBADF;
631 case rcIncomplete : return EAGAIN;
632 case rcExhausted : return ENOMEM;
633 }
634
635 return EBADF;
636 }
637
638 return EBADF;
639 } /* XFS_FUSE_rc_to_errno () */
640
641
642 /*****************************************************
643 * Operations
644 *****************************************************/
645
646 /*****************************************************/
647 #if USE_XFS_FUSE_GETATTR == 1
648
649 static
650 int
XFS_FUSE_getattr(const char * ThePath,struct stat * TheStat)651 XFS_FUSE_getattr ( const char * ThePath, struct stat * TheStat )
652 {
653 rc_t RCt;
654 const struct XFSNode * Node;
655 XFSNType Type;
656
657 RCt = 0;
658 Node = NULL;
659 Type = kxfsNotFound;
660
661 pLogMsg ( klogDebug, "GETATTR(Fuse): [$(path)]", "path=%s", ThePath );
662
663 if ( ThePath == NULL || TheStat == NULL ) {
664 pLogMsg ( klogDebug, "GETATTR(Fuse,cont): [$(path)] [INVALID]", "path=%s", ThePath );
665 return EINVAL * - 1;
666 }
667 memset ( TheStat, 0, sizeof ( struct stat ) );
668
669 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, & Type );
670 if ( RCt == 0 ) {
671 if ( Type == kxfsNotFound ) {
672 XFSNodeRelease ( Node );
673
674 pLogMsg ( klogDebug, "GETATTR(Fuse,cont): [$(path)] [NotFound]", "path=%s", ThePath );
675 return ENOENT * - 1;
676 }
677
678 RCt = _FUSE_stat_for_node ( Node, TheStat, NULL );
679
680 XFSNodeRelease ( Node );
681 }
682
683 pLogMsg ( klogDebug, "GETATTR(Fuse,cont): [$(path)] [$(rc)]", "path=%s,rc=%d", ThePath, RCt );
684
685 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
686 } /* XFS_FUSE_getattr() */
687
688 #endif /* USE_XFS_FUSE_GETATTR == 1 */
689
690 /*****************************************************/
691 #if USE_XFS_FUSE_READLINK == 1
692
693 static
694 int
XFS_FUSE_readlink(const char * ThePath,char * RetBuf,size_t RetBufSize)695 XFS_FUSE_readlink (
696 const char * ThePath,
697 char * RetBuf,
698 size_t RetBufSize
699 )
700 {
701 pLogMsg ( klogDebug, "READLINK(!): [$(path)]", "path=%s", ThePath );
702
703 return -EPERM;
704 } /* XFS_FUSE_readlink() */
705
706 #endif /* USE_XFS_FUSE_READLINK == 1 */
707
708 /*****************************************************/
709 #if USE_XFS_FUSE_GETDIR == 1
710
711 static
712 int
XFS_FUSE_getdir(const char * ThePath,fuse_dirh_t TheFDH,fuse_dirfil_t TheFDF)713 XFS_FUSE_getdir (
714 const char * ThePath,
715 fuse_dirh_t TheFDH,
716 fuse_dirfil_t TheFDF
717 )
718 {
719 pLogMsg ( klogDebug, "GETDIR(!): [$(path)]", "path=%s", ThePath );
720
721 return -EPERM;
722 } /* XFS_FUSE_getdir() */
723
724 #endif /* USE_XFS_FUSE_GETDIR == 1 */
725
726 /*****************************************************/
727 #if USE_XFS_FUSE_MKNOD == 1
728
729 static
730 int
XFS_FUSE_mknod(const char * ThePath,mode_t TheMode,dev_t TheDev)731 XFS_FUSE_mknod ( const char * ThePath, mode_t TheMode, dev_t TheDev )
732 {
733 pLogMsg ( klogDebug, "MKNOD(!): [$(path)]", "path=%s", ThePath );
734
735 return -EPERM;
736 } /* XFS_FUSE_mknod() */
737
738 #endif /* USE_XFS_FUSE_MKNOD == 1 */
739
740 /*****************************************************/
741 #if USE_XFS_FUSE_MKDIR == 1
742
743 static
744 int
XFS_FUSE_mkdir(const char * ThePath,mode_t TheMode)745 XFS_FUSE_mkdir ( const char * ThePath, mode_t TheMode )
746 {
747 rc_t RCt;
748 const struct XFSNode * Parent;
749 char * Child;
750 const struct XFSDirEditor * Editor;
751
752 RCt = 0;
753 Parent = NULL;
754 Child = NULL;
755 Editor = NULL;
756
757 pLogMsg ( klogDebug, "MKDIR(Fuse): [$(path)] MD[$(mode)]", "path=%s,mode=%d", ThePath, TheMode );
758
759 if ( ThePath == NULL ) {
760 return EINVAL * - 1;
761 }
762
763 RCt = _FUSE_get_parent_node ( ThePath, & Parent, NULL, & Child );
764 if ( RCt == 0 ) {
765 RCt = XFSNodeDirEditor ( Parent, & Editor );
766 if ( RCt == 0 ) {
767 RCt = XFSDirEditorCreateDir ( Editor, Child );
768
769 XFSEditorDispose ( & ( Editor -> Papahen ) );
770 }
771
772 XFSNodeRelease ( Parent );
773 free ( Child );
774 }
775
776 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
777 } /* XFS_FUSE_mkdir() */
778
779 #endif /* USE_XFS_FUSE_MKDIR == 1 */
780
781 /*****************************************************/
782 #if USE_XFS_FUSE_UNLINK == 1
783
784 static
785 int
XFS_FUSE_unlink(const char * ThePath)786 XFS_FUSE_unlink ( const char * ThePath )
787 {
788 rc_t RCt;
789
790 RCt = 0;
791
792 pLogMsg ( klogDebug, "UNLINK(Fuse): [$(path)]", "path=%s", ThePath );
793
794 if ( ThePath == NULL ) {
795 return EINVAL * - 1;
796 }
797
798 RCt = _FUSE_delete_file_dir ( ThePath );
799
800 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
801 } /* XFS_FUSE_unlink() */
802
803 #endif /* USE_XFS_FUSE_UNLINK == 1 */
804
805 /*****************************************************/
806 #if USE_XFS_FUSE_RMDIR == 1
807
808 static
809 int
XFS_FUSE_rmdir(const char * ThePath)810 XFS_FUSE_rmdir ( const char * ThePath )
811 {
812 rc_t RCt;
813
814 RCt = 0;
815
816 pLogMsg ( klogDebug, "RMDIR(Fuse): [$(path)]", "path=%s", ThePath );
817
818 if ( ThePath == NULL ) {
819 return EINVAL * - 1;
820 }
821
822 RCt = _FUSE_delete_file_dir ( ThePath );
823
824 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
825 } /* XFS_FUSE_rmdir() */
826
827 #endif /* USE_XFS_FUSE_RMDIR == 1 */
828
829 /*****************************************************/
830 #if USE_XFS_FUSE_SYMLINK == 1
831
832 static
833 int
XFS_FUSE_symlink(const char * OldPath,const char * NewPath)834 XFS_FUSE_symlink ( const char * OldPath, const char * NewPath )
835 {
836 pLogMsg ( klogDebug, "SYMLINK(!): [$(path)]", "path=%s", OldPath );
837
838 return -EPERM;
839 } /* XFS_FUSE_symlink() */
840
841 #endif /* USE_XFS_FUSE_SYMLINK == 1 */
842
843 /*****************************************************/
844 #if USE_XFS_FUSE_RENAME == 1
845
846 static
847 int
XFS_FUSE_rename(const char * OldPath,const char * NewPath)848 XFS_FUSE_rename ( const char * OldPath, const char * NewPath )
849 {
850 rc_t RCt;
851 const struct XFSNode * OldDir, * NewDir;
852 char * OldName, * NewName;
853 const struct XFSDirEditor * Editor;
854
855 RCt = 0;
856 OldDir = NewDir = NULL;
857 OldName = NewName = NULL;
858 Editor = NULL;
859
860
861 pLogMsg ( klogDebug, "RENAME(Fuse): FR[$(from)] TO[$(to)]", "from=%s,to=%s", OldPath, NewPath );
862
863 if ( OldPath == NULL || NewPath == NULL ) {
864 return EINVAL * - 1;
865 }
866
867 RCt = _FUSE_get_parent_node ( OldPath, & OldDir, NULL, & OldName );
868 if ( RCt == 0 ) {
869 RCt = _FUSE_get_parent_node ( NewPath, & NewDir, NULL, & NewName );
870
871 if ( RCt == 0 ) {
872 RCt = XFSNodeDirEditor ( OldDir, & Editor );
873 if ( RCt == 0 ) {
874 RCt = XFSDirEditorMove ( Editor, OldName, NewDir, NewName );
875 XFSEditorDispose ( & ( Editor -> Papahen ) );
876 }
877
878 XFSNodeRelease ( NewDir );
879 free ( NewName );
880 }
881
882 XFSNodeRelease ( OldDir );
883 free ( OldName );
884 }
885
886 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
887 } /* XFS_FUSE_rename() */
888
889 #endif /* USE_XFS_FUSE_RENAME == 1 */
890
891 /*****************************************************/
892 #if USE_XFS_FUSE_LINK == 1
893
894 static
895 int
XFS_FUSE_link(const char * OldPath,const char * NewPath)896 XFS_FUSE_link ( const char * OldPath, const char * NewPath )
897 {
898 pLogMsg ( klogDebug, "LINK(!): FR[$(from)] TO[$(to)]", "from=%s,to=%s", OldPath, NewPath );
899
900 return -EPERM;
901 } /* XFS_FUSE_link() */
902
903 #endif /* USE_XFS_FUSE_LINK == 1 */
904
905 /*****************************************************/
906 #if USE_XFS_FUSE_CHMOD == 1
907
908 static
909 int
XFS_FUSE_chmod(const char * ThePath,mode_t TheMode)910 XFS_FUSE_chmod ( const char * ThePath, mode_t TheMode )
911 {
912 rc_t RCt;
913 const struct XFSAttrEditor * Editor;
914 const struct XFSNode * Node;
915 char Buf [ 16 ];
916
917 RCt = 0;
918 Editor = NULL;
919 Node = NULL;
920 * Buf = 0;
921
922 pLogMsg ( klogDebug, "CHMOD(Fuse): [$(path)] MD[$(mode)]", "path=%s,mode=%d", ThePath, TheMode );
923
924 if ( ThePath == NULL ) {
925 return EINVAL * - 1;
926 }
927
928 RCt = XFSPermToChar ( TheMode, Buf, sizeof ( Buf ) );
929 if ( RCt == 0 ) {
930 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, NULL );
931 if ( RCt == 0 ) {
932 RCt = XFSNodeAttrEditor ( Node, & Editor );
933 if ( RCt == 0 ) {
934 RCt = XFSAttrEditorSetPermissions ( Editor, Buf );
935 }
936
937 XFSNodeRelease ( Node );
938 }
939 }
940
941 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
942 } /* XFS_FUSE_chmod() */
943
944 #endif /* USE_XFS_FUSE_CHMOD == 1 */
945
946 /*****************************************************/
947 #if USE_XFS_FUSE_CHOWN == 1
948
949 static
950 int
XFS_FUSE_chown(const char * ThePath,uid_t TheUid,gid_t TheDid)951 XFS_FUSE_chown ( const char * ThePath, uid_t TheUid, gid_t TheDid )
952 {
953 pLogMsg ( klogDebug, "CHOWN(!): [$(path)]", "path=%s", ThePath );
954
955 return -EPERM;
956 } /* XFS_FUSE_chown() */
957
958 #endif /* USE_XFS_FUSE_CHOWN == 1 */
959
960 /*****************************************************/
961 #if USE_XFS_FUSE_TRUNCATE == 1
962
963 static
964 int
XFS_FUSE_truncate(const char * ThePath,off_t TheSize)965 XFS_FUSE_truncate ( const char * ThePath, off_t TheSize )
966 {
967 rc_t RCt;
968 const struct XFSFileEditor * Editor;
969 const struct XFSNode * Node;
970
971 RCt = 0;
972 Editor = NULL;
973 Node = NULL;
974
975 pLogMsg ( klogDebug, "TRUNCATE(Fuse): [$(path)] SZ[$(size)]", "path=%s,size=%d", ThePath, TheSize );
976
977 if ( ThePath == NULL ) {
978 return EINVAL * - 1;
979 }
980
981 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, NULL );
982 if ( RCt == 0 ) {
983 RCt = XFSNodeFileEditor ( Node, & Editor );
984 if ( RCt == 0 ) {
985 RCt = XFSFileEditorSetSize ( Editor, TheSize );
986 }
987
988 XFSNodeRelease ( Node );
989 }
990
991 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
992 } /* XFS_FUSE_truncate() */
993
994 #endif /* USE_XFS_FUSE_TRUNCATE == 1 */
995
996 /*****************************************************/
997 #if USE_XFS_FUSE_UTIME == 1
998
999 static
1000 int
XFS_FUSE_utime(const char * ThePath,struct utimbuf * TheBuf)1001 XFS_FUSE_utime ( const char * ThePath, struct utimbuf * TheBuf )
1002 {
1003 rc_t RCt;
1004 const struct XFSAttrEditor * Editor;
1005 const struct XFSNode * Node;
1006
1007 RCt = 0;
1008 Editor = NULL;
1009 Node = NULL;
1010
1011 pLogMsg ( klogDebug, "TRUNCATE(Fuse): [$(path)] AT[$(actime)] MT[$(modtime)]", "path=%s,actime=%d,modtime=%d", ThePath, TheBuf -> actime, TheBuf -> modtime );
1012
1013 if ( ThePath == NULL ) {
1014 return EINVAL * - 1;
1015 }
1016
1017 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, NULL );
1018 if ( RCt == 0 ) {
1019 RCt = XFSNodeAttrEditor ( Node, & Editor );
1020 if ( RCt == 0 ) {
1021 RCt = XFSAttrEditorSetDate ( Editor, TheBuf -> modtime );
1022 }
1023
1024 XFSNodeRelease ( Node );
1025 }
1026
1027 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1028 } /* XFS_FUSE_utime() */
1029
1030 #endif /* USE_XFS_FUSE_UTIME == 1 */
1031
1032 /*****************************************************/
1033 #if USE_XFS_FUSE_OPEN == 1
1034
1035 static
1036 int
XFS_FUSE_open(const char * ThePath,struct fuse_file_info * TheInfo)1037 XFS_FUSE_open ( const char * ThePath, struct fuse_file_info * TheInfo )
1038 {
1039 rc_t RCt;
1040 const struct XFSNode * Node;
1041 XFSNType Type;
1042 int Flags;
1043 const struct XFSFileEditor * Editor;
1044 XFSNMode Mode;
1045 const struct XFSHandle * Handle;
1046
1047 RCt = 0;
1048 Node = NULL;
1049 Type = kxfsNotFound;
1050 Flags = TheInfo == NULL ? 0xbad : TheInfo -> flags;
1051 Editor = NULL;
1052 Mode = kxfsNone;
1053 Handle = NULL;
1054
1055 pLogMsg ( klogDebug, "OPEN(Fuse): [$(path)] FI[$(info)] FL[$(flags)]", "path=%s,info=%p,flags=%d", ThePath, TheInfo, Flags );
1056
1057 if ( ThePath == NULL || TheInfo == NULL ) {
1058 return EINVAL * - 1;
1059 }
1060
1061 if ( ( Flags & O_RDWR ) == O_RDWR ) {
1062 Mode = kxfsReadWrite;
1063 }
1064 else {
1065 if ( ( Flags & O_WRONLY ) == O_WRONLY ) {
1066 Mode = kxfsWrite;
1067 }
1068 else {
1069 Mode = kxfsRead;
1070 }
1071
1072 }
1073
1074 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, & Type );
1075 if ( RCt == 0 ) {
1076 if ( Type == kxfsNotFound ) {
1077 XFSNodeRelease ( Node );
1078 return ENOENT * - 1;
1079 }
1080
1081 RCt = XFSNodeFileEditor ( Node, & Editor );
1082 if ( RCt == 0 ) {
1083 RCt = XFSFileEditorOpen ( Editor, Mode );
1084 if ( RCt == 0 ) {
1085 RCt = XFSHandleMake ( Node, & Handle );
1086 if ( RCt == 0 ) {
1087 XFSHandleSet ( Handle, ( void * ) Editor );
1088 TheInfo -> fh = ( uint64_t ) Handle;
1089 }
1090 }
1091 }
1092
1093 XFSNodeRelease ( Node );
1094 }
1095
1096 if ( RCt != 0 ) {
1097 if ( Editor != NULL ) {
1098 XFSEditorDispose ( & ( Editor -> Papahen ) );
1099 }
1100 }
1101
1102 pLogMsg ( klogDebug, "OPEN(Fuse,cont): [$(path)] RC[$(rc)] FI[$(info)] FH[$(handle)]", "path=%s,rc=%d,info=%p,handle=%p", ThePath, RCt, TheInfo, Handle );
1103
1104 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1105 } /* XFS_FUSE_open() */
1106
1107 #endif /* USE_XFS_FUSE_OPEN == 1 */
1108
1109 /*****************************************************/
1110 #if USE_XFS_FUSE_READ == 1
1111
1112 static
1113 int
XFS_FUSE_read(const char * ThePath,char * TheBuf,size_t TheSizeRead,off_t TheOffsetRead,struct fuse_file_info * TheFileInfo)1114 XFS_FUSE_read (
1115 const char * ThePath,
1116 char * TheBuf,
1117 size_t TheSizeRead,
1118 off_t TheOffsetRead,
1119 struct fuse_file_info * TheFileInfo
1120 )
1121 {
1122 rc_t RCt;
1123 const struct XFSHandle * Handle;
1124 const struct XFSFileEditor * Editor;
1125 size_t NumBytesReaded;
1126
1127 RCt = 0;
1128 Editor = NULL;
1129 Handle = TheFileInfo == NULL
1130 ? NULL
1131 : ( const struct XFSHandle * ) TheFileInfo -> fh
1132 ;
1133 NumBytesReaded = 0;
1134
1135 pLogMsg ( klogDebug, "READ(Fuse): [$(path)] FI[$(info)] FH[$(handle)] OF[$(off)] SZ[$(size)]", "path=%s,info=%p,handle=%p,off=%d,size=%d", ThePath, TheFileInfo, Handle, TheOffsetRead, TheSizeRead );
1136
1137 if ( ThePath == NULL || TheBuf == NULL || TheFileInfo == NULL ) {
1138 return EINVAL * - 1;
1139 }
1140
1141 if ( Handle == NULL ) {
1142 return EBADF * - 1;
1143 }
1144
1145 Editor = ( const struct XFSFileEditor * ) XFSHandleGet ( Handle );
1146 if ( Editor == NULL ) {
1147 return EBADF * - 1;
1148 }
1149
1150 RCt = XFSFileEditorRead (
1151 Editor,
1152 TheOffsetRead,
1153 TheBuf,
1154 TheSizeRead,
1155 & NumBytesReaded
1156 );
1157 pLogMsg ( klogDebug, "READ(Fuse,cont): [$(path)] FI[$(info)] FH[$(handle)] OF[$(off)] SZ[$(size)] RD[$(read)] RC[$(rc)]", "path=%s,info=%p,handle=%p,off=%d,size=%d,read=%d,rc=%d", ThePath, TheFileInfo, Handle, TheOffsetRead, TheSizeRead, NumBytesReaded, RCt );
1158
1159 return RCt == 0
1160 ? NumBytesReaded
1161 : ( XFS_FUSE_rc_to_errno ( RCt ) * - 1)
1162 ;
1163
1164 } /* XFS_FUSE_read() */
1165
1166 #endif /* USE_XFS_FUSE_READ == 1 */
1167
1168 /*****************************************************/
1169 #if USE_XFS_FUSE_WRITE == 1
1170
1171 static
1172 int
XFS_FUSE_write(const char * ThePath,const char * TheBuf,size_t TheSizeWrite,off_t TheOffsetWrite,struct fuse_file_info * TheFileInfo)1173 XFS_FUSE_write (
1174 const char * ThePath,
1175 const char * TheBuf,
1176 size_t TheSizeWrite,
1177 off_t TheOffsetWrite,
1178 struct fuse_file_info * TheFileInfo
1179 )
1180 {
1181 rc_t RCt;
1182 const struct XFSHandle * Handle;
1183 const struct XFSFileEditor * Editor;
1184 size_t NumBytesWritten;
1185
1186 RCt = 0;
1187 Editor = NULL;
1188 Handle = TheFileInfo == NULL
1189 ? NULL
1190 : ( const struct XFSHandle * ) TheFileInfo -> fh
1191 ;
1192 NumBytesWritten = 0;
1193
1194 pLogMsg ( klogDebug, "WRITE(Fuse): [$(path)] FI[$(info)] FH[$(handle)] OF[$(off)] SZ[$(size)]", "path=%s,info=%p,handle=%p,off=%d,size=%d", ThePath, TheFileInfo, Handle, TheOffsetWrite, TheSizeWrite );
1195
1196 if ( ThePath == NULL || TheBuf == NULL || TheFileInfo == NULL ) {
1197 return EINVAL * - 1;
1198 }
1199
1200 if ( Handle == NULL ) {
1201 return EBADF * - 1;
1202 }
1203
1204 Editor = ( const struct XFSFileEditor * ) XFSHandleGet ( Handle );
1205 if ( Editor == NULL ) {
1206 return EBADF * - 1;
1207 }
1208
1209 RCt = XFSFileEditorWrite (
1210 Editor,
1211 TheOffsetWrite,
1212 TheBuf,
1213 TheSizeWrite,
1214 & NumBytesWritten
1215 );
1216
1217 pLogMsg ( klogDebug, "WRITE(Fuse,cont): [$(path)] FI[$(info)] FH[$(handle)] OF[$(off)] SZ[$(size)] WR[$(wrote)] RC[$(rc)]", "path=%s,info=%p,handle=%p,off=%d,size=%d,wrote=%d,rc=%d", ThePath, TheFileInfo, Handle, TheOffsetWrite, TheSizeWrite, NumBytesWritten, RCt );
1218
1219 return RCt == 0
1220 ? NumBytesWritten
1221 : ( XFS_FUSE_rc_to_errno ( RCt ) * - 1)
1222 ;
1223 } /* XFS_FUSE_write() */
1224
1225 #endif /* USE_XFS_FUSE_WRITE == 1 */
1226
1227 /*****************************************************/
1228 #if USE_XFS_FUSE_STATFS == 1
1229
1230 static
1231 int
XFS_FUSE_statfs(const char * ThePath,struct statvfs * TheFSStat)1232 XFS_FUSE_statfs (
1233 const char * ThePath,
1234 struct statvfs * TheFSStat
1235 )
1236 {
1237 pLogMsg ( klogDebug, "STATFS(!): [$(path)]", "path=%d", ThePath );
1238
1239 return -EPERM;
1240 } /* XFS_FUSE_statfs() */
1241
1242 #endif /* USE_XFS_FUSE_STATFS == 1 */
1243
1244 /*****************************************************/
1245 #if USE_XFS_FUSE_FLUSH == 1
1246
1247 static
1248 int
XFS_FUSE_flush(const char * ThePath,struct fuse_file_info * TheFileInfo)1249 XFS_FUSE_flush (
1250 const char * ThePath,
1251 struct fuse_file_info * TheFileInfo
1252 )
1253 {
1254 pLogMsg ( klogDebug, "FLUSH(DUMMY): [$(path)] FI[$(info)]", "path=%d,info=%p", ThePath, TheFileInfo );
1255
1256 return 0;
1257 } /* XFS_FUSE_flush() */
1258
1259 #endif /* USE_XFS_FUSE_FLUSH == 1 */
1260
1261 /*****************************************************/
1262 #if USE_XFS_FUSE_RELEASE == 1
1263
1264 static
1265 int
XFS_FUSE_release(const char * ThePath,struct fuse_file_info * TheFileInfo)1266 XFS_FUSE_release (
1267 const char * ThePath,
1268 struct fuse_file_info * TheFileInfo
1269 )
1270 {
1271 rc_t RCt;
1272 const struct XFSHandle * Handle;
1273 const struct XFSFileEditor * Editor;
1274
1275 RCt = 0;
1276 Editor = NULL;
1277 Handle = TheFileInfo == NULL
1278 ? NULL
1279 : ( const struct XFSHandle * ) TheFileInfo -> fh
1280 ;
1281
1282 pLogMsg ( klogDebug, "RELEASE(Fuse): [$(path)] FI[$(info)] FH[$(handle)]", "path=%d,info=%p,handle=%p", ThePath, TheFileInfo, Handle );
1283
1284 if ( ThePath == NULL || TheFileInfo == NULL ) {
1285 return EINVAL * - 1;
1286 }
1287
1288 if ( Handle != NULL ) {
1289 Editor = ( const struct XFSFileEditor * ) XFSHandleGet ( Handle );
1290
1291 if ( Editor != NULL ) {
1292 XFSFileEditorClose ( Editor );
1293 XFSEditorDispose ( & ( Editor -> Papahen ) );
1294 XFSHandleSet ( Handle, NULL );
1295 }
1296
1297 XFSHandleRelease ( Handle );
1298 }
1299
1300 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1301 } /* XFS_FUSE_release() */
1302
1303 #endif /* USE_XFS_FUSE_RELEASE == 1 */
1304
1305 /*****************************************************/
1306 #if USE_XFS_FUSE_FSYNC == 1
1307
1308 static
1309 int
XFS_FUSE_fsync(const char * ThePath,int DataSync,struct fuse_file_info * TheFileInfo)1310 XFS_FUSE_fsync (
1311 const char * ThePath,
1312 int DataSync,
1313 struct fuse_file_info * TheFileInfo
1314 )
1315 {
1316 pLogMsg ( klogDebug, "FSYNC(DUMMY): [$(path)] FI[$(info)] DT[$(data)]", "path=%d,info=%p,data=%p", ThePath, TheFileInfo, DataSync );
1317 return 0;
1318 } /* XFS_FUSE_fsync() */
1319
1320 #endif /* USE_XFS_FUSE_FSYNC == 1 */
1321
1322 /*****************************************************/
1323 #if USE_XFS_FUSE_SETXATTR == 1
1324
1325 static
1326 int
XFS_FUSE_setxattr(const char * ThePath,const char * TheName,const char * TheValue,size_t TheValueSize,int TheFlags)1327 XFS_FUSE_setxattr (
1328 const char * ThePath,
1329 const char * TheName,
1330 const char * TheValue,
1331 size_t TheValueSize,
1332 int TheFlags
1333 )
1334 {
1335 pLogMsg ( klogDebug, "SETXATTR(!): [$(path)]", "path=%d", ThePath );
1336
1337 return -EPERM;
1338 } /* XFS_FUSE_setxattr() */
1339
1340 #endif /* USE_XFS_FUSE_SETXATTR == 1 */
1341
1342 /*****************************************************/
1343 #if USE_XFS_FUSE_GETXATTR == 1
1344
1345 static
1346 int
XFS_FUSE_getxattr(const char * ThePath,const char * TheName,char * TheValue,size_t TheValueSize)1347 XFS_FUSE_getxattr (
1348 const char * ThePath,
1349 const char * TheName,
1350 char * TheValue,
1351 size_t TheValueSize
1352 )
1353 {
1354 pLogMsg ( klogDebug, "GETXATTR(!): [$(path)]", "path=%d", ThePath );
1355
1356 return -EPERM;
1357 } /* XFS_FUSE_getxattr() */
1358
1359 #endif /* USE_XFS_FUSE_GETXATTR == 1 */
1360
1361 /*****************************************************/
1362 #if USE_XFS_FUSE_LISTXATTR == 1
1363
1364 static
1365 int
XFS_FUSE_listxattr(const char * ThePath,char * TheList,size_t TheListSize)1366 XFS_FUSE_listxattr (
1367 const char * ThePath,
1368 char * TheList,
1369 size_t TheListSize
1370 )
1371 {
1372 pLogMsg ( klogDebug, "LISTXATTR(!): [$(path)]", "path=%d", ThePath );
1373
1374 return -EPERM;
1375 } /* XFS_FUSE_listxattr() */
1376
1377 #endif /* USE_XFS_FUSE_LISTXATTR == 1 */
1378
1379 /*****************************************************/
1380 #if USE_XFS_FUSE_REMOVEXATTR == 1
1381
1382 static
1383 int
XFS_FUSE_removexattr(const char * ThePath,const char * TheName)1384 XFS_FUSE_removexattr ( const char * ThePath, const char * TheName)
1385 {
1386 pLogMsg ( klogDebug, "REMOVEXATTR(!): [$(path)]", "path=%d", ThePath );
1387
1388 return -EPERM;
1389 } /* XFS_FUSE_removexattr() */
1390
1391 #endif /* USE_XFS_FUSE_REMOVEXATTR == 1 */
1392
1393 /*****************************************************/
1394 #if USE_XFS_FUSE_OPENDIR == 1
1395
1396 static
1397 int
XFS_FUSE_opendir(const char * ThePath,struct fuse_file_info * TheFileInfo)1398 XFS_FUSE_opendir (
1399 const char * ThePath,
1400 struct fuse_file_info * TheFileInfo
1401 )
1402 {
1403 rc_t RCt;
1404 const struct XFSNode * Node;
1405 const struct XFSHandle * Handle;
1406 XFSNType Type;
1407
1408 RCt = 0;
1409 Node = NULL;
1410 Handle = NULL;
1411 Type = kxfsBadPath;
1412
1413 if ( ThePath == NULL || TheFileInfo == NULL ) {
1414 return EINVAL * - 1;
1415 }
1416
1417 pLogMsg ( klogDebug, "OPENDIR(Fuse): [$(path)] FI[$(info)] FL[$(flags)]", "path=%d,info=%p,flags=%d", ThePath, TheFileInfo, TheFileInfo -> flags );
1418
1419 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, & Type );
1420 if ( RCt == 0 ) {
1421 if ( Type != kxfsDir ) {
1422 XFSNodeRelease ( Node );
1423
1424 return ENOENT * - 1;
1425 }
1426
1427 RCt = XFSHandleMake ( Node, & Handle );
1428 if ( RCt == 0 ) {
1429 TheFileInfo -> fh = ( uint64_t ) Handle;
1430 }
1431
1432 XFSNodeRelease ( Node );
1433 }
1434
1435 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1436 } /* XFS_FUSE_opendir() */
1437
1438 #endif /* USE_XFS_FUSE_OPENDIR == 1 */
1439
1440 /*****************************************************/
1441 #if USE_XFS_FUSE_READDIR == 1
1442
1443 /*****************************************************************
1444 * JUST FOR ANY CASE, THAT FUNCTION IS USED IN 'readdir()' TO
1445 * FILL BUFFER WITH DIRECTORY INFORMATION
1446 *
1447 * typedef int (*fuse_fill_dir_t) (
1448 * void *buf,
1449 * const char *name,
1450 * const struct stat *stbuf,
1451 * off_t off
1452 * );
1453 *****************************************************************/
1454
1455 static
1456 int
XFS_FUSE_readdir(const char * ThePath,void * TheBuffer,fuse_fill_dir_t TheFiller,off_t TheOffset,struct fuse_file_info * TheFileInfo)1457 XFS_FUSE_readdir (
1458 const char * ThePath,
1459 void * TheBuffer,
1460 fuse_fill_dir_t TheFiller,
1461 off_t TheOffset,
1462 struct fuse_file_info * TheFileInfo
1463 )
1464 {
1465 rc_t RCt;
1466 const struct XFSNode * Node;
1467 const struct XFSHandle * Handle;
1468 const struct XFSDirEditor * Editor;
1469 const struct KNamelist * List;
1470 uint32_t ListQty, llp;
1471 const char * Name;
1472
1473 RCt = 0;
1474 Node = NULL;
1475 Handle = NULL;
1476 Editor = NULL;
1477 List = NULL;
1478 ListQty = llp = 0;
1479 Name = NULL;
1480
1481 if ( ThePath == NULL || TheFileInfo == NULL ) {
1482 return EINVAL * - 1;
1483 }
1484
1485 Handle = ( const struct XFSHandle * ) TheFileInfo -> fh;
1486
1487 pLogMsg ( klogDebug, "READDIR(Fuse): [$(path)] FI[$(info)] FH[$(handle)]", "path=%d,info=%p,handle=%p", ThePath, TheFileInfo, ( void * ) Handle );
1488
1489 if ( Handle != NULL ) {
1490 Node = XFSHandleNode ( Handle );
1491 if ( Node == NULL ) {
1492 RCt = XFS_RC ( rcInvalid );
1493 }
1494 else {
1495 RCt = XFSNodeDirEditor ( Node, & Editor );
1496 if ( RCt == 0 ) {
1497 if ( Editor == NULL ) {
1498 RCt = XFS_RC ( rcInvalid );
1499 }
1500 else {
1501 RCt = XFSDirEditorList ( Editor, & List );
1502 if ( RCt == 0 ) {
1503 RCt = KNamelistCount ( List, & ListQty );
1504 if ( RCt == 0 ) {
1505 for ( llp = 0; llp < ListQty; llp ++ ) {
1506 RCt = KNamelistGet ( List, llp, & Name );
1507 if ( RCt == 0 ) {
1508 TheFiller (
1509 TheBuffer,
1510 Name,
1511 NULL,
1512 0
1513 );
1514 }
1515
1516 if ( RCt != 0 ) {
1517 /* Do we need that? TODO!!!
1518 break;
1519 */
1520 RCt = 0; /* Right ? */
1521 }
1522 }
1523 }
1524
1525 KNamelistRelease ( List );
1526 }
1527
1528 XFSEditorDispose ( & ( Editor -> Papahen ) );
1529 }
1530 }
1531 else {
1532 RCt = XFS_RC ( rcInvalid );
1533 }
1534 }
1535 }
1536 else {
1537 RCt = XFS_RC ( rcInvalid );
1538 }
1539
1540 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1541 } /* XFS_FUSE_readdir() */
1542
1543 #endif /* USE_XFS_FUSE_READDIR == 1 */
1544
1545 /*****************************************************/
1546 #if USE_XFS_FUSE_RELEASEDIR == 1
1547
1548 static
1549 int
XFS_FUSE_releasedir(const char * ThePath,struct fuse_file_info * TheFileInfo)1550 XFS_FUSE_releasedir (
1551 const char * ThePath,
1552 struct fuse_file_info * TheFileInfo
1553 )
1554 {
1555 rc_t RCt;
1556 const struct XFSHandle * Handle;
1557
1558 RCt = 0;
1559 Handle = NULL;
1560
1561 if ( ThePath == NULL || TheFileInfo == NULL ) {
1562 return EINVAL * - 1;
1563 }
1564
1565 Handle = ( const struct XFSHandle * ) TheFileInfo -> fh;
1566
1567 pLogMsg ( klogDebug, "RELEASEDIR(Fuse): [$(path)] FI[$(info)] FH[$(handle)]", "path=%d,info=%p,handle=%p", ThePath, TheFileInfo, ( void * ) Handle );
1568
1569 if ( Handle != NULL ) {
1570 RCt = XFSHandleRelease ( Handle );
1571 }
1572 else {
1573 RCt = XFS_RC ( rcInvalid );
1574 }
1575
1576 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1577 } /* XFS_FUSE_releasedir() */
1578
1579 #endif /* USE_XFS_FUSE_RELEASEDIR == 1 */
1580
1581 /*****************************************************/
1582 #if USE_XFS_FUSE_FSYNCDIR == 1
1583
1584 static
1585 int
XFS_FUSE_fsyncdir(const char * ThePath,int DataSync,struct fuse_file_info * TheFileInfo)1586 XFS_FUSE_fsyncdir (
1587 const char * ThePath,
1588 int DataSync,
1589 struct fuse_file_info * TheFileInfo
1590 )
1591 {
1592 pLogMsg ( klogDebug, "FSYNCDIR(!): [$(path)]", "path=%d", ThePath );
1593
1594 return -EPERM;
1595 } /* XFS_FUSE_fsyncdir() */
1596
1597 #endif /* USE_XFS_FUSE_FSYNCDIR == 1 */
1598
1599 /*****************************************************/
1600 #if USE_XFS_FUSE_INIT == 1
1601
1602 static
1603 void *
XFS_FUSE_init(struct fuse_conn_info * TheConnInfo)1604 XFS_FUSE_init ( struct fuse_conn_info * TheConnInfo )
1605 {
1606 rc_t RCt;
1607 const struct XFSTreeDepot * Depot;
1608
1609 RCt = 0;
1610 Depot = NULL;
1611
1612 RCt = _FUSE_tree_depot ( & Depot );
1613
1614 pLogMsg ( klogDebug, "INIT(): TheConnInfo [$(conn)] TreeDepot [$(depot)]\n", "conn=%p,depot=%p", TheConnInfo, Depot );
1615
1616 return RCt != 0 ? NULL : ( void * ) Depot;
1617 } /* XFS_FUSE_init() */
1618
1619 #endif /* USE_XFS_FUSE_INIT == 1 */
1620
1621 /*****************************************************/
1622 #if USE_XFS_FUSE_DESTROY == 1
1623
1624 static
1625 void
XFS_FUSE_destroy(void * OnoSamoe)1626 XFS_FUSE_destroy ( void * OnoSamoe )
1627 {
1628 pLogMsg ( klogDebug, "DESTROY(Dummy): OnoSamoe [$(samoe)]", "samoe=%p", OnoSamoe );
1629
1630 } /* XFS_FUSE_destroy() */
1631
1632 #endif /* USE_XFS_FUSE_DESTROY == 1 */
1633
1634 /*****************************************************/
1635 #if USE_XFS_FUSE_ACCESS == 1
1636
1637 static
1638 int
XFS_FUSE_access(const char * ThePath,int Access)1639 XFS_FUSE_access ( const char * ThePath, int Access )
1640 {
1641 rc_t RCt;
1642 const struct XFSAttrEditor * Editor;
1643 const struct XFSNode * Node;
1644 bool xOK, rOK, wOK, fOK;
1645 XFSNType Type;
1646 const char * Perm;
1647 const struct XFSPerm * xPerm;
1648 const struct XFSAuth * Auth;
1649
1650 RCt = 0;
1651 Editor = NULL;
1652 Node = NULL;
1653 Type = kxfsNotFound;
1654 Perm = NULL;
1655 xPerm = NULL;
1656 Auth = NULL;
1657
1658 xOK = ( Access & X_OK ) == X_OK; /* Can Execute */
1659 wOK = ( Access & W_OK ) == W_OK; /* Can Write */
1660 rOK = ( Access & R_OK ) == R_OK; /* Can Read */
1661 fOK = ( Access & F_OK ) == F_OK; /* File Exists */
1662
1663 pLogMsg ( klogDebug, "ACCESS(Fuse): [$(path)] MD[$(mode)] X[$(x)] W[$(w)] R[$(r)] F[$(f)]", "path=%s,mode=%d,x=%d,w=%d,r=%d,f=%d", ThePath, Access, xOK, wOK, rOK, fOK );
1664
1665 if ( ThePath == NULL ) {
1666 return - 1;
1667 }
1668
1669 if ( ! xOK && ! wOK && ! rOK && ! fOK ) {
1670 return - 1;
1671 }
1672
1673 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, & Type );
1674 if ( RCt == 0 ) {
1675 /* Check for fOK */
1676 if ( Type == kxfsNotFound ) {
1677 RCt = 1;
1678 }
1679 else {
1680 if ( xOK || wOK || rOK ) {
1681 RCt = XFSNodeAttrEditor ( Node, & Editor );
1682 if ( RCt == 0 ) {
1683 RCt = XFSAttrEditorPermissions ( Editor, & Perm );
1684 if ( RCt == 0 ) {
1685 RCt = XFSPermMake ( Perm, & xPerm );
1686 if ( RCt == 0 ) {
1687 Auth = XFSPermAuth ( xPerm, kxfsUser );
1688 if ( Auth == NULL ) {
1689 RCt = 1;
1690 }
1691 else {
1692 if ( xOK ) {
1693 RCt = ! XFSAuthCanExecute ( Auth );
1694 }
1695 if ( rOK && RCt == 0 ) {
1696 RCt = ! XFSAuthCanRead ( Auth );
1697 }
1698 if ( wOK && RCt == 0 ) {
1699 RCt = ! XFSAuthCanWrite ( Auth );
1700 }
1701 }
1702
1703 XFSPermDispose ( xPerm );
1704 }
1705 }
1706
1707 XFSEditorDispose ( & ( Editor -> Papahen ) );
1708 }
1709 }
1710 }
1711
1712 XFSNodeRelease ( Node );
1713 }
1714
1715 pLogMsg ( klogDebug, "ACCESS(Fuse,cont): [$(path)] RC[$(rc)]", "path=%s,rc=%d", ThePath, RCt );
1716
1717 return RCt == 0 ? 0 : - 1;
1718 } /* XFS_FUSE_access() */
1719
1720 #endif /* USE_XFS_FUSE_ACCESS == 1 */
1721
1722 /*****************************************************/
1723 #if USE_XFS_FUSE_CREATE == 1
1724
1725 static
1726 int
XFS_FUSE_create(const char * ThePath,mode_t TheMode,struct fuse_file_info * TheFileInfo)1727 XFS_FUSE_create (
1728 const char * ThePath,
1729 mode_t TheMode,
1730 struct fuse_file_info * TheFileInfo
1731 )
1732 {
1733 rc_t RCt;
1734 uint32_t Flags;
1735 const struct XFSNode * Node;
1736 const struct XFSDirEditor *Editor;
1737 const struct XFSHandle * Handle;
1738 char * Child;
1739 XFSNMode Mode;
1740
1741 RCt = 0;
1742 Node = NULL;
1743 Editor = NULL;
1744 Handle = NULL;
1745 Child = NULL;
1746 Mode = kxfsNone;
1747
1748 Flags = TheFileInfo -> flags;
1749
1750 pLogMsg ( klogDebug, "CREATE(Fuse): [$(path)] FI[$(info)] FL[$(flags)] MD[$(mode)]", "path=%s,info=%p,flags=%d,mode=%d", ThePath, TheFileInfo, Flags, TheMode );
1751
1752 if ( ThePath == NULL ) {
1753 return EINVAL * - 1;
1754 }
1755
1756 if ( ( Flags & O_RDWR ) == O_RDWR ) {
1757 Mode = kxfsReadWrite;
1758 }
1759 else {
1760 if ( ( Flags & O_WRONLY ) == O_WRONLY ) {
1761 Mode = kxfsWrite;
1762 }
1763 else {
1764 Mode = kxfsRead;
1765 }
1766 }
1767
1768 RCt = _FUSE_get_parent_node ( ThePath, & Node, NULL, & Child );
1769 if ( RCt == 0 ) {
1770 RCt = XFSNodeDirEditor ( Node, & Editor );
1771 if ( RCt == 0 ) {
1772 RCt = XFSDirEditorCreate ( Editor, Child, Mode, & Handle );
1773 if ( RCt != 0 ) {
1774 XFSEditorDispose ( & ( Editor -> Papahen ) );
1775 TheFileInfo -> fh = 0;
1776 }
1777 else {
1778 TheFileInfo -> fh = ( uint64_t ) Handle;
1779 }
1780 }
1781
1782 XFSNodeRelease ( Node );
1783 free ( Child );
1784 }
1785
1786 pLogMsg ( klogDebug, "CREATE(Fuse,cont): [$(path)] FI[$(info)] FH[$(handle)] MD[$(mode)]", "path=%s,info=%p,handle=%p,mode=%d", ThePath, TheFileInfo, Handle, Mode );
1787
1788 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1789 } /* XFS_FUSE_create() */
1790
1791 #endif /* USE_XFS_FUSE_CREATE == 1 */
1792
1793 /*****************************************************/
1794 #if USE_XFS_FUSE_FTRUNCATE == 1
1795
1796 static
1797 int
XFS_FUSE_ftruncate(const char * ThePath,off_t TheSize,struct fuse_file_info * TheFileInfo)1798 XFS_FUSE_ftruncate (
1799 const char * ThePath,
1800 off_t TheSize,
1801 struct fuse_file_info * TheFileInfo
1802 )
1803 {
1804 rc_t RCt;
1805 const struct XFSHandle * Handle;
1806 const struct XFSFileEditor * Editor;
1807 const struct XFSNode * Node;
1808
1809 RCt = 0;
1810 Editor = NULL;
1811 Handle = TheFileInfo == NULL
1812 ? NULL
1813 : ( const struct XFSHandle * ) TheFileInfo -> fh
1814 ;
1815 Node = NULL;
1816
1817 pLogMsg ( klogDebug, "FTRUNCATE(Fuse): [$(path)] FI[$(info)] FH[$(hadle)] SZ[$(size)]", "path=%s,info=%p,handle=%p,size=%d", ThePath, TheFileInfo, Handle, TheSize );
1818
1819 if ( ThePath == NULL ) {
1820 return EINVAL * - 1;
1821 }
1822
1823 if ( Handle != NULL ) {
1824 Editor = ( const struct XFSFileEditor * )
1825 XFSHandleGet ( Handle );
1826 }
1827 else {
1828 RCt = _FUSE_get_path_and_node ( ThePath, NULL, & Node, NULL );
1829 if ( RCt == 0 ) {
1830 RCt = XFSNodeFileEditor ( Node, & Editor );
1831
1832 XFSNodeRelease ( Node );
1833 }
1834 }
1835
1836 if ( RCt == 0 && Editor != NULL ) {
1837 RCt = XFSFileEditorSetSize ( Editor, TheSize );
1838 }
1839
1840 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1841 } /* XFS_FUSE_ftruncate() */
1842
1843 #endif /* USE_XFS_FUSE_FTRUNCATE == 1 */
1844
1845 /*****************************************************/
1846 #if USE_XFS_FUSE_FGETATTR == 1
1847
1848 static
1849 int
XFS_FUSE_fgetattr(const char * ThePath,struct stat * TheStat,struct fuse_file_info * TheFileInfo)1850 XFS_FUSE_fgetattr (
1851 const char * ThePath,
1852 struct stat * TheStat,
1853 struct fuse_file_info * TheFileInfo
1854 )
1855 {
1856 rc_t RCt;
1857 const struct XFSHandle * Handle;
1858 const struct XFSNode * Node;
1859 const struct XFSFileEditor * Editor;
1860
1861 RCt = 0;
1862 Handle = TheFileInfo == NULL
1863 ? NULL
1864 : ( const struct XFSHandle * ) TheFileInfo -> fh
1865 ;
1866 Node = NULL;
1867 Editor = NULL;
1868
1869 pLogMsg ( klogDebug, "FGETATTR(Fuse): [$(path)] FI[$(info)] FH[$(hadle)]", "path=%s,info=%p,handle=%p", ThePath, TheFileInfo, Handle );
1870
1871 if ( ThePath == NULL || TheStat == NULL || TheFileInfo == NULL || Handle == NULL ) {
1872 return EINVAL * - 1;
1873 }
1874
1875 memset ( TheStat, 0, sizeof ( struct stat ) );
1876
1877 Node = XFSHandleNode ( Handle );
1878 if ( Node == NULL ) {
1879 return EINVAL * - 1;
1880 }
1881
1882 Editor = ( const struct XFSFileEditor * ) XFSHandleGet ( Handle );
1883
1884 RCt = _FUSE_stat_for_node ( Node, TheStat, Editor );
1885
1886 return XFS_FUSE_rc_to_errno ( RCt ) * - 1;
1887 } /* XFS_FUSE_fgetattr () */
1888
1889 #endif /* USE_XFS_FUSE_FGETATTR == 1 */
1890
1891 /*****************************************************/
1892 #if USE_XFS_FUSE_LOCK == 1
1893
1894 static
1895 int
XFS_FUSE_lock(const char * ThePath,struct fuse_file_info * TheFileInfo,int TheCmd,struct flock * TheFLock)1896 XFS_FUSE_lock (
1897 const char * ThePath,
1898 struct fuse_file_info * TheFileInfo,
1899 int TheCmd,
1900 struct flock * TheFLock
1901 )
1902 {
1903 pLogMsg ( klogDebug, "LOCK(!): [$(path)]", "path=%s", ThePath );
1904
1905 return -EPERM;
1906 } /* XFS_FUSE_lock() */
1907
1908 #endif /* USE_XFS_FUSE_LOCK == 1 */
1909
1910 /*****************************************************/
1911 #if USE_XFS_FUSE_UTIMENS == 1
1912
1913 static
1914 int
XFS_FUSE_utimens(const char * ThePath,const struct timespec TheTimespec[2])1915 XFS_FUSE_utimens (
1916 const char * ThePath,
1917 const struct timespec TheTimespec[2]
1918 )
1919 {
1920 pLogMsg ( klogDebug, "UTIMENS(!): [$(path)]", "path=%s", ThePath );
1921
1922 return -EPERM;
1923 } /* XFS_FUSE_utimens() */
1924
1925 #endif /* USE_XFS_FUSE_UTIMENS == 1 */
1926
1927 /*****************************************************/
1928 #if USE_XFS_FUSE_BMAP == 1
1929
1930 static
1931 int
XFS_FUSE_bmap(const char * ThePath,size_t TheBlockSize,uint64_t * TheIdx)1932 XFS_FUSE_bmap (
1933 const char * ThePath,
1934 size_t TheBlockSize,
1935 uint64_t *TheIdx
1936 )
1937 {
1938 pLogMsg ( klogDebug, "BMAP(!): [$(path)]", "path=%s", ThePath );
1939
1940 return -EPERM;
1941 } /* XFS_FUSE_bmap() */
1942
1943 #endif /* USE_XFS_FUSE_BMAP == 1 */
1944
1945 /*****************************************************/
1946 #if USE_XFS_FUSE_IOCTL == 1
1947
1948 static
1949 int
XFS_FUSE_ioctl(const char * ThePath,int TheCmd,void * TheArg,struct fuse_file_info * TheFileInfo,unsigned int TheFlags,void * TheData)1950 XFS_FUSE_ioctl (
1951 const char * ThePath,
1952 int TheCmd,
1953 void *TheArg,
1954 struct fuse_file_info * TheFileInfo,
1955 unsigned int TheFlags,
1956 void * TheData
1957 )
1958 {
1959 pLogMsg ( klogDebug, "IOCTL(!): [$(path)]", "path=%s", ThePath );
1960
1961 return -EPERM;
1962 } /* XFS_FUSE_ioctl() */
1963
1964 #endif /* USE_XFS_FUSE_IOCTL == 1 */
1965
1966 /*****************************************************/
1967 #if USE_XFS_FUSE_POLL == 1
1968
1969 static
1970 int
XFS_FUSE_poll(const char * ThePath,struct fuse_file_info * TheFileInfo,struct fuse_pollhandle * ThePollHandle,unsigned * TheReventsp)1971 XFS_FUSE_poll (
1972 const char * ThePath,
1973 struct fuse_file_info * TheFileInfo,
1974 struct fuse_pollhandle * ThePollHandle,
1975 unsigned * TheReventsp
1976 )
1977 {
1978 pLogMsg ( klogDebug, "POLL(*): [$(path)]", "path=%s", ThePath );
1979
1980 return -EPERM;
1981 } /* XFS_FUSE_poll() */
1982
1983 #endif /* USE_XFS_FUSE_POLL == 1 */
1984
1985 /* Very important method, but very stupid.
1986 */
1987 rc_t
XFS_Private_InitOperations(struct fuse_operations * Operations)1988 XFS_Private_InitOperations ( struct fuse_operations * Operations )
1989 {
1990 XFS_CAN ( Operations )
1991
1992 memset ( Operations, 0, sizeof( struct fuse_operations ) );
1993
1994 #if USE_XFS_FUSE_GETATTR == 1
1995 Operations -> getattr = XFS_FUSE_getattr;
1996 #endif /* USE_XFS_FUSE_GETATTR == 1 */
1997
1998 #if USE_XFS_FUSE_READLINK == 1
1999 Operations -> readlink = XFS_FUSE_readlink;
2000 #endif /* USE_XFS_FUSE_READLINK == 1 */
2001
2002 #if USE_XFS_FUSE_GETDIR == 1
2003 Operations -> getdir = XFS_FUSE_getdir;
2004 #endif /* USE_XFS_FUSE_GETDIR == 1 */
2005
2006 #if USE_XFS_FUSE_MKNOD == 1
2007 Operations -> mknod = XFS_FUSE_mknod;
2008 #endif /* USE_XFS_FUSE_MKNOD == 1 */
2009
2010 #if USE_XFS_FUSE_MKDIR == 1
2011 Operations -> mkdir = XFS_FUSE_mkdir;
2012 #endif /* USE_XFS_FUSE_MKDIR == 1 */
2013
2014 #if USE_XFS_FUSE_UNLINK == 1
2015 Operations -> unlink = XFS_FUSE_unlink;
2016 #endif /* USE_XFS_FUSE_UNLINK == 1 */
2017
2018 #if USE_XFS_FUSE_RMDIR == 1
2019 Operations -> rmdir = XFS_FUSE_rmdir;
2020 #endif /* USE_XFS_FUSE_RMDIR == 1 */
2021
2022 #if USE_XFS_FUSE_SYMLINK == 1
2023 Operations -> symlink = XFS_FUSE_symlink;
2024 #endif /* USE_XFS_FUSE_SYMLINK == 1 */
2025
2026 #if USE_XFS_FUSE_RENAME == 1
2027 Operations -> rename = XFS_FUSE_rename;
2028 #endif /* USE_XFS_FUSE_RENAME == 1 */
2029
2030 #if USE_XFS_FUSE_LINK == 1
2031 Operations -> link = XFS_FUSE_link;
2032 #endif /* USE_XFS_FUSE_LINK == 1 */
2033
2034 #if USE_XFS_FUSE_CHMOD == 1
2035 Operations -> chmod = XFS_FUSE_chmod;
2036 #endif /* USE_XFS_FUSE_CHMOD == 1 */
2037
2038 #if USE_XFS_FUSE_CHOWN == 1
2039 Operations -> chown = XFS_FUSE_chown;
2040 #endif /* USE_XFS_FUSE_CHOWN == 1 */
2041
2042 #if USE_XFS_FUSE_TRUNCATE == 1
2043 Operations -> truncate = XFS_FUSE_truncate;
2044 #endif /* USE_XFS_FUSE_TRUNCATE == 1 */
2045
2046 #if USE_XFS_FUSE_UTIME == 1
2047 Operations -> utime = XFS_FUSE_utime;
2048 #endif /* USE_XFS_FUSE_UTIME == 1 */
2049
2050 #if USE_XFS_FUSE_OPEN == 1
2051 Operations -> open = XFS_FUSE_open;
2052 #endif /* USE_XFS_FUSE_OPEN == 1 */
2053
2054 #if USE_XFS_FUSE_READ == 1
2055 Operations -> read = XFS_FUSE_read;
2056 #endif /* USE_XFS_FUSE_READ == 1 */
2057
2058 #if USE_XFS_FUSE_WRITE == 1
2059 Operations -> write = XFS_FUSE_write;
2060 #endif /* USE_XFS_FUSE_WRITE == 1 */
2061
2062 #if USE_XFS_FUSE_STATFS == 1
2063 Operations -> statfs = XFS_FUSE_statfs;
2064 #endif /* USE_XFS_FUSE_STATFS == 1 */
2065
2066 #if USE_XFS_FUSE_FLUSH == 1
2067 Operations -> flush = XFS_FUSE_flush;
2068 #endif /* USE_XFS_FUSE_FLUSH == 1 */
2069
2070 #if USE_XFS_FUSE_RELEASE == 1
2071 Operations -> release = XFS_FUSE_release;
2072 #endif /* USE_XFS_FUSE_RELEASE == 1 */
2073
2074 #if USE_XFS_FUSE_FSYNC == 1
2075 Operations -> fsync = XFS_FUSE_fsync;
2076 #endif /* USE_XFS_FUSE_FSYNC == 1 */
2077
2078 #if USE_XFS_FUSE_SETXATTR == 1
2079 Operations -> setxattr = XFS_FUSE_setxattr;
2080 #endif /* USE_XFS_FUSE_SETXATTR == 1 */
2081
2082 #if USE_XFS_FUSE_GETXATTR == 1
2083 Operations -> getxattr = XFS_FUSE_getxattr;
2084 #endif /* USE_XFS_FUSE_GETXATTR == 1 */
2085
2086 #if USE_XFS_FUSE_LISTXATTR == 1
2087 Operations -> listxattr = XFS_FUSE_listxattr;
2088 #endif /* USE_XFS_FUSE_LISTXATTR == 1 */
2089
2090 #if USE_XFS_FUSE_REMOVEXATTR == 1
2091 Operations -> removexattr = XFS_FUSE_removexattr;
2092 #endif /* USE_XFS_FUSE_REMOVEXATTR == 1 */
2093
2094 #if USE_XFS_FUSE_OPENDIR == 1
2095 Operations -> opendir = XFS_FUSE_opendir;
2096 #endif /* USE_XFS_FUSE_OPENDIR == 1 */
2097
2098 #if USE_XFS_FUSE_READDIR == 1
2099 Operations -> readdir = XFS_FUSE_readdir;
2100 #endif /* USE_XFS_FUSE_READDIR == 1 */
2101
2102 #if USE_XFS_FUSE_RELEASEDIR == 1
2103 Operations -> releasedir = XFS_FUSE_releasedir;
2104 #endif /* USE_XFS_FUSE_RELESEDIR == 1 */
2105
2106 #if USE_XFS_FUSE_FSYNCDIR == 1
2107 Operations -> fsyncdir = XFS_FUSE_fsyncdir;
2108 #endif /* USE_XFS_FUSE_FSYNCDIR == 1 */
2109
2110 #if USE_XFS_FUSE_INIT == 1
2111 Operations -> init = XFS_FUSE_init;
2112 #endif /* USE_XFS_FUSE_INIT == 1 */
2113
2114 #if USE_XFS_FUSE_DESTROY == 1
2115 Operations -> destroy = XFS_FUSE_destroy;
2116 #endif /* USE_XFS_FUSE_DESTROY == 1 */
2117
2118 #if USE_XFS_FUSE_ACCESS == 1
2119 Operations -> access = XFS_FUSE_access;
2120 #endif /* USE_XFS_FUSE_ACCESS == 1 */
2121
2122 #if USE_XFS_FUSE_CREATE == 1
2123 Operations -> create = XFS_FUSE_create;
2124 #endif /* USE_XFS_FUSE_CREATE == 1 */
2125
2126 #if USE_XFS_FUSE_FTRUNCATE == 1
2127 Operations -> ftruncate = XFS_FUSE_ftruncate;
2128 #endif /* USE_XFS_FUSE_FTRUNCATE == 1 */
2129
2130 #if USE_XFS_FUSE_FGETATTR == 1
2131 Operations -> fgetattr = XFS_FUSE_fgetattr;
2132 #endif /* USE_XFS_FUSE_FGETATTR == 1 */
2133
2134 #if USE_XFS_FUSE_LOCK == 1
2135 Operations -> lock = XFS_FUSE_lock;
2136 #endif /* USE_XFS_FUSE_LOCK == 1 */
2137
2138 #if USE_XFS_FUSE_UTIMENS == 1
2139 Operations -> utimens = XFS_FUSE_utimens;
2140 #endif /* USE_XFS_FUSE_UTIMENS == 1 */
2141
2142 #if USE_XFS_FUSE_BMAP == 1
2143 Operations -> bmap = XFS_FUSE_bmap;
2144 #endif /* USE_XFS_FUSE_BMAP == 1 */
2145
2146 #if USE_XFS_FUSE_IOCTL == 1
2147 Operations -> ioctl = XFS_FUSE_ioctl;
2148 #endif /* USE_XFS_FUSE_IOCTL == 1 */
2149
2150 #if USE_XFS_FUSE_POLL == 1
2151 Operations -> poll = XFS_FUSE_poll;
2152 #endif /* USE_XFS_FUSE_POLL == 1 */
2153
2154 return 0;
2155 } /* XFS_Private_InitOperations() */
2156