xref: /netbsd-src/lib/libperfuse/subr.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*  $NetBSD: subr.c,v 1.4 2010/09/03 07:15:18 manu Exp $ */
2 
3 /*-
4  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions
8  *  are met:
9  *  1. Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16  *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19  *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  *  POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <err.h>
31 #include <errno.h>
32 #include <sysexits.h>
33 #include <syslog.h>
34 #include <puffs.h>
35 #include <paths.h>
36 
37 #include "perfuse_priv.h"
38 
39 struct puffs_node *
40 perfuse_new_pn(pu, parent)
41 	struct puffs_usermount *pu;
42 	struct puffs_node *parent;
43 {
44 	struct puffs_node *pn;
45 	struct perfuse_node_data *pnd;
46 
47 	if ((pnd = malloc(sizeof(*pnd))) == NULL)
48 		DERR(EX_OSERR, "malloc failed");
49 
50 	if ((pn = puffs_pn_new(pu, pnd)) == NULL)
51 		DERR(EX_SOFTWARE, "puffs_pn_new failed");
52 
53 	(void)memset(pnd, 0, sizeof(*pnd));
54 	pnd->pnd_rfh = FUSE_UNKNOWN_FH;
55 	pnd->pnd_wfh = FUSE_UNKNOWN_FH;
56 	pnd->pnd_ino = PERFUSE_UNKNOWN_INO;
57 	pnd->pnd_nlookup = 1;
58 	pnd->pnd_parent = parent;
59 	TAILQ_INIT(&pnd->pnd_pcq);
60 
61 	if (parent != NULL)
62 		PERFUSE_NODE_DATA(parent)->pnd_childcount++;
63 
64 	return pn;
65 }
66 
67 void
68 perfuse_destroy_pn(pn)
69 	struct puffs_node *pn;
70 {
71 	struct perfuse_node_data *pnd;
72 
73 	if ((pnd = puffs_pn_getpriv(pn)) != NULL) {
74 		if (pnd->pnd_parent != NULL)
75 			PERFUSE_NODE_DATA(pnd->pnd_parent)->pnd_childcount--;
76 
77 		if (pnd->pnd_dirent != NULL)
78 			free(pnd->pnd_dirent);
79 
80 		if (pnd->pnd_all_fd != NULL)
81 			free(pnd->pnd_all_fd);
82 #ifdef PERFUSE_DEBUG
83 		if (pnd->pnd_flags & PND_OPEN)
84 			DERRX(EX_SOFTWARE, "%s: file open", __func__);
85 
86 		if (!TAILQ_EMPTY(&pnd->pnd_pcq))
87 			DERRX(EX_SOFTWARE, "%s: non empty pnd_pcq", __func__);
88 #endif /* PERFUSE_DEBUG */
89 
90 		free(pnd);
91 	}
92 
93 	puffs_pn_remove(pn);
94 
95 	return;
96 }
97 
98 
99 void
100 perfuse_new_fh(opc, fh, mode)
101 	puffs_cookie_t opc;
102 	uint64_t fh;
103 	int mode;
104 {
105 	struct perfuse_node_data *pnd;
106 
107 	pnd = PERFUSE_NODE_DATA(opc);
108 
109 	if (mode & FWRITE) {
110 		if (pnd->pnd_flags & PND_WFH)
111 			DERRX(EX_SOFTWARE, "%s: opc = %p, write fh already set",
112 			      __func__, (void *)opc);
113 		pnd->pnd_wfh = fh;
114 		pnd->pnd_flags |= PND_WFH;
115 	}
116 
117 	if (mode & FREAD) {
118 		if (pnd->pnd_flags & PND_RFH)
119 			DERRX(EX_SOFTWARE, "%s: opc = %p, read fh already set",
120 			      __func__, (void *)opc);
121 		pnd->pnd_rfh = fh;
122 		pnd->pnd_flags |= PND_RFH;
123 	}
124 
125 	return;
126 }
127 
128 void
129 perfuse_destroy_fh(opc, fh)
130 	puffs_cookie_t opc;
131 	uint64_t fh;
132 {
133 	struct perfuse_node_data *pnd;
134 
135 	pnd = PERFUSE_NODE_DATA(opc);
136 
137 	if (fh == pnd->pnd_rfh) {
138 		if (!(pnd->pnd_flags & PND_RFH) && (fh != FUSE_UNKNOWN_FH))
139 			DERRX(EX_SOFTWARE,
140 			      "%s: opc = %p, unset rfh = %"PRIx64"",
141 			      __func__, (void *)opc, fh);
142 		pnd->pnd_rfh = FUSE_UNKNOWN_FH;
143 		pnd->pnd_flags &= ~PND_RFH;
144 	}
145 
146 	if (fh == pnd->pnd_wfh) {
147 		if (!(pnd->pnd_flags & PND_WFH) && (fh != FUSE_UNKNOWN_FH))
148 			DERRX(EX_SOFTWARE,
149 			      "%s: opc = %p, unset wfh = %"PRIx64"",
150 			      __func__, (void *)opc, fh);
151 		pnd->pnd_wfh = FUSE_UNKNOWN_FH;
152 		pnd->pnd_flags &= ~PND_WFH;
153 	}
154 
155 	return;
156 }
157 
158 uint64_t
159 perfuse_get_fh(opc, mode)
160 	puffs_cookie_t opc;
161 	int mode;
162 {
163 	struct perfuse_node_data *pnd;
164 
165 	pnd = PERFUSE_NODE_DATA(opc);
166 
167 	if (mode & FWRITE)
168 		if (pnd->pnd_flags & PND_WFH)
169 			return pnd->pnd_wfh;
170 
171 	if (mode & FREAD) {
172 		if (pnd->pnd_flags & PND_RFH)
173 			return pnd->pnd_rfh;
174 
175 		if (pnd->pnd_flags & PND_WFH)
176 			return pnd->pnd_wfh;
177 	}
178 
179 	return FUSE_UNKNOWN_FH;
180 }
181 
182