Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw:
  GFS2: print glock numbers in hex
  GFS2: ordered writes are backwards
  GFS2: Remove old, unused linked list code from quota
  GFS2: Remove loopy umount code
  GFS2: Metadata address space clean up
  • Loading branch information
Linus Torvalds committed Mar 3, 2010
2 parents 3ff1562 + 4818972 commit 4850f52
Show file tree
Hide file tree
Showing 17 changed files with 109 additions and 164 deletions.
4 changes: 2 additions & 2 deletions fs/gfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,8 +1061,8 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,

int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
{
struct inode *aspace = page->mapping->host;
struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info;
struct address_space *mapping = page->mapping;
struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping);
struct buffer_head *bh, *head;
struct gfs2_bufdata *bd;

Expand Down
75 changes: 24 additions & 51 deletions fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/module.h>
#include <linux/rwsem.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
Expand Down Expand Up @@ -60,7 +59,6 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl);
#define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { __dump_glock(NULL, gl); BUG(); } } while(0)
static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target);

static DECLARE_RWSEM(gfs2_umount_flush_sem);
static struct dentry *gfs2_root;
static struct workqueue_struct *glock_workqueue;
struct workqueue_struct *gfs2_delete_workqueue;
Expand Down Expand Up @@ -154,12 +152,14 @@ 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;
struct address_space *mapping = gfs2_glock2aspace(gl);
struct kmem_cache *cachep = gfs2_glock_cachep;

if (aspace)
gfs2_aspace_put(aspace);
GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
trace_gfs2_glock_put(gl);
sdp->sd_lockstruct.ls_ops->lm_put_lock(gfs2_glock_cachep, gl);
if (mapping)
cachep = gfs2_glock_aspace_cachep;
sdp->sd_lockstruct.ls_ops->lm_put_lock(cachep, gl);
}

/**
Expand Down Expand Up @@ -712,7 +712,6 @@ static void glock_work_func(struct work_struct *work)
finish_xmote(gl, gl->gl_reply);
drop_ref = 1;
}
down_read(&gfs2_umount_flush_sem);
spin_lock(&gl->gl_spin);
if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
gl->gl_state != LM_ST_UNLOCKED &&
Expand All @@ -725,7 +724,6 @@ static void glock_work_func(struct work_struct *work)
}
run_queue(gl, 0);
spin_unlock(&gl->gl_spin);
up_read(&gfs2_umount_flush_sem);
if (!delay ||
queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
gfs2_glock_put(gl);
Expand All @@ -750,10 +748,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
const struct gfs2_glock_operations *glops, int create,
struct gfs2_glock **glp)
{
struct super_block *s = sdp->sd_vfs;
struct lm_lockname name = { .ln_number = number, .ln_type = glops->go_type };
struct gfs2_glock *gl, *tmp;
unsigned int hash = gl_hash(sdp, &name);
int error;
struct address_space *mapping;

read_lock(gl_lock_addr(hash));
gl = search_bucket(hash, sdp, &name);
Expand All @@ -765,7 +764,10 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
if (!create)
return -ENOENT;

gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL);
if (glops->go_flags & GLOF_ASPACE)
gl = kmem_cache_alloc(gfs2_glock_aspace_cachep, GFP_KERNEL);
else
gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL);
if (!gl)
return -ENOMEM;

Expand All @@ -784,18 +786,18 @@ 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);
INIT_WORK(&gl->gl_delete, delete_work_func);

/* 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;
}
mapping = gfs2_glock2aspace(gl);
if (mapping) {
mapping->a_ops = &gfs2_meta_aops;
mapping->host = s->s_bdev->bd_inode;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_NOFS);
mapping->assoc_mapping = NULL;
mapping->backing_dev_info = s->s_bdi;
mapping->writeback_index = 0;
}

write_lock(gl_lock_addr(hash));
Expand All @@ -812,10 +814,6 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
*glp = gl;

return 0;

fail:
kmem_cache_free(gfs2_glock_cachep, gl);
return error;
}

/**
Expand Down Expand Up @@ -1510,35 +1508,10 @@ void gfs2_glock_thaw(struct gfs2_sbd *sdp)

void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
{
unsigned long t;
unsigned int x;
int cont;

t = jiffies;

for (;;) {
cont = 0;
for (x = 0; x < GFS2_GL_HASH_SIZE; x++) {
if (examine_bucket(clear_glock, sdp, x))
cont = 1;
}

if (!cont)
break;

if (time_after_eq(jiffies,
t + gfs2_tune_get(sdp, gt_stall_secs) * HZ)) {
fs_warn(sdp, "Unmount seems to be stalled. "
"Dumping lock state...\n");
gfs2_dump_lockstate(sdp);
t = jiffies;
}

down_write(&gfs2_umount_flush_sem);
invalidate_inodes(sdp->sd_vfs);
up_write(&gfs2_umount_flush_sem);
msleep(10);
}
for (x = 0; x < GFS2_GL_HASH_SIZE; x++)
examine_bucket(clear_glock, sdp, x);
flush_workqueue(glock_workqueue);
wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0);
gfs2_dump_lockstate(sdp);
Expand Down Expand Up @@ -1685,7 +1658,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl)
dtime *= 1000000/HZ; /* demote time in uSec */
if (!test_bit(GLF_DEMOTE, &gl->gl_flags))
dtime = 0;
gfs2_print_dbg(seq, "G: s:%s n:%u/%llu f:%s t:%s d:%s/%llu a:%d r:%d\n",
gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d r:%d\n",
state2str(gl->gl_state),
gl->gl_name.ln_type,
(unsigned long long)gl->gl_name.ln_number,
Expand Down
7 changes: 7 additions & 0 deletions fs/gfs2/glock.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
return gl->gl_state == LM_ST_SHARED;
}

