linux_file.c (e3b1c847a4237ad990cab71427927ced34b47507) linux_file.c (de774e422e7f8abf9d4c6084165c9de66f11b2de)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1994-1995 Søren Schmidt
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 107 unchanged lines hidden (view full) ---

116 error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE,
117 O_WRONLY | O_CREAT | O_TRUNC, args->mode);
118 LFREEPATH(path);
119 return (error);
120}
121#endif
122
123static int
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1994-1995 Søren Schmidt
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 107 unchanged lines hidden (view full) ---

116 error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE,
117 O_WRONLY | O_CREAT | O_TRUNC, args->mode);
118 LFREEPATH(path);
119 return (error);
120}
121#endif
122
123static int
124linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags,
125 int mode, enum uio_seg seg)
124linux_common_openflags(int l_flags)
126{
125{
127 struct proc *p = td->td_proc;
128 struct file *fp;
129 int fd;
130 int bsd_flags, error;
126 int bsd_flags;
131
132 bsd_flags = 0;
133 switch (l_flags & LINUX_O_ACCMODE) {
134 case LINUX_O_WRONLY:
135 bsd_flags |= O_WRONLY;
136 break;
137 case LINUX_O_RDWR:
138 bsd_flags |= O_RDWR;

--- 23 unchanged lines hidden (view full) ---

162 bsd_flags |= O_NOCTTY;
163 if (l_flags & LINUX_O_DIRECT)
164 bsd_flags |= O_DIRECT;
165 if (l_flags & LINUX_O_NOFOLLOW)
166 bsd_flags |= O_NOFOLLOW;
167 if (l_flags & LINUX_O_DIRECTORY)
168 bsd_flags |= O_DIRECTORY;
169 /* XXX LINUX_O_NOATIME: unable to be easily implemented. */
127
128 bsd_flags = 0;
129 switch (l_flags & LINUX_O_ACCMODE) {
130 case LINUX_O_WRONLY:
131 bsd_flags |= O_WRONLY;
132 break;
133 case LINUX_O_RDWR:
134 bsd_flags |= O_RDWR;

--- 23 unchanged lines hidden (view full) ---

158 bsd_flags |= O_NOCTTY;
159 if (l_flags & LINUX_O_DIRECT)
160 bsd_flags |= O_DIRECT;
161 if (l_flags & LINUX_O_NOFOLLOW)
162 bsd_flags |= O_NOFOLLOW;
163 if (l_flags & LINUX_O_DIRECTORY)
164 bsd_flags |= O_DIRECTORY;
165 /* XXX LINUX_O_NOATIME: unable to be easily implemented. */
166 return (bsd_flags);
167}
170
168
169static int
170linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags,
171 int mode, enum uio_seg seg)
172{
173 struct proc *p = td->td_proc;
174 struct file *fp;
175 int fd;
176 int bsd_flags, error;
177
178 bsd_flags = linux_common_openflags(l_flags);
171 error = kern_openat(td, dirfd, path, seg, bsd_flags, mode);
172 if (error != 0) {
173 if (error == EMLINK)
174 error = ELOOP;
175 goto done;
176 }
177 if (p->p_flag & P_CONTROLT)
178 goto done;

--- 71 unchanged lines hidden (view full) ---

250 error = linux_common_open(td, AT_FDCWD, path, args->flags, args->mode,
251 UIO_SYSSPACE);
252 LFREEPATH(path);
253 return (error);
254}
255#endif
256
257int
179 error = kern_openat(td, dirfd, path, seg, bsd_flags, mode);
180 if (error != 0) {
181 if (error == EMLINK)
182 error = ELOOP;
183 goto done;
184 }
185 if (p->p_flag & P_CONTROLT)
186 goto done;

--- 71 unchanged lines hidden (view full) ---

258 error = linux_common_open(td, AT_FDCWD, path, args->flags, args->mode,
259 UIO_SYSSPACE);
260 LFREEPATH(path);
261 return (error);
262}
263#endif
264
265int
266linux_name_to_handle_at(struct thread *td,
267 struct linux_name_to_handle_at_args *args)
268{
269 static const l_int valid_flags = (LINUX_AT_SYMLINK_FOLLOW |
270 LINUX_AT_EMPTY_PATH);
271 static const l_uint fh_size = sizeof(fhandle_t);
272
273 fhandle_t fh;
274 l_uint fh_bytes;
275 l_int mount_id;
276 int error, fd, bsd_flags;
277
278 if (args->flags & ~valid_flags)
279 return (EINVAL);
280 if (args->flags & LINUX_AT_EMPTY_PATH)
281 /* XXX: not supported yet */
282 return (EOPNOTSUPP);
283
284 fd = args->dirfd;
285 if (fd == LINUX_AT_FDCWD)
286 fd = AT_FDCWD;
287
288 bsd_flags = 0;
289 if (!(args->flags & LINUX_AT_SYMLINK_FOLLOW))
290 bsd_flags |= AT_SYMLINK_NOFOLLOW;
291
292 if (!LUSECONVPATH(td)) {
293 error = kern_getfhat(td, bsd_flags, fd, args->name,
294 UIO_USERSPACE, &fh, UIO_SYSSPACE);
295 } else {
296 char *path;
297
298 LCONVPATH_AT(td, args->name, &path, 0, fd);
299 error = kern_getfhat(td, bsd_flags, fd, path, UIO_SYSSPACE,
300 &fh, UIO_SYSSPACE);
301 LFREEPATH(path);
302 }
303 if (error != 0)
304 return (error);
305
306 /* Emit mount_id -- required before EOVERFLOW case. */
307 mount_id = (fh.fh_fsid.val[0] ^ fh.fh_fsid.val[1]);
308 error = copyout(&mount_id, args->mnt_id, sizeof(mount_id));
309 if (error != 0)
310 return (error);
311
312 /* Check if there is room for handle. */
313 error = copyin(&args->handle->handle_bytes, &fh_bytes,
314 sizeof(fh_bytes));
315 if (error != 0)
316 return (error);
317
318 if (fh_bytes < fh_size) {
319 error = copyout(&fh_size, &args->handle->handle_bytes,
320 sizeof(fh_size));
321 if (error == 0)
322 error = EOVERFLOW;
323 return (error);
324 }
325
326 /* Emit handle. */
327 mount_id = 0;
328 /*
329 * We don't use handle_type for anything yet, but initialize a known
330 * value.
331 */
332 error = copyout(&mount_id, &args->handle->handle_type,
333 sizeof(mount_id));
334 if (error != 0)
335 return (error);
336
337 error = copyout(&fh, &args->handle->f_handle,
338 sizeof(fh));
339 return (error);
340}
341
342int
343linux_open_by_handle_at(struct thread *td,
344 struct linux_open_by_handle_at_args *args)
345{
346 l_uint fh_bytes;
347 int bsd_flags, error;
348
349 error = copyin(&args->handle->handle_bytes, &fh_bytes,
350 sizeof(fh_bytes));
351 if (error != 0)
352 return (error);
353
354 if (fh_bytes < sizeof(fhandle_t))
355 return (EINVAL);
356
357 bsd_flags = linux_common_openflags(args->flags);
358 return (kern_fhopen(td, (void *)&args->handle->f_handle, bsd_flags));
359}
360
361int
258linux_lseek(struct thread *td, struct linux_lseek_args *args)
259{
260
261 return (kern_lseek(td, args->fdes, args->off, args->whence));
262}
263
264#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
265int

--- 1655 unchanged lines hidden ---
362linux_lseek(struct thread *td, struct linux_lseek_args *args)
363{
364
365 return (kern_lseek(td, args->fdes, args->off, args->whence));
366}
367
368#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
369int

--- 1655 unchanged lines hidden ---