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 | |
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>
-rw-r--r-- | fs/exofs/namei.c | 13 | ||||
-rw-r--r-- | fs/exofs/super.c | 1 | ||||
-rw-r--r-- | fs/ext2/namei.c | 13 | ||||
-rw-r--r-- | fs/ext2/super.c | 1 | ||||
-rw-r--r-- | fs/jfs/namei.c | 13 | ||||
-rw-r--r-- | fs/jfs/super.c | 1 | ||||
-rw-r--r-- | fs/logfs/dir.c | 3 | ||||
-rw-r--r-- | fs/logfs/super.c | 1 | ||||
-rw-r--r-- | fs/minix/inode.c | 10 | ||||
-rw-r--r-- | fs/minix/minix.h | 1 | ||||
-rw-r--r-- | fs/minix/namei.c | 14 | ||||
-rw-r--r-- | fs/namei.c | 13 | ||||
-rw-r--r-- | fs/nilfs2/namei.c | 11 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 1 | ||||
-rw-r--r-- | fs/sysv/namei.c | 12 | ||||
-rw-r--r-- | fs/sysv/super.c | 24 | ||||
-rw-r--r-- | fs/sysv/sysv.h | 1 | ||||
-rw-r--r-- | fs/udf/namei.c | 13 | ||||
-rw-r--r-- | fs/udf/super.c | 3 | ||||
-rw-r--r-- | fs/ufs/namei.c | 14 | ||||
-rw-r--r-- | fs/ufs/super.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_rename.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_utils.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 16 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
26 files changed, 46 insertions, 149 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; |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 080419814bae..dffb86536285 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -195,9 +195,6 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, | |||
195 | struct inode *inode = old_dentry->d_inode; | 195 | struct inode *inode = old_dentry->d_inode; |
196 | int err; | 196 | int err; |
197 | 197 | ||
198 | if (inode->i_nlink >= EXT2_LINK_MAX) | ||
199 | return -EMLINK; | ||
200 | |||
201 | dquot_initialize(dir); | 198 | dquot_initialize(dir); |
202 | 199 | ||
203 | inode->i_ctime = CURRENT_TIME_SEC; | 200 | inode->i_ctime = CURRENT_TIME_SEC; |
@@ -217,10 +214,7 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, | |||
217 | static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | 214 | static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) |
218 | { | 215 | { |
219 | struct inode * inode; | 216 | struct inode * inode; |
220 | int err = -EMLINK; | 217 | int err; |
221 | |||
222 | if (dir->i_nlink >= EXT2_LINK_MAX) | ||
223 | goto out; | ||
224 | 218 | ||
225 | dquot_initialize(dir); | 219 | dquot_initialize(dir); |
226 | 220 | ||
@@ -346,11 +340,6 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
346 | drop_nlink(new_inode); | 340 | drop_nlink(new_inode); |
347 | inode_dec_link_count(new_inode); | 341 | inode_dec_link_count(new_inode); |
348 | } else { | 342 | } else { |
349 | if (dir_de) { | ||
350 | err = -EMLINK; | ||
351 | if (new_dir->i_nlink >= EXT2_LINK_MAX) | ||
352 | goto out_dir; | ||
353 | } | ||
354 | err = ext2_add_link(new_dentry, old_inode); | 343 | err = ext2_add_link(new_dentry, old_inode); |
355 | if (err) | 344 | if (err) |
356 | goto out_dir; | 345 | goto out_dir; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 0090595beb28..9f6766a3ac1e 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -919,6 +919,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
919 | } | 919 | } |
920 | 920 | ||
921 | sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits); | 921 | sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits); |
922 | sb->s_max_links = EXT2_LINK_MAX; | ||
922 | 923 | ||
923 | if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) { | 924 | if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) { |
924 | sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE; | 925 | sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE; |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 5f7c160ea64f..07c91ca6017d 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -220,12 +220,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) | |||
220 | 220 | ||
221 | dquot_initialize(dip); | 221 | dquot_initialize(dip); |
222 | 222 | ||
223 | /* link count overflow on parent directory ? */ | ||
224 | if (dip->i_nlink == JFS_LINK_MAX) { | ||
225 | rc = -EMLINK; | ||
226 | goto out1; | ||
227 | } | ||
228 | |||
229 | /* | 223 | /* |
230 | * search parent directory for entry/freespace | 224 | * search parent directory for entry/freespace |
231 | * (dtSearch() returns parent directory page pinned) | 225 | * (dtSearch() returns parent directory page pinned) |
@@ -806,9 +800,6 @@ static int jfs_link(struct dentry *old_dentry, | |||
806 | jfs_info("jfs_link: %s %s", old_dentry->d_name.name, | 800 | jfs_info("jfs_link: %s %s", old_dentry->d_name.name, |
807 | dentry->d_name.name); | 801 | dentry->d_name.name); |
808 | 802 | ||
809 | if (ip->i_nlink == JFS_LINK_MAX) | ||
810 | return -EMLINK; | ||
811 | |||
812 | dquot_initialize(dir); | 803 | dquot_initialize(dir); |
813 | 804 | ||
814 | tid = txBegin(ip->i_sb, 0); | 805 | tid = txBegin(ip->i_sb, 0); |
@@ -1138,10 +1129,6 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1138 | rc = -ENOTEMPTY; | 1129 | rc = -ENOTEMPTY; |
1139 | goto out3; | 1130 | goto out3; |
1140 | } | 1131 | } |
1141 | } else if ((new_dir != old_dir) && | ||
1142 | (new_dir->i_nlink == JFS_LINK_MAX)) { | ||
1143 | rc = -EMLINK; | ||
1144 | goto out3; | ||
1145 | } | 1132 | } |
1146 | } else if (new_ip) { | 1133 | } else if (new_ip) { |
1147 | IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL); | 1134 | IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL); |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 682bca642f38..4661ad705130 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -441,6 +441,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
441 | return -ENOMEM; | 441 | return -ENOMEM; |
442 | 442 | ||
443 | sb->s_fs_info = sbi; | 443 | sb->s_fs_info = sbi; |
444 | sb->s_max_links = JFS_LINK_MAX; | ||
444 | sbi->sb = sb; | 445 | sbi->sb = sb; |
445 | sbi->uid = sbi->gid = sbi->umask = -1; | 446 | sbi->uid = sbi->gid = sbi->umask = -1; |
446 | 447 | ||
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 3de7a32cadbe..4aea231fc9e6 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -558,9 +558,6 @@ static int logfs_link(struct dentry *old_dentry, struct inode *dir, | |||
558 | { | 558 | { |
559 | struct inode *inode = old_dentry->d_inode; | 559 | struct inode *inode = old_dentry->d_inode; |
560 | 560 | ||
561 | if (inode->i_nlink >= LOGFS_LINK_MAX) | ||
562 | return -EMLINK; | ||
563 | |||
564 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 561 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
565 | ihold(inode); | 562 | ihold(inode); |
566 | inc_nlink(inode); | 563 | inc_nlink(inode); |
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index c9ee7f5d1caf..b1a491a5fe78 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -542,6 +542,7 @@ static struct dentry *logfs_get_sb_device(struct logfs_super *super, | |||
542 | * the filesystem incompatible with 32bit systems. | 542 | * the filesystem incompatible with 32bit systems. |
543 | */ | 543 | */ |
544 | sb->s_maxbytes = (1ull << 43) - 1; | 544 | sb->s_maxbytes = (1ull << 43) - 1; |
545 | sb->s_max_links = LOGFS_LINK_MAX; | ||
545 | sb->s_op = &logfs_super_operations; | 546 | sb->s_op = &logfs_super_operations; |
546 | sb->s_flags = flags | MS_NOATIME; | 547 | sb->s_flags = flags | MS_NOATIME; |
547 | 548 | ||
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index fa8b612b8ce2..62c697caffb9 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -190,24 +190,24 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) | |||
190 | sbi->s_version = MINIX_V1; | 190 | sbi->s_version = MINIX_V1; |
191 | sbi->s_dirsize = 16; | 191 | sbi->s_dirsize = 16; |
192 | sbi->s_namelen = 14; | 192 | sbi->s_namelen = 14; |
193 | sbi->s_link_max = MINIX_LINK_MAX; | 193 | s->s_max_links = MINIX_LINK_MAX; |
194 | } else if (s->s_magic == MINIX_SUPER_MAGIC2) { | 194 | } else if (s->s_magic == MINIX_SUPER_MAGIC2) { |
195 | sbi->s_version = MINIX_V1; | 195 | sbi->s_version = MINIX_V1; |
196 | sbi->s_dirsize = 32; | 196 | sbi->s_dirsize = 32; |
197 | sbi->s_namelen = 30; | 197 | sbi->s_namelen = 30; |
198 | sbi->s_link_max = MINIX_LINK_MAX; | 198 | s->s_max_links = MINIX_LINK_MAX; |
199 | } else if (s->s_magic == MINIX2_SUPER_MAGIC) { | 199 | } else if (s->s_magic == MINIX2_SUPER_MAGIC) { |
200 | sbi->s_version = MINIX_V2; | 200 | sbi->s_version = MINIX_V2; |
201 | sbi->s_nzones = ms->s_zones; | 201 | sbi->s_nzones = ms->s_zones; |
202 | sbi->s_dirsize = 16; | 202 | sbi->s_dirsize = 16; |
203 | sbi->s_namelen = 14; | 203 | sbi->s_namelen = 14; |
204 | sbi->s_link_max = MINIX2_LINK_MAX; | 204 | s->s_max_links = MINIX2_LINK_MAX; |
205 | } else if (s->s_magic == MINIX2_SUPER_MAGIC2) { | 205 | } else if (s->s_magic == MINIX2_SUPER_MAGIC2) { |
206 | sbi->s_version = MINIX_V2; | 206 | sbi->s_version = MINIX_V2; |
207 | sbi->s_nzones = ms->s_zones; | 207 | sbi->s_nzones = ms->s_zones; |
208 | sbi->s_dirsize = 32; | 208 | sbi->s_dirsize = 32; |
209 | sbi->s_namelen = 30; | 209 | sbi->s_namelen = 30; |
210 | sbi->s_link_max = MINIX2_LINK_MAX; | 210 | s->s_max_links = MINIX2_LINK_MAX; |
211 | } else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) { | 211 | } else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) { |
212 | m3s = (struct minix3_super_block *) bh->b_data; | 212 | m3s = (struct minix3_super_block *) bh->b_data; |
213 | s->s_magic = m3s->s_magic; | 213 | s->s_magic = m3s->s_magic; |
@@ -221,9 +221,9 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) | |||
221 | sbi->s_dirsize = 64; | 221 | sbi->s_dirsize = 64; |
222 | sbi->s_namelen = 60; | 222 | sbi->s_namelen = 60; |
223 | sbi->s_version = MINIX_V3; | 223 | sbi->s_version = MINIX_V3; |
224 | sbi->s_link_max = MINIX2_LINK_MAX; | ||
225 | sbi->s_mount_state = MINIX_VALID_FS; | 224 | sbi->s_mount_state = MINIX_VALID_FS; |
226 | sb_set_blocksize(s, m3s->s_blocksize); | 225 | sb_set_blocksize(s, m3s->s_blocksize); |
226 | s->s_max_links = MINIX2_LINK_MAX; | ||
227 | } else | 227 | } else |
228 | goto out_no_fs; | 228 | goto out_no_fs; |
229 | 229 | ||
diff --git a/fs/minix/minix.h b/fs/minix/minix.h index c889ef0aa571..1ebd11854622 100644 --- a/fs/minix/minix.h +++ b/fs/minix/minix.h | |||
@@ -34,7 +34,6 @@ struct minix_sb_info { | |||
34 | unsigned long s_max_size; | 34 | unsigned long s_max_size; |
35 | int s_dirsize; | 35 | int s_dirsize; |
36 | int s_namelen; | 36 | int s_namelen; |
37 | int s_link_max; | ||
38 | struct buffer_head ** s_imap; | 37 | struct buffer_head ** s_imap; |
39 | struct buffer_head ** s_zmap; | 38 | struct buffer_head ** s_zmap; |
40 | struct buffer_head * s_sbh; | 39 | struct buffer_head * s_sbh; |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 2f76e38c2065..2d0ee1786305 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -94,9 +94,6 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir, | |||
94 | { | 94 | { |
95 | struct inode *inode = old_dentry->d_inode; | 95 | struct inode *inode = old_dentry->d_inode; |
96 | 96 | ||
97 | if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max) | ||
98 | return -EMLINK; | ||
99 | |||
100 | inode->i_ctime = CURRENT_TIME_SEC; | 97 | inode->i_ctime = CURRENT_TIME_SEC; |
101 | inode_inc_link_count(inode); | 98 | inode_inc_link_count(inode); |
102 | ihold(inode); | 99 | ihold(inode); |
@@ -106,10 +103,7 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir, | |||
106 | static int minix_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) | 103 | static int minix_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) |
107 | { | 104 | { |
108 | struct inode * inode; | 105 | struct inode * inode; |
109 | int err = -EMLINK; | 106 | int err; |
110 | |||
111 | if (dir->i_nlink >= minix_sb(dir->i_sb)->s_link_max) | ||
112 | goto out; | ||
113 | 107 | ||
114 | inode_inc_link_count(dir); | 108 | inode_inc_link_count(dir); |
115 | 109 | ||
@@ -181,7 +175,6 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry) | |||
181 | static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, | 175 | static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, |
182 | struct inode * new_dir, struct dentry *new_dentry) | 176 | struct inode * new_dir, struct dentry *new_dentry) |
183 | { | 177 | { |
184 | struct minix_sb_info * info = minix_sb(old_dir->i_sb); | ||
185 | struct inode * old_inode = old_dentry->d_inode; | 178 | struct inode * old_inode = old_dentry->d_inode; |
186 | struct inode * new_inode = new_dentry->d_inode; | 179 | struct inode * new_inode = new_dentry->d_inode; |
187 | struct page * dir_page = NULL; | 180 | struct page * dir_page = NULL; |
@@ -219,11 +212,6 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
219 | drop_nlink(new_inode); | 212 | drop_nlink(new_inode); |
220 | inode_dec_link_count(new_inode); | 213 | inode_dec_link_count(new_inode); |
221 | } else { | 214 | } else { |
222 | if (dir_de) { | ||
223 | err = -EMLINK; | ||
224 | if (new_dir->i_nlink >= info->s_link_max) | ||
225 | goto out_dir; | ||
226 | } | ||
227 | err = minix_add_link(new_dentry, old_inode); | 215 | err = minix_add_link(new_dentry, old_inode); |
228 | if (err) | 216 | if (err) |
229 | goto out_dir; | 217 | goto out_dir; |
diff --git a/fs/namei.c b/fs/namei.c index 46ea9cc16647..a0b82762e8fc 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2569,6 +2569,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d | |||
2569 | int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 2569 | int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
2570 | { | 2570 | { |
2571 | int error = may_create(dir, dentry); | 2571 | int error = may_create(dir, dentry); |
2572 | unsigned max_links = dir->i_sb->s_max_links; | ||
2572 | 2573 | ||
2573 | if (error) | 2574 | if (error) |
2574 | return error; | 2575 | return error; |
@@ -2581,6 +2582,9 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
2581 | if (error) | 2582 | if (error) |
2582 | return error; | 2583 | return error; |
2583 | 2584 | ||
2585 | if (max_links && dir->i_nlink >= max_links) | ||
2586 | return -EMLINK; | ||
2587 | |||
2584 | error = dir->i_op->mkdir(dir, dentry, mode); | 2588 | error = dir->i_op->mkdir(dir, dentry, mode); |
2585 | if (!error) | 2589 | if (!error) |
2586 | fsnotify_mkdir(dir, dentry); | 2590 | fsnotify_mkdir(dir, dentry); |
@@ -2911,6 +2915,7 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newn | |||
2911 | int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) | 2915 | int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) |
2912 | { | 2916 | { |
2913 | struct inode *inode = old_dentry->d_inode; | 2917 | struct inode *inode = old_dentry->d_inode; |
2918 | unsigned max_links = dir->i_sb->s_max_links; | ||
2914 | int error; | 2919 | int error; |
2915 | 2920 | ||
2916 | if (!inode) | 2921 | if (!inode) |
@@ -2941,6 +2946,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2941 | /* Make sure we don't allow creating hardlink to an unlinked file */ | 2946 | /* Make sure we don't allow creating hardlink to an unlinked file */ |
2942 | if (inode->i_nlink == 0) | 2947 | if (inode->i_nlink == 0) |
2943 | error = -ENOENT; | 2948 | error = -ENOENT; |
2949 | else if (max_links && inode->i_nlink >= max_links) | ||
2950 | error = -EMLINK; | ||
2944 | else | 2951 | else |
2945 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2952 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
2946 | mutex_unlock(&inode->i_mutex); | 2953 | mutex_unlock(&inode->i_mutex); |
@@ -3050,6 +3057,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
3050 | { | 3057 | { |
3051 | int error = 0; | 3058 | int error = 0; |
3052 | struct inode *target = new_dentry->d_inode; | 3059 | struct inode *target = new_dentry->d_inode; |
3060 | unsigned max_links = new_dir->i_sb->s_max_links; | ||
3053 | 3061 | ||
3054 | /* | 3062 | /* |
3055 | * If we are going to change the parent - check write permissions, | 3063 | * If we are going to change the parent - check write permissions, |
@@ -3073,6 +3081,11 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
3073 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) | 3081 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) |
3074 | goto out; | 3082 | goto out; |
3075 | 3083 | ||
3084 | error = -EMLINK; | ||
3085 | if (max_links && !target && new_dir != old_dir && | ||
3086 | new_dir->i_nlink >= max_links) | ||
3087 | goto out; | ||
3088 | |||
3076 | if (target) | 3089 | if (target) |
3077 | shrink_dcache_parent(new_dentry); | 3090 | shrink_dcache_parent(new_dentry); |
3078 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | 3091 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 1cd3f624dffc..fce2bbee66d4 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -193,9 +193,6 @@ static int nilfs_link(struct dentry *old_dentry, struct inode *dir, | |||
193 | struct nilfs_transaction_info ti; | 193 | struct nilfs_transaction_info ti; |
194 | int err; | 194 | int err; |
195 | 195 | ||
196 | if (inode->i_nlink >= NILFS_LINK_MAX) | ||
197 | return -EMLINK; | ||
198 | |||
199 | err = nilfs_transaction_begin(dir->i_sb, &ti, 1); | 196 | err = nilfs_transaction_begin(dir->i_sb, &ti, 1); |
200 | if (err) | 197 | if (err) |
201 | return err; | 198 | return err; |
@@ -219,9 +216,6 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
219 | struct nilfs_transaction_info ti; | 216 | struct nilfs_transaction_info ti; |
220 | int err; | 217 | int err; |
221 | 218 | ||
222 | if (dir->i_nlink >= NILFS_LINK_MAX) | ||
223 | return -EMLINK; | ||
224 | |||
225 | err = nilfs_transaction_begin(dir->i_sb, &ti, 1); | 219 | err = nilfs_transaction_begin(dir->i_sb, &ti, 1); |
226 | if (err) | 220 | if (err) |
227 | return err; | 221 | return err; |
@@ -400,11 +394,6 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
400 | drop_nlink(new_inode); | 394 | drop_nlink(new_inode); |
401 | nilfs_mark_inode_dirty(new_inode); | 395 | nilfs_mark_inode_dirty(new_inode); |
402 | } else { | 396 | } else { |
403 | if (dir_de) { | ||
404 | err = -EMLINK; | ||
405 | if (new_dir->i_nlink >= NILFS_LINK_MAX) | ||
406 | goto out_dir; | ||
407 | } | ||
408 | err = nilfs_add_link(new_dentry, old_inode); | 397 | err = nilfs_add_link(new_dentry, old_inode); |
409 | if (err) | 398 | if (err) |
410 | goto out_dir; | 399 | goto out_dir; |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 08e3d4f9df18..1fc9ad3c1d14 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -1059,6 +1059,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1059 | sb->s_export_op = &nilfs_export_ops; | 1059 | sb->s_export_op = &nilfs_export_ops; |
1060 | sb->s_root = NULL; | 1060 | sb->s_root = NULL; |
1061 | sb->s_time_gran = 1; | 1061 | sb->s_time_gran = 1; |
1062 | sb->s_max_links = NILFS_LINK_MAX; | ||
1062 | 1063 | ||
1063 | bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info; | 1064 | bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info; |
1064 | sb->s_bdi = bdi ? : &default_backing_dev_info; | 1065 | sb->s_bdi = bdi ? : &default_backing_dev_info; |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index b217797e621b..d7466e293614 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -121,9 +121,6 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir, | |||
121 | { | 121 | { |
122 | struct inode *inode = old_dentry->d_inode; | 122 | struct inode *inode = old_dentry->d_inode; |
123 | 123 | ||
124 | if (inode->i_nlink >= SYSV_SB(inode->i_sb)->s_link_max) | ||
125 | return -EMLINK; | ||
126 | |||
127 | inode->i_ctime = CURRENT_TIME_SEC; | 124 | inode->i_ctime = CURRENT_TIME_SEC; |
128 | inode_inc_link_count(inode); | 125 | inode_inc_link_count(inode); |
129 | ihold(inode); | 126 | ihold(inode); |
@@ -134,10 +131,8 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir, | |||
134 | static int sysv_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) | 131 | static int sysv_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode) |
135 | { | 132 | { |
136 | struct inode * inode; | 133 | struct inode * inode; |
137 | int err = -EMLINK; | 134 | int err; |
138 | 135 | ||
139 | if (dir->i_nlink >= SYSV_SB(dir->i_sb)->s_link_max) | ||
140 | goto out; | ||
141 | inode_inc_link_count(dir); | 136 | inode_inc_link_count(dir); |
142 | 137 | ||
143 | inode = sysv_new_inode(dir, S_IFDIR|mode); | 138 | inode = sysv_new_inode(dir, S_IFDIR|mode); |
@@ -251,11 +246,6 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, | |||
251 | drop_nlink(new_inode); | 246 | drop_nlink(new_inode); |
252 | inode_dec_link_count(new_inode); | 247 | inode_dec_link_count(new_inode); |
253 | } else { | 248 | } else { |
254 | if (dir_de) { | ||
255 | err = -EMLINK; | ||
256 | if (new_dir->i_nlink >= SYSV_SB(new_dir->i_sb)->s_link_max) | ||
257 | goto out_dir; | ||
258 | } | ||
259 | err = sysv_add_link(new_dentry, old_inode); | 249 | err = sysv_add_link(new_dentry, old_inode); |
260 | if (err) | 250 | if (err) |
261 | goto out_dir; | 251 | goto out_dir; |
diff --git a/fs/sysv/super.c b/fs/sysv/super.c index f60c196913ea..f467740e088c 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c | |||
@@ -44,7 +44,7 @@ enum { | |||
44 | JAN_1_1980 = (10*365 + 2) * 24 * 60 * 60 | 44 | JAN_1_1980 = (10*365 + 2) * 24 * 60 * 60 |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static void detected_xenix(struct sysv_sb_info *sbi) | 47 | static void detected_xenix(struct sysv_sb_info *sbi, unsigned *max_links) |
48 | { | 48 | { |
49 | struct buffer_head *bh1 = sbi->s_bh1; | 49 | struct buffer_head *bh1 = sbi->s_bh1; |
50 | struct buffer_head *bh2 = sbi->s_bh2; | 50 | struct buffer_head *bh2 = sbi->s_bh2; |
@@ -59,7 +59,7 @@ static void detected_xenix(struct sysv_sb_info *sbi) | |||
59 | sbd2 = (struct xenix_super_block *) (bh2->b_data - 512); | 59 | sbd2 = (struct xenix_super_block *) (bh2->b_data - 512); |
60 | } | 60 | } |
61 | 61 | ||
62 | sbi->s_link_max = XENIX_LINK_MAX; | 62 | *max_links = XENIX_LINK_MAX; |
63 | sbi->s_fic_size = XENIX_NICINOD; | 63 | sbi->s_fic_size = XENIX_NICINOD; |
64 | sbi->s_flc_size = XENIX_NICFREE; | 64 | sbi->s_flc_size = XENIX_NICFREE; |
65 | sbi->s_sbd1 = (char *)sbd1; | 65 | sbi->s_sbd1 = (char *)sbd1; |
@@ -75,7 +75,7 @@ static void detected_xenix(struct sysv_sb_info *sbi) | |||
75 | sbi->s_nzones = fs32_to_cpu(sbi, sbd1->s_fsize); | 75 | sbi->s_nzones = fs32_to_cpu(sbi, sbd1->s_fsize); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void detected_sysv4(struct sysv_sb_info *sbi) | 78 | static void detected_sysv4(struct sysv_sb_info *sbi, unsigned *max_links) |
79 | { | 79 | { |
80 | struct sysv4_super_block * sbd; | 80 | struct sysv4_super_block * sbd; |
81 | struct buffer_head *bh1 = sbi->s_bh1; | 81 | struct buffer_head *bh1 = sbi->s_bh1; |
@@ -86,7 +86,7 @@ static void detected_sysv4(struct sysv_sb_info *sbi) | |||
86 | else | 86 | else |
87 | sbd = (struct sysv4_super_block *) bh2->b_data; | 87 | sbd = (struct sysv4_super_block *) bh2->b_data; |
88 | 88 | ||
89 | sbi->s_link_max = SYSV_LINK_MAX; | 89 | *max_links = SYSV_LINK_MAX; |
90 | sbi->s_fic_size = SYSV_NICINOD; | 90 | sbi->s_fic_size = SYSV_NICINOD; |
91 | sbi->s_flc_size = SYSV_NICFREE; | 91 | sbi->s_flc_size = SYSV_NICFREE; |
92 | sbi->s_sbd1 = (char *)sbd; | 92 | sbi->s_sbd1 = (char *)sbd; |
@@ -103,7 +103,7 @@ static void detected_sysv4(struct sysv_sb_info *sbi) | |||
103 | sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); | 103 | sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); |
104 | } | 104 | } |
105 | 105 | ||
106 | static void detected_sysv2(struct sysv_sb_info *sbi) | 106 | static void detected_sysv2(struct sysv_sb_info *sbi, unsigned *max_links) |
107 | { | 107 | { |
108 | struct sysv2_super_block *sbd; | 108 | struct sysv2_super_block *sbd; |
109 | struct buffer_head *bh1 = sbi->s_bh1; | 109 | struct buffer_head *bh1 = sbi->s_bh1; |
@@ -114,7 +114,7 @@ static void detected_sysv2(struct sysv_sb_info *sbi) | |||
114 | else | 114 | else |
115 | sbd = (struct sysv2_super_block *) bh2->b_data; | 115 | sbd = (struct sysv2_super_block *) bh2->b_data; |
116 | 116 | ||
117 | sbi->s_link_max = SYSV_LINK_MAX; | 117 | *max_links = SYSV_LINK_MAX; |
118 | sbi->s_fic_size = SYSV_NICINOD; | 118 | sbi->s_fic_size = SYSV_NICINOD; |
119 | sbi->s_flc_size = SYSV_NICFREE; | 119 | sbi->s_flc_size = SYSV_NICFREE; |
120 | sbi->s_sbd1 = (char *)sbd; | 120 | sbi->s_sbd1 = (char *)sbd; |
@@ -131,14 +131,14 @@ static void detected_sysv2(struct sysv_sb_info *sbi) | |||
131 | sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); | 131 | sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); |
132 | } | 132 | } |
133 | 133 | ||
134 | static void detected_coherent(struct sysv_sb_info *sbi) | 134 | static void detected_coherent(struct sysv_sb_info *sbi, unsigned *max_links) |
135 | { | 135 | { |
136 | struct coh_super_block * sbd; | 136 | struct coh_super_block * sbd; |
137 | struct buffer_head *bh1 = sbi->s_bh1; | 137 | struct buffer_head *bh1 = sbi->s_bh1; |
138 | 138 | ||
139 | sbd = (struct coh_super_block *) bh1->b_data; | 139 | sbd = (struct coh_super_block *) bh1->b_data; |
140 | 140 | ||
141 | sbi->s_link_max = COH_LINK_MAX; | 141 | *max_links = COH_LINK_MAX; |
142 | sbi->s_fic_size = COH_NICINOD; | 142 | sbi->s_fic_size = COH_NICINOD; |
143 | sbi->s_flc_size = COH_NICFREE; | 143 | sbi->s_flc_size = COH_NICFREE; |
144 | sbi->s_sbd1 = (char *)sbd; | 144 | sbi->s_sbd1 = (char *)sbd; |
@@ -154,12 +154,12 @@ static void detected_coherent(struct sysv_sb_info *sbi) | |||
154 | sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); | 154 | sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); |
155 | } | 155 | } |
156 | 156 | ||
157 | static void detected_v7(struct sysv_sb_info *sbi) | 157 | static void detected_v7(struct sysv_sb_info *sbi, unsigned *max_links) |
158 | { | 158 | { |
159 | struct buffer_head *bh2 = sbi->s_bh2; | 159 | struct buffer_head *bh2 = sbi->s_bh2; |
160 | struct v7_super_block *sbd = (struct v7_super_block *)bh2->b_data; | 160 | struct v7_super_block *sbd = (struct v7_super_block *)bh2->b_data; |
161 | 161 | ||
162 | sbi->s_link_max = V7_LINK_MAX; | 162 | *max_links = V7_LINK_MAX; |
163 | sbi->s_fic_size = V7_NICINOD; | 163 | sbi->s_fic_size = V7_NICINOD; |
164 | sbi->s_flc_size = V7_NICFREE; | 164 | sbi->s_flc_size = V7_NICFREE; |
165 | sbi->s_sbd1 = (char *)sbd; | 165 | sbi->s_sbd1 = (char *)sbd; |
@@ -290,7 +290,7 @@ static char *flavour_names[] = { | |||
290 | [FSTYPE_AFS] = "AFS", | 290 | [FSTYPE_AFS] = "AFS", |
291 | }; | 291 | }; |
292 | 292 | ||
293 | static void (*flavour_setup[])(struct sysv_sb_info *) = { | 293 | static void (*flavour_setup[])(struct sysv_sb_info *, unsigned *) = { |
294 | [FSTYPE_XENIX] = detected_xenix, | 294 | [FSTYPE_XENIX] = detected_xenix, |
295 | [FSTYPE_SYSV4] = detected_sysv4, | 295 | [FSTYPE_SYSV4] = detected_sysv4, |
296 | [FSTYPE_SYSV2] = detected_sysv2, | 296 | [FSTYPE_SYSV2] = detected_sysv2, |
@@ -310,7 +310,7 @@ static int complete_read_super(struct super_block *sb, int silent, int size) | |||
310 | 310 | ||
311 | sbi->s_firstinodezone = 2; | 311 | sbi->s_firstinodezone = 2; |
312 | 312 | ||
313 | flavour_setup[sbi->s_type](sbi); | 313 | flavour_setup[sbi->s_type](sbi, &sb->s_max_links); |
314 | 314 | ||
315 | sbi->s_truncate = 1; | 315 | sbi->s_truncate = 1; |
316 | sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone; | 316 | sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone; |
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h index 0e4b821c5691..11b07672f6c5 100644 --- a/fs/sysv/sysv.h +++ b/fs/sysv/sysv.h | |||
@@ -24,7 +24,6 @@ struct sysv_sb_info { | |||
24 | char s_bytesex; /* bytesex (le/be/pdp) */ | 24 | char s_bytesex; /* bytesex (le/be/pdp) */ |
25 | char s_truncate; /* if 1: names > SYSV_NAMELEN chars are truncated */ | 25 | char s_truncate; /* if 1: names > SYSV_NAMELEN chars are truncated */ |
26 | /* if 0: they are disallowed (ENAMETOOLONG) */ | 26 | /* if 0: they are disallowed (ENAMETOOLONG) */ |
27 | nlink_t s_link_max; /* max number of hard links to a file */ | ||
28 | unsigned int s_inodes_per_block; /* number of inodes per block */ | 27 | unsigned int s_inodes_per_block; /* number of inodes per block */ |
29 | unsigned int s_inodes_per_block_1; /* inodes_per_block - 1 */ | 28 | unsigned int s_inodes_per_block_1; /* inodes_per_block - 1 */ |
30 | unsigned int s_inodes_per_block_bits; /* log2(inodes_per_block) */ | 29 | unsigned int s_inodes_per_block_bits; /* log2(inodes_per_block) */ |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 08bf46edf9c4..38de8f234b94 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <linux/crc-itu-t.h> | 32 | #include <linux/crc-itu-t.h> |
33 | #include <linux/exportfs.h> | 33 | #include <linux/exportfs.h> |
34 | 34 | ||
35 | enum { UDF_MAX_LINKS = 0xffff }; | ||
36 | |||
37 | static inline int udf_match(int len1, const unsigned char *name1, int len2, | 35 | static inline int udf_match(int len1, const unsigned char *name1, int len2, |
38 | const unsigned char *name2) | 36 | const unsigned char *name2) |
39 | { | 37 | { |
@@ -649,10 +647,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
649 | struct udf_inode_info *dinfo = UDF_I(dir); | 647 | struct udf_inode_info *dinfo = UDF_I(dir); |
650 | struct udf_inode_info *iinfo; | 648 | struct udf_inode_info *iinfo; |
651 | 649 | ||
652 | err = -EMLINK; | ||
653 | if (dir->i_nlink >= UDF_MAX_LINKS) | ||
654 | goto out; | ||
655 | |||
656 | err = -EIO; | 650 | err = -EIO; |
657 | inode = udf_new_inode(dir, S_IFDIR | mode, &err); | 651 | inode = udf_new_inode(dir, S_IFDIR | mode, &err); |
658 | if (!inode) | 652 | if (!inode) |
@@ -1032,9 +1026,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1032 | struct fileIdentDesc cfi, *fi; | 1026 | struct fileIdentDesc cfi, *fi; |
1033 | int err; | 1027 | int err; |
1034 | 1028 | ||
1035 | if (inode->i_nlink >= UDF_MAX_LINKS) | ||
1036 | return -EMLINK; | ||
1037 | |||
1038 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1029 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
1039 | if (!fi) { | 1030 | if (!fi) { |
1040 | return err; | 1031 | return err; |
@@ -1126,10 +1117,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1126 | if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) != | 1117 | if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) != |
1127 | old_dir->i_ino) | 1118 | old_dir->i_ino) |
1128 | goto end_rename; | 1119 | goto end_rename; |
1129 | |||
1130 | retval = -EMLINK; | ||
1131 | if (!new_inode && new_dir->i_nlink >= UDF_MAX_LINKS) | ||
1132 | goto end_rename; | ||
1133 | } | 1120 | } |
1134 | if (!nfi) { | 1121 | if (!nfi) { |
1135 | nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, | 1122 | nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, |
diff --git a/fs/udf/super.c b/fs/udf/super.c index c09a84daaf50..8d8b25336fbb 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -75,6 +75,8 @@ | |||
75 | 75 | ||
76 | #define UDF_DEFAULT_BLOCKSIZE 2048 | 76 | #define UDF_DEFAULT_BLOCKSIZE 2048 |
77 | 77 | ||
78 | enum { UDF_MAX_LINKS = 0xffff }; | ||
79 | |||
78 | /* These are the "meat" - everything else is stuffing */ | 80 | /* These are the "meat" - everything else is stuffing */ |
79 | static int udf_fill_super(struct super_block *, void *, int); | 81 | static int udf_fill_super(struct super_block *, void *, int); |
80 | static void udf_put_super(struct super_block *); | 82 | static void udf_put_super(struct super_block *); |
@@ -2042,6 +2044,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
2042 | goto error_out; | 2044 | goto error_out; |
2043 | } | 2045 | } |
2044 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 2046 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
2047 | sb->s_max_links = UDF_MAX_LINKS; | ||
2045 | return 0; | 2048 | return 0; |
2046 | 2049 | ||
2047 | error_out: | 2050 | error_out: |
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, | |||
183 | static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | 179 | static 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)) { |
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 866de277079a..e44ef7ee8ce8 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -118,17 +118,6 @@ xfs_rename( | |||
118 | new_parent = (src_dp != target_dp); | 118 | new_parent = (src_dp != target_dp); |
119 | src_is_directory = S_ISDIR(src_ip->i_d.di_mode); | 119 | src_is_directory = S_ISDIR(src_ip->i_d.di_mode); |
120 | 120 | ||
121 | if (src_is_directory) { | ||
122 | /* | ||
123 | * Check for link count overflow on target_dp | ||
124 | */ | ||
125 | if (target_ip == NULL && new_parent && | ||
126 | target_dp->i_d.di_nlink >= XFS_MAXLINK) { | ||
127 | error = XFS_ERROR(EMLINK); | ||
128 | goto std_return; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, | 121 | xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, |
133 | inodes, &num_inodes); | 122 | inodes, &num_inodes); |
134 | 123 | ||
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index ee5b695c99a7..0e4c5c017fba 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1341,6 +1341,7 @@ xfs_fs_fill_super( | |||
1341 | sb->s_blocksize = mp->m_sb.sb_blocksize; | 1341 | sb->s_blocksize = mp->m_sb.sb_blocksize; |
1342 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; | 1342 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; |
1343 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); | 1343 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); |
1344 | sb->s_max_links = XFS_MAXLINK; | ||
1344 | sb->s_time_gran = 1; | 1345 | sb->s_time_gran = 1; |
1345 | set_posix_acl_flag(sb); | 1346 | set_posix_acl_flag(sb); |
1346 | 1347 | ||
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 89dbb4a50872..79c05ac85bfe 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -296,8 +296,6 @@ xfs_bumplink( | |||
296 | xfs_trans_t *tp, | 296 | xfs_trans_t *tp, |
297 | xfs_inode_t *ip) | 297 | xfs_inode_t *ip) |
298 | { | 298 | { |
299 | if (ip->i_d.di_nlink >= XFS_MAXLINK) | ||
300 | return XFS_ERROR(EMLINK); | ||
301 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); | 299 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); |
302 | 300 | ||
303 | ASSERT(ip->i_d.di_nlink > 0); | 301 | ASSERT(ip->i_d.di_nlink > 0); |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index ebdb88840a47..64981d7e7375 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -917,14 +917,6 @@ xfs_create( | |||
917 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 917 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
918 | unlock_dp_on_error = B_TRUE; | 918 | unlock_dp_on_error = B_TRUE; |
919 | 919 | ||
920 | /* | ||
921 | * Check for directory link count overflow. | ||
922 | */ | ||
923 | if (is_dir && dp->i_d.di_nlink >= XFS_MAXLINK) { | ||
924 | error = XFS_ERROR(EMLINK); | ||
925 | goto out_trans_cancel; | ||
926 | } | ||
927 | |||
928 | xfs_bmap_init(&free_list, &first_block); | 920 | xfs_bmap_init(&free_list, &first_block); |
929 | 921 | ||
930 | /* | 922 | /* |
@@ -1429,14 +1421,6 @@ xfs_link( | |||
1429 | xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); | 1421 | xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); |
1430 | 1422 | ||
1431 | /* | 1423 | /* |
1432 | * If the source has too many links, we can't make any more to it. | ||
1433 | */ | ||
1434 | if (sip->i_d.di_nlink >= XFS_MAXLINK) { | ||
1435 | error = XFS_ERROR(EMLINK); | ||
1436 | goto error_return; | ||
1437 | } | ||
1438 | |||
1439 | /* | ||
1440 | * If we are using project inheritance, we only allow hard link | 1424 | * If we are using project inheritance, we only allow hard link |
1441 | * creation in our tree when the project IDs are the same; else | 1425 | * creation in our tree when the project IDs are the same; else |
1442 | * the tree quota mechanism could be circumvented. | 1426 | * the tree quota mechanism could be circumvented. |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 69cd5bb640f5..0ab89426ba55 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1459,6 +1459,7 @@ struct super_block { | |||
1459 | u8 s_uuid[16]; /* UUID */ | 1459 | u8 s_uuid[16]; /* UUID */ |
1460 | 1460 | ||
1461 | void *s_fs_info; /* Filesystem private info */ | 1461 | void *s_fs_info; /* Filesystem private info */ |
1462 | unsigned int s_max_links; | ||
1462 | fmode_t s_mode; | 1463 | fmode_t s_mode; |
1463 | 1464 | ||
1464 | /* Granularity of c/m/atime in ns. | 1465 | /* Granularity of c/m/atime in ns. |