lm.c 5.7 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 13 14 15
 */

#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/delay.h>
16
#include <linux/gfs2_ondisk.h>
17
#include <linux/lm_interface.h>
D
David Teigland 已提交
18 19

#include "gfs2.h"
20
#include "incore.h"
D
David Teigland 已提交
21 22 23
#include "glock.h"
#include "lm.h"
#include "super.h"
24
#include "util.h"
D
David Teigland 已提交
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

/**
 * gfs2_lm_mount - mount a locking protocol
 * @sdp: the filesystem
 * @args: mount arguements
 * @silent: if 1, don't complain if the FS isn't a GFS2 fs
 *
 * Returns: errno
 */

int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
{
	char *proto = sdp->sd_proto_name;
	char *table = sdp->sd_table_name;
	int flags = 0;
	int error;

	if (sdp->sd_args.ar_spectator)
		flags |= LM_MFLAG_SPECTATOR;

	fs_info(sdp, "Trying to join cluster \"%s\", \"%s\"\n", proto, table);

	error = gfs2_mount_lockproto(proto, table, sdp->sd_args.ar_hostdata,
				     gfs2_glock_cb, sdp,
				     GFS2_MIN_LVB_SIZE, flags,
				     &sdp->sd_lockstruct, &sdp->sd_kobj);
	if (error) {
		fs_info(sdp, "can't mount proto=%s, table=%s, hostdata=%s\n",
			proto, table, sdp->sd_args.ar_hostdata);
		goto out;
	}

	if (gfs2_assert_warn(sdp, sdp->sd_lockstruct.ls_lockspace) ||
	    gfs2_assert_warn(sdp, sdp->sd_lockstruct.ls_ops) ||
	    gfs2_assert_warn(sdp, sdp->sd_lockstruct.ls_lvb_size >=
				  GFS2_MIN_LVB_SIZE)) {
		gfs2_unmount_lockproto(&sdp->sd_lockstruct);
		goto out;
	}

	if (sdp->sd_args.ar_spectator)
		snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.s", table);
	else
		snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.%u", table,
			 sdp->sd_lockstruct.ls_jid);

	fs_info(sdp, "Joined cluster. Now mounting FS...\n");

	if ((sdp->sd_lockstruct.ls_flags & LM_LSFLAG_LOCAL) &&
	    !sdp->sd_args.ar_ignore_local_fs) {
		sdp->sd_args.ar_localflocks = 1;
		sdp->sd_args.ar_localcaching = 1;
	}

79
out:
D
David Teigland 已提交
80 81 82 83 84 85
	return error;
}

void gfs2_lm_others_may_mount(struct gfs2_sbd *sdp)
{
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
86 87
		sdp->sd_lockstruct.ls_ops->lm_others_may_mount(
					sdp->sd_lockstruct.ls_lockspace);
D
David Teigland 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
}

void gfs2_lm_unmount(struct gfs2_sbd *sdp)
{
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		gfs2_unmount_lockproto(&sdp->sd_lockstruct);
}

int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...)
{
	va_list args;

	if (test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
		return 0;

	va_start(args, fmt);
	vprintk(fmt, args);
	va_end(args);

	fs_err(sdp, "about to withdraw from the cluster\n");
108
	BUG_ON(sdp->sd_args.ar_debug);
109

D
David Teigland 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124

	fs_err(sdp, "waiting for outstanding I/O\n");

	/* FIXME: suspend dm device so oustanding bio's complete
	   and all further io requests fail */

	fs_err(sdp, "telling LM to withdraw\n");
	gfs2_withdraw_lockproto(&sdp->sd_lockstruct);
	fs_err(sdp, "withdrawn\n");
	dump_stack();

	return -1;
}

int gfs2_lm_get_lock(struct gfs2_sbd *sdp, struct lm_lockname *name,
125
		     void **lockp)
D
David Teigland 已提交
126
{
S
Steven Whitehouse 已提交
127 128
	int error = -EIO;
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
129 130
		error = sdp->sd_lockstruct.ls_ops->lm_get_lock(
				sdp->sd_lockstruct.ls_lockspace, name, lockp);
D
David Teigland 已提交
131 132 133
	return error;
}

134
void gfs2_lm_put_lock(struct gfs2_sbd *sdp, void *lock)
D
David Teigland 已提交
135 136 137 138 139
{
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		sdp->sd_lockstruct.ls_ops->lm_put_lock(lock);
}

140
unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock,
D
David Teigland 已提交
141 142 143
			  unsigned int cur_state, unsigned int req_state,
			  unsigned int flags)
{
S
Steven Whitehouse 已提交
144 145 146
	int ret = 0;
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock, cur_state,
D
David Teigland 已提交
147 148 149 150
							 req_state, flags);
	return ret;
}

