xref: /minix3/minix/lib/libpuffs/inode.c (revision ba736c796854b82e29da17267614db0a449419db)
1*ba736c79SDavid van Moolenbroek /*
2*ba736c79SDavid van Moolenbroek  * Created (MFS based):
3*ba736c79SDavid van Moolenbroek  *   June 2011 (Evgeniy Ivanov)
4*ba736c79SDavid van Moolenbroek  */
5*ba736c79SDavid van Moolenbroek 
6*ba736c79SDavid van Moolenbroek #include "fs.h"
7*ba736c79SDavid van Moolenbroek 
release_node(struct puffs_usermount * pu,struct puffs_node * pn)8*ba736c79SDavid van Moolenbroek void release_node(struct puffs_usermount *pu, struct puffs_node *pn)
9*ba736c79SDavid van Moolenbroek {
10*ba736c79SDavid van Moolenbroek   assert(pn->pn_count == 0);
11*ba736c79SDavid van Moolenbroek 
12*ba736c79SDavid van Moolenbroek   /* Required if puffs_node_reclaim() decides to leave node in the list */
13*ba736c79SDavid van Moolenbroek   pn->pn_mountpoint = FALSE;
14*ba736c79SDavid van Moolenbroek 
15*ba736c79SDavid van Moolenbroek   if (pu->pu_ops.puffs_node_reclaim) {
16*ba736c79SDavid van Moolenbroek 	if (global_pu->pu_ops.puffs_node_reclaim(global_pu, pn) != 0)
17*ba736c79SDavid van Moolenbroek 		lpuffs_debug("Warning: reclaim failed\n");
18*ba736c79SDavid van Moolenbroek   } else {
19*ba736c79SDavid van Moolenbroek 	puffs_pn_put(pn);
20*ba736c79SDavid van Moolenbroek   }
21*ba736c79SDavid van Moolenbroek }
22*ba736c79SDavid van Moolenbroek 
23*ba736c79SDavid van Moolenbroek 
24*ba736c79SDavid van Moolenbroek /*===========================================================================*
25*ba736c79SDavid van Moolenbroek  *                fs_putnode                                                 *
26*ba736c79SDavid van Moolenbroek  *===========================================================================*/
fs_putnode(ino_t ino_nr,unsigned int count)27*ba736c79SDavid van Moolenbroek int fs_putnode(ino_t ino_nr, unsigned int count)
28*ba736c79SDavid van Moolenbroek {
29*ba736c79SDavid van Moolenbroek /* Find the pnode specified by the request message and decrease its counter.
30*ba736c79SDavid van Moolenbroek  * Release unused pnode.
31*ba736c79SDavid van Moolenbroek  */
32*ba736c79SDavid van Moolenbroek   struct puffs_node *pn;
33*ba736c79SDavid van Moolenbroek 
34*ba736c79SDavid van Moolenbroek   if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
35*ba736c79SDavid van Moolenbroek 	/* XXX Probably removed from the list, see puffs_pn_remove() */
36*ba736c79SDavid van Moolenbroek 	struct puffs_node *pn_cur, *pn_next;
37*ba736c79SDavid van Moolenbroek 	pn_cur = LIST_FIRST(&global_pu->pu_pnode_removed_lst);
38*ba736c79SDavid van Moolenbroek 	while (pn_cur) {
39*ba736c79SDavid van Moolenbroek 		pn_next = LIST_NEXT(pn_cur, pn_entries);
40*ba736c79SDavid van Moolenbroek 		if (pn_cur->pn_va.va_fileid == ino_nr) {
41*ba736c79SDavid van Moolenbroek 			pn = pn_cur;
42*ba736c79SDavid van Moolenbroek 			break;
43*ba736c79SDavid van Moolenbroek 		}
44*ba736c79SDavid van Moolenbroek 		pn_cur = pn_next;
45*ba736c79SDavid van Moolenbroek 	}
46*ba736c79SDavid van Moolenbroek   }
47*ba736c79SDavid van Moolenbroek 
48*ba736c79SDavid van Moolenbroek   if (pn == NULL) {
49*ba736c79SDavid van Moolenbroek 	lpuffs_debug("%s:%d putnode: pnode #%"PRIu64" not found\n",
50*ba736c79SDavid van Moolenbroek 	    __FILE__, __LINE__, ino_nr);
51*ba736c79SDavid van Moolenbroek 	panic("fs_putnode failed");
52*ba736c79SDavid van Moolenbroek   }
53*ba736c79SDavid van Moolenbroek 
54*ba736c79SDavid van Moolenbroek   if (count <= 0) {
55*ba736c79SDavid van Moolenbroek 	lpuffs_debug("%s:%d putnode: bad value for count: %d\n", __FILE__,
56*ba736c79SDavid van Moolenbroek 		__LINE__, count);
57*ba736c79SDavid van Moolenbroek 	panic("fs_putnode failed");
58*ba736c79SDavid van Moolenbroek   } else if (pn->pn_count == 0) {
59*ba736c79SDavid van Moolenbroek 	/* FUSE fs might store in the list pnodes, which we hasn't
60*ba736c79SDavid van Moolenbroek 	 * open, this means we got put request for file,
61*ba736c79SDavid van Moolenbroek 	 * which wasn't opened by VFS.
62*ba736c79SDavid van Moolenbroek 	 */
63*ba736c79SDavid van Moolenbroek 	lpuffs_debug("%s:%d putnode: pn_count already zero\n", __FILE__,
64*ba736c79SDavid van Moolenbroek 		__LINE__);
65*ba736c79SDavid van Moolenbroek 	panic("fs_putnode failed");
66*ba736c79SDavid van Moolenbroek   } else if (count > pn->pn_count) {
67*ba736c79SDavid van Moolenbroek 	struct puffs_node *pn_cur, *pn_next;
68*ba736c79SDavid van Moolenbroek 	struct puffs_usermount *pu = global_pu;
69*ba736c79SDavid van Moolenbroek 	ino_t ino = pn->pn_va.va_fileid;
70*ba736c79SDavid van Moolenbroek 
71*ba736c79SDavid van Moolenbroek 	pn_cur = LIST_FIRST(&pu->pu_pnodelst);
72*ba736c79SDavid van Moolenbroek 	lpuffs_debug("inum  count  path  polen  hash\n");
73*ba736c79SDavid van Moolenbroek 	while (pn_cur) {
74*ba736c79SDavid van Moolenbroek 		pn_next = LIST_NEXT(pn_cur, pn_entries);
75*ba736c79SDavid van Moolenbroek 		if (pn_cur->pn_va.va_fileid == ino) {
76*ba736c79SDavid van Moolenbroek 			lpuffs_debug("%"PRIu64": %d %s %u %u\n",
77*ba736c79SDavid van Moolenbroek 				ino,
78*ba736c79SDavid van Moolenbroek 				pn_cur->pn_count,
79*ba736c79SDavid van Moolenbroek 				(char *)pn_cur->pn_po.po_path,
80*ba736c79SDavid van Moolenbroek 				pn_cur->pn_po.po_len,
81*ba736c79SDavid van Moolenbroek 				pn_cur->pn_po.po_hash);
82*ba736c79SDavid van Moolenbroek 		}
83*ba736c79SDavid van Moolenbroek 		pn_cur = pn_next;
84*ba736c79SDavid van Moolenbroek 	}
85*ba736c79SDavid van Moolenbroek 	lpuffs_debug("%s:%d putnode: count too high: %d > %d\n", __FILE__,
86*ba736c79SDavid van Moolenbroek 		__LINE__, count, pn->pn_count);
87*ba736c79SDavid van Moolenbroek 	panic("fs_putnode failed");
88*ba736c79SDavid van Moolenbroek   }
89*ba736c79SDavid van Moolenbroek 
90*ba736c79SDavid van Moolenbroek   pn->pn_count -= count;
91*ba736c79SDavid van Moolenbroek 
92*ba736c79SDavid van Moolenbroek   if (pn->pn_count == 0)
93*ba736c79SDavid van Moolenbroek 	release_node(global_pu, pn);
94*ba736c79SDavid van Moolenbroek 
95*ba736c79SDavid van Moolenbroek   return(OK);
96*ba736c79SDavid van Moolenbroek }
97