xref: /minix3/lib/libpuffs/pnode.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
184d9c625SLionel Sambuc /*	$NetBSD: pnode.c,v 1.13 2012/08/16 09:25:43 manu Exp $	*/
2490e0de5SThomas Veerman 
3490e0de5SThomas Veerman /*
4490e0de5SThomas Veerman  * Copyright (c) 2006 Antti Kantee.  All Rights Reserved.
5490e0de5SThomas Veerman  *
6490e0de5SThomas Veerman  * Redistribution and use in source and binary forms, with or without
7490e0de5SThomas Veerman  * modification, are permitted provided that the following conditions
8490e0de5SThomas Veerman  * are met:
9490e0de5SThomas Veerman  * 1. Redistributions of source code must retain the above copyright
10490e0de5SThomas Veerman  *    notice, this list of conditions and the following disclaimer.
11490e0de5SThomas Veerman  * 2. Redistributions in binary form must reproduce the above copyright
12490e0de5SThomas Veerman  *    notice, this list of conditions and the following disclaimer in the
13490e0de5SThomas Veerman  *    documentation and/or other materials provided with the distribution.
14490e0de5SThomas Veerman  *
15490e0de5SThomas Veerman  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16490e0de5SThomas Veerman  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17490e0de5SThomas Veerman  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18490e0de5SThomas Veerman  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19490e0de5SThomas Veerman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20490e0de5SThomas Veerman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21490e0de5SThomas Veerman  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22490e0de5SThomas Veerman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23490e0de5SThomas Veerman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24490e0de5SThomas Veerman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25490e0de5SThomas Veerman  * SUCH DAMAGE.
26490e0de5SThomas Veerman  */
27490e0de5SThomas Veerman 
28490e0de5SThomas Veerman #include <sys/cdefs.h>
29490e0de5SThomas Veerman #if !defined(lint)
3084d9c625SLionel Sambuc __RCSID("$NetBSD: pnode.c,v 1.13 2012/08/16 09:25:43 manu Exp $");
31490e0de5SThomas Veerman #endif /* !lint */
32490e0de5SThomas Veerman 
33490e0de5SThomas Veerman #include <sys/types.h>
34490e0de5SThomas Veerman 
35490e0de5SThomas Veerman #include <assert.h>
3684d9c625SLionel Sambuc #include <puffs.h>
37490e0de5SThomas Veerman #include <stdlib.h>
38490e0de5SThomas Veerman #include <stdio.h>
39490e0de5SThomas Veerman #include <string.h>
40490e0de5SThomas Veerman 
41490e0de5SThomas Veerman #include "puffs_priv.h"
42490e0de5SThomas Veerman 
43490e0de5SThomas Veerman /*
44490e0de5SThomas Veerman  * Well, you're probably wondering why this isn't optimized.
45490e0de5SThomas Veerman  * The reason is simple: my available time is not optimized for
46490e0de5SThomas Veerman  * size ... so please be patient ;)
47490e0de5SThomas Veerman  */
48490e0de5SThomas Veerman struct puffs_node *
puffs_pn_new(struct puffs_usermount * pu,void * privdata)49490e0de5SThomas Veerman puffs_pn_new(struct puffs_usermount *pu, void *privdata)
50490e0de5SThomas Veerman {
51490e0de5SThomas Veerman 	struct puffs_node *pn;
52490e0de5SThomas Veerman 
53490e0de5SThomas Veerman 	pn = calloc(1, sizeof(struct puffs_node));
54490e0de5SThomas Veerman 	if (pn == NULL)
55490e0de5SThomas Veerman 		return NULL;
56490e0de5SThomas Veerman 
57490e0de5SThomas Veerman 	pn->pn_data = privdata;
58490e0de5SThomas Veerman 	pn->pn_mnt = pu;
59490e0de5SThomas Veerman 	puffs_vattr_null(&pn->pn_va);
60490e0de5SThomas Veerman 
61490e0de5SThomas Veerman 	LIST_INSERT_HEAD(&pu->pu_pnodelst, pn, pn_entries);
62490e0de5SThomas Veerman 
6384d9c625SLionel Sambuc 	pu->pu_flags |= PUFFS_FLAG_PNCOOKIE;
6484d9c625SLionel Sambuc 
65490e0de5SThomas Veerman 	return pn;
66490e0de5SThomas Veerman }
67490e0de5SThomas Veerman 
68490e0de5SThomas Veerman void
puffs_pn_remove(struct puffs_node * pn)69490e0de5SThomas Veerman puffs_pn_remove(struct puffs_node *pn)
70490e0de5SThomas Veerman {
71490e0de5SThomas Veerman 
72490e0de5SThomas Veerman 	LIST_REMOVE(pn, pn_entries);
73490e0de5SThomas Veerman 	pn->pn_flags |= PUFFS_NODE_REMOVED;
74*0a6a1f1dSLionel Sambuc #if defined(__minix)
75490e0de5SThomas Veerman 	if (pn->pn_count != 0) {
76ba736c79SDavid van Moolenbroek 		struct puffs_usermount *pu = pn->pn_mnt;
77ba736c79SDavid van Moolenbroek 		assert(pu != NULL);
78ba736c79SDavid van Moolenbroek 
79490e0de5SThomas Veerman 		/* XXX FS removes this pn from the list to prevent further
80490e0de5SThomas Veerman 		 * lookups from finding node after remove/rm/rename op.
81490e0de5SThomas Veerman 		 * But VFS still uses it, i.e. pnode is still open, and
82490e0de5SThomas Veerman 		 * will put it later. Keep it in separate list to do reclaim
83490e0de5SThomas Veerman 		 * in fs_put().
84490e0de5SThomas Veerman 		 */
85490e0de5SThomas Veerman 		LIST_INSERT_HEAD(&pu->pu_pnode_removed_lst, pn, pn_entries);
86490e0de5SThomas Veerman 	}
87*0a6a1f1dSLionel Sambuc #endif /* defined(__minix) */
88490e0de5SThomas Veerman }
89490e0de5SThomas Veerman 
90490e0de5SThomas Veerman void
puffs_pn_put(struct puffs_node * pn)91490e0de5SThomas Veerman puffs_pn_put(struct puffs_node *pn)
92490e0de5SThomas Veerman {
93490e0de5SThomas Veerman 	struct puffs_usermount *pu = pn->pn_mnt;
94490e0de5SThomas Veerman 
95490e0de5SThomas Veerman 	pu->pu_pathfree(pu, &pn->pn_po);
9684d9c625SLionel Sambuc 	if ((pn->pn_flags & PUFFS_NODE_REMOVED) == 0)
97490e0de5SThomas Veerman 		LIST_REMOVE(pn, pn_entries);
98490e0de5SThomas Veerman 	free(pn);
99490e0de5SThomas Veerman }
100490e0de5SThomas Veerman 
101ba736c79SDavid van Moolenbroek /* walk list, rv can be used either to halt or to return a value */
102490e0de5SThomas Veerman void *
puffs_pn_nodewalk(struct puffs_usermount * pu,puffs_nodewalk_fn fn,void * arg)103490e0de5SThomas Veerman puffs_pn_nodewalk(struct puffs_usermount *pu, puffs_nodewalk_fn fn, void *arg)
104490e0de5SThomas Veerman {
105490e0de5SThomas Veerman 	struct puffs_node *pn_cur, *pn_next;
106490e0de5SThomas Veerman 	void *rv;
107490e0de5SThomas Veerman 
108490e0de5SThomas Veerman 	pn_cur = LIST_FIRST(&pu->pu_pnodelst);
109490e0de5SThomas Veerman 	while (pn_cur) {
110490e0de5SThomas Veerman 		pn_next = LIST_NEXT(pn_cur, pn_entries);
111490e0de5SThomas Veerman 		rv = fn(pu, pn_cur, arg);
112490e0de5SThomas Veerman 		if (rv)
113490e0de5SThomas Veerman 			return rv;
114490e0de5SThomas Veerman 		pn_cur = pn_next;
115490e0de5SThomas Veerman 	}
116490e0de5SThomas Veerman 
117490e0de5SThomas Veerman 	return NULL;
118490e0de5SThomas Veerman }
119490e0de5SThomas Veerman 
120490e0de5SThomas Veerman struct vattr *
puffs_pn_getvap(struct puffs_node * pn)121490e0de5SThomas Veerman puffs_pn_getvap(struct puffs_node *pn)
122490e0de5SThomas Veerman {
123490e0de5SThomas Veerman 
124490e0de5SThomas Veerman 	return &pn->pn_va;
125490e0de5SThomas Veerman }
126490e0de5SThomas Veerman 
127490e0de5SThomas Veerman void *
puffs_pn_getpriv(struct puffs_node * pn)128490e0de5SThomas Veerman puffs_pn_getpriv(struct puffs_node *pn)
129490e0de5SThomas Veerman {
130490e0de5SThomas Veerman 
131490e0de5SThomas Veerman 	return pn->pn_data;
132490e0de5SThomas Veerman }
133490e0de5SThomas Veerman 
134490e0de5SThomas Veerman void
puffs_pn_setpriv(struct puffs_node * pn,void * priv)135490e0de5SThomas Veerman puffs_pn_setpriv(struct puffs_node *pn, void *priv)
136490e0de5SThomas Veerman {
137490e0de5SThomas Veerman 
138490e0de5SThomas Veerman 	pn->pn_data = priv;
139490e0de5SThomas Veerman }
140490e0de5SThomas Veerman 
141490e0de5SThomas Veerman struct puffs_pathobj *
puffs_pn_getpo(struct puffs_node * pn)142490e0de5SThomas Veerman puffs_pn_getpo(struct puffs_node *pn)
143490e0de5SThomas Veerman {
144490e0de5SThomas Veerman 
145490e0de5SThomas Veerman 	return &pn->pn_po;
146490e0de5SThomas Veerman }
147490e0de5SThomas Veerman 
148490e0de5SThomas Veerman struct puffs_usermount *
puffs_pn_getmnt(struct puffs_node * pn)149490e0de5SThomas Veerman puffs_pn_getmnt(struct puffs_node *pn)
150490e0de5SThomas Veerman {
151490e0de5SThomas Veerman 
152490e0de5SThomas Veerman 	return pn->pn_mnt;
153490e0de5SThomas Veerman }
154490e0de5SThomas Veerman 
155490e0de5SThomas Veerman /* convenience / shortcut */
156490e0de5SThomas Veerman void *
puffs_pn_getmntspecific(struct puffs_node * pn)157490e0de5SThomas Veerman puffs_pn_getmntspecific(struct puffs_node *pn)
158490e0de5SThomas Veerman {
159490e0de5SThomas Veerman 
160490e0de5SThomas Veerman 	return pn->pn_mnt->pu_privdata;
161490e0de5SThomas Veerman }
162490e0de5SThomas Veerman 
163490e0de5SThomas Veerman /*
164490e0de5SThomas Veerman  * newnode parameters
165490e0de5SThomas Veerman  */
166490e0de5SThomas Veerman void
puffs_newinfo_setcookie(struct puffs_newinfo * pni,puffs_cookie_t cookie)167490e0de5SThomas Veerman puffs_newinfo_setcookie(struct puffs_newinfo *pni, puffs_cookie_t cookie)
168490e0de5SThomas Veerman {
169490e0de5SThomas Veerman 
170490e0de5SThomas Veerman 	*pni->pni_cookie = cookie;
171490e0de5SThomas Veerman }
172490e0de5SThomas Veerman 
173490e0de5SThomas Veerman void
puffs_newinfo_setvtype(struct puffs_newinfo * pni,enum vtype vt)174490e0de5SThomas Veerman puffs_newinfo_setvtype(struct puffs_newinfo *pni, enum vtype vt)
175490e0de5SThomas Veerman {
176490e0de5SThomas Veerman 
177490e0de5SThomas Veerman 	*pni->pni_vtype = vt;
178490e0de5SThomas Veerman }
179490e0de5SThomas Veerman 
180490e0de5SThomas Veerman void
puffs_newinfo_setsize(struct puffs_newinfo * pni,voff_t size)181490e0de5SThomas Veerman puffs_newinfo_setsize(struct puffs_newinfo *pni, voff_t size)
182490e0de5SThomas Veerman {
183490e0de5SThomas Veerman 
184490e0de5SThomas Veerman 	*pni->pni_size = size;
185490e0de5SThomas Veerman }
186490e0de5SThomas Veerman 
187490e0de5SThomas Veerman void
puffs_newinfo_setrdev(struct puffs_newinfo * pni,dev_t rdev)188490e0de5SThomas Veerman puffs_newinfo_setrdev(struct puffs_newinfo *pni, dev_t rdev)
189490e0de5SThomas Veerman {
190490e0de5SThomas Veerman 
191490e0de5SThomas Veerman 	*pni->pni_rdev = rdev;
192490e0de5SThomas Veerman }
19384d9c625SLionel Sambuc 
19484d9c625SLionel Sambuc void
puffs_newinfo_setva(struct puffs_newinfo * pni,struct vattr * va)19584d9c625SLionel Sambuc puffs_newinfo_setva(struct puffs_newinfo *pni, struct vattr *va)
19684d9c625SLionel Sambuc {
19784d9c625SLionel Sambuc 
19884d9c625SLionel Sambuc 	(void)memcpy(pni->pni_va, va, sizeof(struct vattr));
19984d9c625SLionel Sambuc }
20084d9c625SLionel Sambuc 
20184d9c625SLionel Sambuc void
puffs_newinfo_setvattl(struct puffs_newinfo * pni,struct timespec * va_ttl)20284d9c625SLionel Sambuc puffs_newinfo_setvattl(struct puffs_newinfo *pni, struct timespec *va_ttl)
20384d9c625SLionel Sambuc {
20484d9c625SLionel Sambuc 
20584d9c625SLionel Sambuc 	pni->pni_va_ttl->tv_sec = va_ttl->tv_sec;
20684d9c625SLionel Sambuc 	pni->pni_va_ttl->tv_nsec = va_ttl->tv_nsec;
20784d9c625SLionel Sambuc }
20884d9c625SLionel Sambuc 
20984d9c625SLionel Sambuc void
puffs_newinfo_setcnttl(struct puffs_newinfo * pni,struct timespec * cn_ttl)21084d9c625SLionel Sambuc puffs_newinfo_setcnttl(struct puffs_newinfo *pni, struct timespec *cn_ttl)
21184d9c625SLionel Sambuc {
21284d9c625SLionel Sambuc 
21384d9c625SLionel Sambuc 	pni->pni_cn_ttl->tv_sec = cn_ttl->tv_sec;
21484d9c625SLionel Sambuc 	pni->pni_cn_ttl->tv_nsec = cn_ttl->tv_nsec;
21584d9c625SLionel Sambuc }
21684d9c625SLionel Sambuc 
217