Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Dec 2017 18:20:38 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r326986 - in head/sys: fs/fdescfs kern sys
Message-ID:  <201712191820.vBJIKcPB045388@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Tue Dec 19 18:20:38 2017
New Revision: 326986
URL: https://svnweb.freebsd.org/changeset/base/326986

Log:
  Add a custom VOP_PATHCONF method for fdescfs.
  
  The method handles NAME_MAX and LINK_MAX explicitly.  For all other
  pathconf variables, the method passes the request down to the underlying
  file descriptor.  This requires splitting a kern_fpathconf() syscallsubr
  routine out of sys_fpathconf().  Also, to avoid lock order reversals with
  vnode locks, the fdescfs vnode is unlocked around the call to
  kern_fpathconf(), but with the usecount of the vnode bumped.
  
  MFC after:	1 month
  Sponsored by:	Chelsio Communications

Modified:
  head/sys/fs/fdescfs/fdesc_vnops.c
  head/sys/kern/kern_descrip.c
  head/sys/sys/syscallsubr.h

Modified: head/sys/fs/fdescfs/fdesc_vnops.c
==============================================================================
--- head/sys/fs/fdescfs/fdesc_vnops.c	Tue Dec 19 18:12:18 2017	(r326985)
+++ head/sys/fs/fdescfs/fdesc_vnops.c	Tue Dec 19 18:20:38 2017	(r326986)
@@ -55,6 +55,8 @@
 #include <sys/namei.h>
 #include <sys/proc.h>
 #include <sys/stat.h>
+#include <sys/syscallsubr.h>
+#include <sys/unistd.h>
 #include <sys/vnode.h>
 
 #include <fs/fdescfs/fdesc.h>
@@ -70,6 +72,7 @@ struct mtx fdesc_hashmtx;
 static vop_getattr_t	fdesc_getattr;
 static vop_lookup_t	fdesc_lookup;
 static vop_open_t	fdesc_open;
+static vop_pathconf_t	fdesc_pathconf;
 static vop_readdir_t	fdesc_readdir;
 static vop_readlink_t	fdesc_readlink;
 static vop_reclaim_t	fdesc_reclaim;
@@ -82,7 +85,7 @@ static struct vop_vector fdesc_vnodeops = {
 	.vop_getattr =		fdesc_getattr,
 	.vop_lookup =		fdesc_lookup,
 	.vop_open =		fdesc_open,
-	.vop_pathconf =		vop_stdpathconf,
+	.vop_pathconf =		fdesc_pathconf,
 	.vop_readdir =		fdesc_readdir,
 	.vop_readlink =		fdesc_readlink,
 	.vop_reclaim =		fdesc_reclaim,
@@ -393,6 +396,33 @@ fdesc_open(struct vop_open_args *ap)
 	 */
 	ap->a_td->td_dupfd = VTOFDESC(vp)->fd_fd;	/* XXX */
 	return (ENODEV);
+}
+
+static int
+fdesc_pathconf(struct vop_pathconf_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	int error;
+
+	switch (ap->a_name) {
+	case _PC_NAME_MAX:
+		*ap->a_retval = NAME_MAX;
+		return (0);
+	case _PC_LINK_MAX:
+		if (VTOFDESC(vp)->fd_type == Froot)
+			*ap->a_retval = 2;
+		else
+			*ap->a_retval = 1;
+		return (0);
+	default:
+		vref(vp);
+		VOP_UNLOCK(vp, 0);
+		error = kern_fpathconf(curthread, VTOFDESC(vp)->fd_fd,
+		    ap->a_name);
+		vn_lock(vp, LK_SHARED | LK_RETRY);
+		vunref(vp);
+		return (error);
+	}
 }
 
 static int

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Tue Dec 19 18:12:18 2017	(r326985)
+++ head/sys/kern/kern_descrip.c	Tue Dec 19 18:20:38 2017	(r326986)
@@ -1418,26 +1418,33 @@ struct fpathconf_args {
 int
 sys_fpathconf(struct thread *td, struct fpathconf_args *uap)
 {
+
+	return (kern_fpathconf(td, uap->fd, uap->name));
+}
+
+int
+kern_fpathconf(struct thread *td, int fd, int name)
+{
 	struct file *fp;
 	struct vnode *vp;
 	cap_rights_t rights;
 	int error;
 
-	error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FPATHCONF), &fp);
+	error = fget(td, fd, cap_rights_init(&rights, CAP_FPATHCONF), &fp);
 	if (error != 0)
 		return (error);
 
-	if (uap->name == _PC_ASYNC_IO) {
+	if (name == _PC_ASYNC_IO) {
 		td->td_retval[0] = _POSIX_ASYNCHRONOUS_IO;
 		goto out;
 	}
 	vp = fp->f_vnode;
 	if (vp != NULL) {
 		vn_lock(vp, LK_SHARED | LK_RETRY);
-		error = VOP_PATHCONF(vp, uap->name, td->td_retval);
+		error = VOP_PATHCONF(vp, name, td->td_retval);
 		VOP_UNLOCK(vp, 0);
 	} else if (fp->f_type == DTYPE_PIPE || fp->f_type == DTYPE_SOCKET) {
-		if (uap->name != _PC_PIPE_BUF) {
+		if (name != _PC_PIPE_BUF) {
 			error = EINVAL;
 		} else {
 			td->td_retval[0] = PIPE_BUF;

Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h	Tue Dec 19 18:12:18 2017	(r326985)
+++ head/sys/sys/syscallsubr.h	Tue Dec 19 18:20:38 2017	(r326986)
@@ -111,6 +111,7 @@ int	kern_fcntl(struct thread *td, int fd, int cmd, int
 int	kern_fcntl_freebsd(struct thread *td, int fd, int cmd, long arg);
 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);
 int	kern_fstat(struct thread *td, int fd, struct stat *sbp);
 int	kern_fstatfs(struct thread *td, int fd, struct statfs *buf);
 int	kern_fsync(struct thread *td, int fd, bool fullsync);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712191820.vBJIKcPB045388>