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