FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 12-12-2007, 03:39 PM
Steven Whitehouse
 
Default Reduce meta inodes to one per fs

>From f030a5ef7df90484a41fa68609f7f2ad1849a47b Mon Sep 17 00:00:00 2001
From: Steven Whitehouse <swhiteho@redhat.com>
Date: Wed, 12 Dec 2007 16:01:09 +0000
Subject: [PATCH] [GFS2] Reduce meta inodes to one per fs

Now that the previous patches have laid the groundwork, this
patch is the one which actually reduces the meta inodes to
a single one per filesystem.

As a result we save:
- The space of one gfs2_inode per "real" inode (about 1800 bytes on x86_64,
just over 1k on x86)
- Whenever we have block size < page size and lots of metadata we save on
wasted space in the page cache

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 52c8a09..d18f00c 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -181,13 +181,9 @@ static unsigned int gl_hash(const struct gfs2_sbd *sdp,
static void glock_free(struct gfs2_glock *gl)
{
struct gfs2_sbd *sdp = gl->gl_sbd;
- struct inode *aspace = gl->gl_aspace;

gfs2_lm_put_lock(sdp, gl->gl_lock);

- if (aspace)
- gfs2_aspace_put(aspace);
-
kmem_cache_free(gfs2_glock_cachep, gl);
}

@@ -344,23 +340,12 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
gl->gl_tchange = jiffies;
gl->gl_object = NULL;
gl->gl_sbd = sdp;
- gl->gl_aspace = NULL;
INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
gl->gl_start = gl->gl_end = number;

- /* If this glock protects actual on-disk data or metadata blocks,
- create a VFS inode to manage the pages/buffers holding them. */
- if (glops == &gfs2_inode_glops || glops == &gfs2_rgrp_glops) {
- gl->gl_aspace = gfs2_aspace_get(sdp);
- if (!gl->gl_aspace) {
- error = -ENOMEM;
- goto fail;
- }
- }
-
error = gfs2_lm_get_lock(sdp, &name, &gl->gl_lock);
if (error)
- goto fail_aspace;
+ goto fail;

write_lock(gl_lock_addr(hash));
tmp = search_bucket(hash, sdp, &name);
@@ -377,9 +362,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,

return 0;

-fail_aspace:
- if (gl->gl_aspace)
- gfs2_aspace_put(gl->gl_aspace);
fail:
kmem_cache_free(gfs2_glock_cachep, gl);
return error;
@@ -1894,11 +1876,6 @@ static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
print_dbg(gi, " object = %s
", (gl->gl_object) ? "yes" : "no");
print_dbg(gi, " reclaim = %s
",
(list_empty(&gl->gl_reclaim)) ? "no" : "yes");
- if (gl->gl_aspace)
- print_dbg(gi, " aspace = 0x%p nrpages = %lu
", gl->gl_aspace,
- gl->gl_aspace->i_mapping->nrpages);
- else
- print_dbg(gi, " aspace = no
");
print_dbg(gi, " ail = %d
", atomic_read(&gl->gl_ail_count));
if (gl->gl_req_gh) {
error = dump_holder(gi, "Request", gl->gl_req_gh);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 26640c1..98abc83 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -91,8 +91,8 @@ static int gfs2_wait_on_meta_pages(struct buffer_head *bh)
static void gfs2_foreach_page(struct gfs2_glock *gl,
int (*fxn)(struct buffer_head *bh))
{
- struct address_space *mapping = gl->gl_aspace->i_mapping;
struct gfs2_sbd *sdp = gl->gl_sbd;
+ struct address_space *mapping = sdp->sd_meta->i_mapping;
unsigned shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift;
pgoff_t start = (pgoff_t)(gl->gl_start >> shift);
pgoff_t end = (pgoff_t)(gl->gl_end >> shift);
@@ -157,8 +157,8 @@ do_writepage:

static int gfs2_meta_sync(struct gfs2_glock *gl)
{
- struct address_space *mapping = gl->gl_aspace->i_mapping;
struct gfs2_sbd *sdp = gl->gl_sbd;
+ struct address_space *mapping = sdp->sd_meta->i_mapping;
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = LONG_MAX,
@@ -183,8 +183,7 @@ static int gfs2_meta_sync(struct gfs2_glock *gl)
static void meta_go_sync(struct gfs2_glock *gl)
{
gfs2_log_flush(gl->gl_sbd, gl);
- if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
- gfs2_meta_sync(gl);
+ gfs2_meta_sync(gl);
gfs2_ail_empty_gl(gl);
}

@@ -215,12 +214,8 @@ static void inode_go_sync(struct gfs2_glock *gl)
if (ip && S_ISREG(ip->i_inode.i_mode)) {
struct inode *inode = &ip->i_inode;
struct address_space *mapping = inode->i_mapping;
- int mapped = mapping->i_mmap_writable;
unmap_shared_mapping_range(mapping, 0, 0);
- if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags) || mapped) {
- generic_osync_inode(inode, mapping,
- OSYNC_DATA|OSYNC_METADATA);
- }
+ generic_osync_inode(inode, mapping, OSYNC_DATA|OSYNC_METADATA);
} else {
gfs2_meta_sync(gl);
}
@@ -281,7 +276,7 @@ static int inode_go_demote_ok(struct gfs2_glock *gl)
struct gfs2_sbd *sdp = gl->gl_sbd;
int demote = 0;

- if (!gl->gl_object && !gl->gl_aspace->i_mapping->nrpages)
+ if (!gl->gl_object)
demote = 1;
else if (!sdp->sd_args.ar_localcaching &&
time_after_eq(jiffies, gl->gl_stamp +
@@ -331,7 +326,13 @@ static int inode_go_lock(struct gfs2_holder *gh)

static int rgrp_go_demote_ok(struct gfs2_glock *gl)
{
- return !gl->gl_aspace->i_mapping->nrpages;
+ struct gfs2_sbd *sdp = gl->gl_sbd;
+
+ if (!sdp->sd_args.ar_localcaching &&
+ time_after_eq(jiffies, gl->gl_stamp +
+ gfs2_tune_get(sdp, gt_demote_secs) * HZ))
+ return 1;
+ return 0;
}

/**
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index f478e8b..8ab0563 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -203,7 +203,6 @@ enum {
GLF_STICKY = 2,
GLF_DEMOTE = 3,
GLF_PENDING_DEMOTE = 4,
- GLF_DIRTY = 5,
GLF_DEMOTE_IN_PROGRESS = 6,
GLF_LFLUSH = 7,
};
@@ -245,7 +244,6 @@ struct gfs2_glock {

struct gfs2_sbd *gl_sbd;

- struct inode *gl_aspace;
struct list_head gl_ail_list;
atomic_t gl_ail_count;
struct delayed_work gl_work;
@@ -557,6 +555,7 @@ struct gfs2_sbd {
struct inode *sd_qc_inode;
struct inode *sd_rindex;
struct inode *sd_quota_inode;
+ struct inode *sd_meta;

/* Inum stuff */

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 58e51ef..86118eb 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -147,7 +147,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
if (!list_empty(&le->le_list))
goto out;
set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
- set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
gfs2_meta_check(sdp, bd->bd_bh);
gfs2_pin(sdp, bd->bd_bh);
sdp->sd_log_num_buf++;
@@ -527,7 +526,6 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
goto out;

set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
- set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
if (gfs2_is_jdata(ip)) {
gfs2_pin(sdp, bd->bd_bh);
tr->tr_num_databuf_new++;
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 1cf711f..1451a4b 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -98,8 +98,8 @@ void gfs2_aspace_put(struct inode *aspace)

static struct buffer_head *getbuf(struct gfs2_glock *gl, u64 blkno, int create)
{
- struct address_space *mapping = gl->gl_aspace->i_mapping;
struct gfs2_sbd *sdp = gl->gl_sbd;
+ struct address_space *mapping = sdp->sd_meta->i_mapping;
struct page *page;
struct buffer_head *bh;
unsigned int shift;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 35ec630..5558fdf 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -37,6 +37,7 @@
#include "sys.h"
#include "util.h"
#include "log.h"
+#include "meta_io.h"

#define DO 0
#define UNDO 1
@@ -247,6 +248,10 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
dput(sb->s_root);
sb->s_root = NULL;
}
+ if (sdp->sd_meta) {
+ iput(sdp->sd_meta);
+ sdp->sd_meta = NULL;
+ }
return 0;
}

@@ -280,6 +285,12 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
}
sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);

+ sdp->sd_meta = gfs2_aspace_get(sdp);
+ if (sdp->sd_meta == NULL) {
+ error = -ENOMEM;
+ goto out;
+ }
+
/* Get the root inode */
no_addr = sdp->sd_sb.sb_root_dir.no_addr;
if (sb->s_type == &gfs2meta_fs_type)
@@ -288,6 +299,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
if (IS_ERR(inode)) {
error = PTR_ERR(inode);
fs_err(sdp, "can't read in root inode: %d
", error);
+ iput(sdp->sd_meta);
goto out;
}

@@ -295,6 +307,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
if (!sb->s_root) {
fs_err(sdp, "can't get root dentry
");
error = -ENOMEM;
+ iput(sdp->sd_meta);
iput(inode);
} else
sb->s_root->d_op = &gfs2_dops;
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 5e52421..ade8c2e 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -108,6 +108,7 @@ static void gfs2_put_super(struct super_block *sb)
iput(sdp->sd_statfs_inode);
iput(sdp->sd_rindex);
iput(sdp->sd_quota_inode);
+ iput(sdp->sd_meta);

gfs2_glock_put(sdp->sd_rename_gl);
gfs2_glock_put(sdp->sd_trans_gl);
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index 2a4d414..b916679 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -147,7 +147,15 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta)

bd = bh_to_bufdata(bh);
if (bd) {
- BUG_ON(bd->bd_gl != gl);
+ if (unlikely(bd->bd_gl != gl)) {
+ BUG_ON(buffer_dirty(bh));
+ BUG_ON(!list_empty(&bd->bd_le.le_list));
+ gfs2_log_lock(sdp);
+ if (bd->bd_ail)
+ gfs2_remove_from_ail(bd);
+ bd->bd_gl = gl;
+ gfs2_log_unlock(sdp);
+ }
goto out;
}

--
1.5.1.2
 

Thread Tools




All times are GMT. The time now is 10:36 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org