Source-Changes-HG archive

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

[src/trunk]: src Cache vattr in psshfs's setattr.



details:   https://anonhg.NetBSD.org/src/rev/d782836cb18b
branches:  trunk
changeset: 768218:d782836cb18b
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Fri Aug 12 04:14:00 2011 +0000

description:
Cache vattr in psshfs's setattr.

This means within the cache window, a setattr that wouldn't change the
remote file's attributes from our current view of them will not be
relayed to the server and wait for the server to answer.  Thus, e.g., a
process with a periodic timer interrupt that calls open(2) in a loop
can make progress with much higher probability than without caching.

XXX The test case doesn't work, so it's currently disabled.  It needs
to stop the child of sshd that is handling an sftp session, not sshd
itself, and it's not obvious how to do that.

ok pooka

diffstat:

 tests/fs/psshfs/t_psshfs.sh        |  30 +++++++++++++++++-
 usr.sbin/puffs/mount_psshfs/node.c |  63 ++++++++++++++++++++++++++++++++++---
 2 files changed, 86 insertions(+), 7 deletions(-)

diffs (149 lines):

diff -r b759f87db709 -r d782836cb18b tests/fs/psshfs/t_psshfs.sh
--- a/tests/fs/psshfs/t_psshfs.sh       Fri Aug 12 03:59:44 2011 +0000
+++ b/tests/fs/psshfs/t_psshfs.sh       Fri Aug 12 04:14:00 2011 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: t_psshfs.sh,v 1.5 2011/03/31 12:56:03 pooka Exp $
+# $NetBSD: t_psshfs.sh,v 1.6 2011/08/12 04:14:00 riastradh Exp $
 #
 # Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -235,6 +235,33 @@
        stop_ssh
 }
 
+atf_test_case setattr_cache cleanup
+setattr_cache_head() {
+       atf_set "descr" "Checks that setattr caches"
+       # Don't wait for the eternity that atf usually waits.  Twenty
+       # seconds should be good enough, except maybe on a VAX...
+       atf_set "timeout" 20
+}
+setattr_cache_body() {
+       require_puffs
+       start_ssh
+       atf_check -s exit:0 mkdir root
+       atf_check -s exit:0 mkdir mnt
+       mount_psshfs root mnt
+       atf_check -s exit:0 -x ': > mnt/loser'
+       atf_check -s exit:0 -o save:stat stat mnt/loser
+       # Oops -- this doesn't work.  We need to stop the child of the
+       # sshd that is handling the sftp session.
+       atf_check -s exit:0 kill -STOP $(cat sshd.pid)
+       atf_check -s exit:0 -x ': > mnt/loser'
+       atf_check -s exit:0 -o file:stat stat mnt/loser
+}
+setattr_cache_cleanup() {
+       umount mnt
+       kill -CONT $(cat sshd.pid)
+       stop_ssh
+}
+
 # -------------------------------------------------------------------------
 # Initialization.
 # -------------------------------------------------------------------------
@@ -243,4 +270,5 @@
        atf_add_test_case inode_nos
        atf_add_test_case pwd
        atf_add_test_case ls
+       #atf_add_test_case setattr_cache
 }
diff -r b759f87db709 -r d782836cb18b usr.sbin/puffs/mount_psshfs/node.c
--- a/usr.sbin/puffs/mount_psshfs/node.c        Fri Aug 12 03:59:44 2011 +0000
+++ b/usr.sbin/puffs/mount_psshfs/node.c        Fri Aug 12 04:14:00 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: node.c,v 1.62 2010/10/29 16:13:51 pooka Exp $  */
+/*     $NetBSD: node.c,v 1.63 2011/08/12 04:14:00 riastradh Exp $      */
 
 /*
  * Copyright (c) 2006-2009  Antti Kantee.  All Rights Reserved.
@@ -27,7 +27,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: node.c,v 1.62 2010/10/29 16:13:51 pooka Exp $");
+__RCSID("$NetBSD: node.c,v 1.63 2011/08/12 04:14:00 riastradh Exp $");
 #endif /* !lint */
 
 #include <assert.h>
@@ -133,9 +133,57 @@
 psshfs_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc,
        const struct vattr *va, const struct puffs_cred *pcr)
 {
-       PSSHFSAUTOVAR(pu);
+       struct puffs_cc *pcc = puffs_cc_getcc(pu);
+       struct psshfs_ctx *pctx = puffs_getspecific(pu);
+       uint32_t reqid;
+       struct puffs_framebuf *pb;
        struct vattr kludgeva;
        struct puffs_node *pn = opc;
+       struct psshfs_node *psn = pn->pn_data;
+       int rv;
+
+       /*
+        * If we cached the remote attributes recently enough, and this
+        * setattr operation would change nothing that sftp actually
+        * records, then we can skip the sftp request.  So first check
+        * whether we have the attributes cached, and then compare
+        * every field that we might send to the sftp server.
+        */
+
+       if (!psn->attrread || REFRESHTIMEOUT(pctx, time(NULL)-psn->attrread))
+               goto setattr;
+
+#define CHECK(FIELD, TYPE) do {                                                \
+       if ((va->FIELD != (TYPE)PUFFS_VNOVAL) &&                        \
+           (va->FIELD != pn->pn_va.FIELD))                             \
+               goto setattr;                                           \
+} while (0)
+
+#define CHECKID(FIELD, TYPE, DOMANGLE, MINE, MANGLED) do {             \
+       if ((va->FIELD != (TYPE)PUFFS_VNOVAL) &&                        \
+           (pn->pn_va.FIELD !=                                         \
+               ((pctx->DOMANGLE && (va->FIELD == pctx->MINE))          \
+                   ? pctx->MANGLED                                     \
+                   : va->FIELD)))                                      \
+               goto setattr;                                           \
+} while (0)
+
+       CHECK(va_size, uint64_t);
+       CHECKID(va_uid, uid_t, domangleuid, myuid, mangleuid);
+       CHECKID(va_gid, gid_t, domanglegid, mygid, manglegid);
+       CHECK(va_mode, mode_t);
+       CHECK(va_atime.tv_sec, time_t);
+       CHECK(va_mtime.tv_sec, time_t);
+
+       /* Nothing to change.  */
+       return 0;
+
+#undef CHECK
+#undef CHECKID
+
+ setattr:
+       reqid = NEXTREQ(pctx);
+       pb = psbuf_makeout();
 
        psbuf_req_str(pb, SSH_FXP_SETSTAT, reqid, PNPATH(pn));
 
@@ -156,16 +204,19 @@
                else
                        kludgeva.va_atime.tv_sec = va->va_mtime.tv_sec;
        }
-                       
+
        psbuf_put_vattr(pb, &kludgeva, pctx);
        GETRESPONSE(pb, pctx->sshfd);
 
        rv = psbuf_expect_status(pb);
-       if (rv == 0)
+       if (rv == 0) {
                puffs_setvattr(&pn->pn_va, &kludgeva);
+               psn->attrread = time(NULL);
+       }
 
  out:
-       PSSHFSRETURN(rv);
+       puffs_framebuf_destroy(pb);
+       return rv;
 }
 
 int



Home | Main Index | Thread Index | Old Index