diff options
Diffstat (limited to 'fs/nilfs2/inode.c')
| -rw-r--r-- | fs/nilfs2/inode.c | 32 | 
1 files changed, 19 insertions, 13 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 6e2c3db976b..6b49f14eac8 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -213,6 +213,16 @@ static int nilfs_set_page_dirty(struct page *page)  	return ret;  } +void nilfs_write_failed(struct address_space *mapping, loff_t to) +{ +	struct inode *inode = mapping->host; + +	if (to > inode->i_size) { +		truncate_pagecache(inode, to, inode->i_size); +		nilfs_truncate(inode); +	} +} +  static int nilfs_write_begin(struct file *file, struct address_space *mapping,  			     loff_t pos, unsigned len, unsigned flags,  			     struct page **pagep, void **fsdata) @@ -227,10 +237,7 @@ static int nilfs_write_begin(struct file *file, struct address_space *mapping,  	err = block_write_begin(mapping, pos, len, flags, pagep,  				nilfs_get_block);  	if (unlikely(err)) { -		loff_t isize = mapping->host->i_size; -		if (pos + len > isize) -			vmtruncate(mapping->host, isize); - +		nilfs_write_failed(mapping, pos + len);  		nilfs_transaction_abort(inode->i_sb);  	}  	return err; @@ -259,6 +266,7 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,  		loff_t offset, unsigned long nr_segs)  {  	struct file *file = iocb->ki_filp; +	struct address_space *mapping = file->f_mapping;  	struct inode *inode = file->f_mapping->host;  	ssize_t size; @@ -278,7 +286,7 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,  		loff_t end = offset + iov_length(iov, nr_segs);  		if (end > isize) -			vmtruncate(inode, isize); +			nilfs_write_failed(mapping, end);  	}  	return size; @@ -401,8 +409,8 @@ int nilfs_read_inode_common(struct inode *inode,  	int err;  	inode->i_mode = le16_to_cpu(raw_inode->i_mode); -	inode->i_uid = (uid_t)le32_to_cpu(raw_inode->i_uid); -	inode->i_gid = (gid_t)le32_to_cpu(raw_inode->i_gid); +	i_uid_write(inode, le32_to_cpu(raw_inode->i_uid)); +	i_gid_write(inode, le32_to_cpu(raw_inode->i_gid));  	set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));  	inode->i_size = le64_to_cpu(raw_inode->i_size);  	inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime); @@ -590,8 +598,8 @@ void nilfs_write_inode_common(struct inode *inode,  	struct nilfs_inode_info *ii = NILFS_I(inode);  	raw_inode->i_mode = cpu_to_le16(inode->i_mode); -	raw_inode->i_uid = cpu_to_le32(inode->i_uid); -	raw_inode->i_gid = cpu_to_le32(inode->i_gid); +	raw_inode->i_uid = cpu_to_le32(i_uid_read(inode)); +	raw_inode->i_gid = cpu_to_le32(i_gid_read(inode));  	raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);  	raw_inode->i_size = cpu_to_le64(inode->i_size);  	raw_inode->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); @@ -786,10 +794,8 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)  	if ((iattr->ia_valid & ATTR_SIZE) &&  	    iattr->ia_size != i_size_read(inode)) {  		inode_dio_wait(inode); - -		err = vmtruncate(inode, iattr->ia_size); -		if (unlikely(err)) -			goto out_err; +		truncate_setsize(inode, iattr->ia_size); +		nilfs_truncate(inode);  	}  	setattr_copy(inode, iattr);  |