Introduce -c [12], which can be used to open 1 or 2 ssh connections

to the server.  If "2" is specified, a separate connection is used
for data and directory operations.  Using two connections can
significantly increase directory operation performance on a saturated
link, at least up to 30x faster.
This commit is contained in:
pooka 2009-05-20 13:56:36 +00:00
parent 2d212d801f
commit 8ff915319e
6 changed files with 141 additions and 77 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fs.c,v 1.18 2009/02/23 18:43:46 pooka Exp $ */
/* $NetBSD: fs.c,v 1.19 2009/05/20 13:56:36 pooka Exp $ */
/*
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fs.c,v 1.18 2009/02/23 18:43:46 pooka Exp $");
__RCSID("$NetBSD: fs.c,v 1.19 2009/05/20 13:56:36 pooka Exp $");
#endif /* !lint */
#include <err.h>
@ -84,7 +84,7 @@ static const struct extunit {
}};
int
psshfs_handshake(struct puffs_usermount *pu)
psshfs_handshake(struct puffs_usermount *pu, int fd)
{
struct psshfs_ctx *pctx = puffs_getspecific(pu);
struct puffs_framebuf *pb;
@ -100,10 +100,10 @@ psshfs_handshake(struct puffs_usermount *pu)
pb = psbuf_makeout();
psbuf_put_1(pb, SSH_FXP_INIT);
psbuf_put_4(pb, SFTP_PROTOVERSION);
DO_IO(psbuf_write, pu, pb, pctx->sshfd, &done, rv);
DO_IO(psbuf_write, pu, pb, fd, &done, rv);
puffs_framebuf_recycle(pb);
DO_IO(psbuf_read, pu, pb, pctx->sshfd, &done, rv);
DO_IO(psbuf_read, pu, pb, fd, &done, rv);
if (psbuf_get_type(pb) != SSH_FXP_VERSION)
reterr((stderr, "invalid server response: %d",
psbuf_get_type(pb)), EPROTO);
@ -118,7 +118,7 @@ psshfs_handshake(struct puffs_usermount *pu)
break;
if (psbuf_get_str(pb, &val, NULL) != 0)
break;
for (extu = exttable; extu->ext; extu++)
if (strcmp(ext, extu->ext) == 0
&& strcmp(val, extu->val) == 0)
@ -130,10 +130,10 @@ psshfs_handshake(struct puffs_usermount *pu)
psbuf_put_1(pb, SSH_FXP_REALPATH);
psbuf_put_4(pb, NEXTREQ(pctx));
psbuf_put_str(pb, pctx->mountpath);
DO_IO(psbuf_write, pu, pb, pctx->sshfd, &done, rv);
DO_IO(psbuf_write, pu, pb, fd, &done, rv);
puffs_framebuf_recycle(pb);
DO_IO(psbuf_read, pu, pb, pctx->sshfd, &done, rv);
DO_IO(psbuf_read, pu, pb, fd, &done, rv);
if (psbuf_get_type(pb) != SSH_FXP_NAME)
reterr((stderr, "invalid server realpath response for \"%s\"",
pctx->mountpath), EPROTO);
@ -145,10 +145,10 @@ psshfs_handshake(struct puffs_usermount *pu)
/* stat the rootdir so that we know it's a dir */
psbuf_recycleout(pb);
psbuf_req_str(pb, SSH_FXP_LSTAT, NEXTREQ(pctx), rootpath);
DO_IO(psbuf_write, pu, pb, pctx->sshfd, &done, rv);
DO_IO(psbuf_write, pu, pb, fd, &done, rv);
puffs_framebuf_recycle(pb);
DO_IO(psbuf_read, pu, pb, pctx->sshfd, &done, rv);
DO_IO(psbuf_read, pu, pb, fd, &done, rv);
rv = psbuf_expect_attrs(pb, &va);
if (rv)
@ -187,7 +187,7 @@ psshfs_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp)
psbuf_req_str(pb, SSH_FXP_EXTENDED, reqid, "statvfs@openssh.com");
psbuf_put_str(pb, pctx->mountpath);
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
type = psbuf_get_type(pb);
if (type != SSH_FXP_EXTENDED_REPLY) {
@ -222,6 +222,11 @@ psshfs_fs_unmount(struct puffs_usermount *pu, int flags)
kill(pctx->sshpid, SIGTERM);
close(pctx->sshfd);
if (pctx->numconnections == 2) {
kill(pctx->sshpid_data, SIGTERM);
close(pctx->sshfd_data);
}
return 0;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: mount_psshfs.8,v 1.19 2009/02/26 07:14:36 wiz Exp $
.\" $NetBSD: mount_psshfs.8,v 1.20 2009/05/20 13:56:36 pooka Exp $
.\"
.\" Copyright (c) 2007 Antti Kantee. All rights reserved.
.\"
@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd February 25, 2009
.Dd May 20, 2009
.Dt MOUNT_PSSHFS 8
.Os
.Sh NAME
@ -56,6 +56,19 @@ will be used.
The following command line options are available:
.Pp
.Bl -tag -width xxx
.It Fl c Ar nconnect
Opens
.Ar nconnect
connections to the server.
Currently, the value has to be 1 or 2.
If 2 is specified, a second connection is opened for the reading
and writing of data, while directory operations are performed on
their own connection.
This can greatly increase directory operation performance (ls,
mkdir, etc.) if
.Nm
completely saturates the available bandwidth by doing bulk data copying.
The default is 1.
.It Fl e
Makes the mounted file system NFS exportable.
If this option is used, it is very important to understand that

View File

@ -1,4 +1,4 @@
/* $NetBSD: node.c,v 1.56 2009/03/29 16:06:53 pooka Exp $ */
/* $NetBSD: node.c,v 1.57 2009/05/20 13:56:36 pooka Exp $ */
/*
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: node.c,v 1.56 2009/03/29 16:06:53 pooka Exp $");
__RCSID("$NetBSD: node.c,v 1.57 2009/05/20 13:56:36 pooka Exp $");
#endif /* !lint */
#include <assert.h>
@ -148,7 +148,7 @@ psshfs_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc,
}
psbuf_put_vattr(pb, &kludgeva);
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_status(pb);
if (rv == 0)
@ -173,7 +173,7 @@ psshfs_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
psbuf_req_str(pb, SSH_FXP_OPEN, reqid, PCNPATH(pcn));
psbuf_put_4(pb, SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC);
psbuf_put_vattr(pb, va);
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_handle(pb, &fhand, &fhandlen);
if (rv)
goto out;
@ -190,7 +190,7 @@ psshfs_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
struct puffs_framebuf *pb2 = psbuf_makeout();
reqid = NEXTREQ(pctx);
psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn));
JUSTSEND(pb2);
JUSTSEND(pb2, pctx->sshfd);
rv = ENOMEM;
}
@ -200,7 +200,7 @@ psshfs_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
reqid = NEXTREQ(pctx);
psbuf_recycleout(pb);
psbuf_req_data(pb, SSH_FXP_CLOSE, reqid, fhand, fhandlen);
JUSTSEND(pb);
JUSTSEND(pb, pctx->sshfd);
free(fhand);
return rv;
@ -248,7 +248,7 @@ psshfs_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
psbuf_put_4(pb, SSH_FXF_READ);
psbuf_put_vattr(pb, &va);
if (puffs_framev_enqueue_cb(pu, pctx->sshfd, pb,
if (puffs_framev_enqueue_cb(pu, pctx->sshfd_data, pb,
lazyopen_rresp, psn, 0) == -1) {
rv = errno;
puffs_framebuf_destroy(pb);
@ -266,7 +266,7 @@ psshfs_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
psbuf_put_4(pb2, SSH_FXF_WRITE);
psbuf_put_vattr(pb2, &va);
if (puffs_framev_enqueue_cb(pu, pctx->sshfd, pb2,
if (puffs_framev_enqueue_cb(pu, pctx->sshfd_data, pb2,
lazyopen_wresp, psn, 0) == -1) {
rv = errno;
puffs_framebuf_destroy(pb2);
@ -480,7 +480,7 @@ psshfs_node_read(struct puffs_usermount *pu, puffs_cookie_t opc, uint8_t *buf,
puffs_cc_yield(pcc);
}
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd_data);
rv = psbuf_do_data(pb, buf, &readlen);
if (rv == 0)
@ -574,7 +574,7 @@ psshfs_node_write(struct puffs_usermount *pu, puffs_cookie_t opc, uint8_t *buf,
psbuf_req_data(pb, SSH_FXP_WRITE, reqid, psn->fhand_w,psn->fhand_w_len);
psbuf_put_8(pb, offset);
psbuf_put_data(pb, buf, writelen);
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd_data);
rv = psbuf_expect_status(pb);
if (rv == 0)
@ -626,7 +626,7 @@ psshfs_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc,
}
psbuf_req_str(pb, SSH_FXP_READLINK, reqid, PNPATH(pn));
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_name(pb, &count);
if (rv)
@ -662,7 +662,7 @@ doremove(struct puffs_usermount *pu, struct puffs_node *pn_dir,
op = SSH_FXP_REMOVE;
psbuf_req_str(pb, op, reqid, PNPATH(pn));
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_status(pb);
if (rv == 0)
@ -715,7 +715,7 @@ psshfs_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc,
psbuf_req_str(pb, SSH_FXP_MKDIR, reqid, PCNPATH(pcn));
psbuf_put_vattr(pb, va);
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_status(pb);
if (rv)
@ -729,7 +729,7 @@ psshfs_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc,
reqid = NEXTREQ(pctx);
psbuf_recycleout(pb2);
psbuf_req_str(pb2, SSH_FXP_RMDIR, reqid, PCNPATH(pcn));
JUSTSEND(pb2);
JUSTSEND(pb2, pctx->sshfd);
rv = ENOMEM;
}
@ -757,7 +757,7 @@ psshfs_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc,
*/
psbuf_req_str(pb, SSH_FXP_SYMLINK, reqid, link_target);
psbuf_put_str(pb, PCNPATH(pcn));
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_status(pb);
if (rv)
@ -771,7 +771,7 @@ psshfs_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc,
reqid = NEXTREQ(pctx);
psbuf_recycleout(pb2);
psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn));
JUSTSEND(pb2);
JUSTSEND(pb2, pctx->sshfd);
rv = ENOMEM;
}
@ -804,7 +804,7 @@ psshfs_node_rename(struct puffs_usermount *pu, puffs_cookie_t opc,
psbuf_req_str(pb, SSH_FXP_RENAME, reqid, PCNPATH(pcn_src));
psbuf_put_str(pb, PCNPATH(pcn_targ));
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_status(pb);
if (rv == 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: psshfs.c,v 1.50 2009/02/23 18:43:46 pooka Exp $ */
/* $NetBSD: psshfs.c,v 1.51 2009/05/20 13:56:36 pooka Exp $ */
/*
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
@ -41,7 +41,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: psshfs.c,v 1.50 2009/02/23 18:43:46 pooka Exp $");
__RCSID("$NetBSD: psshfs.c,v 1.51 2009/05/20 13:56:36 pooka Exp $");
#endif /* !lint */
#include <sys/types.h>
@ -60,7 +60,7 @@ __RCSID("$NetBSD: psshfs.c,v 1.50 2009/02/23 18:43:46 pooka Exp $");
#include "psshfs.h"
static int pssh_connect(struct psshfs_ctx *);
static int pssh_connect(struct puffs_usermount *, int);
static void psshfs_loopfn(struct puffs_usermount *);
static void usage(void);
static void add_ssharg(char ***, int *, char *);
@ -87,7 +87,7 @@ usage()
{
fprintf(stderr, "usage: %s "
"[-es] [-F configfile] [-O sshopt=value] [-o opts] "
"[-ceprst] [-F configfile] [-O sshopt=value] [-o opts] "
"user@host:path mountpath\n",
getprogname());
exit(1);
@ -116,8 +116,8 @@ main(int argc, char *argv[])
char *hostpath;
int mntflags, pflags, ch;
int detach;
int exportfs, refreshival;
int nargs, x;
int exportfs, refreshival, numconnections;
int nargs;
setprogname(argv[0]);
@ -125,6 +125,7 @@ main(int argc, char *argv[])
usage();
mntflags = pflags = exportfs = nargs = 0;
numconnections = 1;
detach = 1;
refreshival = DEFAULTREFRESH;
notfn = puffs_framev_unmountonclose;
@ -133,8 +134,17 @@ main(int argc, char *argv[])
add_ssharg(&sshargs, &nargs, "-axs");
add_ssharg(&sshargs, &nargs, "-oClearAllForwardings=yes");
while ((ch = getopt(argc, argv, "eF:o:O:pr:st:")) != -1) {
while ((ch = getopt(argc, argv, "c:eF:o:O:pr:st:")) != -1) {
switch (ch) {
case 'c':
numconnections = atoi(optarg);
if (numconnections < 1 || numconnections > 2) {
fprintf(stderr, "%s: only 1 or 2 connections "
"permitted currently\n", getprogname());
usage();
/*NOTREACHED*/
}
break;
case 'e':
exportfs = 1;
break;
@ -214,6 +224,7 @@ main(int argc, char *argv[])
memset(&pctx, 0, sizeof(pctx));
pctx.mounttime = time(NULL);
pctx.refreshival = refreshival;
pctx.numconnections = numconnections;
userhost = argv[0];
hostpath = strchr(userhost, ':');
@ -234,26 +245,29 @@ main(int argc, char *argv[])
return errno;
puffs_setroot(pu, pn_root);
puffs_framev_init(pu, psbuf_read, psbuf_write, psbuf_cmp, NULL, notfn);
signal(SIGHUP, takehup);
puffs_ml_setloopfn(pu, psshfs_loopfn);
if (pssh_connect(&pctx) == -1)
err(1, "can't connect");
if (pssh_connect(pu, PSSHFD_META) == -1)
err(1, "can't connect meta");
if (puffs_framev_addfd(pu, pctx.sshfd,
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
err(1, "framebuf addfd meta");
if (numconnections == 2) {
if (pssh_connect(pu, PSSHFD_DATA) == -1)
err(1, "can't connect data");
if (puffs_framev_addfd(pu, pctx.sshfd_data,
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
err(1, "framebuf addfd data");
} else {
pctx.sshfd_data = pctx.sshfd;
}
if (exportfs)
puffs_setfhsize(pu, sizeof(struct psshfs_fid),
PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3);
if (psshfs_handshake(pu) != 0)
errx(1, "psshfs_handshake");
x = 1;
if (ioctl(pctx.sshfd, FIONBIO, &x) == -1)
err(1, "nonblocking descriptor");
puffs_framev_init(pu, psbuf_read, psbuf_write, psbuf_cmp, NULL, notfn);
if (puffs_framev_addfd(pu, pctx.sshfd,
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
err(1, "framebuf addfd");
rva = &pn_root->pn_va;
rva->va_fileid = pctx.nextino++;
rva->va_nlink = 101; /* XXX */
@ -280,36 +294,43 @@ void
psshfs_notify(struct puffs_usermount *pu, int fd, int what)
{
struct psshfs_ctx *pctx = puffs_getspecific(pu);
int x, nretry;
int x, nretry, which, newfd;
if (fd == pctx->sshfd) {
which = PSSHFD_META;
} else {
assert(fd == pctx->sshfd_data);
which = PSSHFD_DATA;
}
if (puffs_getstate(pu) != PUFFS_STATE_RUNNING)
return;
if (what != (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) {
puffs_framev_removefd(pu, pctx->sshfd, ECONNRESET);
puffs_framev_removefd(pu, fd, ECONNRESET);
return;
}
close(pctx->sshfd);
close(fd);
for (nretry = 0;;nretry++) {
if (pssh_connect(pctx) == -1)
if ((newfd = pssh_connect(pu, which)) == -1)
goto retry2;
if (psshfs_handshake(pu) != 0)
if (psshfs_handshake(pu, newfd) != 0)
goto retry1;
x = 1;
if (ioctl(pctx->sshfd, FIONBIO, &x) == -1)
if (ioctl(newfd, FIONBIO, &x) == -1)
goto retry1;
if (puffs_framev_addfd(pu, pctx->sshfd,
if (puffs_framev_addfd(pu, newfd,
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
goto retry1;
break;
retry1:
fprintf(stderr, "reconnect failed... ");
close(pctx->sshfd);
close(newfd);
retry2:
if (nretry < RETRY_MAX) {
fprintf(stderr, "retrying\n");
@ -322,12 +343,24 @@ psshfs_notify(struct puffs_usermount *pu, int fd, int what)
}
static int
pssh_connect(struct psshfs_ctx *pctx)
pssh_connect(struct puffs_usermount *pu, int which)
{
struct psshfs_ctx *pctx = puffs_getspecific(pu);
char **sshargs = pctx->sshargs;
int fds[2];
pid_t pid;
int dnfd;
int dnfd, x;
int *sshfd;
pid_t *sshpid;
if (which == PSSHFD_META) {
sshfd = &pctx->sshfd;
sshpid = &pctx->sshpid;
} else {
assert(which == PSSHFD_DATA);
sshfd = &pctx->sshfd_data;
sshpid = &pctx->sshpid_data;
}
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1)
return -1;
@ -350,15 +383,22 @@ pssh_connect(struct psshfs_ctx *pctx)
dup2(dnfd, STDERR_FILENO);
execvp(sshargs[0], sshargs);
/*NOTREACHED*/
break;
default:
pctx->sshpid = pid;
pctx->sshfd = fds[1];
*sshpid = pid;
*sshfd = fds[1];
close(fds[0]);
break;
}
return 0;
if (psshfs_handshake(pu, *sshfd) != 0)
errx(1, "psshfs_handshake %d", which);
x = 1;
if (ioctl(*sshfd, FIONBIO, &x) == -1)
err(1, "nonblocking descriptor %d", which);
return *sshfd;
}
static void *

View File

@ -1,4 +1,4 @@
/* $NetBSD: psshfs.h,v 1.35 2009/02/23 18:43:46 pooka Exp $ */
/* $NetBSD: psshfs.h,v 1.36 2009/05/20 13:56:36 pooka Exp $ */
/*
* Copyright (c) 2006, 2007 Antti Kantee. All Rights Reserved.
@ -65,25 +65,25 @@ PUFFSOP_PROTOS(psshfs);
puffs_framebuf_destroy(pb); \
return (rv)
#define GETRESPONSE(pb) \
#define GETRESPONSE(pb, fd) \
do { \
if (puffs_framev_enqueue_cc(pcc, pctx->sshfd, pb, 0) == -1) { \
if (puffs_framev_enqueue_cc(pcc, fd, pb, 0) == -1) { \
rv = errno; \
goto out; \
} \
} while (/*CONSTCOND*/0)
#define JUSTSEND(pb) \
#define JUSTSEND(pb,fd) \
do { \
if (puffs_framev_enqueue_justsend(pu,pctx->sshfd,pb,1,0) == -1){\
if (puffs_framev_enqueue_justsend(pu, fd, pb, 1, 0) == -1) { \
rv = errno; \
goto out; \
} \
} while (/*CONSTCOND*/0)
#define SENDCB(pb, f, a) \
#define SENDCB(pb, fd, f, a) \
do { \
if (puffs_framev_enqueue_cb(pu, pctx->sshfd, pb,f,a,0) == -1) { \
if (puffs_framev_enqueue_cb(pu, fd, pb, f, a, 0) == -1) { \
rv = errno; \
goto out; \
} \
@ -153,8 +153,12 @@ struct psshfs_node {
#define HANDLE_WRITE 0x2
struct psshfs_ctx {
int numconnections;
int sshfd;
int sshfd_data;
pid_t sshpid;
pid_t sshpid_data;
const char *mountpath;
char **sshargs;
@ -173,8 +177,10 @@ struct psshfs_ctx {
int refreshival;
};
#define PSSHFD_META 0
#define PSSHFD_DATA 1
int psshfs_handshake(struct puffs_usermount *);
int psshfs_handshake(struct puffs_usermount *, int);
int psbuf_read(struct puffs_usermount *, struct puffs_framebuf *,int,int*);
int psbuf_write(struct puffs_usermount *, struct puffs_framebuf *,int,int*);

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr.c,v 1.45 2007/12/13 14:59:00 pooka Exp $ */
/* $NetBSD: subr.c,v 1.46 2009/05/20 13:56:36 pooka Exp $ */
/*
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
@ -27,7 +27,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: subr.c,v 1.45 2007/12/13 14:59:00 pooka Exp $");
__RCSID("$NetBSD: subr.c,v 1.46 2009/05/20 13:56:36 pooka Exp $");
#endif /* !lint */
#include <assert.h>
@ -134,7 +134,7 @@ closehandles(struct puffs_usermount *pu, struct psshfs_node *psn, int which)
reqid = NEXTREQ(pctx);
psbuf_req_data(pb1, SSH_FXP_CLOSE, reqid,
psn->fhand_r, psn->fhand_r_len);
puffs_framev_enqueue_justsend(pu, pctx->sshfd, pb1, 1, 0);
puffs_framev_enqueue_justsend(pu, pctx->sshfd_data, pb1, 1, 0);
free(psn->fhand_r);
psn->fhand_r = NULL;
}
@ -146,7 +146,7 @@ closehandles(struct puffs_usermount *pu, struct psshfs_node *psn, int which)
reqid = NEXTREQ(pctx);
psbuf_req_data(pb2, SSH_FXP_CLOSE, reqid,
psn->fhand_w, psn->fhand_w_len);
puffs_framev_enqueue_justsend(pu, pctx->sshfd, pb2, 1, 0);
puffs_framev_enqueue_justsend(pu, pctx->sshfd_data, pb2, 1, 0);
free(psn->fhand_w);
psn->fhand_w = NULL;
}
@ -220,7 +220,7 @@ getpathattr(struct puffs_usermount *pu, const char *path, struct vattr *vap)
PSSHFSAUTOVAR(pu);
psbuf_req_str(pb, SSH_FXP_LSTAT, reqid, path);
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
rv = psbuf_expect_attrs(pb, vap);
@ -307,7 +307,7 @@ sftp_readdir(struct puffs_usermount *pu, struct psshfs_ctx *pctx,
reqid = NEXTREQ(pctx);
psbuf_recycleout(pb);
psbuf_req_data(pb, SSH_FXP_READDIR, reqid, dhand, dhandlen);
GETRESPONSE(pb);
GETRESPONSE(pb, pctx->sshfd);
/* check for EOF */
if (psbuf_get_type(pb) == SSH_FXP_STATUS) {