mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	switch timerfd compat syscalls to COMPAT_SYSCALL_DEFINE
... and move them over to fs/timerfd.c. Cleaner and easier that way... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									90caf58dad
								
							
						
					
					
						commit
						9d94b9e2f3
					
				
					 2 changed files with 66 additions and 60 deletions
				
			
		
							
								
								
									
										41
									
								
								fs/compat.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								fs/compat.c
									
									
									
									
									
								
							|  | @ -1737,47 +1737,6 @@ asmlinkage long compat_sys_signalfd(int ufd, | ||||||
| } | } | ||||||
| #endif /* CONFIG_SIGNALFD */ | #endif /* CONFIG_SIGNALFD */ | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_TIMERFD |  | ||||||
| 
 |  | ||||||
| asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, |  | ||||||
| 				   const struct compat_itimerspec __user *utmr, |  | ||||||
| 				   struct compat_itimerspec __user *otmr) |  | ||||||
| { |  | ||||||
| 	int error; |  | ||||||
| 	struct itimerspec t; |  | ||||||
| 	struct itimerspec __user *ut; |  | ||||||
| 
 |  | ||||||
| 	if (get_compat_itimerspec(&t, utmr)) |  | ||||||
| 		return -EFAULT; |  | ||||||
| 	ut = compat_alloc_user_space(2 * sizeof(struct itimerspec)); |  | ||||||
| 	if (copy_to_user(&ut[0], &t, sizeof(t))) |  | ||||||
| 		return -EFAULT; |  | ||||||
| 	error = sys_timerfd_settime(ufd, flags, &ut[0], &ut[1]); |  | ||||||
| 	if (!error && otmr) |  | ||||||
| 		error = (copy_from_user(&t, &ut[1], sizeof(struct itimerspec)) || |  | ||||||
| 			 put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0; |  | ||||||
| 
 |  | ||||||
| 	return error; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| asmlinkage long compat_sys_timerfd_gettime(int ufd, |  | ||||||
| 				   struct compat_itimerspec __user *otmr) |  | ||||||
| { |  | ||||||
| 	int error; |  | ||||||
| 	struct itimerspec t; |  | ||||||
| 	struct itimerspec __user *ut; |  | ||||||
| 
 |  | ||||||
| 	ut = compat_alloc_user_space(sizeof(struct itimerspec)); |  | ||||||
| 	error = sys_timerfd_gettime(ufd, ut); |  | ||||||
| 	if (!error) |  | ||||||
| 		error = (copy_from_user(&t, ut, sizeof(struct itimerspec)) || |  | ||||||
| 			 put_compat_itimerspec(otmr, &t)) ? -EFAULT: 0; |  | ||||||
| 
 |  | ||||||
| 	return error; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #endif /* CONFIG_TIMERFD */ |  | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_FHANDLE | #ifdef CONFIG_FHANDLE | ||||||
| /*
 | /*
 | ||||||
|  * Exactly like fs/open.c:sys_open_by_handle_at(), except that it |  * Exactly like fs/open.c:sys_open_by_handle_at(), except that it | ||||||
|  |  | ||||||
							
								
								
									
										85
									
								
								fs/timerfd.c
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								fs/timerfd.c
									
									
									
									
									
								
							|  | @ -22,6 +22,7 @@ | ||||||
| #include <linux/anon_inodes.h> | #include <linux/anon_inodes.h> | ||||||
| #include <linux/timerfd.h> | #include <linux/timerfd.h> | ||||||
| #include <linux/syscalls.h> | #include <linux/syscalls.h> | ||||||
|  | #include <linux/compat.h> | ||||||
| #include <linux/rcupdate.h> | #include <linux/rcupdate.h> | ||||||
| 
 | 
 | ||||||
| struct timerfd_ctx { | struct timerfd_ctx { | ||||||
|  | @ -278,21 +279,17 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | ||||||
| 	return ufd; | 	return ufd; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | static int do_timerfd_settime(int ufd, int flags,  | ||||||
| 		const struct itimerspec __user *, utmr, | 		const struct itimerspec *new, | ||||||
| 		struct itimerspec __user *, otmr) | 		struct itimerspec *old) | ||||||
| { | { | ||||||
| 	struct fd f; | 	struct fd f; | ||||||
| 	struct timerfd_ctx *ctx; | 	struct timerfd_ctx *ctx; | ||||||
| 	struct itimerspec ktmr, kotmr; |  | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) |  | ||||||
| 		return -EFAULT; |  | ||||||
| 
 |  | ||||||
| 	if ((flags & ~TFD_SETTIME_FLAGS) || | 	if ((flags & ~TFD_SETTIME_FLAGS) || | ||||||
| 	    !timespec_valid(&ktmr.it_value) || | 	    !timespec_valid(&new->it_value) || | ||||||
| 	    !timespec_valid(&ktmr.it_interval)) | 	    !timespec_valid(&new->it_interval)) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 
 | 
 | ||||||
| 	ret = timerfd_fget(ufd, &f); | 	ret = timerfd_fget(ufd, &f); | ||||||
|  | @ -323,27 +320,23 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | ||||||
| 	if (ctx->expired && ctx->tintv.tv64) | 	if (ctx->expired && ctx->tintv.tv64) | ||||||
| 		hrtimer_forward_now(&ctx->tmr, ctx->tintv); | 		hrtimer_forward_now(&ctx->tmr, ctx->tintv); | ||||||
| 
 | 
 | ||||||
| 	kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 	old->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | ||||||
| 	kotmr.it_interval = ktime_to_timespec(ctx->tintv); | 	old->it_interval = ktime_to_timespec(ctx->tintv); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Re-program the timer to the new value ... | 	 * Re-program the timer to the new value ... | ||||||
| 	 */ | 	 */ | ||||||
| 	ret = timerfd_setup(ctx, flags, &ktmr); | 	ret = timerfd_setup(ctx, flags, new); | ||||||
| 
 | 
 | ||||||
| 	spin_unlock_irq(&ctx->wqh.lock); | 	spin_unlock_irq(&ctx->wqh.lock); | ||||||
| 	fdput(f); | 	fdput(f); | ||||||
| 	if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) |  | ||||||
| 		return -EFAULT; |  | ||||||
| 
 |  | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | static int do_timerfd_gettime(int ufd, struct itimerspec *t) | ||||||
| { | { | ||||||
| 	struct fd f; | 	struct fd f; | ||||||
| 	struct timerfd_ctx *ctx; | 	struct timerfd_ctx *ctx; | ||||||
| 	struct itimerspec kotmr; |  | ||||||
| 	int ret = timerfd_fget(ufd, &f); | 	int ret = timerfd_fget(ufd, &f); | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		return ret; | 		return ret; | ||||||
|  | @ -356,11 +349,65 @@ SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | ||||||
| 			hrtimer_forward_now(&ctx->tmr, ctx->tintv) - 1; | 			hrtimer_forward_now(&ctx->tmr, ctx->tintv) - 1; | ||||||
| 		hrtimer_restart(&ctx->tmr); | 		hrtimer_restart(&ctx->tmr); | ||||||
| 	} | 	} | ||||||
| 	kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 	t->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | ||||||
| 	kotmr.it_interval = ktime_to_timespec(ctx->tintv); | 	t->it_interval = ktime_to_timespec(ctx->tintv); | ||||||
| 	spin_unlock_irq(&ctx->wqh.lock); | 	spin_unlock_irq(&ctx->wqh.lock); | ||||||
| 	fdput(f); | 	fdput(f); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | ||||||
|  | 		const struct itimerspec __user *, utmr, | ||||||
|  | 		struct itimerspec __user *, otmr) | ||||||
|  | { | ||||||
|  | 	struct itimerspec new, old; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (copy_from_user(&new, utmr, sizeof(new))) | ||||||
|  | 		return -EFAULT; | ||||||
|  | 	ret = do_timerfd_settime(ufd, flags, &new, &old); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 	if (otmr && copy_to_user(otmr, &old, sizeof(old))) | ||||||
|  | 		return -EFAULT; | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | ||||||
|  | { | ||||||
|  | 	struct itimerspec kotmr; | ||||||
|  | 	int ret = do_timerfd_gettime(ufd, &kotmr); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
| 	return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; | 	return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #ifdef COMPAT | ||||||
|  | COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | ||||||
|  | 		const struct itimerspec __user *, utmr, | ||||||
|  | 		struct itimerspec __user *, otmr) | ||||||
|  | { | ||||||
|  | 	struct itimerspec new, old; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (get_compat_itimerspec(&new, utmr)) | ||||||
|  | 		return -EFAULT; | ||||||
|  | 	ret = do_timerfd_settime(ufd, flags, &new, &old); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 	if (otmr && put_compat_itimerspec(otmr, &old)) | ||||||
|  | 		return -EFAULT; | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd, | ||||||
|  | 		struct itimerspec __user *, otmr) | ||||||
|  | { | ||||||
|  | 	struct itimerspec kotmr; | ||||||
|  | 	int ret = do_timerfd_gettime(ufd, &kotmr); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 	return put_compat_itimerspec(otmr, &t) ? -EFAULT: 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Al Viro
						Al Viro