这个函数在kernel space中从当前进程的用户空间申请一段内存空间并从kernel中的到quote 信息后,然后copy到用户空间中
其中的quote信息如下:
struct if_dqblk {
__u64 dqb_bhardlimit;
__u64 dqb_bsoftlimit;
__u64 dqb_curspace;
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
__u64 dqb_btime;
__u64 dqb_itime;
__u32 dqb_valid;
};
其源码分析如下:
asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
qid_t id, void __user *addr)
{
unsigned int cmds;
struct if_dqblk __user *dqblk;
struct compat_if_dqblk __user *compat_dqblk;
struct fs_quota_stat __user *fsqstat;
struct compat_fs_quota_stat __user *compat_fsqstat;
compat_uint_t data;
u16 xdata;
long ret;
cmds = cmd >> SUBCMDSHIFT;
#总共有三个命令,分别是Q_GETQUOTA/Q_SETQUOTA/Q_XGETQSTAT 这三个命令的实现类似
switch (cmds) {
case Q_GETQUOTA:
#从用户空间申请一段memory
dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
compat_dqblk = addr;
#得到quote信息dqblk
ret = sys_quotactl(cmd, special, id, dqblk);
if (ret)
break;
#将dqblk中的信息copy到用户空间memory compat_dqblk 中,这里 compat_dqblk 和 dqblk 都是用户空间的memory
if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
get_user(data, &dqblk->dqb_valid) ||
put_user(data, &compat_dqblk->dqb_valid))
ret = -EFAULT;
break;
}
下来我们看看如何在kernel中申请用户空间memory
void __user *compat_alloc_user_space(unsigned long len)
{
void __user *ptr;
/* If len would occupy more than half of the entire compat space... */
#检查参数是否合理
if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
return NULL;
ptr = arch_compat_alloc_user_space(len);
#检查是否有写权限
if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
return NULL;
return ptr;
}
static inline void __user *arch_compat_alloc_user_space(long len)
{
return (void __user *)compat_user_stack_pointer() - len;
}
原来就是直接从stack 顶端拿一个memory呀
系统调用之sys32_quotactl
最新推荐文章于 2022-09-01 09:17:30 发布