Blame view

fs/gfs2/locking.c 5.41 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3a8a9a103   Steven Whitehouse   [GFS2] Update cop...
3
   * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
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
e9fc2aa09   Steven Whitehouse   [GFS2] Update cop...
7
   * of the GNU General Public License version 2.
b3b94faa5   David Teigland   [GFS2] The core o...
8
9
10
11
12
13
14
15
16
17
18
   */
  
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/string.h>
  #include <linux/slab.h>
  #include <linux/wait.h>
  #include <linux/sched.h>
  #include <linux/kmod.h>
  #include <linux/fs.h>
  #include <linux/delay.h>
7d308590a   Fabio Massimo Di Nitto   [GFS2] Export lm_...
19
  #include <linux/lm_interface.h>
b3b94faa5   David Teigland   [GFS2] The core o...
20
21
22
  
  struct lmh_wrapper {
  	struct list_head lw_list;
9b47c11d1   Steven Whitehouse   [GFS2] Use void *...
23
  	const struct lm_lockops *lw_ops;
b3b94faa5   David Teigland   [GFS2] The core o...
24
  };
048bca223   Steven Whitehouse   [GFS2] No lock_no...
25
26
27
28
29
  static int nolock_mount(char *table_name, char *host_data,
  			lm_callback_t cb, void *cb_data,
  			unsigned int min_lvb_size, int flags,
  			struct lm_lockstruct *lockstruct,
  			struct kobject *fskobj);
b3b94faa5   David Teigland   [GFS2] The core o...
30
31
  /* List of registered low-level locking protocols.  A file system selects one
     of them by name at mount time, e.g. lock_nolock, lock_dlm. */
048bca223   Steven Whitehouse   [GFS2] No lock_no...
32
33
34
35
36
37
38
39
40
  static const struct lm_lockops nolock_ops = {
  	.lm_proto_name = "lock_nolock",
  	.lm_mount = nolock_mount,
  };
  
  static struct lmh_wrapper nolock_proto  = {
  	.lw_list = LIST_HEAD_INIT(nolock_proto.lw_list),
  	.lw_ops = &nolock_ops,
  };
