mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
gfs2: Remove ordered write mode handling from gfs2_trans_add_data
In journaled data mode, we need to add each buffer head to the current transaction. In ordered write mode, we only need to add the inode to the ordered inode list. So far, both cases are handled in gfs2_trans_add_data. This makes the code look misleading and is inefficient for small block sizes as well. Handle both cases separately instead. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
This commit is contained in:
parent
d6382a3505
commit
845802b112
@ -54,8 +54,7 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
|
|||||||
continue;
|
continue;
|
||||||
if (start >= to)
|
if (start >= to)
|
||||||
break;
|
break;
|
||||||
if (gfs2_is_jdata(ip))
|
set_buffer_uptodate(bh);
|
||||||
set_buffer_uptodate(bh);
|
|
||||||
gfs2_trans_add_data(ip->i_gl, bh);
|
gfs2_trans_add_data(ip->i_gl, bh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -894,8 +893,10 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
|
|||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gfs2_is_writeback(ip))
|
if (gfs2_is_jdata(ip))
|
||||||
gfs2_page_add_databufs(ip, page, pos & ~PAGE_MASK, len);
|
gfs2_page_add_databufs(ip, page, pos & ~PAGE_MASK, len);
|
||||||
|
else
|
||||||
|
gfs2_ordered_add_inode(ip);
|
||||||
|
|
||||||
ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
|
ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
|
||||||
page = NULL;
|
page = NULL;
|
||||||
|
@ -89,10 +89,12 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
|
|||||||
map_bh(bh, inode->i_sb, block);
|
map_bh(bh, inode->i_sb, block);
|
||||||
|
|
||||||
set_buffer_uptodate(bh);
|
set_buffer_uptodate(bh);
|
||||||
if (!gfs2_is_jdata(ip))
|
if (gfs2_is_jdata(ip))
|
||||||
mark_buffer_dirty(bh);
|
|
||||||
if (!gfs2_is_writeback(ip))
|
|
||||||
gfs2_trans_add_data(ip->i_gl, bh);
|
gfs2_trans_add_data(ip->i_gl, bh);
|
||||||
|
else {
|
||||||
|
mark_buffer_dirty(bh);
|
||||||
|
gfs2_ordered_add_inode(ip);
|
||||||
|
}
|
||||||
|
|
||||||
if (release) {
|
if (release) {
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
@ -1028,8 +1030,10 @@ static int gfs2_block_zero_range(struct inode *inode, loff_t from,
|
|||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gfs2_is_writeback(ip))
|
if (gfs2_is_jdata(ip))
|
||||||
gfs2_trans_add_data(ip->i_gl, bh);
|
gfs2_trans_add_data(ip->i_gl, bh);
|
||||||
|
else
|
||||||
|
gfs2_ordered_add_inode(ip);
|
||||||
|
|
||||||
zero_user(page, offset, length);
|
zero_user(page, offset, length);
|
||||||
mark_buffer_dirty(bh);
|
mark_buffer_dirty(bh);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include "incore.h"
|
#include "incore.h"
|
||||||
|
#include "inode.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gfs2_log_lock - acquire the right to mess with the log manager
|
* gfs2_log_lock - acquire the right to mess with the log manager
|
||||||
@ -50,8 +51,12 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp,
|
|||||||
|
|
||||||
static inline void gfs2_ordered_add_inode(struct gfs2_inode *ip)
|
static inline void gfs2_ordered_add_inode(struct gfs2_inode *ip)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
struct gfs2_sbd *sdp;
|
||||||
|
|
||||||
|
if (!gfs2_is_ordered(ip))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sdp = GFS2_SB(&ip->i_inode);
|
||||||
if (!test_bit(GIF_ORDERED, &ip->i_flags)) {
|
if (!test_bit(GIF_ORDERED, &ip->i_flags)) {
|
||||||
spin_lock(&sdp->sd_ordered_lock);
|
spin_lock(&sdp->sd_ordered_lock);
|
||||||
if (!test_and_set_bit(GIF_ORDERED, &ip->i_flags))
|
if (!test_and_set_bit(GIF_ORDERED, &ip->i_flags))
|
||||||
|
@ -735,7 +735,10 @@ static int gfs2_write_buf_to_page(struct gfs2_inode *ip, unsigned long index,
|
|||||||
if (!buffer_uptodate(bh))
|
if (!buffer_uptodate(bh))
|
||||||
goto unlock_out;
|
goto unlock_out;
|
||||||
}
|
}
|
||||||
gfs2_trans_add_data(ip->i_gl, bh);
|
if (gfs2_is_jdata(ip))
|
||||||
|
gfs2_trans_add_data(ip->i_gl, bh);
|
||||||
|
else
|
||||||
|
gfs2_ordered_add_inode(ip);
|
||||||
|
|
||||||
/* If we need to write to the next block as well */
|
/* If we need to write to the next block as well */
|
||||||
if (to_write > (bsize - boff)) {
|
if (to_write > (bsize - boff)) {
|
||||||
|
@ -143,32 +143,21 @@ static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl,
|
|||||||
* @gl: The inode glock associated with the buffer
|
* @gl: The inode glock associated with the buffer
|
||||||
* @bh: The buffer to add
|
* @bh: The buffer to add
|
||||||
*
|
*
|
||||||
* This is used in two distinct cases:
|
* This is used in journaled data mode.
|
||||||
* i) In ordered write mode
|
* We need to journal the data block in the same way as metadata in
|
||||||
* We put the data buffer on a list so that we can ensure that it's
|
* the functions above. The difference is that here we have a tag
|
||||||
* synced to disk at the right time
|
* which is two __be64's being the block number (as per meta data)
|
||||||
* ii) In journaled data mode
|
* and a flag which says whether the data block needs escaping or
|
||||||
* We need to journal the data block in the same way as metadata in
|
* not. This means we need a new log entry for each 251 or so data
|
||||||
* the functions above. The difference is that here we have a tag
|
* blocks, which isn't an enormous overhead but twice as much as
|
||||||
* which is two __be64's being the block number (as per meta data)
|
* for normal metadata blocks.
|
||||||
* and a flag which says whether the data block needs escaping or
|
|
||||||
* not. This means we need a new log entry for each 251 or so data
|
|
||||||
* blocks, which isn't an enormous overhead but twice as much as
|
|
||||||
* for normal metadata blocks.
|
|
||||||
*/
|
*/
|
||||||
void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh)
|
void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh)
|
||||||
{
|
{
|
||||||
struct gfs2_trans *tr = current->journal_info;
|
struct gfs2_trans *tr = current->journal_info;
|
||||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||||
struct address_space *mapping = bh->b_page->mapping;
|
|
||||||
struct gfs2_inode *ip = GFS2_I(mapping->host);
|
|
||||||
struct gfs2_bufdata *bd;
|
struct gfs2_bufdata *bd;
|
||||||
|
|
||||||
if (!gfs2_is_jdata(ip)) {
|
|
||||||
gfs2_ordered_add_inode(ip);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_buffer(bh);
|
lock_buffer(bh);
|
||||||
if (buffer_pinned(bh)) {
|
if (buffer_pinned(bh)) {
|
||||||
set_bit(TR_TOUCHED, &tr->tr_flags);
|
set_bit(TR_TOUCHED, &tr->tr_flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user