aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/aops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/aops.c')
-rw-r--r--fs/gfs2/aops.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 0c1d0b82dcf1..194fe16d8418 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -136,10 +136,7 @@ static int gfs2_writeback_writepage(struct page *page,
136 if (ret <= 0) 136 if (ret <= 0)
137 return ret; 137 return ret;
138 138
139 ret = mpage_writepage(page, gfs2_get_block_noalloc, wbc); 139 return nobh_writepage(page, gfs2_get_block_noalloc, wbc);
140 if (ret == -EAGAIN)
141 ret = block_write_full_page(page, gfs2_get_block_noalloc, wbc);
142 return ret;
143} 140}
144 141
145/** 142/**
@@ -418,6 +415,7 @@ static int gfs2_jdata_writepages(struct address_space *mapping,
418static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) 415static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
419{ 416{
420 struct buffer_head *dibh; 417 struct buffer_head *dibh;
418 u64 dsize = i_size_read(&ip->i_inode);
421 void *kaddr; 419 void *kaddr;
422 int error; 420 int error;
423 421
@@ -437,9 +435,10 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
437 return error; 435 return error;
438 436
439 kaddr = kmap_atomic(page, KM_USER0); 437 kaddr = kmap_atomic(page, KM_USER0);
440 memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), 438 if (dsize > (dibh->b_size - sizeof(struct gfs2_dinode)))
441 ip->i_disksize); 439 dsize = (dibh->b_size - sizeof(struct gfs2_dinode));
442 memset(kaddr + ip->i_disksize, 0, PAGE_CACHE_SIZE - ip->i_disksize); 440 memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
441 memset(kaddr + dsize, 0, PAGE_CACHE_SIZE - dsize);
443 kunmap_atomic(kaddr, KM_USER0); 442 kunmap_atomic(kaddr, KM_USER0);
444 flush_dcache_page(page); 443 flush_dcache_page(page);
445 brelse(dibh); 444 brelse(dibh);
@@ -635,9 +634,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
635 } 634 }
636 } 635 }
637 636
638 error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); 637 alloc_required = gfs2_write_alloc_required(ip, pos, len);
639 if (error)
640 goto out_unlock;
641 638
642 if (alloc_required || gfs2_is_jdata(ip)) 639 if (alloc_required || gfs2_is_jdata(ip))
643 gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); 640 gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
@@ -698,8 +695,14 @@ out:
698 return 0; 695 return 0;
699 696
700 page_cache_release(page); 697 page_cache_release(page);
698
699 /*
700 * XXX(truncate): the call below should probably be replaced with
701 * a call to the gfs2-specific truncate blocks helper to actually
702 * release disk blocks..
703 */
701 if (pos + len > ip->i_inode.i_size) 704 if (pos + len > ip->i_inode.i_size)
702 vmtruncate(&ip->i_inode, ip->i_inode.i_size); 705 truncate_setsize(&ip->i_inode, ip->i_inode.i_size);
703out_endtrans: 706out_endtrans:
704 gfs2_trans_end(sdp); 707 gfs2_trans_end(sdp);
705out_trans_fail: 708out_trans_fail:
@@ -1039,9 +1042,9 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
1039 if (rv != 1) 1042 if (rv != 1)
1040 goto out; /* dio not valid, fall back to buffered i/o */ 1043 goto out; /* dio not valid, fall back to buffered i/o */
1041 1044
1042 rv = blockdev_direct_IO_no_locking(rw, iocb, inode, inode->i_sb->s_bdev, 1045 rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
1043 iov, offset, nr_segs, 1046 offset, nr_segs, gfs2_get_block_direct,
1044 gfs2_get_block_direct, NULL); 1047 NULL, NULL, 0);
1045out: 1048out:
1046 gfs2_glock_dq_m(1, &gh); 1049 gfs2_glock_dq_m(1, &gh);
1047 gfs2_holder_uninit(&gh); 1050 gfs2_holder_uninit(&gh);