⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys_sparc32.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -