mirror of
https://github.com/rclone/rclone.git
synced 2024-12-22 23:22:08 +01:00
cmount, mount, mountlib: make --read-only reject modify operations
Normally mount/cmount use `-o ro` to get the kernel to mark the fs as read only. However this is ignored by WinFsp, so in addition if `--read-only` is in effect then return EROFS ("Read only File System") from all methods which attempt to modify something.
This commit is contained in:
parent
8be8a8e41b
commit
b259f8b752
@ -44,6 +44,9 @@ func NewFS(f fs.Fs) *FS {
|
||||
if noChecksum {
|
||||
fsys.FS.NoChecksum()
|
||||
}
|
||||
if readOnly {
|
||||
fsys.FS.ReadOnly()
|
||||
}
|
||||
return fsys
|
||||
}
|
||||
|
||||
@ -659,6 +662,8 @@ func translateError(err error) (errc int) {
|
||||
return -fuse.ESPIPE
|
||||
case mountlib.EBADF:
|
||||
return -fuse.EBADF
|
||||
case mountlib.EROFS:
|
||||
return -fuse.EROFS
|
||||
}
|
||||
}
|
||||
fs.Errorf(nil, "IO error: %v", err)
|
||||
|
@ -5,6 +5,8 @@
|
||||
package mount
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"bazil.org/fuse"
|
||||
fusefs "bazil.org/fuse/fs"
|
||||
"github.com/ncw/rclone/cmd/mountlib"
|
||||
@ -34,6 +36,9 @@ func NewFS(f fs.Fs) *FS {
|
||||
if noChecksum {
|
||||
fsys.FS.NoChecksum()
|
||||
}
|
||||
if readOnly {
|
||||
fsys.FS.ReadOnly()
|
||||
}
|
||||
return fsys
|
||||
}
|
||||
|
||||
@ -75,12 +80,20 @@ func translateError(err error) error {
|
||||
cause := errors.Cause(err)
|
||||
if mErr, ok := cause.(mountlib.Error); ok {
|
||||
switch mErr {
|
||||
case mountlib.OK:
|
||||
return nil
|
||||
case mountlib.ENOENT:
|
||||
return fuse.ENOENT
|
||||
case mountlib.ENOTEMPTY:
|
||||
return fuse.EEXIST // return fuse.ENOTEMPTY - doesn't exist though so use EEXIST
|
||||
return fuse.Errno(syscall.ENOTEMPTY)
|
||||
case mountlib.EEXIST:
|
||||
return fuse.EEXIST
|
||||
case mountlib.ESPIPE:
|
||||
return fuse.Errno(syscall.ESPIPE)
|
||||
case mountlib.EBADF:
|
||||
return fuse.Errno(syscall.EBADF)
|
||||
case mountlib.EROFS:
|
||||
return fuse.Errno(syscall.EROFS)
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
@ -242,6 +242,9 @@ func (d *Dir) ModTime() time.Time {
|
||||
|
||||
// SetModTime sets the modTime for this dir
|
||||
func (d *Dir) SetModTime(modTime time.Time) error {
|
||||
if d.fsys.readOnly {
|
||||
return EROFS
|
||||
}
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
d.modTime = modTime
|
||||
@ -312,6 +315,9 @@ func (d *Dir) ReadDirAll() (items []*DirEntry, err error) {
|
||||
|
||||
// Create makes a new file
|
||||
func (d *Dir) Create(name string) (*File, *WriteFileHandle, error) {
|
||||
if d.fsys.readOnly {
|
||||
return nil, nil, EROFS
|
||||
}
|
||||
path := path.Join(d.path, name)
|
||||
// fs.Debugf(path, "Dir.Create")
|
||||
src := newCreateInfo(d.f, path)
|
||||
@ -328,6 +334,9 @@ func (d *Dir) Create(name string) (*File, *WriteFileHandle, error) {
|
||||
|
||||
// Mkdir creates a new directory
|
||||
func (d *Dir) Mkdir(name string) (*Dir, error) {
|
||||
if d.fsys.readOnly {
|
||||
return nil, EROFS
|
||||
}
|
||||
path := path.Join(d.path, name)
|
||||
// fs.Debugf(path, "Dir.Mkdir")
|
||||
err := d.f.Mkdir(path)
|
||||
@ -349,6 +358,9 @@ func (d *Dir) Mkdir(name string) (*Dir, error) {
|
||||
// the receiver, which must be a directory. The entry to be removed
|
||||
// may correspond to a file (unlink) or to a directory (rmdir).
|
||||
func (d *Dir) Remove(name string) error {
|
||||
if d.fsys.readOnly {
|
||||
return EROFS
|
||||
}
|
||||
path := path.Join(d.path, name)
|
||||
// fs.Debugf(path, "Dir.Remove")
|
||||
item, err := d.lookupNode(name)
|
||||
@ -393,6 +405,9 @@ func (d *Dir) Remove(name string) error {
|
||||
|
||||
// Rename the file
|
||||
func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
|
||||
if d.fsys.readOnly {
|
||||
return EROFS
|
||||
}
|
||||
oldPath := path.Join(d.path, oldName)
|
||||
newPath := path.Join(destDir.path, newName)
|
||||
// fs.Debugf(oldPath, "Dir.Rename to %q", newPath)
|
||||
|
@ -7,6 +7,8 @@ import "fmt"
|
||||
// Error describes low level errors in a cross platform way
|
||||
type Error byte
|
||||
|
||||
// NB if changing errors translateError in cmd/mount/fs.go, cmd/cmount/fs.go
|
||||
|
||||
// Low level errors
|
||||
const (
|
||||
OK Error = iota
|
||||
@ -15,6 +17,7 @@ const (
|
||||
EEXIST
|
||||
ESPIPE
|
||||
EBADF
|
||||
EROFS
|
||||
)
|
||||
|
||||
var errorNames = []string{
|
||||
@ -24,6 +27,7 @@ var errorNames = []string{
|
||||
EEXIST: "File exists",
|
||||
ESPIPE: "Illegal seek",
|
||||
EBADF: "Bad file descriptor",
|
||||
EROFS: "Read only file system",
|
||||
}
|
||||
|
||||
// Error renders the error as a string
|
||||
|
@ -93,6 +93,9 @@ func (f *File) Attr(noModTime bool) (modTime time.Time, Size, Blocks uint64, err
|
||||
|
||||
// SetModTime sets the modtime for the file
|
||||
func (f *File) SetModTime(modTime time.Time) error {
|
||||
if f.d.fsys.readOnly {
|
||||
return EROFS
|
||||
}
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
@ -188,6 +191,9 @@ func (f *File) OpenRead() (fh *ReadFileHandle, err error) {
|
||||
|
||||
// OpenWrite open the file for write
|
||||
func (f *File) OpenWrite() (fh *WriteFileHandle, err error) {
|
||||
if f.d.fsys.readOnly {
|
||||
return nil, EROFS
|
||||
}
|
||||
// if o is nil it isn't valid yet
|
||||
o, err := f.waitForValidObject()
|
||||
if err != nil {
|
||||
|
@ -39,6 +39,7 @@ type FS struct {
|
||||
root *Dir
|
||||
noSeek bool // don't allow seeking if set
|
||||
noChecksum bool // don't check checksums if set
|
||||
readOnly bool // if set FS is read only
|
||||
}
|
||||
|
||||
// NewFS creates a new filing system and root directory
|
||||
@ -66,6 +67,13 @@ func (fsys *FS) NoChecksum() *FS {
|
||||
return fsys
|
||||
}
|
||||
|
||||
// ReadOnly sets the fs into read only mode, returning EROFS for any
|
||||
// write operations.
|
||||
func (fsys *FS) ReadOnly() *FS {
|
||||
fsys.readOnly = true
|
||||
return fsys
|
||||
}
|
||||
|
||||
// Root returns the root node
|
||||
func (fsys *FS) Root() (*Dir, error) {
|
||||
// fs.Debugf(fsys.f, "Root()")
|
||||
|
Loading…
Reference in New Issue
Block a user