151
unsigned int gfs2_lm_unlock(struct gfs2_sbd *sdp, void *lock,
D
David Teigland 已提交
152 153
			    unsigned int cur_state)
{
S
Steven Whitehouse 已提交
154 155
	int ret = 0;
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
D
David Teigland 已提交
156 157 158 159
		ret =  sdp->sd_lockstruct.ls_ops->lm_unlock(lock, cur_state);
	return ret;
}

160
void gfs2_lm_cancel(struct gfs2_sbd *sdp, void *lock)
D
David Teigland 已提交
161 162 163 164 165
{
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		sdp->sd_lockstruct.ls_ops->lm_cancel(lock);
}

166
int gfs2_lm_hold_lvb(struct gfs2_sbd *sdp, void *lock, char **lvbp)
D
David Teigland 已提交
167
{
S
Steven Whitehouse 已提交
168 169
	int error = -EIO;
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
D
David Teigland 已提交
170 171 172 173
		error = sdp->sd_lockstruct.ls_ops->lm_hold_lvb(lock, lvbp);
	return error;
}

174
void gfs2_lm_unhold_lvb(struct gfs2_sbd *sdp, void *lock, char *lvb)
D
David Teigland 已提交
175 176 177 178 179 180 181 182
{
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		sdp->sd_lockstruct.ls_ops->lm_unhold_lvb(lock, lvb);
}

int gfs2_lm_plock_get(struct gfs2_sbd *sdp, struct lm_lockname *name,
		      struct file *file, struct file_lock *fl)
{
S
Steven Whitehouse 已提交
183 184
	int error = -EIO;
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
D
David Teigland 已提交
185
		error = sdp->sd_lockstruct.ls_ops->lm_plock_get(
S
Steven Whitehouse 已提交
186
				sdp->sd_lockstruct.ls_lockspace, name, file, fl);
D
David Teigland 已提交
187 188 189 190 191 192
	return error;
}

int gfs2_lm_plock(struct gfs2_sbd *sdp, struct lm_lockname *name,
		  struct file *file, int cmd, struct file_lock *fl)
{
S
Steven Whitehouse 已提交
193 194
	int error = -EIO;
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
D
David Teigland 已提交
195
		error = sdp->sd_lockstruct.ls_ops->lm_plock(
S
Steven Whitehouse 已提交
196
				sdp->sd_lockstruct.ls_lockspace, name, file, cmd, fl);
D
David Teigland 已提交
197 198 199 200 201 202
	return error;
}

int gfs2_lm_punlock(struct gfs2_sbd *sdp, struct lm_lockname *name,
		    struct file *file, struct file_lock *fl)
{
S
Steven Whitehouse 已提交
203 204
	int error = -EIO;
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
D
David Teigland 已提交
205
		error = sdp->sd_lockstruct.ls_ops->lm_punlock(
S
Steven Whitehouse 已提交
206
				sdp->sd_lockstruct.ls_lockspace, name, file, fl);
D
David Teigland 已提交
207 208 209 210 211 212 213
	return error;
}

void gfs2_lm_recovery_done(struct gfs2_sbd *sdp, unsigned int jid,
			   unsigned int message)
{
	if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
214 215
		sdp->sd_lockstruct.ls_ops->lm_recovery_done(
			sdp->sd_lockstruct.ls_lockspace, jid, message);
D
David Teigland 已提交
216 217
}