mirror of https://gitee.com/openkylin/linux.git
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/20210304123541.30749-2-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
1e28eed176
commit
9dfa23c8de
fs/quota
|
@ -17,6 +17,7 @@
|
|||
#include <linux/capability.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/nospec.h>
|
||||
#include "compat.h"
|
||||
|
@ -827,8 +828,6 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLOCK
|
||||
|
||||
/* Return 1 if 'cmd' will block on frozen filesystem */
|
||||
static int quotactl_cmd_write(int cmd)
|
||||
{
|
||||
|
@ -850,7 +849,6 @@ static int quotactl_cmd_write(int cmd)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_BLOCK */
|
||||
|
||||
/* Return true if quotactl command is manipulating quota on/off state */
|
||||
static bool quotactl_cmd_onoff(int cmd)
|
||||
|
@ -968,3 +966,48 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
|
|||
path_put(pathp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE4(quotactl_path, unsigned int, cmd, const char __user *,
|
||||
mountpoint, qid_t, id, void __user *, addr)
|
||||
{
|
||||
struct super_block *sb;
|
||||
struct path mountpath;
|
||||
unsigned int cmds = cmd >> SUBCMDSHIFT;
|
||||
unsigned int type = cmd & SUBCMDMASK;
|
||||
int ret;
|
||||
|
||||
if (type >= MAXQUOTAS)
|
||||
return -EINVAL;
|
||||
|
||||
ret = user_path_at(AT_FDCWD, mountpoint,
|
||||
LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT, &mountpath);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sb = mountpath.mnt->mnt_sb;
|
||||
|
||||
if (quotactl_cmd_write(cmds)) {
|
||||
ret = mnt_want_write(mountpath.mnt);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (quotactl_cmd_onoff(cmds))
|
||||
down_write(&sb->s_umount);
|
||||
else
|
||||
down_read(&sb->s_umount);
|
||||
|
||||
ret = do_quotactl(sb, type, cmds, id, addr, ERR_PTR(-EINVAL));
|
||||
|
||||
if (quotactl_cmd_onoff(cmds))
|
||||
up_write(&sb->s_umount);
|
||||
else
|
||||
up_read(&sb->s_umount);
|
||||
|
||||
if (quotactl_cmd_write(cmds))
|
||||
mnt_drop_write(mountpath.mnt);
|
||||
out:
|
||||
path_put(&mountpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue