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
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
#include <linux/quotaops.h>
|
#include <linux/quotaops.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/mount.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/nospec.h>
|
#include <linux/nospec.h>
|
||||||
#include "compat.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 */
|
/* Return 1 if 'cmd' will block on frozen filesystem */
|
||||||
static int quotactl_cmd_write(int cmd)
|
static int quotactl_cmd_write(int cmd)
|
||||||
{
|
{
|
||||||
|
@ -850,7 +849,6 @@ static int quotactl_cmd_write(int cmd)
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLOCK */
|
|
||||||
|
|
||||||
/* Return true if quotactl command is manipulating quota on/off state */
|
/* Return true if quotactl command is manipulating quota on/off state */
|
||||||
static bool quotactl_cmd_onoff(int cmd)
|
static bool quotactl_cmd_onoff(int cmd)
|
||||||
|
@ -968,3 +966,48 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
|
||||||
path_put(pathp);
|
path_put(pathp);
|
||||||
return ret;
|
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