diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-20 19:32:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-20 19:32:16 -0400 |
| commit | 92075f9f640dc3fde91b833c08fbc921b1649088 (patch) | |
| tree | 9ee9ab21296f03d32d561187cdfe6eed547c09a1 /fs | |
| parent | 3951ad2e051543f6cd01706da477a73f19165eb6 (diff) | |
| parent | e6d8fb340f20bc5275ceed86133d1823dec9478d (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull filesystem fixes from Jan Kara:
"udf, isofs, and ext3 bug fixes"
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
ext3: Count internal journal as bsddf overhead in ext3_statfs
isofs: Fix unbounded recursion when processing relocated directories
udf: avoid unneeded up_write when fail to add entry in ->symlink
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ext3/super.c | 5 | ||||
| -rw-r--r-- | fs/isofs/inode.c | 15 | ||||
| -rw-r--r-- | fs/isofs/isofs.h | 23 | ||||
| -rw-r--r-- | fs/isofs/rock.c | 39 | ||||
| -rw-r--r-- | fs/udf/namei.c | 3 |
5 files changed, 60 insertions, 25 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 08cdfe5461e3..622e88249024 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -2828,8 +2828,9 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
| 2828 | */ | 2828 | */ |
| 2829 | overhead += ngroups * (2 + sbi->s_itb_per_group); | 2829 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
| 2830 | 2830 | ||
| 2831 | /* Add the journal blocks as well */ | 2831 | /* Add the internal journal blocks as well */ |
| 2832 | overhead += sbi->s_journal->j_maxlen; | 2832 | if (sbi->s_journal && !sbi->journal_bdev) |
| 2833 | overhead += sbi->s_journal->j_maxlen; | ||
| 2833 | 2834 | ||
| 2834 | sbi->s_overhead_last = overhead; | 2835 | sbi->s_overhead_last = overhead; |
| 2835 | smp_wmb(); | 2836 | smp_wmb(); |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 4556ce1af5b0..5ddaf8625d3b 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
| @@ -61,7 +61,7 @@ static void isofs_put_super(struct super_block *sb) | |||
| 61 | return; | 61 | return; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static int isofs_read_inode(struct inode *); | 64 | static int isofs_read_inode(struct inode *, int relocated); |
| 65 | static int isofs_statfs (struct dentry *, struct kstatfs *); | 65 | static int isofs_statfs (struct dentry *, struct kstatfs *); |
| 66 | 66 | ||
| 67 | static struct kmem_cache *isofs_inode_cachep; | 67 | static struct kmem_cache *isofs_inode_cachep; |
| @@ -1259,7 +1259,7 @@ out_toomany: | |||
| 1259 | goto out; | 1259 | goto out; |
| 1260 | } | 1260 | } |
| 1261 | 1261 | ||
| 1262 | static int isofs_read_inode(struct inode *inode) | 1262 | static int isofs_read_inode(struct inode *inode, int relocated) |
| 1263 | { | 1263 | { |
| 1264 | struct super_block *sb = inode->i_sb; | 1264 | struct super_block *sb = inode->i_sb; |
| 1265 | struct isofs_sb_info *sbi = ISOFS_SB(sb); | 1265 | struct isofs_sb_info *sbi = ISOFS_SB(sb); |
| @@ -1404,7 +1404,7 @@ static int isofs_read_inode(struct inode *inode) | |||
| 1404 | */ | 1404 | */ |
| 1405 | 1405 | ||
| 1406 | if (!high_sierra) { | 1406 | if (!high_sierra) { |
| 1407 | parse_rock_ridge_inode(de, inode); | 1407 | parse_rock_ridge_inode(de, inode, relocated); |
| 1408 | /* if we want uid/gid set, override the rock ridge setting */ | 1408 | /* if we want uid/gid set, override the rock ridge setting */ |
| 1409 | if (sbi->s_uid_set) | 1409 | if (sbi->s_uid_set) |
| 1410 | inode->i_uid = sbi->s_uid; | 1410 | inode->i_uid = sbi->s_uid; |
| @@ -1483,9 +1483,10 @@ static int isofs_iget5_set(struct inode *ino, void *data) | |||
| 1483 | * offset that point to the underlying meta-data for the inode. The | 1483 | * offset that point to the underlying meta-data for the inode. The |
| 1484 | * code below is otherwise similar to the iget() code in | 1484 | * code below is otherwise similar to the iget() code in |
| 1485 | * include/linux/fs.h */ | 1485 | * include/linux/fs.h */ |
| 1486 | struct inode *isofs_iget(struct super_block *sb, | 1486 | struct inode *__isofs_iget(struct super_block *sb, |
| 1487 | unsigned long block, | 1487 | unsigned long block, |
| 1488 | unsigned long offset) | 1488 | unsigned long offset, |
| 1489 | int relocated) | ||
| 1489 | { | 1490 | { |
| 1490 | unsigned long hashval; | 1491 | unsigned long hashval; |
| 1491 | struct inode *inode; | 1492 | struct inode *inode; |
| @@ -1507,7 +1508,7 @@ struct inode *isofs_iget(struct super_block *sb, | |||
| 1507 | return ERR_PTR(-ENOMEM); | 1508 | return ERR_PTR(-ENOMEM); |
| 1508 | 1509 | ||
| 1509 | if (inode->i_state & I_NEW) { | 1510 | if (inode->i_state & I_NEW) { |
| 1510 | ret = isofs_read_inode(inode); | 1511 | ret = isofs_read_inode(inode, relocated); |
| 1511 | if (ret < 0) { | 1512 | if (ret < 0) { |
| 1512 | iget_failed(inode); | 1513 | iget_failed(inode); |
| 1513 | inode = ERR_PTR(ret); | 1514 | inode = ERR_PTR(ret); |
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index 99167238518d..0ac4c1f73fbd 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h | |||
| @@ -107,7 +107,7 @@ extern int iso_date(char *, int); | |||
| 107 | 107 | ||
| 108 | struct inode; /* To make gcc happy */ | 108 | struct inode; /* To make gcc happy */ |
| 109 | 109 | ||
| 110 | extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *); | 110 | extern int parse_rock_ridge_inode(struct iso_directory_record *, struct inode *, int relocated); |
| 111 | extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *); | 111 | extern int get_rock_ridge_filename(struct iso_directory_record *, char *, struct inode *); |
| 112 | extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *); | 112 | extern int isofs_name_translate(struct iso_directory_record *, char *, struct inode *); |
| 113 | 113 | ||
| @@ -118,9 +118,24 @@ extern struct dentry *isofs_lookup(struct inode *, struct dentry *, unsigned int | |||
| 118 | extern struct buffer_head *isofs_bread(struct inode *, sector_t); | 118 | extern struct buffer_head *isofs_bread(struct inode *, sector_t); |
| 119 | extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); | 119 | extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); |
| 120 | 120 | ||
| 121 | extern struct inode *isofs_iget(struct super_block *sb, | 121 | struct inode *__isofs_iget(struct super_block *sb, |
| 122 | unsigned long block, | 122 | unsigned long block, |
| 123 | unsigned long offset); | 123 | unsigned long offset, |
| 124 | int relocated); | ||
| 125 | |||
| 126 | static inline struct inode *isofs_iget(struct super_block *sb, | ||
| 127 | unsigned long block, | ||
| 128 | unsigned long offset) | ||
| 129 | { | ||
| 130 | return __isofs_iget(sb, block, offset, 0); | ||
| 131 | } | ||
| 132 | |||
| 133 | static inline struct inode *isofs_iget_reloc(struct super_block *sb, | ||
| 134 | unsigned long block, | ||
| 135 | unsigned long offset) | ||
| 136 | { | ||
| 137 | return __isofs_iget(sb, block, offset, 1); | ||
| 138 | } | ||
| 124 | 139 | ||
| 125 | /* Because the inode number is no longer relevant to finding the | 140 | /* Because the inode number is no longer relevant to finding the |
| 126 | * underlying meta-data for an inode, we are free to choose a more | 141 | * underlying meta-data for an inode, we are free to choose a more |
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index c0bf42472e40..f488bbae541a 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c | |||
| @@ -288,12 +288,16 @@ eio: | |||
| 288 | goto out; | 288 | goto out; |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | #define RR_REGARD_XA 1 | ||
| 292 | #define RR_RELOC_DE 2 | ||
| 293 | |||
| 291 | static int | 294 | static int |
| 292 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, | 295 | parse_rock_ridge_inode_internal(struct iso_directory_record *de, |
| 293 | struct inode *inode, int regard_xa) | 296 | struct inode *inode, int flags) |
| 294 | { | 297 | { |
| 295 | int symlink_len = 0; | 298 | int symlink_len = 0; |
| 296 | int cnt, sig; | 299 | int cnt, sig; |
| 300 | unsigned int reloc_block; | ||
| 297 | struct inode *reloc; | 301 | struct inode *reloc; |
| 298 | struct rock_ridge *rr; | 302 | struct rock_ridge *rr; |
| 299 | int rootflag; | 303 | int rootflag; |
| @@ -305,7 +309,7 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, | |||
| 305 | 309 | ||
| 306 | init_rock_state(&rs, inode); | 310 | init_rock_state(&rs, inode); |
| 307 | setup_rock_ridge(de, inode, &rs); | 311 | setup_rock_ridge(de, inode, &rs); |
| 308 | if (regard_xa) { | 312 | if (flags & RR_REGARD_XA) { |
| 309 | rs.chr += 14; | 313 | rs.chr += 14; |
| 310 | rs.len -= 14; | 314 | rs.len -= 14; |
| 311 | if (rs.len < 0) | 315 | if (rs.len < 0) |
| @@ -485,12 +489,22 @@ repeat: | |||
| 485 | "relocated directory\n"); | 489 | "relocated directory\n"); |
| 486 | goto out; | 490 | goto out; |
| 487 | case SIG('C', 'L'): | 491 | case SIG('C', 'L'): |
| 488 | ISOFS_I(inode)->i_first_extent = | 492 | if (flags & RR_RELOC_DE) { |
| 489 | isonum_733(rr->u.CL.location); | 493 | printk(KERN_ERR |
| 490 | reloc = | 494 | "ISOFS: Recursive directory relocation " |
| 491 | isofs_iget(inode->i_sb, | 495 | "is not supported\n"); |
| 492 | ISOFS_I(inode)->i_first_extent, | 496 | goto eio; |
| 493 | 0); | 497 | } |
| 498 | reloc_block = isonum_733(rr->u.CL.location); | ||
| 499 | if (reloc_block == ISOFS_I(inode)->i_iget5_block && | ||
| 500 | ISOFS_I(inode)->i_iget5_offset == 0) { | ||
| 501 | printk(KERN_ERR | ||
| 502 | "ISOFS: Directory relocation points to " | ||
| 503 | "itself\n"); | ||
| 504 | goto eio; | ||
| 505 | } | ||
| 506 | ISOFS_I(inode)->i_first_extent = reloc_block; | ||
| 507 | reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0); | ||
| 494 | if (IS_ERR(reloc)) { | 508 | if (IS_ERR(reloc)) { |
| 495 | ret = PTR_ERR(reloc); | 509 | ret = PTR_ERR(reloc); |
| 496 | goto out; | 510 | goto out; |
| @@ -637,9 +651,11 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) | |||
| 637 | return rpnt; | 651 | return rpnt; |
| 638 | } | 652 | } |
| 639 | 653 | ||
| 640 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | 654 | int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode, |
| 655 | int relocated) | ||
| 641 | { | 656 | { |
| 642 | int result = parse_rock_ridge_inode_internal(de, inode, 0); | 657 | int flags = relocated ? RR_RELOC_DE : 0; |
| 658 | int result = parse_rock_ridge_inode_internal(de, inode, flags); | ||
| 643 | 659 | ||
| 644 | /* | 660 | /* |
| 645 | * if rockridge flag was reset and we didn't look for attributes | 661 | * if rockridge flag was reset and we didn't look for attributes |
| @@ -647,7 +663,8 @@ int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) | |||
| 647 | */ | 663 | */ |
| 648 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) | 664 | if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) |
| 649 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { | 665 | && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { |
| 650 | result = parse_rock_ridge_inode_internal(de, inode, 14); | 666 | result = parse_rock_ridge_inode_internal(de, inode, |
| 667 | flags | RR_REGARD_XA); | ||
| 651 | } | 668 | } |
| 652 | return result; | 669 | return result; |
| 653 | } | 670 | } |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 9737cba1357d..83a06001742b 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
| @@ -1014,7 +1014,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 1014 | 1014 | ||
| 1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
| 1016 | if (!fi) | 1016 | if (!fi) |
| 1017 | goto out_no_entry; | 1017 | goto out_fail; |
| 1018 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); | 1018 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); |
| 1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | 1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); |
| 1020 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { | 1020 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { |
| @@ -1036,6 +1036,7 @@ out: | |||
| 1036 | 1036 | ||
| 1037 | out_no_entry: | 1037 | out_no_entry: |
| 1038 | up_write(&iinfo->i_data_sem); | 1038 | up_write(&iinfo->i_data_sem); |
| 1039 | out_fail: | ||
| 1039 | inode_dec_link_count(inode); | 1040 | inode_dec_link_count(inode); |
| 1040 | iput(inode); | 1041 | iput(inode); |
| 1041 | goto out; | 1042 | goto out; |
