void presto_put_super(struct super_block *sb) { struct presto_cache *cache; struct upc_comm *psdev; struct super_operations *sops; struct list_head *lh; ENTRY; cache = presto_find_cache(sb->s_dev); if (!cache) { EXIT; goto exit; } psdev = &upc_comms[presto_c2m(cache)]; sops = filter_c2csops(cache->cache_filter); if (sops->put_super) sops->put_super(sb); /* free any remaining async upcalls when the filesystem is unmounted */ lh = psdev->uc_pending.next; while ( lh != &psdev->uc_pending) { struct upc_req *req; req = list_entry(lh, struct upc_req, rq_chain); /* assignment must be here: we are about to free &lh */ lh = lh->next; if ( ! (req->rq_flags & REQ_ASYNC) ) continue; list_del(&(req->rq_chain)); PRESTO_FREE(req->rq_data, req->rq_bufsize); PRESTO_FREE(req, sizeof(struct upc_req)); } presto_free_cache(cache); exit: CDEBUG(D_MALLOC, "after umount: kmem %ld, vmem %ld\n", presto_kmemory, presto_vmemory); MOD_DEC_USE_COUNT; return ; }
static void presto_put_super(struct super_block *sb) { struct presto_cache *cache; struct upc_channel *channel; struct super_operations *sops; struct list_head *lh; int err; ENTRY; cache = presto_cache_find(sb->s_dev); if (!cache) { EXIT; goto exit; } channel = &izo_channels[presto_c2m(cache)]; sops = filter_c2csops(cache->cache_filter); err = izo_clear_all_fsetroots(cache); if (err) { CERROR("%s: err %d\n", __FUNCTION__, err); } PRESTO_FREE(cache->cache_vfsmount, sizeof(struct vfsmount)); /* look at kill_super - fsync_super is not exported GRRR but probably not needed */ unlock_super(sb); shrink_dcache_parent(cache->cache_root); dput(cache->cache_root); //fsync_super(sb); lock_super(sb); if (sops->write_super) sops->write_super(sb); if (sops->put_super) sops->put_super(sb); /* free any remaining async upcalls when the filesystem is unmounted */ spin_lock(&channel->uc_lock); lh = channel->uc_pending.next; while ( lh != &channel->uc_pending) { struct upc_req *req; req = list_entry(lh, struct upc_req, rq_chain); /* assignment must be here: we are about to free &lh */ lh = lh->next; if ( ! (req->rq_flags & REQ_ASYNC) ) continue; list_del(&(req->rq_chain)); PRESTO_FREE(req->rq_data, req->rq_bufsize); PRESTO_FREE(req, sizeof(struct upc_req)); } list_del(&cache->cache_channel_list); spin_unlock(&channel->uc_lock); presto_free_cache(cache); exit: CDEBUG(D_MALLOC, "after umount: kmem %ld, vmem %ld\n", presto_kmemory, presto_vmemory); MOD_DEC_USE_COUNT; return ; }