Browse Source
fix: avoid error file name too long when writing a file (#4876)
pull/4877/head
Konstantin Lebedev
1 year ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with
43 additions and
4 deletions
-
weed/command/filer_replication.go
-
weed/replication/sink/localsink/local_sink.go
-
weed/util/file_util.go
-
weed/util/file_util_test.go
|
|
@ -99,7 +99,7 @@ func runFilerReplicate(cmd *Command, args []string) bool { |
|
|
|
if m.OldEntry != nil && m.NewEntry == nil { |
|
|
|
glog.V(1).Infof("delete: %s", key) |
|
|
|
} else if m.OldEntry == nil && m.NewEntry != nil { |
|
|
|
glog.V(1).Infof(" add: %s", key) |
|
|
|
glog.V(1).Infof("add: %s", key) |
|
|
|
} else { |
|
|
|
glog.V(1).Infof("modify: %s", key) |
|
|
|
} |
|
|
|
|
|
@ -90,7 +90,7 @@ func (localsink *LocalSink) CreateEntry(key string, entry *filer_pb.Entry, signa |
|
|
|
return os.Mkdir(key, os.FileMode(entry.Attributes.FileMode)) |
|
|
|
} |
|
|
|
|
|
|
|
dstFile, err := os.OpenFile(key, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(entry.Attributes.FileMode)) |
|
|
|
dstFile, err := os.OpenFile(util.ToShortFileName(key), os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(entry.Attributes.FileMode)) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
@ -1,16 +1,20 @@ |
|
|
|
package util |
|
|
|
|
|
|
|
import ( |
|
|
|
"bytes" |
|
|
|
"crypto/sha256" |
|
|
|
"errors" |
|
|
|
"fmt" |
|
|
|
"github.com/seaweedfs/seaweedfs/weed/glog" |
|
|
|
"os" |
|
|
|
"os/user" |
|
|
|
"path/filepath" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/glog" |
|
|
|
) |
|
|
|
|
|
|
|
const maxFilenameLength = 255 |
|
|
|
|
|
|
|
func TestFolderWritable(folder string) (err error) { |
|
|
|
fileInfo, err := os.Stat(folder) |
|
|
|
if err != nil { |
|
|
@ -106,6 +110,19 @@ func FileNameBase(filename string) string { |
|
|
|
return filename[:lastDotIndex] |
|
|
|
} |
|
|
|
|
|
|
|
func ToShortFileName(path string) string { |
|
|
|
fileName := filepath.Base(path) |
|
|
|
if fileNameBytes := []byte(fileName); len(fileNameBytes) > maxFilenameLength { |
|
|
|
shaStr := fmt.Sprintf("%x", sha256.Sum256(fileNameBytes)) |
|
|
|
fileNameBase := FileNameBase(fileName) |
|
|
|
fileExt := fileName[len(fileNameBase):] |
|
|
|
fileNameBaseBates := bytes.ToValidUTF8([]byte(fileNameBase)[:maxFilenameLength-len([]byte(fileExt))-8], []byte{}) |
|
|
|
shortFileName := string(fileNameBaseBates) + shaStr[len(shaStr)-8:] |
|
|
|
return filepath.Join(filepath.Dir(path), shortFileName) + fileExt |
|
|
|
} |
|
|
|
return path |
|
|
|
} |
|
|
|
|
|
|
|
// Copied from os.WriteFile(), adding file sync.
|
|
|
|
// see https://github.com/golang/go/issues/20599
|
|
|
|
func WriteFile(name string, data []byte, perm os.FileMode) error { |
|
|
|
|
|
@ -0,0 +1,22 @@ |
|
|
|
package util |
|
|
|
|
|
|
|
import ( |
|
|
|
"testing" |
|
|
|
) |
|
|
|
|
|
|
|
func TestToShortFileName(t *testing.T) { |
|
|
|
tests := []struct { |
|
|
|
in string |
|
|
|
value string |
|
|
|
}{ |
|
|
|
{"/data/a/b/c/d.txt", "/data/a/b/c/d.txt"}, |
|
|
|
{"/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованных_форм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТА_ООО).txt", "/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованных_форм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТ354fcaf4.txt"}, |
|
|
|
{"/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованных_форм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТА_ООО)_without_extension", "/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованных_форм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТА_О21a6e47a"}, |
|
|
|
} |
|
|
|
for _, p := range tests { |
|
|
|
got := ToShortFileName(p.in) |
|
|
|
if got != p.value { |
|
|
|
t.Errorf("failed to test: got %v, want %v", got, p.value) |
|
|
|
} |
|
|
|
} |
|
|
|
} |