Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b08b2721 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 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
parents 8484baaa 846f4045
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;

	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;

@@ -879,6 +883,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
out_rlist:
	gfs2_rlist_free(&rlist);
out:
	if (ip != GFS2_I(sdp->sd_rindex))
		gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh);
	return error;
}
+34 −37
Original line number Diff line number Diff line
@@ -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
@@ -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);
@@ -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);
}

@@ -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);
}

@@ -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);
@@ -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",
	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)", buffer);
		       gh_owner ? gh_owner->comm : "(ended)",
		       (void *)gh->gh_ip);
	return 0;
}

@@ -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);
+6 −22
Original line number Diff line number Diff line
@@ -87,11 +87,10 @@ 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.
@@ -99,15 +98,11 @@ enum {
 * 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
@@ -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)
{
@@ -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, ...);

/**
+0 −1
Original line number Diff line number Diff line
@@ -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);
	}
+7 −5
Original line number Diff line number Diff line
@@ -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;

Loading