Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfs: protect i_nlink

Prevent direct modification of i_nlink by making it const and adding a
non-const __i_nlink alias.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Tested-by: Toshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Miklos Szeredi and committed by
Christoph Hellwig
a78ef704 bfe86848

+16 -6
+1 -1
fs/inode.c
··· 142 142 atomic_set(&inode->i_count, 1); 143 143 inode->i_op = &empty_iops; 144 144 inode->i_fop = &empty_fops; 145 - inode->i_nlink = 1; 145 + inode->__i_nlink = 1; 146 146 inode->i_opflags = 0; 147 147 inode->i_uid = 0; 148 148 inode->i_gid = 0;
+15 -5
include/linux/fs.h
··· 768 768 769 769 /* Stat data, not accessed from path walking */ 770 770 unsigned long i_ino; 771 - unsigned int i_nlink; 771 + /* 772 + * Filesystems may only read i_nlink directly. They shall use the 773 + * following functions for modification: 774 + * 775 + * (set|clear|inc|drop)_nlink 776 + * inode_(inc|dec)_link_count 777 + */ 778 + union { 779 + const unsigned int i_nlink; 780 + unsigned int __i_nlink; 781 + }; 772 782 dev_t i_rdev; 773 783 loff_t i_size; 774 784 struct timespec i_atime; ··· 1774 1764 */ 1775 1765 static inline void set_nlink(struct inode *inode, unsigned int nlink) 1776 1766 { 1777 - inode->i_nlink = nlink; 1767 + inode->__i_nlink = nlink; 1778 1768 } 1779 1769 1780 1770 /** ··· 1787 1777 */ 1788 1778 static inline void inc_nlink(struct inode *inode) 1789 1779 { 1790 - inode->i_nlink++; 1780 + inode->__i_nlink++; 1791 1781 } 1792 1782 1793 1783 static inline void inode_inc_link_count(struct inode *inode) ··· 1809 1799 */ 1810 1800 static inline void drop_nlink(struct inode *inode) 1811 1801 { 1812 - inode->i_nlink--; 1802 + inode->__i_nlink--; 1813 1803 } 1814 1804 1815 1805 /** ··· 1822 1812 */ 1823 1813 static inline void clear_nlink(struct inode *inode) 1824 1814 { 1825 - inode->i_nlink = 0; 1815 + inode->__i_nlink = 0; 1826 1816 } 1827 1817 1828 1818 static inline void inode_dec_link_count(struct inode *inode)