diff --git a/weed/command/mount.go b/weed/command/mount.go index f5972fd30..bdc0638c9 100644 --- a/weed/command/mount.go +++ b/weed/command/mount.go @@ -33,6 +33,7 @@ type MountOptions struct { localSocket *string disableXAttr *bool extraOptions []string + writeOnceReadMany *bool } var ( @@ -70,6 +71,7 @@ func init() { mountOptions.debugPort = cmdMount.Flag.Int("debug.port", 6061, "http port for debugging") mountOptions.localSocket = cmdMount.Flag.String("localSocket", "", "default to /tmp/seaweedfs-mount-.sock") mountOptions.disableXAttr = cmdMount.Flag.Bool("disableXAttr", false, "disable xattr") + mountOptions.writeOnceReadMany = cmdMount.Flag.Bool("writeOnceReadMany", false, "write once, read many times") mountCpuProfile = cmdMount.Flag.String("cpuprofile", "", "cpu profile output file") mountMemProfile = cmdMount.Flag.String("memprofile", "", "memory profile output file") diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go index f85e7386d..53357eba6 100644 --- a/weed/command/mount_std.go +++ b/weed/command/mount_std.go @@ -247,6 +247,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool { Cipher: cipher, UidGidMapper: uidGidMapper, DisableXAttr: *option.disableXAttr, + WriteOnceReadMany: *option.writeOnceReadMany, }) // create mount root diff --git a/weed/mount/weedfs.go b/weed/mount/weedfs.go index a9fbd9380..3ad938699 100644 --- a/weed/mount/weedfs.go +++ b/weed/mount/weedfs.go @@ -46,6 +46,8 @@ type Option struct { Quota int64 DisableXAttr bool + WriteOnceReadMany bool + MountUid uint32 MountGid uint32 MountMode os.FileMode diff --git a/weed/mount/weedfs_file_io.go b/weed/mount/weedfs_file_io.go index 7039b14ec..c6fcb8a14 100644 --- a/weed/mount/weedfs_file_io.go +++ b/weed/mount/weedfs_file_io.go @@ -62,7 +62,7 @@ import ( */ func (wfs *WFS) Open(cancel <-chan struct{}, in *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) { var fileHandle *FileHandle - fileHandle, status = wfs.AcquireHandle(in.NodeId, in.Uid, in.Gid) + fileHandle, status = wfs.AcquireHandle(in.NodeId, in.Flags, in.Uid, in.Gid) if status == fuse.OK { out.Fh = uint64(fileHandle.fh) // TODO https://github.com/libfuse/libfuse/blob/master/include/fuse_common.h#L64 diff --git a/weed/mount/weedfs_filehandle.go b/weed/mount/weedfs_filehandle.go index 4845654ed..99b54850a 100644 --- a/weed/mount/weedfs_filehandle.go +++ b/weed/mount/weedfs_filehandle.go @@ -3,12 +3,20 @@ package mount import ( "github.com/hanwen/go-fuse/v2/fuse" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" + "time" ) -func (wfs *WFS) AcquireHandle(inode uint64, uid, gid uint32) (fileHandle *FileHandle, status fuse.Status) { +func (wfs *WFS) AcquireHandle(inode uint64, flags, uid, gid uint32) (fileHandle *FileHandle, status fuse.Status) { var entry *filer_pb.Entry _, _, entry, status = wfs.maybeReadEntry(inode) if status == fuse.OK { + if entry != nil && wfs.option.WriteOnceReadMany { + if entry.Attributes.Mtime+10 < time.Now().Unix() { + if flags&fuse.O_ANYWRITE != 0 { + return nil, fuse.EPERM + } + } + } // need to AcquireFileHandle again to ensure correct handle counter fileHandle = wfs.fhmap.AcquireFileHandle(wfs, inode, entry) }