aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2013-08-17 09:32:32 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-08-17 09:32:32 -0400
commit1c8924eb106c1ac755d5d35ce9b3ff42e89e2511 (patch)
tree8e47b0d4121cffc818dfd28399fbfebd09e817a2
parent19883bd9658d0dc269fc228b1b39db3615f7c7b0 (diff)
quota: provide interface for readding allocated space into reserved space
ext4 needs to convert allocated (metadata) blocks back into blocks reserved for delayed allocation. Add functions into quota code for supporting such operation. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/quota/dquot.c46
-rw-r--r--fs/stat.c11
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/quotaops.h15
4 files changed, 71 insertions, 2 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index fbad622841f9..9a702e193538 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1094,6 +1094,14 @@ static void dquot_claim_reserved_space(struct dquot *dquot, qsize_t number)
1094 dquot->dq_dqb.dqb_rsvspace -= number; 1094 dquot->dq_dqb.dqb_rsvspace -= number;
1095} 1095}
1096 1096
1097static void dquot_reclaim_reserved_space(struct dquot *dquot, qsize_t number)
1098{
1099 if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number))
1100 number = dquot->dq_dqb.dqb_curspace;
1101 dquot->dq_dqb.dqb_rsvspace += number;
1102 dquot->dq_dqb.dqb_curspace -= number;
1103}
1104
1097static inline 1105static inline
1098void dquot_free_reserved_space(struct dquot *dquot, qsize_t number) 1106void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
1099{ 1107{
@@ -1528,6 +1536,15 @@ void inode_claim_rsv_space(struct inode *inode, qsize_t number)
1528} 1536}
1529EXPORT_SYMBOL(inode_claim_rsv_space); 1537EXPORT_SYMBOL(inode_claim_rsv_space);
1530 1538
1539void inode_reclaim_rsv_space(struct inode *inode, qsize_t number)
1540{
1541 spin_lock(&inode->i_lock);
1542 *inode_reserved_space(inode) += number;
1543 __inode_sub_bytes(inode, number);
1544 spin_unlock(&inode->i_lock);
1545}
1546EXPORT_SYMBOL(inode_reclaim_rsv_space);
1547
1531void inode_sub_rsv_space(struct inode *inode, qsize_t number) 1548void inode_sub_rsv_space(struct inode *inode, qsize_t number)
1532{ 1549{
1533 spin_lock(&inode->i_lock); 1550 spin_lock(&inode->i_lock);
@@ -1702,6 +1719,35 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
1702EXPORT_SYMBOL(dquot_claim_space_nodirty); 1719EXPORT_SYMBOL(dquot_claim_space_nodirty);
1703 1720
1704/* 1721/*
1722 * Convert allocated space back to in-memory reserved quotas
1723 */
1724void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
1725{
1726 int cnt;
1727
1728 if (!dquot_active(inode)) {
1729 inode_reclaim_rsv_space(inode, number);
1730 return;
1731 }
1732
1733 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1734 spin_lock(&dq_data_lock);
1735 /* Claim reserved quotas to allocated quotas */
1736 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1737 if (inode->i_dquot[cnt])
1738 dquot_reclaim_reserved_space(inode->i_dquot[cnt],
1739 number);
1740 }
1741 /* Update inode bytes */
1742 inode_reclaim_rsv_space(inode, number);
1743 spin_unlock(&dq_data_lock);
1744 mark_all_dquot_dirty(inode->i_dquot);
1745 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1746 return;
1747}
1748EXPORT_SYMBOL(dquot_reclaim_space_nodirty);
1749
1750/*
1705 * This operation can block, but only after everything is updated 1751 * This operation can block, but only after everything is updated
1706 */ 1752 */
1707void __dquot_free_space(struct inode *inode, qsize_t number, int flags) 1753void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
diff --git a/fs/stat.c b/fs/stat.c
index 04ce1ac20d20..d0ea7ef75e26 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -447,9 +447,8 @@ void inode_add_bytes(struct inode *inode, loff_t bytes)
447 447
448EXPORT_SYMBOL(inode_add_bytes); 448EXPORT_SYMBOL(inode_add_bytes);
449 449
450void inode_sub_bytes(struct inode *inode, loff_t bytes) 450void __inode_sub_bytes(struct inode *inode, loff_t bytes)
451{ 451{
452 spin_lock(&inode->i_lock);
453 inode->i_blocks -= bytes >> 9; 452 inode->i_blocks -= bytes >> 9;
454 bytes &= 511; 453 bytes &= 511;
455 if (inode->i_bytes < bytes) { 454 if (inode->i_bytes < bytes) {
@@ -457,6 +456,14 @@ void inode_sub_bytes(struct inode *inode, loff_t bytes)
457 inode->i_bytes += 512; 456 inode->i_bytes += 512;
458 } 457 }
459 inode->i_bytes -= bytes; 458 inode->i_bytes -= bytes;
459}
460
461EXPORT_SYMBOL(__inode_sub_bytes);
462
463void inode_sub_bytes(struct inode *inode, loff_t bytes)
464{
465 spin_lock(&inode->i_lock);
466 __inode_sub_bytes(inode, bytes);
460 spin_unlock(&inode->i_lock); 467 spin_unlock(&inode->i_lock);
461} 468}
462 469
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 981874773e85..e7893523f81f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2503,6 +2503,7 @@ extern void generic_fillattr(struct inode *, struct kstat *);
2503extern int vfs_getattr(struct path *, struct kstat *); 2503extern int vfs_getattr(struct path *, struct kstat *);
2504void __inode_add_bytes(struct inode *inode, loff_t bytes); 2504void __inode_add_bytes(struct inode *inode, loff_t bytes);
2505void inode_add_bytes(struct inode *inode, loff_t bytes); 2505void inode_add_bytes(struct inode *inode, loff_t bytes);
2506void __inode_sub_bytes(struct inode *inode, loff_t bytes);
2506void inode_sub_bytes(struct inode *inode, loff_t bytes); 2507void inode_sub_bytes(struct inode *inode, loff_t bytes);
2507loff_t inode_get_bytes(struct inode *inode); 2508loff_t inode_get_bytes(struct inode *inode);
2508void inode_set_bytes(struct inode *inode, loff_t bytes); 2509void inode_set_bytes(struct inode *inode, loff_t bytes);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 1c50093ae656..6965fe394c3b 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -41,6 +41,7 @@ void __quota_error(struct super_block *sb, const char *func,
41void inode_add_rsv_space(struct inode *inode, qsize_t number); 41void inode_add_rsv_space(struct inode *inode, qsize_t number);
42void inode_claim_rsv_space(struct inode *inode, qsize_t number); 42void inode_claim_rsv_space(struct inode *inode, qsize_t number);
43void inode_sub_rsv_space(struct inode *inode, qsize_t number); 43void inode_sub_rsv_space(struct inode *inode, qsize_t number);
44void inode_reclaim_rsv_space(struct inode *inode, qsize_t number);
44 45
45void dquot_initialize(struct inode *inode); 46void dquot_initialize(struct inode *inode);
46void dquot_drop(struct inode *inode); 47void dquot_drop(struct inode *inode);
@@ -59,6 +60,7 @@ int dquot_alloc_inode(const struct inode *inode);
59 60
60int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); 61int dquot_claim_space_nodirty(struct inode *inode, qsize_t number);
61void dquot_free_inode(const struct inode *inode); 62void dquot_free_inode(const struct inode *inode);
63void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number);
62 64
63int dquot_disable(struct super_block *sb, int type, unsigned int flags); 65int dquot_disable(struct super_block *sb, int type, unsigned int flags);
64/* Suspend quotas on remount RO */ 66/* Suspend quotas on remount RO */
@@ -238,6 +240,13 @@ static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
238 return 0; 240 return 0;
239} 241}
240 242
243static inline int dquot_reclaim_space_nodirty(struct inode *inode,
244 qsize_t number)
245{
246 inode_sub_bytes(inode, number);
247 return 0;
248}
249
241static inline int dquot_disable(struct super_block *sb, int type, 250static inline int dquot_disable(struct super_block *sb, int type,
242 unsigned int flags) 251 unsigned int flags)
243{ 252{
@@ -336,6 +345,12 @@ static inline int dquot_claim_block(struct inode *inode, qsize_t nr)
336 return ret; 345 return ret;
337} 346}
338 347
348static inline void dquot_reclaim_block(struct inode *inode, qsize_t nr)
349{
350 dquot_reclaim_space_nodirty(inode, nr << inode->i_blkbits);
351 mark_inode_dirty_sync(inode);
352}
353
339static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr) 354static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr)
340{ 355{
341 __dquot_free_space(inode, nr, 0); 356 __dquot_free_space(inode, nr, 0);