static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
{
if (gl->gl_ops->go_flags & GLOF_ASPACE)
return (struct address_space *)(gl + 1);
return NULL;
}

int gfs2_glock_get(struct gfs2_sbd *sdp,
u64 number, const struct gfs2_glock_operations *glops,
int create, struct gfs2_glock **glp);
Expand Down
16 changes: 9 additions & 7 deletions fs/gfs2/glops.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)

static void rgrp_go_sync(struct gfs2_glock *gl)
{
struct address_space *metamapping = gl->gl_aspace->i_mapping;
struct address_space *metamapping = gfs2_glock2aspace(gl);
int error;

if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
Expand All @@ -113,7 +113,7 @@ static void rgrp_go_sync(struct gfs2_glock *gl)

static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
{
struct address_space *mapping = gl->gl_aspace->i_mapping;
struct address_space *mapping = gfs2_glock2aspace(gl);

BUG_ON(!(flags & DIO_METADATA));
gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));
Expand All @@ -134,7 +134,7 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
static void inode_go_sync(struct gfs2_glock *gl)
{
struct gfs2_inode *ip = gl->gl_object;
struct address_space *metamapping = gl->gl_aspace->i_mapping;
struct address_space *metamapping = gfs2_glock2aspace(gl);
int error;

if (ip && !S_ISREG(ip->i_inode.i_mode))
Expand Down Expand Up @@ -183,7 +183,7 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));

if (flags & DIO_METADATA) {
struct address_space *mapping = gl->gl_aspace->i_mapping;
struct address_space *mapping = gfs2_glock2aspace(gl);
truncate_inode_pages(mapping, 0);
if (ip) {
set_bit(GIF_INVALID, &ip->i_flags);
Expand Down Expand Up @@ -282,7 +282,8 @@ static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl)

static int rgrp_go_demote_ok(const struct gfs2_glock *gl)
{
return !gl->gl_aspace->i_mapping->nrpages;
const struct address_space *mapping = (const struct address_space *)(gl + 1);
return !mapping->nrpages;
}

/**
Expand Down Expand Up @@ -387,8 +388,7 @@ static void iopen_go_callback(struct gfs2_glock *gl)
struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;

if (gl->gl_demote_state == LM_ST_UNLOCKED &&
gl->gl_state == LM_ST_SHARED &&
ip && test_bit(GIF_USER, &ip->i_flags)) {
gl->gl_state == LM_ST_SHARED && ip) {
gfs2_glock_hold(gl);
if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
gfs2_glock_put_nolock(gl);
Expand All @@ -407,6 +407,7 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
.go_dump = inode_go_dump,
.go_type = LM_TYPE_INODE,
.go_min_hold_time = HZ / 5,
.go_flags = GLOF_ASPACE,
};

const struct gfs2_glock_operations gfs2_rgrp_glops = {
Expand All @@ -418,6 +419,7 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = {
.go_dump = gfs2_rgrp_dump,
.go_type = LM_TYPE_RGRP,
.go_min_hold_time = HZ / 5,
.go_flags = GLOF_ASPACE,
};

const struct gfs2_glock_operations gfs2_trans_glops = {
Expand Down
5 changes: 2 additions & 3 deletions fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ struct gfs2_glock_operations {
void (*go_callback) (struct gfs2_glock *gl);
const int go_type;
const unsigned long go_min_hold_time;
const unsigned long go_flags;
#define GLOF_ASPACE 1
};

enum {
Expand Down Expand Up @@ -225,7 +227,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;
Expand Down Expand Up @@ -258,7 +259,6 @@ enum {
GIF_INVALID = 0,
GIF_QD_LOCKED = 1,
GIF_SW_PAGED = 3,
GIF_USER = 4, /* user inode, not metadata addr space */
};


