diff options
-rw-r--r-- | fs/hpfs/file.c | 20 | ||||
-rw-r--r-- | fs/hpfs/hpfs_fn.h | 1 | ||||
-rw-r--r-- | fs/hpfs/inode.c | 5 |
3 files changed, 18 insertions, 8 deletions
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 89d2a5803ae3..fbfe2df5624b 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c | |||
@@ -50,7 +50,7 @@ static secno hpfs_bmap(struct inode *inode, unsigned file_secno) | |||
50 | return disk_secno; | 50 | return disk_secno; |
51 | } | 51 | } |
52 | 52 | ||
53 | static void hpfs_truncate(struct inode *i) | 53 | void hpfs_truncate(struct inode *i) |
54 | { | 54 | { |
55 | if (IS_IMMUTABLE(i)) return /*-EPERM*/; | 55 | if (IS_IMMUTABLE(i)) return /*-EPERM*/; |
56 | hpfs_lock_assert(i->i_sb); | 56 | hpfs_lock_assert(i->i_sb); |
@@ -105,6 +105,16 @@ static int hpfs_readpage(struct file *file, struct page *page) | |||
105 | return block_read_full_page(page,hpfs_get_block); | 105 | return block_read_full_page(page,hpfs_get_block); |
106 | } | 106 | } |
107 | 107 | ||
108 | static void hpfs_write_failed(struct address_space *mapping, loff_t to) | ||
109 | { | ||
110 | struct inode *inode = mapping->host; | ||
111 | |||
112 | if (to > inode->i_size) { | ||
113 | truncate_pagecache(inode, to, inode->i_size); | ||
114 | hpfs_truncate(inode); | ||
115 | } | ||
116 | } | ||
117 | |||
108 | static int hpfs_write_begin(struct file *file, struct address_space *mapping, | 118 | static int hpfs_write_begin(struct file *file, struct address_space *mapping, |
109 | loff_t pos, unsigned len, unsigned flags, | 119 | loff_t pos, unsigned len, unsigned flags, |
110 | struct page **pagep, void **fsdata) | 120 | struct page **pagep, void **fsdata) |
@@ -115,11 +125,8 @@ static int hpfs_write_begin(struct file *file, struct address_space *mapping, | |||
115 | ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 125 | ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, |
116 | hpfs_get_block, | 126 | hpfs_get_block, |
117 | &hpfs_i(mapping->host)->mmu_private); | 127 | &hpfs_i(mapping->host)->mmu_private); |
118 | if (unlikely(ret)) { | 128 | if (unlikely(ret)) |
119 | loff_t isize = mapping->host->i_size; | 129 | hpfs_write_failed(mapping, pos + len); |
120 | if (pos + len > isize) | ||
121 | vmtruncate(mapping->host, isize); | ||
122 | } | ||
123 | 130 | ||
124 | return ret; | 131 | return ret; |
125 | } | 132 | } |
@@ -166,6 +173,5 @@ const struct file_operations hpfs_file_ops = | |||
166 | 173 | ||
167 | const struct inode_operations hpfs_file_iops = | 174 | const struct inode_operations hpfs_file_iops = |
168 | { | 175 | { |
169 | .truncate = hpfs_truncate, | ||
170 | .setattr = hpfs_setattr, | 176 | .setattr = hpfs_setattr, |
171 | }; | 177 | }; |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 7102aaecc244..b7ae286646b5 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -252,6 +252,7 @@ void hpfs_set_ea(struct inode *, struct fnode *, const char *, | |||
252 | /* file.c */ | 252 | /* file.c */ |
253 | 253 | ||
254 | int hpfs_file_fsync(struct file *, loff_t, loff_t, int); | 254 | int hpfs_file_fsync(struct file *, loff_t, loff_t, int); |
255 | void hpfs_truncate(struct inode *); | ||
255 | extern const struct file_operations hpfs_file_ops; | 256 | extern const struct file_operations hpfs_file_ops; |
256 | extern const struct inode_operations hpfs_file_iops; | 257 | extern const struct inode_operations hpfs_file_iops; |
257 | extern const struct address_space_operations hpfs_aops; | 258 | extern const struct address_space_operations hpfs_aops; |
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 804a9a842cbc..5dc06c837105 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -277,9 +277,12 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
277 | 277 | ||
278 | if ((attr->ia_valid & ATTR_SIZE) && | 278 | if ((attr->ia_valid & ATTR_SIZE) && |
279 | attr->ia_size != i_size_read(inode)) { | 279 | attr->ia_size != i_size_read(inode)) { |
280 | error = vmtruncate(inode, attr->ia_size); | 280 | error = inode_newsize_ok(inode, attr->ia_size); |
281 | if (error) | 281 | if (error) |
282 | goto out_unlock; | 282 | goto out_unlock; |
283 | |||
284 | truncate_setsize(inode, attr->ia_size); | ||
285 | hpfs_truncate(inode); | ||
283 | } | 286 | } |
284 | 287 | ||
285 | setattr_copy(inode, attr); | 288 | setattr_copy(inode, attr); |