| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ops.c,v 1.50 2012/01/29 06:22:02 manu Exp $ */ | | 1 | /* $NetBSD: ops.c,v 1.51 2012/03/08 14:58:57 manu Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. | | 4 | * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -504,26 +504,27 @@ node_lookup_common(pu, opc, path, pcr, p | | | @@ -504,26 +504,27 @@ node_lookup_common(pu, opc, path, pcr, p |
504 | "cookie = %p, nodeid = 0x%"PRIx64" " | | 504 | "cookie = %p, nodeid = 0x%"PRIx64" " |
505 | "for \"%s\"\n", __func__, | | 505 | "for \"%s\"\n", __func__, |
506 | (void *)opc, perfuse_node_path(opc), | | 506 | (void *)opc, perfuse_node_path(opc), |
507 | (void *)oldpnd->pnd_pn, oldpnd->pnd_nodeid, | | 507 | (void *)oldpnd->pnd_pn, oldpnd->pnd_nodeid, |
508 | path); | | 508 | path); |
509 | #endif | | 509 | #endif |
510 | break; | | 510 | break; |
511 | } | | 511 | } |
512 | | | 512 | |
513 | /* | | 513 | /* |
514 | * Check for cached name | | 514 | * Check for cached name |
515 | */ | | 515 | */ |
516 | if ((oldpnd != NULL) && !entry_expired(oldpnd->pnd_pn)) { | | 516 | if ((oldpnd != NULL) && !entry_expired(oldpnd->pnd_pn)) { |
| | | 517 | oldpnd->pnd_puffs_nlookup++; |
517 | *pnp = oldpnd->pnd_pn; | | 518 | *pnp = oldpnd->pnd_pn; |
518 | return 0; | | 519 | return 0; |
519 | } | | 520 | } |
520 | | | 521 | |
521 | len = strlen(path) + 1; | | 522 | len = strlen(path) + 1; |
522 | | | 523 | |
523 | pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, pcr); | | 524 | pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, pcr); |
524 | (void)strlcpy(_GET_INPAYLOAD(ps, pm, char *), path, len); | | 525 | (void)strlcpy(_GET_INPAYLOAD(ps, pm, char *), path, len); |
525 | | | 526 | |
526 | error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply); | | 527 | error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply); |
527 | | | 528 | |
528 | switch (error) { | | 529 | switch (error) { |
529 | case 0: | | 530 | case 0: |
| @@ -540,27 +541,28 @@ node_lookup_common(pu, opc, path, pcr, p | | | @@ -540,27 +541,28 @@ node_lookup_common(pu, opc, path, pcr, p |
540 | #endif | | 541 | #endif |
541 | } | | 542 | } |
542 | /* FALLTHROUGH */ | | 543 | /* FALLTHROUGH */ |
543 | default: | | 544 | default: |
544 | return error; | | 545 | return error; |
545 | /* NOTREACHED */ | | 546 | /* NOTREACHED */ |
546 | break; | | 547 | break; |
547 | } | | 548 | } |
548 | | | 549 | |
549 | feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out); | | 550 | feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out); |
550 | | | 551 | |
551 | if (oldpnd != NULL) { | | 552 | if (oldpnd != NULL) { |
552 | if (oldpnd->pnd_nodeid == feo->nodeid) { | | 553 | if (oldpnd->pnd_nodeid == feo->nodeid) { |
553 | oldpnd->pnd_nlookup++; | | 554 | oldpnd->pnd_fuse_nlookup++; |
| | | 555 | oldpnd->pnd_puffs_nlookup++; |
554 | *pnp = oldpnd->pnd_pn; | | 556 | *pnp = oldpnd->pnd_pn; |
555 | | | 557 | |
556 | ps->ps_destroy_msg(pm); | | 558 | ps->ps_destroy_msg(pm); |
557 | return 0; | | 559 | return 0; |
558 | } else { | | 560 | } else { |
559 | oldpnd->pnd_flags |= PND_REMOVED; | | 561 | oldpnd->pnd_flags |= PND_REMOVED; |
560 | #ifdef PERFUSE_DEBUG | | 562 | #ifdef PERFUSE_DEBUG |
561 | if (perfuse_diagflags & PDF_FILENAME) | | 563 | if (perfuse_diagflags & PDF_FILENAME) |
562 | DPRINTF("%s: opc = %p nodeid = 0x%"PRIx64" " | | 564 | DPRINTF("%s: opc = %p nodeid = 0x%"PRIx64" " |
563 | "file = \"%s\" replaced\n", __func__, | | 565 | "file = \"%s\" replaced\n", __func__, |
564 | oldpnd->pnd_pn, oldpnd->pnd_nodeid, | | 566 | oldpnd->pnd_pn, oldpnd->pnd_nodeid, |
565 | oldpnd->pnd_name); | | 567 | oldpnd->pnd_name); |
566 | #endif | | 568 | #endif |
| @@ -2692,83 +2694,84 @@ perfuse_node_reclaim(pu, opc) | | | @@ -2692,83 +2694,84 @@ perfuse_node_reclaim(pu, opc) |
2692 | struct puffs_node *pn; | | 2694 | struct puffs_node *pn; |
2693 | struct puffs_node *pn_root; | | 2695 | struct puffs_node *pn_root; |
2694 | | | 2696 | |
2695 | ps = puffs_getspecific(pu); | | 2697 | ps = puffs_getspecific(pu); |
2696 | pnd = PERFUSE_NODE_DATA(opc); | | 2698 | pnd = PERFUSE_NODE_DATA(opc); |
2697 | | | 2699 | |
2698 | /* | | 2700 | /* |
2699 | * Never forget the root. | | 2701 | * Never forget the root. |
2700 | */ | | 2702 | */ |
2701 | if (pnd->pnd_nodeid == FUSE_ROOT_ID) | | 2703 | if (pnd->pnd_nodeid == FUSE_ROOT_ID) |
2702 | return 0; | | 2704 | return 0; |
2703 | | | 2705 | |
2704 | pnd->pnd_flags |= PND_RECLAIMED; | | 2706 | pnd->pnd_flags |= PND_RECLAIMED; |
| | | 2707 | pnd->pnd_puffs_nlookup--; |
2705 | | | 2708 | |
2706 | #ifdef PERFUSE_DEBUG | | 2709 | #ifdef PERFUSE_DEBUG |
2707 | if (perfuse_diagflags & PDF_RECLAIM) | | 2710 | if (perfuse_diagflags & PDF_RECLAIM) |
2708 | DPRINTF("%s (nodeid %"PRId64") reclaimed\n", | | 2711 | DPRINTF("%s (nodeid %"PRId64") reclaimed\n", |
2709 | perfuse_node_path(opc), pnd->pnd_nodeid); | | 2712 | perfuse_node_path(opc), pnd->pnd_nodeid); |
2710 | #endif | | 2713 | #endif |
2711 | | | 2714 | |
2712 | pn_root = puffs_getroot(pu); | | 2715 | pn_root = puffs_getroot(pu); |
2713 | pn = (struct puffs_node *)opc; | | 2716 | pn = (struct puffs_node *)opc; |
2714 | while (pn != pn_root) { | | 2717 | while (pn != pn_root) { |
2715 | struct puffs_node *parent_pn; | | 2718 | struct puffs_node *parent_pn; |
2716 | | | 2719 | |
2717 | pnd = PERFUSE_NODE_DATA(pn); | | 2720 | pnd = PERFUSE_NODE_DATA(pn); |
2718 | | | 2721 | |
2719 | #ifdef PERFUSE_DEBUG | | 2722 | #ifdef PERFUSE_DEBUG |
2720 | if (perfuse_diagflags & PDF_RECLAIM) | | 2723 | if (perfuse_diagflags & PDF_RECLAIM) |
2721 | DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, " | | 2724 | DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, nlookup = %d " |
2722 | "has childcount %d %s%s%s%s, pending ops:%s%s%s\n", | | 2725 | "has childcount %d %s%s%s%s, pending ops:%s%s%s\n", |
2723 | perfuse_node_path((puffs_cookie_t)pn), pnd->pnd_nodeid, | | 2726 | perfuse_node_path((puffs_cookie_t)pn), pnd->pnd_nodeid, |
2724 | pnd->pnd_flags & PND_RECLAIMED ? "" : "not ", | | 2727 | pnd->pnd_flags & PND_RECLAIMED ? "" : "not ", |
2725 | pnd->pnd_childcount, | | 2728 | pnd->pnd_puffs_nlookup, pnd->pnd_childcount, |
2726 | pnd->pnd_flags & PND_OPEN ? "open " : "not open", | | 2729 | pnd->pnd_flags & PND_OPEN ? "open " : "not open", |
2727 | pnd->pnd_flags & PND_RFH ? "r" : "", | | 2730 | pnd->pnd_flags & PND_RFH ? "r" : "", |
2728 | pnd->pnd_flags & PND_WFH ? "w" : "", | | 2731 | pnd->pnd_flags & PND_WFH ? "w" : "", |
2729 | pnd->pnd_flags & PND_BUSY ? "" : " none", | | 2732 | pnd->pnd_flags & PND_BUSY ? "" : " none", |
2730 | pnd->pnd_flags & PND_INREADDIR ? " readdir" : "", | | 2733 | pnd->pnd_flags & PND_INREADDIR ? " readdir" : "", |
2731 | pnd->pnd_flags & PND_INWRITE ? " write" : "", | | 2734 | pnd->pnd_flags & PND_INWRITE ? " write" : "", |
2732 | pnd->pnd_flags & PND_INOPEN ? " open" : ""); | | 2735 | pnd->pnd_flags & PND_INOPEN ? " open" : ""); |
2733 | #endif | | 2736 | #endif |
2734 | | | | |
2735 | if (!(pnd->pnd_flags & PND_RECLAIMED) || | | 2737 | if (!(pnd->pnd_flags & PND_RECLAIMED) || |
| | | 2738 | (pnd->pnd_puffs_nlookup != 0) || |
2736 | (pnd->pnd_childcount != 0)) | | 2739 | (pnd->pnd_childcount != 0)) |
2737 | return 0; | | 2740 | return 0; |
2738 | | | 2741 | |
2739 | #ifdef PERFUSE_DEBUG | | 2742 | #ifdef PERFUSE_DEBUG |
2740 | if ((pnd->pnd_flags & PND_OPEN) || | | 2743 | if ((pnd->pnd_flags & PND_OPEN) || |
2741 | !TAILQ_EMPTY(&pnd->pnd_pcq)) | | 2744 | !TAILQ_EMPTY(&pnd->pnd_pcq)) |
2742 | DERRX(EX_SOFTWARE, "%s: opc = %p: still open", | | 2745 | DERRX(EX_SOFTWARE, "%s: opc = %p: still open", |
2743 | __func__, (void *)opc); | | 2746 | __func__, (void *)opc); |
2744 | | | 2747 | |
2745 | if ((pnd->pnd_flags & PND_BUSY) || | | 2748 | if ((pnd->pnd_flags & PND_BUSY) || |
2746 | !TAILQ_EMPTY(&pnd->pnd_pcq)) | | 2749 | !TAILQ_EMPTY(&pnd->pnd_pcq)) |
2747 | DERRX(EX_SOFTWARE, "%s: opc = %p: ongoing operations", | | 2750 | DERRX(EX_SOFTWARE, "%s: opc = %p: ongoing operations", |
2748 | __func__, (void *)opc); | | 2751 | __func__, (void *)opc); |
2749 | #endif | | 2752 | #endif |
2750 | | | 2753 | |
2751 | /* | | 2754 | /* |
2752 | * Send the FORGET message | | 2755 | * Send the FORGET message |
2753 | * | | 2756 | * |
2754 | * ps_new_msg() is called with NULL creds, which will | | 2757 | * ps_new_msg() is called with NULL creds, which will |
2755 | * be interpreted as FUSE superuser. This is obviously | | 2758 | * be interpreted as FUSE superuser. This is obviously |
2756 | * fine since we operate with kernel creds here. | | 2759 | * fine since we operate with kernel creds here. |
2757 | */ | | 2760 | */ |
2758 | pm = ps->ps_new_msg(pu, (puffs_cookie_t)pn, FUSE_FORGET, | | 2761 | pm = ps->ps_new_msg(pu, (puffs_cookie_t)pn, FUSE_FORGET, |
2759 | sizeof(*ffi), NULL); | | 2762 | sizeof(*ffi), NULL); |
2760 | ffi = GET_INPAYLOAD(ps, pm, fuse_forget_in); | | 2763 | ffi = GET_INPAYLOAD(ps, pm, fuse_forget_in); |
2761 | ffi->nlookup = pnd->pnd_nlookup; | | 2764 | ffi->nlookup = pnd->pnd_fuse_nlookup; |
2762 | | | 2765 | |
2763 | /* | | 2766 | /* |
2764 | * No reply is expected, pm is freed in xchg_msg | | 2767 | * No reply is expected, pm is freed in xchg_msg |
2765 | */ | | 2768 | */ |
2766 | (void)xchg_msg(pu, (puffs_cookie_t)pn, | | 2769 | (void)xchg_msg(pu, (puffs_cookie_t)pn, |
2767 | pm, UNSPEC_REPLY_LEN, no_reply); | | 2770 | pm, UNSPEC_REPLY_LEN, no_reply); |
2768 | | | 2771 | |
2769 | parent_pn = pnd->pnd_parent; | | 2772 | parent_pn = pnd->pnd_parent; |
2770 | | | 2773 | |
2771 | perfuse_destroy_pn(pn); | | 2774 | perfuse_destroy_pn(pn); |
2772 | | | 2775 | |
2773 | pn = parent_pn; | | 2776 | pn = parent_pn; |
2774 | } | | 2777 | } |