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: Don't flush delete workqueue when releasing the transaction lock
  GFS2: fsck.gfs2 reported statfs error after gfs2_grow
  GFS2: Merge glock state fields into a bitfield
  GFS2: Fix uninitialised error value in previous patch
  GFS2: fix recursive locking during rindex truncates
  GFS2: reread rindex when necessary to grow rindex
  GFS2: Remove duplicate #defines from glock.h
  GFS2: Clean up of gdlm_lock function
  GFS2: Allow gfs2 to update quota usage values through the quotactl interface
  GFS2: fs/gfs2/glock.h: Add __attribute__((format(printf,2,3)) to gfs2_print_dbg
  GFS2: fs/gfs2/glock.c: Use printf extension %pV
  GFS2: Clean up duplicated setattr code
  GFS2: Remove unreachable calls to vmtruncate
  GFS2: fs/gfs2/glock.c: Convert sprintf_symbol to %pS
  GFS2: Change two WQ_RESCUERs into WQ_MEM_RECLAIM
  • Loading branch information
Linus Torvalds committed Jan 6, 2011
2 parents 8484baa + 846f404 commit b08b272
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 173 deletions.
11 changes: 8 additions & 3 deletions fs/gfs2/bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
int metadata;
unsigned int revokes = 0;
int x;
int error;
int error = 0;

if (!*top)
sm->sm_first = 0;
Expand All @@ -780,7 +780,11 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
if (metadata)
revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs;

error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh);
if (ip != GFS2_I(sdp->sd_rindex))
error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh);
else if (!sdp->sd_rgrps)
error = gfs2_ri_update(ip);

if (error)
return error;

Expand Down Expand Up @@ -879,7 +883,8 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
out_rlist:
gfs2_rlist_free(&rlist);
out:
gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh);
if (ip != GFS2_I(sdp->sd_rindex))
gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh);
return error;
}

Expand Down
71 changes: 34 additions & 37 deletions fs/gfs2/glock.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,21 +541,6 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
spin_unlock(&gl->gl_spin);
}

static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock,
unsigned int req_state,
unsigned int flags)
{
int ret = LM_OUT_ERROR;

if (!sdp->sd_lockstruct.ls_ops->lm_lock)
return req_state == LM_ST_UNLOCKED ? 0 : req_state;

if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock,
req_state, flags);
return ret;
}

/**
* do_xmote - Calls the DLM to change the state of a lock
* @gl: The lock state
Expand All @@ -575,13 +560,14 @@ __acquires(&gl->gl_spin)

lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
LM_FLAG_PRIORITY);
BUG_ON(gl->gl_state == target);
BUG_ON(gl->gl_state == gl->gl_target);
GLOCK_BUG_ON(gl, gl->gl_state == target);
GLOCK_BUG_ON(gl, gl->gl_state == gl->gl_target);
if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) &&
glops->go_inval) {
set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags);
do_error(gl, 0); /* Fail queued try locks */
}
gl->gl_req = target;
spin_unlock(&gl->gl_spin);
if (glops->go_xmote_th)
glops->go_xmote_th(gl);
Expand All @@ -594,15 +580,17 @@ __acquires(&gl->gl_spin)
gl->gl_state == LM_ST_DEFERRED) &&
!(lck_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
lck_flags |= LM_FLAG_TRY_1CB;
ret = gfs2_lm_lock(sdp, gl, target, lck_flags);

if (!(ret & LM_OUT_ASYNC)) {
finish_xmote(gl, ret);
if (sdp->sd_lockstruct.ls_ops->lm_lock) {
/* lock_dlm */
ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags);
GLOCK_BUG_ON(gl, ret);
} else { /* lock_nolock */
finish_xmote(gl, target);
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put(gl);
} else {
GLOCK_BUG_ON(gl, ret != LM_OUT_ASYNC);
}

spin_lock(&gl->gl_spin);
}

Expand Down Expand Up @@ -951,17 +939,22 @@ int gfs2_glock_wait(struct gfs2_holder *gh)