Expand Down Expand Up @@ -451,7 +451,6 @@ struct gfs2_tune {
unsigned int gt_quota_quantum; /* Secs between syncs to quota file */
unsigned int gt_new_files_jdata;
unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */
unsigned int gt_stall_secs; /* Detects trouble! */
unsigned int gt_complain_secs;
unsigned int gt_statfs_quantum;
unsigned int gt_statfs_slow;
Expand Down
6 changes: 2 additions & 4 deletions fs/gfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static int iget_test(struct inode *inode, void *opaque)
struct gfs2_inode *ip = GFS2_I(inode);
u64 *no_addr = opaque;

if (ip->i_no_addr == *no_addr && test_bit(GIF_USER, &ip->i_flags))
if (ip->i_no_addr == *no_addr)
return 1;

return 0;
Expand All @@ -58,7 +58,6 @@ static int iget_set(struct inode *inode, void *opaque)

inode->i_ino = (unsigned long)*no_addr;
ip->i_no_addr = *no_addr;
set_bit(GIF_USER, &ip->i_flags);
return 0;
}

Expand All @@ -84,7 +83,7 @@ static int iget_skip_test(struct inode *inode, void *opaque)
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_skip_data *data = opaque;

if (ip->i_no_addr == data->no_addr && test_bit(GIF_USER, &ip->i_flags)){
if (ip->i_no_addr == data->no_addr) {
if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){
data->skipped = 1;
return 0;
Expand All @@ -103,7 +102,6 @@ static int iget_skip_set(struct inode *inode, void *opaque)
return 1;
inode->i_ino = (unsigned long)(data->no_addr);
ip->i_no_addr = data->no_addr;
set_bit(GIF_USER, &ip->i_flags);
return 0;
}

Expand Down
5 changes: 4 additions & 1 deletion fs/gfs2/lock_dlm.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ static void gdlm_ast(void *arg)

switch (gl->gl_lksb.sb_status) {
case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */
kmem_cache_free(gfs2_glock_cachep, gl);
if (gl->gl_ops->go_flags & GLOF_ASPACE)
kmem_cache_free(gfs2_glock_aspace_cachep, gl);
else
kmem_cache_free(gfs2_glock_cachep, gl);
if (atomic_dec_and_test(&sdp->sd_glock_disposal))
wake_up(&sdp->sd_glock_wait);
return;
Expand Down
4 changes: 2 additions & 2 deletions fs/gfs2/lops.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,9 +528,9 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
gfs2_pin(sdp, bd->bd_bh);
tr->tr_num_databuf_new++;
sdp->sd_log_num_databuf++;
list_add(&le->le_list, &sdp->sd_log_le_databuf);
list_add_tail(&le->le_list, &sdp->sd_log_le_databuf);
} else {
list_add(&le->le_list, &sdp->sd_log_le_ordered);
list_add_tail(&le->le_list, &sdp->sd_log_le_ordered);
}
out:
gfs2_log_unlock(sdp);
Expand Down
Loading

0 comments on commit 4850f52

Please sign in to comment.