Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133456813
D27111.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D27111.diff
View Options
Index: head/sys/amd64/linux/syscalls.master
===================================================================
--- head/sys/amd64/linux/syscalls.master
+++ head/sys/amd64/linux/syscalls.master
@@ -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);
Index: head/sys/amd64/linux32/syscalls.master
===================================================================
--- head/sys/amd64/linux32/syscalls.master
+++ head/sys/amd64/linux32/syscalls.master
@@ -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);
Index: head/sys/arm64/linux/syscalls.master
===================================================================
--- head/sys/arm64/linux/syscalls.master
+++ head/sys/arm64/linux/syscalls.master
@@ -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);
Index: head/sys/compat/linux/linux_dummy.c
===================================================================
--- head/sys/compat/linux/linux_dummy.c
+++ head/sys/compat/linux/linux_dummy.c
@@ -101,8 +101,6 @@
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);
Index: head/sys/compat/linux/linux_file.h
===================================================================
--- head/sys/compat/linux/linux_file.h
+++ head/sys/compat/linux/linux_file.h
@@ -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_ */
Index: head/sys/compat/linux/linux_file.c
===================================================================
--- head/sys/compat/linux/linux_file.c
+++ head/sys/compat/linux/linux_file.c
@@ -121,13 +121,9 @@
#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 @@
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 @@
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)
Index: head/sys/i386/linux/syscalls.master
===================================================================
--- head/sys/i386/linux/syscalls.master
+++ head/sys/i386/linux/syscalls.master
@@ -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);
Index: head/sys/kern/vfs_syscalls.c
===================================================================
--- head/sys/kern/vfs_syscalls.c
+++ head/sys/kern/vfs_syscalls.c
@@ -105,8 +105,6 @@
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 @@
{
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 @@
{
return (kern_getfhat(td, 0, AT_FDCWD, uap->fname, UIO_USERSPACE,
- uap->fhp));
+ uap->fhp, UIO_USERSPACE));
}
/*
@@ -4355,12 +4353,12 @@
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 @@
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 @@
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 @@
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 */
Index: head/sys/sys/syscallsubr.h
===================================================================
--- head/sys/sys/syscallsubr.h
+++ head/sys/sys/syscallsubr.h
@@ -140,6 +140,7 @@
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 @@
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 *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 26, 10:46 PM (9 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24254504
Default Alt Text
D27111.diff (10 KB)
Attached To
Mode
D27111: linux(4): Implement name_to_handle_at(), open_by_handle_at()
Attached
Detach File
Event Timeline
Log In to Comment