Skip to content

Commit

Permalink
cmd/clone: check clone path (#3369)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhijian-pro authored Mar 26, 2023
1 parent 317e380 commit fb50c38
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 48 deletions.
36 changes: 32 additions & 4 deletions cmd/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ func clone(ctx *cli.Context) error {
if err != nil {
return fmt.Errorf("abs of %s: %s", srcPath, err)
}
srcParent := filepath.Dir(srcAbsPath)
srcIno, err := utils.GetFileInode(srcPath)
if err != nil {
return fmt.Errorf("lookup inode for %s: %s", srcPath, err)
Expand All @@ -84,6 +83,22 @@ func clone(ctx *cli.Context) error {
if err != nil {
return fmt.Errorf("abs of %s: %s", dst, err)
}

srcMp, err := findMountpoint(srcAbsPath)
if err != nil {
return err
}
dstMp, err := findMountpoint(filepath.Dir(dstAbsPath))
if err != nil {
return err
}
if srcMp != dstMp {
return fmt.Errorf("the clone DST path should be at the same mount point as the SRC path")
}
if strings.HasPrefix(dstAbsPath, srcAbsPath) {
return fmt.Errorf("the clone DST path should not be under the SRC path")
}

dstParent := filepath.Dir(dstAbsPath)
dstName := filepath.Base(dstAbsPath)
dstParentIno, err := utils.GetFileInode(dstParent)
Expand All @@ -107,9 +122,9 @@ func clone(ctx *cli.Context) error {
wb.Put([]byte(dstName))
wb.Put16(uint16(umask))
wb.Put8(cmode)
f := openController(srcParent)
if f == nil {
return fmt.Errorf("%s is not inside JuiceFS", srcPath)
f, err := openController(srcMp)
if err == nil {
return err
}
defer f.Close()
if _, err = f.Write(wb.Bytes()); err != nil {
Expand All @@ -127,3 +142,16 @@ func clone(ctx *cli.Context) error {
}
return nil
}

func findMountpoint(fpath string) (string, error) {
for p := fpath; p != "/"; p = filepath.Dir(p) {
inode, err := utils.GetFileInode(p)
if err != nil {
return "", fmt.Errorf("get inode of %s: %s", p, err)
}
if inode == uint64(meta.RootInode) {
return p, nil
}
}
return "", fmt.Errorf("%s is not inside JuiceFS", fpath)
}
18 changes: 8 additions & 10 deletions cmd/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ func info(ctx *cli.Context) error {
if inode < uint64(meta.RootInode) {
logger.Fatalf("inode number shouldn't be less than %d", meta.RootInode)
}
f := openController(d)
if f == nil {
logger.Errorf("%s is not inside JuiceFS", path)
f, err := openController(d)
if err != nil {
logger.Errorf("Open control file for %s: %s", d, err)
continue
}

Expand Down Expand Up @@ -244,21 +244,19 @@ func ltypeToString(t uint32) string {
}

func legacyInfo(d, path string, inode uint64, recursive, raw uint8) {
f := openController(d)
defer f.Close()
if f == nil {
logger.Errorf("%s is not inside JuiceFS", path)
// continue to next path
f, err := openController(d)
if err != nil {
logger.Errorf("Open control file for %s: %s", d, err)
return
}

defer f.Close()
wb := utils.NewBuffer(8 + 10)
wb.Put32(meta.LegacyInfo)
wb.Put32(10)
wb.Put64(inode)
wb.Put8(recursive)
wb.Put8(raw)
_, err := f.Write(wb.Bytes())
_, err = f.Write(wb.Bytes())
if err != nil {
logger.Fatalf("write message: %s", err)
}
Expand Down
27 changes: 7 additions & 20 deletions cmd/rmr.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,12 @@ $ juicefs rmr /mnt/jfs/foo`,
}
}

func openController(mp string) *os.File {
st, err := os.Stat(mp)
func openController(path string) (*os.File, error) {
mp, err := findMountpoint(path)
if err != nil {
logger.Fatal(err)
return nil, err
}
if !st.IsDir() {
mp = filepath.Dir(mp)
}
for ; mp != "/"; mp = filepath.Dir(mp) {
f, err := os.OpenFile(filepath.Join(mp, ".control"), os.O_RDWR, 0)
if err == nil {
return f
}
if !os.IsNotExist(err) {
logger.Fatal(err)
}
}
logger.Fatalf("Path %s is not inside JuiceFS", mp)
panic("unreachable")
return os.OpenFile(filepath.Join(mp, ".control"), os.O_RDWR, 0)
}

func rmr(ctx *cli.Context) error {
Expand All @@ -84,9 +71,9 @@ func rmr(ctx *cli.Context) error {
if err != nil {
return fmt.Errorf("lookup inode for %s: %s", d, err)
}
f := openController(d)
if f == nil {
logger.Errorf("%s is not inside JuiceFS", path)
f, err := openController(d)
if err != nil {
logger.Errorf("Open control file for %s: %s", d, err)
continue
}
wb := utils.NewBuffer(8 + 8 + 1 + uint32(len(name)))
Expand Down
21 changes: 7 additions & 14 deletions cmd/warmup.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,22 +178,15 @@ func warmup(ctx *cli.Context) error {

// find mount point
first := paths[0]
controller := openController(first)
if controller == nil {
logger.Fatalf("open control file for %s", first)
mp, err := findMountpoint(first)
if err != nil {
return err
}
defer controller.Close()

mp := first
for ; mp != "/"; mp = filepath.Dir(mp) {
inode, err := utils.GetFileInode(mp)
if err != nil {
logger.Fatalf("lookup inode for %s: %s", mp, err)
}
if inode == uint64(meta.RootInode) {
break
}
controller, err := openController(mp)
if err != nil {
return fmt.Errorf("open control file for %s: %s", first, err)
}
defer controller.Close()

threads := ctx.Uint("threads")
if threads == 0 {
Expand Down

0 comments on commit fb50c38

Please sign in to comment.