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); |
