fs: keep struct mnt_id_req extensible
Make it extensible so that we have the liberty to reuse it in future mount-id based apis. Treat zero size as the first published struct. Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
d8b0f54650
commit
35e27a5744
2 changed files with 35 additions and 4 deletions
|
@ -4956,6 +4956,30 @@ static int prepare_kstatmount(struct kstatmount *ks, struct mnt_id_req *kreq,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int copy_mnt_id_req(const struct mnt_id_req __user *req,
|
||||||
|
struct mnt_id_req *kreq)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t usize;
|
||||||
|
|
||||||
|
BUILD_BUG_ON(sizeof(struct mnt_id_req) != MNT_ID_REQ_SIZE_VER0);
|
||||||
|
|
||||||
|
ret = get_user(usize, &req->size);
|
||||||
|
if (ret)
|
||||||
|
return -EFAULT;
|
||||||
|
if (unlikely(usize > PAGE_SIZE))
|
||||||
|
return -E2BIG;
|
||||||
|
if (unlikely(usize < MNT_ID_REQ_SIZE_VER0))
|
||||||
|
return -EINVAL;
|
||||||
|
memset(kreq, 0, sizeof(*kreq));
|
||||||
|
ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (kreq->spare != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
|
SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
|
||||||
struct statmount __user *, buf, size_t, bufsize,
|
struct statmount __user *, buf, size_t, bufsize,
|
||||||
unsigned int, flags)
|
unsigned int, flags)
|
||||||
|
@ -4970,8 +4994,9 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
|
||||||
if (flags)
|
if (flags)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&kreq, req, sizeof(kreq)))
|
ret = copy_mnt_id_req(req, &kreq);
|
||||||
return -EFAULT;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
ret = prepare_kstatmount(&ks, &kreq, buf, bufsize, seq_size);
|
ret = prepare_kstatmount(&ks, &kreq, buf, bufsize, seq_size);
|
||||||
|
@ -5052,8 +5077,9 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req,
|
||||||
if (flags)
|
if (flags)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&kreq, req, sizeof(kreq)))
|
ret = copy_mnt_id_req(req, &kreq);
|
||||||
return -EFAULT;
|
if (ret)
|
||||||
|
return ret;
|
||||||
mnt_id = kreq.mnt_id;
|
mnt_id = kreq.mnt_id;
|
||||||
last_mnt_id = kreq.param;
|
last_mnt_id = kreq.param;
|
||||||
|
|
||||||
|
|
|
@ -184,10 +184,15 @@ struct statmount {
|
||||||
* For listmount(2) @param represents the last listed mount id (or zero).
|
* For listmount(2) @param represents the last listed mount id (or zero).
|
||||||
*/
|
*/
|
||||||
struct mnt_id_req {
|
struct mnt_id_req {
|
||||||
|
__u32 size;
|
||||||
|
__u32 spare;
|
||||||
__u64 mnt_id;
|
__u64 mnt_id;
|
||||||
__u64 param;
|
__u64 param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* List of all mnt_id_req versions. */
|
||||||
|
#define MNT_ID_REQ_SIZE_VER0 24 /* sizeof first published struct */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @mask bits for statmount(2)
|
* @mask bits for statmount(2)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue