18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 48c2ecf20Sopenharmony_ci * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __GLOCK_DOT_H__ 88c2ecf20Sopenharmony_ci#define __GLOCK_DOT_H__ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/sched.h> 118c2ecf20Sopenharmony_ci#include <linux/parser.h> 128c2ecf20Sopenharmony_ci#include "incore.h" 138c2ecf20Sopenharmony_ci#include "util.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* Options for hostdata parser */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cienum { 188c2ecf20Sopenharmony_ci Opt_jid, 198c2ecf20Sopenharmony_ci Opt_id, 208c2ecf20Sopenharmony_ci Opt_first, 218c2ecf20Sopenharmony_ci Opt_nodir, 228c2ecf20Sopenharmony_ci Opt_err, 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* 268c2ecf20Sopenharmony_ci * lm_lockname types 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define LM_TYPE_RESERVED 0x00 308c2ecf20Sopenharmony_ci#define LM_TYPE_NONDISK 0x01 318c2ecf20Sopenharmony_ci#define LM_TYPE_INODE 0x02 328c2ecf20Sopenharmony_ci#define LM_TYPE_RGRP 0x03 338c2ecf20Sopenharmony_ci#define LM_TYPE_META 0x04 348c2ecf20Sopenharmony_ci#define LM_TYPE_IOPEN 0x05 358c2ecf20Sopenharmony_ci#define LM_TYPE_FLOCK 0x06 368c2ecf20Sopenharmony_ci#define LM_TYPE_PLOCK 0x07 378c2ecf20Sopenharmony_ci#define LM_TYPE_QUOTA 0x08 388c2ecf20Sopenharmony_ci#define LM_TYPE_JOURNAL 0x09 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * lm_lock() states 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * SHARED is compatible with SHARED, not with DEFERRED or EX. 448c2ecf20Sopenharmony_ci * DEFERRED is compatible with DEFERRED, not with SHARED or EX. 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define LM_ST_UNLOCKED 0 488c2ecf20Sopenharmony_ci#define LM_ST_EXCLUSIVE 1 498c2ecf20Sopenharmony_ci#define LM_ST_DEFERRED 2 508c2ecf20Sopenharmony_ci#define LM_ST_SHARED 3 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* 538c2ecf20Sopenharmony_ci * lm_lock() flags 548c2ecf20Sopenharmony_ci * 558c2ecf20Sopenharmony_ci * LM_FLAG_TRY 568c2ecf20Sopenharmony_ci * Don't wait to acquire the lock if it can't be granted immediately. 578c2ecf20Sopenharmony_ci * 588c2ecf20Sopenharmony_ci * LM_FLAG_TRY_1CB 598c2ecf20Sopenharmony_ci * Send one blocking callback if TRY is set and the lock is not granted. 608c2ecf20Sopenharmony_ci * 618c2ecf20Sopenharmony_ci * LM_FLAG_NOEXP 628c2ecf20Sopenharmony_ci * GFS sets this flag on lock requests it makes while doing journal recovery. 638c2ecf20Sopenharmony_ci * These special requests should not be blocked due to the recovery like 648c2ecf20Sopenharmony_ci * ordinary locks would be. 658c2ecf20Sopenharmony_ci * 668c2ecf20Sopenharmony_ci * LM_FLAG_ANY 678c2ecf20Sopenharmony_ci * A SHARED request may also be granted in DEFERRED, or a DEFERRED request may 688c2ecf20Sopenharmony_ci * also be granted in SHARED. The preferred state is whichever is compatible 698c2ecf20Sopenharmony_ci * with other granted locks, or the specified state if no other locks exist. 708c2ecf20Sopenharmony_ci * 718c2ecf20Sopenharmony_ci * LM_FLAG_PRIORITY 728c2ecf20Sopenharmony_ci * Override fairness considerations. Suppose a lock is held in a shared state 738c2ecf20Sopenharmony_ci * and there is a pending request for the deferred state. A shared lock 748c2ecf20Sopenharmony_ci * request with the priority flag would be allowed to bypass the deferred 758c2ecf20Sopenharmony_ci * request and directly join the other shared lock. A shared lock request 768c2ecf20Sopenharmony_ci * without the priority flag might be forced to wait until the deferred 778c2ecf20Sopenharmony_ci * requested had acquired and released the lock. 788c2ecf20Sopenharmony_ci */ 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#define LM_FLAG_TRY 0x0001 818c2ecf20Sopenharmony_ci#define LM_FLAG_TRY_1CB 0x0002 828c2ecf20Sopenharmony_ci#define LM_FLAG_NOEXP 0x0004 838c2ecf20Sopenharmony_ci#define LM_FLAG_ANY 0x0008 848c2ecf20Sopenharmony_ci#define LM_FLAG_PRIORITY 0x0010 858c2ecf20Sopenharmony_ci#define GL_ASYNC 0x0040 868c2ecf20Sopenharmony_ci#define GL_EXACT 0x0080 878c2ecf20Sopenharmony_ci#define GL_SKIP 0x0100 888c2ecf20Sopenharmony_ci#define GL_NOCACHE 0x0400 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* 918c2ecf20Sopenharmony_ci * lm_async_cb return flags 928c2ecf20Sopenharmony_ci * 938c2ecf20Sopenharmony_ci * LM_OUT_ST_MASK 948c2ecf20Sopenharmony_ci * Masks the lower two bits of lock state in the returned value. 958c2ecf20Sopenharmony_ci * 968c2ecf20Sopenharmony_ci * LM_OUT_CANCELED 978c2ecf20Sopenharmony_ci * The lock request was canceled. 988c2ecf20Sopenharmony_ci * 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci#define LM_OUT_ST_MASK 0x00000003 1028c2ecf20Sopenharmony_ci#define LM_OUT_CANCELED 0x00000008 1038c2ecf20Sopenharmony_ci#define LM_OUT_ERROR 0x00000004 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* 1068c2ecf20Sopenharmony_ci * lm_recovery_done() messages 1078c2ecf20Sopenharmony_ci */ 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci#define LM_RD_GAVEUP 308 1108c2ecf20Sopenharmony_ci#define LM_RD_SUCCESS 309 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci#define GLR_TRYFAILED 13 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci#define GL_GLOCK_MAX_HOLD (long)(HZ / 5) 1158c2ecf20Sopenharmony_ci#define GL_GLOCK_DFT_HOLD (long)(HZ / 5) 1168c2ecf20Sopenharmony_ci#define GL_GLOCK_MIN_HOLD (long)(10) 1178c2ecf20Sopenharmony_ci#define GL_GLOCK_HOLD_INCR (long)(HZ / 20) 1188c2ecf20Sopenharmony_ci#define GL_GLOCK_HOLD_DECR (long)(HZ / 40) 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistruct lm_lockops { 1218c2ecf20Sopenharmony_ci const char *lm_proto_name; 1228c2ecf20Sopenharmony_ci int (*lm_mount) (struct gfs2_sbd *sdp, const char *table); 1238c2ecf20Sopenharmony_ci void (*lm_first_done) (struct gfs2_sbd *sdp); 1248c2ecf20Sopenharmony_ci void (*lm_recovery_result) (struct gfs2_sbd *sdp, unsigned int jid, 1258c2ecf20Sopenharmony_ci unsigned int result); 1268c2ecf20Sopenharmony_ci void (*lm_unmount) (struct gfs2_sbd *sdp); 1278c2ecf20Sopenharmony_ci void (*lm_withdraw) (struct gfs2_sbd *sdp); 1288c2ecf20Sopenharmony_ci void (*lm_put_lock) (struct gfs2_glock *gl); 1298c2ecf20Sopenharmony_ci int (*lm_lock) (struct gfs2_glock *gl, unsigned int req_state, 1308c2ecf20Sopenharmony_ci unsigned int flags); 1318c2ecf20Sopenharmony_ci void (*lm_cancel) (struct gfs2_glock *gl); 1328c2ecf20Sopenharmony_ci const match_table_t *lm_tokens; 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ciextern struct workqueue_struct *gfs2_delete_workqueue; 1368c2ecf20Sopenharmony_cistatic inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci struct gfs2_holder *gh; 1398c2ecf20Sopenharmony_ci struct pid *pid; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci /* Look in glock's list of holders for one with current task as owner */ 1428c2ecf20Sopenharmony_ci spin_lock(&gl->gl_lockref.lock); 1438c2ecf20Sopenharmony_ci pid = task_pid(current); 1448c2ecf20Sopenharmony_ci list_for_each_entry(gh, &gl->gl_holders, gh_list) { 1458c2ecf20Sopenharmony_ci if (!test_bit(HIF_HOLDER, &gh->gh_iflags)) 1468c2ecf20Sopenharmony_ci break; 1478c2ecf20Sopenharmony_ci if (gh->gh_owner_pid == pid) 1488c2ecf20Sopenharmony_ci goto out; 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci gh = NULL; 1518c2ecf20Sopenharmony_ciout: 1528c2ecf20Sopenharmony_ci spin_unlock(&gl->gl_lockref.lock); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci return gh; 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic inline int gfs2_glock_is_held_excl(struct gfs2_glock *gl) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci return gl->gl_state == LM_ST_EXCLUSIVE; 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic inline int gfs2_glock_is_held_dfrd(struct gfs2_glock *gl) 1638c2ecf20Sopenharmony_ci{ 1648c2ecf20Sopenharmony_ci return gl->gl_state == LM_ST_DEFERRED; 1658c2ecf20Sopenharmony_ci} 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci return gl->gl_state == LM_ST_SHARED; 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistatic inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci if (gl->gl_ops->go_flags & GLOF_ASPACE) 1758c2ecf20Sopenharmony_ci return (struct address_space *)(gl + 1); 1768c2ecf20Sopenharmony_ci return NULL; 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ciextern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, 1808c2ecf20Sopenharmony_ci const struct gfs2_glock_operations *glops, 1818c2ecf20Sopenharmony_ci int create, struct gfs2_glock **glp); 1828c2ecf20Sopenharmony_ciextern void gfs2_glock_hold(struct gfs2_glock *gl); 1838c2ecf20Sopenharmony_ciextern void gfs2_glock_put(struct gfs2_glock *gl); 1848c2ecf20Sopenharmony_ciextern void gfs2_glock_queue_put(struct gfs2_glock *gl); 1858c2ecf20Sopenharmony_ciextern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, 1868c2ecf20Sopenharmony_ci u16 flags, struct gfs2_holder *gh); 1878c2ecf20Sopenharmony_ciextern void gfs2_holder_reinit(unsigned int state, u16 flags, 1888c2ecf20Sopenharmony_ci struct gfs2_holder *gh); 1898c2ecf20Sopenharmony_ciextern void gfs2_holder_uninit(struct gfs2_holder *gh); 1908c2ecf20Sopenharmony_ciextern int gfs2_glock_nq(struct gfs2_holder *gh); 1918c2ecf20Sopenharmony_ciextern int gfs2_glock_poll(struct gfs2_holder *gh); 1928c2ecf20Sopenharmony_ciextern int gfs2_glock_wait(struct gfs2_holder *gh); 1938c2ecf20Sopenharmony_ciextern int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs); 1948c2ecf20Sopenharmony_ciextern void gfs2_glock_dq(struct gfs2_holder *gh); 1958c2ecf20Sopenharmony_ciextern void gfs2_glock_dq_wait(struct gfs2_holder *gh); 1968c2ecf20Sopenharmony_ciextern void gfs2_glock_dq_uninit(struct gfs2_holder *gh); 1978c2ecf20Sopenharmony_ciextern int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, 1988c2ecf20Sopenharmony_ci const struct gfs2_glock_operations *glops, 1998c2ecf20Sopenharmony_ci unsigned int state, u16 flags, 2008c2ecf20Sopenharmony_ci struct gfs2_holder *gh); 2018c2ecf20Sopenharmony_ciextern int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); 2028c2ecf20Sopenharmony_ciextern void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); 2038c2ecf20Sopenharmony_ciextern void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl, 2048c2ecf20Sopenharmony_ci bool fsid); 2058c2ecf20Sopenharmony_ci#define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { \ 2068c2ecf20Sopenharmony_ci gfs2_dump_glock(NULL, gl, true); \ 2078c2ecf20Sopenharmony_ci BUG(); } } while(0) 2088c2ecf20Sopenharmony_ci#define gfs2_glock_assert_warn(gl, x) do { if (unlikely(!(x))) { \ 2098c2ecf20Sopenharmony_ci gfs2_dump_glock(NULL, gl, true); \ 2108c2ecf20Sopenharmony_ci gfs2_assert_warn((gl)->gl_name.ln_sbd, (x)); } } \ 2118c2ecf20Sopenharmony_ci while (0) 2128c2ecf20Sopenharmony_ci#define gfs2_glock_assert_withdraw(gl, x) do { if (unlikely(!(x))) { \ 2138c2ecf20Sopenharmony_ci gfs2_dump_glock(NULL, gl, true); \ 2148c2ecf20Sopenharmony_ci gfs2_assert_withdraw((gl)->gl_name.ln_sbd, (x)); } } \ 2158c2ecf20Sopenharmony_ci while (0) 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ciextern __printf(2, 3) 2188c2ecf20Sopenharmony_civoid gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci/** 2218c2ecf20Sopenharmony_ci * gfs2_glock_nq_init - initialize a holder and enqueue it on a glock 2228c2ecf20Sopenharmony_ci * @gl: the glock 2238c2ecf20Sopenharmony_ci * @state: the state we're requesting 2248c2ecf20Sopenharmony_ci * @flags: the modifier flags 2258c2ecf20Sopenharmony_ci * @gh: the holder structure 2268c2ecf20Sopenharmony_ci * 2278c2ecf20Sopenharmony_ci * Returns: 0, GLR_*, or errno 2288c2ecf20Sopenharmony_ci */ 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic inline int gfs2_glock_nq_init(struct gfs2_glock *gl, 2318c2ecf20Sopenharmony_ci unsigned int state, u16 flags, 2328c2ecf20Sopenharmony_ci struct gfs2_holder *gh) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci int error; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci gfs2_holder_init(gl, state, flags, gh); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci error = gfs2_glock_nq(gh); 2398c2ecf20Sopenharmony_ci if (error) 2408c2ecf20Sopenharmony_ci gfs2_holder_uninit(gh); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci return error; 2438c2ecf20Sopenharmony_ci} 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ciextern void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state); 2468c2ecf20Sopenharmony_ciextern void gfs2_glock_complete(struct gfs2_glock *gl, int ret); 2478c2ecf20Sopenharmony_ciextern bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay); 2488c2ecf20Sopenharmony_ciextern void gfs2_cancel_delete_work(struct gfs2_glock *gl); 2498c2ecf20Sopenharmony_ciextern bool gfs2_delete_work_queued(const struct gfs2_glock *gl); 2508c2ecf20Sopenharmony_ciextern void gfs2_flush_delete_work(struct gfs2_sbd *sdp); 2518c2ecf20Sopenharmony_ciextern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); 2528c2ecf20Sopenharmony_ciextern void gfs2_glock_finish_truncate(struct gfs2_inode *ip); 2538c2ecf20Sopenharmony_ciextern void gfs2_glock_thaw(struct gfs2_sbd *sdp); 2548c2ecf20Sopenharmony_ciextern void gfs2_glock_add_to_lru(struct gfs2_glock *gl); 2558c2ecf20Sopenharmony_ciextern void gfs2_glock_free(struct gfs2_glock *gl); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ciextern int __init gfs2_glock_init(void); 2588c2ecf20Sopenharmony_ciextern void gfs2_glock_exit(void); 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ciextern void gfs2_create_debugfs_file(struct gfs2_sbd *sdp); 2618c2ecf20Sopenharmony_ciextern void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp); 2628c2ecf20Sopenharmony_ciextern void gfs2_register_debugfs(void); 2638c2ecf20Sopenharmony_ciextern void gfs2_unregister_debugfs(void); 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ciextern const struct lm_lockops gfs2_dlm_ops; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_cistatic inline void gfs2_holder_mark_uninitialized(struct gfs2_holder *gh) 2688c2ecf20Sopenharmony_ci{ 2698c2ecf20Sopenharmony_ci gh->gh_gl = NULL; 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cistatic inline bool gfs2_holder_initialized(struct gfs2_holder *gh) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci return gh->gh_gl; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic inline bool gfs2_holder_queued(struct gfs2_holder *gh) 2788c2ecf20Sopenharmony_ci{ 2798c2ecf20Sopenharmony_ci return !list_empty(&gh->gh_list); 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci/** 2838c2ecf20Sopenharmony_ci * glock_set_object - set the gl_object field of a glock 2848c2ecf20Sopenharmony_ci * @gl: the glock 2858c2ecf20Sopenharmony_ci * @object: the object 2868c2ecf20Sopenharmony_ci */ 2878c2ecf20Sopenharmony_cistatic inline void glock_set_object(struct gfs2_glock *gl, void *object) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci spin_lock(&gl->gl_lockref.lock); 2908c2ecf20Sopenharmony_ci if (gfs2_assert_warn(gl->gl_name.ln_sbd, gl->gl_object == NULL)) 2918c2ecf20Sopenharmony_ci gfs2_dump_glock(NULL, gl, true); 2928c2ecf20Sopenharmony_ci gl->gl_object = object; 2938c2ecf20Sopenharmony_ci spin_unlock(&gl->gl_lockref.lock); 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/** 2978c2ecf20Sopenharmony_ci * glock_clear_object - clear the gl_object field of a glock 2988c2ecf20Sopenharmony_ci * @gl: the glock 2998c2ecf20Sopenharmony_ci * @object: the object 3008c2ecf20Sopenharmony_ci * 3018c2ecf20Sopenharmony_ci * I'd love to similarly add this: 3028c2ecf20Sopenharmony_ci * else if (gfs2_assert_warn(gl->gl_sbd, gl->gl_object == object)) 3038c2ecf20Sopenharmony_ci * gfs2_dump_glock(NULL, gl, true); 3048c2ecf20Sopenharmony_ci * Unfortunately, that's not possible because as soon as gfs2_delete_inode 3058c2ecf20Sopenharmony_ci * frees the block in the rgrp, another process can reassign it for an I_NEW 3068c2ecf20Sopenharmony_ci * inode in gfs2_create_inode because that calls new_inode, not gfs2_iget. 3078c2ecf20Sopenharmony_ci * That means gfs2_delete_inode may subsequently try to call this function 3088c2ecf20Sopenharmony_ci * for a glock that's already pointing to a brand new inode. If we clear the 3098c2ecf20Sopenharmony_ci * new inode's gl_object, we'll introduce metadata corruption. Function 3108c2ecf20Sopenharmony_ci * gfs2_delete_inode calls clear_inode which calls gfs2_clear_inode which also 3118c2ecf20Sopenharmony_ci * tries to clear gl_object, so it's more than just gfs2_delete_inode. 3128c2ecf20Sopenharmony_ci * 3138c2ecf20Sopenharmony_ci */ 3148c2ecf20Sopenharmony_cistatic inline void glock_clear_object(struct gfs2_glock *gl, void *object) 3158c2ecf20Sopenharmony_ci{ 3168c2ecf20Sopenharmony_ci spin_lock(&gl->gl_lockref.lock); 3178c2ecf20Sopenharmony_ci if (gl->gl_object == object) 3188c2ecf20Sopenharmony_ci gl->gl_object = NULL; 3198c2ecf20Sopenharmony_ci spin_unlock(&gl->gl_lockref.lock); 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ciextern void gfs2_inode_remember_delete(struct gfs2_glock *gl, u64 generation); 3238c2ecf20Sopenharmony_ciextern bool gfs2_inode_already_deleted(struct gfs2_glock *gl, u64 generation); 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci#endif /* __GLOCK_DOT_H__ */ 326