2 Commits

Author SHA1 Message Date
62ca9f2378 Update README.md 2025-01-04 02:31:44 +03:00
f73d612666 Restore COW on copy for linux 2025-01-04 02:28:26 +03:00
4 changed files with 34 additions and 12 deletions

View File

@@ -19,7 +19,7 @@ structure for that files.
## Installing
```bash
go install github.com/derfenix/photocatalog@latest
go install github.com/derfenix/photocatalog/v2@latest
```
Optionally you could copy created binary from the GO's bin path to
system or user $PATH, e.g. /usr/local/bin/.
@@ -27,6 +27,10 @@ system or user $PATH, e.g. /usr/local/bin/.
sudo cp ${GOPATH}/bin/photocatalog /usr/local/bin/photocatalog
```
## Migrating from v0.*
TODO
## Supported formats
At this moment supported jpeg files with filled exif data or any other
files but with names matching pattern `yyymmdd_HHMMSS.ext`. Such
@@ -40,31 +44,31 @@ at this time.
### One-shot
#### Copy files (make a COW if fs supports it)
```bash
photocalog -mode copy -target ./photos/ ./sync/photos/*
photocalog -mode copy -target ./photos/ -source ./sync/photos/
```
#### Create hardlinks (only withing one disk partition)
```bash
photocalog -mode hardlink -target ./photos/ ./sync/photos/*
photocalog -mode hardlink -target ./photos/ -source ./sync/photos/
```
or
```bash
photocalog -target ./photos/ ./sync/photos/*
photocalog -target ./photos/ -source ./sync/photos/*
```
### Monitor
### Watch mode
#### Copy files (make a COW if fs supports it)
```bash
photocalog -mode copy -target ./photos -monitor ./sync/photos/*
photocalog -mode copy -target ./photos -watch -source ./sync/photos/
```
#### Create hardlinks (only withing one disk partition)
```bash
photocalog -mode hardlink -target ./photos/ -monitor ./sync/photos/
photocalog -mode hardlink -target ./photos/ -watch -source ./sync/photos/
```
or
```bash
photocalog -target ./photos/ -monitor ./sync/photos/
photocalog -target ./photos/ -watch -source ./sync/photos/
```
## Install and run monitor service
@@ -89,6 +93,6 @@ under corresponding sub-dir.
### Why this tool was created if there is awesome XXX tool?
I had two good reasons:
1. I wanted
1. I wish
2. I can

View File

@@ -33,7 +33,7 @@ func (c *Config) Validate() error {
return fmt.Errorf("target dir is required")
}
if !slices.Contains([]Mode{ModeHardlink, ModeSymlink, ModeMove, ModeSymlink}, c.Mode) {
if !slices.Contains([]Mode{ModeHardlink, ModeSymlink, ModeMove, ModeCopy}, c.Mode) {
return fmt.Errorf("invalid mode %s", c.Mode)
}

View File

@@ -5,12 +5,18 @@ import (
"io"
"log"
"os"
"runtime"
"sync/atomic"
"golang.org/x/sys/unix"
)
var cowDisabled = atomic.Bool{}
type Copy struct{}
func (c Copy) PlaceIt(sourcePath, targetPath string, mode os.FileMode) error {
targetFile, err := os.OpenFile(targetPath, os.O_TRUNC|os.O_RDWR|os.O_CREATE, mode)
targetFile, err := os.OpenFile(targetPath, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, mode)
if err != nil {
return fmt.Errorf("open target file: %w", err)
}
@@ -28,6 +34,17 @@ func (c Copy) PlaceIt(sourcePath, targetPath string, mode os.FileMode) error {
_ = sourceFile.Close()
}()
// Try to do a COW.
if runtime.GOOS == "linux" && !cowDisabled.Load() {
if err := unix.IoctlFileClone(int(targetFile.Fd()+1), int(sourceFile.Fd())); err == nil {
return nil
} else {
log.Println(fmt.Errorf("COW attempt for %s failed: %w", targetPath, err))
log.Println("Disabling COW until restart")
cowDisabled.Store(true)
}
}
copySize, err := io.Copy(targetFile, sourceFile)
if err != nil {
return fmt.Errorf("copy source file: %w", err)

View File

@@ -268,6 +268,7 @@ func (o *Organizer) BuildTargetPath(sourcePath string, meta metadata.Metadata) (
o.targetDir,
strconv.Itoa(meta.Created.Year()),
strconv.Itoa(int(meta.Created.Month())),
strconv.Itoa(meta.Created.Day()),
sourcePath,
)