glock.h 7.2 KB
Newer Older
D
David Teigland 已提交
1 2
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
D
David Teigland 已提交
4 5 6
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
7
 * of the GNU General Public License version 2.
D
David Teigland 已提交
8 9 10 11 12
 */

#ifndef __GLOCK_DOT_H__
#define __GLOCK_DOT_H__

A
Alexey Dobriyan 已提交
13
#include <linux/sched.h>
14
#include <linux/parser.h>
15 16
#include "incore.h"

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
/* Options for hostdata parser */

enum {
	Opt_jid,
	Opt_id,
	Opt_first,
	Opt_nodir,
	Opt_err,
};

/*
 * lm_lockname types
 */

#define LM_TYPE_RESERVED	0x00
#define LM_TYPE_NONDISK		0x01
#define LM_TYPE_INODE		0x02
#define LM_TYPE_RGRP		0x03
#define LM_TYPE_META		0x04
#define LM_TYPE_IOPEN		0x05
#define LM_TYPE_FLOCK		0x06
#define LM_TYPE_PLOCK		0x07
#define LM_TYPE_QUOTA		0x08
#define LM_TYPE_JOURNAL		0x09

/*
 * lm_lock() states
 *
 * SHARED is compatible with SHARED, not with DEFERRED or EX.
 * DEFERRED is compatible with DEFERRED, not with SHARED or EX.
 */

#define LM_ST_UNLOCKED		0
#define LM_ST_EXCLUSIVE		1
#define LM_ST_DEFERRED		2
#define LM_ST_SHARED		3

/*
 * lm_lock() flags
 *
 * LM_FLAG_TRY
 * Don't wait to acquire the lock if it can't be granted immediately.
 *
 * LM_FLAG_TRY_1CB
 * Send one blocking callback if TRY is set and the lock is not granted.
 *
 * LM_FLAG_NOEXP
 * GFS sets this flag on lock requests it makes while doing journal recovery.
 * These special requests should not be blocked due to the recovery like
 * ordinary locks would be.
 *
 * LM_FLAG_ANY
 * A SHARED request may also be granted in DEFERRED, or a DEFERRED request may
 * also be granted in SHARED.  The preferred state is whichever is compatible
 * with other granted locks, or the specified state if no other locks exist.
 *
 * LM_FLAG_PRIORITY
 * Override fairness considerations.  Suppose a lock is held in a shared state
 * and there is a pending request for the deferred state.  A shared lock
 * request with the priority flag would be allowed to bypass the deferred
 * request and directly join the other shared lock.  A shared lock request
 * without the priority flag might be forced to wait until the deferred
 * requested had acquired and released the lock.
 */

D
David Teigland 已提交
82 83 84 85
#define LM_FLAG_TRY		0x00000001
#define LM_FLAG_TRY_1CB		0x00000002
#define LM_FLAG_NOEXP		0x00000004
#define LM_FLAG_ANY		0x00000008
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
#define LM_FLAG_PRIORITY	0x00000010
#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_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

/*
 * lm_recovery_done() messages
 */

#define LM_RD_GAVEUP		308
#define LM_RD_SUCCESS		309

#define GLR_TRYFAILED		13

struct lm_lockops {
	const char *lm_proto_name;
	int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname);
 	void (*lm_unmount) (struct gfs2_sbd *sdp);
	void (*lm_withdraw) (struct gfs2_sbd *sdp);
	void (*lm_put_lock) (struct kmem_cache *cachep, void *gl);
	unsigned 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
D
David Teigland 已提交
138 139 140 141 142 143 144 145

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

#define GLR_TRYFAILED		13

146
extern struct workqueue_struct *gfs2_delete_workqueue;
147
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
D
David Teigland 已提交
148 149
{
	struct gfs2_holder *gh;
150
	struct pid *pid;
D
David Teigland 已提交
151 152 153

	/* Look in glock's list of holders for one with current task as owner */
	spin_lock(&gl->gl_spin);
154
	pid = task_pid(current);
D
David Teigland 已提交
155
	list_for_each_entry(gh, &gl->gl_holders, gh_list) {
156 157
		if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
			break;
158 159
		if (gh->gh_owner_pid == pid)
			goto out;
D
David Teigland 已提交
160
	}
161 162
	gh = NULL;
out:
D
David Teigland 已提交
163 164
	spin_unlock(&gl->gl_spin);

165
	return gh;
D
David Teigland 已提交
166 167 168 169
}

