From f5f7475bb168b75c1b9c7d3bc5bc5127ce19a0f9 Mon Sep 17 00:00:00 2001 From: Tomas Mudrunka Date: Thu, 5 May 2016 03:47:17 +0200 Subject: [PATCH 1/2] Initial code for reporting fake fs size as suggested in #32 --- TODO | 4 ++++ src/bindfs.1 | 9 +++++++++ src/bindfs.c | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 257de9d..58def4b 100644 --- a/TODO +++ b/TODO @@ -20,3 +20,7 @@ Minor: - Look at capabilities instead of uid==0 when checking for special privileges. Do this in a portable way and fall back to uid==0 if not available. +- add real diskspace limiting (quota) besides of ability to report fake size. + Maybe there can be even different limit for different paths? dunno. + I think it's good idea to have sepparate code for faking reported size and + limiting size, so user can decide if he wants both or only one of them. diff --git a/src/bindfs.1 b/src/bindfs.1 index d98cb74..515e06f 100644 --- a/src/bindfs.1 +++ b/src/bindfs.1 @@ -277,6 +277,14 @@ only if deleting the target succeeded). The default is \fBsymlink-only\fP. Note that deleting files inside symlinked directories is always possible with all settings, including \fBdeny\fP, unless something else protects those files. +.SH SIZE LIMITS AND FAKE SIZE REPORTING + +.TP +.B \-\-size=\fI...\fPM, \-o size=\fI...\fPM +Report fake FS size of \fB...\fP Megabytes. Note this does not actually limit anything. +It's experimental feature and it may cause your \fBdf\fP go nuts. +Currently only \fBM\fP suffix is supported. +Actual limiting is planned in future. .SH MISCELLANEOUS OPTIONS @@ -477,6 +485,7 @@ for consistency. .SH AUTHOR Martin P\[:a]rtel +Contributors: Tomas 'Harvie' Mudrunka (2016 - concept of size limiting and initial code for reporting fake fs size) .SH SEE ALSO \fBchmod\fP(1), \fBfusermount\fP(1), \fBhttp://bindfs.org/\fP diff --git a/src/bindfs.c b/src/bindfs.c index d4a77ab..c6bd8fe 100644 --- a/src/bindfs.c +++ b/src/bindfs.c @@ -173,6 +173,8 @@ static struct Settings { uid_t uid_offset; gid_t gid_offset; + long bindfs_size; //Maybe it should be unsigned in future, however right now i use -1 to signal it's not used + } settings; @@ -1098,8 +1100,19 @@ static int bindfs_statfs(const char *path, struct statvfs *stbuf) real_path = process_path(path, true); if (real_path == NULL) return -errno; - res = statvfs(real_path, stbuf); + + if(settings.bindfs_size >= 0) { + //stbuf->f_frsize //block size + stbuf->f_blocks = settings.bindfs_size/stbuf->f_frsize; //total size in blocks + /* + stbuf->f_bfree = 0; //free blocks + stbuf->f_bavail = 0; //free blocks for unprivileged + stbuf->f_ffree = 0; //free inodes + stbuf->f_favail = 0; //free inodes for unprivileged + */ + } + free(real_path); if (res == -1) return -errno; @@ -1404,6 +1417,14 @@ static void print_usage(const char *progname) "Rate limits:\n" " --read-rate=... Limit to bytes/sec that can be read.\n" " --write-rate=... Limit to bytes/sec that can be written.\n" + "\n" + "Size limits:\n" + " --size=...M Report fake FS size of ... Megabytes\n" + " Note this does not actually limit anything\n" + " and it may cause your df go nuts.\n" +// " --size-limit=...M Limit usable FS size to ... Megabytes\n" +// " this defaults to --size, unless you want it to\n" +// " be different from value reported to df.\n" "\n" "Miscellaneous:\n" " -n --no-allow-other Do not add -o allow_other to fuse options.\n" @@ -1809,6 +1830,7 @@ int main(int argc, char *argv[]) int multithreaded; char *uid_offset; char *gid_offset; + char *bindfs_size; } od; #define OPT2(one, two, key) \ @@ -1874,6 +1896,8 @@ int main(int argc, char *argv[]) OPT_OFFSET2("--uid-offset=%s", "uid-offset=%s", uid_offset, 0), OPT_OFFSET2("--gid-offset=%s", "gid-offset=%s", gid_offset, 0), + + OPT_OFFSET2("--size=%s", "size=%s", bindfs_size, 0), FUSE_OPT_END }; @@ -1916,6 +1940,7 @@ int main(int argc, char *argv[]) settings.ctime_from_mtime = 0; settings.uid_offset = 0; settings.gid_offset = 0; + settings.bindfs_size = -1; atexit(&atexit_func); @@ -2101,6 +2126,13 @@ int main(int argc, char *argv[]) } } + /* parse size */ + if (od.bindfs_size) { + char* bindfs_size_ptr = od.bindfs_size; + settings.bindfs_size = strtoul(od.bindfs_size, &bindfs_size_ptr, 10); + //fprintf(stderr, "Activated experimental fake size: %ldM\n", settings.bindfs_size); //Debug + settings.bindfs_size *= (1024*1024); //Currently only Megabytes are supported + } /* Single-threaded mode by default */ if (!od.multithreaded) { From d1b47f9cc88deb4368fa7bcec59bcae35b7132a9 Mon Sep 17 00:00:00 2001 From: Tomas Mudrunka Date: Thu, 5 May 2016 04:08:13 +0200 Subject: [PATCH 2/2] fixed df output that was broken when using --size= #32 --- src/bindfs.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/bindfs.c b/src/bindfs.c index c6bd8fe..d12d58f 100644 --- a/src/bindfs.c +++ b/src/bindfs.c @@ -1100,14 +1100,21 @@ static int bindfs_statfs(const char *path, struct statvfs *stbuf) real_path = process_path(path, true); if (real_path == NULL) return -errno; + res = statvfs(real_path, stbuf); if(settings.bindfs_size >= 0) { - //stbuf->f_frsize //block size + //see: man 3 statvfs + //stbuf->f_frsize //block size (used for block to size conversion) + stbuf->f_blocks = settings.bindfs_size/stbuf->f_frsize; //total size in blocks + //We cannot have more free blocks than there are blocks in total: + stbuf->f_bfree = stbuf->f_bfree < stbuf->f_blocks ? stbuf->f_bfree : stbuf->f_blocks ; //free blocks + stbuf->f_bavail = stbuf->f_bavail < stbuf->f_blocks ? stbuf->f_bavail : stbuf->f_blocks ; //free blocks for unprivileged + /* - stbuf->f_bfree = 0; //free blocks - stbuf->f_bavail = 0; //free blocks for unprivileged + //TODO: same for inodes in future (when size limiting will be done) + stbuf->f_file = 0; //total size in inodes stbuf->f_ffree = 0; //free inodes stbuf->f_favail = 0; //free inodes for unprivileged */