1b3b94faaSDavid Teigland /* 2b3b94faaSDavid Teigland * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 33a8a9a10SSteven Whitehouse * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4b3b94faaSDavid Teigland * 5b3b94faaSDavid Teigland * This copyrighted material is made available to anyone wishing to use, 6b3b94faaSDavid Teigland * modify, copy, or redistribute it subject to the terms and conditions 7e9fc2aa0SSteven Whitehouse * of the GNU General Public License version 2. 8b3b94faaSDavid Teigland */ 9b3b94faaSDavid Teigland 10b3b94faaSDavid Teigland #ifndef __GLOCK_DOT_H__ 11b3b94faaSDavid Teigland #define __GLOCK_DOT_H__ 12b3b94faaSDavid Teigland 13e8edc6e0SAlexey Dobriyan #include <linux/sched.h> 14*f057f6cdSSteven Whitehouse #include <linux/parser.h> 15f2f7ba52SSteven Whitehouse #include "incore.h" 16f2f7ba52SSteven Whitehouse 17*f057f6cdSSteven Whitehouse /* Options for hostdata parser */ 18*f057f6cdSSteven Whitehouse 19*f057f6cdSSteven Whitehouse enum { 20*f057f6cdSSteven Whitehouse Opt_jid, 21*f057f6cdSSteven Whitehouse Opt_id, 22*f057f6cdSSteven Whitehouse Opt_first, 23*f057f6cdSSteven Whitehouse Opt_nodir, 24*f057f6cdSSteven Whitehouse Opt_err, 25*f057f6cdSSteven Whitehouse }; 26*f057f6cdSSteven Whitehouse 27*f057f6cdSSteven Whitehouse /* 28*f057f6cdSSteven Whitehouse * lm_lockname types 29*f057f6cdSSteven Whitehouse */ 30*f057f6cdSSteven Whitehouse 31*f057f6cdSSteven Whitehouse #define LM_TYPE_RESERVED 0x00 32*f057f6cdSSteven Whitehouse #define LM_TYPE_NONDISK 0x01 33*f057f6cdSSteven Whitehouse #define LM_TYPE_INODE 0x02 34*f057f6cdSSteven Whitehouse #define LM_TYPE_RGRP 0x03 35*f057f6cdSSteven Whitehouse #define LM_TYPE_META 0x04 36*f057f6cdSSteven Whitehouse #define LM_TYPE_IOPEN 0x05 37*f057f6cdSSteven Whitehouse #define LM_TYPE_FLOCK 0x06 38*f057f6cdSSteven Whitehouse #define LM_TYPE_PLOCK 0x07 39*f057f6cdSSteven Whitehouse #define LM_TYPE_QUOTA 0x08 40*f057f6cdSSteven Whitehouse #define LM_TYPE_JOURNAL 0x09 41*f057f6cdSSteven Whitehouse 42*f057f6cdSSteven Whitehouse /* 43*f057f6cdSSteven Whitehouse * lm_lock() states 44*f057f6cdSSteven Whitehouse * 45*f057f6cdSSteven Whitehouse * SHARED is compatible with SHARED, not with DEFERRED or EX. 46*f057f6cdSSteven Whitehouse * DEFERRED is compatible with DEFERRED, not with SHARED or EX. 47*f057f6cdSSteven Whitehouse */ 48*f057f6cdSSteven Whitehouse 49*f057f6cdSSteven Whitehouse #define LM_ST_UNLOCKED 0 50*f057f6cdSSteven Whitehouse #define LM_ST_EXCLUSIVE 1 51*f057f6cdSSteven Whitehouse #define LM_ST_DEFERRED 2 52*f057f6cdSSteven Whitehouse #define LM_ST_SHARED 3 53*f057f6cdSSteven Whitehouse 54*f057f6cdSSteven Whitehouse /* 55*f057f6cdSSteven Whitehouse * lm_lock() flags 56*f057f6cdSSteven Whitehouse * 57*f057f6cdSSteven Whitehouse * LM_FLAG_TRY 58*f057f6cdSSteven Whitehouse * Don't wait to acquire the lock if it can't be granted immediately. 59*f057f6cdSSteven Whitehouse * 60*f057f6cdSSteven Whitehouse * LM_FLAG_TRY_1CB 61*f057f6cdSSteven Whitehouse * Send one blocking callback if TRY is set and the lock is not granted. 62*f057f6cdSSteven Whitehouse * 63*f057f6cdSSteven Whitehouse * LM_FLAG_NOEXP 64*f057f6cdSSteven Whitehouse * GFS sets this flag on lock requests it makes while doing journal recovery. 65*f057f6cdSSteven Whitehouse * These special requests should not be blocked due to the recovery like 66*f057f6cdSSteven Whitehouse * ordinary locks would be. 67*f057f6cdSSteven Whitehouse * 68*f057f6cdSSteven Whitehouse * LM_FLAG_ANY 69*f057f6cdSSteven Whitehouse * A SHARED request may also be granted in DEFERRED, or a DEFERRED request may 70*f057f6cdSSteven Whitehouse * also be granted in SHARED. The preferred state is whichever is compatible 71*f057f6cdSSteven Whitehouse * with other granted locks, or the specified state if no other locks exist. 72*f057f6cdSSteven Whitehouse * 73*f057f6cdSSteven Whitehouse * LM_FLAG_PRIORITY 74*f057f6cdSSteven Whitehouse * Override fairness considerations. Suppose a lock is held in a shared state 75*f057f6cdSSteven Whitehouse * and there is a pending request for the deferred state. A shared lock 76*f057f6cdSSteven Whitehouse * request with the priority flag would be allowed to bypass the deferred 77*f057f6cdSSteven Whitehouse * request and directly join the other shared lock. A shared lock request 78*f057f6cdSSteven Whitehouse * without the priority flag might be forced to wait until the deferred 79*f057f6cdSSteven Whitehouse * requested had acquired and released the lock. 80*f057f6cdSSteven Whitehouse */ 81*f057f6cdSSteven Whitehouse 82b3b94faaSDavid Teigland #define LM_FLAG_TRY 0x00000001 83b3b94faaSDavid Teigland #define LM_FLAG_TRY_1CB 0x00000002 84b3b94faaSDavid Teigland #define LM_FLAG_NOEXP 0x00000004 85b3b94faaSDavid Teigland #define LM_FLAG_ANY 0x00000008 86*f057f6cdSSteven Whitehouse #define LM_FLAG_PRIORITY 0x00000010 87*f057f6cdSSteven Whitehouse #define GL_ASYNC 0x00000040 88*f057f6cdSSteven Whitehouse #define GL_EXACT 0x00000080 89*f057f6cdSSteven Whitehouse #define GL_SKIP 0x00000100 90*f057f6cdSSteven Whitehouse #define GL_ATIME 0x00000200 91*f057f6cdSSteven Whitehouse #define GL_NOCACHE 0x00000400 92*f057f6cdSSteven Whitehouse 93*f057f6cdSSteven Whitehouse /* 94*f057f6cdSSteven Whitehouse * lm_lock() and lm_async_cb return flags 95*f057f6cdSSteven Whitehouse * 96*f057f6cdSSteven Whitehouse * LM_OUT_ST_MASK 97*f057f6cdSSteven Whitehouse * Masks the lower two bits of lock state in the returned value. 98*f057f6cdSSteven Whitehouse * 99*f057f6cdSSteven Whitehouse * LM_OUT_CANCELED 100*f057f6cdSSteven Whitehouse * The lock request was canceled. 101*f057f6cdSSteven Whitehouse * 102*f057f6cdSSteven Whitehouse * LM_OUT_ASYNC 103*f057f6cdSSteven Whitehouse * The result of the request will be returned in an LM_CB_ASYNC callback. 104*f057f6cdSSteven Whitehouse * 105*f057f6cdSSteven Whitehouse */ 106*f057f6cdSSteven Whitehouse 107*f057f6cdSSteven Whitehouse #define LM_OUT_ST_MASK 0x00000003 108*f057f6cdSSteven Whitehouse #define LM_OUT_CANCELED 0x00000008 109*f057f6cdSSteven Whitehouse #define LM_OUT_ASYNC 0x00000080 110*f057f6cdSSteven Whitehouse #define LM_OUT_ERROR 0x00000100 111*f057f6cdSSteven Whitehouse 112*f057f6cdSSteven Whitehouse /* 113*f057f6cdSSteven Whitehouse * lm_recovery_done() messages 114*f057f6cdSSteven Whitehouse */ 115*f057f6cdSSteven Whitehouse 116*f057f6cdSSteven Whitehouse #define LM_RD_GAVEUP 308 117*f057f6cdSSteven Whitehouse #define LM_RD_SUCCESS 309 118*f057f6cdSSteven Whitehouse 119*f057f6cdSSteven Whitehouse #define GLR_TRYFAILED 13 120*f057f6cdSSteven Whitehouse 121*f057f6cdSSteven Whitehouse struct lm_lockops { 122*f057f6cdSSteven Whitehouse const char *lm_proto_name; 123*f057f6cdSSteven Whitehouse int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname); 124*f057f6cdSSteven Whitehouse void (*lm_unmount) (struct gfs2_sbd *sdp); 125*f057f6cdSSteven Whitehouse void (*lm_withdraw) (struct gfs2_sbd *sdp); 126*f057f6cdSSteven Whitehouse void (*lm_put_lock) (struct kmem_cache *cachep, void *gl); 127*f057f6cdSSteven Whitehouse unsigned int (*lm_lock) (struct gfs2_glock *gl, 128*f057f6cdSSteven Whitehouse unsigned int req_state, unsigned int flags); 129*f057f6cdSSteven Whitehouse void (*lm_cancel) (struct gfs2_glock *gl); 130*f057f6cdSSteven Whitehouse const match_table_t *lm_tokens; 131*f057f6cdSSteven Whitehouse }; 132*f057f6cdSSteven Whitehouse 133*f057f6cdSSteven Whitehouse #define LM_FLAG_TRY 0x00000001 134*f057f6cdSSteven Whitehouse #define LM_FLAG_TRY_1CB 0x00000002 135*f057f6cdSSteven Whitehouse #define LM_FLAG_NOEXP 0x00000004 136*f057f6cdSSteven Whitehouse #define LM_FLAG_ANY 0x00000008 137*f057f6cdSSteven Whitehouse #define LM_FLAG_PRIORITY 0x00000010 138b3b94faaSDavid Teigland 139b3b94faaSDavid Teigland #define GL_ASYNC 0x00000040 140b3b94faaSDavid Teigland #define GL_EXACT 0x00000080 141b3b94faaSDavid Teigland #define GL_SKIP 0x00000100 142b3b94faaSDavid Teigland #define GL_NOCACHE 0x00000400 143b3b94faaSDavid Teigland 144b3b94faaSDavid Teigland #define GLR_TRYFAILED 13 145b3b94faaSDavid Teigland 1467afd88d9SSteven Whitehouse static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl) 147b3b94faaSDavid Teigland { 148b3b94faaSDavid Teigland struct gfs2_holder *gh; 149b1e058daSPavel Emelyanov struct pid *pid; 150b3b94faaSDavid Teigland 151b3b94faaSDavid Teigland /* Look in glock's list of holders for one with current task as owner */ 152b3b94faaSDavid Teigland spin_lock(&gl->gl_spin); 153b1e058daSPavel Emelyanov pid = task_pid(current); 154b3b94faaSDavid Teigland list_for_each_entry(gh, &gl->gl_holders, gh_list) { 1556802e340SSteven Whitehouse if (!test_bit(HIF_HOLDER, &gh->gh_iflags)) 1566802e340SSteven Whitehouse break; 1577afd88d9SSteven Whitehouse if (gh->gh_owner_pid == pid) 1587afd88d9SSteven Whitehouse goto out; 159b3b94faaSDavid Teigland } 1607afd88d9SSteven Whitehouse gh = NULL; 1617afd88d9SSteven Whitehouse out: 162b3b94faaSDavid Teigland spin_unlock(&gl->gl_spin); 163b3b94faaSDavid Teigland 1647afd88d9SSteven Whitehouse return gh; 165b3b94faaSDavid Teigland } 166b3b94faaSDavid Teigland 167b3b94faaSDavid Teigland static inline int gfs2_glock_is_held_excl(struct gfs2_glock *gl) 168b3b94faaSDavid Teigland { 16950299965SSteven Whitehouse return gl->gl_state == LM_ST_EXCLUSIVE; 170b3b94faaSDavid Teigland } 171b3b94faaSDavid Teigland 172b3b94faaSDavid Teigland static inline int gfs2_glock_is_held_dfrd(struct gfs2_glock *gl) 173b3b94faaSDavid Teigland { 17450299965SSteven Whitehouse return gl->gl_state == LM_ST_DEFERRED; 175b3b94faaSDavid Teigland } 176b3b94faaSDavid Teigland 177b3b94faaSDavid Teigland static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl) 178b3b94faaSDavid Teigland { 17950299965SSteven Whitehouse return gl->gl_state == LM_ST_SHARED; 180b3b94faaSDavid Teigland } 181b3b94faaSDavid Teigland 182b3b94faaSDavid Teigland static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl) 183b3b94faaSDavid Teigland { 184b3b94faaSDavid Teigland int ret; 185b3b94faaSDavid Teigland spin_lock(&gl->gl_spin); 1866802e340SSteven Whitehouse ret = test_bit(GLF_DEMOTE, &gl->gl_flags); 187b3b94faaSDavid Teigland spin_unlock(&gl->gl_spin); 188b3b94faaSDavid Teigland return ret; 189b3b94faaSDavid Teigland } 190b3b94faaSDavid Teigland 191b3b94faaSDavid Teigland int gfs2_glock_get(struct gfs2_sbd *sdp, 192cd915493SSteven Whitehouse u64 number, const struct gfs2_glock_operations *glops, 193b3b94faaSDavid Teigland int create, struct gfs2_glock **glp); 194b3b94faaSDavid Teigland int gfs2_glock_put(struct gfs2_glock *gl); 195190562bdSSteven Whitehouse void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags, 196b3b94faaSDavid Teigland struct gfs2_holder *gh); 197190562bdSSteven Whitehouse void gfs2_holder_reinit(unsigned int state, unsigned flags, 198190562bdSSteven Whitehouse struct gfs2_holder *gh); 199b3b94faaSDavid Teigland void gfs2_holder_uninit(struct gfs2_holder *gh); 200b3b94faaSDavid Teigland int gfs2_glock_nq(struct gfs2_holder *gh); 201b3b94faaSDavid Teigland int gfs2_glock_poll(struct gfs2_holder *gh); 202b3b94faaSDavid Teigland int gfs2_glock_wait(struct gfs2_holder *gh); 203b3b94faaSDavid Teigland void gfs2_glock_dq(struct gfs2_holder *gh); 204d93cfa98SAbhijith Das void gfs2_glock_dq_wait(struct gfs2_holder *gh); 205b3b94faaSDavid Teigland 206b3b94faaSDavid Teigland void gfs2_glock_dq_uninit(struct gfs2_holder *gh); 207b3b94faaSDavid Teigland int gfs2_glock_nq_num(struct gfs2_sbd *sdp, 208cd915493SSteven Whitehouse u64 number, const struct gfs2_glock_operations *glops, 209b3b94faaSDavid Teigland unsigned int state, int flags, struct gfs2_holder *gh); 210b3b94faaSDavid Teigland 211b3b94faaSDavid Teigland int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); 212b3b94faaSDavid Teigland void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); 213b3b94faaSDavid Teigland void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs); 2146802e340SSteven Whitehouse void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...); 215b3b94faaSDavid Teigland 216d0dc80dbSSteven Whitehouse /** 217d0dc80dbSSteven Whitehouse * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock 218d0dc80dbSSteven Whitehouse * @gl: the glock 219d0dc80dbSSteven Whitehouse * @state: the state we're requesting 220d0dc80dbSSteven Whitehouse * @flags: the modifier flags 221d0dc80dbSSteven Whitehouse * @gh: the holder structure 222d0dc80dbSSteven Whitehouse * 223d0dc80dbSSteven Whitehouse * Returns: 0, GLR_*, or errno 224d0dc80dbSSteven Whitehouse */ 225d0dc80dbSSteven Whitehouse 226d0dc80dbSSteven Whitehouse static inline int gfs2_glock_nq_init(struct gfs2_glock *gl, 227d0dc80dbSSteven Whitehouse unsigned int state, int flags, 228d0dc80dbSSteven Whitehouse struct gfs2_holder *gh) 229d0dc80dbSSteven Whitehouse { 230d0dc80dbSSteven Whitehouse int error; 231d0dc80dbSSteven Whitehouse 232d0dc80dbSSteven Whitehouse gfs2_holder_init(gl, state, flags, gh); 233d0dc80dbSSteven Whitehouse 234d0dc80dbSSteven Whitehouse error = gfs2_glock_nq(gh); 235d0dc80dbSSteven Whitehouse if (error) 236d0dc80dbSSteven Whitehouse gfs2_holder_uninit(gh); 237d0dc80dbSSteven Whitehouse 238d0dc80dbSSteven Whitehouse return error; 239d0dc80dbSSteven Whitehouse } 240d0dc80dbSSteven Whitehouse 241b3b94faaSDavid Teigland /* Lock Value Block functions */ 242b3b94faaSDavid Teigland 243b3b94faaSDavid Teigland int gfs2_lvb_hold(struct gfs2_glock *gl); 244b3b94faaSDavid Teigland void gfs2_lvb_unhold(struct gfs2_glock *gl); 245b3b94faaSDavid Teigland 246*f057f6cdSSteven Whitehouse void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state); 247*f057f6cdSSteven Whitehouse void gfs2_glock_complete(struct gfs2_glock *gl, int ret); 248b3b94faaSDavid Teigland void gfs2_reclaim_glock(struct gfs2_sbd *sdp); 249fefc03bfSSteven Whitehouse void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); 250813e0c46SSteven Whitehouse void gfs2_glock_finish_truncate(struct gfs2_inode *ip); 251*f057f6cdSSteven Whitehouse void gfs2_glock_thaw(struct gfs2_sbd *sdp); 252b3b94faaSDavid Teigland 25385d1da67SSteven Whitehouse int __init gfs2_glock_init(void); 2548fbbfd21SSteven Whitehouse void gfs2_glock_exit(void); 2558fbbfd21SSteven Whitehouse 2567c52b166SRobert Peterson int gfs2_create_debugfs_file(struct gfs2_sbd *sdp); 2577c52b166SRobert Peterson void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp); 2587c52b166SRobert Peterson int gfs2_register_debugfs(void); 2597c52b166SRobert Peterson void gfs2_unregister_debugfs(void); 26085d1da67SSteven Whitehouse 261*f057f6cdSSteven Whitehouse extern const struct lm_lockops gfs2_dlm_ops; 262*f057f6cdSSteven Whitehouse 263b3b94faaSDavid Teigland #endif /* __GLOCK_DOT_H__ */ 264