Add quota support
Hello, i'd like to use bindfs to mount one directory to another, while i'd like the second one to have some disk space limit.
Eg.: I'll have 1GB disk mounted in /mnt/storage and i'll have this directory /mnt/storage/unlimited that will have 1GB of free space in it. I want to mount /mnt/storage/unlimited using bindfs to /mnt/limited while specifiing that i want it to have eg. 10MB of space. eg.:
mount -t bindfs /mnt/storage/unlimited /mnt/limited -o quota=10M
So i will see the same directory in /mnt/limited and work with it as one would suppose, but when diskspace occupied by /mnt/storage/unlimited will reach 10MB i will not be able to write more data into /mnt/limited (only replace/delete).
There are several ways to implement this. Cheap way is to call "df" at every write, which is probably not good idea. So there probably should be some index/cache that will account the data as they are written in. eg. in /var/cache/bindfs/ when mounted by root (or from fstab) or in ~/.cache/bindfs when mounted manually by user. For me it's not important to account the data written directy to /mnt/storage/unlimited as i will simply not be doing this. But the index should be initialized during mount and check if there were any changes in original directory since the index was created. Also there can be option to override quota index location and/or completely disabling it (which would force bindfs to rebuild it at every mount).
Also would be super usefull if the quota could be changed without unmounting. Eg.:
fusermount -o remount,quota=23M /mnt/limited
A good idea. Feel free to send a PR :)
I agree, the implementation should keep track of the total number of bytes (and probably the number of files - it often makes sense to limit the number of inodes used). Always scanning at startup and keeping it in memory is probably good enough for most use cases, so that should probably be the default behavior. Storing the cache in a file only makes sense if the user promises to not change the source directory between mounts. Otherwise we need to stat every file anyway and the cache file is of no benefit that I can see.
Bindfs already accepts SIGUSR1 to clear its cache of user-group mappings, so it may make sense to accept SIGUSR2 for this. I'm not sure if fuse supports -o remount.
One small difficulty in the implementation would be rounding up to the block size of the underlying FS (think ls -lh vs du -h). This can probably be done by fstat'ing the file as we write it and checking st_blocks, even though we might overrun the quota a bit that way. I'm not sure if all filesystems are guaranteed to have a constant block size that can be queried somehow. That would be useful, even if a bit of a lie because I think some filesystems store very small files inline with metadata.
Another place to be careful is in write() where it's necessary to differentiate between (partially) overwriting and appending.
Any update on this ? Is there any chance to get quota support with bindfs ?
Or maybe to get bindfs to respect the underlying file-system's quotas ?
To be honest i've ended up using ZFS, which supports quotas without need for bindfs wrapper. But it comes with whole another can of worms...
Thanks for your quick response.
I'm using bindfs to limit individual file size on a samba share. E.g., to prevent users to store files overs 100MB, I put in a startup script :
ulimit -S -f 102400; ulimit -H -f 102400; trap '' XFSZ; bindfs /srv/ /srv.bindfs/
And then I share some folder in /srv.bindfs, instead of sharing it in /srv
It works perfectly. Only problem : the underlying file-system's quotas are not enforced through bindfs.
So, basically, I can have either a samba share with quotas, or a samba share with individual file size limit, but I cannot have both...
Do you think it's achievable with ZFS ? (I have no experience with ZFS, but it's on my to-do list). Any other ideas ?
Unfortunately I don't have the time to add any major features to bindfs in the foreseeable future, but PRs are welcome.
I'm not entirely familiar with how Linux quotas work, but maybe you can run bindfs as the user that has a quota limit and bindfs gets limited that way?
Yep, that was it ! THANKS, you made my day !