📄 sys_sparc32.c
字号:
blksize = inode->i_blksize; blocks = inode->i_blocks; err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev); err |= put_user(ino, &statbuf->st_ino); err |= put_user(mode, &statbuf->st_mode); err |= put_user(nlink, &statbuf->st_nlink); err |= put_user(high2lowuid(uid), &statbuf->st_uid); err |= put_user(high2lowgid(gid), &statbuf->st_gid); err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev); err |= put_user(size, &statbuf->st_size); err |= put_user(atime, &statbuf->st_atime); err |= put_user(0, &statbuf->__unused1); err |= put_user(mtime, &statbuf->st_mtime); err |= put_user(0, &statbuf->__unused2); err |= put_user(ctime, &statbuf->st_ctime); err |= put_user(0, &statbuf->__unused3); if (blksize) { err |= put_user(blksize, &statbuf->st_blksize); err |= put_user(blocks, &statbuf->st_blocks); } else { unsigned int tmp_blocks;#define D_B 7#define I_B (BLOCK_SIZE / sizeof(unsigned short)) tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE; if (tmp_blocks > D_B) { unsigned int indirect; indirect = (tmp_blocks - D_B + I_B - 1) / I_B; tmp_blocks += indirect; if (indirect > 1) { indirect = (indirect - 1 + I_B - 1) / I_B; tmp_blocks += indirect; if (indirect > 1) tmp_blocks++; } } err |= put_user(BLOCK_SIZE, &statbuf->st_blksize); err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);#undef D_B#undef I_B } err |= put_user(0, &statbuf->__unused4[0]); err |= put_user(0, &statbuf->__unused4[1]); return err;}/* Perhaps this belongs in fs.h or similar. -DaveM */static __inline__ intdo_revalidate(struct dentry *dentry){ struct inode * inode = dentry->d_inode; if (inode->i_op && inode->i_op->revalidate) return inode->i_op->revalidate(dentry); return 0;}asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf){ struct nameidata nd; int error; error = user_path_walk(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); if (!error) error = cp_new_stat32(nd.dentry->d_inode, statbuf); path_release(&nd); } return error;}asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf){ struct nameidata nd; int error; error = user_path_walk_link(filename, &nd); if (!error) { error = do_revalidate(nd.dentry); if (!error) error = cp_new_stat32(nd.dentry->d_inode, statbuf); path_release(&nd); } return error;}asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf){ struct file *f; int err = -EBADF; f = fget(fd); if (f) { struct dentry * dentry = f->f_dentry; err = do_revalidate(dentry); if (!err) err = cp_new_stat32(dentry->d_inode, statbuf); fput(f); } return err;}extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2){ return sys_sysfs(option, arg1, arg2);}struct ncp_mount_data32 { int version; unsigned int ncp_fd; __kernel_uid_t32 mounted_uid; __kernel_pid_t32 wdog_pid; unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; unsigned int time_out; unsigned int retry_count; unsigned int flags; __kernel_uid_t32 uid; __kernel_gid_t32 gid; __kernel_mode_t32 file_mode; __kernel_mode_t32 dir_mode;};static void *do_ncp_super_data_conv(void *raw_data){ struct ncp_mount_data news, *n = &news; struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data; n->dir_mode = n32->dir_mode; n->file_mode = n32->file_mode; n->gid = low2highgid(n32->gid); n->uid = low2highuid(n32->uid); memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int))); n->wdog_pid = n32->wdog_pid; n->mounted_uid = low2highuid(n32->mounted_uid); memcpy(raw_data, n, sizeof(struct ncp_mount_data)); return raw_data;}struct smb_mount_data32 { int version; __kernel_uid_t32 mounted_uid; __kernel_uid_t32 uid; __kernel_gid_t32 gid; __kernel_mode_t32 file_mode; __kernel_mode_t32 dir_mode;};static void *do_smb_super_data_conv(void *raw_data){ struct smb_mount_data news, *s = &news; struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data; s->version = s32->version; s->mounted_uid = low2highuid(s32->mounted_uid); s->uid = low2highuid(s32->uid); s->gid = low2highgid(s32->gid); s->file_mode = s32->file_mode; s->dir_mode = s32->dir_mode; memcpy(raw_data, s, sizeof(struct smb_mount_data)); return raw_data;}static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel){ int i; unsigned long page; struct vm_area_struct *vma; *kernel = 0; if(!user) return 0; vma = find_vma(current->mm, (unsigned long)user); if(!vma || (unsigned long)user < vma->vm_start) return -EFAULT; if(!(vma->vm_flags & VM_READ)) return -EFAULT; i = vma->vm_end - (unsigned long) user; if(PAGE_SIZE <= (unsigned long) i) i = PAGE_SIZE - 1; if(!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; if(copy_from_user((void *) page, user, i)) { free_page(page); return -EFAULT; } *kernel = page; return 0;}#define SMBFS_NAME "smbfs"#define NCPFS_NAME "ncpfs"asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data){ unsigned long type_page = 0; unsigned long data_page = 0; unsigned long dev_page = 0; unsigned long dir_page = 0; int err, is_smb, is_ncp; is_smb = is_ncp = 0; err = copy_mount_stuff_to_kernel((const void *)type, &type_page); if (err) goto out; if (!type_page) { err = -EINVAL; goto out; } is_smb = !strcmp((char *)type_page, SMBFS_NAME); is_ncp = !strcmp((char *)type_page, NCPFS_NAME); err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page); if (err) goto type_out; err = copy_mount_stuff_to_kernel(dev_name, &dev_page); if (err) goto data_out; err = copy_mount_stuff_to_kernel(dir_name, &dir_page); if (err) goto dev_out; if (!is_smb && !is_ncp) { lock_kernel(); err = do_mount((char*)dev_page, (char*)dir_page, (char*)type_page, new_flags, (char*)data_page); unlock_kernel(); } else { if (is_ncp) do_ncp_super_data_conv((void *)data_page); else do_smb_super_data_conv((void *)data_page); lock_kernel(); err = do_mount((char*)dev_page, (char*)dir_page, (char*)type_page, new_flags, (char*)data_page); unlock_kernel(); } free_page(dir_page);dev_out: free_page(dev_page);data_out: free_page(data_page);type_out: free_page(type_page);out: return err;}struct rusage32 { struct timeval32 ru_utime; struct timeval32 ru_stime; s32 ru_maxrss; s32 ru_ixrss; s32 ru_idrss; s32 ru_isrss; s32 ru_minflt; s32 ru_majflt; s32 ru_nswap; s32 ru_inblock; s32 ru_oublock; s32 ru_msgsnd; s32 ru_msgrcv; s32 ru_nsignals; s32 ru_nvcsw; s32 ru_nivcsw;};static int put_rusage (struct rusage32 *ru, struct rusage *r){ int err; err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec); err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec); err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec); err |= __put_user (r->ru_maxrss, &ru->ru_maxrss); err |= __put_user (r->ru_ixrss, &ru->ru_ixrss); err |= __put_user (r->ru_idrss, &ru->ru_idrss); err |= __put_user (r->ru_isrss, &ru->ru_isrss); err |= __put_user (r->ru_minflt, &ru->ru_minflt); err |= __put_user (r->ru_majflt, &ru->ru_majflt); err |= __put_user (r->ru_nswap, &ru->ru_nswap); err |= __put_user (r->ru_inblock, &ru->ru_inblock); err |= __put_user (r->ru_oublock, &ru->ru_oublock); err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd); err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv); err |= __put_user (r->ru_nsignals, &ru->ru_nsignals); err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw); err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw); return err;}extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru){ if (!ru) return sys_wait4(pid, stat_addr, options, NULL); else { struct rusage r; int ret; unsigned int status; mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r); set_fs (old_fs); if (put_rusage (ru, &r)) return -EFAULT; if (stat_addr && put_user (status, stat_addr)) return -EFAULT; return ret; }}struct sysinfo32 { s32 uptime; u32 loads[3]; u32 totalram; u32 freeram; u32 sharedram; u32 bufferram; u32 totalswap; u32 freeswap; unsigned short procs; char _f[22];};extern asmlinkage int sys_sysinfo(struct sysinfo *info);asmlinkage int sys32_sysinfo(struct sysinfo32 *info){ struct sysinfo s; int ret, err; mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); ret = sys_sysinfo(&s); set_fs (old_fs); err = put_user (s.uptime, &info->uptime); err |= __put_user (s.loads[0], &info->loads[0]); err |= __put_user (s.loads[1], &info->loads[1]); err |= __put_user (s.loads[2], &info->loads[2]); err |= __put_user (s.totalram, &info->totalram); err |= __put_user (s.freeram, &info->freeram); err |= __put_user (s.sharedram, &info->sharedram); err |= __put_user (s.bufferram, &info->bufferram); err |= __put_user (s.totalswap, &info->totalswap); err |= __put_user (s.freeswap, &info->freeswap); err |= __put_user (s.procs, &info->procs); if (err) return -EFAULT; return ret;}struct timespec32 { s32 tv_sec; s32 tv_nsec;}; extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval){ struct timespec t; int ret; mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval(pid, &t); set_fs (old_fs); if (put_user (t.tv_sec, &interval->tv_sec) || __put_user (t.tv_nsec, &interval->tv_nsec)) return -EFAULT; return ret;}extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp){ struct timespec t; int ret; mm_segment_t old_fs = get_fs (); if (get_user (t.tv_sec, &rqtp->tv_sec) || __get_user (t.tv_nsec, &rqtp->tv_nsec)) return -EFAULT; set_fs (KERNEL_DS); ret = sys_nanosleep(&t, rmtp ? &t : NULL); set_fs (old_fs); if (rmtp && ret == -EINTR) { if (__put_user (t.tv_sec, &rmtp->tv_sec) || __put_user (t.tv_nsec, &rmtp->tv_nsec)) return -EFAULT; } return ret;}extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset){ old_sigset_t s; int ret; mm_segment_t old_fs = get_fs(); if (set && get_user (s, set)) return -EFAULT; set_fs (KERNEL_DS); ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); set_fs (old_fs); if (ret) return ret; if (oset && put_user (s, oset)) return -EFAULT; return 0;}extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize){ sigset_t s; sigset_t32 s32; int ret; mm_segment_t old_fs = get_fs(); if (set) { if (copy_from_user (&s32, set, sizeof(sigset_t32))) return -EFAULT; switch (_NSIG_WORDS) { case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); } } set_fs (KERNEL_DS); ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize); set_fs (old_fs); if (ret) return ret; if (oset) { switch (_NSIG_WORDS) { case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; } if (copy_to_user (oset, &s32, sizeof(sigset_t32))) return -EFAULT; } return 0;}extern asmlinkage int sys_sigpending(old_sigset_t *set);asmlinkage int sys32_sigpending(old_sigset_t32 *set){ old_sigset_t s; int ret; mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_sigpending(&s); set_fs (old_fs); if (put_user (s, set)) return -EFAULT; return ret;}extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize){ sigset_t s; sigset_t32 s32; int ret; mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); ret = sys_rt_sigpending(&s, sigsetsize); set_fs (old_fs); if (!ret) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -