本文共 1702 字,大约阅读时间需要 5 分钟。
这个函数在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中申请用户空间memoryvoid __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呀
转载地址:http://icnmi.baihongyu.com/