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