diff options
-rw-r--r-- | fs/quota/dquot.c | 46 | ||||
-rw-r--r-- | fs/stat.c | 11 | ||||
-rw-r--r-- | include/linux/fs.h | 1 | ||||
-rw-r--r-- | include/linux/quotaops.h | 15 |
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 | ||
1097 | static 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 | |||
1097 | static inline | 1105 | static inline |
1098 | void dquot_free_reserved_space(struct dquot *dquot, qsize_t number) | 1106 | void 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 | } |
1529 | EXPORT_SYMBOL(inode_claim_rsv_space); | 1537 | EXPORT_SYMBOL(inode_claim_rsv_space); |
1530 | 1538 | ||
1539 | void 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 | } | ||
1546 | EXPORT_SYMBOL(inode_reclaim_rsv_space); | ||
1547 | |||
1531 | void inode_sub_rsv_space(struct inode *inode, qsize_t number) | 1548 | void 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) | |||
1702 | EXPORT_SYMBOL(dquot_claim_space_nodirty); | 1719 | EXPORT_SYMBOL(dquot_claim_space_nodirty); |
1703 | 1720 | ||
1704 | /* | 1721 | /* |
1722 | * Convert allocated space back to in-memory reserved quotas | ||
1723 | */ | ||
1724 | void 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 | } | ||
1748 | EXPORT_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 | */ |
1707 | void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | 1753 | void __dquot_free_space(struct inode *inode, qsize_t number, int flags) |
@@ -447,9 +447,8 @@ void inode_add_bytes(struct inode *inode, loff_t bytes) | |||
447 | 447 | ||
448 | EXPORT_SYMBOL(inode_add_bytes); | 448 | EXPORT_SYMBOL(inode_add_bytes); |
449 | 449 | ||
450 | void inode_sub_bytes(struct inode *inode, loff_t bytes) | 450 | void __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 | |||
461 | EXPORT_SYMBOL(__inode_sub_bytes); | ||
462 | |||
463 | void 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 *); | |||
2503 | extern int vfs_getattr(struct path *, struct kstat *); | 2503 | extern int vfs_getattr(struct path *, struct kstat *); |
2504 | void __inode_add_bytes(struct inode *inode, loff_t bytes); | 2504 | void __inode_add_bytes(struct inode *inode, loff_t bytes); |
2505 | void inode_add_bytes(struct inode *inode, loff_t bytes); | 2505 | void inode_add_bytes(struct inode *inode, loff_t bytes); |
2506 | void __inode_sub_bytes(struct inode *inode, loff_t bytes); | ||
2506 | void inode_sub_bytes(struct inode *inode, loff_t bytes); | 2507 | void inode_sub_bytes(struct inode *inode, loff_t bytes); |
2507 | loff_t inode_get_bytes(struct inode *inode); | 2508 | loff_t inode_get_bytes(struct inode *inode); |
2508 | void inode_set_bytes(struct inode *inode, loff_t bytes); | 2509 | void 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, | |||
41 | void inode_add_rsv_space(struct inode *inode, qsize_t number); | 41 | void inode_add_rsv_space(struct inode *inode, qsize_t number); |
42 | void inode_claim_rsv_space(struct inode *inode, qsize_t number); | 42 | void inode_claim_rsv_space(struct inode *inode, qsize_t number); |
43 | void inode_sub_rsv_space(struct inode *inode, qsize_t number); | 43 | void inode_sub_rsv_space(struct inode *inode, qsize_t number); |
44 | void inode_reclaim_rsv_space(struct inode *inode, qsize_t number); | ||
44 | 45 | ||
45 | void dquot_initialize(struct inode *inode); | 46 | void dquot_initialize(struct inode *inode); |
46 | void dquot_drop(struct inode *inode); | 47 | void dquot_drop(struct inode *inode); |
@@ -59,6 +60,7 @@ int dquot_alloc_inode(const struct inode *inode); | |||
59 | 60 | ||
60 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); | 61 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); |
61 | void dquot_free_inode(const struct inode *inode); | 62 | void dquot_free_inode(const struct inode *inode); |
63 | void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number); | ||
62 | 64 | ||
63 | int dquot_disable(struct super_block *sb, int type, unsigned int flags); | 65 | int 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 | ||
243 | static 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 | |||
241 | static inline int dquot_disable(struct super_block *sb, int type, | 250 | static 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 | ||
348 | static 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 | |||
339 | static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr) | 354 | static 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); |