-
Notifications
You must be signed in to change notification settings - Fork 149
/
XrdSfsInterface.hh
1336 lines (1147 loc) · 63.5 KB
/
XrdSfsInterface.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef __SFS_INTERFACE_H__
#define __SFS_INTERFACE_H__
/******************************************************************************/
/* */
/* X r d S f s I n t e r f a c e . h h */
/* */
/* (c) 2018 by the Board of Trustees of the Leland Stanford, Jr., University */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include <string.h> // For strlcpy()
#include <errno.h>
#include <cstdint>
#include <sys/types.h>
#include <sys/stat.h>
#include "XrdOuc/XrdOucErrInfo.hh"
#include "XrdOuc/XrdOucIOVec.hh"
#include "XrdOuc/XrdOucSFVec.hh"
#include "XrdSfs/XrdSfsGPFile.hh"
/******************************************************************************/
/* O p e n M o d e s */
/******************************************************************************/
#define SFS_O_RDONLY 0 // open read/only
#define SFS_O_WRONLY 1 // open write/only
#define SFS_O_RDWR 2 // open read/write
#define SFS_O_CREAT 0x100 // used for file creation
#define SFS_O_TRUNC 0x200 // used for file truncation
#define SFS_O_MULTIW 0x400 // used for multi-write locations
#define SFS_O_NOTPC 0x800 // used to suppress TPC opens
#define SFS_O_POSC 0x0100000 // persist on successful close
#define SFS_O_FORCE 0x0200000 // used for locate only
#define SFS_O_HNAME 0x0400000 // used for locate only
#define SFS_O_LOCAL 0x0800000 // used for locate only (local cmd)
#define SFS_O_NOWAIT 0x01000000 // do not impose operational delays
#define SFS_O_RAWIO 0x02000000 // allow client-side decompression
#define SFS_O_RESET 0x04000000 // Reset any cached information
#define SFS_O_REPLICA 0x08000000 // Open for replication
// The following flag may be set in the access mode arg for open() & mkdir()
// Note that on some systems mode_t is 16-bits so we use a careful value!
//
#define SFS_O_MKPTH 0x00004000 // Make directory path if missing
// The following options are here to provide a uniform clustering interface.
// They may be passed through open/locate/stat, as applicable.
//
#define SFS_O_LOCATE 0x10000000 // This request generated by locate()
#define SFS_O_STAT 0x20000000 // This request generated by stat()
#define SFS_O_META 0x40000000 // This request generated by metaop
/******************************************************************************/
/* D e f i n e s */
/******************************************************************************/
// Common fctl command values (0 to 255)
//
#define SFS_FCTL_GETFD 1 // Return file descriptor if possible
#define SFS_FCTL_STATV 2 // Return visa information
#define SFS_FCTL_SPEC1 3 // Return implementation defined information
#define SFS_SFIO_FDVAL 0x80000000 // Use SendData() method GETFD response value
// Common fsctl command values (0 to 255)
//
#define SFS_FSCTL_CMD 255
#define SFS_FSCTL_LOCATE 1 // Locate a file
#define SFS_FSCTL_STATFS 2 // Return FS data
#define SFS_FSCTL_STATLS 3 // Return LS data
#define SFS_FSCTL_STATXA 4 // Return XA data
#define SFS_FSCTL_STATCC 5 // Return Cluster Config status
#define SFS_FSCTL_PLUGIN 8 // Return Implementation Dependent Data
#define SFS_FSCTL_PLUGIO 16 // Return Implementation Dependent Data
// Return values for integer & XrdSfsXferSize returning XrdSfs methods
//
#define SFS_STALL 1 // Return value -> Seconds to stall client
#define SFS_OK 0 // ErrInfo code -> All is well
#define SFS_ERROR -1 // ErrInfo code -> Error occurred
#define SFS_REDIRECT -256 // ErrInfo code -> Port number to redirect to
#define SFS_STARTED -512 // ErrInfo code -> Estimated seconds to completion
#define SFS_DATA -1024 // ErrInfo code -> Length of data
#define SFS_DATAVEC -2048 // ErrInfo code -> Num iovec elements in msgbuff
// The following macros are used for dealing with special local paths
//
#define SFS_LCLPRFX "/=/"
#define SFS_LCLPLEN 3
#define SFS_LCLPATH(x) !strncmp(x, SFS_LCLPRFX, SFS_LCLPLEN)
#define SFS_LCLPRFY "/="
#define SFS_LCLROOT(x) !strncmp(x, SFS_LCLPRFX, SFS_LCLPLEN-1) \
&& (*(x+SFS_LCLPLEN-1) == '/' || *(x+SFS_LCLPLEN-1) == 0)
// The native SFS page size
//
#define XrdSfsPageSize 4096
/******************************************************************************/
/* S t r u c t u r e s & T y p e d e f s */
/******************************************************************************/
typedef long long XrdSfsFileOffset;
typedef int XrdSfsFileOpenMode;
typedef int XrdSfsMode;
typedef int XrdSfsXferSize;
enum XrdSfsFileExistence
{
XrdSfsFileExistNo,
XrdSfsFileExistIsFile,
XrdSfsFileExistIsDirectory,
XrdSfsFileExistIsOffline,
XrdSfsFileExistIsOther
};
//------------------------------------------------
#define Prep_PRTY0 0
#define Prep_PRTY1 1
#define Prep_PRTY2 2
#define Prep_PRTY3 3
#define Prep_PMASK 3
#define Prep_SENDAOK 4
#define Prep_SENDERR 8
#define Prep_SENDACK 12
#define Prep_WMODE 16
#define Prep_STAGE 32
#define Prep_COLOC 64
#define Prep_FRESH 128
#define Prep_CANCEL 256
#define Prep_QUERY 512
#define Prep_EVICT 1024
class XrdOucTList;
struct XrdSfsFSctl //!< SFS_FSCTL_PLUGIN/PLUGIO parms
{
const char *Arg1; //!< PLUGIO, PLUGIN
int Arg1Len; //!< Length
int Arg2Len; //!< Length
const char *Arg2; //!< PLUGIN opaque string
};
struct XrdSfsPrep //!< Prepare parameters
{
char *reqid; //!< Request ID
char *notify; //!< Notification path or 0
int opts; //!< Prep_xxx
XrdOucTList *paths; //!< List of paths
XrdOucTList *oinfo; //!< 1-to-1 correspondence of opaque info
};
/******************************************************************************/
/* A b s t r a c t C l a s s e s */
/******************************************************************************/
class XrdOucEnv;
class XrdSecEntity;
struct XrdSfsFACtl;
/******************************************************************************/
/* O b j e c t W r a p p i n g G u i d e */
/******************************************************************************/
/* The XrdSfsDirectory and XrdSfsFile objects can be wrapped. Wraping can be
used to add functionality. The process is common and pretty muche rote.
There is only one caveat: all wrappers must use the same XrdOucErrInfo
object. This is because the ErrInfo object contains client parameters that
are used to control how things are done to be backward compatible. Newer
client can then use more efficient internal processing. The SFS provides
two ways to make sure the same ErrInfo object is used by all objects in
the wrapped chain. Forward propagation (the one typically used) and
backward propagation (used in certain unusual cases). In forward mode,
the ErrInfo object of the last object in the chain is propagated to the
front of the chain. In backward mode the reverse happens. Let's assume
the following scenarion. Object-A wraps object-B (the object here can be
directory or file object). In forward mode weneed to create objects in
reverse order (bottom to top) which is typically what you would do anyway
as you need to capture the pinter to the object your wrapping. So, using
newFile() as an example where sfsP points to the Interface being wrapped:
XrdSfsFile *newFile(const char *user, int MonID)
{
XrdSfsFile *wrapped_file = sfsP->newFile(user, MonID);
if (!wrapped_file) return 0;
return new mySfsFile(wrapped_file,...);
}
class mySfsFile : public XrdSfsFile
{public:
mySfsFile(XrdSfsFile *wrapped_file,...) : XrdSfsFile(*wrapped_file)
{....}
....
};
Notice we are allocating the wrapped file ahead of the wrapper so that
the wrapper can use the ErrInfo object of the wrapped file.
In backward mode we want to use the ErrInfo object of the front-most
wrapper for all wrappers after it. This mechanism is far more complicated
due to error handling requirements. However, it's useful when a wrapped
object is not necessarily instantiated to accomplish the needs of the
wrapper. An example of this is the newFile and newDir implementations for
XrdSsi where wrapped object creation is subject to the resource name.
*/
/******************************************************************************/
/* X r d S f s D i r e c t o r y */
/******************************************************************************/
//------------------------------------------------------------------------------
//! The XrdSfsDirectory object is returned by XrdSfsFileSystem::newFile() when
//! the caller wants to be able to perform directory oriented operations.
//------------------------------------------------------------------------------
class XrdSfsDirectory
{
public:
//-----------------------------------------------------------------------------
//! The error object is used to return details whenever something other than
//! SFS_OK is returned from the methods in this class, when noted.
//-----------------------------------------------------------------------------
XrdOucErrInfo &error;
//-----------------------------------------------------------------------------
//! Open a directory.
//!
//! @param path - Pointer to the path of the directory to be opened.
//! @param client - Client's identify (see common description).
//! @param opaque - path's CGI information (see common description).
//!
//! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, ir SFS_STALL
//-----------------------------------------------------------------------------
virtual int open(const char *path,
const XrdSecEntity *client = 0,
const char *opaque = 0) = 0;
//-----------------------------------------------------------------------------
//! Get the next directory entry.
//!
//! @return A null terminated string with the directory name. Normally, "."
//! ".." are not returned. If a null pointer is returned then if this
//! is due to an error, error.code should contain errno. Otherwise,
//! error.code should contain zero to indicate that no more entries
//! exist (i.e. end of list).
//-----------------------------------------------------------------------------
virtual const char *nextEntry() = 0;
//-----------------------------------------------------------------------------
//! Close the directory.
//!
//! @return One of SFS_OK or SFS_ERROR
//-----------------------------------------------------------------------------
virtual int close() = 0;
//-----------------------------------------------------------------------------
//! Get the directory path.
//!
//! @return Null terminated string of the path used in open().
//-----------------------------------------------------------------------------
virtual const char *FName() = 0;
//-----------------------------------------------------------------------------
//! Set the stat() buffer where stat information is to be placed corresponding
//! to the directory entry returned by nextEntry().
//!
//! @return If supported, SFS_OK should be returned. If not supported, then
//! SFS_ERROR should be returned with error.code set to ENOTSUP.
//-----------------------------------------------------------------------------
virtual int autoStat(struct stat *buf)
{(void)buf;
error.setErrInfo(ENOTSUP, "Not supported.");
return SFS_ERROR;
}
//-----------------------------------------------------------------------------
//! Constructor (user and MonID are the ones passed to newDir()!). This
//! constructor should only be used by base plugins. Plugins that wrap an
//! SfsDirectory should use the second version of the constructor shown below.
//!
//! @param user - Text identifying the client responsible for this call.
//! The pointer may be null if identification is missing.
//! @param MonID - The monitoring identifier assigned to this and all
//! future requests using the returned object.
//-----------------------------------------------------------------------------
XrdSfsDirectory(const char *user=0, int MonID=0)
: error(*(new XrdOucErrInfo(user, MonID)))
{lclEI = &error;}
//-----------------------------------------------------------------------------
//! Constructor for plugins that wrap another SfsDirectory. This constructor
//! inherits the error object from a wrapped SfsDirectory object so that only
//! one identical error object exists for all directory objects in the chain.
//!
//! @param wrapD - Reference to the directory object being wrapped.
//-----------------------------------------------------------------------------
XrdSfsDirectory(XrdSfsDirectory &wrapD)
: error(wrapD.error), lclEI(0) {}
//-----------------------------------------------------------------------------
//! Constructor for base plugins that predefined an error object. This is a
//! convenience constructor for base plugins only.
//!
//! @param eInfo - Reference to the error object to use.
//-----------------------------------------------------------------------------
XrdSfsDirectory(XrdOucErrInfo &eInfo)
: error(eInfo), lclEI(0) {}
//-----------------------------------------------------------------------------
//! Destructor
//-----------------------------------------------------------------------------
virtual ~XrdSfsDirectory() {if (lclEI) delete lclEI;}
private:
XrdOucErrInfo* lclEI;
}; // class XrdSfsDirectory
/******************************************************************************/
/* X r d S f s F i l e */
/******************************************************************************/
//------------------------------------------------------------------------------
//! The XrdSfsFile object is returned by XrdSfsFileSystem::newFile() when
//! the caller wants to be able to perform file oriented operations.
//------------------------------------------------------------------------------
class XrdSfsAio;
class XrdSfsDio;
class XrdSfsXio;
class XrdSfsFile
{
public:
//-----------------------------------------------------------------------------
//! The error object is used to return details whenever something other than
//! SFS_OK is returned from the methods in this class, when noted.
//-----------------------------------------------------------------------------
XrdOucErrInfo &error;
//-----------------------------------------------------------------------------
//! Open a file.
//!
//! @param path - Pointer to the path of the file to be opened.
//! @param oMode - Flags indicating how the open is to be handled.
//! SFS_O_CREAT create the file
//! SFS_O_MKPTH Make directory path if missing
//! SFS_O_NOWAIT do not impose operational delays
//! SFS_O_POSC persist only on successful close
//! SFS_O_RAWIO allow client-side decompression
//! SFS_O_RDONLY open read/only
//! SFS_O_RDWR open read/write
//! SFS_O_REPLICA Open for replication
//! SFS_O_RESET Reset any cached information
//! SFS_O_TRUNC truncate existing file to zero length
//! SFS_O_WRONLY open write/only
//! @param cMode - The file's mode if it will be created.
//! @param client - Client's identify (see common description).
//! @param opaque - path's CGI information (see common description).
//!
//! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED
//-----------------------------------------------------------------------------
virtual int open(const char *fileName,
XrdSfsFileOpenMode openMode,
mode_t createMode,
const XrdSecEntity *client = 0,
const char *opaque = 0) = 0;
//-----------------------------------------------------------------------------
//! Close the file.
//!
//! @return One of SFS_OK or SFS_ERROR.
//-----------------------------------------------------------------------------
virtual int close() = 0;
//-----------------------------------------------------------------------------
//! Execute a special operation on the file (version 1)
//!
//! @param cmd - The operation to be performed (see below).
//! SFS_FCTL_GETFD Return file descriptor if possible
//! SFS_FCTL_STATV Reserved for future use.
//! @param args - specific arguments to cmd
//! SFS_FCTL_GETFD Set to zero.
//! @param eInfo - The object where error info or results are to be returned.
//! This is legacy and the error onject may be used as well.
//!
//! @return If an error occurs or the operation is not support, SFS_ERROR
//! should be returned with error.code set to errno. Otherwise,
//! SFS_FCTL_GETFD error.code holds the real file descriptor number
//! If the value is negative, sendfile() is not used.
//! If the value is SFS_SFIO_FDVAL then the SendData()
//! method is used for future read requests.
//-----------------------------------------------------------------------------
virtual int fctl(const int cmd,
const char *args,
XrdOucErrInfo &eInfo) = 0;
//-----------------------------------------------------------------------------
//! Execute a special operation on the file (version 2)
//!
//! @param cmd - The operation to be performed:
//! SFS_FCTL_SPEC1 Perform implementation defined action
//! @param alen - Length of data pointed to by args.
//! @param args - Data sent with request, zero if alen is zero.
//! @param client - Client's identify (see common description).
//!
//! @return SFS_OK a null response is sent.
//! @return SFS_DATA error.code length of the data to be sent.
//! error.message contains the data to be sent.
//! o/w one of SFS_ERROR, SFS_REDIRECT, or SFS_STALL.
//-----------------------------------------------------------------------------
virtual int fctl(const int cmd,
int alen,
const char *args,
const XrdSecEntity *client = 0)
{
(void)cmd; (void)alen; (void)args; (void)client;
return SFS_OK;
}
//-----------------------------------------------------------------------------
//! Get the file path.
//!
//! @return Null terminated string of the path used in open().
//-----------------------------------------------------------------------------
virtual const char *FName() = 0;
//-----------------------------------------------------------------------------
//! Get file's memory mapping if one exists (memory mapped files only).
//!
//! @param addr - Place where the starting memory address is returned.
//! @param size - Place where the file's size is returned.
//!
//! @return SFS_OK when the file is memory mapped or any other code otherwise.
//-----------------------------------------------------------------------------
virtual int getMmap(void **Addr, off_t &Size) = 0;
//-----------------------------------------------------------------------------
//! Read file pages into a buffer and return corresponding checksums.
//!
//! @param offset - The offset where the read is to start. It must be
//! page aligned.
//! @param buffer - pointer to buffer where the bytes are to be placed.
//! @param rdlen - The number of bytes to read. The amount must be an
//! integral number of XrdSfsPageSize bytes.
//! @param csvec - A vector of [rdlen/XrdSfsPageSize] entries which will be
//! filled with the corresponding CRC32 checksum for each
//! page. A nil pointer does not return the checksums.
//! @param verify - When true, the checksum is verified for each page; an
//! error is returned if any checksum is incorrect.
//!
//! @return >= 0 The number of bytes that placed in buffer.
//! @return SFS_ERROR File could not be read, error holds the reason.
//-----------------------------------------------------------------------------
virtual XrdSfsXferSize pgRead(XrdSfsFileOffset offset,
char *buffer,
XrdSfsXferSize rdlen,
uint32_t *csvec,
bool verify=true);
//-----------------------------------------------------------------------------
//! Read file pages and checksums using asynchronous I/O.
//!
//! @param aioparm - Pointer to async I/O object controlling the I/O.
//! @param verify - When true, the checksum is verified for each page; an
//! error is returned if any checksum is incorrect.
//!
//! @return SFS_OK Request accepted and will be scheduled.
//! @return SFS_ERROR File could not be read, error holds the reason.
//-----------------------------------------------------------------------------
virtual int pgRead(XrdSfsAio *aioparm, bool verify=true);
//-----------------------------------------------------------------------------
//! Write file pages into a file with corresponding checksums.
//!
//! @param offset - The offset where the write is to start. It must be
//! page aligned.
//! @param buffer - pointer to buffer containing the bytes to write.
//! @param wrlen - The number of bytes to write. If amount is not an
//! integral number of XrdSfsPageSize bytes, then this must
//! be the last write to the file at or above the offset.
//! @param csvec - A vector of [CEILING(wrlen/XrdSfsPageSize)] entries which
//! contain the corresponding CRC32 checksum for each page.
//! A nil pointer causes the checksums to be computed.
//! @param verify - When true, the checksum in csvec is verified for each
//! page; and error is returned if any checksum is incorrect.
//!
//! @return >= 0 The number of bytes written.
//! @return SFS_ERROR File could not be read, error holds the reason.
//-----------------------------------------------------------------------------
virtual XrdSfsXferSize pgWrite(XrdSfsFileOffset offset,
char *buffer,
XrdSfsXferSize wrlen,
uint32_t *csvec,
bool verify=true);
//-----------------------------------------------------------------------------
//! Write file pages and checksums using asynchronous I/O.
//!
//! @param aioparm - Pointer to async I/O object controlling the I/O.
//! @param verify - When true, the checksum in csvec is verified for each
//! page; and error is returned if any checksum is incorrect.
//!
//! @return SFS_OK Request accepted and will be scheduled.
//! @return SFS_ERROR File could not be read, error holds the reason.
//-----------------------------------------------------------------------------
virtual int pgWrite(XrdSfsAio *aioparm, bool verify=true);
//-----------------------------------------------------------------------------
//! Preread file blocks into the file system cache.
//!
//! @param offset - The offset where the read is to start.
//! @param size - The number of bytes to pre-read.
//!
//! @return >= 0 The number of bytes that will be pre-read.
//! @return SFS_ERROR File could not be preread, error holds the reason.
//-----------------------------------------------------------------------------
virtual XrdSfsXferSize read(XrdSfsFileOffset offset,
XrdSfsXferSize size) = 0;
//-----------------------------------------------------------------------------
//! Read file bytes into a buffer.
//!
//! @param offset - The offset where the read is to start.
//! @param buffer - pointer to buffer where the bytes are to be placed.
//! @param size - The number of bytes to read.
//!
//! @return >= 0 The number of bytes that placed in buffer.
//! @return SFS_ERROR File could not be read, error holds the reason.
//-----------------------------------------------------------------------------
virtual XrdSfsXferSize read(XrdSfsFileOffset offset,
char *buffer,
XrdSfsXferSize size) = 0;
//-----------------------------------------------------------------------------
//! Read file bytes using asynchronous I/O.
//!
//! @param aioparm - Pointer to async I/O object controlling the I/O.
//!
//! @return SFS_OK Request accepted and will be scheduled.
//! @return SFS_ERROR File could not be read, error holds the reason.
//-----------------------------------------------------------------------------
virtual int read(XrdSfsAio *aioparm) = 0;
//-----------------------------------------------------------------------------
//! Given an array of read requests (size rdvCnt), read them from the file
//! and place the contents consecutively in the provided buffer. A dumb default
//! implementation is supplied but should be replaced to increase performance.
//!
//! @param readV pointer to the array of read requests.
//! @param rdvcnt the number of elements in readV.
//!
//! @return >=0 The numbe of bytes placed into the buffer.
//! @return SFS_ERROR File could not be read, error holds the reason.
//-----------------------------------------------------------------------------
virtual XrdSfsXferSize readv(XrdOucIOVec *readV,
int rdvCnt);
//-----------------------------------------------------------------------------
//! Send file bytes via a XrdSfsDio sendfile object to a client (optional).
//!
//! @param sfDio - Pointer to the sendfile object for data transfer.
//! @param offset - The offset where the read is to start.
//! @param size - The number of bytes to read and send.
//!
//! @return SFS_ERROR File not read, error object has reason.
//! @return SFS_OK Either data has been successfully sent via sfDio or no
//! data has been sent and a normal read() should be issued.
//-----------------------------------------------------------------------------
virtual int SendData(XrdSfsDio *sfDio,
XrdSfsFileOffset offset,
XrdSfsXferSize size)
{
(void)sfDio; (void)offset; (void)size;
return SFS_OK;
}
//-----------------------------------------------------------------------------
//! Write file bytes from a buffer.
//!
//! @param offset - The offset where the write is to start.
//! @param buffer - pointer to buffer where the bytes reside.
//! @param size - The number of bytes to write.
//!
//! @return >= 0 The number of bytes that were written.
//! @return SFS_ERROR File could not be written, error holds the reason.
//-----------------------------------------------------------------------------
virtual XrdSfsXferSize write(XrdSfsFileOffset offset,
const char *buffer,
XrdSfsXferSize size) = 0;
//-----------------------------------------------------------------------------
//! Write file bytes using asynchronous I/O.
//!
//! @param aioparm - Pointer to async I/O object controlling the I/O.
//!
//! @return 0 Request accepted and will be scheduled.
//! @return !0 Request not accepted, returned value is errno.
//-----------------------------------------------------------------------------
virtual int write(XrdSfsAio *aioparm) = 0;
//-----------------------------------------------------------------------------
//! Given an array of write requests (size wdvcnt), write them to the file
//! from the provided associated buffer. A dumb default implementation is
//! supplied but should be replaced to increase performance.
//!
//! @param writeV pointer to the array of write requests.
//! @param wdvcnt the number of elements in writeV.
//!
//! @return >=0 The total number of bytes written to the file.
//! @return SFS_ERROR File could not be written, error holds the reason.
//-----------------------------------------------------------------------------
virtual XrdSfsXferSize writev(XrdOucIOVec *writeV,
int wdvCnt);
//-----------------------------------------------------------------------------
//! Return state information on the file.
//!
//! @param buf - Pointer to the structure where info it to be returned.
//!
//! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL. When SFS_OK
//! is returned, buf must hold stat information.
//-----------------------------------------------------------------------------
virtual int stat(struct stat *buf) = 0;
//-----------------------------------------------------------------------------
//! Make sure all outstanding data is actually written to the file (sync).
//!
//! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED
//-----------------------------------------------------------------------------
virtual int sync() = 0;
//-----------------------------------------------------------------------------
//! Make sure all outstanding data is actually written to the file (async).
//!
//! @return SFS_OK Request accepted and will be scheduled.
//! @return SFS_ERROR Request could not be accepted, return error has reason.
//-----------------------------------------------------------------------------
virtual int sync(XrdSfsAio *aiop) = 0;
//-----------------------------------------------------------------------------
//! Truncate the file.
//!
//! @param fsize - The size that the file is to have.
//!
//! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, or SFS_STALL
//-----------------------------------------------------------------------------
virtual int truncate(XrdSfsFileOffset fsize) = 0;
//-----------------------------------------------------------------------------
//! Get compression information for the file.
//!
//! @param cxtype - Place where the compression algorithm name is to be placed
//! @param cxrsz - Place where the compression page size is to be returned
//!
//! @return One of the valid SFS return codes described above. If the file
//! is not compressed or an error is returned, cxrsz must be set to 0.
//-----------------------------------------------------------------------------
virtual int getCXinfo(char cxtype[4], int &cxrsz) = 0;
//-----------------------------------------------------------------------------
//! Enable exchange buffer I/O for write calls.
//!
//! @param - Pointer to the XrdSfsXio object to be used for buffer exchanges.
//-----------------------------------------------------------------------------
virtual void setXio(XrdSfsXio *xioP) { (void)xioP; }
//-----------------------------------------------------------------------------
//! Constructor (user and MonID are the ones passed to newFile()!). This
//! constructor should only be used by base plugins. Plugins that wrap an
//! SfsFile should use the second version of the constructor shown below.
//!
//! @param user - Text identifying the client responsible for this call.
//! The pointer may be null if identification is missing.
//! @param MonID - The monitoring identifier assigned to this and all
//! future requests using the returned object.
//-----------------------------------------------------------------------------
XrdSfsFile(const char *user=0, int MonID=0)
: error(*(new XrdOucErrInfo(user, MonID)))
{lclEI = &error; pgwrEOF = 0;}
//-----------------------------------------------------------------------------
//! Constructor for plugins that wrap another SFS plugin. This constructor
//! inherits the error object from a wrapped XrdSfsFile object so that only
//! one identical error object exists for all file objects in the chain.
//!
//! @param wrapF - Reference to the file object being wrapped.
//-----------------------------------------------------------------------------
XrdSfsFile(XrdSfsFile &wrapF)
: error(wrapF.error), lclEI(0), pgwrEOF(0) {}
//-----------------------------------------------------------------------------
//! Constructor for base plugins that predefined an error object. This is a
//! convenience constructor for base plugins only.
//!
//! @param eInfo - Reference to the error object to use.
//-----------------------------------------------------------------------------
XrdSfsFile(XrdOucErrInfo &eInfo)
: error(eInfo), lclEI(0), pgwrEOF(0) {}
//-----------------------------------------------------------------------------
//! Destructor
//-----------------------------------------------------------------------------
virtual ~XrdSfsFile() {if (lclEI) delete lclEI;}
private:
XrdOucErrInfo* lclEI;
XrdSfsFileOffset pgwrEOF;
}; // class XrdSfsFile
/******************************************************************************/
/* X r d S f s F i l e S y s t e m */
/******************************************************************************/
//-----------------------------------------------------------------------------
//! Common parameters: Many of the methods have certain common parameters.
//! These are documented here to avoid lengthy duplicate descriptions.
//!
//! @param eInfo - The object where error info or results are to be returned.
//! For errors, you should return information as follows:
//! SFS_OK eInfo may contain results, as described in
//! specified method description that follows.
//! SFS_ERROR eInfo.code - errno number
//! eInfo.message - error message text
//! SFS_REDIRECT eInfo.code - target port number
//! eInfo.message - target host address/name
//! SFS_STALL eInfo.code - expected seconds to stall
//! eInfo.message - reason for the delay
//! SFS_STARTED eInfo.code - expected seconds to completion
//! eInfo.message - reason for the delay
//! SFS_DATA eInfo.code - length of data in message
//! eInfo.message - the request data
//!
//! @param client - Pointer to the client's identity information or nil if
//! the identity is not known.
//!
//! @param opaque - Pointer to the CGI information associated with Path or
//! nil if there is no opaque information.
//-----------------------------------------------------------------------------
class XrdSfsFileSystem
{
public:
//-----------------------------------------------------------------------------
//! Obtain a new director object to be used for future directory requests.
//!
//! @param user - Text identifying the client responsible for this call.
//! The pointer may be null if identification is missing.
//! @param MonID - The monitoring identifier assigned to this and all
//! future requests using the returned object.
//!
//! @return pointer- Pointer to an XrdSfsDirectory object.
//! @return nil - Insufficient memory to allocate an object.
//-----------------------------------------------------------------------------
virtual XrdSfsDirectory *newDir(char *user=0, int MonID=0) = 0;
//-----------------------------------------------------------------------------
//! Obtain a new wrapped directory object to be used for future requests.
//!
//! @param eInfo - Reference to the error object to be used by the new
//! directory object. Note that an implementation is supplied
//! for compatability purposes but it returns a nil pointer
//! which is considered to be a failure. You must supply an
//! implementation for this to work correctly.
//!
//! @return pointer- Pointer to an XrdSfsDirectory object.
//! @return nil - Insufficient memory to allocate an object.
//-----------------------------------------------------------------------------
virtual XrdSfsDirectory *newDir(XrdOucErrInfo &eInfo)
{(void)eInfo; return 0;}
//-----------------------------------------------------------------------------
//! Obtain a new file object to be used for a future file requests.
//!
//! @param user - Text identifying the client responsible for this call.
//! The pointer may be null if identification is missing.
//! @param MonID - The monitoring identifier assigned to this and all
//! future requests using the returned object.
//!
//! @return pointer- Pointer to an XrdSfsFile object.
//! @return nil - Insufficient memory to allocate an object.
//-----------------------------------------------------------------------------
virtual XrdSfsFile *newFile(char *user=0, int MonID=0) = 0;
//-----------------------------------------------------------------------------
//! Obtain a new wrapped file object to be used for a future requests.
//!
//! @param eInfo - Reference to the error object to be used by the new file
//! object. Note that an implementation is supplied for
//! compatibility purposes but it returns a nil pointer
//! which is considered to be a failure. You must supply an
//! implementation for this to work correctly.
//!
//! @return pointer- Pointer to an XrdSfsFile object.
//! @return nil - Insufficient memory to allocate an object.
//-----------------------------------------------------------------------------
virtual XrdSfsFile *newFile(XrdOucErrInfo &eInfo)
{(void)eInfo; return 0;}
//-----------------------------------------------------------------------------
//! Obtain checksum information for a file.
//!
//! @param Func - The checksum operation to be performed:
//! csCalc - (re)calculate and return the checksum value
//! csGet - return the existing checksum value, if any
//! csSize - return the size of the checksum value that
//! corresponds to csName (path may be null).
//! @param csName - The name of the checksum value wanted.
//! @param path - Pointer to the path of the file in question.
//! @param eInfo - The object where error info or results are to be returned.
//! @param client - Client's identify (see common description).
//! @param opaque - Path's CGI information (see common description).
//!
//! @return One of SFS_OK, SFS_ERROR, or SFS_REDIRECT. When SFS_OK is returned,
//! eInfo should contain results, as follows:
//! csCalc/csGet eInfo.message - null terminated string with the
//! checksum value in ASCII hex.
//! csSize eInfo.code - size of binary checksum value.
//-----------------------------------------------------------------------------
enum csFunc {csCalc = 0, csGet, csSize};
virtual int chksum( csFunc Func,
const char *csName,
const char *path,
XrdOucErrInfo &eInfo,
const XrdSecEntity *client = 0,
const char *opaque = 0)
{
(void)Func; (void)csName; (void)path; (void)eInfo; (void)client;
(void)opaque;
eInfo.setErrInfo(ENOTSUP, "Not supported.");
return SFS_ERROR;
}
//-----------------------------------------------------------------------------
//! Change file mode settings.
//!
//! @param path - Pointer to the path of the file in question.
//! @param mode - The new file mode setting.
//! @param eInfo - The object where error info or results are to be returned.
//! @param client - Client's identify (see common description).
//! @param opaque - Path's CGI information (see common description).
//!
//! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT or SFS_STALL
//-----------------------------------------------------------------------------
virtual int chmod(const char *path,
XrdSfsMode mode,
XrdOucErrInfo &eInfo,
const XrdSecEntity *client = 0,
const char *opaque = 0) = 0;
//-----------------------------------------------------------------------------
//! Notify filesystem that a client has connected.
//!
//! @param client - Client's identify (see common description).
//-----------------------------------------------------------------------------
virtual void Connect(const XrdSecEntity *client = 0)
{
(void)client;
}
//-----------------------------------------------------------------------------
//! Notify filesystem that a client has disconnected.
//!
//! @param client - Client's identify (see common description).
//-----------------------------------------------------------------------------
virtual void Disc(const XrdSecEntity *client = 0)
{
(void)client;
}
//-----------------------------------------------------------------------------
//! Notify filesystem about implmentation dependent environment. This method
//! may be called only once, if at all, right after obtaining this object.
//!
//! @param envP - Pointer to environmental information.
//-----------------------------------------------------------------------------
virtual void EnvInfo(XrdOucEnv *envP)
{
(void)envP;
}
//-----------------------------------------------------------------------------
//! Return directory/file existence information (short stat).
//!
//! @param path - Pointer to the path of the file/directory in question.
//! @param eFlag - Where the results are to be returned.
//! @param eInfo - The object where error info is to be returned.
//! @param client - Client's identify (see common description).
//! @param opaque - Path's CGI information (see common description).
//!
//! @return One of SFS_OK, SFS_ERROR, SFS_REDIRECT, SFS_STALL, or SFS_STARTED
//! When SFS_OK is returned, eFlag must be properly set, as follows:
//! XrdSfsFileExistNo - path does not exist
//! XrdSfsFileExistIsFile - path refers to an online file
//! XrdSfsFileExistIsDirectory - path refers to an online directory
//! XrdSfsFileExistIsOffline - path refers to an offline file
//! XrdSfsFileExistIsOther - path is neither a file nor directory
//-----------------------------------------------------------------------------
virtual int exists(const char *path,
XrdSfsFileExistence &eFlag,
XrdOucErrInfo &eInfo,
const XrdSecEntity *client = 0,
const char *opaque = 0) = 0;
//-----------------------------------------------------------------------------
//! Perform a filesystem extended attribute function.
//!
//! @param faReq - pointer to the request object (see XrdSfsFAttr.hh). If the
//! pointer is nill, simply return whether or not extended
//! attributes are supported.
//! @param eInfo - The object where error info or results are to be returned.
//! @param client - Client's identify (see common description).
//!
//! @return SFS_OK a null response is sent.
//! @return SFS_DATA error.code length of the data to be sent.
//! error.message contains the data to be sent.
//! @return SFS_STARTED Operation started result will be returned via callback.
//! o/w one of SFS_ERROR, SFS_REDIRECT, or SFS_STALL.
//-----------------------------------------------------------------------------
virtual int FAttr( XrdSfsFACtl *faReq,
XrdOucErrInfo &eInfo,
const XrdSecEntity *client = 0)
{(void)faReq; (void)client;