void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...)
{
struct va_format vaf;
va_list args;

va_start(args, fmt);

if (seq) {
struct gfs2_glock_iter *gi = seq->private;
vsprintf(gi->string, fmt, args);
seq_printf(seq, gi->string);
} else {
printk(KERN_ERR " ");
vprintk(fmt, args);
vaf.fmt = fmt;
vaf.va = &args;

printk(KERN_ERR " %pV", &vaf);
}

va_end(args);
}

Expand Down Expand Up @@ -1361,24 +1354,28 @@ static int gfs2_should_freeze(const struct gfs2_glock *gl)
* @gl: Pointer to the glock
* @ret: The return value from the dlm
*
* The gl_reply field is under the gl_spin lock so that it is ok
* to use a bitfield shared with other glock state fields.
*/

void gfs2_glock_complete(struct gfs2_glock *gl, int ret)
{
struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;

spin_lock(&gl->gl_spin);
gl->gl_reply = ret;

if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) {
spin_lock(&gl->gl_spin);
if (gfs2_should_freeze(gl)) {
set_bit(GLF_FROZEN, &gl->gl_flags);
spin_unlock(&gl->gl_spin);
return;
}
spin_unlock(&gl->gl_spin);
}

spin_unlock(&gl->gl_spin);
set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
smp_wmb();
gfs2_glock_hold(gl);
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
gfs2_glock_put(gl);
Expand Down Expand Up @@ -1626,18 +1623,17 @@ static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags)
static int dump_holder(struct seq_file *seq, const struct gfs2_holder *gh)
{
struct task_struct *gh_owner = NULL;
char buffer[KSYM_SYMBOL_LEN];
char flags_buf[32];

sprint_symbol(buffer, gh->gh_ip);
if (gh->gh_owner_pid)
gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID);
gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %s\n",
state2str(gh->gh_state),
hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags),
gh->gh_error,
gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1,
gh_owner ? gh_owner->comm : "(ended)", buffer);
gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %pS\n",
state2str(gh->gh_state),
hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags),
gh->gh_error,
gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1,
gh_owner ? gh_owner->comm : "(ended)",
(void *)gh->gh_ip);
return 0;
}

Expand Down Expand Up @@ -1782,12 +1778,13 @@ int __init gfs2_glock_init(void)
}
#endif

