static int sfs_reclaim(struct inode *node) { struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs); struct sfs_inode *sin = vop_info(node, sfs_inode); lock_sfs_fs(sfs); int ret = -E_BUSY; assert(sin->reclaim_count > 0); if ((-- sin->reclaim_count) != 0) { goto failed_unlock; } assert(inode_ref_count(node) == 0 && inode_open_count(node) == 0); if (sin->din->nlinks == 0) { uint32_t nblks; for (nblks = sin->din->blocks; nblks != 0; nblks --) { sfs_bmap_truncate_nolock(sfs, sin); } } else if (sin->dirty) { if ((ret = vop_fsync(node)) != 0) { goto failed_unlock; } } sfs_remove_links(sin); unlock_sfs_fs(sfs); if (sin->din->nlinks == 0) { sfs_block_free(sfs, sin->ino); uint32_t ent; if ((ent = sin->din->indirect) != 0) { sfs_block_free(sfs, ent); } if ((ent = sin->din->db_indirect) != 0) { int i; for (i = 0; i < SFS_BLK_NENTRY; i ++) { sfs_bmap_free_sub_nolock(sfs, ent, i); } sfs_block_free(sfs, ent); } } kfree(sin->din); vop_kill(node); return 0; failed_unlock: unlock_sfs_fs(sfs); return ret; }
static int pipe_inode_reclaim(struct inode *node) { struct pipe_inode *pin = vop_info(node, pipe_inode); if (pin->name != NULL) { struct pipe_fs *pipe = fsop_info(vop_fs(node), pipe); lock_pipe(pipe); assert(pin->reclaim_count > 0); if ((--pin->reclaim_count) != 0 || inode_ref_count(node) != 0) { unlock_pipe(pipe); return -E_BUSY; } list_del(&(pin->pipe_link)); unlock_pipe(pipe); kfree(pin->name); } pipe_state_release(pin->state); vop_kill(node); return 0; }
/* * sfs_reclaim - Free all resources inode occupied . Called when inode is no longer in use. */ static int sfs_reclaim(struct inode *node) { struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs); struct sfs_inode *sin = vop_info(node, sfs_inode); int ret = -E_BUSY; uint32_t ent; lock_sfs_fs(sfs); assert(sin->reclaim_count > 0); if ((-- sin->reclaim_count) != 0 || inode_ref_count(node) != 0) { goto failed_unlock; } if (sin->din->nlinks == 0) { if ((ret = vop_truncate(node, 0)) != 0) { goto failed_unlock; } } if (sin->dirty) { if ((ret = vop_fsync(node)) != 0) { goto failed_unlock; } } sfs_remove_links(sin); unlock_sfs_fs(sfs); if (sin->din->nlinks == 0) { sfs_block_free(sfs, sin->ino); if ((ent = sin->din->indirect) != 0) { sfs_block_free(sfs, ent); } } kfree(sin->din); vop_kill(node); return 0; failed_unlock: unlock_sfs_fs(sfs); return ret; }