/* * Need to be a bit clever again: the fid is clunked no matter if * the remove succeeds or not. Re-getting a fid would be way too * difficult in case the remove failed for a valid reason (directory * not empty etcetc.). So walk ourselves another fid to prod the * ice with. */ static int noderemove(struct puffs_usermount *pu, struct puffs_node *pn) { AUTOVAR(pu); struct p9pnode *p9n = pn->pn_data; p9pfid_t testfid = NEXTFID(p9p); rv = proto_cc_dupfid(pu, p9n->fid_base, testfid); if (rv) goto out; p9pbuf_put_1(pb, P9PROTO_T_REMOVE); p9pbuf_put_2(pb, tag); p9pbuf_put_4(pb, testfid); /* * XXX: error handling isn't very robust, but doom is impending * anyway, so just accept we're going belly up and play dead */ GETRESPONSE(pb); if (p9pbuf_get_type(pb) != P9PROTO_R_REMOVE) { rv = EPROTO; } else { proto_cc_clunkfid(pu, p9n->fid_base, 0); p9n->fid_base = P9P_INVALFID; puffs_pn_remove(pn); } out: if (rv == 0) puffs_setback(pcc, PUFFS_SETBACK_NOREF_N2); RETURN(rv); }
/*ARGSUSED*/ int puffs_null_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc, puffs_cookie_t targ, const struct puffs_cn *pcn) { struct puffs_node *pn_targ = targ; if (rmdir(PNPATH(pn_targ)) == -1) return errno; puffs_pn_remove(pn_targ); return 0; }