|
@@ -1139,15 +1139,17 @@ int cifs_vmtruncate(struct inode * inode, loff_t offset)
|
|
|
struct address_space *mapping = inode->i_mapping;
|
|
|
unsigned long limit;
|
|
|
|
|
|
+ spin_lock(&inode->i_lock);
|
|
|
if (inode->i_size < offset)
|
|
|
goto do_expand;
|
|
|
/*
|
|
|
* truncation of in-use swapfiles is disallowed - it would cause
|
|
|
* subsequent swapout to scribble on the now-freed blocks.
|
|
|
*/
|
|
|
- if (IS_SWAPFILE(inode))
|
|
|
+ if (IS_SWAPFILE(inode)) {
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
goto out_busy;
|
|
|
- spin_lock(&inode->i_lock);
|
|
|
+ }
|
|
|
i_size_write(inode, offset);
|
|
|
spin_unlock(&inode->i_lock);
|
|
|
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
|
|
@@ -1156,12 +1158,16 @@ int cifs_vmtruncate(struct inode * inode, loff_t offset)
|
|
|
|
|
|
do_expand:
|
|
|
limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
|
|
|
- if (limit != RLIM_INFINITY && offset > limit)
|
|
|
+ if (limit != RLIM_INFINITY && offset > limit) {
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
goto out_sig;
|
|
|
- if (offset > inode->i_sb->s_maxbytes)
|
|
|
+ }
|
|
|
+ if (offset > inode->i_sb->s_maxbytes) {
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
goto out_big;
|
|
|
+ }
|
|
|
i_size_write(inode, offset);
|
|
|
-
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
out_truncate:
|
|
|
if (inode->i_op && inode->i_op->truncate)
|
|
|
inode->i_op->truncate(inode);
|