502999654   Steven Whitehouse   [GFS2] Tidy up lo...
41
42
  static LIST_HEAD(lmh_list);
  static DEFINE_MUTEX(lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
43

048bca223   Steven Whitehouse   [GFS2] No lock_no...
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
  static int nolock_mount(char *table_name, char *host_data,
  			lm_callback_t cb, void *cb_data,
  			unsigned int min_lvb_size, int flags,
  			struct lm_lockstruct *lockstruct,
  			struct kobject *fskobj)
  {
  	char *c;
  	unsigned int jid;
  
  	c = strstr(host_data, "jid=");
  	if (!c)
  		jid = 0;
  	else {
  		c += 4;
  		sscanf(c, "%u", &jid);
  	}
  
  	lockstruct->ls_jid = jid;
  	lockstruct->ls_first = 1;
  	lockstruct->ls_lvb_size = min_lvb_size;
  	lockstruct->ls_ops = &nolock_ops;
  	lockstruct->ls_flags = LM_LSFLAG_LOCAL;
  
  	return 0;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
69
  /**
2b557f6dc   Steven Whitehouse   [GFS2] Fix gfs_ p...
70
   * gfs2_register_lockproto - Register a low-level locking protocol
b3b94faa5   David Teigland   [GFS2] The core o...
71
72
73
74
   * @proto: the protocol definition
   *
   * Returns: 0 on success, -EXXX on failure
   */
9b47c11d1   Steven Whitehouse   [GFS2] Use void *...
75
  int gfs2_register_lockproto(const struct lm_lockops *proto)
b3b94faa5   David Teigland   [GFS2] The core o...
76
77
  {
  	struct lmh_wrapper *lw;
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
78
  	mutex_lock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
79
80
81
  
  	list_for_each_entry(lw, &lmh_list, lw_list) {
  		if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) {
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
82
  			mutex_unlock(&lmh_lock);
d92a8d480   Steven Whitehouse   [GFS2] Audit prin...
83
84
  			printk(KERN_INFO "GFS2: protocol %s already exists
  ",
b3b94faa5   David Teigland   [GFS2] The core o...
85
86
87
88
  			       proto->lm_proto_name);
  			return -EEXIST;
  		}
  	}
d92a8d480   Steven Whitehouse   [GFS2] Audit prin...
89
  	lw = kzalloc(sizeof(struct lmh_wrapper), GFP_KERNEL);
b3b94faa5   David Teigland   [GFS2] The core o...
90
  	if (!lw) {
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
91
  		mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
92
93
  		return -ENOMEM;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
94
95
96
  
  	lw->lw_ops = proto;
  	list_add(&lw->lw_list, &lmh_list);
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
97
  	mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
98
99
100
101
102
  
  	return 0;
  }
  
  /**
2b557f6dc   Steven Whitehouse   [GFS2] Fix gfs_ p...
103
   * gfs2_unregister_lockproto - Unregister a low-level locking protocol
b3b94faa5   David Teigland   [GFS2] The core o...
104
105
106
   * @proto: the protocol definition
   *
   */
9b47c11d1   Steven Whitehouse   [GFS2] Use void *...
107
  void gfs2_unregister_lockproto(const struct lm_lockops *proto)
b3b94faa5   David Teigland   [GFS2] The core o...
108
109
  {
  	struct lmh_wrapper *lw;
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
110
  	mutex_lock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
111
112
113
114
  
  	list_for_each_entry(lw, &lmh_list, lw_list) {
  		if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) {
  			list_del(&lw->lw_list);
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
115
  			mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
116
117
118
119
  			kfree(lw);
  			return;
  		}
  	}
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
120
  	mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
121

d92a8d480   Steven Whitehouse   [GFS2] Audit prin...
122
123
  	printk(KERN_WARNING "GFS2: can't unregister lock protocol %s
  ",
b3b94faa5   David Teigland   [GFS2] The core o...
124
125
126
127
128
129
130
131
132
  	       proto->lm_proto_name);
  }
  
  /**
   * gfs2_mount_lockproto - Mount a lock protocol
   * @proto_name - the name of the protocol
   * @table_name - the name of the lock space
   * @host_data - data specific to this host
   * @cb - the callback to the code using the lock module
1c089c325   Steven Whitehouse   [GFS2] Remove one...
133
   * @sdp - The GFS2 superblock
b3b94faa5   David Teigland   [GFS2] The core o...
134
135
136
137
138
139
140
141
   * @min_lvb_size - the mininum LVB size that the caller can deal with
   * @flags - LM_MFLAG_*
   * @lockstruct - a structure returned describing the mount
   *
   * Returns: 0 on success, -EXXX on failure
   */
  
  int gfs2_mount_lockproto(char *proto_name, char *table_name, char *host_data,
9b47c11d1   Steven Whitehouse   [GFS2] Use void *...
142
  			 lm_callback_t cb, void *cb_data,
b3b94faa5   David Teigland   [GFS2] The core o...
143
144
145
146
147
148
149
  			 unsigned int min_lvb_size, int flags,
  			 struct lm_lockstruct *lockstruct,
  			 struct kobject *fskobj)
  {
  	struct lmh_wrapper *lw = NULL;
  	int try = 0;
  	int error, found;
048bca223   Steven Whitehouse   [GFS2] No lock_no...
150

2b557f6dc   Steven Whitehouse   [GFS2] Fix gfs_ p...
151
  retry:
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
152
  	mutex_lock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
153

048bca223   Steven Whitehouse   [GFS2] No lock_no...
154
  	if (list_empty(&nolock_proto.lw_list))
802747372   Steven Whitehouse   [GFS2] Fix orderi...
155
  		list_add(&nolock_proto.lw_list, &lmh_list);
048bca223   Steven Whitehouse   [GFS2] No lock_no...
156

b3b94faa5   David Teigland   [GFS2] The core o...
157
158
159
160
161
162
163
164
165
166
167
  	found = 0;
  	list_for_each_entry(lw, &lmh_list, lw_list) {
  		if (!strcmp(lw->lw_ops->lm_proto_name, proto_name)) {
  			found = 1;
  			break;
  		}
  	}
  
  	if (!found) {
  		if (!try && capable(CAP_SYS_MODULE)) {
  			try = 1;
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
168
  			mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
169
170
171
  			request_module(proto_name);
  			goto retry;
  		}
d92a8d480   Steven Whitehouse   [GFS2] Audit prin...
172
173
  		printk(KERN_INFO "GFS2: can't find protocol %s
  ", proto_name);
b3b94faa5   David Teigland   [GFS2] The core o...
174
175
176
  		error = -ENOENT;
  		goto out;
  	}
048bca223   Steven Whitehouse   [GFS2] No lock_no...
177
178
  	if (lw->lw_ops->lm_owner &&
  	    !try_module_get(lw->lw_ops->lm_owner)) {
b3b94faa5   David Teigland   [GFS2] The core o...
179
  		try = 0;
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
180
  		mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
181
182
183
  		msleep(1000);
  		goto retry;
  	}
9b47c11d1   Steven Whitehouse   [GFS2] Use void *...
184
  	error = lw->lw_ops->lm_mount(table_name, host_data, cb, cb_data,
b3b94faa5   David Teigland   [GFS2] The core o...
185
186
187
  				     min_lvb_size, flags, lockstruct, fskobj);
  	if (error)
  		module_put(lw->lw_ops->lm_owner);
2b557f6dc   Steven Whitehouse   [GFS2] Fix gfs_ p...
188
  out:
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
189
  	mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
190
191
192
193
194
  	return error;
  }
  
  void gfs2_unmount_lockproto(struct lm_lockstruct *lockstruct)
  {
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
195
  	mutex_lock(&lmh_lock);
048bca223   Steven Whitehouse   [GFS2] No lock_no...
196
197
  	if (lockstruct->ls_ops->lm_unmount)
  		lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace);
b3b94faa5   David Teigland   [GFS2] The core o...
198
199
  	if (lockstruct->ls_ops->lm_owner)
  		module_put(lockstruct->ls_ops->lm_owner);
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
200
  	mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
201
202
203
204
205
206
207
208
209
210
  }
  
  /**
   * gfs2_withdraw_lockproto - abnormally unmount a lock module
   * @lockstruct: the lockstruct passed into mount
   *
   */
  
  void gfs2_withdraw_lockproto(struct lm_lockstruct *lockstruct)
  {
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
211
  	mutex_lock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
212
213
214
  	lockstruct->ls_ops->lm_withdraw(lockstruct->ls_lockspace);
  	if (lockstruct->ls_ops->lm_owner)
  		module_put(lockstruct->ls_ops->lm_owner);
a74604bee   Steven Whitehouse   [GFS2] sem -> mut...
215
  	mutex_unlock(&lmh_lock);
b3b94faa5   David Teigland   [GFS2] The core o...
216
  }
2b557f6dc   Steven Whitehouse   [GFS2] Fix gfs_ p...
217
218
  EXPORT_SYMBOL_GPL(gfs2_register_lockproto);
  EXPORT_SYMBOL_GPL(gfs2_unregister_lockproto);
b3b94faa5   David Teigland   [GFS2] The core o...
219