aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
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/udf
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/udf')
-rw-r--r--fs/udf/namei.c13
-rw-r--r--fs/udf/super.c3
2 files changed, 3 insertions, 13 deletions
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
35enum { UDF_MAX_LINKS = 0xffff };
36
37static inline int udf_match(int len1, const unsigned char *name1, int len2, 35static 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
78enum { UDF_MAX_LINKS = 0xffff };
79
78/* These are the "meat" - everything else is stuffing */ 80/* These are the "meat" - everything else is stuffing */
79static int udf_fill_super(struct super_block *, void *, int); 81static int udf_fill_super(struct super_block *, void *, int);
80static void udf_put_super(struct super_block *); 82static 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
2047error_out: 2050error_out: