From 9ec31d4b95fb29bb24ebcdfd2fc78bca1ecf0335 Mon Sep 17 00:00:00 2001 From: pooka Date: Mon, 16 Jul 2007 09:36:06 +0000 Subject: If the target node exists in rename, do not try to issue a setback to signal no references, as that is not currently supported for node_rename(). The removed node will not immediately be reclaimed, but we can live with that for now. While here, factor the removal code a bit to share with remove and rmdir. fixes PR kern/36637 by reinoud --- usr.sbin/puffs/mount_psshfs/node.c | 82 +++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 37 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/puffs/mount_psshfs/node.c b/usr.sbin/puffs/mount_psshfs/node.c index 3ad2f18f27b..bb2a8310e5b 100644 --- a/usr.sbin/puffs/mount_psshfs/node.c +++ b/usr.sbin/puffs/mount_psshfs/node.c @@ -1,4 +1,4 @@ -/* $NetBSD: node.c,v 1.33 2007/07/02 10:26:50 pooka Exp $ */ +/* $NetBSD: node.c,v 1.34 2007/07/16 09:36:06 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -27,7 +27,7 @@ #include #ifndef lint -__RCSID("$NetBSD: node.c,v 1.33 2007/07/02 10:26:50 pooka Exp $"); +__RCSID("$NetBSD: node.c,v 1.34 2007/07/16 09:36:06 pooka Exp $"); #endif /* !lint */ #include @@ -402,30 +402,59 @@ psshfs_node_readlink(struct puffs_cc *pcc, void *opc, PSSHFSRETURN(rv); } +static int +doremove(struct puffs_cc *pcc, struct puffs_node *pn_dir, + struct puffs_node *pn, const char *name) +{ + PSSHFSAUTOVAR(pcc); + int op; + + if (pn->pn_va.va_type == VDIR) + op = SSH_FXP_RMDIR; + else + op = SSH_FXP_REMOVE; + + psbuf_req_str(pb, op, reqid, PNPATH(pn)); + GETRESPONSE(pb); + + rv = psbuf_expect_status(pb); + if (rv == 0) + nukenode(pn, name, 0); + + out: + PSSHFSRETURN(rv); +} + int psshfs_node_remove(struct puffs_cc *pcc, void *opc, void *targ, const struct puffs_cn *pcn) { - PSSHFSAUTOVAR(pcc); struct puffs_node *pn_targ = targ; + int rv; - if (pn_targ->pn_va.va_type == VDIR) { - rv = EPERM; - goto out; - } + assert(pn_targ->pn_va.va_type != VDIR); - psbuf_req_str(pb, SSH_FXP_REMOVE, reqid, PNPATH(pn_targ)); - GETRESPONSE(pb); + rv = doremove(pcc, opc, targ, pcn->pcn_name); + if (rv == 0) + puffs_setback(pcc, PUFFS_SETBACK_NOREF_N2); - rv = psbuf_expect_status(pb); + return rv; +} - if (rv == 0) { - nukenode(pn_targ, pcn->pcn_name, 0); +int +psshfs_node_rmdir(struct puffs_cc *pcc, void *opc, void *targ, + const struct puffs_cn *pcn) +{ + struct puffs_node *pn_targ = targ; + int rv; + + assert(pn_targ->pn_va.va_type == VDIR); + + rv = doremove(pcc, opc, targ, pcn->pcn_name); + if (rv == 0) puffs_setback(pcc, PUFFS_SETBACK_NOREF_N2); - } - out: - PSSHFSRETURN(rv); + return rv; } int @@ -458,26 +487,6 @@ psshfs_node_mkdir(struct puffs_cc *pcc, void *opc, struct puffs_newinfo *pni, PSSHFSRETURN(rv); } -int -psshfs_node_rmdir(struct puffs_cc *pcc, void *opc, void *targ, - const struct puffs_cn *pcn) -{ - PSSHFSAUTOVAR(pcc); - struct puffs_node *pn_targ = targ; - - psbuf_req_str(pb, SSH_FXP_RMDIR, reqid, PNPATH(pn_targ)); - GETRESPONSE(pb); - - rv = psbuf_expect_status(pb); - if (rv == 0) { - nukenode(pn_targ, pcn->pcn_name, 0); - puffs_setback(pcc, PUFFS_SETBACK_NOREF_N2); - } - - out: - PSSHFSRETURN(rv); -} - int psshfs_node_symlink(struct puffs_cc *pcc, void *opc, struct puffs_newinfo *pni, const struct puffs_cn *pcn, const struct vattr *va, @@ -533,8 +542,7 @@ psshfs_node_rename(struct puffs_cc *pcc, void *opc, void *src, } if (pn_tf) { - /* XXX: no backend implementation for now, so call directly */ - rv = psshfs_node_remove(pcc, targ_dir, pn_tf, pcn_targ); + rv = doremove(pcc, targ_dir, pn_tf, pcn_targ->pcn_name); if (rv) goto out; } -- cgit