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, int *nodir)
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);
104 } else if (!strcmp(x, "nodir")) {
106 log_error("need argument to nodir");
110 sscanf(y, "%u", nodir);
113 log_error("unkonwn option: %s", x);
122 static int gdlm_mount(char *table_name, char *host_data,
123 lm_callback_t cb, lm_fsdata_t *fsdata,
124 unsigned int min_lvb_size, int flags,
125 struct lm_lockstruct *lockstruct,
126 struct kobject *fskobj)
129 int error = -ENOMEM, nodir = 0;
131 if (min_lvb_size > GDLM_LVB_SIZE)
134 ls = init_gdlm(cb, fsdata, flags, table_name);
138 error = make_args(ls, host_data, &nodir);
142 error = gdlm_init_threads(ls);
146 error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
148 nodir ? DLM_LSFL_NODIR : 0,
151 log_error("dlm_new_lockspace error %d", error);
155 error = gdlm_kobject_setup(ls, fskobj);
159 lockstruct->ls_jid = ls->jid;
160 lockstruct->ls_first = ls->first;
161 lockstruct->ls_lockspace = ls;
162 lockstruct->ls_ops = &gdlm_ops;
163 lockstruct->ls_flags = 0;
164 lockstruct->ls_lvb_size = GDLM_LVB_SIZE;
168 dlm_release_lockspace(ls->dlm_lockspace, 2);
170 gdlm_release_threads(ls);
177 static void gdlm_unmount(lm_lockspace_t *lockspace)
179 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
182 log_debug("unmount flags %lx", ls->flags);
184 /* FIXME: serialize unmount and withdraw in case they
185 happen at once. Also, if unmount follows withdraw,
186 wait for withdraw to finish. */
188 if (test_bit(DFL_WITHDRAW, &ls->flags))
191 gdlm_kobject_release(ls);
192 dlm_release_lockspace(ls->dlm_lockspace, 2);
193 gdlm_release_threads(ls);
194 rv = gdlm_release_all_locks(ls);
196 log_info("gdlm_unmount: %d stray locks freed", rv);
201 static void gdlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid,
202 unsigned int message)
204 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
205 ls->recover_jid_done = jid;
206 kobject_uevent(&ls->kobj, KOBJ_CHANGE);
209 static void gdlm_others_may_mount(lm_lockspace_t *lockspace)
211 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
213 kobject_uevent(&ls->kobj, KOBJ_CHANGE);
216 /* Userspace gets the offline uevent, blocks new gfs locks on
217 other mounters, and lets us know (sets WITHDRAW flag). Then,
218 userspace leaves the mount group while we leave the lockspace. */
220 static void gdlm_withdraw(lm_lockspace_t *lockspace)
222 struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
224 kobject_uevent(&ls->kobj, KOBJ_OFFLINE);
226 wait_event_interruptible(ls->wait_control,
227 test_bit(DFL_WITHDRAW, &ls->flags));
229 dlm_release_lockspace(ls->dlm_lockspace, 2);
230 gdlm_release_threads(ls);
231 gdlm_release_all_locks(ls);
232 gdlm_kobject_release(ls);
235 struct lm_lockops gdlm_ops = {
236 .lm_proto_name = "lock_dlm",
237 .lm_mount = gdlm_mount,
238 .lm_others_may_mount = gdlm_others_may_mount,
239 .lm_unmount = gdlm_unmount,
240 .lm_withdraw = gdlm_withdraw,
241 .lm_get_lock = gdlm_get_lock,
242 .lm_put_lock = gdlm_put_lock,
243 .lm_lock = gdlm_lock,
244 .lm_unlock = gdlm_unlock,
245 .lm_plock = gdlm_plock,
246 .lm_punlock = gdlm_punlock,
247 .lm_plock_get = gdlm_plock_get,
248 .lm_cancel = gdlm_cancel,
249 .lm_hold_lvb = gdlm_hold_lvb,
250 .lm_unhold_lvb = gdlm_unhold_lvb,
251 .lm_sync_lvb = gdlm_sync_lvb,
252 .lm_recovery_done = gdlm_recovery_done,
253 .lm_owner = THIS_MODULE,