svn commit: r326986 - in head/sys: fs/fdescfs kern sys
John Baldwin
jhb at FreeBSD.org
Tue Dec 19 18:20:40 UTC 2017
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);
More information about the svn-src-head
mailing list