aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorMingming Cao <cmm@us.ibm.com>2009-01-13 10:43:09 -0500
committerJan Kara <jack@suse.cz>2009-03-25 21:15:50 -0400
commitf18df228997fb716990590d248663981a15f17d4 (patch)
treef5fc935b09cddde325235c265fd3a553ee40af51 /include/linux
parent8e0ee43bc2c3e19db56a4adaa9a9b04ce885cd84 (diff)
quota: Add quota reservation support
Delayed allocation defers the block allocation at the dirty pages flush-out time, doing quota charge/check at that time is too late. But we can't charge the quota blocks until blocks are really allocated, otherwise users could get overcharged after reboot from system crash. This patch adds quota reservation for delayed allocation. Quota blocks are reserved in memory, inode and quota won't gets dirtied until later block allocation time. Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/quota.h3
-rw-r--r--include/linux/quotaops.h21
2 files changed, 24 insertions, 0 deletions
diff --git a/include/linux/quota.h b/include/linux/quota.h
index d72d5d84fde5..54b837fa64f2 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -198,6 +198,7 @@ struct mem_dqblk {
198 qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ 198 qsize_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
199 qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */ 199 qsize_t dqb_bsoftlimit; /* preferred limit on disk blks */
200 qsize_t dqb_curspace; /* current used space */ 200 qsize_t dqb_curspace; /* current used space */
201 qsize_t dqb_rsvspace; /* current reserved space for delalloc*/
201 qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */ 202 qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */
202 qsize_t dqb_isoftlimit; /* preferred inode limit */ 203 qsize_t dqb_isoftlimit; /* preferred inode limit */
203 qsize_t dqb_curinodes; /* current # allocated inodes */ 204 qsize_t dqb_curinodes; /* current # allocated inodes */
@@ -308,6 +309,8 @@ struct dquot_operations {
308 int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */ 309 int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */
309 int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */ 310 int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */
310 int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */ 311 int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */
312 /* reserve quota for delayed block allocation */
313 int (*reserve_space) (struct inode *, qsize_t, int);
311}; 314};
312 315
313/* Operations handling requests from userspace */ 316/* Operations handling requests from userspace */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 0b35b3a1be05..3e3a0d2874d9 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -183,6 +183,16 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
183 return ret; 183 return ret;
184} 184}
185 185
186static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
187{
188 if (sb_any_quota_active(inode->i_sb)) {
189 /* Used space is updated in alloc_space() */
190 if (inode->i_sb->dq_op->reserve_space(inode, nr, 0) == NO_QUOTA)
191 return 1;
192 }
193 return 0;
194}
195
186static inline int vfs_dq_alloc_inode(struct inode *inode) 196static inline int vfs_dq_alloc_inode(struct inode *inode)
187{ 197{
188 if (sb_any_quota_active(inode->i_sb)) { 198 if (sb_any_quota_active(inode->i_sb)) {
@@ -339,6 +349,11 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
339 return 0; 349 return 0;
340} 350}
341 351
352static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
353{
354 return 0;
355}
356
342static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr) 357static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
343{ 358{
344 inode_sub_bytes(inode, nr); 359 inode_sub_bytes(inode, nr);
@@ -376,6 +391,12 @@ static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr)
376 nr << inode->i_sb->s_blocksize_bits); 391 nr << inode->i_sb->s_blocksize_bits);
377} 392}
378 393
394static inline int vfs_dq_reserve_block(struct inode *inode, qsize_t nr)
395{
396 return vfs_dq_reserve_space(inode,
397 nr << inode->i_blkbits);
398}
399
379static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr) 400static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr)
380{ 401{
381 vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits); 402 vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits);