/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU General Public License v.2. */ #ifndef LOCK_DLM_DOT_H #define LOCK_DLM_DOT_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../lm_interface.h" /* * Internally, we prefix things with gdlm_ and GDLM_ (for gfs-dlm) since a * prefix of lock_dlm_ gets awkward. Externally, GFS refers to this module * as "lock_dlm". */ #define GDLM_STRNAME_BYTES 24 #define GDLM_LVB_SIZE 32 #define GDLM_DROP_COUNT 50000 #define GDLM_DROP_PERIOD 60 #define GDLM_NAME_LEN 128 /* GFS uses 12 bytes to identify a resource (32 bit type + 64 bit number). We sprintf these numbers into a 24 byte string of hex values to make them human-readable (to make debugging simpler.) */ struct gdlm_strname { unsigned char name[GDLM_STRNAME_BYTES]; unsigned short namelen; }; enum { DFL_BLOCK_LOCKS = 0, DFL_SPECTATOR = 1, DFL_WITHDRAW = 2, }; struct gdlm_ls { uint32_t id; int jid; int first; int first_done; unsigned long flags; struct kobject kobj; char clustername[GDLM_NAME_LEN]; char fsname[GDLM_NAME_LEN]; int fsflags; dlm_lockspace_t *dlm_lockspace; lm_callback_t fscb; lm_fsdata_t *fsdata; int recover_jid; int recover_jid_done; spinlock_t async_lock; struct list_head complete; struct list_head blocking; struct list_head delayed; struct list_head submit; struct list_head all_locks; uint32_t all_locks_count; wait_queue_head_t wait_control; struct task_struct *thread1; struct task_struct *thread2; wait_queue_head_t thread_wait; unsigned long drop_time; int drop_locks_count; int drop_locks_period; }; enum { LFL_NOBLOCK = 0, LFL_NOCACHE = 1, LFL_DLM_UNLOCK = 2, LFL_DLM_CANCEL = 3, LFL_SYNC_LVB = 4, LFL_FORCE_PROMOTE = 5, LFL_REREQUEST = 6, LFL_ACTIVE = 7, LFL_INLOCK = 8, LFL_CANCEL = 9, LFL_NOBAST = 10, LFL_HEADQUE = 11, LFL_UNLOCK_DELETE = 12, }; struct gdlm_lock { struct gdlm_ls *ls; struct lm_lockname lockname; char *lvb; struct dlm_lksb lksb; int16_t cur; int16_t req; int16_t prev_req; uint32_t lkf; /* dlm flags DLM_LKF_ */ unsigned long flags; /* lock_dlm flags LFL_ */ int bast_mode; /* protected by async_lock */ struct completion ast_wait; struct list_head clist; /* complete */ struct list_head blist; /* blocking */ struct list_head delay_list; /* delayed */ struct list_head all_list; /* all locks for the fs */ struct gdlm_lock *hold_null; /* NL lock for hold_lvb */ }; #define gdlm_assert(assertion, fmt, args...) \ do { \ if (unlikely(!(assertion))) { \ printk(KERN_EMERG "lock_dlm: fatal assertion failed \"%s\"\n" \ "lock_dlm: " fmt "\n", \ #assertion, ##args); \ BUG(); \ } \ } while (0) #define log_print(lev, fmt, arg...) printk(lev "lock_dlm: " fmt "\n" , ## arg) #define log_info(fmt, arg...) log_print(KERN_INFO , fmt , ## arg) #define log_error(fmt, arg...) log_print(KERN_ERR , fmt , ## arg) #ifdef LOCK_DLM_LOG_DEBUG #define log_debug(fmt, arg...) log_print(KERN_DEBUG , fmt , ## arg) #else #define log_debug(fmt, arg...) #endif /* sysfs.c */ int gdlm_sysfs_init(void); void gdlm_sysfs_exit(void); int gdlm_kobject_setup(struct gdlm_ls *, struct kobject *); void gdlm_kobject_release(struct gdlm_ls *); /* thread.c */ int gdlm_init_threads(struct gdlm_ls *); void gdlm_release_threads(struct gdlm_ls *); /* lock.c */ int16_t gdlm_make_lmstate(int16_t); void gdlm_queue_delayed(struct gdlm_lock *); void gdlm_submit_delayed(struct gdlm_ls *); int gdlm_release_all_locks(struct gdlm_ls *); int gdlm_create_lp(struct gdlm_ls *, struct lm_lockname *, struct gdlm_lock **); void gdlm_delete_lp(struct gdlm_lock *); int gdlm_add_lvb(struct gdlm_lock *); void gdlm_del_lvb(struct gdlm_lock *); unsigned int gdlm_do_lock(struct gdlm_lock *, struct dlm_range *); unsigned int gdlm_do_unlock(struct gdlm_lock *); int gdlm_get_lock(lm_lockspace_t *, struct lm_lockname *, lm_lock_t **); void gdlm_put_lock(lm_lock_t *); unsigned int gdlm_lock(lm_lock_t *, unsigned int, unsigned int, unsigned int); unsigned int gdlm_unlock(lm_lock_t *, unsigned int); void gdlm_cancel(lm_lock_t *); int gdlm_hold_lvb(lm_lock_t *, char **); void gdlm_unhold_lvb(lm_lock_t *, char *); void gdlm_sync_lvb(lm_lock_t *, char *); /* plock.c */ int gdlm_plock_init(void); void gdlm_plock_exit(void); int gdlm_plock(lm_lockspace_t *, struct lm_lockname *, struct file *, int, struct file_lock *); int gdlm_plock_get(lm_lockspace_t *, struct lm_lockname *, struct file *, struct file_lock *); int gdlm_punlock(lm_lockspace_t *, struct lm_lockname *, struct file *, struct file_lock *); #endif