diff options
Diffstat (limited to 'fs/hfs')
-rw-r--r-- | fs/hfs/btree.c | 20 | ||||
-rw-r--r-- | fs/hfs/inode.c | 15 | ||||
-rw-r--r-- | fs/hfs/trans.c | 2 |
3 files changed, 29 insertions, 8 deletions
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 3ebc437736f..1cbdeea1db4 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c | |||
@@ -46,11 +46,26 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
46 | case HFS_EXT_CNID: | 46 | case HFS_EXT_CNID: |
47 | hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, | 47 | hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, |
48 | mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); | 48 | mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); |
49 | if (HFS_I(tree->inode)->alloc_blocks > | ||
50 | HFS_I(tree->inode)->first_blocks) { | ||
51 | printk(KERN_ERR "hfs: invalid btree extent records\n"); | ||
52 | unlock_new_inode(tree->inode); | ||
53 | goto free_inode; | ||
54 | } | ||
55 | |||
49 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; | 56 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; |
50 | break; | 57 | break; |
51 | case HFS_CAT_CNID: | 58 | case HFS_CAT_CNID: |
52 | hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, | 59 | hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, |
53 | mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); | 60 | mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); |
61 | |||
62 | if (!HFS_I(tree->inode)->first_blocks) { | ||
63 | printk(KERN_ERR "hfs: invalid btree extent records " | ||
64 | "(0 size).\n"); | ||
65 | unlock_new_inode(tree->inode); | ||
66 | goto free_inode; | ||
67 | } | ||
68 | |||
54 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; | 69 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; |
55 | break; | 70 | break; |
56 | default: | 71 | default: |
@@ -59,11 +74,6 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
59 | } | 74 | } |
60 | unlock_new_inode(tree->inode); | 75 | unlock_new_inode(tree->inode); |
61 | 76 | ||
62 | if (!HFS_I(tree->inode)->first_blocks) { | ||
63 | printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n"); | ||
64 | goto free_inode; | ||
65 | } | ||
66 | |||
67 | mapping = tree->inode->i_mapping; | 77 | mapping = tree->inode->i_mapping; |
68 | page = read_mapping_page(mapping, 0, NULL); | 78 | page = read_mapping_page(mapping, 0, NULL); |
69 | if (IS_ERR(page)) | 79 | if (IS_ERR(page)) |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index fff16c968e6..96a1b625fc7 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -123,8 +123,8 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb, | |||
123 | struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; | 123 | struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; |
124 | ssize_t ret; | 124 | ssize_t ret; |
125 | 125 | ||
126 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 126 | ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, |
127 | offset, nr_segs, hfs_get_block, NULL); | 127 | hfs_get_block); |
128 | 128 | ||
129 | /* | 129 | /* |
130 | * In case of error extending write may have instantiated a few | 130 | * In case of error extending write may have instantiated a few |
@@ -615,6 +615,8 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr) | |||
615 | 615 | ||
616 | if ((attr->ia_valid & ATTR_SIZE) && | 616 | if ((attr->ia_valid & ATTR_SIZE) && |
617 | attr->ia_size != i_size_read(inode)) { | 617 | attr->ia_size != i_size_read(inode)) { |
618 | inode_dio_wait(inode); | ||
619 | |||
618 | error = vmtruncate(inode, attr->ia_size); | 620 | error = vmtruncate(inode, attr->ia_size); |
619 | if (error) | 621 | if (error) |
620 | return error; | 622 | return error; |
@@ -625,12 +627,18 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr) | |||
625 | return 0; | 627 | return 0; |
626 | } | 628 | } |
627 | 629 | ||
628 | static int hfs_file_fsync(struct file *filp, int datasync) | 630 | static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end, |
631 | int datasync) | ||
629 | { | 632 | { |
630 | struct inode *inode = filp->f_mapping->host; | 633 | struct inode *inode = filp->f_mapping->host; |
631 | struct super_block * sb; | 634 | struct super_block * sb; |
632 | int ret, err; | 635 | int ret, err; |
633 | 636 | ||
637 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
638 | if (ret) | ||
639 | return ret; | ||
640 | mutex_lock(&inode->i_mutex); | ||
641 | |||
634 | /* sync the inode to buffers */ | 642 | /* sync the inode to buffers */ |
635 | ret = write_inode_now(inode, 0); | 643 | ret = write_inode_now(inode, 0); |
636 | 644 | ||
@@ -647,6 +655,7 @@ static int hfs_file_fsync(struct file *filp, int datasync) | |||
647 | err = sync_blockdev(sb->s_bdev); | 655 | err = sync_blockdev(sb->s_bdev); |
648 | if (!ret) | 656 | if (!ret) |
649 | ret = err; | 657 | ret = err; |
658 | mutex_unlock(&inode->i_mutex); | ||
650 | return ret; | 659 | return ret; |
651 | } | 660 | } |
652 | 661 | ||
diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c index e673a88b8ae..b1ce4c7ad3f 100644 --- a/fs/hfs/trans.c +++ b/fs/hfs/trans.c | |||
@@ -40,6 +40,8 @@ int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in) | |||
40 | 40 | ||
41 | src = in->name; | 41 | src = in->name; |
42 | srclen = in->len; | 42 | srclen = in->len; |
43 | if (srclen > HFS_NAMELEN) | ||
44 | srclen = HFS_NAMELEN; | ||
43 | dst = out; | 45 | dst = out; |
44 | dstlen = HFS_MAX_NAMELEN; | 46 | dstlen = HFS_MAX_NAMELEN; |
45 | if (nls_io) { | 47 | if (nls_io) { |