diff options
| author | Sougata Santra <sougata@tuxera.com> | 2014-12-18 19:17:12 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-18 22:08:10 -0500 |
| commit | 89ac9b4d3d1a049ae1054f99b1aed81092cd0a82 (patch) | |
| tree | b76f017fbe75cacd124b6ab796d2e4d5ddb9ea76 /fs/hfsplus | |
| parent | 859f7ef142a956676cb387b90f18e2e71e959c68 (diff) | |
hfsplus: fix longname handling
Longname is not correctly handled by hfsplus driver. If an attempt to
create a longname(>255) file/directory is made, it succeeds by creating a
file/directory with HFSPLUS_MAX_STRLEN and incorrect catalog key. Thus
leaving the volume in an inconsistent state. This patch fixes this issue.
Although lookup is always called first to create a negative entry, so just
doing a check in lookup would probably fix this issue. I choose to
propagate error to other iops as well.
Please NOTE: I have factored out hfsplus_cat_build_key_with_cnid from
hfsplus_cat_build_key, to avoid unncessary branching.
Thanks a lot.
TEST:
------
dir="TEST_DIR"
cdir=`pwd`
name255="_123456789_123456789_123456789_123456789_123456789_123456789\
_123456789_123456789_123456789_123456789_123456789_123456789_123456789\
_123456789_123456789_123456789_123456789_123456789_123456789_123456789\
_123456789_123456789_123456789_123456789_123456789_1234"
name256="${name255}5"
mkdir $dir
cd $dir
touch $name255
rm -f $name255
touch $name256
ls -la
cd $cdir
rm -rf $dir
RESULT:
-------
[sougata@ultrabook tmp]$ cdir=`pwd`
[sougata@ultrabook tmp]$
name255="_123456789_123456789_123456789_123456789_123456789_123456789\
> _123456789_123456789_123456789_123456789_123456789_123456789_123456789\
> _123456789_123456789_123456789_123456789_123456789_123456789_123456789\
> _123456789_123456789_123456789_123456789_123456789_1234"
[sougata@ultrabook tmp]$ name256="${name255}5"
[sougata@ultrabook tmp]$
[sougata@ultrabook tmp]$ mkdir $dir
[sougata@ultrabook tmp]$ cd $dir
[sougata@ultrabook TEST_DIR]$ touch $name255
[sougata@ultrabook TEST_DIR]$ rm -f $name255
[sougata@ultrabook TEST_DIR]$ touch $name256
[sougata@ultrabook TEST_DIR]$ ls -la
ls: cannot access
_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_1234:
No such file or directory
total 0
drwxrwxr-x 1 sougata sougata 3 Feb 20 19:56 .
drwxrwxrwx 1 root root 6 Feb 20 19:56 ..
-????????? ? ? ? ? ?
_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_1234
[sougata@ultrabook TEST_DIR]$ cd $cdir
[sougata@ultrabook tmp]$ rm -rf $dir
rm: cannot remove `TEST_DIR': Directory not empty
-ENAMETOOLONG returned from hfsplus_asc2uni was not propaged to iops.
This allowed hfsplus to create files/directories with HFSPLUS_MAX_STRLEN
and incorrect keys, leaving the FS in an inconsistent state. This patch
fixes this issue.
Signed-off-by: Sougata Santra <sougata@tuxera.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: Vyacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/hfsplus')
| -rw-r--r-- | fs/hfsplus/catalog.c | 89 | ||||
| -rw-r--r-- | fs/hfsplus/dir.c | 11 | ||||
| -rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 4 | ||||
| -rw-r--r-- | fs/hfsplus/super.c | 4 |
4 files changed, 79 insertions, 29 deletions
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 32602c667b4a..7892e6fddb66 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c | |||
| @@ -38,21 +38,30 @@ int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1, | |||
| 38 | return hfsplus_strcmp(&k1->cat.name, &k2->cat.name); | 38 | return hfsplus_strcmp(&k1->cat.name, &k2->cat.name); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key, | 41 | /* Generates key for catalog file/folders record. */ |
| 42 | u32 parent, struct qstr *str) | 42 | int hfsplus_cat_build_key(struct super_block *sb, |
| 43 | hfsplus_btree_key *key, u32 parent, struct qstr *str) | ||
| 43 | { | 44 | { |
| 44 | int len; | 45 | int len, err; |
| 45 | 46 | ||
| 46 | key->cat.parent = cpu_to_be32(parent); | 47 | key->cat.parent = cpu_to_be32(parent); |
| 47 | if (str) { | 48 | err = hfsplus_asc2uni(sb, &key->cat.name, HFSPLUS_MAX_STRLEN, |
| 48 | hfsplus_asc2uni(sb, &key->cat.name, HFSPLUS_MAX_STRLEN, | 49 | str->name, str->len); |
| 49 | str->name, str->len); | 50 | if (unlikely(err < 0)) |
| 50 | len = be16_to_cpu(key->cat.name.length); | 51 | return err; |
| 51 | } else { | 52 | |
| 52 | key->cat.name.length = 0; | 53 | len = be16_to_cpu(key->cat.name.length); |
| 53 | len = 0; | ||
| 54 | } | ||
| 55 | key->key_len = cpu_to_be16(6 + 2 * len); | 54 | key->key_len = cpu_to_be16(6 + 2 * len); |
| 55 | return 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | /* Generates key for catalog thread record. */ | ||
| 59 | void hfsplus_cat_build_key_with_cnid(struct super_block *sb, | ||
| 60 | hfsplus_btree_key *key, u32 parent) | ||
| 61 | { | ||
| 62 | key->cat.parent = cpu_to_be32(parent); | ||
| 63 | key->cat.name.length = 0; | ||
| 64 | key->key_len = cpu_to_be16(6); | ||
| 56 | } | 65 | } |
| 57 | 66 | ||
| 58 | static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent, | 67 | static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent, |
| @@ -167,11 +176,16 @@ static int hfsplus_fill_cat_thread(struct super_block *sb, | |||
| 167 | hfsplus_cat_entry *entry, int type, | 176 | hfsplus_cat_entry *entry, int type, |
| 168 | u32 parentid, struct qstr *str) | 177 | u32 parentid, struct qstr *str) |
| 169 | { | 178 | { |
| 179 | int err; | ||
| 180 | |||
| 170 | entry->type = cpu_to_be16(type); | 181 | entry->type = cpu_to_be16(type); |
| 171 | entry->thread.reserved = 0; | 182 | entry->thread.reserved = 0; |
| 172 | entry->thread.parentID = cpu_to_be32(parentid); | 183 | entry->thread.parentID = cpu_to_be32(parentid); |
| 173 | hfsplus_asc2uni(sb, &entry->thread.nodeName, HFSPLUS_MAX_STRLEN, | 184 | err = hfsplus_asc2uni(sb, &entry->thread.nodeName, HFSPLUS_MAX_STRLEN, |
| 174 | str->name, str->len); | 185 | str->name, str->len); |
| 186 | if (unlikely(err < 0)) | ||
| 187 | return err; | ||
| 188 | |||
| 175 | return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2; | 189 | return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2; |
| 176 | } | 190 | } |
| 177 | 191 | ||
| @@ -183,7 +197,7 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid, | |||
| 183 | int err; | 197 | int err; |
| 184 | u16 type; | 198 | u16 type; |
| 185 | 199 | ||
| 186 | hfsplus_cat_build_key(sb, fd->search_key, cnid, NULL); | 200 | hfsplus_cat_build_key_with_cnid(sb, fd->search_key, cnid); |
| 187 | err = hfs_brec_read(fd, &tmp, sizeof(hfsplus_cat_entry)); | 201 | err = hfs_brec_read(fd, &tmp, sizeof(hfsplus_cat_entry)); |
| 188 | if (err) | 202 | if (err) |
| 189 | return err; | 203 | return err; |
| @@ -250,11 +264,16 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, | |||
| 250 | if (err) | 264 | if (err) |
| 251 | return err; | 265 | return err; |
| 252 | 266 | ||
| 253 | hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); | 267 | hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
| 254 | entry_size = hfsplus_fill_cat_thread(sb, &entry, | 268 | entry_size = hfsplus_fill_cat_thread(sb, &entry, |
| 255 | S_ISDIR(inode->i_mode) ? | 269 | S_ISDIR(inode->i_mode) ? |
| 256 | HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD, | 270 | HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD, |
| 257 | dir->i_ino, str); | 271 | dir->i_ino, str); |
| 272 | if (unlikely(entry_size < 0)) { | ||
| 273 | err = entry_size; | ||
| 274 | goto err2; | ||
| 275 | } | ||
| 276 | |||
| 258 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); | 277 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
| 259 | if (err != -ENOENT) { | 278 | if (err != -ENOENT) { |
| 260 | if (!err) | 279 | if (!err) |
| @@ -265,7 +284,10 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, | |||
| 265 | if (err) | 284 | if (err) |
| 266 | goto err2; | 285 | goto err2; |
| 267 | 286 | ||
| 268 | hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); | 287 | err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); |
| 288 | if (unlikely(err)) | ||
| 289 | goto err1; | ||
| 290 | |||
| 269 | entry_size = hfsplus_cat_build_record(&entry, cnid, inode); | 291 | entry_size = hfsplus_cat_build_record(&entry, cnid, inode); |
| 270 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); | 292 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
| 271 | if (err != -ENOENT) { | 293 | if (err != -ENOENT) { |
| @@ -288,7 +310,7 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, | |||
| 288 | return 0; | 310 | return 0; |
| 289 | 311 | ||
| 290 | err1: | 312 | err1: |
| 291 | hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); | 313 | hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
| 292 | if (!hfs_brec_find(&fd, hfs_find_rec_by_key)) | 314 | if (!hfs_brec_find(&fd, hfs_find_rec_by_key)) |
| 293 | hfs_brec_remove(&fd); | 315 | hfs_brec_remove(&fd); |
| 294 | err2: | 316 | err2: |
| @@ -313,7 +335,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) | |||
| 313 | if (!str) { | 335 | if (!str) { |
| 314 | int len; | 336 | int len; |
| 315 | 337 | ||
| 316 | hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); | 338 | hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
| 317 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); | 339 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
| 318 | if (err) | 340 | if (err) |
| 319 | goto out; | 341 | goto out; |
| @@ -329,7 +351,9 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) | |||
| 329 | off + 2, len); | 351 | off + 2, len); |
| 330 | fd.search_key->key_len = cpu_to_be16(6 + len); | 352 | fd.search_key->key_len = cpu_to_be16(6 + len); |
| 331 | } else | 353 | } else |
| 332 | hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); | 354 | err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); |
| 355 | if (unlikely(err)) | ||
| 356 | goto out; | ||
| 333 | 357 | ||
| 334 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); | 358 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
| 335 | if (err) | 359 | if (err) |
| @@ -360,7 +384,7 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) | |||
| 360 | if (err) | 384 | if (err) |
| 361 | goto out; | 385 | goto out; |
| 362 | 386 | ||
| 363 | hfsplus_cat_build_key(sb, fd.search_key, cnid, NULL); | 387 | hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
| 364 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); | 388 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
| 365 | if (err) | 389 | if (err) |
| 366 | goto out; | 390 | goto out; |
| @@ -405,7 +429,11 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 405 | dst_fd = src_fd; | 429 | dst_fd = src_fd; |
| 406 | 430 | ||
| 407 | /* find the old dir entry and read the data */ | 431 | /* find the old dir entry and read the data */ |
| 408 | hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name); | 432 | err = hfsplus_cat_build_key(sb, src_fd.search_key, |
| 433 | src_dir->i_ino, src_name); | ||
| 434 | if (unlikely(err)) | ||
| 435 | goto out; | ||
| 436 | |||
| 409 | err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); | 437 | err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); |
| 410 | if (err) | 438 | if (err) |
| 411 | goto out; | 439 | goto out; |
| @@ -419,7 +447,11 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 419 | type = be16_to_cpu(entry.type); | 447 | type = be16_to_cpu(entry.type); |
| 420 | 448 | ||
| 421 | /* create new dir entry with the data from the old entry */ | 449 | /* create new dir entry with the data from the old entry */ |
| 422 | hfsplus_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name); | 450 | err = hfsplus_cat_build_key(sb, dst_fd.search_key, |
| 451 | dst_dir->i_ino, dst_name); | ||
| 452 | if (unlikely(err)) | ||
| 453 | goto out; | ||
| 454 | |||
| 423 | err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); | 455 | err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); |
| 424 | if (err != -ENOENT) { | 456 | if (err != -ENOENT) { |
| 425 | if (!err) | 457 | if (!err) |
| @@ -436,7 +468,11 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 436 | dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC; | 468 | dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC; |
| 437 | 469 | ||
| 438 | /* finally remove the old entry */ | 470 | /* finally remove the old entry */ |
| 439 | hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name); | 471 | err = hfsplus_cat_build_key(sb, src_fd.search_key, |
| 472 | src_dir->i_ino, src_name); | ||
| 473 | if (unlikely(err)) | ||
| 474 | goto out; | ||
| 475 | |||
| 440 | err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); | 476 | err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); |
| 441 | if (err) | 477 | if (err) |
| 442 | goto out; | 478 | goto out; |
| @@ -449,7 +485,7 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 449 | src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC; | 485 | src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC; |
| 450 | 486 | ||
| 451 | /* remove old thread entry */ | 487 | /* remove old thread entry */ |
| 452 | hfsplus_cat_build_key(sb, src_fd.search_key, cnid, NULL); | 488 | hfsplus_cat_build_key_with_cnid(sb, src_fd.search_key, cnid); |
| 453 | err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); | 489 | err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); |
| 454 | if (err) | 490 | if (err) |
| 455 | goto out; | 491 | goto out; |
| @@ -459,9 +495,14 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 459 | goto out; | 495 | goto out; |
| 460 | 496 | ||
| 461 | /* create new thread entry */ | 497 | /* create new thread entry */ |
| 462 | hfsplus_cat_build_key(sb, dst_fd.search_key, cnid, NULL); | 498 | hfsplus_cat_build_key_with_cnid(sb, dst_fd.search_key, cnid); |
| 463 | entry_size = hfsplus_fill_cat_thread(sb, &entry, type, | 499 | entry_size = hfsplus_fill_cat_thread(sb, &entry, type, |
| 464 | dst_dir->i_ino, dst_name); | 500 | dst_dir->i_ino, dst_name); |
| 501 | if (unlikely(entry_size < 0)) { | ||
| 502 | err = entry_size; | ||
| 503 | goto out; | ||
| 504 | } | ||
| 505 | |||
| 465 | err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); | 506 | err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); |
| 466 | if (err != -ENOENT) { | 507 | if (err != -ENOENT) { |
| 467 | if (!err) | 508 | if (!err) |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 610a3260bef1..435bea231cc6 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
| @@ -44,7 +44,10 @@ static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, | |||
| 44 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); | 44 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); |
| 45 | if (err) | 45 | if (err) |
| 46 | return ERR_PTR(err); | 46 | return ERR_PTR(err); |
| 47 | hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, &dentry->d_name); | 47 | err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, |
| 48 | &dentry->d_name); | ||
| 49 | if (unlikely(err < 0)) | ||
| 50 | goto fail; | ||
| 48 | again: | 51 | again: |
| 49 | err = hfs_brec_read(&fd, &entry, sizeof(entry)); | 52 | err = hfs_brec_read(&fd, &entry, sizeof(entry)); |
| 50 | if (err) { | 53 | if (err) { |
| @@ -97,9 +100,11 @@ again: | |||
| 97 | be32_to_cpu(entry.file.permissions.dev); | 100 | be32_to_cpu(entry.file.permissions.dev); |
| 98 | str.len = sprintf(name, "iNode%d", linkid); | 101 | str.len = sprintf(name, "iNode%d", linkid); |
| 99 | str.name = name; | 102 | str.name = name; |
| 100 | hfsplus_cat_build_key(sb, fd.search_key, | 103 | err = hfsplus_cat_build_key(sb, fd.search_key, |
| 101 | HFSPLUS_SB(sb)->hidden_dir->i_ino, | 104 | HFSPLUS_SB(sb)->hidden_dir->i_ino, |
| 102 | &str); | 105 | &str); |
| 106 | if (unlikely(err < 0)) | ||
| 107 | goto fail; | ||
| 103 | goto again; | 108 | goto again; |
| 104 | } | 109 | } |
| 105 | } else if (!dentry->d_fsdata) | 110 | } else if (!dentry->d_fsdata) |
| @@ -145,7 +150,7 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx) | |||
| 145 | err = -ENOMEM; | 150 | err = -ENOMEM; |
| 146 | goto out; | 151 | goto out; |
| 147 | } | 152 | } |
| 148 | hfsplus_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); | 153 | hfsplus_cat_build_key_with_cnid(sb, fd.search_key, inode->i_ino); |
| 149 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); | 154 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
| 150 | if (err) | 155 | if (err) |
| 151 | goto out; | 156 | goto out; |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index eb5e059f481a..b0441d65fa54 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
| @@ -443,8 +443,10 @@ int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *k1, | |||
| 443 | const hfsplus_btree_key *k2); | 443 | const hfsplus_btree_key *k2); |
| 444 | int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1, | 444 | int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1, |
| 445 | const hfsplus_btree_key *k2); | 445 | const hfsplus_btree_key *k2); |
| 446 | void hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key, | 446 | int hfsplus_cat_build_key(struct super_block *sb, hfsplus_btree_key *key, |
| 447 | u32 parent, struct qstr *str); | 447 | u32 parent, struct qstr *str); |
| 448 | void hfsplus_cat_build_key_with_cnid(struct super_block *sb, | ||
| 449 | hfsplus_btree_key *key, u32 parent); | ||
| 448 | void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms); | 450 | void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms); |
| 449 | int hfsplus_find_cat(struct super_block *sb, u32 cnid, | 451 | int hfsplus_find_cat(struct super_block *sb, u32 cnid, |
| 450 | struct hfs_find_data *fd); | 452 | struct hfs_find_data *fd); |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 4cf2024b87da..593af2fdcc2d 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
| @@ -515,7 +515,9 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
| 515 | err = hfs_find_init(sbi->cat_tree, &fd); | 515 | err = hfs_find_init(sbi->cat_tree, &fd); |
| 516 | if (err) | 516 | if (err) |
| 517 | goto out_put_root; | 517 | goto out_put_root; |
| 518 | hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str); | 518 | err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str); |
| 519 | if (unlikely(err < 0)) | ||
| 520 | goto out_put_root; | ||
| 519 | if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { | 521 | if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { |
| 520 | hfs_find_exit(&fd); | 522 | hfs_find_exit(&fd); |
| 521 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) | 523 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) |
