| .. | .. |
|---|
| 187 | 187 | mode = be16_to_cpu(perms->mode); |
|---|
| 188 | 188 | |
|---|
| 189 | 189 | i_uid_write(inode, be32_to_cpu(perms->owner)); |
|---|
| 190 | | - if (!i_uid_read(inode) && !mode) |
|---|
| 190 | + if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) |
|---|
| 191 | 191 | inode->i_uid = sbi->uid; |
|---|
| 192 | 192 | |
|---|
| 193 | 193 | i_gid_write(inode, be32_to_cpu(perms->group)); |
|---|
| 194 | | - if (!i_gid_read(inode) && !mode) |
|---|
| 194 | + if ((test_bit(HFSPLUS_SB_GID, &sbi->flags)) || (!i_gid_read(inode) && !mode)) |
|---|
| 195 | 195 | inode->i_gid = sbi->gid; |
|---|
| 196 | 196 | |
|---|
| 197 | 197 | if (dir) { |
|---|
| .. | .. |
|---|
| 270 | 270 | return 0; |
|---|
| 271 | 271 | } |
|---|
| 272 | 272 | |
|---|
| 273 | +int hfsplus_getattr(const struct path *path, struct kstat *stat, |
|---|
| 274 | + u32 request_mask, unsigned int query_flags) |
|---|
| 275 | +{ |
|---|
| 276 | + struct inode *inode = d_inode(path->dentry); |
|---|
| 277 | + struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
|---|
| 278 | + |
|---|
| 279 | + if (inode->i_flags & S_APPEND) |
|---|
| 280 | + stat->attributes |= STATX_ATTR_APPEND; |
|---|
| 281 | + if (inode->i_flags & S_IMMUTABLE) |
|---|
| 282 | + stat->attributes |= STATX_ATTR_IMMUTABLE; |
|---|
| 283 | + if (hip->userflags & HFSPLUS_FLG_NODUMP) |
|---|
| 284 | + stat->attributes |= STATX_ATTR_NODUMP; |
|---|
| 285 | + |
|---|
| 286 | + stat->attributes_mask |= STATX_ATTR_APPEND | STATX_ATTR_IMMUTABLE | |
|---|
| 287 | + STATX_ATTR_NODUMP; |
|---|
| 288 | + |
|---|
| 289 | + generic_fillattr(inode, stat); |
|---|
| 290 | + return 0; |
|---|
| 291 | +} |
|---|
| 292 | + |
|---|
| 273 | 293 | int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, |
|---|
| 274 | 294 | int datasync) |
|---|
| 275 | 295 | { |
|---|
| .. | .. |
|---|
| 320 | 340 | } |
|---|
| 321 | 341 | |
|---|
| 322 | 342 | if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) |
|---|
| 323 | | - blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); |
|---|
| 343 | + blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL); |
|---|
| 324 | 344 | |
|---|
| 325 | 345 | inode_unlock(inode); |
|---|
| 326 | 346 | |
|---|
| .. | .. |
|---|
| 329 | 349 | |
|---|
| 330 | 350 | static const struct inode_operations hfsplus_file_inode_operations = { |
|---|
| 331 | 351 | .setattr = hfsplus_setattr, |
|---|
| 352 | + .getattr = hfsplus_getattr, |
|---|
| 332 | 353 | .listxattr = hfsplus_listxattr, |
|---|
| 333 | 354 | }; |
|---|
| 334 | 355 | |
|---|
| .. | .. |
|---|
| 476 | 497 | if (type == HFSPLUS_FOLDER) { |
|---|
| 477 | 498 | struct hfsplus_cat_folder *folder = &entry.folder; |
|---|
| 478 | 499 | |
|---|
| 479 | | - if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) |
|---|
| 480 | | - /* panic? */; |
|---|
| 500 | + if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) { |
|---|
| 501 | + pr_err("bad catalog folder entry\n"); |
|---|
| 502 | + res = -EIO; |
|---|
| 503 | + goto out; |
|---|
| 504 | + } |
|---|
| 481 | 505 | hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, |
|---|
| 482 | 506 | sizeof(struct hfsplus_cat_folder)); |
|---|
| 483 | 507 | hfsplus_get_perms(inode, &folder->permissions, 1); |
|---|
| 484 | 508 | set_nlink(inode, 1); |
|---|
| 485 | 509 | inode->i_size = 2 + be32_to_cpu(folder->valence); |
|---|
| 486 | | - inode->i_atime = timespec_to_timespec64(hfsp_mt2ut(folder->access_date)); |
|---|
| 487 | | - inode->i_mtime = timespec_to_timespec64(hfsp_mt2ut(folder->content_mod_date)); |
|---|
| 488 | | - inode->i_ctime = timespec_to_timespec64(hfsp_mt2ut(folder->attribute_mod_date)); |
|---|
| 510 | + inode->i_atime = hfsp_mt2ut(folder->access_date); |
|---|
| 511 | + inode->i_mtime = hfsp_mt2ut(folder->content_mod_date); |
|---|
| 512 | + inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); |
|---|
| 489 | 513 | HFSPLUS_I(inode)->create_date = folder->create_date; |
|---|
| 490 | 514 | HFSPLUS_I(inode)->fs_blocks = 0; |
|---|
| 491 | 515 | if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) { |
|---|
| .. | .. |
|---|
| 497 | 521 | } else if (type == HFSPLUS_FILE) { |
|---|
| 498 | 522 | struct hfsplus_cat_file *file = &entry.file; |
|---|
| 499 | 523 | |
|---|
| 500 | | - if (fd->entrylength < sizeof(struct hfsplus_cat_file)) |
|---|
| 501 | | - /* panic? */; |
|---|
| 524 | + if (fd->entrylength < sizeof(struct hfsplus_cat_file)) { |
|---|
| 525 | + pr_err("bad catalog file entry\n"); |
|---|
| 526 | + res = -EIO; |
|---|
| 527 | + goto out; |
|---|
| 528 | + } |
|---|
| 502 | 529 | hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, |
|---|
| 503 | 530 | sizeof(struct hfsplus_cat_file)); |
|---|
| 504 | 531 | |
|---|
| .. | .. |
|---|
| 521 | 548 | init_special_inode(inode, inode->i_mode, |
|---|
| 522 | 549 | be32_to_cpu(file->permissions.dev)); |
|---|
| 523 | 550 | } |
|---|
| 524 | | - inode->i_atime = timespec_to_timespec64(hfsp_mt2ut(file->access_date)); |
|---|
| 525 | | - inode->i_mtime = timespec_to_timespec64(hfsp_mt2ut(file->content_mod_date)); |
|---|
| 526 | | - inode->i_ctime = timespec_to_timespec64(hfsp_mt2ut(file->attribute_mod_date)); |
|---|
| 551 | + inode->i_atime = hfsp_mt2ut(file->access_date); |
|---|
| 552 | + inode->i_mtime = hfsp_mt2ut(file->content_mod_date); |
|---|
| 553 | + inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); |
|---|
| 527 | 554 | HFSPLUS_I(inode)->create_date = file->create_date; |
|---|
| 528 | 555 | } else { |
|---|
| 529 | 556 | pr_err("bad catalog entry used to create inode\n"); |
|---|
| 530 | 557 | res = -EIO; |
|---|
| 531 | 558 | } |
|---|
| 559 | +out: |
|---|
| 532 | 560 | return res; |
|---|
| 533 | 561 | } |
|---|
| 534 | 562 | |
|---|
| .. | .. |
|---|
| 537 | 565 | struct inode *main_inode = inode; |
|---|
| 538 | 566 | struct hfs_find_data fd; |
|---|
| 539 | 567 | hfsplus_cat_entry entry; |
|---|
| 568 | + int res = 0; |
|---|
| 540 | 569 | |
|---|
| 541 | 570 | if (HFSPLUS_IS_RSRC(inode)) |
|---|
| 542 | 571 | main_inode = HFSPLUS_I(inode)->rsrc_inode; |
|---|
| .. | .. |
|---|
| 555 | 584 | if (S_ISDIR(main_inode->i_mode)) { |
|---|
| 556 | 585 | struct hfsplus_cat_folder *folder = &entry.folder; |
|---|
| 557 | 586 | |
|---|
| 558 | | - if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) |
|---|
| 559 | | - /* panic? */; |
|---|
| 587 | + if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) { |
|---|
| 588 | + pr_err("bad catalog folder entry\n"); |
|---|
| 589 | + res = -EIO; |
|---|
| 590 | + goto out; |
|---|
| 591 | + } |
|---|
| 560 | 592 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
|---|
| 561 | 593 | sizeof(struct hfsplus_cat_folder)); |
|---|
| 562 | 594 | /* simple node checks? */ |
|---|
| .. | .. |
|---|
| 581 | 613 | } else { |
|---|
| 582 | 614 | struct hfsplus_cat_file *file = &entry.file; |
|---|
| 583 | 615 | |
|---|
| 584 | | - if (fd.entrylength < sizeof(struct hfsplus_cat_file)) |
|---|
| 585 | | - /* panic? */; |
|---|
| 616 | + if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { |
|---|
| 617 | + pr_err("bad catalog file entry\n"); |
|---|
| 618 | + res = -EIO; |
|---|
| 619 | + goto out; |
|---|
| 620 | + } |
|---|
| 586 | 621 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
|---|
| 587 | 622 | sizeof(struct hfsplus_cat_file)); |
|---|
| 588 | 623 | hfsplus_inode_write_fork(inode, &file->data_fork); |
|---|
| .. | .. |
|---|
| 603 | 638 | set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); |
|---|
| 604 | 639 | out: |
|---|
| 605 | 640 | hfs_find_exit(&fd); |
|---|
| 606 | | - return 0; |
|---|
| 641 | + return res; |
|---|
| 607 | 642 | } |
|---|