From owner-svn-src-all@freebsd.org Mon Aug 19 00:29:05 2019 Return-Path: Delivered-To: svn-src-all@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 B7582D4E1A; Mon, 19 Aug 2019 00:29:05 +0000 (UTC) (envelope-from rmacklem@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) server-signature RSA-PSS (4096 bits) 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 46BZYF4PFbz480D; Mon, 19 Aug 2019 00:29:05 +0000 (UTC) (envelope-from rmacklem@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 75EFBA4A2; Mon, 19 Aug 2019 00:29:05 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x7J0T5Ya063617; Mon, 19 Aug 2019 00:29:05 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x7J0T5R6063616; Mon, 19 Aug 2019 00:29:05 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201908190029.x7J0T5R6063616@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Mon, 19 Aug 2019 00:29:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r351201 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 351201 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Aug 2019 00:29:05 -0000 Author: rmacklem Date: Mon Aug 19 00:29:05 2019 New Revision: 351201 URL: https://svnweb.freebsd.org/changeset/base/351201 Log: Add a vop_stdioctl() that performs a trivial FIOSEEKDATA/FIOSEEKHOLE. Without this patch, when an application performed lseek(SEEK_DATA/SEEK_HOLE) on a file in a file system that does not have its own VOP_IOCTL(), the lseek(2) fails with errno ENOTTY. This didn't seem appropriate, since ENOTTY is not listed as an error return by either the lseek(2) man page nor the POSIX draft for lseek(2). A discussion on freebsd-current@ seemed to indicate that implementing a trivial algorithm that returns the offset argument for FIOSEEKDATA and returns the file's size for FIOSEEKHOLE was the preferred fix. http://docs.FreeBSD.org/cgi/mid.cgi?CAOtMX2iiQdv1+15e1N_r7V6aCx_VqAJCTP1AW+qs3Yg7sPg9wA The Linux kernel appears to implement this trivial algorithm as well. This patch adds a vop_stdioctl() that implements this trivial algorithm. It returns errors consistent with vn_bmap_seekhole() and, as such, will still return ENOTTY for non-regular files. I have proposed a separate patch that maps errors not described by the lseek(2) man page nor POSIX draft to EINVAL. This patch is under separate review. Reviewed by: kib Relnotes: yes Differential Revision: https://reviews.freebsd.org/D21299 Modified: head/sys/kern/vfs_default.c Modified: head/sys/kern/vfs_default.c ============================================================================== --- head/sys/kern/vfs_default.c Sun Aug 18 23:44:23 2019 (r351200) +++ head/sys/kern/vfs_default.c Mon Aug 19 00:29:05 2019 (r351201) @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -86,6 +87,7 @@ static int vop_stdadd_writecount(struct vop_add_writec static int vop_stdcopy_file_range(struct vop_copy_file_range_args *ap); static int vop_stdfdatasync(struct vop_fdatasync_args *ap); static int vop_stdgetpages_async(struct vop_getpages_async_args *ap); +static int vop_stdioctl(struct vop_ioctl_args *ap); /* * This vnode table stores what we want to do if the filesystem doesn't @@ -118,7 +120,7 @@ struct vop_vector default_vnodeops = { .vop_getpages_async = vop_stdgetpages_async, .vop_getwritemount = vop_stdgetwritemount, .vop_inactive = VOP_NULL, - .vop_ioctl = VOP_ENOTTY, + .vop_ioctl = vop_stdioctl, .vop_kqfilter = vop_stdkqfilter, .vop_islocked = vop_stdislocked, .vop_lock1 = vop_stdlock, @@ -1152,6 +1154,41 @@ vop_stdadd_writecount(struct vop_add_writecount_args * error = 0; } VI_UNLOCK(vp); + return (error); +} + +static int +vop_stdioctl(struct vop_ioctl_args *ap) +{ + struct vnode *vp; + struct vattr va; + off_t *offp; + int error; + + switch (ap->a_command) { + case FIOSEEKDATA: + case FIOSEEKHOLE: + vp = ap->a_vp; + error = vn_lock(vp, LK_SHARED); + if (error != 0) + return (EBADF); + if (vp->v_type == VREG) + error = VOP_GETATTR(vp, &va, ap->a_cred); + else + error = ENOTTY; + if (error == 0) { + offp = ap->a_data; + if (*offp < 0 || *offp >= va.va_size) + error = ENXIO; + else if (ap->a_command == FIOSEEKHOLE) + *offp = va.va_size; + } + VOP_UNLOCK(vp, 0); + break; + default: + error = ENOTTY; + break; + } return (error); }