Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 76018
b: refs/heads/master
c: 5561093
h: refs/heads/master
v: v3
  • Loading branch information
Steven Whitehouse committed Jan 25, 2008
1 parent e8fd4ec commit 42b5a89
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bf36a713169432643d4fc7eeb4e0ace96d791d26
refs/heads/master: 5561093e2cac9f7d2a77e39cc689b8d2b7f9b2bc
4 changes: 3 additions & 1 deletion trunk/fs/gfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ void gfs2_set_iop(struct inode *inode)
if (S_ISREG(mode)) {
inode->i_op = &gfs2_file_iops;
inode->i_fop = &gfs2_file_fops;
inode->i_mapping->a_ops = &gfs2_file_aops;
} else if (S_ISDIR(mode)) {
inode->i_op = &gfs2_dir_iops;
inode->i_fop = &gfs2_dir_fops;
Expand Down Expand Up @@ -290,6 +289,9 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
di->di_entries = be32_to_cpu(str->di_entries);

di->di_eattr = be64_to_cpu(str->di_eattr);
if (S_ISREG(ip->i_inode.i_mode))
gfs2_set_aops(&ip->i_inode);

return 0;
}

Expand Down
6 changes: 6 additions & 0 deletions trunk/fs/gfs2/inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ static inline int gfs2_is_writeback(const struct gfs2_inode *ip)
return (sdp->sd_args.ar_data == GFS2_DATA_WRITEBACK) && !gfs2_is_jdata(ip);
}

static inline int gfs2_is_ordered(const struct gfs2_inode *ip)
{
const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
return (sdp->sd_args.ar_data == GFS2_DATA_ORDERED) && !gfs2_is_jdata(ip);
}

static inline int gfs2_is_dir(const struct gfs2_inode *ip)
{
return S_ISDIR(ip->i_inode.i_mode);
Expand Down
78 changes: 50 additions & 28 deletions trunk/fs/gfs2/ops_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,28 +162,18 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
}

/**
* gfs2_writepages - Write a bunch of dirty pages back to disk
* gfs2_writeback_writepages - Write a bunch of dirty pages back to disk
* @mapping: The mapping to write
* @wbc: Write-back control
*
* For journaled files and/or ordered writes this just falls back to the
* kernel's default writepages path for now. We will probably want to change
* that eventually (i.e. when we look at allocate on flush).
*
* For the data=writeback case though we can already ignore buffer heads
* For the data=writeback case we can already ignore buffer heads
* and write whole extents at once. This is a big reduction in the
* number of I/O requests we send and the bmap calls we make in this case.
*/
static int gfs2_writepages(struct address_space *mapping,
struct writeback_control *wbc)
static int gfs2_writeback_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
struct inode *inode = mapping->host;
struct gfs2_inode *ip = GFS2_I(inode);

if (gfs2_is_writeback(ip))
return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc);

return generic_writepages(mapping, wbc);
return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc);
}

/**
Expand Down Expand Up @@ -644,11 +634,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,

static int gfs2_set_page_dirty(struct page *page)
{
struct gfs2_inode *ip = GFS2_I(page->mapping->host);
struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);

if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
SetPageChecked(page);
SetPageChecked(page);
return __set_page_dirty_buffers(page);
}

Expand Down Expand Up @@ -738,13 +724,9 @@ static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset)
{
/*
* Should we return an error here? I can't see that O_DIRECT for
* a journaled file makes any sense. For now we'll silently fall
* back to buffered I/O, likewise we do the same for stuffed
* files since they are (a) small and (b) unaligned.
* a stuffed file makes any sense. For now we'll silently fall
* back to buffered I/O
*/
if (gfs2_is_jdata(ip))
return 0;

if (gfs2_is_stuffed(ip))
return 0;

Expand Down Expand Up @@ -855,9 +837,22 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
return 0;
}

const struct address_space_operations gfs2_file_aops = {
static const struct address_space_operations gfs2_writeback_aops = {
.writepage = gfs2_writepage,
.writepages = gfs2_writeback_writepages,
.readpage = gfs2_readpage,
.readpages = gfs2_readpages,
.sync_page = block_sync_page,
.write_begin = gfs2_write_begin,
.write_end = gfs2_write_end,
.bmap = gfs2_bmap,
.invalidatepage = gfs2_invalidatepage,
.releasepage = gfs2_releasepage,
.direct_IO = gfs2_direct_IO,
};

static const struct address_space_operations gfs2_ordered_aops = {
.writepage = gfs2_writepage,
.writepages = gfs2_writepages,
.readpage = gfs2_readpage,
.readpages = gfs2_readpages,
.sync_page = block_sync_page,
Expand All @@ -870,3 +865,30 @@ const struct address_space_operations gfs2_file_aops = {
.direct_IO = gfs2_direct_IO,
};

static const struct address_space_operations gfs2_jdata_aops = {
.writepage = gfs2_writepage,
.readpage = gfs2_readpage,
.readpages = gfs2_readpages,
.sync_page = block_sync_page,
.write_begin = gfs2_write_begin,
.write_end = gfs2_write_end,
.set_page_dirty = gfs2_set_page_dirty,
.bmap = gfs2_bmap,
.invalidatepage = gfs2_invalidatepage,
.releasepage = gfs2_releasepage,
};

void gfs2_set_aops(struct inode *inode)
{
struct gfs2_inode *ip = GFS2_I(inode);

if (gfs2_is_writeback(ip))
inode->i_mapping->a_ops = &gfs2_writeback_aops;
else if (gfs2_is_ordered(ip))
inode->i_mapping->a_ops = &gfs2_ordered_aops;
else if (gfs2_is_jdata(ip))
inode->i_mapping->a_ops = &gfs2_jdata_aops;
else
BUG();
}

2 changes: 1 addition & 1 deletion trunk/fs/gfs2/ops_address.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
#include <linux/buffer_head.h>
#include <linux/mm.h>

extern const struct address_space_operations gfs2_file_aops;
extern int gfs2_get_block(struct inode *inode, sector_t lblock,
struct buffer_head *bh_result, int create);
extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask);
extern int gfs2_internal_read(struct gfs2_inode *ip,
struct file_ra_state *ra_state,
char *buf, loff_t *pos, unsigned size);
extern void gfs2_set_aops(struct inode *inode);

#endif /* __OPS_ADDRESS_DOT_H__ */
13 changes: 12 additions & 1 deletion trunk/fs/gfs2/ops_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "trans.h"
#include "util.h"
#include "eaops.h"
#include "ops_address.h"

/**
* gfs2_llseek - seek to a location in a file
Expand Down Expand Up @@ -245,7 +246,16 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
if (error)
goto out;
}

if ((flags ^ new_flags) & GFS2_DIF_JDATA) {
if (flags & GFS2_DIF_JDATA)
gfs2_log_flush(sdp, ip->i_gl);
error = filemap_fdatawrite(inode->i_mapping);
if (error)
goto out;
error = filemap_fdatawait(inode->i_mapping);
if (error)
goto out;
}
error = gfs2_trans_begin(sdp, RES_DINODE, 0);
if (error)
goto out;
Expand All @@ -257,6 +267,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
gfs2_dinode_out(ip, bh->b_data);
brelse(bh);
gfs2_set_inode_flags(inode);
gfs2_set_aops(inode);
out_trans_end:
gfs2_trans_end(sdp);
out:
Expand Down

0 comments on commit 42b5a89

Please sign in to comment.