static inline int gfs2_glock_is_held_excl(struct gfs2_glock *gl)
{
S
Steven Whitehouse 已提交
170
	return gl->gl_state == LM_ST_EXCLUSIVE;
D
David Teigland 已提交
171 172 173 174
}

static inline int gfs2_glock_is_held_dfrd(struct gfs2_glock *gl)
{
S
Steven Whitehouse 已提交
175
	return gl->gl_state == LM_ST_DEFERRED;
D
David Teigland 已提交
176 177 178 179
}

static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
{
S
Steven Whitehouse 已提交
180
	return gl->gl_state == LM_ST_SHARED;
D
David Teigland 已提交
181 182 183 184 185 186
}

static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl)
{
	int ret;
	spin_lock(&gl->gl_spin);
187
	ret = test_bit(GLF_DEMOTE, &gl->gl_flags);
D
David Teigland 已提交
188 189 190 191 192
	spin_unlock(&gl->gl_spin);
	return ret;
}

int gfs2_glock_get(struct gfs2_sbd *sdp,
193
		   u64 number, const struct gfs2_glock_operations *glops,
D
David Teigland 已提交
194
		   int create, struct gfs2_glock **glp);
195 196
void gfs2_glock_hold(struct gfs2_glock *gl);
void gfs2_glock_put_nolock(struct gfs2_glock *gl);
D
David Teigland 已提交
197
int gfs2_glock_put(struct gfs2_glock *gl);
198
void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags,
D
David Teigland 已提交
199
		      struct gfs2_holder *gh);
200 201
void gfs2_holder_reinit(unsigned int state, unsigned flags,
			struct gfs2_holder *gh);
D
David Teigland 已提交
202 203 204 205 206
void gfs2_holder_uninit(struct gfs2_holder *gh);
int gfs2_glock_nq(struct gfs2_holder *gh);
int gfs2_glock_poll(struct gfs2_holder *gh);
int gfs2_glock_wait(struct gfs2_holder *gh);
void gfs2_glock_dq(struct gfs2_holder *gh);
A
Abhijith Das 已提交
207
void gfs2_glock_dq_wait(struct gfs2_holder *gh);
D
David Teigland 已提交
208 209 210

void gfs2_glock_dq_uninit(struct gfs2_holder *gh);
int gfs2_glock_nq_num(struct gfs2_sbd *sdp,
211
		      u64 number, const struct gfs2_glock_operations *glops,
D
David Teigland 已提交
212 213 214 215 216
		      unsigned int state, int flags, struct gfs2_holder *gh);

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);
217
void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...);
D
David Teigland 已提交
218

S
Steven Whitehouse 已提交
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
/**
 * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock
 * @gl: the glock
 * @state: the state we're requesting
 * @flags: the modifier flags
 * @gh: the holder structure
 *
 * Returns: 0, GLR_*, or errno
 */

static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,
				     unsigned int state, int flags,
				     struct gfs2_holder *gh)
{
	int error;

	gfs2_holder_init(gl, state, flags, gh);

	error = gfs2_glock_nq(gh);
	if (error)
		gfs2_holder_uninit(gh);

	return error;
}

D
David Teigland 已提交
244 245 246 247 248
/*  Lock Value Block functions  */

int gfs2_lvb_hold(struct gfs2_glock *gl);
void gfs2_lvb_unhold(struct gfs2_glock *gl);

249 250
void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state);
void gfs2_glock_complete(struct gfs2_glock *gl, int ret);
D
David Teigland 已提交
251
void gfs2_reclaim_glock(struct gfs2_sbd *sdp);
252
void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
253
void gfs2_glock_finish_truncate(struct gfs2_inode *ip);
254
void gfs2_glock_thaw(struct gfs2_sbd *sdp);
D
David Teigland 已提交
255

256
int __init gfs2_glock_init(void);
257 258
void gfs2_glock_exit(void);

259 260 261 262
int gfs2_create_debugfs_file(struct gfs2_sbd *sdp);
void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp);
int gfs2_register_debugfs(void);
void gfs2_unregister_debugfs(void);
263

264 265
extern const struct lm_lockops gfs2_dlm_ops;

D
David Teigland 已提交
266
#endif /* __GLOCK_DOT_H__ */