|
@@ -843,14 +843,14 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
|
|
list_add_tail(&info->swaplist, &shmem_swaplist);
|
|
list_add_tail(&info->swaplist, &shmem_swaplist);
|
|
|
|
|
|
if (add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) {
|
|
if (add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) {
|
|
- swap_shmem_alloc(swap);
|
|
|
|
- shmem_delete_from_page_cache(page, swp_to_radix_entry(swap));
|
|
|
|
-
|
|
|
|
spin_lock(&info->lock);
|
|
spin_lock(&info->lock);
|
|
- info->swapped++;
|
|
|
|
shmem_recalc_inode(inode);
|
|
shmem_recalc_inode(inode);
|
|
|
|
+ info->swapped++;
|
|
spin_unlock(&info->lock);
|
|
spin_unlock(&info->lock);
|
|
|
|
|
|
|
|
+ swap_shmem_alloc(swap);
|
|
|
|
+ shmem_delete_from_page_cache(page, swp_to_radix_entry(swap));
|
|
|
|
+
|
|
mutex_unlock(&shmem_swaplist_mutex);
|
|
mutex_unlock(&shmem_swaplist_mutex);
|
|
BUG_ON(page_mapped(page));
|
|
BUG_ON(page_mapped(page));
|
|
swap_writepage(page, wbc);
|
|
swap_writepage(page, wbc);
|
|
@@ -1078,7 +1078,7 @@ repeat:
|
|
if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
|
|
if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
|
|
((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
|
|
((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
|
|
error = -EINVAL;
|
|
error = -EINVAL;
|
|
- goto failed;
|
|
|
|
|
|
+ goto unlock;
|
|
}
|
|
}
|
|
|
|
|
|
if (page && sgp == SGP_WRITE)
|
|
if (page && sgp == SGP_WRITE)
|
|
@@ -1246,11 +1246,15 @@ clear:
|
|
/* Perhaps the file has been truncated since we checked */
|
|
/* Perhaps the file has been truncated since we checked */
|
|
if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
|
|
if (sgp != SGP_WRITE && sgp != SGP_FALLOC &&
|
|
((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
|
|
((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) {
|
|
|
|
+ if (alloced) {
|
|
|
|
+ ClearPageDirty(page);
|
|
|
|
+ delete_from_page_cache(page);
|
|
|
|
+ spin_lock(&info->lock);
|
|
|
|
+ shmem_recalc_inode(inode);
|
|
|
|
+ spin_unlock(&info->lock);
|
|
|
|
+ }
|
|
error = -EINVAL;
|
|
error = -EINVAL;
|
|
- if (alloced)
|
|
|
|
- goto trunc;
|
|
|
|
- else
|
|
|
|
- goto failed;
|
|
|
|
|
|
+ goto unlock;
|
|
}
|
|
}
|
|
*pagep = page;
|
|
*pagep = page;
|
|
return 0;
|
|
return 0;
|
|
@@ -1258,23 +1262,13 @@ clear:
|
|
/*
|
|
/*
|
|
* Error recovery.
|
|
* Error recovery.
|
|
*/
|
|
*/
|
|
-trunc:
|
|
|
|
- info = SHMEM_I(inode);
|
|
|
|
- ClearPageDirty(page);
|
|
|
|
- delete_from_page_cache(page);
|
|
|
|
- spin_lock(&info->lock);
|
|
|
|
- info->alloced--;
|
|
|
|
- inode->i_blocks -= BLOCKS_PER_PAGE;
|
|
|
|
- spin_unlock(&info->lock);
|
|
|
|
decused:
|
|
decused:
|
|
- sbinfo = SHMEM_SB(inode->i_sb);
|
|
|
|
if (sbinfo->max_blocks)
|
|
if (sbinfo->max_blocks)
|
|
percpu_counter_add(&sbinfo->used_blocks, -1);
|
|
percpu_counter_add(&sbinfo->used_blocks, -1);
|
|
unacct:
|
|
unacct:
|
|
shmem_unacct_blocks(info->flags, 1);
|
|
shmem_unacct_blocks(info->flags, 1);
|
|
failed:
|
|
failed:
|
|
- if (swap.val && error != -EINVAL &&
|
|
|
|
- !shmem_confirm_swap(mapping, index, swap))
|
|
|
|
|
|
+ if (swap.val && !shmem_confirm_swap(mapping, index, swap))
|
|
error = -EEXIST;
|
|
error = -EEXIST;
|
|
unlock:
|
|
unlock:
|
|
if (page) {
|
|
if (page) {
|