Blame view
fs/nfs_common/grace.c
3.38 KB
09c434b8a treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
af558e33b nfsd: common grac... |
2 3 |
/* * Common code for control of lockd and nfsv4 grace periods. |
f77900296 lockd: move lockd... |
4 5 |
* * Transplanted from lockd code |
af558e33b nfsd: common grac... |
6 7 8 |
*/ #include <linux/module.h> |
db9c45534 LockD: manage gra... |
9 |
#include <net/net_namespace.h> |
f77900296 lockd: move lockd... |
10 11 |
#include <net/netns/generic.h> #include <linux/fs.h> |
db9c45534 LockD: manage gra... |
12 |
|
c7d03a00b netns: make struc... |
13 |
static unsigned int grace_net_id; |
af558e33b nfsd: common grac... |
14 15 16 17 |
static DEFINE_SPINLOCK(grace_lock); /** * locks_start_grace |
f77900296 lockd: move lockd... |
18 |
* @net: net namespace that this lock manager belongs to |
af558e33b nfsd: common grac... |
19 20 21 22 23 24 25 26 27 |
* @lm: who this grace period is for * * A grace period is a period during which locks should not be given * out. Currently grace periods are only enforced by the two lock * managers (lockd and nfsd), using the locks_in_grace() function to * check when they are in a grace period. * * This function is called to start a grace period. */ |
f77900296 lockd: move lockd... |
28 29 |
void locks_start_grace(struct net *net, struct lock_manager *lm) |
af558e33b nfsd: common grac... |
30 |
{ |
f77900296 lockd: move lockd... |
31 |
struct list_head *grace_list = net_generic(net, grace_net_id); |
db9c45534 LockD: manage gra... |
32 |
|
af558e33b nfsd: common grac... |
33 |
spin_lock(&grace_lock); |
81833de1a lockd: fix "list_... |
34 35 36 37 38 39 |
if (list_empty(&lm->list)) list_add(&lm->list, grace_list); else WARN(1, "double list_add attempt detected in net %x %s ", net->ns.inum, (net == &init_net) ? "(init_net)" : ""); |
af558e33b nfsd: common grac... |
40 41 42 43 44 45 |
spin_unlock(&grace_lock); } EXPORT_SYMBOL_GPL(locks_start_grace); /** * locks_end_grace |
f77900296 lockd: move lockd... |
46 |
* @net: net namespace that this lock manager belongs to |
af558e33b nfsd: common grac... |
47 48 49 50 51 52 53 54 |
* @lm: who this grace period is for * * Call this function to state that the given lock manager is ready to * resume regular locking. The grace period will not end until all lock * managers that called locks_start_grace() also call locks_end_grace(). * Note that callers count on it being safe to call this more than once, * and the second call should be a no-op. */ |
f77900296 lockd: move lockd... |
55 56 |
void locks_end_grace(struct lock_manager *lm) |
af558e33b nfsd: common grac... |
57 58 59 60 61 62 |
{ spin_lock(&grace_lock); list_del_init(&lm->list); spin_unlock(&grace_lock); } EXPORT_SYMBOL_GPL(locks_end_grace); |
003278e43 nfs_common: conve... |
63 |
static bool |
c87fb4a37 lockd: NLM grace ... |
64 |
__state_in_grace(struct net *net, bool open) |
af558e33b nfsd: common grac... |
65 |
{ |
f77900296 lockd: move lockd... |
66 |
struct list_head *grace_list = net_generic(net, grace_net_id); |
c87fb4a37 lockd: NLM grace ... |
67 |
struct lock_manager *lm; |
db9c45534 LockD: manage gra... |
68 |
|
c87fb4a37 lockd: NLM grace ... |
69 70 |
if (!open) return !list_empty(grace_list); |
2deeead49 nfs_common: need ... |
71 |
spin_lock(&grace_lock); |
c87fb4a37 lockd: NLM grace ... |
72 |
list_for_each_entry(lm, grace_list, list) { |
2deeead49 nfs_common: need ... |
73 74 |
if (lm->block_opens) { spin_unlock(&grace_lock); |
c87fb4a37 lockd: NLM grace ... |
75 |
return true; |
2deeead49 nfs_common: need ... |
76 |
} |
c87fb4a37 lockd: NLM grace ... |
77 |
} |
2deeead49 nfs_common: need ... |
78 |
spin_unlock(&grace_lock); |
c87fb4a37 lockd: NLM grace ... |
79 80 |
return false; } |
809d4fcf9 nfs_common: move ... |
81 82 83 84 85 86 87 |
/** * locks_in_grace * * Lock managers call this function to determine when it is OK for them * to answer ordinary lock requests, and when they should accept only * lock reclaims. */ |
003278e43 nfs_common: conve... |
88 |
bool locks_in_grace(struct net *net) |
c87fb4a37 lockd: NLM grace ... |
89 |
{ |
003278e43 nfs_common: conve... |
90 |
return __state_in_grace(net, false); |
af558e33b nfsd: common grac... |
91 92 |
} EXPORT_SYMBOL_GPL(locks_in_grace); |
f77900296 lockd: move lockd... |
93 |
|
003278e43 nfs_common: conve... |
94 |
bool opens_in_grace(struct net *net) |
c87fb4a37 lockd: NLM grace ... |
95 |
{ |
003278e43 nfs_common: conve... |
96 |
return __state_in_grace(net, true); |
c87fb4a37 lockd: NLM grace ... |
97 98 |
} EXPORT_SYMBOL_GPL(opens_in_grace); |
f77900296 lockd: move lockd... |
99 100 101 102 103 104 105 106 107 108 109 110 111 |
static int __net_init grace_init_net(struct net *net) { struct list_head *grace_list = net_generic(net, grace_net_id); INIT_LIST_HEAD(grace_list); return 0; } static void __net_exit grace_exit_net(struct net *net) { struct list_head *grace_list = net_generic(net, grace_net_id); |
b87228575 grace: replace BU... |
112 113 114 115 |
WARN_ONCE(!list_empty(grace_list), "net %x %s: grace_list is not empty ", net->ns.inum, __func__); |
f77900296 lockd: move lockd... |
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
} static struct pernet_operations grace_net_ops = { .init = grace_init_net, .exit = grace_exit_net, .id = &grace_net_id, .size = sizeof(struct list_head), }; static int __init init_grace(void) { return register_pernet_subsys(&grace_net_ops); } static void __exit exit_grace(void) { unregister_pernet_subsys(&grace_net_ops); } MODULE_AUTHOR("Jeff Layton <jlayton@primarydata.com>"); MODULE_LICENSE("GPL"); module_init(init_grace) module_exit(exit_grace) |