Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Add fdiscard and posix_fallocate syscalls.



details:   https://anonhg.NetBSD.org/src/rev/af2ab34e2fbd
branches:  trunk
changeset: 330911:af2ab34e2fbd
user:      dholland <dholland%NetBSD.org@localhost>
date:      Fri Jul 25 08:25:47 2014 +0000

description:
Add fdiscard and posix_fallocate syscalls.

diffstat:

 sys/kern/syscalls.master |    6 ++-
 sys/kern/vfs_syscalls.c  |  111 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 114 insertions(+), 3 deletions(-)

diffs (153 lines):

diff -r c4d2b9d426e8 -r af2ab34e2fbd sys/kern/syscalls.master
--- a/sys/kern/syscalls.master  Fri Jul 25 08:24:31 2014 +0000
+++ b/sys/kern/syscalls.master  Fri Jul 25 08:25:47 2014 +0000
@@ -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); }
diff -r c4d2b9d426e8 -r af2ab34e2fbd sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c   Fri Jul 25 08:24:31 2014 +0000
+++ b/sys/kern/vfs_syscalls.c   Fri Jul 25 08:25:47 2014 +0000
@@ -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 @@
 #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 @@
        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;
+}



Home | Main Index | Thread Index | Old Index