summaryrefslogtreecommitdiffstats
path: root/fs/dquot.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-08-19 14:51:22 +0200
committerMark Fasheh <mfasheh@suse.com>2009-01-05 08:36:55 -0800
commit74f783af95c982aef6d3a1415275650dcf511666 (patch)
tree594e978641d31e05e170a56ec68f8c65b37bb649 /fs/dquot.c
parent9f868f16e40e9ad8e39aebff94a4be0d96520734 (diff)
downloadlinux-stable-74f783af95c982aef6d3a1415275650dcf511666.tar.gz
linux-stable-74f783af95c982aef6d3a1415275650dcf511666.tar.bz2
linux-stable-74f783af95c982aef6d3a1415275650dcf511666.zip
quota: Add callbacks for allocating and destroying dquot structures
Some filesystems would like to keep private information together with each dquot. Add callbacks alloc_dquot and destroy_dquot allowing filesystem to allocate larger dquots from their private slab in a similar fashion we currently allocate inodes. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/dquot.c')
-rw-r--r--fs/dquot.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index c237ccc8581c..1b5fc4b7fbeb 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -415,6 +415,16 @@ out_dqlock:
return ret;
}
+static void dquot_destroy(struct dquot *dquot)
+{
+ kmem_cache_free(dquot_cachep, dquot);
+}
+
+static inline void do_destroy_dquot(struct dquot *dquot)
+{
+ dquot->dq_sb->dq_op->destroy_dquot(dquot);
+}
+
/* Invalidate all dquots on the list. Note that this function is called after
* quota is disabled and pointers from inodes removed so there cannot be new
* quota users. There can still be some users of quotas due to inodes being
@@ -463,7 +473,7 @@ restart:
remove_dquot_hash(dquot);
remove_free_dquot(dquot);
remove_inuse(dquot);
- kmem_cache_free(dquot_cachep, dquot);
+ do_destroy_dquot(dquot);
}
spin_unlock(&dq_list_lock);
}
@@ -527,7 +537,7 @@ static void prune_dqcache(int count)
remove_dquot_hash(dquot);
remove_free_dquot(dquot);
remove_inuse(dquot);
- kmem_cache_free(dquot_cachep, dquot);
+ do_destroy_dquot(dquot);
count--;
head = free_dquots.prev;
}
@@ -625,11 +635,16 @@ we_slept:
spin_unlock(&dq_list_lock);
}
+static struct dquot *dquot_alloc(struct super_block *sb, int type)
+{
+ return kmem_cache_zalloc(dquot_cachep, GFP_NOFS);
+}
+
static struct dquot *get_empty_dquot(struct super_block *sb, int type)
{
struct dquot *dquot;
- dquot = kmem_cache_zalloc(dquot_cachep, GFP_NOFS);
+ dquot = sb->dq_op->alloc_dquot(sb, type);
if(!dquot)
return NODQUOT;
@@ -682,7 +697,7 @@ we_slept:
dqstats.lookups++;
spin_unlock(&dq_list_lock);
if (empty)
- kmem_cache_free(dquot_cachep, empty);
+ do_destroy_dquot(empty);
}
/* Wait for dq_lock - after this we know that either dquot_release() is already
* finished or it will be canceled due to dq_count > 1 test */
@@ -1533,7 +1548,9 @@ struct dquot_operations dquot_operations = {
.acquire_dquot = dquot_acquire,
.release_dquot = dquot_release,
.mark_dirty = dquot_mark_dquot_dirty,
- .write_info = dquot_commit_info
+ .write_info = dquot_commit_info,
+ .alloc_dquot = dquot_alloc,
+ .destroy_dquot = dquot_destroy,
};
static inline void set_enable_flags(struct quota_info *dqopt, int type)