glock_workqueue = alloc_workqueue("glock_workqueue", WQ_RESCUER |
glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM |
WQ_HIGHPRI | WQ_FREEZEABLE, 0);
if (IS_ERR(glock_workqueue))
return PTR_ERR(glock_workqueue);
gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", WQ_RESCUER |
WQ_FREEZEABLE, 0);
gfs2_delete_workqueue = alloc_workqueue("delete_workqueue",
WQ_MEM_RECLAIM | WQ_FREEZEABLE,
0);
if (IS_ERR(gfs2_delete_workqueue)) {
destroy_workqueue(glock_workqueue);
return PTR_ERR(gfs2_delete_workqueue);
Expand Down
28 changes: 6 additions & 22 deletions fs/gfs2/glock.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,27 +87,22 @@ enum {
#define GL_ASYNC 0x00000040
#define GL_EXACT 0x00000080
#define GL_SKIP 0x00000100
#define GL_ATIME 0x00000200
#define GL_NOCACHE 0x00000400

/*
* lm_lock() and lm_async_cb return flags
* lm_async_cb return flags
*
* LM_OUT_ST_MASK
* Masks the lower two bits of lock state in the returned value.
*
* LM_OUT_CANCELED
* The lock request was canceled.
*
* LM_OUT_ASYNC
* The result of the request will be returned in an LM_CB_ASYNC callback.
*
*/

#define LM_OUT_ST_MASK 0x00000003
#define LM_OUT_CANCELED 0x00000008
#define LM_OUT_ASYNC 0x00000080
#define LM_OUT_ERROR 0x00000100
#define LM_OUT_ERROR 0x00000004

/*
* lm_recovery_done() messages
Expand All @@ -124,25 +119,12 @@ struct lm_lockops {
void (*lm_unmount) (struct gfs2_sbd *sdp);
void (*lm_withdraw) (struct gfs2_sbd *sdp);
void (*lm_put_lock) (struct kmem_cache *cachep, struct gfs2_glock *gl);
unsigned int (*lm_lock) (struct gfs2_glock *gl,
unsigned int req_state, unsigned int flags);
int (*lm_lock) (struct gfs2_glock *gl, unsigned int req_state,
unsigned int flags);
void (*lm_cancel) (struct gfs2_glock *gl);
const match_table_t *lm_tokens;
};

#define LM_FLAG_TRY 0x00000001
#define LM_FLAG_TRY_1CB 0x00000002
#define LM_FLAG_NOEXP 0x00000004
#define LM_FLAG_ANY 0x00000008
#define LM_FLAG_PRIORITY 0x00000010

#define GL_ASYNC 0x00000040
#define GL_EXACT 0x00000080
#define GL_SKIP 0x00000100
#define GL_NOCACHE 0x00000400

#define GLR_TRYFAILED 13

extern struct workqueue_struct *gfs2_delete_workqueue;
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
{
Expand Down Expand Up @@ -212,6 +194,8 @@ int gfs2_glock_nq_num(struct gfs2_sbd *sdp,
int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs);
void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs);
void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs);

__attribute__ ((format(printf, 2, 3)))
void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...);

/**
Expand Down
1 change: 0 additions & 1 deletion fs/gfs2/glops.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,6 @@ static void trans_go_sync(struct gfs2_glock *gl)

if (gl->gl_state != LM_ST_UNLOCKED &&
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
flush_workqueue(gfs2_delete_workqueue);
gfs2_meta_syncfs(sdp);
gfs2_log_shutdown(sdp);
}
Expand Down
12 changes: 7 additions & 5 deletions fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,14 @@ struct gfs2_glock {

spinlock_t gl_spin;

unsigned int gl_state;
unsigned int gl_target;
unsigned int gl_reply;
/* State fields protected by gl_spin */
unsigned int gl_state:2, /* Current state */
gl_target:2, /* Target state */
gl_demote_state:2, /* State requested by remote node */
gl_req:2, /* State in last dlm request */
gl_reply:8; /* Last reply from the dlm */

unsigned int gl_hash;
unsigned int gl_req;
unsigned int gl_demote_state; /* state requested by remote node */
unsigned long gl_demote_time; /* time of first demote request */
struct list_head gl_holders;

Expand Down
9 changes: 0 additions & 9 deletions fs/gfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,17 +916,8 @@ static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
if (error)
return error;

if ((attr->ia_valid & ATTR_SIZE) &&
attr->ia_size != i_size_read(inode)) {
error = vmtruncate(inode, attr->ia_size);
if (error)
return error;
}

setattr_copy(inode, attr);
mark_inode_dirty(inode);

gfs2_assert_warn(GFS2_SB(inode), !error);
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
Expand Down
15 changes: 4 additions & 11 deletions fs/gfs2/lock_dlm.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,29 +146,22 @@ static u32 make_flags(const u32 lkid, const unsigned int gfs_flags,
return lkf;
}

static unsigned int gdlm_lock(struct gfs2_glock *gl,
unsigned int req_state, unsigned int flags)
static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
unsigned int flags)
{
struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
int error;
int req;
u32 lkf;

gl->gl_req = req_state;
req = make_mode(req_state);
lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);

/*
* Submit the actual lock request.
*/

error = dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
if (error == -EAGAIN)
return 0;
if (error)
return LM_OUT_ERROR;
return LM_OUT_ASYNC;
return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
}

static void gdlm_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl)
Expand Down
18 changes: 1 addition & 17 deletions fs/gfs2/ops_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,6 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *dibh;
u32 ouid, ogid, nuid, ngid;
int error;

Expand Down Expand Up @@ -1100,25 +1099,10 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
if (error)
goto out_gunlock_q;

error = gfs2_meta_inode_buffer(ip, &dibh);
error = gfs2_setattr_simple(ip, attr);
if (error)
goto out_end_trans;

if ((attr->ia_valid & ATTR_SIZE) &&
attr->ia_size != i_size_read(inode)) {
int error;

error = vmtruncate(inode, attr->ia_size);
gfs2_assert_warn(sdp, !error);
}

setattr_copy(inode, attr);
mark_inode_dirty(inode);

gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);

if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
u64 blocks = gfs2_get_inode_blocks(&ip->i_inode);
gfs2_quota_change(ip, -blocks, ouid, ogid);
Expand Down
Loading

0 comments on commit b08b272

Please sign in to comment.