typedef void (*cache_walk_t)(struct cache_node *);
typedef struct cache_node * (*cache_node_alloc_t)(cache_key_t);
-typedef void (*cache_node_flush_t)(struct cache_node *);
+typedef int (*cache_node_flush_t)(struct cache_node *);
typedef void (*cache_node_relse_t)(struct cache_node *);
typedef unsigned int (*cache_node_hash_t)(cache_key_t, unsigned int,
unsigned int);
if (pthread_mutex_trylock(&node->cn_mutex) != 0)
continue;
+ /* can't release dirty objects */
+ if (cache->flush(node)) {
+ pthread_mutex_unlock(&node->cn_mutex);
+ continue;
+ }
+
hash = cache->c_hash + node->cn_hashidx;
if (pthread_mutex_trylock(&hash->ch_mutex) != 0) {
pthread_mutex_unlock(&node->cn_mutex);
pthread_mutex_unlock(&node->cn_mutex);
return count;
}
+
+ /* can't purge dirty objects */
+ if (cache->flush(node)) {
+ pthread_mutex_unlock(&node->cn_mutex);
+ return 1;
+ }
+
mru = &cache->c_mrus[node->cn_priority];
pthread_mutex_lock(&mru->cm_mutex);
list_del_init(&node->cn_mru);
pthread_mutex_destroy(&node->cn_mutex);
list_del_init(&node->cn_hash);
cache->relse(node);
- return count;
+ return 0;
}
/*
bp = kmem_zone_zalloc(xfs_buf_zone, 0);
pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex);
bp->b_ops = NULL;
+ if (bp->b_flags & LIBXFS_B_DIRTY)
+ fprintf(stderr, "found dirty buffer (bulk) on free list!");
return bp;
}
}
static void
-libxfs_brelse(struct cache_node *node)
+libxfs_brelse(
+ struct cache_node *node)
{
- xfs_buf_t *bp = (xfs_buf_t *)node;
+ struct xfs_buf *bp = (struct xfs_buf *)node;
- if (bp != NULL) {
- if (bp->b_flags & LIBXFS_B_DIRTY)
- libxfs_writebufr(bp);
- pthread_mutex_lock(&xfs_buf_freelist.cm_mutex);
- list_add(&bp->b_node.cn_mru, &xfs_buf_freelist.cm_list);
- pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex);
- }
+ if (!bp)
+ return;
+ if (bp->b_flags & LIBXFS_B_DIRTY)
+ fprintf(stderr,
+ "releasing dirty buffer to free list!");
+
+ pthread_mutex_lock(&xfs_buf_freelist.cm_mutex);
+ list_add(&bp->b_node.cn_mru, &xfs_buf_freelist.cm_list);
+ pthread_mutex_unlock(&xfs_buf_freelist.cm_mutex);
}
static unsigned int
libxfs_bulkrelse(
- struct cache *cache,
- struct list_head *list)
+ struct cache *cache,
+ struct list_head *list)
{
xfs_buf_t *bp;
int count = 0;
list_for_each_entry(bp, list, b_node.cn_mru) {
if (bp->b_flags & LIBXFS_B_DIRTY)
- libxfs_writebufr(bp);
+ fprintf(stderr,
+ "releasing dirty buffer (bulk) to free list!");
count++;
}
return count;
}
-static void
-libxfs_bflush(struct cache_node *node)
+static int
+libxfs_bflush(
+ struct cache_node *node)
{
- xfs_buf_t *bp = (xfs_buf_t *)node;
+ struct xfs_buf *bp = (struct xfs_buf *)node;
- if ((bp != NULL) && (bp->b_flags & LIBXFS_B_DIRTY))
- libxfs_writebufr(bp);
+ if (bp->b_flags & LIBXFS_B_DIRTY)
+ return libxfs_writebufr(bp);
+ return 0;
}
void
libxfs_putbufr(xfs_buf_t *bp)
{
+ if (bp->b_flags & LIBXFS_B_DIRTY)
+ libxfs_writebufr(bp);
libxfs_brelse((struct cache_node *)bp);
}