aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ufs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-02-06 12:45:27 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-03-20 21:29:32 -0400
commit8de52778798fe39660a8d6b26f290e0c93202761 (patch)
tree56384beb7863c1f338f2b66b509bf58eea5a99c2 /fs/ufs
parentc16fa4f2ad19908a47c63d8fa436a1178438c7e7 (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/ufs')
-rw-r--r--fs/ufs/namei.c14
-rw-r--r--fs/ufs/super.c1
2 files changed, 2 insertions, 13 deletions
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 38cac199edff..a2281cadefa1 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -166,10 +166,6 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
166 int error; 166 int error;
167 167
168 lock_ufs(dir->i_sb); 168 lock_ufs(dir->i_sb);
169 if (inode->i_nlink >= UFS_LINK_MAX) {
170 unlock_ufs(dir->i_sb);
171 return -EMLINK;
172 }
173 169
174 inode->i_ctime = CURRENT_TIME_SEC; 170 inode->i_ctime = CURRENT_TIME_SEC;
175 inode_inc_link_count(inode); 171 inode_inc_link_count(inode);
@@ -183,10 +179,7 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
183static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) 179static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
184{ 180{
185 struct inode * inode; 181 struct inode * inode;
186 int err = -EMLINK; 182 int err;
187
188 if (dir->i_nlink >= UFS_LINK_MAX)
189 goto out;
190 183
191 lock_ufs(dir->i_sb); 184 lock_ufs(dir->i_sb);
192 inode_inc_link_count(dir); 185 inode_inc_link_count(dir);
@@ -305,11 +298,6 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
305 drop_nlink(new_inode); 298 drop_nlink(new_inode);
306 inode_dec_link_count(new_inode); 299 inode_dec_link_count(new_inode);
307 } else { 300 } else {
308 if (dir_de) {
309 err = -EMLINK;
310 if (new_dir->i_nlink >= UFS_LINK_MAX)
311 goto out_dir;
312 }
313 err = ufs_add_link(new_dentry, old_inode); 301 err = ufs_add_link(new_dentry, old_inode);
314 if (err) 302 if (err)
315 goto out_dir; 303 goto out_dir;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 5246ee3e5607..ec25d09fcaa8 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1157,6 +1157,7 @@ magic_found:
1157 "fast symlink size (%u)\n", uspi->s_maxsymlinklen); 1157 "fast symlink size (%u)\n", uspi->s_maxsymlinklen);
1158 uspi->s_maxsymlinklen = maxsymlen; 1158 uspi->s_maxsymlinklen = maxsymlen;
1159 } 1159 }
1160 sb->s_max_links = UFS_LINK_MAX;
1160 1161
1161 inode = ufs_iget(sb, UFS_ROOTINO); 1162 inode = ufs_iget(sb, UFS_ROOTINO);
1162 if (IS_ERR(inode)) { 1163 if (IS_ERR(inode)) {