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