diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a0ab3754d0d6..4b8debeb3965 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -167,11 +167,16 @@ int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode, | |||
167 | /* | 167 | /* |
168 | * Called at the last iput() if i_nlink is zero. | 168 | * Called at the last iput() if i_nlink is zero. |
169 | */ | 169 | */ |
170 | void ext4_delete_inode(struct inode *inode) | 170 | void ext4_evict_inode(struct inode *inode) |
171 | { | 171 | { |
172 | handle_t *handle; | 172 | handle_t *handle; |
173 | int err; | 173 | int err; |
174 | 174 | ||
175 | if (inode->i_nlink) { | ||
176 | truncate_inode_pages(&inode->i_data, 0); | ||
177 | goto no_delete; | ||
178 | } | ||
179 | |||
175 | if (!is_bad_inode(inode)) | 180 | if (!is_bad_inode(inode)) |
176 | dquot_initialize(inode); | 181 | dquot_initialize(inode); |
177 | 182 | ||
@@ -246,13 +251,13 @@ void ext4_delete_inode(struct inode *inode) | |||
246 | */ | 251 | */ |
247 | if (ext4_mark_inode_dirty(handle, inode)) | 252 | if (ext4_mark_inode_dirty(handle, inode)) |
248 | /* If that failed, just do the required in-core inode clear. */ | 253 | /* If that failed, just do the required in-core inode clear. */ |
249 | clear_inode(inode); | 254 | ext4_clear_inode(inode); |
250 | else | 255 | else |
251 | ext4_free_inode(handle, inode); | 256 | ext4_free_inode(handle, inode); |
252 | ext4_journal_stop(handle); | 257 | ext4_journal_stop(handle); |
253 | return; | 258 | return; |
254 | no_delete: | 259 | no_delete: |
255 | clear_inode(inode); /* We must guarantee clearing of inode... */ | 260 | ext4_clear_inode(inode); /* We must guarantee clearing of inode... */ |
256 | } | 261 | } |
257 | 262 | ||
258 | typedef struct { | 263 | typedef struct { |
@@ -1602,11 +1607,9 @@ retry: | |||
1602 | *pagep = page; | 1607 | *pagep = page; |
1603 | 1608 | ||
1604 | if (ext4_should_dioread_nolock(inode)) | 1609 | if (ext4_should_dioread_nolock(inode)) |
1605 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, | 1610 | ret = __block_write_begin(page, pos, len, ext4_get_block_write); |
1606 | fsdata, ext4_get_block_write); | ||
1607 | else | 1611 | else |
1608 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, | 1612 | ret = __block_write_begin(page, pos, len, ext4_get_block); |
1609 | fsdata, ext4_get_block); | ||
1610 | 1613 | ||
1611 | if (!ret && ext4_should_journal_data(inode)) { | 1614 | if (!ret && ext4_should_journal_data(inode)) { |
1612 | ret = walk_page_buffers(handle, page_buffers(page), | 1615 | ret = walk_page_buffers(handle, page_buffers(page), |
@@ -1617,7 +1620,7 @@ retry: | |||
1617 | unlock_page(page); | 1620 | unlock_page(page); |
1618 | page_cache_release(page); | 1621 | page_cache_release(page); |
1619 | /* | 1622 | /* |
1620 | * block_write_begin may have instantiated a few blocks | 1623 | * __block_write_begin may have instantiated a few blocks |
1621 | * outside i_size. Trim these off again. Don't need | 1624 | * outside i_size. Trim these off again. Don't need |
1622 | * i_size_read because we hold i_mutex. | 1625 | * i_size_read because we hold i_mutex. |
1623 | * | 1626 | * |
@@ -3205,8 +3208,7 @@ retry: | |||
3205 | } | 3208 | } |
3206 | *pagep = page; | 3209 | *pagep = page; |
3207 | 3210 | ||
3208 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 3211 | ret = __block_write_begin(page, pos, len, ext4_da_get_block_prep); |
3209 | ext4_da_get_block_prep); | ||
3210 | if (ret < 0) { | 3212 | if (ret < 0) { |
3211 | unlock_page(page); | 3213 | unlock_page(page); |
3212 | ext4_journal_stop(handle); | 3214 | ext4_journal_stop(handle); |
@@ -3565,15 +3567,24 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb, | |||
3565 | 3567 | ||
3566 | retry: | 3568 | retry: |
3567 | if (rw == READ && ext4_should_dioread_nolock(inode)) | 3569 | if (rw == READ && ext4_should_dioread_nolock(inode)) |
3568 | ret = blockdev_direct_IO_no_locking(rw, iocb, inode, | 3570 | ret = __blockdev_direct_IO(rw, iocb, inode, |
3569 | inode->i_sb->s_bdev, iov, | 3571 | inode->i_sb->s_bdev, iov, |
3570 | offset, nr_segs, | 3572 | offset, nr_segs, |
3571 | ext4_get_block, NULL); | 3573 | ext4_get_block, NULL, NULL, 0); |
3572 | else | 3574 | else { |
3573 | ret = blockdev_direct_IO(rw, iocb, inode, | 3575 | ret = blockdev_direct_IO(rw, iocb, inode, |
3574 | inode->i_sb->s_bdev, iov, | 3576 | inode->i_sb->s_bdev, iov, |
3575 | offset, nr_segs, | 3577 | offset, nr_segs, |
3576 | ext4_get_block, NULL); | 3578 | ext4_get_block, NULL); |
3579 | |||
3580 | if (unlikely((rw & WRITE) && ret < 0)) { | ||
3581 | loff_t isize = i_size_read(inode); | ||
3582 | loff_t end = offset + iov_length(iov, nr_segs); | ||
3583 | |||
3584 | if (end > isize) | ||
3585 | vmtruncate(inode, isize); | ||
3586 | } | ||
3587 | } | ||
3577 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 3588 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
3578 | goto retry; | 3589 | goto retry; |
3579 | 3590 | ||
@@ -5536,11 +5547,19 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
5536 | ext4_truncate(inode); | 5547 | ext4_truncate(inode); |
5537 | } | 5548 | } |
5538 | 5549 | ||
5539 | rc = inode_setattr(inode, attr); | 5550 | if ((attr->ia_valid & ATTR_SIZE) && |
5551 | attr->ia_size != i_size_read(inode)) | ||
5552 | rc = vmtruncate(inode, attr->ia_size); | ||
5540 | 5553 | ||
5541 | /* If inode_setattr's call to ext4_truncate failed to get a | 5554 | if (!rc) { |
5542 | * transaction handle at all, we need to clean up the in-core | 5555 | setattr_copy(inode, attr); |
5543 | * orphan list manually. */ | 5556 | mark_inode_dirty(inode); |
5557 | } | ||
5558 | |||
5559 | /* | ||
5560 | * If the call to ext4_truncate failed to get a transaction handle at | ||
5561 | * all, we need to clean up the in-core orphan list manually. | ||
5562 | */ | ||
5544 | if (inode->i_nlink) | 5563 | if (inode->i_nlink) |
5545 | ext4_orphan_del(NULL, inode); | 5564 | ext4_orphan_del(NULL, inode); |
5546 | 5565 | ||