Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/utime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) static bool nsec_valid(long nsec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 	if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	return nsec >= 0 && nsec <= 999999999;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) int vfs_utimes(const struct path *path, struct timespec64 *times)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	struct iattr newattrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	struct inode *inode = path->dentry->d_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	struct inode *delegated_inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	if (times) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		if (!nsec_valid(times[0].tv_nsec) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		    !nsec_valid(times[1].tv_nsec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 		if (times[0].tv_nsec == UTIME_NOW &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		    times[1].tv_nsec == UTIME_NOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 			times = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	error = mnt_want_write(path->mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (times) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		if (times[0].tv_nsec == UTIME_OMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			newattrs.ia_valid &= ~ATTR_ATIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		else if (times[0].tv_nsec != UTIME_NOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			newattrs.ia_atime = times[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			newattrs.ia_valid |= ATTR_ATIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		if (times[1].tv_nsec == UTIME_OMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			newattrs.ia_valid &= ~ATTR_MTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		else if (times[1].tv_nsec != UTIME_NOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			newattrs.ia_mtime = times[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			newattrs.ia_valid |= ATTR_MTIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		 * Tell setattr_prepare(), that this is an explicit time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		 * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		 * were used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		newattrs.ia_valid |= ATTR_TIMES_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		newattrs.ia_valid |= ATTR_TOUCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) retry_deleg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	error = notify_change(path->dentry, &newattrs, &delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	if (delegated_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		error = break_deleg_wait(&delegated_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			goto retry_deleg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	mnt_drop_write(path->mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static int do_utimes_path(int dfd, const char __user *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		struct timespec64 *times, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int lookup_flags = 0, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (!(flags & AT_SYMLINK_NOFOLLOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		lookup_flags |= LOOKUP_FOLLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (flags & AT_EMPTY_PATH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		lookup_flags |= LOOKUP_EMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	error = user_path_at(dfd, filename, lookup_flags, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	error = vfs_utimes(&path, times);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	path_put(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (retry_estale(error, lookup_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		lookup_flags |= LOOKUP_REVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int do_utimes_fd(int fd, struct timespec64 *times, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	error = vfs_utimes(&f.file->f_path, times);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * do_utimes - change times on filename or file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * @dfd: open file descriptor, -1 or AT_FDCWD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * @filename: path name or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * @times: new times or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * @flags: zero or more flags (only AT_SYMLINK_NOFOLLOW for the moment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * If filename is NULL and dfd refers to an open file, then operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * the file.  Otherwise look up filename, possibly using dfd as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * starting point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * If times==NULL, set access and modification to current time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * must be owner or have write permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * Else, update from *times, must be owner or super user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	       int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if (filename == NULL && dfd != AT_FDCWD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		return do_utimes_fd(dfd, times, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	return do_utimes_path(dfd, filename, times, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		struct __kernel_timespec __user *, utimes, int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct timespec64 tstimes[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (utimes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		if ((get_timespec64(&tstimes[0], &utimes[0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			get_timespec64(&tstimes[1], &utimes[1])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		/* Nothing to do, we must not even check the path.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		if (tstimes[0].tv_nsec == UTIME_OMIT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		    tstimes[1].tv_nsec == UTIME_OMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	return do_utimes(dfd, filename, utimes ? tstimes : NULL, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #ifdef __ARCH_WANT_SYS_UTIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * futimesat(), utimes() and utime() are older versions of utimensat()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * that are provided for compatibility with traditional C libraries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * On modern architectures, we always use libc wrappers around
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * utimensat() instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static long do_futimesat(int dfd, const char __user *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			 struct __kernel_old_timeval __user *utimes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	struct __kernel_old_timeval times[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	struct timespec64 tstimes[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if (utimes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		if (copy_from_user(&times, utimes, sizeof(times)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		/* This test is needed to catch all invalid values.  If we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		   would test only in do_utimes we would miss those invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		   values truncated by the multiplication with 1000.  Note
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		   that we also catch UTIME_{NOW,OMIT} here which are only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		   valid for utimensat.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if (times[0].tv_usec >= 1000000 || times[0].tv_usec < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		    times[1].tv_usec >= 1000000 || times[1].tv_usec < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		tstimes[0].tv_sec = times[0].tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		tstimes[0].tv_nsec = 1000 * times[0].tv_usec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		tstimes[1].tv_sec = times[1].tv_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		tstimes[1].tv_nsec = 1000 * times[1].tv_usec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	return do_utimes(dfd, filename, utimes ? tstimes : NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		struct __kernel_old_timeval __user *, utimes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	return do_futimesat(dfd, filename, utimes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) SYSCALL_DEFINE2(utimes, char __user *, filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		struct __kernel_old_timeval __user *, utimes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	return do_futimesat(AT_FDCWD, filename, utimes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct timespec64 tv[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (times) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		if (get_user(tv[0].tv_sec, &times->actime) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		    get_user(tv[1].tv_sec, &times->modtime))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		tv[0].tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		tv[1].tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return do_utimes(AT_FDCWD, filename, times ? tv : NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #ifdef CONFIG_COMPAT_32BIT_TIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * Not all architectures have sys_utime, so implement this in terms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * of sys_utimes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #ifdef __ARCH_WANT_SYS_UTIME32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) SYSCALL_DEFINE2(utime32, const char __user *, filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		struct old_utimbuf32 __user *, t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	struct timespec64 tv[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		if (get_user(tv[0].tv_sec, &t->actime) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		    get_user(tv[1].tv_sec, &t->modtime))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		tv[0].tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		tv[1].tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) SYSCALL_DEFINE4(utimensat_time32, unsigned int, dfd, const char __user *, filename, struct old_timespec32 __user *, t, int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	struct timespec64 tv[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	if  (t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		if (get_old_timespec32(&tv[0], &t[0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		    get_old_timespec32(&tv[1], &t[1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	return do_utimes(dfd, filename, t ? tv : NULL, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #ifdef __ARCH_WANT_SYS_UTIME32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static long do_compat_futimesat(unsigned int dfd, const char __user *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				struct old_timeval32 __user *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	struct timespec64 tv[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		    get_user(tv[0].tv_nsec, &t[0].tv_usec) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		    get_user(tv[1].tv_sec, &t[1].tv_sec) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		    get_user(tv[1].tv_nsec, &t[1].tv_usec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		    tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		tv[0].tv_nsec *= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		tv[1].tv_nsec *= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	return do_utimes(dfd, filename, t ? tv : NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) SYSCALL_DEFINE3(futimesat_time32, unsigned int, dfd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		       const char __user *, filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		       struct old_timeval32 __user *, t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	return do_compat_futimesat(dfd, filename, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) SYSCALL_DEFINE2(utimes_time32, const char __user *, filename, struct old_timeval32 __user *, t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	return do_compat_futimesat(AT_FDCWD, filename, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #endif