From owner-svn-src-head@freebsd.org Tue Nov 17 19:51:49 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C3AE546D665; Tue, 17 Nov 2020 19:51:49 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CbGmP3z7dz3MkT; Tue, 17 Nov 2020 19:51:49 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6D587257AF; Tue, 17 Nov 2020 19:51:49 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0AHJpn4M015676; Tue, 17 Nov 2020 19:51:49 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0AHJplW4015667; Tue, 17 Nov 2020 19:51:47 GMT (envelope-from cem@FreeBSD.org) Message-Id: <202011171951.0AHJplW4015667@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Tue, 17 Nov 2020 19:51:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367773 - in head/sys: amd64/linux amd64/linux32 arm64/linux compat/linux i386/linux kern sys X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: in head/sys: amd64/linux amd64/linux32 arm64/linux compat/linux i386/linux kern sys X-SVN-Commit-Revision: 367773 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Nov 2020 19:51:49 -0000 Author: cem Date: Tue Nov 17 19:51:47 2020 New Revision: 367773 URL: https://svnweb.freebsd.org/changeset/base/367773 Log: linux(4): Implement name_to_handle_at(), open_by_handle_at() They are similar to our getfhat(2) and fhopen(2) syscalls. Differential Revision: https://reviews.freebsd.org/D27111 Modified: head/sys/amd64/linux/syscalls.master head/sys/amd64/linux32/syscalls.master head/sys/arm64/linux/syscalls.master head/sys/compat/linux/linux_dummy.c head/sys/compat/linux/linux_file.c head/sys/compat/linux/linux_file.h head/sys/i386/linux/syscalls.master head/sys/kern/vfs_syscalls.c head/sys/sys/syscallsubr.h Modified: head/sys/amd64/linux/syscalls.master ============================================================================== --- head/sys/amd64/linux/syscalls.master Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/amd64/linux/syscalls.master Tue Nov 17 19:51:47 2020 (r367773) @@ -1792,10 +1792,20 @@ } ; Linux 2.6.39 (glibc 2.14): 303 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 304 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 305 AUE_NULL STD { int linux_clock_adjtime(void); Modified: head/sys/amd64/linux32/syscalls.master ============================================================================== --- head/sys/amd64/linux32/syscalls.master Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/amd64/linux32/syscalls.master Tue Nov 17 19:51:47 2020 (r367773) @@ -1916,10 +1916,20 @@ } ; Linux 2.6.39: 341 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 342 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 343 AUE_NULL STD { int linux_clock_adjtime(void); Modified: head/sys/arm64/linux/syscalls.master ============================================================================== --- head/sys/arm64/linux/syscalls.master Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/arm64/linux/syscalls.master Tue Nov 17 19:51:47 2020 (r367773) @@ -1473,10 +1473,20 @@ int linux_fanotify_mark(void); } 264 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 265 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 266 AUE_NULL STD { int linux_clock_adjtime(void); Modified: head/sys/compat/linux/linux_dummy.c ============================================================================== --- head/sys/compat/linux/linux_dummy.c Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/compat/linux/linux_dummy.c Tue Nov 17 19:51:47 2020 (r367773) @@ -101,8 +101,6 @@ DUMMY(perf_event_open); DUMMY(fanotify_init); DUMMY(fanotify_mark); /* Linux 2.6.39: */ -DUMMY(name_to_handle_at); -DUMMY(open_by_handle_at); DUMMY(clock_adjtime); /* Linux 3.0: */ DUMMY(setns); Modified: head/sys/compat/linux/linux_file.c ============================================================================== --- head/sys/compat/linux/linux_file.c Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/compat/linux/linux_file.c Tue Nov 17 19:51:47 2020 (r367773) @@ -121,13 +121,9 @@ linux_creat(struct thread *td, struct linux_creat_args #endif static int -linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags, - int mode, enum uio_seg seg) +linux_common_openflags(int l_flags) { - struct proc *p = td->td_proc; - struct file *fp; - int fd; - int bsd_flags, error; + int bsd_flags; bsd_flags = 0; switch (l_flags & LINUX_O_ACCMODE) { @@ -167,7 +163,19 @@ linux_common_open(struct thread *td, int dirfd, const if (l_flags & LINUX_O_DIRECTORY) bsd_flags |= O_DIRECTORY; /* XXX LINUX_O_NOATIME: unable to be easily implemented. */ + return (bsd_flags); +} +static int +linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags, + int mode, enum uio_seg seg) +{ + struct proc *p = td->td_proc; + struct file *fp; + int fd; + int bsd_flags, error; + + bsd_flags = linux_common_openflags(l_flags); error = kern_openat(td, dirfd, path, seg, bsd_flags, mode); if (error != 0) { if (error == EMLINK) @@ -253,6 +261,102 @@ linux_open(struct thread *td, struct linux_open_args * return (error); } #endif + +int +linux_name_to_handle_at(struct thread *td, + struct linux_name_to_handle_at_args *args) +{ + static const l_int valid_flags = (LINUX_AT_SYMLINK_FOLLOW | + LINUX_AT_EMPTY_PATH); + static const l_uint fh_size = sizeof(fhandle_t); + + fhandle_t fh; + l_uint fh_bytes; + l_int mount_id; + int error, fd, bsd_flags; + + if (args->flags & ~valid_flags) + return (EINVAL); + if (args->flags & LINUX_AT_EMPTY_PATH) + /* XXX: not supported yet */ + return (EOPNOTSUPP); + + fd = args->dirfd; + if (fd == LINUX_AT_FDCWD) + fd = AT_FDCWD; + + bsd_flags = 0; + if (!(args->flags & LINUX_AT_SYMLINK_FOLLOW)) + bsd_flags |= AT_SYMLINK_NOFOLLOW; + + if (!LUSECONVPATH(td)) { + error = kern_getfhat(td, bsd_flags, fd, args->name, + UIO_USERSPACE, &fh, UIO_SYSSPACE); + } else { + char *path; + + LCONVPATH_AT(td, args->name, &path, 0, fd); + error = kern_getfhat(td, bsd_flags, fd, path, UIO_SYSSPACE, + &fh, UIO_SYSSPACE); + LFREEPATH(path); + } + if (error != 0) + return (error); + + /* Emit mount_id -- required before EOVERFLOW case. */ + mount_id = (fh.fh_fsid.val[0] ^ fh.fh_fsid.val[1]); + error = copyout(&mount_id, args->mnt_id, sizeof(mount_id)); + if (error != 0) + return (error); + + /* Check if there is room for handle. */ + error = copyin(&args->handle->handle_bytes, &fh_bytes, + sizeof(fh_bytes)); + if (error != 0) + return (error); + + if (fh_bytes < fh_size) { + error = copyout(&fh_size, &args->handle->handle_bytes, + sizeof(fh_size)); + if (error == 0) + error = EOVERFLOW; + return (error); + } + + /* Emit handle. */ + mount_id = 0; + /* + * We don't use handle_type for anything yet, but initialize a known + * value. + */ + error = copyout(&mount_id, &args->handle->handle_type, + sizeof(mount_id)); + if (error != 0) + return (error); + + error = copyout(&fh, &args->handle->f_handle, + sizeof(fh)); + return (error); +} + +int +linux_open_by_handle_at(struct thread *td, + struct linux_open_by_handle_at_args *args) +{ + l_uint fh_bytes; + int bsd_flags, error; + + error = copyin(&args->handle->handle_bytes, &fh_bytes, + sizeof(fh_bytes)); + if (error != 0) + return (error); + + if (fh_bytes < sizeof(fhandle_t)) + return (EINVAL); + + bsd_flags = linux_common_openflags(args->flags); + return (kern_fhopen(td, (void *)&args->handle->f_handle, bsd_flags)); +} int linux_lseek(struct thread *td, struct linux_lseek_args *args) Modified: head/sys/compat/linux/linux_file.h ============================================================================== --- head/sys/compat/linux/linux_file.h Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/compat/linux/linux_file.h Tue Nov 17 19:51:47 2020 (r367773) @@ -36,6 +36,7 @@ #define LINUX_AT_EACCESS 0x200 #define LINUX_AT_REMOVEDIR 0x200 #define LINUX_AT_SYMLINK_FOLLOW 0x400 +#define LINUX_AT_EMPTY_PATH 0x1000 /* * posix_fadvise advice @@ -173,5 +174,11 @@ #define LINUX_HUGETLB_FLAG_ENCODE_1GB (30 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_2GB (31 << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) #define LINUX_HUGETLB_FLAG_ENCODE_16GB (34U << LINUX_HUGETLB_FLAG_ENCODE_SHIFT) + +struct l_file_handle { + l_uint handle_bytes; + l_int handle_type; + unsigned char f_handle[0]; +}; #endif /* !_LINUX_FILE_H_ */ Modified: head/sys/i386/linux/syscalls.master ============================================================================== --- head/sys/i386/linux/syscalls.master Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/i386/linux/syscalls.master Tue Nov 17 19:51:47 2020 (r367773) @@ -1934,10 +1934,20 @@ } ; Linux 2.6.39: 341 AUE_NULL STD { - int linux_name_to_handle_at(void); + int linux_name_to_handle_at( + l_int dirfd, + const char *name, + struct l_file_handle *handle, + l_int *mnt_id, + l_int flags + ); } 342 AUE_NULL STD { - int linux_open_by_handle_at(void); + int linux_open_by_handle_at( + l_int mountdirfd, + struct l_file_handle *handle, + l_int flags + ); } 343 AUE_NULL STD { int linux_clock_adjtime(void); Modified: head/sys/kern/vfs_syscalls.c ============================================================================== --- head/sys/kern/vfs_syscalls.c Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/kern/vfs_syscalls.c Tue Nov 17 19:51:47 2020 (r367773) @@ -105,8 +105,6 @@ static int vn_access(struct vnode *vp, int user_flags, struct thread *td); static int kern_fhlinkat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, fhandle_t *fhp); -static int kern_getfhat(struct thread *td, int flags, int fd, - const char *path, enum uio_seg pathseg, fhandle_t *fhp); static int kern_readlink_vp(struct vnode *vp, char *buf, enum uio_seg bufseg, size_t count, struct thread *td); static int kern_linkat_vp(struct thread *td, struct vnode *vp, int fd, @@ -4315,7 +4313,7 @@ sys_lgetfh(struct thread *td, struct lgetfh_args *uap) { return (kern_getfhat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->fname, - UIO_USERSPACE, uap->fhp)); + UIO_USERSPACE, uap->fhp, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ @@ -4329,7 +4327,7 @@ sys_getfh(struct thread *td, struct getfh_args *uap) { return (kern_getfhat(td, 0, AT_FDCWD, uap->fname, UIO_USERSPACE, - uap->fhp)); + uap->fhp, UIO_USERSPACE)); } /* @@ -4355,12 +4353,12 @@ sys_getfhat(struct thread *td, struct getfhat_args *ua AT_RESOLVE_BENEATH)) != 0) return (EINVAL); return (kern_getfhat(td, uap->flags, uap->fd, uap->path, UIO_USERSPACE, - uap->fhp)); + uap->fhp, UIO_USERSPACE)); } -static int +int kern_getfhat(struct thread *td, int flags, int fd, const char *path, - enum uio_seg pathseg, fhandle_t *fhp) + enum uio_seg pathseg, fhandle_t *fhp, enum uio_seg fhseg) { struct nameidata nd; fhandle_t fh; @@ -4382,8 +4380,12 @@ kern_getfhat(struct thread *td, int flags, int fd, con fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); - if (error == 0) - error = copyout(&fh, fhp, sizeof (fh)); + if (error == 0) { + if (fhseg == UIO_USERSPACE) + error = copyout(&fh, fhp, sizeof (fh)); + else + memcpy(fhp, &fh, sizeof(fh)); + } return (error); } @@ -4493,6 +4495,12 @@ struct fhopen_args { int sys_fhopen(struct thread *td, struct fhopen_args *uap) { + return (kern_fhopen(td, uap->u_fhp, uap->flags)); +} + +int +kern_fhopen(struct thread *td, const struct fhandle *u_fhp, int flags) +{ struct mount *mp; struct vnode *vp; struct fhandle fhp; @@ -4504,11 +4512,11 @@ sys_fhopen(struct thread *td, struct fhopen_args *uap) if (error != 0) return (error); indx = -1; - fmode = FFLAGS(uap->flags); + fmode = FFLAGS(flags); /* why not allow a non-read/write open for our lockd? */ if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) return (EINVAL); - error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); + error = copyin(u_fhp, &fhp, sizeof(fhp)); if (error != 0) return(error); /* find the mount point */ Modified: head/sys/sys/syscallsubr.h ============================================================================== --- head/sys/sys/syscallsubr.h Tue Nov 17 18:28:20 2020 (r367772) +++ head/sys/sys/syscallsubr.h Tue Nov 17 19:51:47 2020 (r367773) @@ -140,6 +140,7 @@ int kern_fchownat(struct thread *td, int fd, const cha enum uio_seg pathseg, int uid, int gid, int flag); int kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg); int kern_fcntl_freebsd(struct thread *td, int fd, int cmd, long arg); +int kern_fhopen(struct thread *td, const struct fhandle *u_fhp, int flags); int kern_fhstat(struct thread *td, fhandle_t fh, struct stat *buf); int kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf); int kern_fpathconf(struct thread *td, int fd, int name, long *valuep); @@ -153,6 +154,8 @@ int kern_futimens(struct thread *td, int fd, struct ti enum uio_seg tptrseg); int kern_getdirentries(struct thread *td, int fd, char *buf, size_t count, off_t *basep, ssize_t *residp, enum uio_seg bufseg); +int kern_getfhat(struct thread *td, int flags, int fd, const char *path, + enum uio_seg pathseg, fhandle_t *fhp, enum uio_seg fhseg); int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, size_t *countp, enum uio_seg bufseg, int mode); int kern_getitimer(struct thread *, u_int, struct itimerval *);