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 = { |
