aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/inode.c4
-rw-r--r--fs/gfs2/inode.h6
-rw-r--r--fs/gfs2/ops_address.c78
-rw-r--r--fs/gfs2/ops_address.h2
-rw-r--r--fs/gfs2/ops_file.c13
5 files changed, 72 insertions, 31 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index af493fc6c8ce..532784eb5ba4 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -136,7 +136,6 @@ void gfs2_set_iop(struct inode *inode)
136 if (S_ISREG(mode)) { 136 if (S_ISREG(mode)) {
137 inode->i_op = &gfs2_file_iops; 137 inode->i_op = &gfs2_file_iops;
138 inode->i_fop = &gfs2_file_fops; 138 inode->i_fop = &gfs2_file_fops;
139 inode->i_mapping->a_ops = &gfs2_file_aops;
140 } else if (S_ISDIR(mode)) { 139 } else if (S_ISDIR(mode)) {
141 inode->i_op = &gfs2_dir_iops; 140 inode->i_op = &gfs2_dir_iops;
142 inode->i_fop = &gfs2_dir_fops; 141 inode->i_fop = &gfs2_dir_fops;
@@ -290,6 +289,9 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
290 di->di_entries = be32_to_cpu(str->di_entries); 289 di->di_entries = be32_to_cpu(str->di_entries);
291 290
292 di->di_eattr = be64_to_cpu(str->di_eattr); 291 di->di_eattr = be64_to_cpu(str->di_eattr);
292 if (S_ISREG(ip->i_inode.i_mode))
293 gfs2_set_aops(&ip->i_inode);
294
293 return 0; 295 return 0;
294} 296}
295 297
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index bed3dc212a18..d44650662615 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -26,6 +26,12 @@ static inline int gfs2_is_writeback(const struct gfs2_inode *ip)
26 return (sdp->sd_args.ar_data == GFS2_DATA_WRITEBACK) && !gfs2_is_jdata(ip); 26 return (sdp->sd_args.ar_data == GFS2_DATA_WRITEBACK) && !gfs2_is_jdata(ip);
27} 27}
28 28
29static inline int gfs2_is_ordered(const struct gfs2_inode *ip)
30{
31 const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
32 return (sdp->sd_args.ar_data == GFS2_DATA_ORDERED) && !gfs2_is_jdata(ip);
33}
34
29static inline int gfs2_is_dir(const struct gfs2_inode *ip) 35static inline int gfs2_is_dir(const struct gfs2_inode *ip)
30{ 36{
31 return S_ISDIR(ip->i_inode.i_mode); 37 return S_ISDIR(ip->i_inode.i_mode);
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index ed154af86171..207014f363d8 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -162,28 +162,18 @@ out_ignore:
162} 162}
163 163
164/** 164/**
165 * gfs2_writepages - Write a bunch of dirty pages back to disk 165 * gfs2_writeback_writepages - Write a bunch of dirty pages back to disk
166 * @mapping: The mapping to write 166 * @mapping: The mapping to write
167 * @wbc: Write-back control 167 * @wbc: Write-back control
168 * 168 *
169 * For journaled files and/or ordered writes this just falls back to the 169 * For the data=writeback case we can already ignore buffer heads
170 * kernel's default writepages path for now. We will probably want to change
171 * that eventually (i.e. when we look at allocate on flush).
172 *
173 * For the data=writeback case though we can already ignore buffer heads
174 * and write whole extents at once. This is a big reduction in the 170 * and write whole extents at once. This is a big reduction in the
175 * number of I/O requests we send and the bmap calls we make in this case. 171 * number of I/O requests we send and the bmap calls we make in this case.
176 */ 172 */
177static int gfs2_writepages(struct address_space *mapping, 173static int gfs2_writeback_writepages(struct address_space *mapping,
178 struct writeback_control *wbc) 174 struct writeback_control *wbc)
179{ 175{
180 struct inode *inode = mapping->host; 176 return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc);
181 struct gfs2_inode *ip = GFS2_I(inode);
182
183 if (gfs2_is_writeback(ip))
184 return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc);
185
186 return generic_writepages(mapping, wbc);
187} 177}
188 178
189/** 179/**
@@ -644,11 +634,7 @@ failed:
644 634
645static int gfs2_set_page_dirty(struct page *page) 635static int gfs2_set_page_dirty(struct page *page)
646{ 636{
647 struct gfs2_inode *ip = GFS2_I(page->mapping->host); 637 SetPageChecked(page);
648 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
649
650 if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
651 SetPageChecked(page);
652 return __set_page_dirty_buffers(page); 638 return __set_page_dirty_buffers(page);
653} 639}
654 640
@@ -738,13 +724,9 @@ static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset)
738{ 724{
739 /* 725 /*
740 * Should we return an error here? I can't see that O_DIRECT for 726 * Should we return an error here? I can't see that O_DIRECT for
741 * a journaled file makes any sense. For now we'll silently fall 727 * a stuffed file makes any sense. For now we'll silently fall
742 * back to buffered I/O, likewise we do the same for stuffed 728 * back to buffered I/O
743 * files since they are (a) small and (b) unaligned.
744 */ 729 */
745 if (gfs2_is_jdata(ip))
746 return 0;
747
748 if (gfs2_is_stuffed(ip)) 730 if (gfs2_is_stuffed(ip))
749 return 0; 731 return 0;
750 732
@@ -855,9 +837,22 @@ cannot_release:
855 return 0; 837 return 0;
856} 838}
857 839
858const struct address_space_operations gfs2_file_aops = { 840static const struct address_space_operations gfs2_writeback_aops = {
841 .writepage = gfs2_writepage,
842 .writepages = gfs2_writeback_writepages,
843 .readpage = gfs2_readpage,
844 .readpages = gfs2_readpages,
845 .sync_page = block_sync_page,
846 .write_begin = gfs2_write_begin,
847 .write_end = gfs2_write_end,
848 .bmap = gfs2_bmap,
849 .invalidatepage = gfs2_invalidatepage,
850 .releasepage = gfs2_releasepage,
851 .direct_IO = gfs2_direct_IO,
852};
853
854static const struct address_space_operations gfs2_ordered_aops = {
859 .writepage = gfs2_writepage, 855 .writepage = gfs2_writepage,
860 .writepages = gfs2_writepages,
861 .readpage = gfs2_readpage, 856 .readpage = gfs2_readpage,
862 .readpages = gfs2_readpages, 857 .readpages = gfs2_readpages,
863 .sync_page = block_sync_page, 858 .sync_page = block_sync_page,
@@ -870,3 +865,30 @@ const struct address_space_operations gfs2_file_aops = {
870 .direct_IO = gfs2_direct_IO, 865 .direct_IO = gfs2_direct_IO,
871}; 866};
872 867
868static const struct address_space_operations gfs2_jdata_aops = {
869 .writepage = gfs2_writepage,
870 .readpage = gfs2_readpage,
871 .readpages = gfs2_readpages,
872 .sync_page = block_sync_page,
873 .write_begin = gfs2_write_begin,
874 .write_end = gfs2_write_end,
875 .set_page_dirty = gfs2_set_page_dirty,
876 .bmap = gfs2_bmap,
877 .invalidatepage = gfs2_invalidatepage,
878 .releasepage = gfs2_releasepage,
879};
880
881void gfs2_set_aops(struct inode *inode)
882{
883 struct gfs2_inode *ip = GFS2_I(inode);
884
885 if (gfs2_is_writeback(ip))
886 inode->i_mapping->a_ops = &gfs2_writeback_aops;
887 else if (gfs2_is_ordered(ip))
888 inode->i_mapping->a_ops = &gfs2_ordered_aops;
889 else if (gfs2_is_jdata(ip))
890 inode->i_mapping->a_ops = &gfs2_jdata_aops;
891 else
892 BUG();
893}
894
diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h
index e8fe83fcd583..d3b76d0cdc81 100644
--- a/fs/gfs2/ops_address.h
+++ b/fs/gfs2/ops_address.h
@@ -14,12 +14,12 @@
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16 16
17extern const struct address_space_operations gfs2_file_aops;
18extern int gfs2_get_block(struct inode *inode, sector_t lblock, 17extern int gfs2_get_block(struct inode *inode, sector_t lblock,
19 struct buffer_head *bh_result, int create); 18 struct buffer_head *bh_result, int create);
20extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); 19extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask);
21extern int gfs2_internal_read(struct gfs2_inode *ip, 20extern int gfs2_internal_read(struct gfs2_inode *ip,
22 struct file_ra_state *ra_state, 21 struct file_ra_state *ra_state,
23 char *buf, loff_t *pos, unsigned size); 22 char *buf, loff_t *pos, unsigned size);
23extern void gfs2_set_aops(struct inode *inode);
24 24
25#endif /* __OPS_ADDRESS_DOT_H__ */ 25#endif /* __OPS_ADDRESS_DOT_H__ */
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 6f3aeb059c61..ad5daaa6babc 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -38,6 +38,7 @@
38#include "trans.h" 38#include "trans.h"
39#include "util.h" 39#include "util.h"
40#include "eaops.h" 40#include "eaops.h"
41#include "ops_address.h"
41 42
42/** 43/**
43 * gfs2_llseek - seek to a location in a file 44 * gfs2_llseek - seek to a location in a file
@@ -245,7 +246,16 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
245 if (error) 246 if (error)
246 goto out; 247 goto out;
247 } 248 }
248 249 if ((flags ^ new_flags) & GFS2_DIF_JDATA) {
250 if (flags & GFS2_DIF_JDATA)
251 gfs2_log_flush(sdp, ip->i_gl);
252 error = filemap_fdatawrite(inode->i_mapping);
253 if (error)
254 goto out;
255 error = filemap_fdatawait(inode->i_mapping);
256 if (error)
257 goto out;
258 }
249 error = gfs2_trans_begin(sdp, RES_DINODE, 0); 259 error = gfs2_trans_begin(sdp, RES_DINODE, 0);
250 if (error) 260 if (error)
251 goto out; 261 goto out;
@@ -257,6 +267,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
257 gfs2_dinode_out(ip, bh->b_data); 267 gfs2_dinode_out(ip, bh->b_data);
258 brelse(bh); 268 brelse(bh);
259 gfs2_set_inode_flags(inode); 269 gfs2_set_inode_flags(inode);
270 gfs2_set_aops(inode);
260out_trans_end: 271out_trans_end:
261 gfs2_trans_end(sdp); 272 gfs2_trans_end(sdp);
262out: 273out: