Skip to content

Commit 34ce800

Browse files
committed
兼容软链接是相对路径的情况
1 parent 9cf08c3 commit 34ce800

2 files changed

Lines changed: 91 additions & 43 deletions

File tree

backend/db/db.go

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"gorm.io/gorm/logger"
1818
"io"
1919
"path"
20+
"path/filepath"
2021
"regexp"
2122
"strconv"
2223
"strings"
@@ -304,7 +305,7 @@ func (f *Fs) FindLeaf(ctx context.Context, pathID, leaf string) (pathIDOut strin
304305
}
305306
//如果打开的软链接文件,需要特殊处理
306307
if !f.opt.IsLinkFileMode && pathIDFile.IsLink {
307-
linkToFileInfo, err := f.findRealLinkedToFileInfo(ctx, pathIDFile.LinkToPath, true)
308+
linkToFileInfo, err := f.findRealLinkedToFileInfo(ctx, pathIDFile, true)
308309
if err != nil {
309310
return "", false, err
310311
}
@@ -402,20 +403,55 @@ func (f *Fs) findRootRelativePathFile(path string) (*FileInfo, error) {
402403
}
403404
return &retrievedFile, nil
404405
}
405-
406-
func (f *Fs) findRealLinkedToFileInfo(ctx context.Context, linkToPath string, findDir bool) (linkToFileInfo *FileInfo, err error) {
407-
for linkToFileInfo == nil || linkToFileInfo.IsLink {
408-
linkToFileInfo, err = f.readAbsoluteFileInfo(ctx, linkToPath)
406+
func (f *Fs) findAbsolutePathFromFileInfo(fileInfo FileInfo) (absolutePath string, err error) {
407+
for fileInfo.Id != rootDir.Id {
408+
if absolutePath == "" {
409+
absolutePath = fileInfo.Name
410+
} else {
411+
absolutePath = fileInfo.Name + "/" + absolutePath
412+
}
413+
var foundFile []FileInfo
414+
tx := f.db.Find(&foundFile, &FileInfo{Id: fileInfo.ParentId})
415+
if tx.Error != nil {
416+
return "", errors.Wrapf(tx.Error, "db find error")
417+
}
418+
if len(foundFile) == 0 {
419+
return "", errors.Errorf("can not found parent fileinfo in db. id (%s)", fileInfo.Id)
420+
}
421+
if len(foundFile) > 1 {
422+
return "", errors.Errorf("found %d parent fileinfo in db. id (%s)", len(foundFile), fileInfo.Id)
423+
}
424+
fileInfo = foundFile[0]
425+
}
426+
absolutePath = "/" + absolutePath
427+
return absolutePath, nil
428+
}
429+
func (f *Fs) findRealLinkedToFileInfo(ctx context.Context, fileInfo FileInfo, findDir bool) (*FileInfo, error) {
430+
for fileInfo.IsLink {
431+
var linkToPath = fileInfo.LinkToPath
432+
if fileInfo.LinkToPath == "" {
433+
absolutePath, err := f.findAbsolutePathFromFileInfo(fileInfo)
434+
if err != nil {
435+
return nil, err
436+
}
437+
if fileInfo.IsDir {
438+
linkToPath = path.Join(absolutePath, filepath.ToSlash(fileInfo.LinkToLocalPath))
439+
} else {
440+
linkToPath = path.Join(path.Dir(absolutePath), filepath.ToSlash(fileInfo.LinkToLocalPath))
441+
}
442+
}
443+
fileInfoTemp, err := f.readAbsoluteFileInfo(ctx, linkToPath)
409444
if err != nil {
410445
return nil, err
411446
}
412-
if findDir && !linkToFileInfo.IsDir {
447+
if findDir && !fileInfoTemp.IsDir {
413448
return nil, fs.ErrorIsFile
414-
} else if !findDir && linkToFileInfo.IsDir {
449+
} else if !findDir && fileInfoTemp.IsDir {
415450
return nil, fs.ErrorIsDir
416451
}
452+
fileInfo = *fileInfoTemp
417453
}
418-
return linkToFileInfo, nil
454+
return &fileInfo, nil
419455
}
420456

421457
// List entries normal need to implement fs.Directory or fs.Object ,dir is relative path,f.root is base path
@@ -434,7 +470,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e
434470
return nil, errors.Wrapf(db.Error, "List: dir find error")
435471
}
436472
if dirFileInfo.IsLink {
437-
realFileInfo, err := f.findRealLinkedToFileInfo(ctx, dirFileInfo.LinkToPath, true)
473+
realFileInfo, err := f.findRealLinkedToFileInfo(ctx, dirFileInfo, true)
438474
if err != nil {
439475
return nil, err
440476
}

backend/db/db_object.go

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ import (
2020
//
2121
// Will definitely have info but maybe not meta
2222
type Object struct {
23-
fs *Fs // what this object is part of
24-
remote string // The remote path base root relativePath path,have file name
25-
size int64 // size of the object
26-
modTime time.Time // modification time of the object
27-
id string // ID of the object
28-
parentId string
29-
fileName string
30-
isLink bool
31-
linkToPath string
23+
fs *Fs // what this object is part of
24+
remote string // The remote path base root relativePath path,have file name
25+
size int64 // size of the object
26+
modTime time.Time // modification time of the object
27+
id string // ID of the object
28+
parentId string
29+
fileName string
30+
isLink bool
31+
linkToPath string // 如果linkToPath为""则软链接为相对路径,使用LinkToLocalPath
32+
LinkToLocalPath string
3233
}
3334

3435
// ------------------------------------------------------------
@@ -45,15 +46,16 @@ func NewObjectFromFileInfo(file *FileInfo, absolutePath string, f *Fs) *Object {
4546
}
4647
} else {
4748
return &Object{
48-
id: file.Id,
49-
parentId: file.ParentId,
50-
remote: absolutePath,
51-
modTime: file.ModTime,
52-
size: file.FileSize,
53-
fs: f,
54-
fileName: file.Name,
55-
isLink: file.IsLink,
56-
linkToPath: file.LinkToPath,
49+
id: file.Id,
50+
parentId: file.ParentId,
51+
remote: absolutePath,
52+
modTime: file.ModTime,
53+
size: file.FileSize,
54+
fs: f,
55+
fileName: file.Name,
56+
isLink: file.IsLink,
57+
linkToPath: file.LinkToPath,
58+
LinkToLocalPath: file.LinkToLocalPath,
5759
}
5860
}
5961
}
@@ -97,6 +99,10 @@ func (o *Object) ModTime(ctx context.Context) time.Time {
9799
// SetModTime sets the modification time of the local fs object
98100
func (o *Object) SetModTime(ctx context.Context, modTime time.Time) error {
99101
o.modTime = modTime
102+
result := o.fs.db.Where("id = ?", o.id).Updates(FileInfo{ModTime: modTime})
103+
if result.Error != nil {
104+
return errors.Wrap(result.Error, "SetModTime error")
105+
}
100106
return nil
101107
}
102108

@@ -110,7 +116,7 @@ func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.Read
110116

111117
//如果打开的软链接文件,需要特殊处理
112118
if !o.fs.opt.IsLinkFileMode && o.isLink {
113-
linkToFileInfo, err := o.fs.findRealLinkedToFileInfo(ctx, o.linkToPath, false)
119+
linkToFileInfo, err := o.fs.findRealLinkedToFileInfo(ctx, FileInfo{IsDir: false, LinkToLocalPath: o.LinkToLocalPath, LinkToPath: o.linkToPath, IsLink: o.isLink}, false)
114120
if err != nil {
115121
return nil, err
116122
}
@@ -226,22 +232,28 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
226232
//}
227233

228234
linkToPath := string(allByte)
229-
linkToFileInfo, err := os.Stat(linkToPath)
230-
if err != nil {
231-
return err
232-
}
233-
fileInfo.LinkToLocalPath = linkToPath
234-
srcLinkPath := strings.TrimSuffix(path.Join(src.Fs().Root(), src.Remote()), linkSuffix)
235-
dstLinkPath := strings.TrimSuffix(path.Join(o.fs.root, o.remote), linkSuffix)
235+
if paths.IsAbs(linkToPath) {
236+
linkToFileInfo, err := os.Stat(linkToPath)
237+
if err != nil {
238+
return err
239+
}
240+
fileInfo.LinkToLocalPath = linkToPath
241+
srcLinkPath := strings.TrimSuffix(path.Join(src.Fs().Root(), src.Remote()), linkSuffix)
242+
dstLinkPath := strings.TrimSuffix(path.Join(o.fs.root, o.remote), linkSuffix)
236243

237-
fileInfo.IsDir = linkToFileInfo.IsDir()
238-
derivedPathFromRelative, err := ResolveDerivedPathFromRelative(srcLinkPath, linkToPath, dstLinkPath, fileInfo.IsDir)
239-
if err != nil {
240-
//如果转化的路径超过了绝对路径的根路径就会报错
241-
return err
244+
fileInfo.IsDir = linkToFileInfo.IsDir()
245+
derivedPathFromRelative, err := ResolveDerivedPathFromRelative(srcLinkPath, linkToPath, dstLinkPath, fileInfo.IsDir)
246+
if err != nil {
247+
//如果转化的路径超过了绝对路径的根路径就会报错
248+
return err
249+
} else {
250+
fileInfo.LinkToPath = derivedPathFromRelative
251+
}
242252
} else {
243-
fileInfo.LinkToPath = derivedPathFromRelative
253+
fileInfo.LinkToLocalPath = ""
254+
fileInfo.LinkToPath = linkToPath
244255
}
256+
245257
//// 文件夹链接大小定为-1,文件链接大小定为0
246258
//if linkToFileInfo.IsDir() {
247259
// fileInfo.FileSize = -1
@@ -251,7 +263,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
251263
}
252264
tx := o.fs.db
253265
var oldFileInfos []FileInfo
254-
db := tx.Find(&oldFileInfos, &FileInfo{ParentId: o.parentId, Name: o.fileName})
266+
db := tx.Find(&oldFileInfos, &FileInfo{ParentId: o.parentId, Name: fileInfo.Name})
255267
if db.Error != nil {
256268
//tx.Rollback()
257269
return errors.Wrapf(db.Error, "Error update object %s", o)
@@ -274,7 +286,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
274286
//只有原本文件存在时,才会进行更新,如果文件不存在,则应该是走创建链接文件的逻辑,而不是这里
275287
//如果打开的软链接文件,需要特殊处理
276288
if !o.fs.opt.IsLinkFileMode && oldFileInfo.IsLink {
277-
linkToFileInfo, err := o.fs.findRealLinkedToFileInfo(ctx, oldFileInfo.LinkToPath, false)
289+
linkToFileInfo, err := o.fs.findRealLinkedToFileInfo(ctx, oldFileInfo, false)
278290
if err != nil {
279291
return err
280292
}

0 commit comments

Comments
 (0)