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>
This commit is contained in:
parent
9f868f16e4
commit
74f783af95
27
fs/dquot.c
27
fs/dquot.c
|
@ -415,6 +415,16 @@ out_dqlock:
|
||||||
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 @@ restart:
|
||||||
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)
|
||||||
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 @@ we_slept:
|
||||||
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 @@ we_slept:
|
||||||
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 = {
|
||||||
.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 {
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in New Issue