@@ -40,11 +40,12 @@ import (
40
40
)
41
41
42
42
type ScoutfsOpts struct {
43
- ChownUID bool
44
- ChownGID bool
45
- GlacierMode bool
46
- BucketLinks bool
47
- NewDirPerm fs.FileMode
43
+ ChownUID bool
44
+ ChownGID bool
45
+ GlacierMode bool
46
+ BucketLinks bool
47
+ NewDirPerm fs.FileMode
48
+ DisableNoArchive bool
48
49
}
49
50
50
51
type ScoutFS struct {
@@ -78,6 +79,11 @@ type ScoutFS struct {
78
79
79
80
// newDirPerm is the permissions to use when creating new directories
80
81
newDirPerm fs.FileMode
82
+
83
+ // disableNoArchive is used to disable setting scoutam noarchive flag
84
+ // on mutlipart parts. This is enabled by default to prevent archive
85
+ // copies of temporary multipart parts.
86
+ disableNoArchive bool
81
87
}
82
88
83
89
var _ backend.Backend = & ScoutFS {}
@@ -156,6 +162,31 @@ func (s *ScoutFS) getChownIDs(acct auth.Account) (int, int, bool) {
156
162
return uid , gid , needsChown
157
163
}
158
164
165
+ func (s * ScoutFS ) UploadPart (ctx context.Context , input * s3.UploadPartInput ) (* s3.UploadPartOutput , error ) {
166
+ out , err := s .Posix .UploadPart (ctx , input )
167
+ if err != nil {
168
+ return nil , err
169
+ }
170
+
171
+ if ! s .disableNoArchive {
172
+ sum := sha256 .Sum256 ([]byte (* input .Key ))
173
+ partPath := filepath .Join (
174
+ * input .Bucket , // bucket
175
+ metaTmpMultipartDir , // temp multipart dir
176
+ fmt .Sprintf ("%x" , sum ), // hashed objname
177
+ * input .UploadId , // upload id
178
+ fmt .Sprintf ("%v" , * input .PartNumber ), // part number
179
+ )
180
+
181
+ err = setNoArchive (partPath )
182
+ if err != nil {
183
+ return nil , fmt .Errorf ("set noarchive: %w" , err )
184
+ }
185
+ }
186
+
187
+ return out , err
188
+ }
189
+
159
190
// CompleteMultipartUpload scoutfs complete upload uses scoutfs move blocks
160
191
// ioctl to not have to read and copy the part data to the final object. This
161
192
// saves a read and write cycle for all mutlipart uploads.
@@ -932,56 +963,60 @@ func (s *ScoutFS) RestoreObject(_ context.Context, input *s3.RestoreObjectInput)
932
963
return nil
933
964
}
934
965
935
- func setStaging (objname string ) error {
966
+ func isStaging (objname string ) ( bool , error ) {
936
967
b , err := xattr .Get (objname , flagskey )
937
968
if err != nil && ! isNoAttr (err ) {
938
- return err
969
+ return false , err
939
970
}
940
971
941
- var oldflags uint64
972
+ var flags uint64
942
973
if ! isNoAttr (err ) {
943
- err = json .Unmarshal (b , & oldflags )
974
+ err = json .Unmarshal (b , & flags )
944
975
if err != nil {
945
- return err
976
+ return false , err
946
977
}
947
978
}
948
979
949
- newflags := oldflags | Staging
950
-
951
- if newflags == oldflags {
952
- // no flags change, just return
953
- return nil
954
- }
955
-
956
- return fSetNewGlobalFlags (objname , newflags )
980
+ return flags & Staging == Staging , nil
957
981
}
958
982
959
- func isStaging (objname string ) ( bool , error ) {
983
+ func setFlag (objname string , flag uint64 ) error {
960
984
b , err := xattr .Get (objname , flagskey )
961
985
if err != nil && ! isNoAttr (err ) {
962
- return false , err
986
+ return err
963
987
}
964
988
965
- var flags uint64
989
+ var oldflags uint64
966
990
if ! isNoAttr (err ) {
967
- err = json .Unmarshal (b , & flags )
991
+ err = json .Unmarshal (b , & oldflags )
968
992
if err != nil {
969
- return false , err
993
+ return err
970
994
}
971
995
}
972
996
973
- return flags & Staging == Staging , nil
974
- }
997
+ newflags := oldflags | flag
998
+
999
+ if newflags == oldflags {
1000
+ // no flags change, just return
1001
+ return nil
1002
+ }
975
1003
976
- func fSetNewGlobalFlags (objname string , flags uint64 ) error {
977
- b , err := json .Marshal (& flags )
1004
+ b , err = json .Marshal (& newflags )
978
1005
if err != nil {
979
1006
return err
980
1007
}
981
1008
982
1009
return xattr .Set (objname , flagskey , b )
983
1010
}
984
1011
1012
+ func setStaging (objname string ) error {
1013
+ return setFlag (objname , Staging )
1014
+ }
1015
+
1016
+ func setNoArchive (objname string ) error {
1017
+ return setFlag (objname , NoArchive )
1018
+ }
1019
+
985
1020
func isNoAttr (err error ) bool {
986
1021
xerr , ok := err .(* xattr.Error )
987
1022
if ok && xerr .Err == xattr .ENOATTR {
0 commit comments