Module Name: src Committed By: dholland Date: Fri Jul 25 08:25:47 UTC 2014
Modified Files: src/sys/kern: syscalls.master vfs_syscalls.c Log Message: Add fdiscard and posix_fallocate syscalls. To generate a diff of this commit: cvs rdiff -u -r1.269 -r1.270 src/sys/kern/syscalls.master cvs rdiff -u -r1.487 -r1.488 src/sys/kern/vfs_syscalls.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/syscalls.master diff -u src/sys/kern/syscalls.master:1.269 src/sys/kern/syscalls.master:1.270 --- src/sys/kern/syscalls.master:1.269 Thu Jun 12 21:41:33 2014 +++ src/sys/kern/syscalls.master Fri Jul 25 08:25:47 2014 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.269 2014/06/12 21:41:33 joerg Exp $ + $NetBSD: syscalls.master,v 1.270 2014/07/25 08:25:47 dholland Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -944,3 +944,7 @@ 478 STD { int|sys|60|_lwp_park(clockid_t clock_id, int flags, \ const struct timespec *ts, lwpid_t unpark, \ const void *hint, const void *unparkhint); } +479 STD RUMP { int|sys||posix_fallocate(int fd, int PAD, off_t pos, \ + off_t len); } +480 STD RUMP { int|sys||fdiscard(int fd, int PAD, off_t pos, \ + off_t len); } Index: src/sys/kern/vfs_syscalls.c diff -u src/sys/kern/vfs_syscalls.c:1.487 src/sys/kern/vfs_syscalls.c:1.488 --- src/sys/kern/vfs_syscalls.c:1.487 Mon Jun 30 17:51:31 2014 +++ src/sys/kern/vfs_syscalls.c Fri Jul 25 08:25:47 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.487 2014/06/30 17:51:31 maxv Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.488 2014/07/25 08:25:47 dholland Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.487 2014/06/30 17:51:31 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.488 2014/07/25 08:25:47 dholland Exp $"); #ifdef _KERNEL_OPT #include "opt_fileassoc.h" @@ -116,6 +116,11 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_syscalls #include <nfs/nfs.h> #include <nfs/nfs_var.h> +/* XXX this shouldn't be here */ +#ifndef OFF_T_MAX +#define OFF_T_MAX __type_max(off_t) +#endif + static int change_flags(struct vnode *, u_long, struct lwp *); static int change_mode(struct vnode *, int, struct lwp *); static int change_owner(struct vnode *, uid_t, gid_t, struct lwp *, int); @@ -4685,3 +4690,105 @@ sys_revoke(struct lwp *l, const struct s vrele(vp); return (error); } + +/* + * Allocate backing store for a file, filling a hole without having to + * explicitly write anything out. + */ +/* ARGSUSED */ +int +sys_posix_fallocate(struct lwp *l, const struct sys_posix_fallocate_args *uap, + register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(off_t) pos; + syscallarg(off_t) len; + } */ + int fd; + off_t pos, len; + struct file *fp; + struct vnode *vp; + int result; + + fd = SCARG(uap, fd); + pos = SCARG(uap, pos); + len = SCARG(uap, len); + + if (pos < 0 || len < 0 || len > OFF_T_MAX - pos) { + return EINVAL; + } + + result = fd_getvnode(fd, &fp); + if (result) { + return result; + } + if ((fp->f_flag & FWRITE) == 0) { + result = EBADF; + goto fail; + } + vp = fp->f_data; + + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + if (vp->v_type == VDIR) { + result = EISDIR; + } else { + result = VOP_FALLOCATE(vp, pos, len); + } + VOP_UNLOCK(vp); + +fail: + fd_putfile(fd); + return result; +} + +/* + * Dellocate backing store for a file, creating a hole. Also used for + * invoking TRIM on disks. + */ +/* ARGSUSED */ +int +sys_fdiscard(struct lwp *l, const struct sys_fdiscard_args *uap, + register_t *retval) +{ + /* { + syscallarg(int) fd; + syscallarg(off_t) pos; + syscallarg(off_t) len; + } */ + int fd; + off_t pos, len; + struct file *fp; + struct vnode *vp; + int result; + + fd = SCARG(uap, fd); + pos = SCARG(uap, pos); + len = SCARG(uap, len); + + if (pos < 0 || len < 0 || len > OFF_T_MAX - pos) { + return EINVAL; + } + + result = fd_getvnode(fd, &fp); + if (result) { + return result; + } + if ((fp->f_flag & FWRITE) == 0) { + result = EBADF; + goto fail; + } + vp = fp->f_data; + + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + if (vp->v_type == VDIR) { + result = EISDIR; + } else { + result = VOP_FDISCARD(vp, pos, len); + } + VOP_UNLOCK(vp); + +fail: + fd_putfile(fd); + return result; +}