summaryrefslogtreecommitdiffstats
path: root/module/zfs/dbuf.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2014-05-02 12:26:47 -0700
committerBrian Behlendorf <[email protected]>2014-05-05 13:56:59 -0700
commitcc79a5c263802b58de62b190e264c7f61b6235c9 (patch)
tree0017858a7f09f0cbea79e245ea508556b3e06679 /module/zfs/dbuf.c
parent51268f31a8a5d5c7a48a449437001f77591587f2 (diff)
Treat spill block dbufs as meta data
When the system attributes (SAs) for an object exceed what can can be stored in the bonus area of a dnode a spill block is allocated. These spill blocks are currently considered data blocks. However, they should be accounted for as meta data because they are effectively an extension of the dnode. While this may seem like a minor accounting issue it has broader implications. The key thing to be aware of is that each spill block will hold a reference on its parent dnode. The dnode in turn holds a reference on its dbuf in the dnode object. This means that a single 512 byte data buffer for a spill block can pin over 16k of meta data. This is analogous to the small file situation described in 2b13331 where a relatively small number of data buffer can cause the ARC to exceed the meta limit. However, unlike the small file case a spill block can legitimately be considered meta data. By changing the spill block to meta data they will now be dropped from the cache when the meta limit is reached. This then allows the dnodes and dbufs which the spill block was pinning to be released. Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Prakash Surya <[email protected]> Closes #2294
Diffstat (limited to 'module/zfs/dbuf.c')
-rw-r--r--module/zfs/dbuf.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c
index c8a526171..4f1750650 100644
--- a/module/zfs/dbuf.c
+++ b/module/zfs/dbuf.c
@@ -263,7 +263,10 @@ dbuf_evict_user(dmu_buf_impl_t *db)
boolean_t
dbuf_is_metadata(dmu_buf_impl_t *db)
{
- if (db->db_level > 0) {
+ /*
+ * Consider indirect blocks and spill blocks to be meta data.
+ */
+ if (db->db_level > 0 || db->db_blkid == DMU_SPILL_BLKID) {
return (B_TRUE);
} else {
boolean_t is_metadata;