diff options
Diffstat (limited to 'fs/jfs/inode.c')
-rw-r--r-- | fs/jfs/inode.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index ed9ba6fe04f5..9978803ceedc 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -145,31 +145,32 @@ int jfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | void jfs_delete_inode(struct inode *inode) | 148 | void jfs_evict_inode(struct inode *inode) |
149 | { | 149 | { |
150 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); | 150 | jfs_info("In jfs_evict_inode, inode = 0x%p", inode); |
151 | 151 | ||
152 | if (!is_bad_inode(inode)) | 152 | if (!inode->i_nlink && !is_bad_inode(inode)) { |
153 | dquot_initialize(inode); | 153 | dquot_initialize(inode); |
154 | 154 | ||
155 | if (!is_bad_inode(inode) && | 155 | if (JFS_IP(inode)->fileset == FILESYSTEM_I) { |
156 | (JFS_IP(inode)->fileset == FILESYSTEM_I)) { | 156 | truncate_inode_pages(&inode->i_data, 0); |
157 | truncate_inode_pages(&inode->i_data, 0); | ||
158 | 157 | ||
159 | if (test_cflag(COMMIT_Freewmap, inode)) | 158 | if (test_cflag(COMMIT_Freewmap, inode)) |
160 | jfs_free_zero_link(inode); | 159 | jfs_free_zero_link(inode); |
161 | 160 | ||
162 | diFree(inode); | 161 | diFree(inode); |
163 | 162 | ||
164 | /* | 163 | /* |
165 | * Free the inode from the quota allocation. | 164 | * Free the inode from the quota allocation. |
166 | */ | 165 | */ |
167 | dquot_initialize(inode); | 166 | dquot_initialize(inode); |
168 | dquot_free_inode(inode); | 167 | dquot_free_inode(inode); |
169 | dquot_drop(inode); | 168 | } |
169 | } else { | ||
170 | truncate_inode_pages(&inode->i_data, 0); | ||
170 | } | 171 | } |
171 | 172 | end_writeback(inode); | |
172 | clear_inode(inode); | 173 | dquot_drop(inode); |
173 | } | 174 | } |
174 | 175 | ||
175 | void jfs_dirty_inode(struct inode *inode) | 176 | void jfs_dirty_inode(struct inode *inode) |
@@ -303,8 +304,17 @@ static int jfs_write_begin(struct file *file, struct address_space *mapping, | |||
303 | loff_t pos, unsigned len, unsigned flags, | 304 | loff_t pos, unsigned len, unsigned flags, |
304 | struct page **pagep, void **fsdata) | 305 | struct page **pagep, void **fsdata) |
305 | { | 306 | { |
306 | return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 307 | int ret; |
308 | |||
309 | ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata, | ||
307 | jfs_get_block); | 310 | jfs_get_block); |
311 | if (unlikely(ret)) { | ||
312 | loff_t isize = mapping->host->i_size; | ||
313 | if (pos + len > isize) | ||
314 | vmtruncate(mapping->host, isize); | ||
315 | } | ||
316 | |||
317 | return ret; | ||
308 | } | 318 | } |
309 | 319 | ||
310 | static sector_t jfs_bmap(struct address_space *mapping, sector_t block) | 320 | static sector_t jfs_bmap(struct address_space *mapping, sector_t block) |
@@ -317,9 +327,24 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb, | |||
317 | { | 327 | { |
318 | struct file *file = iocb->ki_filp; | 328 | struct file *file = iocb->ki_filp; |
319 | struct inode *inode = file->f_mapping->host; | 329 | struct inode *inode = file->f_mapping->host; |
330 | ssize_t ret; | ||
320 | 331 | ||
321 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 332 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
322 | offset, nr_segs, jfs_get_block, NULL); | 333 | offset, nr_segs, jfs_get_block, NULL); |
334 | |||
335 | /* | ||
336 | * In case of error extending write may have instantiated a few | ||
337 | * blocks outside i_size. Trim these off again. | ||
338 | */ | ||
339 | if (unlikely((rw & WRITE) && ret < 0)) { | ||
340 | loff_t isize = i_size_read(inode); | ||
341 | loff_t end = offset + iov_length(iov, nr_segs); | ||
342 | |||
343 | if (end > isize) | ||
344 | vmtruncate(inode, isize); | ||
345 | } | ||
346 | |||
347 | return ret; | ||
323 | } | 348 | } |
324 | 349 | ||
325 | const struct address_space_operations jfs_aops = { | 350 | const struct address_space_operations jfs_aops = { |