diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-02-06 12:45:27 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-03-20 21:29:32 -0400 |
commit | 8de52778798fe39660a8d6b26f290e0c93202761 (patch) | |
tree | 56384beb7863c1f338f2b66b509bf58eea5a99c2 /fs/exofs | |
parent | c16fa4f2ad19908a47c63d8fa436a1178438c7e7 (diff) |
vfs: check i_nlink limits in vfs_{mkdir,rename_dir,link}
New field of struct super_block - ->s_max_links. Maximal allowed
value of ->i_nlink or 0; in the latter case all checks still need
to be done in ->link/->mkdir/->rename instances. Note that this
limit applies both to directoris and to non-directories.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/exofs')
-rw-r--r-- | fs/exofs/namei.c | 13 | ||||
-rw-r--r-- | fs/exofs/super.c | 1 |
2 files changed, 2 insertions, 12 deletions
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index 9dbf0c301030..fc7161d6bf6b 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c | |||
@@ -143,9 +143,6 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir, | |||
143 | { | 143 | { |
144 | struct inode *inode = old_dentry->d_inode; | 144 | struct inode *inode = old_dentry->d_inode; |
145 | 145 | ||
146 | if (inode->i_nlink >= EXOFS_LINK_MAX) | ||
147 | return -EMLINK; | ||
148 | |||
149 | inode->i_ctime = CURRENT_TIME; | 146 | inode->i_ctime = CURRENT_TIME; |
150 | inode_inc_link_count(inode); | 147 | inode_inc_link_count(inode); |
151 | ihold(inode); | 148 | ihold(inode); |
@@ -156,10 +153,7 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir, | |||
156 | static int exofs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 153 | static int exofs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
157 | { | 154 | { |
158 | struct inode *inode; | 155 | struct inode *inode; |
159 | int err = -EMLINK; | 156 | int err; |
160 | |||
161 | if (dir->i_nlink >= EXOFS_LINK_MAX) | ||
162 | goto out; | ||
163 | 157 | ||
164 | inode_inc_link_count(dir); | 158 | inode_inc_link_count(dir); |
165 | 159 | ||
@@ -275,11 +269,6 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
275 | if (err) | 269 | if (err) |
276 | goto out_dir; | 270 | goto out_dir; |
277 | } else { | 271 | } else { |
278 | if (dir_de) { | ||
279 | err = -EMLINK; | ||
280 | if (new_dir->i_nlink >= EXOFS_LINK_MAX) | ||
281 | goto out_dir; | ||
282 | } | ||
283 | err = exofs_add_link(new_dentry, old_inode); | 272 | err = exofs_add_link(new_dentry, old_inode); |
284 | if (err) | 273 | if (err) |
285 | goto out_dir; | 274 | goto out_dir; |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index d22cd168c6ee..6cafcadfc3c8 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -754,6 +754,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
754 | sb->s_blocksize = EXOFS_BLKSIZE; | 754 | sb->s_blocksize = EXOFS_BLKSIZE; |
755 | sb->s_blocksize_bits = EXOFS_BLKSHIFT; | 755 | sb->s_blocksize_bits = EXOFS_BLKSHIFT; |
756 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 756 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
757 | sb->s_max_links = EXOFS_LINK_MAX; | ||
757 | atomic_set(&sbi->s_curr_pending, 0); | 758 | atomic_set(&sbi->s_curr_pending, 0); |
758 | sb->s_bdev = NULL; | 759 | sb->s_bdev = NULL; |
759 | sb->s_dev = 0; | 760 | sb->s_dev = 0; |