aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/inode.c')
-rw-r--r--fs/nilfs2/inode.c78
1 files changed, 64 insertions, 14 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 39e038ac8fcb..eccb2f2e2315 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -27,6 +27,7 @@
27#include <linux/writeback.h> 27#include <linux/writeback.h>
28#include <linux/uio.h> 28#include <linux/uio.h>
29#include "nilfs.h" 29#include "nilfs.h"
30#include "btnode.h"
30#include "segment.h" 31#include "segment.h"
31#include "page.h" 32#include "page.h"
32#include "mdt.h" 33#include "mdt.h"
@@ -197,11 +198,15 @@ static int nilfs_write_begin(struct file *file, struct address_space *mapping,
197 if (unlikely(err)) 198 if (unlikely(err))
198 return err; 199 return err;
199 200
200 *pagep = NULL; 201 err = block_write_begin(mapping, pos, len, flags, pagep,
201 err = block_write_begin(file, mapping, pos, len, flags, pagep, 202 nilfs_get_block);
202 fsdata, nilfs_get_block); 203 if (unlikely(err)) {
203 if (unlikely(err)) 204 loff_t isize = mapping->host->i_size;
205 if (pos + len > isize)
206 vmtruncate(mapping->host, isize);
207
204 nilfs_transaction_abort(inode->i_sb); 208 nilfs_transaction_abort(inode->i_sb);
209 }
205 return err; 210 return err;
206} 211}
207 212
@@ -237,6 +242,19 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
237 /* Needs synchronization with the cleaner */ 242 /* Needs synchronization with the cleaner */
238 size = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 243 size = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
239 offset, nr_segs, nilfs_get_block, NULL); 244 offset, nr_segs, nilfs_get_block, NULL);
245
246 /*
247 * In case of error extending write may have instantiated a few
248 * blocks outside i_size. Trim these off again.
249 */
250 if (unlikely((rw & WRITE) && size < 0)) {
251 loff_t isize = i_size_read(inode);
252 loff_t end = offset + iov_length(iov, nr_segs);
253
254 if (end > isize)
255 vmtruncate(inode, isize);
256 }
257
240 return size; 258 return size;
241} 259}
242 260
@@ -337,7 +355,6 @@ void nilfs_free_inode(struct inode *inode)
337 struct super_block *sb = inode->i_sb; 355 struct super_block *sb = inode->i_sb;
338 struct nilfs_sb_info *sbi = NILFS_SB(sb); 356 struct nilfs_sb_info *sbi = NILFS_SB(sb);
339 357
340 clear_inode(inode);
341 /* XXX: check error code? Is there any thing I can do? */ 358 /* XXX: check error code? Is there any thing I can do? */
342 (void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino); 359 (void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino);
343 atomic_dec(&sbi->s_inodes_count); 360 atomic_dec(&sbi->s_inodes_count);
@@ -597,16 +614,34 @@ void nilfs_truncate(struct inode *inode)
597 But truncate has no return value. */ 614 But truncate has no return value. */
598} 615}
599 616
600void nilfs_delete_inode(struct inode *inode) 617static void nilfs_clear_inode(struct inode *inode)
618{
619 struct nilfs_inode_info *ii = NILFS_I(inode);
620
621 /*
622 * Free resources allocated in nilfs_read_inode(), here.
623 */
624 BUG_ON(!list_empty(&ii->i_dirty));
625 brelse(ii->i_bh);
626 ii->i_bh = NULL;
627
628 if (test_bit(NILFS_I_BMAP, &ii->i_state))
629 nilfs_bmap_clear(ii->i_bmap);
630
631 nilfs_btnode_cache_clear(&ii->i_btnode_cache);
632}
633
634void nilfs_evict_inode(struct inode *inode)
601{ 635{
602 struct nilfs_transaction_info ti; 636 struct nilfs_transaction_info ti;
603 struct super_block *sb = inode->i_sb; 637 struct super_block *sb = inode->i_sb;
604 struct nilfs_inode_info *ii = NILFS_I(inode); 638 struct nilfs_inode_info *ii = NILFS_I(inode);
605 639
606 if (unlikely(is_bad_inode(inode))) { 640 if (inode->i_nlink || unlikely(is_bad_inode(inode))) {
607 if (inode->i_data.nrpages) 641 if (inode->i_data.nrpages)
608 truncate_inode_pages(&inode->i_data, 0); 642 truncate_inode_pages(&inode->i_data, 0);
609 clear_inode(inode); 643 end_writeback(inode);
644 nilfs_clear_inode(inode);
610 return; 645 return;
611 } 646 }
612 nilfs_transaction_begin(sb, &ti, 0); /* never fails */ 647 nilfs_transaction_begin(sb, &ti, 0); /* never fails */
@@ -616,6 +651,8 @@ void nilfs_delete_inode(struct inode *inode)
616 651
617 nilfs_truncate_bmap(ii, 0); 652 nilfs_truncate_bmap(ii, 0);
618 nilfs_mark_inode_dirty(inode); 653 nilfs_mark_inode_dirty(inode);
654 end_writeback(inode);
655 nilfs_clear_inode(inode);
619 nilfs_free_inode(inode); 656 nilfs_free_inode(inode);
620 /* nilfs_free_inode() marks inode buffer dirty */ 657 /* nilfs_free_inode() marks inode buffer dirty */
621 if (IS_SYNC(inode)) 658 if (IS_SYNC(inode))
@@ -639,14 +676,27 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)
639 err = nilfs_transaction_begin(sb, &ti, 0); 676 err = nilfs_transaction_begin(sb, &ti, 0);
640 if (unlikely(err)) 677 if (unlikely(err))
641 return err; 678 return err;
642 err = inode_setattr(inode, iattr); 679
643 if (!err && (iattr->ia_valid & ATTR_MODE)) 680 if ((iattr->ia_valid & ATTR_SIZE) &&
681 iattr->ia_size != i_size_read(inode)) {
682 err = vmtruncate(inode, iattr->ia_size);
683 if (unlikely(err))
684 goto out_err;
685 }
686
687 setattr_copy(inode, iattr);
688 mark_inode_dirty(inode);
689
690 if (iattr->ia_valid & ATTR_MODE) {
644 err = nilfs_acl_chmod(inode); 691 err = nilfs_acl_chmod(inode);
645 if (likely(!err)) 692 if (unlikely(err))
646 err = nilfs_transaction_commit(sb); 693 goto out_err;
647 else 694 }
648 nilfs_transaction_abort(sb); 695
696 return nilfs_transaction_commit(sb);
649 697
698out_err:
699 nilfs_transaction_abort(sb);
650 return err; 700 return err;
651} 701}
652 702