diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2011-10-28 14:13:30 +0200 |
---|---|---|
committer | Christoph Hellwig <hch@serles.lst.de> | 2011-11-02 12:53:43 +0100 |
commit | a78ef704a8dd430225955f0709b22d4a6ba21deb (patch) | |
tree | ebd8f8a5a257077912b7cc38ecfdab43e1d7d73d | |
parent | bfe8684869601dacfcb2cd69ef8cfd9045f62170 (diff) |
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>
-rw-r--r-- | fs/inode.c | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 20 |
2 files changed, 16 insertions, 6 deletions
diff --git a/fs/inode.c b/fs/inode.c index ecbb68dc7e2..ee4e66b998f 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -142,7 +142,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode) atomic_set(&inode->i_count, 1); inode->i_op = &empty_iops; inode->i_fop = &empty_fops; - inode->i_nlink = 1; + inode->__i_nlink = 1; inode->i_opflags = 0; inode->i_uid = 0; inode->i_gid = 0; diff --git a/include/linux/fs.h b/include/linux/fs.h index 48c1f5fc741..23467d768ca 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -768,7 +768,17 @@ struct inode { /* Stat data, not accessed from path walking */ unsigned long i_ino; - unsigned int i_nlink; + /* + * Filesystems may only read i_nlink directly. They shall use the + * following functions for modification: + * + * (set|clear|inc|drop)_nlink + * inode_(inc|dec)_link_count + */ + union { + const unsigned int i_nlink; + unsigned int __i_nlink; + }; dev_t i_rdev; loff_t i_size; struct timespec i_atime; @@ -1764,7 +1774,7 @@ static inline void mark_inode_dirty_sync(struct inode *inode) */ static inline void set_nlink(struct inode *inode, unsigned int nlink) { - inode->i_nlink = nlink; + inode->__i_nlink = nlink; } /** @@ -1777,7 +1787,7 @@ static inline void set_nlink(struct inode *inode, unsigned int nlink) */ static inline void inc_nlink(struct inode *inode) { - inode->i_nlink++; + inode->__i_nlink++; } static inline void inode_inc_link_count(struct inode *inode) @@ -1799,7 +1809,7 @@ static inline void inode_inc_link_count(struct inode *inode) */ static inline void drop_nlink(struct inode *inode) { - inode->i_nlink--; + inode->__i_nlink--; } /** @@ -1812,7 +1822,7 @@ static inline void drop_nlink(struct inode *inode) */ static inline void clear_nlink(struct inode *inode) { - inode->i_nlink = 0; + inode->__i_nlink = 0; } static inline void inode_dec_link_count(struct inode *inode) |