2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License v.2.
14 struct lm_lockops gdlm_ops;
17 static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata,
18 int flags, char *table_name)
23 ls = kzalloc(sizeof(struct gdlm_ls), GFP_KERNEL);
27 ls->drop_locks_count = gdlm_drop_count;
28 ls->drop_locks_period = gdlm_drop_period;
32 spin_lock_init(&ls->async_lock);
33 INIT_LIST_HEAD(&ls->complete);
34 INIT_LIST_HEAD(&ls->blocking);
35 INIT_LIST_HEAD(&ls->delayed);
36 INIT_LIST_HEAD(&ls->submit);
37 INIT_LIST_HEAD(&ls->all_locks);
38 init_waitqueue_head(&ls->thread_wait);
39 init_waitqueue_head(&ls->wait_control);
42 ls->drop_time = jiffies;
45 strncpy(buf, table_name, 256);
50 log_info("invalid table_name \"%s\"", table_name);
57 strncpy(ls->clustername, buf, GDLM_NAME_LEN);
58 strncpy(ls->fsname, p, GDLM_NAME_LEN);
63 static int make_args(struct gdlm_ls *ls, char *data_arg)
66 char *options, *x, *y;
70 strncpy(data, data_arg, 255);
72 for (options = data; (x = strsep(&options, ":")); ) {
80 if (!strcmp(x, "jid")) {
82 log_error("need argument to jid");
86 sscanf(y, "%u", &ls->jid);
88 } else if (!strcmp(x, "first")) {
90 log_error("need argument to first");
94 sscanf(y, "%u", &ls->first);
96 } else if (!strcmp(x, "id")) {
98 log_error("need argument to id");
102 sscanf(y, "%u", &ls->id);
105 log_error("unkonwn option: %s", x);
114 static int gdlm_mount(char *table_name, char *host_data,
115 lm_callback_t cb, lm_fsdata_t *fsdata,
116 unsigned int min_lvb_size, int flags,
117 struct lm_lockstruct *lockstruct,
118 struct kobject *fskobj)
123 if (min_lvb_size > GDLM_LVB_SIZE)
126 ls = init_gdlm(cb, fsdata, flags, table_name);
130 error = gdlm_init_threads(ls);
134 error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
135 &ls->dlm_lockspace, 0, GDLM_LVB_SIZE);
137 log_error("dlm_new_lockspace error %d", error);
141 error = gdlm_kobject_setup(ls, fskobj);
145 error = make_args(ls, host_data);
149 lockstruct->ls_jid = ls->jid;
150 lockstruct->ls_first = ls->first;
151 lockstruct->ls_lockspace = ls;
152 lockstruct->ls_ops = &gdlm_ops;
153 lockstruct->ls_flags = 0;
154 lockstruct->ls_lvb_size = GDLM_LVB_SIZE;
158 gdlm_kobject_release(ls);
160 dlm_release_lockspace(ls->dlm_lockspace, 2);
162 gdlm_release_threads(ls);
169 static void gdlm_unmount(lm_lockspace_t *lockspace)
171 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
174 log_debug("unmount flags %lx", ls->flags);
176 /* FIXME: serialize unmount and withdraw in case they
177 happen at once. Also, if unmount follows withdraw,
178 wait for withdraw to finish. */
180 if (test_bit(DFL_WITHDRAW, &ls->flags))
183 gdlm_kobject_release(ls);
184 dlm_release_lockspace(ls->dlm_lockspace, 2);
185 gdlm_release_threads(ls);
186 rv = gdlm_release_all_locks(ls);
188 log_info("gdlm_unmount: %d stray locks freed", rv);
193 static void gdlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid,
194 unsigned int message)
196 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
197 ls->recover_jid_done = jid;
198 kobject_uevent(&ls->kobj, KOBJ_CHANGE);
201 static void gdlm_others_may_mount(lm_lockspace_t *lockspace)
203 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
205 kobject_uevent(&ls->kobj, KOBJ_CHANGE);
208 /* Userspace gets the offline uevent, blocks new gfs locks on
209 other mounters, and lets us know (sets WITHDRAW flag). Then,
210 userspace leaves the mount group while we leave the lockspace. */
212 static void gdlm_withdraw(lm_lockspace_t *lockspace)
214 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
216 kobject_uevent(&ls->kobj, KOBJ_OFFLINE);
218 wait_event_interruptible(ls->wait_control,
219 test_bit(DFL_WITHDRAW, &ls->flags));
221 dlm_release_lockspace(ls->dlm_lockspace, 2);
222 gdlm_release_threads(ls);
223 gdlm_release_all_locks(ls);
224 gdlm_kobject_release(ls);
227 struct lm_lockops gdlm_ops = {
228 .lm_proto_name = "lock_dlm",
229 .lm_mount = gdlm_mount,
230 .lm_others_may_mount = gdlm_others_may_mount,
231 .lm_unmount = gdlm_unmount,
232 .lm_withdraw = gdlm_withdraw,
233 .lm_get_lock = gdlm_get_lock,
234 .lm_put_lock = gdlm_put_lock,
235 .lm_lock = gdlm_lock,
236 .lm_unlock = gdlm_unlock,
237 .lm_plock = gdlm_plock,
238 .lm_punlock = gdlm_punlock,
239 .lm_plock_get = gdlm_plock_get,
240 .lm_cancel = gdlm_cancel,
241 .lm_hold_lvb = gdlm_hold_lvb,
242 .lm_unhold_lvb = gdlm_unhold_lvb,
243 .lm_sync_lvb = gdlm_sync_lvb,
244 .lm_recovery_done = gdlm_recovery_done,
245 .lm_owner = THIS_MODULE,