diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2011-11-21 06:11:32 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-01-06 23:20:12 -0500 |
commit | 7ada4db88634429f4da690ad1c4eb73c93085f0c (patch) | |
tree | ed1228f0bfa9d0050d746933595004d7c6e940f9 /include/linux/fs.h | |
parent | 4ed5e82fe77f4147cf386327c9a63a2dd7eff518 (diff) |
vfs: count unlinked inodes
Add a new counter to the superblock that keeps track of unlinked but
not yet deleted inodes.
Do not WARN_ON if set_nlink is called with zero count, just do a
ratelimited printk. This happens on xfs and probably other
filesystems after an unclean shutdown when the filesystem reads inodes
which already have zero i_nlink. Reported by Christoph Hellwig.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Tested-by: Toshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux/fs.h')
-rw-r--r-- | include/linux/fs.h | 61 |
1 files changed, 7 insertions, 54 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 7b8a681b1ef4..8ac40921f5ac 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1483,6 +1483,9 @@ struct super_block { | |||
1483 | 1483 | ||
1484 | struct shrinker s_shrink; /* per-sb shrinker handle */ | 1484 | struct shrinker s_shrink; /* per-sb shrinker handle */ |
1485 | 1485 | ||
1486 | /* Number of inodes with nlink == 0 but still referenced */ | ||
1487 | atomic_long_t s_remove_count; | ||
1488 | |||
1486 | /* Being remounted read-only */ | 1489 | /* Being remounted read-only */ |
1487 | int s_readonly_remount; | 1490 | int s_readonly_remount; |
1488 | }; | 1491 | }; |
@@ -1768,31 +1771,10 @@ static inline void mark_inode_dirty_sync(struct inode *inode) | |||
1768 | __mark_inode_dirty(inode, I_DIRTY_SYNC); | 1771 | __mark_inode_dirty(inode, I_DIRTY_SYNC); |
1769 | } | 1772 | } |
1770 | 1773 | ||
1771 | /** | 1774 | extern void inc_nlink(struct inode *inode); |
1772 | * set_nlink - directly set an inode's link count | 1775 | extern void drop_nlink(struct inode *inode); |
1773 | * @inode: inode | 1776 | extern void clear_nlink(struct inode *inode); |
1774 | * @nlink: new nlink (should be non-zero) | 1777 | extern void set_nlink(struct inode *inode, unsigned int nlink); |
1775 | * | ||
1776 | * This is a low-level filesystem helper to replace any | ||
1777 | * direct filesystem manipulation of i_nlink. | ||
1778 | */ | ||
1779 | static inline void set_nlink(struct inode *inode, unsigned int nlink) | ||
1780 | { | ||
1781 | inode->__i_nlink = nlink; | ||
1782 | } | ||
1783 | |||
1784 | /** | ||
1785 | * inc_nlink - directly increment an inode's link count | ||
1786 | * @inode: inode | ||
1787 | * | ||
1788 | * This is a low-level filesystem helper to replace any | ||
1789 | * direct filesystem manipulation of i_nlink. Currently, | ||
1790 | * it is only here for parity with dec_nlink(). | ||
1791 | */ | ||
1792 | static inline void inc_nlink(struct inode *inode) | ||
1793 | { | ||
1794 | inode->__i_nlink++; | ||
1795 | } | ||
1796 | 1778 | ||
1797 | static inline void inode_inc_link_count(struct inode *inode) | 1779 | static inline void inode_inc_link_count(struct inode *inode) |
1798 | { | 1780 | { |
@@ -1800,35 +1782,6 @@ static inline void inode_inc_link_count(struct inode *inode) | |||
1800 | mark_inode_dirty(inode); | 1782 | mark_inode_dirty(inode); |
1801 | } | 1783 | } |
1802 | 1784 | ||
1803 | /** | ||
1804 | * drop_nlink - directly drop an inode's link count | ||
1805 | * @inode: inode | ||
1806 | * | ||
1807 | * This is a low-level filesystem helper to replace any | ||
1808 | * direct filesystem manipulation of i_nlink. In cases | ||
1809 | * where we are attempting to track writes to the | ||
1810 | * filesystem, a decrement to zero means an imminent | ||
1811 | * write when the file is truncated and actually unlinked | ||
1812 | * on the filesystem. | ||
1813 | */ | ||
1814 | static inline void drop_nlink(struct inode *inode) | ||
1815 | { | ||
1816 | inode->__i_nlink--; | ||
1817 | } | ||
1818 | |||
1819 | /** | ||
1820 | * clear_nlink - directly zero an inode's link count | ||
1821 | * @inode: inode | ||
1822 | * | ||
1823 | * This is a low-level filesystem helper to replace any | ||
1824 | * direct filesystem manipulation of i_nlink. See | ||
1825 | * drop_nlink() for why we care about i_nlink hitting zero. | ||
1826 | */ | ||
1827 | static inline void clear_nlink(struct inode *inode) | ||
1828 | { | ||
1829 | inode->__i_nlink = 0; | ||
1830 | } | ||
1831 | |||
1832 | static inline void inode_dec_link_count(struct inode *inode) | 1785 | static inline void inode_dec_link_count(struct inode *inode) |
1833 | { | 1786 | { |
1834 | drop_nlink(inode); | 1787 | drop_nlink(inode); |