aboutsummaryrefslogtreecommitdiffstats
path: root/lib/fuse.c
diff options
context:
space:
mode:
authorgandalfs_cat <meow@kittcat.dev>2024-06-23 04:28:30 -0700
committerBernd Schubert <bernd.schubert@fastmail.fm>2024-07-03 12:50:06 +0200
commit54b8cd6757ed383c0da10a5ba6a778dd45f28ad6 (patch)
tree04a238edd22081fc047baf83022a51de01d1a5aa /lib/fuse.c
parentf88e08f34d2d4f398f23797707e1c50cd306e405 (diff)
downloadlibfuse-54b8cd6757ed383c0da10a5ba6a778dd45f28ad6.tar.gz
high-level: add fmask and dmask options
dmask: umask applied to directories fmask: umask applied to non-directories to get "typical" permission bits for regular files (0644) and directories (0755), a single umask option is not sufficient (or well, it isn't the way fuse implements it) there is precident for separate umask and dmask options in other filesystems (see for example fat: https://github.com/torvalds/linux/tree/master/fs/fat) this addition should not affect backward-compatibility; the original umask option retains the same meaning, but non-zero fmask or dmask will override it.
Diffstat (limited to 'lib/fuse.c')
-rw-r--r--lib/fuse.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/fuse.c b/lib/fuse.c
index 35a807b..24b843f 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1487,9 +1487,17 @@ static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf)
{
if (!f->conf.use_ino)
stbuf->st_ino = nodeid;
- if (f->conf.set_mode)
- stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
- (0777 & ~f->conf.umask);
+ if (f->conf.set_mode) {
+ if (f->conf.dmask && S_ISDIR(stbuf->st_mode))
+ stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
+ (0777 & ~f->conf.dmask);
+ else if (f->conf.fmask)
+ stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
+ (0777 & ~f->conf.fmask);
+ else
+ stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
+ (0777 & ~f->conf.umask);
+ }
if (f->conf.set_uid)
stbuf->st_uid = f->conf.uid;
if (f->conf.set_gid)
@@ -4681,6 +4689,10 @@ static const struct fuse_opt fuse_lib_opts[] = {
FUSE_LIB_OPT("no_rofd_flush", no_rofd_flush, 1),
FUSE_LIB_OPT("umask=", set_mode, 1),
FUSE_LIB_OPT("umask=%o", umask, 0),
+ FUSE_LIB_OPT("fmask=", set_mode, 1),
+ FUSE_LIB_OPT("fmask=%o", fmask, 0),
+ FUSE_LIB_OPT("dmask=", set_mode, 1),
+ FUSE_LIB_OPT("dmask=%o", dmask, 0),
FUSE_LIB_OPT("uid=", set_uid, 1),
FUSE_LIB_OPT("uid=%d", uid, 0),
FUSE_LIB_OPT("gid=", set_gid, 1),
@@ -4734,6 +4746,8 @@ void fuse_lib_help(struct fuse_args *args)
" -o [no]auto_cache enable caching based on modification times (off)\n"
" -o no_rofd_flush disable flushing of read-only fd on close (off)\n"
" -o umask=M set file permissions (octal)\n"
+" -o fmask=M set file permissions (octal)\n"
+" -o dmask=M set dir permissions (octal)\n"
" -o uid=N set file owner\n"
" -o gid=N set file group\n"
" -o entry_timeout=T cache timeout for names (1.0s)\n"