Commit 74f783af authored by Jan Kara's avatar Jan Kara Committed by Mark Fasheh

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: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
parent 9f868f16
...@@ -415,6 +415,16 @@ int dquot_release(struct dquot *dquot) ...@@ -415,6 +415,16 @@ int dquot_release(struct dquot *dquot)
return ret; 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 /* 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 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 * quota users. There can still be some users of quotas due to inodes being
...@@ -463,7 +473,7 @@ static void invalidate_dquots(struct super_block *sb, int type) ...@@ -463,7 +473,7 @@ static void invalidate_dquots(struct super_block *sb, int type)
remove_dquot_hash(dquot); remove_dquot_hash(dquot);
remove_free_dquot(dquot); remove_free_dquot(dquot);
remove_inuse(dquot); remove_inuse(dquot);
kmem_cache_free(dquot_cachep, dquot); do_destroy_dquot(dquot);
} }
spin_unlock(&dq_list_lock); spin_unlock(&dq_list_lock);
} }
...@@ -527,7 +537,7 @@ static void prune_dqcache(int count) ...@@ -527,7 +537,7 @@ static void prune_dqcache(int count)
remove_dquot_hash(dquot); remove_dquot_hash(dquot);
remove_free_dquot(dquot); remove_free_dquot(dquot);
remove_inuse(dquot); remove_inuse(dquot);
kmem_cache_free(dquot_cachep, dquot); do_destroy_dquot(dquot);
count--; count--;
head = free_dquots.prev; head = free_dquots.prev;
} }
...@@ -625,11 +635,16 @@ static void dqput(struct dquot *dquot) ...@@ -625,11 +635,16 @@ static void dqput(struct dquot *dquot)
spin_unlock(&dq_list_lock); 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) static struct dquot *get_empty_dquot(struct super_block *sb, int type)
{ {
struct dquot *dquot; struct dquot *dquot;
dquot = kmem_cache_zalloc(dquot_cachep, GFP_NOFS); dquot = sb->dq_op->alloc_dquot(sb, type);
if(!dquot) if(!dquot)
return NODQUOT; return NODQUOT;
...@@ -682,7 +697,7 @@ static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) ...@@ -682,7 +697,7 @@ static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
dqstats.lookups++; dqstats.lookups++;
spin_unlock(&dq_list_lock); spin_unlock(&dq_list_lock);
if (empty) 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 /* 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 */ * finished or it will be canceled due to dq_count > 1 test */
...@@ -1533,7 +1548,9 @@ struct dquot_operations dquot_operations = { ...@@ -1533,7 +1548,9 @@ struct dquot_operations dquot_operations = {
.acquire_dquot = dquot_acquire, .acquire_dquot = dquot_acquire,
.release_dquot = dquot_release, .release_dquot = dquot_release,
.mark_dirty = dquot_mark_dquot_dirty, .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) static inline void set_enable_flags(struct quota_info *dqopt, int type)
......
...@@ -292,6 +292,8 @@ struct dquot_operations { ...@@ -292,6 +292,8 @@ struct dquot_operations {
int (*free_inode) (const struct inode *, unsigned long); int (*free_inode) (const struct inode *, unsigned long);
int (*transfer) (struct inode *, struct iattr *); int (*transfer) (struct inode *, struct iattr *);
int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ int (*write_dquot) (struct dquot *); /* Ordinary dquot write */
struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */
void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */
int (*acquire_dquot) (struct dquot *); /* Quota is going to be created on disk */ int (*acquire_dquot) (struct dquot *); /* Quota is going to be created on disk */
int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */ int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */
int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */ int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment