Skip to content

Commit 9dfa23c

Browse files
saschahauerjankara
authored andcommitted
quota: Add mountpath based quota support
Add syscall quotactl_path, a variant of quotactl which allows to specify the mountpath instead of a path of to a block device. The quotactl syscall expects a path to the mounted block device to specify the filesystem to work on. This limits usage to filesystems which actually have a block device. quotactl_path replaces the path to the block device with a path where the filesystem is mounted at. The global Q_SYNC command to sync all filesystems is not supported for this new syscall, otherwise quotactl_path behaves like quotactl. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sascha Hauer <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 1e28eed commit 9dfa23c

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

fs/quota/quota.c

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/capability.h>
1818
#include <linux/quotaops.h>
1919
#include <linux/types.h>
20+
#include <linux/mount.h>
2021
#include <linux/writeback.h>
2122
#include <linux/nospec.h>
2223
#include "compat.h"
@@ -827,8 +828,6 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
827828
}
828829
}
829830

830-
#ifdef CONFIG_BLOCK
831-
832831
/* Return 1 if 'cmd' will block on frozen filesystem */
833832
static int quotactl_cmd_write(int cmd)
834833
{
@@ -850,7 +849,6 @@ static int quotactl_cmd_write(int cmd)
850849
}
851850
return 1;
852851
}
853-
#endif /* CONFIG_BLOCK */
854852

855853
/* Return true if quotactl command is manipulating quota on/off state */
856854
static bool quotactl_cmd_onoff(int cmd)
@@ -968,3 +966,48 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
968966
path_put(pathp);
969967
return ret;
970968
}
969+
970+
SYSCALL_DEFINE4(quotactl_path, unsigned int, cmd, const char __user *,
971+
mountpoint, qid_t, id, void __user *, addr)
972+
{
973+
struct super_block *sb;
974+
struct path mountpath;
975+
unsigned int cmds = cmd >> SUBCMDSHIFT;
976+
unsigned int type = cmd & SUBCMDMASK;
977+
int ret;
978+
979+
if (type >= MAXQUOTAS)
980+
return -EINVAL;
981+
982+
ret = user_path_at(AT_FDCWD, mountpoint,
983+
LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT, &mountpath);
984+
if (ret)
985+
return ret;
986+
987+
sb = mountpath.mnt->mnt_sb;
988+
989+
if (quotactl_cmd_write(cmds)) {
990+
ret = mnt_want_write(mountpath.mnt);
991+
if (ret)
992+
goto out;
993+
}
994+
995+
if (quotactl_cmd_onoff(cmds))
996+
down_write(&sb->s_umount);
997+
else
998+
down_read(&sb->s_umount);
999+
1000+
ret = do_quotactl(sb, type, cmds, id, addr, ERR_PTR(-EINVAL));
1001+
1002+
if (quotactl_cmd_onoff(cmds))
1003+
up_write(&sb->s_umount);
1004+
else
1005+
up_read(&sb->s_umount);
1006+
1007+
if (quotactl_cmd_write(cmds))
1008+
mnt_drop_write(mountpath.mnt);
1009+
out:
1010+
path_put(&mountpath);
1011+
1012+
return ret;
1013+
}

0 commit comments

Comments
 (0)