diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
| commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
| tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/lockd | |
| parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) | |
Patched in Tegra support.
Diffstat (limited to 'fs/lockd')
| -rw-r--r-- | fs/lockd/clnt4xdr.c | 12 | ||||
| -rw-r--r-- | fs/lockd/clntlock.c | 16 | ||||
| -rw-r--r-- | fs/lockd/clntproc.c | 17 | ||||
| -rw-r--r-- | fs/lockd/clntxdr.c | 20 | ||||
| -rw-r--r-- | fs/lockd/grace.c | 16 | ||||
| -rw-r--r-- | fs/lockd/host.c | 158 | ||||
| -rw-r--r-- | fs/lockd/mon.c | 109 | ||||
| -rw-r--r-- | fs/lockd/netns.h | 23 | ||||
| -rw-r--r-- | fs/lockd/svc.c | 284 | ||||
| -rw-r--r-- | fs/lockd/svc4proc.c | 14 | ||||
| -rw-r--r-- | fs/lockd/svclock.c | 79 | ||||
| -rw-r--r-- | fs/lockd/svcproc.c | 19 | ||||
| -rw-r--r-- | fs/lockd/svcsubs.c | 21 |
13 files changed, 279 insertions, 509 deletions
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c index 00ec0b9c94d..f848b52c67b 100644 --- a/fs/lockd/clnt4xdr.c +++ b/fs/lockd/clnt4xdr.c | |||
| @@ -64,6 +64,10 @@ static void nlm4_compute_offsets(const struct nlm_lock *lock, | |||
| 64 | { | 64 | { |
| 65 | const struct file_lock *fl = &lock->fl; | 65 | const struct file_lock *fl = &lock->fl; |
| 66 | 66 | ||
| 67 | BUG_ON(fl->fl_start > NLM4_OFFSET_MAX); | ||
| 68 | BUG_ON(fl->fl_end > NLM4_OFFSET_MAX && | ||
| 69 | fl->fl_end != OFFSET_MAX); | ||
| 70 | |||
| 67 | *l_offset = loff_t_to_s64(fl->fl_start); | 71 | *l_offset = loff_t_to_s64(fl->fl_start); |
| 68 | if (fl->fl_end == OFFSET_MAX) | 72 | if (fl->fl_end == OFFSET_MAX) |
| 69 | *l_len = 0; | 73 | *l_len = 0; |
| @@ -118,6 +122,7 @@ static void encode_netobj(struct xdr_stream *xdr, | |||
| 118 | { | 122 | { |
| 119 | __be32 *p; | 123 | __be32 *p; |
| 120 | 124 | ||
| 125 | BUG_ON(length > XDR_MAX_NETOBJ); | ||
| 121 | p = xdr_reserve_space(xdr, 4 + length); | 126 | p = xdr_reserve_space(xdr, 4 + length); |
| 122 | xdr_encode_opaque(p, data, length); | 127 | xdr_encode_opaque(p, data, length); |
| 123 | } | 128 | } |
| @@ -151,6 +156,7 @@ out_overflow: | |||
| 151 | static void encode_cookie(struct xdr_stream *xdr, | 156 | static void encode_cookie(struct xdr_stream *xdr, |
| 152 | const struct nlm_cookie *cookie) | 157 | const struct nlm_cookie *cookie) |
| 153 | { | 158 | { |
| 159 | BUG_ON(cookie->len > NLM_MAXCOOKIELEN); | ||
| 154 | encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); | 160 | encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); |
| 155 | } | 161 | } |
| 156 | 162 | ||
| @@ -192,6 +198,7 @@ out_overflow: | |||
| 192 | */ | 198 | */ |
| 193 | static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) | 199 | static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) |
| 194 | { | 200 | { |
| 201 | BUG_ON(fh->size > NFS3_FHSIZE); | ||
| 195 | encode_netobj(xdr, (u8 *)&fh->data, fh->size); | 202 | encode_netobj(xdr, (u8 *)&fh->data, fh->size); |
| 196 | } | 203 | } |
| 197 | 204 | ||
| @@ -234,7 +241,7 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) | |||
| 234 | p = xdr_inline_decode(xdr, 4); | 241 | p = xdr_inline_decode(xdr, 4); |
| 235 | if (unlikely(p == NULL)) | 242 | if (unlikely(p == NULL)) |
| 236 | goto out_overflow; | 243 | goto out_overflow; |
| 237 | if (unlikely(ntohl(*p) > ntohl(nlm4_failed))) | 244 | if (unlikely(*p > nlm4_failed)) |
| 238 | goto out_bad_xdr; | 245 | goto out_bad_xdr; |
| 239 | *stat = *p; | 246 | *stat = *p; |
| 240 | return 0; | 247 | return 0; |
| @@ -329,6 +336,7 @@ static void encode_caller_name(struct xdr_stream *xdr, const char *name) | |||
| 329 | u32 length = strlen(name); | 336 | u32 length = strlen(name); |
| 330 | __be32 *p; | 337 | __be32 *p; |
| 331 | 338 | ||
| 339 | BUG_ON(length > NLM_MAXSTRLEN); | ||
| 332 | p = xdr_reserve_space(xdr, 4 + length); | 340 | p = xdr_reserve_space(xdr, 4 + length); |
| 333 | xdr_encode_opaque(p, name, length); | 341 | xdr_encode_opaque(p, name, length); |
| 334 | } | 342 | } |
| @@ -590,7 +598,7 @@ static struct rpc_procinfo nlm4_procedures[] = { | |||
| 590 | PROC(GRANTED_RES, res, norep), | 598 | PROC(GRANTED_RES, res, norep), |
| 591 | }; | 599 | }; |
| 592 | 600 | ||
| 593 | const struct rpc_version nlm_version4 = { | 601 | struct rpc_version nlm_version4 = { |
| 594 | .number = 4, | 602 | .number = 4, |
| 595 | .nrprocs = ARRAY_SIZE(nlm4_procedures), | 603 | .nrprocs = ARRAY_SIZE(nlm4_procedures), |
| 596 | .procs = nlm4_procedures, | 604 | .procs = nlm4_procedures, |
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index ca0a0800144..8d4ea8351e3 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
| @@ -56,16 +56,15 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) | |||
| 56 | u32 nlm_version = (nlm_init->nfs_version == 2) ? 1 : 4; | 56 | u32 nlm_version = (nlm_init->nfs_version == 2) ? 1 : 4; |
| 57 | int status; | 57 | int status; |
| 58 | 58 | ||
| 59 | status = lockd_up(nlm_init->net); | 59 | status = lockd_up(); |
| 60 | if (status < 0) | 60 | if (status < 0) |
| 61 | return ERR_PTR(status); | 61 | return ERR_PTR(status); |
| 62 | 62 | ||
| 63 | host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, | 63 | host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, |
| 64 | nlm_init->protocol, nlm_version, | 64 | nlm_init->protocol, nlm_version, |
| 65 | nlm_init->hostname, nlm_init->noresvport, | 65 | nlm_init->hostname, nlm_init->noresvport); |
| 66 | nlm_init->net); | ||
| 67 | if (host == NULL) { | 66 | if (host == NULL) { |
| 68 | lockd_down(nlm_init->net); | 67 | lockd_down(); |
| 69 | return ERR_PTR(-ENOLCK); | 68 | return ERR_PTR(-ENOLCK); |
| 70 | } | 69 | } |
| 71 | 70 | ||
| @@ -80,10 +79,8 @@ EXPORT_SYMBOL_GPL(nlmclnt_init); | |||
| 80 | */ | 79 | */ |
| 81 | void nlmclnt_done(struct nlm_host *host) | 80 | void nlmclnt_done(struct nlm_host *host) |
| 82 | { | 81 | { |
| 83 | struct net *net = host->net; | ||
| 84 | |||
| 85 | nlmclnt_release_host(host); | 82 | nlmclnt_release_host(host); |
| 86 | lockd_down(net); | 83 | lockd_down(); |
| 87 | } | 84 | } |
| 88 | EXPORT_SYMBOL_GPL(nlmclnt_done); | 85 | EXPORT_SYMBOL_GPL(nlmclnt_done); |
| 89 | 86 | ||
| @@ -222,12 +219,11 @@ reclaimer(void *ptr) | |||
| 222 | struct nlm_wait *block; | 219 | struct nlm_wait *block; |
| 223 | struct file_lock *fl, *next; | 220 | struct file_lock *fl, *next; |
| 224 | u32 nsmstate; | 221 | u32 nsmstate; |
| 225 | struct net *net = host->net; | ||
| 226 | 222 | ||
| 227 | allow_signal(SIGKILL); | 223 | allow_signal(SIGKILL); |
| 228 | 224 | ||
| 229 | down_write(&host->h_rwsem); | 225 | down_write(&host->h_rwsem); |
| 230 | lockd_up(net); /* note: this cannot fail as lockd is already running */ | 226 | lockd_up(); /* note: this cannot fail as lockd is already running */ |
| 231 | 227 | ||
| 232 | dprintk("lockd: reclaiming locks for host %s\n", host->h_name); | 228 | dprintk("lockd: reclaiming locks for host %s\n", host->h_name); |
| 233 | 229 | ||
| @@ -278,6 +274,6 @@ restart: | |||
| 278 | 274 | ||
| 279 | /* Release host handle after use */ | 275 | /* Release host handle after use */ |
| 280 | nlmclnt_release_host(host); | 276 | nlmclnt_release_host(host); |
| 281 | lockd_down(net); | 277 | lockd_down(); |
| 282 | return 0; | 278 | return 0; |
| 283 | } | 279 | } |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 54f9e6ce043..8392cb85bd5 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
| @@ -141,7 +141,7 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) | |||
| 141 | 141 | ||
| 142 | static void nlmclnt_release_lockargs(struct nlm_rqst *req) | 142 | static void nlmclnt_release_lockargs(struct nlm_rqst *req) |
| 143 | { | 143 | { |
| 144 | WARN_ON_ONCE(req->a_args.lock.fl.fl_ops != NULL); | 144 | BUG_ON(req->a_args.lock.fl.fl_ops != NULL); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | /** | 147 | /** |
| @@ -156,16 +156,12 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl) | |||
| 156 | struct nlm_rqst *call; | 156 | struct nlm_rqst *call; |
| 157 | int status; | 157 | int status; |
| 158 | 158 | ||
| 159 | nlm_get_host(host); | ||
| 159 | call = nlm_alloc_call(host); | 160 | call = nlm_alloc_call(host); |
| 160 | if (call == NULL) | 161 | if (call == NULL) |
| 161 | return -ENOMEM; | 162 | return -ENOMEM; |
| 162 | 163 | ||
| 163 | nlmclnt_locks_init_private(fl, host); | 164 | nlmclnt_locks_init_private(fl, host); |
| 164 | if (!fl->fl_u.nfs_fl.owner) { | ||
| 165 | /* lockowner allocation has failed */ | ||
| 166 | nlmclnt_release_call(call); | ||
| 167 | return -ENOMEM; | ||
| 168 | } | ||
| 169 | /* Set up the argument struct */ | 165 | /* Set up the argument struct */ |
| 170 | nlmclnt_setlockargs(call, fl); | 166 | nlmclnt_setlockargs(call, fl); |
| 171 | 167 | ||
| @@ -189,6 +185,9 @@ EXPORT_SYMBOL_GPL(nlmclnt_proc); | |||
| 189 | 185 | ||
| 190 | /* | 186 | /* |
| 191 | * Allocate an NLM RPC call struct | 187 | * Allocate an NLM RPC call struct |
| 188 | * | ||
| 189 | * Note: the caller must hold a reference to host. In case of failure, | ||
| 190 | * this reference will be released. | ||
| 192 | */ | 191 | */ |
| 193 | struct nlm_rqst *nlm_alloc_call(struct nlm_host *host) | 192 | struct nlm_rqst *nlm_alloc_call(struct nlm_host *host) |
| 194 | { | 193 | { |
| @@ -200,7 +199,7 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host) | |||
| 200 | atomic_set(&call->a_count, 1); | 199 | atomic_set(&call->a_count, 1); |
| 201 | locks_init_lock(&call->a_args.lock.fl); | 200 | locks_init_lock(&call->a_args.lock.fl); |
| 202 | locks_init_lock(&call->a_res.lock.fl); | 201 | locks_init_lock(&call->a_res.lock.fl); |
| 203 | call->a_host = nlm_get_host(host); | 202 | call->a_host = host; |
| 204 | return call; | 203 | return call; |
| 205 | } | 204 | } |
| 206 | if (signalled()) | 205 | if (signalled()) |
| @@ -208,6 +207,7 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host) | |||
| 208 | printk("nlm_alloc_call: failed, waiting for memory\n"); | 207 | printk("nlm_alloc_call: failed, waiting for memory\n"); |
| 209 | schedule_timeout_interruptible(5*HZ); | 208 | schedule_timeout_interruptible(5*HZ); |
| 210 | } | 209 | } |
| 210 | nlmclnt_release_host(host); | ||
| 211 | return NULL; | 211 | return NULL; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| @@ -465,6 +465,7 @@ static const struct file_lock_operations nlmclnt_lock_ops = { | |||
| 465 | 465 | ||
| 466 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host) | 466 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host) |
| 467 | { | 467 | { |
| 468 | BUG_ON(fl->fl_ops != NULL); | ||
| 468 | fl->fl_u.nfs_fl.state = 0; | 469 | fl->fl_u.nfs_fl.state = 0; |
| 469 | fl->fl_u.nfs_fl.owner = nlm_find_lockowner(host, fl->fl_owner); | 470 | fl->fl_u.nfs_fl.owner = nlm_find_lockowner(host, fl->fl_owner); |
| 470 | INIT_LIST_HEAD(&fl->fl_u.nfs_fl.list); | 471 | INIT_LIST_HEAD(&fl->fl_u.nfs_fl.list); |
| @@ -749,7 +750,7 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl | |||
| 749 | dprintk("lockd: blocking lock attempt was interrupted by a signal.\n" | 750 | dprintk("lockd: blocking lock attempt was interrupted by a signal.\n" |
| 750 | " Attempting to cancel lock.\n"); | 751 | " Attempting to cancel lock.\n"); |
| 751 | 752 | ||
| 752 | req = nlm_alloc_call(host); | 753 | req = nlm_alloc_call(nlm_get_host(host)); |
| 753 | if (!req) | 754 | if (!req) |
| 754 | return -ENOMEM; | 755 | return -ENOMEM; |
| 755 | req->a_flags = RPC_TASK_ASYNC; | 756 | req->a_flags = RPC_TASK_ASYNC; |
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index 9a55797a1cd..180ac34feb9 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c | |||
| @@ -60,6 +60,10 @@ static void nlm_compute_offsets(const struct nlm_lock *lock, | |||
| 60 | { | 60 | { |
| 61 | const struct file_lock *fl = &lock->fl; | 61 | const struct file_lock *fl = &lock->fl; |
| 62 | 62 | ||
| 63 | BUG_ON(fl->fl_start > NLM_OFFSET_MAX); | ||
| 64 | BUG_ON(fl->fl_end > NLM_OFFSET_MAX && | ||
| 65 | fl->fl_end != OFFSET_MAX); | ||
| 66 | |||
| 63 | *l_offset = loff_t_to_s32(fl->fl_start); | 67 | *l_offset = loff_t_to_s32(fl->fl_start); |
| 64 | if (fl->fl_end == OFFSET_MAX) | 68 | if (fl->fl_end == OFFSET_MAX) |
| 65 | *l_len = 0; | 69 | *l_len = 0; |
| @@ -115,6 +119,7 @@ static void encode_netobj(struct xdr_stream *xdr, | |||
| 115 | { | 119 | { |
| 116 | __be32 *p; | 120 | __be32 *p; |
| 117 | 121 | ||
| 122 | BUG_ON(length > XDR_MAX_NETOBJ); | ||
| 118 | p = xdr_reserve_space(xdr, 4 + length); | 123 | p = xdr_reserve_space(xdr, 4 + length); |
| 119 | xdr_encode_opaque(p, data, length); | 124 | xdr_encode_opaque(p, data, length); |
| 120 | } | 125 | } |
| @@ -148,6 +153,7 @@ out_overflow: | |||
| 148 | static void encode_cookie(struct xdr_stream *xdr, | 153 | static void encode_cookie(struct xdr_stream *xdr, |
| 149 | const struct nlm_cookie *cookie) | 154 | const struct nlm_cookie *cookie) |
| 150 | { | 155 | { |
| 156 | BUG_ON(cookie->len > NLM_MAXCOOKIELEN); | ||
| 151 | encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); | 157 | encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); |
| 152 | } | 158 | } |
| 153 | 159 | ||
| @@ -189,6 +195,7 @@ out_overflow: | |||
| 189 | */ | 195 | */ |
| 190 | static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) | 196 | static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) |
| 191 | { | 197 | { |
| 198 | BUG_ON(fh->size != NFS2_FHSIZE); | ||
| 192 | encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE); | 199 | encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE); |
| 193 | } | 200 | } |
| 194 | 201 | ||
| @@ -216,7 +223,7 @@ static void encode_nlm_stat(struct xdr_stream *xdr, | |||
| 216 | { | 223 | { |
| 217 | __be32 *p; | 224 | __be32 *p; |
| 218 | 225 | ||
| 219 | WARN_ON_ONCE(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); | 226 | BUG_ON(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); |
| 220 | p = xdr_reserve_space(xdr, 4); | 227 | p = xdr_reserve_space(xdr, 4); |
| 221 | *p = stat; | 228 | *p = stat; |
| 222 | } | 229 | } |
| @@ -229,7 +236,7 @@ static int decode_nlm_stat(struct xdr_stream *xdr, | |||
| 229 | p = xdr_inline_decode(xdr, 4); | 236 | p = xdr_inline_decode(xdr, 4); |
| 230 | if (unlikely(p == NULL)) | 237 | if (unlikely(p == NULL)) |
| 231 | goto out_overflow; | 238 | goto out_overflow; |
| 232 | if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period))) | 239 | if (unlikely(*p > nlm_lck_denied_grace_period)) |
| 233 | goto out_enum; | 240 | goto out_enum; |
| 234 | *stat = *p; | 241 | *stat = *p; |
| 235 | return 0; | 242 | return 0; |
| @@ -323,6 +330,7 @@ static void encode_caller_name(struct xdr_stream *xdr, const char *name) | |||
| 323 | u32 length = strlen(name); | 330 | u32 length = strlen(name); |
| 324 | __be32 *p; | 331 | __be32 *p; |
| 325 | 332 | ||
| 333 | BUG_ON(length > NLM_MAXSTRLEN); | ||
| 326 | p = xdr_reserve_space(xdr, 4 + length); | 334 | p = xdr_reserve_space(xdr, 4 + length); |
| 327 | xdr_encode_opaque(p, name, length); | 335 | xdr_encode_opaque(p, name, length); |
| 328 | } | 336 | } |
| @@ -588,19 +596,19 @@ static struct rpc_procinfo nlm_procedures[] = { | |||
| 588 | PROC(GRANTED_RES, res, norep), | 596 | PROC(GRANTED_RES, res, norep), |
| 589 | }; | 597 | }; |
| 590 | 598 | ||
| 591 | static const struct rpc_version nlm_version1 = { | 599 | static struct rpc_version nlm_version1 = { |
| 592 | .number = 1, | 600 | .number = 1, |
| 593 | .nrprocs = ARRAY_SIZE(nlm_procedures), | 601 | .nrprocs = ARRAY_SIZE(nlm_procedures), |
| 594 | .procs = nlm_procedures, | 602 | .procs = nlm_procedures, |
| 595 | }; | 603 | }; |
| 596 | 604 | ||
| 597 | static const struct rpc_version nlm_version3 = { | 605 | static struct rpc_version nlm_version3 = { |
| 598 | .number = 3, | 606 | .number = 3, |
| 599 | .nrprocs = ARRAY_SIZE(nlm_procedures), | 607 | .nrprocs = ARRAY_SIZE(nlm_procedures), |
| 600 | .procs = nlm_procedures, | 608 | .procs = nlm_procedures, |
| 601 | }; | 609 | }; |
| 602 | 610 | ||
| 603 | static const struct rpc_version *nlm_versions[] = { | 611 | static struct rpc_version *nlm_versions[] = { |
| 604 | [1] = &nlm_version1, | 612 | [1] = &nlm_version1, |
| 605 | [3] = &nlm_version3, | 613 | [3] = &nlm_version3, |
| 606 | #ifdef CONFIG_LOCKD_V4 | 614 | #ifdef CONFIG_LOCKD_V4 |
| @@ -610,7 +618,7 @@ static const struct rpc_version *nlm_versions[] = { | |||
| 610 | 618 | ||
| 611 | static struct rpc_stat nlm_rpc_stats; | 619 | static struct rpc_stat nlm_rpc_stats; |
| 612 | 620 | ||
| 613 | const struct rpc_program nlm_program = { | 621 | struct rpc_program nlm_program = { |
| 614 | .name = "lockd", | 622 | .name = "lockd", |
| 615 | .number = NLM_PROGRAM, | 623 | .number = NLM_PROGRAM, |
| 616 | .nrvers = ARRAY_SIZE(nlm_versions), | 624 | .nrvers = ARRAY_SIZE(nlm_versions), |
diff --git a/fs/lockd/grace.c b/fs/lockd/grace.c index 6d1ee7204c8..183cc1f0af1 100644 --- a/fs/lockd/grace.c +++ b/fs/lockd/grace.c | |||
| @@ -4,10 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
| 6 | #include <linux/lockd/bind.h> | 6 | #include <linux/lockd/bind.h> |
| 7 | #include <net/net_namespace.h> | ||
| 8 | |||
| 9 | #include "netns.h" | ||
| 10 | 7 | ||
| 8 | static LIST_HEAD(grace_list); | ||
| 11 | static DEFINE_SPINLOCK(grace_lock); | 9 | static DEFINE_SPINLOCK(grace_lock); |
| 12 | 10 | ||
| 13 | /** | 11 | /** |
| @@ -21,12 +19,10 @@ static DEFINE_SPINLOCK(grace_lock); | |||
| 21 | * | 19 | * |
| 22 | * This function is called to start a grace period. | 20 | * This function is called to start a grace period. |
| 23 | */ | 21 | */ |
| 24 | void locks_start_grace(struct net *net, struct lock_manager *lm) | 22 | void locks_start_grace(struct lock_manager *lm) |
| 25 | { | 23 | { |
| 26 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 27 | |||
| 28 | spin_lock(&grace_lock); | 24 | spin_lock(&grace_lock); |
| 29 | list_add(&lm->list, &ln->grace_list); | 25 | list_add(&lm->list, &grace_list); |
| 30 | spin_unlock(&grace_lock); | 26 | spin_unlock(&grace_lock); |
| 31 | } | 27 | } |
| 32 | EXPORT_SYMBOL_GPL(locks_start_grace); | 28 | EXPORT_SYMBOL_GPL(locks_start_grace); |
| @@ -56,10 +52,8 @@ EXPORT_SYMBOL_GPL(locks_end_grace); | |||
| 56 | * to answer ordinary lock requests, and when they should accept only | 52 | * to answer ordinary lock requests, and when they should accept only |
| 57 | * lock reclaims. | 53 | * lock reclaims. |
| 58 | */ | 54 | */ |
| 59 | int locks_in_grace(struct net *net) | 55 | int locks_in_grace(void) |
| 60 | { | 56 | { |
| 61 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 57 | return !list_empty(&grace_list); |
| 62 | |||
| 63 | return !list_empty(&ln->grace_list); | ||
| 64 | } | 58 | } |
| 65 | EXPORT_SYMBOL_GPL(locks_in_grace); | 59 | EXPORT_SYMBOL_GPL(locks_in_grace); |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 0e17090c310..b7c99bfb3da 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
| @@ -17,12 +17,8 @@ | |||
| 17 | #include <linux/lockd/lockd.h> | 17 | #include <linux/lockd/lockd.h> |
| 18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
| 19 | 19 | ||
| 20 | #include <linux/sunrpc/svc_xprt.h> | ||
| 21 | |||
| 22 | #include <net/ipv6.h> | 20 | #include <net/ipv6.h> |
| 23 | 21 | ||
| 24 | #include "netns.h" | ||
| 25 | |||
| 26 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE | 22 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE |
| 27 | #define NLM_HOST_NRHASH 32 | 23 | #define NLM_HOST_NRHASH 32 |
| 28 | #define NLM_HOST_REBIND (60 * HZ) | 24 | #define NLM_HOST_REBIND (60 * HZ) |
| @@ -43,10 +39,11 @@ static struct hlist_head nlm_client_hosts[NLM_HOST_NRHASH]; | |||
| 43 | hlist_for_each_entry_safe((host), (pos), (next), \ | 39 | hlist_for_each_entry_safe((host), (pos), (next), \ |
| 44 | (chain), h_hash) | 40 | (chain), h_hash) |
| 45 | 41 | ||
| 42 | static unsigned long next_gc; | ||
| 46 | static unsigned long nrhosts; | 43 | static unsigned long nrhosts; |
| 47 | static DEFINE_MUTEX(nlm_host_mutex); | 44 | static DEFINE_MUTEX(nlm_host_mutex); |
| 48 | 45 | ||
| 49 | static void nlm_gc_hosts(struct net *net); | 46 | static void nlm_gc_hosts(void); |
| 50 | 47 | ||
| 51 | struct nlm_lookup_host_info { | 48 | struct nlm_lookup_host_info { |
| 52 | const int server; /* search for server|client */ | 49 | const int server; /* search for server|client */ |
| @@ -57,7 +54,6 @@ struct nlm_lookup_host_info { | |||
| 57 | const char *hostname; /* remote's hostname */ | 54 | const char *hostname; /* remote's hostname */ |
| 58 | const size_t hostname_len; /* it's length */ | 55 | const size_t hostname_len; /* it's length */ |
| 59 | const int noresvport; /* use non-priv port */ | 56 | const int noresvport; /* use non-priv port */ |
| 60 | struct net *net; /* network namespace to bind */ | ||
| 61 | }; | 57 | }; |
| 62 | 58 | ||
| 63 | /* | 59 | /* |
| @@ -159,7 +155,6 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, | |||
| 159 | INIT_LIST_HEAD(&host->h_reclaim); | 155 | INIT_LIST_HEAD(&host->h_reclaim); |
| 160 | host->h_nsmhandle = nsm; | 156 | host->h_nsmhandle = nsm; |
| 161 | host->h_addrbuf = nsm->sm_addrbuf; | 157 | host->h_addrbuf = nsm->sm_addrbuf; |
| 162 | host->net = ni->net; | ||
| 163 | 158 | ||
| 164 | out: | 159 | out: |
| 165 | return host; | 160 | return host; |
| @@ -173,10 +168,12 @@ out: | |||
| 173 | static void nlm_destroy_host_locked(struct nlm_host *host) | 168 | static void nlm_destroy_host_locked(struct nlm_host *host) |
| 174 | { | 169 | { |
| 175 | struct rpc_clnt *clnt; | 170 | struct rpc_clnt *clnt; |
| 176 | struct lockd_net *ln = net_generic(host->net, lockd_net_id); | ||
| 177 | 171 | ||
| 178 | dprintk("lockd: destroy host %s\n", host->h_name); | 172 | dprintk("lockd: destroy host %s\n", host->h_name); |
| 179 | 173 | ||
| 174 | BUG_ON(!list_empty(&host->h_lockowners)); | ||
| 175 | BUG_ON(atomic_read(&host->h_count)); | ||
| 176 | |||
| 180 | hlist_del_init(&host->h_hash); | 177 | hlist_del_init(&host->h_hash); |
| 181 | 178 | ||
| 182 | nsm_unmonitor(host); | 179 | nsm_unmonitor(host); |
| @@ -187,7 +184,6 @@ static void nlm_destroy_host_locked(struct nlm_host *host) | |||
| 187 | rpc_shutdown_client(clnt); | 184 | rpc_shutdown_client(clnt); |
| 188 | kfree(host); | 185 | kfree(host); |
| 189 | 186 | ||
| 190 | ln->nrhosts--; | ||
| 191 | nrhosts--; | 187 | nrhosts--; |
| 192 | } | 188 | } |
| 193 | 189 | ||
| @@ -210,8 +206,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
| 210 | const unsigned short protocol, | 206 | const unsigned short protocol, |
| 211 | const u32 version, | 207 | const u32 version, |
| 212 | const char *hostname, | 208 | const char *hostname, |
| 213 | int noresvport, | 209 | int noresvport) |
| 214 | struct net *net) | ||
| 215 | { | 210 | { |
| 216 | struct nlm_lookup_host_info ni = { | 211 | struct nlm_lookup_host_info ni = { |
| 217 | .server = 0, | 212 | .server = 0, |
| @@ -222,13 +217,11 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
| 222 | .hostname = hostname, | 217 | .hostname = hostname, |
| 223 | .hostname_len = strlen(hostname), | 218 | .hostname_len = strlen(hostname), |
| 224 | .noresvport = noresvport, | 219 | .noresvport = noresvport, |
| 225 | .net = net, | ||
| 226 | }; | 220 | }; |
| 227 | struct hlist_head *chain; | 221 | struct hlist_head *chain; |
| 228 | struct hlist_node *pos; | 222 | struct hlist_node *pos; |
| 229 | struct nlm_host *host; | 223 | struct nlm_host *host; |
| 230 | struct nsm_handle *nsm = NULL; | 224 | struct nsm_handle *nsm = NULL; |
| 231 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 232 | 225 | ||
| 233 | dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, | 226 | dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, |
| 234 | (hostname ? hostname : "<none>"), version, | 227 | (hostname ? hostname : "<none>"), version, |
| @@ -238,8 +231,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
| 238 | 231 | ||
| 239 | chain = &nlm_client_hosts[nlm_hash_address(sap)]; | 232 | chain = &nlm_client_hosts[nlm_hash_address(sap)]; |
| 240 | hlist_for_each_entry(host, pos, chain, h_hash) { | 233 | hlist_for_each_entry(host, pos, chain, h_hash) { |
| 241 | if (host->net != net) | ||
| 242 | continue; | ||
| 243 | if (!rpc_cmp_addr(nlm_addr(host), sap)) | 234 | if (!rpc_cmp_addr(nlm_addr(host), sap)) |
| 244 | continue; | 235 | continue; |
| 245 | 236 | ||
| @@ -263,7 +254,6 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
| 263 | goto out; | 254 | goto out; |
| 264 | 255 | ||
| 265 | hlist_add_head(&host->h_hash, chain); | 256 | hlist_add_head(&host->h_hash, chain); |
| 266 | ln->nrhosts++; | ||
| 267 | nrhosts++; | 257 | nrhosts++; |
| 268 | 258 | ||
| 269 | dprintk("lockd: %s created host %s (%s)\n", __func__, | 259 | dprintk("lockd: %s created host %s (%s)\n", __func__, |
| @@ -286,12 +276,13 @@ void nlmclnt_release_host(struct nlm_host *host) | |||
| 286 | 276 | ||
| 287 | dprintk("lockd: release client host %s\n", host->h_name); | 277 | dprintk("lockd: release client host %s\n", host->h_name); |
| 288 | 278 | ||
| 289 | WARN_ON_ONCE(host->h_server); | 279 | BUG_ON(atomic_read(&host->h_count) < 0); |
| 280 | BUG_ON(host->h_server); | ||
| 290 | 281 | ||
| 291 | if (atomic_dec_and_test(&host->h_count)) { | 282 | if (atomic_dec_and_test(&host->h_count)) { |
| 292 | WARN_ON_ONCE(!list_empty(&host->h_lockowners)); | 283 | BUG_ON(!list_empty(&host->h_lockowners)); |
| 293 | WARN_ON_ONCE(!list_empty(&host->h_granted)); | 284 | BUG_ON(!list_empty(&host->h_granted)); |
| 294 | WARN_ON_ONCE(!list_empty(&host->h_reclaim)); | 285 | BUG_ON(!list_empty(&host->h_reclaim)); |
| 295 | 286 | ||
| 296 | mutex_lock(&nlm_host_mutex); | 287 | mutex_lock(&nlm_host_mutex); |
| 297 | nlm_destroy_host_locked(host); | 288 | nlm_destroy_host_locked(host); |
| @@ -325,9 +316,14 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
| 325 | struct hlist_node *pos; | 316 | struct hlist_node *pos; |
| 326 | struct nlm_host *host = NULL; | 317 | struct nlm_host *host = NULL; |
| 327 | struct nsm_handle *nsm = NULL; | 318 | struct nsm_handle *nsm = NULL; |
| 328 | struct sockaddr *src_sap = svc_daddr(rqstp); | 319 | struct sockaddr_in sin = { |
| 329 | size_t src_len = rqstp->rq_daddrlen; | 320 | .sin_family = AF_INET, |
| 330 | struct net *net = SVC_NET(rqstp); | 321 | }; |
| 322 | struct sockaddr_in6 sin6 = { | ||
| 323 | .sin6_family = AF_INET6, | ||
| 324 | }; | ||
| 325 | struct sockaddr *src_sap; | ||
| 326 | size_t src_len = rqstp->rq_addrlen; | ||
| 331 | struct nlm_lookup_host_info ni = { | 327 | struct nlm_lookup_host_info ni = { |
| 332 | .server = 1, | 328 | .server = 1, |
| 333 | .sap = svc_addr(rqstp), | 329 | .sap = svc_addr(rqstp), |
| @@ -336,9 +332,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
| 336 | .version = rqstp->rq_vers, | 332 | .version = rqstp->rq_vers, |
| 337 | .hostname = hostname, | 333 | .hostname = hostname, |
| 338 | .hostname_len = hostname_len, | 334 | .hostname_len = hostname_len, |
| 339 | .net = net, | ||
| 340 | }; | 335 | }; |
| 341 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 342 | 336 | ||
| 343 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, | 337 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, |
| 344 | (int)hostname_len, hostname, rqstp->rq_vers, | 338 | (int)hostname_len, hostname, rqstp->rq_vers, |
| @@ -346,13 +340,26 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
| 346 | 340 | ||
| 347 | mutex_lock(&nlm_host_mutex); | 341 | mutex_lock(&nlm_host_mutex); |
| 348 | 342 | ||
| 349 | if (time_after_eq(jiffies, ln->next_gc)) | 343 | switch (ni.sap->sa_family) { |
| 350 | nlm_gc_hosts(net); | 344 | case AF_INET: |
| 345 | sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; | ||
| 346 | src_sap = (struct sockaddr *)&sin; | ||
| 347 | break; | ||
| 348 | case AF_INET6: | ||
| 349 | ipv6_addr_copy(&sin6.sin6_addr, &rqstp->rq_daddr.addr6); | ||
| 350 | src_sap = (struct sockaddr *)&sin6; | ||
| 351 | break; | ||
| 352 | default: | ||
| 353 | dprintk("lockd: %s failed; unrecognized address family\n", | ||
| 354 | __func__); | ||
| 355 | goto out; | ||
| 356 | } | ||
| 357 | |||
| 358 | if (time_after_eq(jiffies, next_gc)) | ||
| 359 | nlm_gc_hosts(); | ||
| 351 | 360 | ||
| 352 | chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; | 361 | chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; |
| 353 | hlist_for_each_entry(host, pos, chain, h_hash) { | 362 | hlist_for_each_entry(host, pos, chain, h_hash) { |
| 354 | if (host->net != net) | ||
| 355 | continue; | ||
| 356 | if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) | 363 | if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) |
| 357 | continue; | 364 | continue; |
| 358 | 365 | ||
| @@ -384,7 +391,6 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
| 384 | memcpy(nlm_srcaddr(host), src_sap, src_len); | 391 | memcpy(nlm_srcaddr(host), src_sap, src_len); |
| 385 | host->h_srcaddrlen = src_len; | 392 | host->h_srcaddrlen = src_len; |
| 386 | hlist_add_head(&host->h_hash, chain); | 393 | hlist_add_head(&host->h_hash, chain); |
| 387 | ln->nrhosts++; | ||
| 388 | nrhosts++; | 394 | nrhosts++; |
| 389 | 395 | ||
| 390 | dprintk("lockd: %s created host %s (%s)\n", | 396 | dprintk("lockd: %s created host %s (%s)\n", |
| @@ -408,7 +414,8 @@ void nlmsvc_release_host(struct nlm_host *host) | |||
| 408 | 414 | ||
| 409 | dprintk("lockd: release server host %s\n", host->h_name); | 415 | dprintk("lockd: release server host %s\n", host->h_name); |
| 410 | 416 | ||
| 411 | WARN_ON_ONCE(!host->h_server); | 417 | BUG_ON(atomic_read(&host->h_count) < 0); |
| 418 | BUG_ON(!host->h_server); | ||
| 412 | atomic_dec(&host->h_count); | 419 | atomic_dec(&host->h_count); |
| 413 | } | 420 | } |
| 414 | 421 | ||
| @@ -445,7 +452,7 @@ nlm_bind_host(struct nlm_host *host) | |||
| 445 | .to_retries = 5U, | 452 | .to_retries = 5U, |
| 446 | }; | 453 | }; |
| 447 | struct rpc_create_args args = { | 454 | struct rpc_create_args args = { |
| 448 | .net = host->net, | 455 | .net = &init_net, |
| 449 | .protocol = host->h_proto, | 456 | .protocol = host->h_proto, |
| 450 | .address = nlm_addr(host), | 457 | .address = nlm_addr(host), |
| 451 | .addrsize = host->h_addrlen, | 458 | .addrsize = host->h_addrlen, |
| @@ -567,49 +574,23 @@ void nlm_host_rebooted(const struct nlm_reboot *info) | |||
| 567 | nsm_release(nsm); | 574 | nsm_release(nsm); |
| 568 | } | 575 | } |
| 569 | 576 | ||
| 570 | static void nlm_complain_hosts(struct net *net) | 577 | /* |
| 571 | { | 578 | * Shut down the hosts module. |
| 572 | struct hlist_head *chain; | 579 | * Note that this routine is called only at server shutdown time. |
| 573 | struct hlist_node *pos; | 580 | */ |
| 574 | struct nlm_host *host; | ||
| 575 | |||
| 576 | if (net) { | ||
| 577 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 578 | |||
| 579 | if (ln->nrhosts == 0) | ||
| 580 | return; | ||
| 581 | printk(KERN_WARNING "lockd: couldn't shutdown host module for net %p!\n", net); | ||
| 582 | dprintk("lockd: %lu hosts left in net %p:\n", ln->nrhosts, net); | ||
| 583 | } else { | ||
| 584 | if (nrhosts == 0) | ||
| 585 | return; | ||
| 586 | printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); | ||
| 587 | dprintk("lockd: %lu hosts left:\n", nrhosts); | ||
| 588 | } | ||
| 589 | |||
| 590 | for_each_host(host, pos, chain, nlm_server_hosts) { | ||
| 591 | if (net && host->net != net) | ||
| 592 | continue; | ||
| 593 | dprintk(" %s (cnt %d use %d exp %ld net %p)\n", | ||
| 594 | host->h_name, atomic_read(&host->h_count), | ||
| 595 | host->h_inuse, host->h_expires, host->net); | ||
| 596 | } | ||
| 597 | } | ||
| 598 | |||
| 599 | void | 581 | void |
| 600 | nlm_shutdown_hosts_net(struct net *net) | 582 | nlm_shutdown_hosts(void) |
| 601 | { | 583 | { |
| 602 | struct hlist_head *chain; | 584 | struct hlist_head *chain; |
| 603 | struct hlist_node *pos; | 585 | struct hlist_node *pos; |
| 604 | struct nlm_host *host; | 586 | struct nlm_host *host; |
| 605 | 587 | ||
| 588 | dprintk("lockd: shutting down host module\n"); | ||
| 606 | mutex_lock(&nlm_host_mutex); | 589 | mutex_lock(&nlm_host_mutex); |
| 607 | 590 | ||
| 608 | /* First, make all hosts eligible for gc */ | 591 | /* First, make all hosts eligible for gc */ |
| 609 | dprintk("lockd: nuking all hosts in net %p...\n", net); | 592 | dprintk("lockd: nuking all hosts...\n"); |
| 610 | for_each_host(host, pos, chain, nlm_server_hosts) { | 593 | for_each_host(host, pos, chain, nlm_server_hosts) { |
| 611 | if (net && host->net != net) | ||
| 612 | continue; | ||
| 613 | host->h_expires = jiffies - 1; | 594 | host->h_expires = jiffies - 1; |
| 614 | if (host->h_rpcclnt) { | 595 | if (host->h_rpcclnt) { |
| 615 | rpc_shutdown_client(host->h_rpcclnt); | 596 | rpc_shutdown_client(host->h_rpcclnt); |
| @@ -618,21 +599,19 @@ nlm_shutdown_hosts_net(struct net *net) | |||
| 618 | } | 599 | } |
| 619 | 600 | ||
| 620 | /* Then, perform a garbage collection pass */ | 601 | /* Then, perform a garbage collection pass */ |
| 621 | nlm_gc_hosts(net); | 602 | nlm_gc_hosts(); |
| 622 | mutex_unlock(&nlm_host_mutex); | 603 | mutex_unlock(&nlm_host_mutex); |
| 623 | 604 | ||
| 624 | nlm_complain_hosts(net); | 605 | /* complain if any hosts are left */ |
| 625 | } | 606 | if (nrhosts != 0) { |
| 626 | 607 | printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); | |
| 627 | /* | 608 | dprintk("lockd: %lu hosts left:\n", nrhosts); |
| 628 | * Shut down the hosts module. | 609 | for_each_host(host, pos, chain, nlm_server_hosts) { |
| 629 | * Note that this routine is called only at server shutdown time. | 610 | dprintk(" %s (cnt %d use %d exp %ld)\n", |
| 630 | */ | 611 | host->h_name, atomic_read(&host->h_count), |
| 631 | void | 612 | host->h_inuse, host->h_expires); |
| 632 | nlm_shutdown_hosts(void) | 613 | } |
| 633 | { | 614 | } |
| 634 | dprintk("lockd: shutting down host module\n"); | ||
| 635 | nlm_shutdown_hosts_net(NULL); | ||
| 636 | } | 615 | } |
| 637 | 616 | ||
| 638 | /* | 617 | /* |
| @@ -641,39 +620,30 @@ nlm_shutdown_hosts(void) | |||
| 641 | * mark & sweep for resources held by remote clients. | 620 | * mark & sweep for resources held by remote clients. |
| 642 | */ | 621 | */ |
| 643 | static void | 622 | static void |
| 644 | nlm_gc_hosts(struct net *net) | 623 | nlm_gc_hosts(void) |
| 645 | { | 624 | { |
| 646 | struct hlist_head *chain; | 625 | struct hlist_head *chain; |
| 647 | struct hlist_node *pos, *next; | 626 | struct hlist_node *pos, *next; |
| 648 | struct nlm_host *host; | 627 | struct nlm_host *host; |
| 649 | 628 | ||
| 650 | dprintk("lockd: host garbage collection for net %p\n", net); | 629 | dprintk("lockd: host garbage collection\n"); |
| 651 | for_each_host(host, pos, chain, nlm_server_hosts) { | 630 | for_each_host(host, pos, chain, nlm_server_hosts) |
| 652 | if (net && host->net != net) | ||
| 653 | continue; | ||
| 654 | host->h_inuse = 0; | 631 | host->h_inuse = 0; |
| 655 | } | ||
| 656 | 632 | ||
| 657 | /* Mark all hosts that hold locks, blocks or shares */ | 633 | /* Mark all hosts that hold locks, blocks or shares */ |
| 658 | nlmsvc_mark_resources(net); | 634 | nlmsvc_mark_resources(); |
| 659 | 635 | ||
| 660 | for_each_host_safe(host, pos, next, chain, nlm_server_hosts) { | 636 | for_each_host_safe(host, pos, next, chain, nlm_server_hosts) { |
| 661 | if (net && host->net != net) | ||
| 662 | continue; | ||
| 663 | if (atomic_read(&host->h_count) || host->h_inuse | 637 | if (atomic_read(&host->h_count) || host->h_inuse |
| 664 | || time_before(jiffies, host->h_expires)) { | 638 | || time_before(jiffies, host->h_expires)) { |
| 665 | dprintk("nlm_gc_hosts skipping %s " | 639 | dprintk("nlm_gc_hosts skipping %s " |
| 666 | "(cnt %d use %d exp %ld net %p)\n", | 640 | "(cnt %d use %d exp %ld)\n", |
| 667 | host->h_name, atomic_read(&host->h_count), | 641 | host->h_name, atomic_read(&host->h_count), |
| 668 | host->h_inuse, host->h_expires, host->net); | 642 | host->h_inuse, host->h_expires); |
| 669 | continue; | 643 | continue; |
| 670 | } | 644 | } |
| 671 | nlm_destroy_host_locked(host); | 645 | nlm_destroy_host_locked(host); |
| 672 | } | 646 | } |
| 673 | 647 | ||
| 674 | if (net) { | 648 | next_gc = jiffies + NLM_HOST_COLLECT; |
| 675 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 676 | |||
| 677 | ln->next_gc = jiffies + NLM_HOST_COLLECT; | ||
| 678 | } | ||
| 679 | } | 649 | } |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 3c2cfc68363..23d7451b293 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
| 10 | #include <linux/utsname.h> | ||
| 10 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 11 | #include <linux/ktime.h> | 12 | #include <linux/ktime.h> |
| 12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| @@ -18,8 +19,6 @@ | |||
| 18 | 19 | ||
| 19 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
| 20 | 21 | ||
| 21 | #include "netns.h" | ||
| 22 | |||
| 23 | #define NLMDBG_FACILITY NLMDBG_MONITOR | 22 | #define NLMDBG_FACILITY NLMDBG_MONITOR |
| 24 | #define NSM_PROGRAM 100024 | 23 | #define NSM_PROGRAM 100024 |
| 25 | #define NSM_VERSION 1 | 24 | #define NSM_VERSION 1 |
| @@ -41,7 +40,6 @@ struct nsm_args { | |||
| 41 | u32 proc; | 40 | u32 proc; |
| 42 | 41 | ||
| 43 | char *mon_name; | 42 | char *mon_name; |
| 44 | char *nodename; | ||
| 45 | }; | 43 | }; |
| 46 | 44 | ||
| 47 | struct nsm_res { | 45 | struct nsm_res { |
| @@ -49,7 +47,7 @@ struct nsm_res { | |||
| 49 | u32 state; | 47 | u32 state; |
| 50 | }; | 48 | }; |
| 51 | 49 | ||
| 52 | static const struct rpc_program nsm_program; | 50 | static struct rpc_program nsm_program; |
| 53 | static LIST_HEAD(nsm_handles); | 51 | static LIST_HEAD(nsm_handles); |
| 54 | static DEFINE_SPINLOCK(nsm_lock); | 52 | static DEFINE_SPINLOCK(nsm_lock); |
| 55 | 53 | ||
| @@ -57,22 +55,22 @@ static DEFINE_SPINLOCK(nsm_lock); | |||
| 57 | * Local NSM state | 55 | * Local NSM state |
| 58 | */ | 56 | */ |
| 59 | u32 __read_mostly nsm_local_state; | 57 | u32 __read_mostly nsm_local_state; |
| 60 | bool __read_mostly nsm_use_hostnames; | 58 | int __read_mostly nsm_use_hostnames; |
| 61 | 59 | ||
| 62 | static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm) | 60 | static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm) |
| 63 | { | 61 | { |
| 64 | return (struct sockaddr *)&nsm->sm_addr; | 62 | return (struct sockaddr *)&nsm->sm_addr; |
| 65 | } | 63 | } |
| 66 | 64 | ||
| 67 | static struct rpc_clnt *nsm_create(struct net *net) | 65 | static struct rpc_clnt *nsm_create(void) |
| 68 | { | 66 | { |
| 69 | struct sockaddr_in sin = { | 67 | struct sockaddr_in sin = { |
| 70 | .sin_family = AF_INET, | 68 | .sin_family = AF_INET, |
| 71 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | 69 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), |
| 72 | }; | 70 | }; |
| 73 | struct rpc_create_args args = { | 71 | struct rpc_create_args args = { |
| 74 | .net = net, | 72 | .net = &init_net, |
| 75 | .protocol = XPRT_TRANSPORT_TCP, | 73 | .protocol = XPRT_TRANSPORT_UDP, |
| 76 | .address = (struct sockaddr *)&sin, | 74 | .address = (struct sockaddr *)&sin, |
| 77 | .addrsize = sizeof(sin), | 75 | .addrsize = sizeof(sin), |
| 78 | .servername = "rpc.statd", | 76 | .servername = "rpc.statd", |
| @@ -85,61 +83,9 @@ static struct rpc_clnt *nsm_create(struct net *net) | |||
| 85 | return rpc_create(&args); | 83 | return rpc_create(&args); |
| 86 | } | 84 | } |
| 87 | 85 | ||
| 88 | static struct rpc_clnt *nsm_client_set(struct lockd_net *ln, | 86 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res) |
| 89 | struct rpc_clnt *clnt) | ||
| 90 | { | ||
| 91 | spin_lock(&ln->nsm_clnt_lock); | ||
| 92 | if (ln->nsm_users == 0) { | ||
| 93 | if (clnt == NULL) | ||
| 94 | goto out; | ||
| 95 | ln->nsm_clnt = clnt; | ||
| 96 | } | ||
| 97 | clnt = ln->nsm_clnt; | ||
| 98 | ln->nsm_users++; | ||
| 99 | out: | ||
| 100 | spin_unlock(&ln->nsm_clnt_lock); | ||
| 101 | return clnt; | ||
| 102 | } | ||
| 103 | |||
| 104 | static struct rpc_clnt *nsm_client_get(struct net *net) | ||
| 105 | { | ||
| 106 | struct rpc_clnt *clnt, *new; | ||
| 107 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 108 | |||
| 109 | clnt = nsm_client_set(ln, NULL); | ||
| 110 | if (clnt != NULL) | ||
| 111 | goto out; | ||
| 112 | |||
| 113 | clnt = new = nsm_create(net); | ||
| 114 | if (IS_ERR(clnt)) | ||
| 115 | goto out; | ||
| 116 | |||
| 117 | clnt = nsm_client_set(ln, new); | ||
| 118 | if (clnt != new) | ||
| 119 | rpc_shutdown_client(new); | ||
| 120 | out: | ||
| 121 | return clnt; | ||
| 122 | } | ||
| 123 | |||
| 124 | static void nsm_client_put(struct net *net) | ||
| 125 | { | ||
| 126 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 127 | struct rpc_clnt *clnt = NULL; | ||
| 128 | |||
| 129 | spin_lock(&ln->nsm_clnt_lock); | ||
| 130 | ln->nsm_users--; | ||
| 131 | if (ln->nsm_users == 0) { | ||
| 132 | clnt = ln->nsm_clnt; | ||
| 133 | ln->nsm_clnt = NULL; | ||
| 134 | } | ||
| 135 | spin_unlock(&ln->nsm_clnt_lock); | ||
| 136 | if (clnt != NULL) | ||
| 137 | rpc_shutdown_client(clnt); | ||
| 138 | } | ||
| 139 | |||
| 140 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, | ||
| 141 | struct rpc_clnt *clnt) | ||
| 142 | { | 87 | { |
| 88 | struct rpc_clnt *clnt; | ||
| 143 | int status; | 89 | int status; |
| 144 | struct nsm_args args = { | 90 | struct nsm_args args = { |
| 145 | .priv = &nsm->sm_priv, | 91 | .priv = &nsm->sm_priv, |
| @@ -147,22 +93,31 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, | |||
| 147 | .vers = 3, | 93 | .vers = 3, |
| 148 | .proc = NLMPROC_NSM_NOTIFY, | 94 | .proc = NLMPROC_NSM_NOTIFY, |
| 149 | .mon_name = nsm->sm_mon_name, | 95 | .mon_name = nsm->sm_mon_name, |
| 150 | .nodename = clnt->cl_nodename, | ||
| 151 | }; | 96 | }; |
| 152 | struct rpc_message msg = { | 97 | struct rpc_message msg = { |
| 153 | .rpc_argp = &args, | 98 | .rpc_argp = &args, |
| 154 | .rpc_resp = res, | 99 | .rpc_resp = res, |
| 155 | }; | 100 | }; |
| 156 | 101 | ||
| 102 | clnt = nsm_create(); | ||
| 103 | if (IS_ERR(clnt)) { | ||
| 104 | status = PTR_ERR(clnt); | ||
| 105 | dprintk("lockd: failed to create NSM upcall transport, " | ||
| 106 | "status=%d\n", status); | ||
| 107 | goto out; | ||
| 108 | } | ||
| 109 | |||
| 157 | memset(res, 0, sizeof(*res)); | 110 | memset(res, 0, sizeof(*res)); |
| 158 | 111 | ||
| 159 | msg.rpc_proc = &clnt->cl_procinfo[proc]; | 112 | msg.rpc_proc = &clnt->cl_procinfo[proc]; |
| 160 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN); | 113 | status = rpc_call_sync(clnt, &msg, 0); |
| 161 | if (status < 0) | 114 | if (status < 0) |
| 162 | dprintk("lockd: NSM upcall RPC failed, status=%d\n", | 115 | dprintk("lockd: NSM upcall RPC failed, status=%d\n", |
| 163 | status); | 116 | status); |
| 164 | else | 117 | else |
| 165 | status = 0; | 118 | status = 0; |
| 119 | rpc_shutdown_client(clnt); | ||
| 120 | out: | ||
| 166 | return status; | 121 | return status; |
| 167 | } | 122 | } |
| 168 | 123 | ||
| @@ -182,7 +137,6 @@ int nsm_monitor(const struct nlm_host *host) | |||
| 182 | struct nsm_handle *nsm = host->h_nsmhandle; | 137 | struct nsm_handle *nsm = host->h_nsmhandle; |
| 183 | struct nsm_res res; | 138 | struct nsm_res res; |
| 184 | int status; | 139 | int status; |
| 185 | struct rpc_clnt *clnt; | ||
| 186 | 140 | ||
| 187 | dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); | 141 | dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); |
| 188 | 142 | ||
| @@ -195,15 +149,7 @@ int nsm_monitor(const struct nlm_host *host) | |||
| 195 | */ | 149 | */ |
| 196 | nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; | 150 | nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; |
| 197 | 151 | ||
| 198 | clnt = nsm_client_get(host->net); | 152 | status = nsm_mon_unmon(nsm, NSMPROC_MON, &res); |
| 199 | if (IS_ERR(clnt)) { | ||
| 200 | status = PTR_ERR(clnt); | ||
| 201 | dprintk("lockd: failed to create NSM upcall transport, " | ||
| 202 | "status=%d, net=%p\n", status, host->net); | ||
| 203 | return status; | ||
| 204 | } | ||
| 205 | |||
| 206 | status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt); | ||
| 207 | if (unlikely(res.status != 0)) | 153 | if (unlikely(res.status != 0)) |
| 208 | status = -EIO; | 154 | status = -EIO; |
| 209 | if (unlikely(status < 0)) { | 155 | if (unlikely(status < 0)) { |
| @@ -235,11 +181,9 @@ void nsm_unmonitor(const struct nlm_host *host) | |||
| 235 | 181 | ||
| 236 | if (atomic_read(&nsm->sm_count) == 1 | 182 | if (atomic_read(&nsm->sm_count) == 1 |
| 237 | && nsm->sm_monitored && !nsm->sm_sticky) { | 183 | && nsm->sm_monitored && !nsm->sm_sticky) { |
| 238 | struct lockd_net *ln = net_generic(host->net, lockd_net_id); | ||
| 239 | |||
| 240 | dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); | 184 | dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); |
| 241 | 185 | ||
| 242 | status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt); | 186 | status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res); |
| 243 | if (res.status != 0) | 187 | if (res.status != 0) |
| 244 | status = -EIO; | 188 | status = -EIO; |
| 245 | if (status < 0) | 189 | if (status < 0) |
| @@ -247,8 +191,6 @@ void nsm_unmonitor(const struct nlm_host *host) | |||
| 247 | nsm->sm_name); | 191 | nsm->sm_name); |
| 248 | else | 192 | else |
| 249 | nsm->sm_monitored = 0; | 193 | nsm->sm_monitored = 0; |
| 250 | |||
| 251 | nsm_client_put(host->net); | ||
| 252 | } | 194 | } |
| 253 | } | 195 | } |
| 254 | 196 | ||
| @@ -464,6 +406,7 @@ static void encode_nsm_string(struct xdr_stream *xdr, const char *string) | |||
| 464 | const u32 len = strlen(string); | 406 | const u32 len = strlen(string); |
| 465 | __be32 *p; | 407 | __be32 *p; |
| 466 | 408 | ||
| 409 | BUG_ON(len > SM_MAXSTRLEN); | ||
| 467 | p = xdr_reserve_space(xdr, 4 + len); | 410 | p = xdr_reserve_space(xdr, 4 + len); |
| 468 | xdr_encode_opaque(p, string, len); | 411 | xdr_encode_opaque(p, string, len); |
| 469 | } | 412 | } |
| @@ -486,7 +429,7 @@ static void encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp) | |||
| 486 | { | 429 | { |
| 487 | __be32 *p; | 430 | __be32 *p; |
| 488 | 431 | ||
| 489 | encode_nsm_string(xdr, argp->nodename); | 432 | encode_nsm_string(xdr, utsname()->nodename); |
| 490 | p = xdr_reserve_space(xdr, 4 + 4 + 4); | 433 | p = xdr_reserve_space(xdr, 4 + 4 + 4); |
| 491 | *p++ = cpu_to_be32(argp->prog); | 434 | *p++ = cpu_to_be32(argp->prog); |
| 492 | *p++ = cpu_to_be32(argp->vers); | 435 | *p++ = cpu_to_be32(argp->vers); |
| @@ -591,19 +534,19 @@ static struct rpc_procinfo nsm_procedures[] = { | |||
| 591 | }, | 534 | }, |
| 592 | }; | 535 | }; |
| 593 | 536 | ||
| 594 | static const struct rpc_version nsm_version1 = { | 537 | static struct rpc_version nsm_version1 = { |
| 595 | .number = 1, | 538 | .number = 1, |
| 596 | .nrprocs = ARRAY_SIZE(nsm_procedures), | 539 | .nrprocs = ARRAY_SIZE(nsm_procedures), |
| 597 | .procs = nsm_procedures | 540 | .procs = nsm_procedures |
| 598 | }; | 541 | }; |
| 599 | 542 | ||
| 600 | static const struct rpc_version *nsm_version[] = { | 543 | static struct rpc_version * nsm_version[] = { |
| 601 | [1] = &nsm_version1, | 544 | [1] = &nsm_version1, |
| 602 | }; | 545 | }; |
| 603 | 546 | ||
| 604 | static struct rpc_stat nsm_stats; | 547 | static struct rpc_stat nsm_stats; |
| 605 | 548 | ||
| 606 | static const struct rpc_program nsm_program = { | 549 | static struct rpc_program nsm_program = { |
| 607 | .name = "statd", | 550 | .name = "statd", |
| 608 | .number = NSM_PROGRAM, | 551 | .number = NSM_PROGRAM, |
| 609 | .nrvers = ARRAY_SIZE(nsm_version), | 552 | .nrvers = ARRAY_SIZE(nsm_version), |
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h deleted file mode 100644 index 5010b55628b..00000000000 --- a/fs/lockd/netns.h +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | #ifndef __LOCKD_NETNS_H__ | ||
| 2 | #define __LOCKD_NETNS_H__ | ||
| 3 | |||
| 4 | #include <linux/fs.h> | ||
| 5 | #include <net/netns/generic.h> | ||
| 6 | |||
| 7 | struct lockd_net { | ||
| 8 | unsigned int nlmsvc_users; | ||
| 9 | unsigned long next_gc; | ||
| 10 | unsigned long nrhosts; | ||
| 11 | |||
| 12 | struct delayed_work grace_period_end; | ||
| 13 | struct lock_manager lockd_manager; | ||
| 14 | struct list_head grace_list; | ||
| 15 | |||
| 16 | spinlock_t nsm_clnt_lock; | ||
| 17 | unsigned int nsm_users; | ||
| 18 | struct rpc_clnt *nsm_clnt; | ||
| 19 | }; | ||
| 20 | |||
| 21 | extern int lockd_net_id; | ||
| 22 | |||
| 23 | #endif | ||
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index a2aa97d4567..abfff9d7979 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
| @@ -35,8 +35,6 @@ | |||
| 35 | #include <linux/lockd/lockd.h> | 35 | #include <linux/lockd/lockd.h> |
| 36 | #include <linux/nfs.h> | 36 | #include <linux/nfs.h> |
| 37 | 37 | ||
| 38 | #include "netns.h" | ||
| 39 | |||
| 40 | #define NLMDBG_FACILITY NLMDBG_SVC | 38 | #define NLMDBG_FACILITY NLMDBG_SVC |
| 41 | #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) | 39 | #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) |
| 42 | #define ALLOWED_SIGS (sigmask(SIGKILL)) | 40 | #define ALLOWED_SIGS (sigmask(SIGKILL)) |
| @@ -52,8 +50,6 @@ static struct task_struct *nlmsvc_task; | |||
| 52 | static struct svc_rqst *nlmsvc_rqst; | 50 | static struct svc_rqst *nlmsvc_rqst; |
| 53 | unsigned long nlmsvc_timeout; | 51 | unsigned long nlmsvc_timeout; |
| 54 | 52 | ||
| 55 | int lockd_net_id; | ||
| 56 | |||
| 57 | /* | 53 | /* |
| 58 | * These can be set at insmod time (useful for NFS as root filesystem), | 54 | * These can be set at insmod time (useful for NFS as root filesystem), |
| 59 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 | 55 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 |
| @@ -87,36 +83,32 @@ static unsigned long get_lockd_grace_period(void) | |||
| 87 | return nlm_timeout * 5 * HZ; | 83 | return nlm_timeout * 5 * HZ; |
| 88 | } | 84 | } |
| 89 | 85 | ||
| 90 | static void grace_ender(struct work_struct *grace) | 86 | static struct lock_manager lockd_manager = { |
| 91 | { | 87 | }; |
| 92 | struct delayed_work *dwork = container_of(grace, struct delayed_work, | ||
| 93 | work); | ||
| 94 | struct lockd_net *ln = container_of(dwork, struct lockd_net, | ||
| 95 | grace_period_end); | ||
| 96 | 88 | ||
| 97 | locks_end_grace(&ln->lockd_manager); | 89 | static void grace_ender(struct work_struct *not_used) |
| 90 | { | ||
| 91 | locks_end_grace(&lockd_manager); | ||
| 98 | } | 92 | } |
| 99 | 93 | ||
| 100 | static void set_grace_period(struct net *net) | 94 | static DECLARE_DELAYED_WORK(grace_period_end, grace_ender); |
| 95 | |||
| 96 | static void set_grace_period(void) | ||
| 101 | { | 97 | { |
| 102 | unsigned long grace_period = get_lockd_grace_period(); | 98 | unsigned long grace_period = get_lockd_grace_period(); |
| 103 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 104 | 99 | ||
| 105 | locks_start_grace(net, &ln->lockd_manager); | 100 | locks_start_grace(&lockd_manager); |
| 106 | cancel_delayed_work_sync(&ln->grace_period_end); | 101 | cancel_delayed_work_sync(&grace_period_end); |
| 107 | schedule_delayed_work(&ln->grace_period_end, grace_period); | 102 | schedule_delayed_work(&grace_period_end, grace_period); |
| 108 | } | 103 | } |
| 109 | 104 | ||
| 110 | static void restart_grace(void) | 105 | static void restart_grace(void) |
| 111 | { | 106 | { |
| 112 | if (nlmsvc_ops) { | 107 | if (nlmsvc_ops) { |
| 113 | struct net *net = &init_net; | 108 | cancel_delayed_work_sync(&grace_period_end); |
| 114 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 109 | locks_end_grace(&lockd_manager); |
| 115 | |||
| 116 | cancel_delayed_work_sync(&ln->grace_period_end); | ||
| 117 | locks_end_grace(&ln->lockd_manager); | ||
| 118 | nlmsvc_invalidate_all(); | 110 | nlmsvc_invalidate_all(); |
| 119 | set_grace_period(net); | 111 | set_grace_period(); |
| 120 | } | 112 | } |
| 121 | } | 113 | } |
| 122 | 114 | ||
| @@ -126,7 +118,7 @@ static void restart_grace(void) | |||
| 126 | static int | 118 | static int |
| 127 | lockd(void *vrqstp) | 119 | lockd(void *vrqstp) |
| 128 | { | 120 | { |
| 129 | int err = 0; | 121 | int err = 0, preverr = 0; |
| 130 | struct svc_rqst *rqstp = vrqstp; | 122 | struct svc_rqst *rqstp = vrqstp; |
| 131 | 123 | ||
| 132 | /* try_to_freeze() is called from svc_recv() */ | 124 | /* try_to_freeze() is called from svc_recv() */ |
| @@ -141,6 +133,8 @@ lockd(void *vrqstp) | |||
| 141 | nlm_timeout = LOCKD_DFLT_TIMEO; | 133 | nlm_timeout = LOCKD_DFLT_TIMEO; |
| 142 | nlmsvc_timeout = nlm_timeout * HZ; | 134 | nlmsvc_timeout = nlm_timeout * HZ; |
| 143 | 135 | ||
| 136 | set_grace_period(); | ||
| 137 | |||
| 144 | /* | 138 | /* |
| 145 | * The main request loop. We don't terminate until the last | 139 | * The main request loop. We don't terminate until the last |
| 146 | * NFS mount or NFS daemon has gone away. | 140 | * NFS mount or NFS daemon has gone away. |
| @@ -165,14 +159,29 @@ lockd(void *vrqstp) | |||
| 165 | * recvfrom routine. | 159 | * recvfrom routine. |
| 166 | */ | 160 | */ |
| 167 | err = svc_recv(rqstp, timeout); | 161 | err = svc_recv(rqstp, timeout); |
| 168 | if (err == -EAGAIN || err == -EINTR) | 162 | if (err == -EAGAIN || err == -EINTR) { |
| 163 | preverr = err; | ||
| 164 | continue; | ||
| 165 | } | ||
| 166 | if (err < 0) { | ||
| 167 | if (err != preverr) { | ||
| 168 | printk(KERN_WARNING "%s: unexpected error " | ||
| 169 | "from svc_recv (%d)\n", __func__, err); | ||
| 170 | preverr = err; | ||
| 171 | } | ||
| 172 | schedule_timeout_interruptible(HZ); | ||
| 169 | continue; | 173 | continue; |
| 174 | } | ||
| 175 | preverr = err; | ||
| 176 | |||
| 170 | dprintk("lockd: request from %s\n", | 177 | dprintk("lockd: request from %s\n", |
| 171 | svc_print_addr(rqstp, buf, sizeof(buf))); | 178 | svc_print_addr(rqstp, buf, sizeof(buf))); |
| 172 | 179 | ||
| 173 | svc_process(rqstp); | 180 | svc_process(rqstp); |
| 174 | } | 181 | } |
| 175 | flush_signals(current); | 182 | flush_signals(current); |
| 183 | cancel_delayed_work_sync(&grace_period_end); | ||
| 184 | locks_end_grace(&lockd_manager); | ||
| 176 | if (nlmsvc_ops) | 185 | if (nlmsvc_ops) |
| 177 | nlmsvc_invalidate_all(); | 186 | nlmsvc_invalidate_all(); |
| 178 | nlm_shutdown_hosts(); | 187 | nlm_shutdown_hosts(); |
| @@ -180,29 +189,27 @@ lockd(void *vrqstp) | |||
| 180 | } | 189 | } |
| 181 | 190 | ||
| 182 | static int create_lockd_listener(struct svc_serv *serv, const char *name, | 191 | static int create_lockd_listener(struct svc_serv *serv, const char *name, |
| 183 | struct net *net, const int family, | 192 | const int family, const unsigned short port) |
| 184 | const unsigned short port) | ||
| 185 | { | 193 | { |
| 186 | struct svc_xprt *xprt; | 194 | struct svc_xprt *xprt; |
| 187 | 195 | ||
| 188 | xprt = svc_find_xprt(serv, name, net, family, 0); | 196 | xprt = svc_find_xprt(serv, name, family, 0); |
| 189 | if (xprt == NULL) | 197 | if (xprt == NULL) |
| 190 | return svc_create_xprt(serv, name, net, family, port, | 198 | return svc_create_xprt(serv, name, &init_net, family, port, |
| 191 | SVC_SOCK_DEFAULTS); | 199 | SVC_SOCK_DEFAULTS); |
| 192 | svc_xprt_put(xprt); | 200 | svc_xprt_put(xprt); |
| 193 | return 0; | 201 | return 0; |
| 194 | } | 202 | } |
| 195 | 203 | ||
| 196 | static int create_lockd_family(struct svc_serv *serv, struct net *net, | 204 | static int create_lockd_family(struct svc_serv *serv, const int family) |
| 197 | const int family) | ||
| 198 | { | 205 | { |
| 199 | int err; | 206 | int err; |
| 200 | 207 | ||
| 201 | err = create_lockd_listener(serv, "udp", net, family, nlm_udpport); | 208 | err = create_lockd_listener(serv, "udp", family, nlm_udpport); |
| 202 | if (err < 0) | 209 | if (err < 0) |
| 203 | return err; | 210 | return err; |
| 204 | 211 | ||
| 205 | return create_lockd_listener(serv, "tcp", net, family, nlm_tcpport); | 212 | return create_lockd_listener(serv, "tcp", family, nlm_tcpport); |
| 206 | } | 213 | } |
| 207 | 214 | ||
| 208 | /* | 215 | /* |
| @@ -215,16 +222,16 @@ static int create_lockd_family(struct svc_serv *serv, struct net *net, | |||
| 215 | * Returns zero if all listeners are available; otherwise a | 222 | * Returns zero if all listeners are available; otherwise a |
| 216 | * negative errno value is returned. | 223 | * negative errno value is returned. |
| 217 | */ | 224 | */ |
| 218 | static int make_socks(struct svc_serv *serv, struct net *net) | 225 | static int make_socks(struct svc_serv *serv) |
| 219 | { | 226 | { |
| 220 | static int warned; | 227 | static int warned; |
| 221 | int err; | 228 | int err; |
| 222 | 229 | ||
| 223 | err = create_lockd_family(serv, net, PF_INET); | 230 | err = create_lockd_family(serv, PF_INET); |
| 224 | if (err < 0) | 231 | if (err < 0) |
| 225 | goto out_err; | 232 | goto out_err; |
| 226 | 233 | ||
| 227 | err = create_lockd_family(serv, net, PF_INET6); | 234 | err = create_lockd_family(serv, PF_INET6); |
| 228 | if (err < 0 && err != -EAFNOSUPPORT) | 235 | if (err < 0 && err != -EAFNOSUPPORT) |
| 229 | goto out_err; | 236 | goto out_err; |
| 230 | 237 | ||
| @@ -238,68 +245,51 @@ out_err: | |||
| 238 | return err; | 245 | return err; |
| 239 | } | 246 | } |
| 240 | 247 | ||
| 241 | static int lockd_up_net(struct svc_serv *serv, struct net *net) | 248 | /* |
| 249 | * Bring up the lockd process if it's not already up. | ||
| 250 | */ | ||
| 251 | int lockd_up(void) | ||
| 242 | { | 252 | { |
| 243 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 253 | struct svc_serv *serv; |
| 244 | int error; | 254 | int error = 0; |
| 245 | |||
| 246 | if (ln->nlmsvc_users++) | ||
| 247 | return 0; | ||
| 248 | |||
| 249 | error = svc_bind(serv, net); | ||
| 250 | if (error) | ||
| 251 | goto err_bind; | ||
| 252 | 255 | ||
| 253 | error = make_socks(serv, net); | 256 | mutex_lock(&nlmsvc_mutex); |
| 254 | if (error < 0) | 257 | /* |
| 255 | goto err_socks; | 258 | * Check whether we're already up and running. |
| 256 | set_grace_period(net); | 259 | */ |
| 257 | dprintk("lockd_up_net: per-net data created; net=%p\n", net); | 260 | if (nlmsvc_rqst) |
| 258 | return 0; | 261 | goto out; |
| 259 | 262 | ||
| 260 | err_socks: | 263 | /* |
| 261 | svc_rpcb_cleanup(serv, net); | 264 | * Sanity check: if there's no pid, |
| 262 | err_bind: | 265 | * we should be the first user ... |
| 263 | ln->nlmsvc_users--; | 266 | */ |
| 264 | return error; | 267 | if (nlmsvc_users) |
| 265 | } | 268 | printk(KERN_WARNING |
| 269 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | ||
| 266 | 270 | ||
| 267 | static void lockd_down_net(struct svc_serv *serv, struct net *net) | 271 | error = -ENOMEM; |
| 268 | { | 272 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); |
| 269 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 273 | if (!serv) { |
| 270 | 274 | printk(KERN_WARNING "lockd_up: create service failed\n"); | |
| 271 | if (ln->nlmsvc_users) { | 275 | goto out; |
| 272 | if (--ln->nlmsvc_users == 0) { | ||
| 273 | nlm_shutdown_hosts_net(net); | ||
| 274 | cancel_delayed_work_sync(&ln->grace_period_end); | ||
| 275 | locks_end_grace(&ln->lockd_manager); | ||
| 276 | svc_shutdown_net(serv, net); | ||
| 277 | dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); | ||
| 278 | } | ||
| 279 | } else { | ||
| 280 | printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", | ||
| 281 | nlmsvc_task, net); | ||
| 282 | BUG(); | ||
| 283 | } | 276 | } |
| 284 | } | ||
| 285 | |||
| 286 | static int lockd_start_svc(struct svc_serv *serv) | ||
| 287 | { | ||
| 288 | int error; | ||
| 289 | 277 | ||
| 290 | if (nlmsvc_rqst) | 278 | error = make_socks(serv); |
| 291 | return 0; | 279 | if (error < 0) |
| 280 | goto destroy_and_out; | ||
| 292 | 281 | ||
| 293 | /* | 282 | /* |
| 294 | * Create the kernel thread and wait for it to start. | 283 | * Create the kernel thread and wait for it to start. |
| 295 | */ | 284 | */ |
| 296 | nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); | 285 | nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); |
| 297 | if (IS_ERR(nlmsvc_rqst)) { | 286 | if (IS_ERR(nlmsvc_rqst)) { |
| 298 | error = PTR_ERR(nlmsvc_rqst); | 287 | error = PTR_ERR(nlmsvc_rqst); |
| 288 | nlmsvc_rqst = NULL; | ||
| 299 | printk(KERN_WARNING | 289 | printk(KERN_WARNING |
| 300 | "lockd_up: svc_rqst allocation failed, error=%d\n", | 290 | "lockd_up: svc_rqst allocation failed, error=%d\n", |
| 301 | error); | 291 | error); |
| 302 | goto out_rqst; | 292 | goto destroy_and_out; |
| 303 | } | 293 | } |
| 304 | 294 | ||
| 305 | svc_sock_update_bufs(serv); | 295 | svc_sock_update_bufs(serv); |
| @@ -308,92 +298,25 @@ static int lockd_start_svc(struct svc_serv *serv) | |||
| 308 | nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); | 298 | nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); |
| 309 | if (IS_ERR(nlmsvc_task)) { | 299 | if (IS_ERR(nlmsvc_task)) { |
| 310 | error = PTR_ERR(nlmsvc_task); | 300 | error = PTR_ERR(nlmsvc_task); |
| 301 | svc_exit_thread(nlmsvc_rqst); | ||
| 302 | nlmsvc_task = NULL; | ||
| 303 | nlmsvc_rqst = NULL; | ||
| 311 | printk(KERN_WARNING | 304 | printk(KERN_WARNING |
| 312 | "lockd_up: kthread_run failed, error=%d\n", error); | 305 | "lockd_up: kthread_run failed, error=%d\n", error); |
| 313 | goto out_task; | 306 | goto destroy_and_out; |
| 314 | } | ||
| 315 | dprintk("lockd_up: service started\n"); | ||
| 316 | return 0; | ||
| 317 | |||
| 318 | out_task: | ||
| 319 | svc_exit_thread(nlmsvc_rqst); | ||
| 320 | nlmsvc_task = NULL; | ||
| 321 | out_rqst: | ||
| 322 | nlmsvc_rqst = NULL; | ||
| 323 | return error; | ||
| 324 | } | ||
| 325 | |||
| 326 | static struct svc_serv *lockd_create_svc(void) | ||
| 327 | { | ||
| 328 | struct svc_serv *serv; | ||
| 329 | |||
| 330 | /* | ||
| 331 | * Check whether we're already up and running. | ||
| 332 | */ | ||
| 333 | if (nlmsvc_rqst) { | ||
| 334 | /* | ||
| 335 | * Note: increase service usage, because later in case of error | ||
| 336 | * svc_destroy() will be called. | ||
| 337 | */ | ||
| 338 | svc_get(nlmsvc_rqst->rq_server); | ||
| 339 | return nlmsvc_rqst->rq_server; | ||
| 340 | } | ||
| 341 | |||
| 342 | /* | ||
| 343 | * Sanity check: if there's no pid, | ||
| 344 | * we should be the first user ... | ||
| 345 | */ | ||
| 346 | if (nlmsvc_users) | ||
| 347 | printk(KERN_WARNING | ||
| 348 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | ||
| 349 | |||
| 350 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); | ||
| 351 | if (!serv) { | ||
| 352 | printk(KERN_WARNING "lockd_up: create service failed\n"); | ||
| 353 | return ERR_PTR(-ENOMEM); | ||
| 354 | } | ||
| 355 | dprintk("lockd_up: service created\n"); | ||
| 356 | return serv; | ||
| 357 | } | ||
| 358 | |||
| 359 | /* | ||
| 360 | * Bring up the lockd process if it's not already up. | ||
| 361 | */ | ||
| 362 | int lockd_up(struct net *net) | ||
| 363 | { | ||
| 364 | struct svc_serv *serv; | ||
| 365 | int error; | ||
| 366 | |||
| 367 | mutex_lock(&nlmsvc_mutex); | ||
| 368 | |||
| 369 | serv = lockd_create_svc(); | ||
| 370 | if (IS_ERR(serv)) { | ||
| 371 | error = PTR_ERR(serv); | ||
| 372 | goto err_create; | ||
| 373 | } | 307 | } |
| 374 | 308 | ||
| 375 | error = lockd_up_net(serv, net); | ||
| 376 | if (error < 0) | ||
| 377 | goto err_net; | ||
| 378 | |||
| 379 | error = lockd_start_svc(serv); | ||
| 380 | if (error < 0) | ||
| 381 | goto err_start; | ||
| 382 | |||
| 383 | nlmsvc_users++; | ||
| 384 | /* | 309 | /* |
| 385 | * Note: svc_serv structures have an initial use count of 1, | 310 | * Note: svc_serv structures have an initial use count of 1, |
| 386 | * so we exit through here on both success and failure. | 311 | * so we exit through here on both success and failure. |
| 387 | */ | 312 | */ |
| 388 | err_net: | 313 | destroy_and_out: |
| 389 | svc_destroy(serv); | 314 | svc_destroy(serv); |
| 390 | err_create: | 315 | out: |
| 316 | if (!error) | ||
| 317 | nlmsvc_users++; | ||
| 391 | mutex_unlock(&nlmsvc_mutex); | 318 | mutex_unlock(&nlmsvc_mutex); |
| 392 | return error; | 319 | return error; |
| 393 | |||
| 394 | err_start: | ||
| 395 | lockd_down_net(serv, net); | ||
| 396 | goto err_net; | ||
| 397 | } | 320 | } |
| 398 | EXPORT_SYMBOL_GPL(lockd_up); | 321 | EXPORT_SYMBOL_GPL(lockd_up); |
| 399 | 322 | ||
| @@ -401,10 +324,9 @@ EXPORT_SYMBOL_GPL(lockd_up); | |||
| 401 | * Decrement the user count and bring down lockd if we're the last. | 324 | * Decrement the user count and bring down lockd if we're the last. |
| 402 | */ | 325 | */ |
| 403 | void | 326 | void |
| 404 | lockd_down(struct net *net) | 327 | lockd_down(void) |
| 405 | { | 328 | { |
| 406 | mutex_lock(&nlmsvc_mutex); | 329 | mutex_lock(&nlmsvc_mutex); |
| 407 | lockd_down_net(nlmsvc_rqst->rq_server, net); | ||
| 408 | if (nlmsvc_users) { | 330 | if (nlmsvc_users) { |
| 409 | if (--nlmsvc_users) | 331 | if (--nlmsvc_users) |
| 410 | goto out; | 332 | goto out; |
| @@ -419,9 +341,7 @@ lockd_down(struct net *net) | |||
| 419 | BUG(); | 341 | BUG(); |
| 420 | } | 342 | } |
| 421 | kthread_stop(nlmsvc_task); | 343 | kthread_stop(nlmsvc_task); |
| 422 | dprintk("lockd_down: service stopped\n"); | ||
| 423 | svc_exit_thread(nlmsvc_rqst); | 344 | svc_exit_thread(nlmsvc_rqst); |
| 424 | dprintk("lockd_down: service destroyed\n"); | ||
| 425 | nlmsvc_task = NULL; | 345 | nlmsvc_task = NULL; |
| 426 | nlmsvc_rqst = NULL; | 346 | nlmsvc_rqst = NULL; |
| 427 | out: | 347 | out: |
| @@ -520,7 +440,7 @@ static int param_set_##name(const char *val, struct kernel_param *kp) \ | |||
| 520 | __typeof__(type) num = which_strtol(val, &endp, 0); \ | 440 | __typeof__(type) num = which_strtol(val, &endp, 0); \ |
| 521 | if (endp == val || *endp || num < (min) || num > (max)) \ | 441 | if (endp == val || *endp || num < (min) || num > (max)) \ |
| 522 | return -EINVAL; \ | 442 | return -EINVAL; \ |
| 523 | *((type *) kp->arg) = num; \ | 443 | *((int *) kp->arg) = num; \ |
| 524 | return 0; \ | 444 | return 0; \ |
| 525 | } | 445 | } |
| 526 | 446 | ||
| @@ -577,60 +497,24 @@ module_param_call(nlm_tcpport, param_set_port, param_get_int, | |||
| 577 | module_param(nsm_use_hostnames, bool, 0644); | 497 | module_param(nsm_use_hostnames, bool, 0644); |
| 578 | module_param(nlm_max_connections, uint, 0644); | 498 | module_param(nlm_max_connections, uint, 0644); |
| 579 | 499 | ||
| 580 | static int lockd_init_net(struct net *net) | ||
| 581 | { | ||
| 582 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 583 | |||
| 584 | INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); | ||
| 585 | INIT_LIST_HEAD(&ln->grace_list); | ||
| 586 | spin_lock_init(&ln->nsm_clnt_lock); | ||
| 587 | return 0; | ||
| 588 | } | ||
| 589 | |||
| 590 | static void lockd_exit_net(struct net *net) | ||
| 591 | { | ||
| 592 | } | ||
| 593 | |||
| 594 | static struct pernet_operations lockd_net_ops = { | ||
| 595 | .init = lockd_init_net, | ||
| 596 | .exit = lockd_exit_net, | ||
| 597 | .id = &lockd_net_id, | ||
| 598 | .size = sizeof(struct lockd_net), | ||
| 599 | }; | ||
| 600 | |||
| 601 | |||
| 602 | /* | 500 | /* |
| 603 | * Initialising and terminating the module. | 501 | * Initialising and terminating the module. |
| 604 | */ | 502 | */ |
| 605 | 503 | ||
| 606 | static int __init init_nlm(void) | 504 | static int __init init_nlm(void) |
| 607 | { | 505 | { |
| 608 | int err; | ||
| 609 | |||
| 610 | #ifdef CONFIG_SYSCTL | 506 | #ifdef CONFIG_SYSCTL |
| 611 | err = -ENOMEM; | ||
| 612 | nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root); | 507 | nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root); |
| 613 | if (nlm_sysctl_table == NULL) | 508 | return nlm_sysctl_table ? 0 : -ENOMEM; |
| 614 | goto err_sysctl; | 509 | #else |
| 615 | #endif | ||
| 616 | err = register_pernet_subsys(&lockd_net_ops); | ||
| 617 | if (err) | ||
| 618 | goto err_pernet; | ||
| 619 | return 0; | 510 | return 0; |
| 620 | |||
| 621 | err_pernet: | ||
| 622 | #ifdef CONFIG_SYSCTL | ||
| 623 | unregister_sysctl_table(nlm_sysctl_table); | ||
| 624 | #endif | 511 | #endif |
| 625 | err_sysctl: | ||
| 626 | return err; | ||
| 627 | } | 512 | } |
| 628 | 513 | ||
| 629 | static void __exit exit_nlm(void) | 514 | static void __exit exit_nlm(void) |
| 630 | { | 515 | { |
| 631 | /* FIXME: delete all NLM clients */ | 516 | /* FIXME: delete all NLM clients */ |
| 632 | nlm_shutdown_hosts(); | 517 | nlm_shutdown_hosts(); |
| 633 | unregister_pernet_subsys(&lockd_net_ops); | ||
| 634 | #ifdef CONFIG_SYSCTL | 518 | #ifdef CONFIG_SYSCTL |
| 635 | unregister_sysctl_table(nlm_sysctl_table); | 519 | unregister_sysctl_table(nlm_sysctl_table); |
| 636 | #endif | 520 | #endif |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index b147d1ae71f..9a41fdc1951 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
| 12 | #include <linux/lockd/lockd.h> | 12 | #include <linux/lockd/lockd.h> |
| 13 | #include <linux/lockd/share.h> | 13 | #include <linux/lockd/share.h> |
| 14 | #include <linux/sunrpc/svc_xprt.h> | ||
| 15 | 14 | ||
| 16 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 15 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
| 17 | 16 | ||
| @@ -152,7 +151,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 152 | resp->cookie = argp->cookie; | 151 | resp->cookie = argp->cookie; |
| 153 | 152 | ||
| 154 | /* Don't accept requests during grace period */ | 153 | /* Don't accept requests during grace period */ |
| 155 | if (locks_in_grace(SVC_NET(rqstp))) { | 154 | if (locks_in_grace()) { |
| 156 | resp->status = nlm_lck_denied_grace_period; | 155 | resp->status = nlm_lck_denied_grace_period; |
| 157 | return rpc_success; | 156 | return rpc_success; |
| 158 | } | 157 | } |
| @@ -162,7 +161,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 162 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 161 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| 163 | 162 | ||
| 164 | /* Try to cancel request. */ | 163 | /* Try to cancel request. */ |
| 165 | resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock); | 164 | resp->status = nlmsvc_cancel_blocked(file, &argp->lock); |
| 166 | 165 | ||
| 167 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 166 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
| 168 | nlmsvc_release_host(host); | 167 | nlmsvc_release_host(host); |
| @@ -185,7 +184,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 185 | resp->cookie = argp->cookie; | 184 | resp->cookie = argp->cookie; |
| 186 | 185 | ||
| 187 | /* Don't accept new lock requests during grace period */ | 186 | /* Don't accept new lock requests during grace period */ |
| 188 | if (locks_in_grace(SVC_NET(rqstp))) { | 187 | if (locks_in_grace()) { |
| 189 | resp->status = nlm_lck_denied_grace_period; | 188 | resp->status = nlm_lck_denied_grace_period; |
| 190 | return rpc_success; | 189 | return rpc_success; |
| 191 | } | 190 | } |
| @@ -195,7 +194,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 195 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 194 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| 196 | 195 | ||
| 197 | /* Now try to remove the lock */ | 196 | /* Now try to remove the lock */ |
| 198 | resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock); | 197 | resp->status = nlmsvc_unlock(file, &argp->lock); |
| 199 | 198 | ||
| 200 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 199 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
| 201 | nlmsvc_release_host(host); | 200 | nlmsvc_release_host(host); |
| @@ -257,7 +256,6 @@ static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args | |||
| 257 | return rpc_system_err; | 256 | return rpc_system_err; |
| 258 | 257 | ||
| 259 | call = nlm_alloc_call(host); | 258 | call = nlm_alloc_call(host); |
| 260 | nlmsvc_release_host(host); | ||
| 261 | if (call == NULL) | 259 | if (call == NULL) |
| 262 | return rpc_system_err; | 260 | return rpc_system_err; |
| 263 | 261 | ||
| @@ -323,7 +321,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 323 | resp->cookie = argp->cookie; | 321 | resp->cookie = argp->cookie; |
| 324 | 322 | ||
| 325 | /* Don't accept new lock requests during grace period */ | 323 | /* Don't accept new lock requests during grace period */ |
| 326 | if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) { | 324 | if (locks_in_grace() && !argp->reclaim) { |
| 327 | resp->status = nlm_lck_denied_grace_period; | 325 | resp->status = nlm_lck_denied_grace_period; |
| 328 | return rpc_success; | 326 | return rpc_success; |
| 329 | } | 327 | } |
| @@ -356,7 +354,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 356 | resp->cookie = argp->cookie; | 354 | resp->cookie = argp->cookie; |
| 357 | 355 | ||
| 358 | /* Don't accept requests during grace period */ | 356 | /* Don't accept requests during grace period */ |
| 359 | if (locks_in_grace(SVC_NET(rqstp))) { | 357 | if (locks_in_grace()) { |
| 360 | resp->status = nlm_lck_denied_grace_period; | 358 | resp->status = nlm_lck_denied_grace_period; |
| 361 | return rpc_success; | 359 | return rpc_success; |
| 362 | } | 360 | } |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 8d80c990dff..f0179c3745d 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
| 27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| 28 | #include <linux/sunrpc/clnt.h> | 28 | #include <linux/sunrpc/clnt.h> |
| 29 | #include <linux/sunrpc/svc_xprt.h> | 29 | #include <linux/sunrpc/svc.h> |
| 30 | #include <linux/lockd/nlm.h> | 30 | #include <linux/lockd/nlm.h> |
| 31 | #include <linux/lockd/lockd.h> | 31 | #include <linux/lockd/lockd.h> |
| 32 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
| @@ -46,6 +46,7 @@ static void nlmsvc_remove_block(struct nlm_block *block); | |||
| 46 | static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); | 46 | static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); |
| 47 | static void nlmsvc_freegrantargs(struct nlm_rqst *call); | 47 | static void nlmsvc_freegrantargs(struct nlm_rqst *call); |
| 48 | static const struct rpc_call_ops nlmsvc_grant_ops; | 48 | static const struct rpc_call_ops nlmsvc_grant_ops; |
| 49 | static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie); | ||
| 49 | 50 | ||
| 50 | /* | 51 | /* |
| 51 | * The list of blocked locks to retry | 52 | * The list of blocked locks to retry |
| @@ -53,35 +54,6 @@ static const struct rpc_call_ops nlmsvc_grant_ops; | |||
| 53 | static LIST_HEAD(nlm_blocked); | 54 | static LIST_HEAD(nlm_blocked); |
| 54 | static DEFINE_SPINLOCK(nlm_blocked_lock); | 55 | static DEFINE_SPINLOCK(nlm_blocked_lock); |
| 55 | 56 | ||
| 56 | #ifdef LOCKD_DEBUG | ||
| 57 | static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) | ||
| 58 | { | ||
| 59 | /* | ||
| 60 | * We can get away with a static buffer because we're only | ||
| 61 | * called with BKL held. | ||
| 62 | */ | ||
| 63 | static char buf[2*NLM_MAXCOOKIELEN+1]; | ||
| 64 | unsigned int i, len = sizeof(buf); | ||
| 65 | char *p = buf; | ||
| 66 | |||
| 67 | len--; /* allow for trailing \0 */ | ||
| 68 | if (len < 3) | ||
| 69 | return "???"; | ||
| 70 | for (i = 0 ; i < cookie->len ; i++) { | ||
| 71 | if (len < 2) { | ||
| 72 | strcpy(p-3, "..."); | ||
| 73 | break; | ||
| 74 | } | ||
| 75 | sprintf(p, "%02x", cookie->data[i]); | ||
| 76 | p += 2; | ||
| 77 | len -= 2; | ||
| 78 | } | ||
| 79 | *p = '\0'; | ||
| 80 | |||
| 81 | return buf; | ||
| 82 | } | ||
| 83 | #endif | ||
| 84 | |||
| 85 | /* | 57 | /* |
| 86 | * Insert a blocked lock into the global list | 58 | * Insert a blocked lock into the global list |
| 87 | */ | 59 | */ |
| @@ -219,6 +191,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host, | |||
| 219 | struct nlm_block *block; | 191 | struct nlm_block *block; |
| 220 | struct nlm_rqst *call = NULL; | 192 | struct nlm_rqst *call = NULL; |
| 221 | 193 | ||
| 194 | nlm_get_host(host); | ||
| 222 | call = nlm_alloc_call(host); | 195 | call = nlm_alloc_call(host); |
| 223 | if (call == NULL) | 196 | if (call == NULL) |
| 224 | return NULL; | 197 | return NULL; |
| @@ -289,6 +262,7 @@ static void nlmsvc_free_block(struct kref *kref) | |||
| 289 | dprintk("lockd: freeing block %p...\n", block); | 262 | dprintk("lockd: freeing block %p...\n", block); |
| 290 | 263 | ||
| 291 | /* Remove block from file's list of blocks */ | 264 | /* Remove block from file's list of blocks */ |
| 265 | mutex_lock(&file->f_mutex); | ||
| 292 | list_del_init(&block->b_flist); | 266 | list_del_init(&block->b_flist); |
| 293 | mutex_unlock(&file->f_mutex); | 267 | mutex_unlock(&file->f_mutex); |
| 294 | 268 | ||
| @@ -302,7 +276,7 @@ static void nlmsvc_free_block(struct kref *kref) | |||
| 302 | static void nlmsvc_release_block(struct nlm_block *block) | 276 | static void nlmsvc_release_block(struct nlm_block *block) |
| 303 | { | 277 | { |
| 304 | if (block != NULL) | 278 | if (block != NULL) |
| 305 | kref_put_mutex(&block->b_count, nlmsvc_free_block, &block->b_file->f_mutex); | 279 | kref_put(&block->b_count, nlmsvc_free_block); |
| 306 | } | 280 | } |
| 307 | 281 | ||
| 308 | /* | 282 | /* |
| @@ -445,11 +419,11 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
| 445 | goto out; | 419 | goto out; |
| 446 | } | 420 | } |
| 447 | 421 | ||
| 448 | if (locks_in_grace(SVC_NET(rqstp)) && !reclaim) { | 422 | if (locks_in_grace() && !reclaim) { |
| 449 | ret = nlm_lck_denied_grace_period; | 423 | ret = nlm_lck_denied_grace_period; |
| 450 | goto out; | 424 | goto out; |
| 451 | } | 425 | } |
| 452 | if (reclaim && !locks_in_grace(SVC_NET(rqstp))) { | 426 | if (reclaim && !locks_in_grace()) { |
| 453 | ret = nlm_lck_denied_grace_period; | 427 | ret = nlm_lck_denied_grace_period; |
| 454 | goto out; | 428 | goto out; |
| 455 | } | 429 | } |
| @@ -557,7 +531,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
| 557 | goto out; | 531 | goto out; |
| 558 | } | 532 | } |
| 559 | 533 | ||
| 560 | if (locks_in_grace(SVC_NET(rqstp))) { | 534 | if (locks_in_grace()) { |
| 561 | ret = nlm_lck_denied_grace_period; | 535 | ret = nlm_lck_denied_grace_period; |
| 562 | goto out; | 536 | goto out; |
| 563 | } | 537 | } |
| @@ -601,7 +575,7 @@ out: | |||
| 601 | * must be removed. | 575 | * must be removed. |
| 602 | */ | 576 | */ |
| 603 | __be32 | 577 | __be32 |
| 604 | nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock) | 578 | nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) |
| 605 | { | 579 | { |
| 606 | int error; | 580 | int error; |
| 607 | 581 | ||
| @@ -613,7 +587,7 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock) | |||
| 613 | (long long)lock->fl.fl_end); | 587 | (long long)lock->fl.fl_end); |
| 614 | 588 | ||
| 615 | /* First, cancel any lock that might be there */ | 589 | /* First, cancel any lock that might be there */ |
| 616 | nlmsvc_cancel_blocked(net, file, lock); | 590 | nlmsvc_cancel_blocked(file, lock); |
| 617 | 591 | ||
| 618 | lock->fl.fl_type = F_UNLCK; | 592 | lock->fl.fl_type = F_UNLCK; |
| 619 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); | 593 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); |
| @@ -629,7 +603,7 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock) | |||
| 629 | * The calling procedure must check whether the file can be closed. | 603 | * The calling procedure must check whether the file can be closed. |
| 630 | */ | 604 | */ |
| 631 | __be32 | 605 | __be32 |
| 632 | nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *lock) | 606 | nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) |
| 633 | { | 607 | { |
| 634 | struct nlm_block *block; | 608 | struct nlm_block *block; |
| 635 | int status = 0; | 609 | int status = 0; |
| @@ -641,7 +615,7 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l | |||
| 641 | (long long)lock->fl.fl_start, | 615 | (long long)lock->fl.fl_start, |
| 642 | (long long)lock->fl.fl_end); | 616 | (long long)lock->fl.fl_end); |
| 643 | 617 | ||
| 644 | if (locks_in_grace(net)) | 618 | if (locks_in_grace()) |
| 645 | return nlm_lck_denied_grace_period; | 619 | return nlm_lck_denied_grace_period; |
| 646 | 620 | ||
| 647 | mutex_lock(&file->f_mutex); | 621 | mutex_lock(&file->f_mutex); |
| @@ -961,3 +935,32 @@ nlmsvc_retry_blocked(void) | |||
| 961 | 935 | ||
| 962 | return timeout; | 936 | return timeout; |
| 963 | } | 937 | } |
| 938 | |||
| 939 | #ifdef RPC_DEBUG | ||
| 940 | static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) | ||
| 941 | { | ||
| 942 | /* | ||
| 943 | * We can get away with a static buffer because we're only | ||
| 944 | * called with BKL held. | ||
| 945 | */ | ||
| 946 | static char buf[2*NLM_MAXCOOKIELEN+1]; | ||
| 947 | unsigned int i, len = sizeof(buf); | ||
| 948 | char *p = buf; | ||
| 949 | |||
| 950 | len--; /* allow for trailing \0 */ | ||
| 951 | if (len < 3) | ||
| 952 | return "???"; | ||
| 953 | for (i = 0 ; i < cookie->len ; i++) { | ||
| 954 | if (len < 2) { | ||
| 955 | strcpy(p-3, "..."); | ||
| 956 | break; | ||
| 957 | } | ||
| 958 | sprintf(p, "%02x", cookie->data[i]); | ||
| 959 | p += 2; | ||
| 960 | len -= 2; | ||
| 961 | } | ||
| 962 | *p = '\0'; | ||
| 963 | |||
| 964 | return buf; | ||
| 965 | } | ||
| 966 | #endif | ||
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 21171f0c647..d27aab11f32 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
| 12 | #include <linux/lockd/lockd.h> | 12 | #include <linux/lockd/lockd.h> |
| 13 | #include <linux/lockd/share.h> | 13 | #include <linux/lockd/share.h> |
| 14 | #include <linux/sunrpc/svc_xprt.h> | ||
| 15 | 14 | ||
| 16 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 15 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
| 17 | 16 | ||
| @@ -68,8 +67,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 68 | 67 | ||
| 69 | /* Obtain file pointer. Not used by FREE_ALL call. */ | 68 | /* Obtain file pointer. Not used by FREE_ALL call. */ |
| 70 | if (filp != NULL) { | 69 | if (filp != NULL) { |
| 71 | error = cast_status(nlm_lookup_file(rqstp, &file, &lock->fh)); | 70 | if ((error = nlm_lookup_file(rqstp, &file, &lock->fh)) != 0) |
| 72 | if (error != 0) | ||
| 73 | goto no_locks; | 71 | goto no_locks; |
| 74 | *filp = file; | 72 | *filp = file; |
| 75 | 73 | ||
| @@ -177,14 +175,13 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 177 | { | 175 | { |
| 178 | struct nlm_host *host; | 176 | struct nlm_host *host; |
| 179 | struct nlm_file *file; | 177 | struct nlm_file *file; |
| 180 | struct net *net = SVC_NET(rqstp); | ||
| 181 | 178 | ||
| 182 | dprintk("lockd: CANCEL called\n"); | 179 | dprintk("lockd: CANCEL called\n"); |
| 183 | 180 | ||
| 184 | resp->cookie = argp->cookie; | 181 | resp->cookie = argp->cookie; |
| 185 | 182 | ||
| 186 | /* Don't accept requests during grace period */ | 183 | /* Don't accept requests during grace period */ |
| 187 | if (locks_in_grace(net)) { | 184 | if (locks_in_grace()) { |
| 188 | resp->status = nlm_lck_denied_grace_period; | 185 | resp->status = nlm_lck_denied_grace_period; |
| 189 | return rpc_success; | 186 | return rpc_success; |
| 190 | } | 187 | } |
| @@ -194,7 +191,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 194 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 191 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| 195 | 192 | ||
| 196 | /* Try to cancel request. */ | 193 | /* Try to cancel request. */ |
| 197 | resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); | 194 | resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); |
| 198 | 195 | ||
| 199 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 196 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
| 200 | nlmsvc_release_host(host); | 197 | nlmsvc_release_host(host); |
| @@ -211,14 +208,13 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 211 | { | 208 | { |
| 212 | struct nlm_host *host; | 209 | struct nlm_host *host; |
| 213 | struct nlm_file *file; | 210 | struct nlm_file *file; |
| 214 | struct net *net = SVC_NET(rqstp); | ||
| 215 | 211 | ||
| 216 | dprintk("lockd: UNLOCK called\n"); | 212 | dprintk("lockd: UNLOCK called\n"); |
| 217 | 213 | ||
| 218 | resp->cookie = argp->cookie; | 214 | resp->cookie = argp->cookie; |
| 219 | 215 | ||
| 220 | /* Don't accept new lock requests during grace period */ | 216 | /* Don't accept new lock requests during grace period */ |
| 221 | if (locks_in_grace(net)) { | 217 | if (locks_in_grace()) { |
| 222 | resp->status = nlm_lck_denied_grace_period; | 218 | resp->status = nlm_lck_denied_grace_period; |
| 223 | return rpc_success; | 219 | return rpc_success; |
| 224 | } | 220 | } |
| @@ -228,7 +224,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 228 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 224 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| 229 | 225 | ||
| 230 | /* Now try to remove the lock */ | 226 | /* Now try to remove the lock */ |
| 231 | resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); | 227 | resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); |
| 232 | 228 | ||
| 233 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 229 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
| 234 | nlmsvc_release_host(host); | 230 | nlmsvc_release_host(host); |
| @@ -298,7 +294,6 @@ static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args | |||
| 298 | return rpc_system_err; | 294 | return rpc_system_err; |
| 299 | 295 | ||
| 300 | call = nlm_alloc_call(host); | 296 | call = nlm_alloc_call(host); |
| 301 | nlmsvc_release_host(host); | ||
| 302 | if (call == NULL) | 297 | if (call == NULL) |
| 303 | return rpc_system_err; | 298 | return rpc_system_err; |
| 304 | 299 | ||
| @@ -366,7 +361,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 366 | resp->cookie = argp->cookie; | 361 | resp->cookie = argp->cookie; |
| 367 | 362 | ||
| 368 | /* Don't accept new lock requests during grace period */ | 363 | /* Don't accept new lock requests during grace period */ |
| 369 | if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) { | 364 | if (locks_in_grace() && !argp->reclaim) { |
| 370 | resp->status = nlm_lck_denied_grace_period; | 365 | resp->status = nlm_lck_denied_grace_period; |
| 371 | return rpc_success; | 366 | return rpc_success; |
| 372 | } | 367 | } |
| @@ -399,7 +394,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 399 | resp->cookie = argp->cookie; | 394 | resp->cookie = argp->cookie; |
| 400 | 395 | ||
| 401 | /* Don't accept requests during grace period */ | 396 | /* Don't accept requests during grace period */ |
| 402 | if (locks_in_grace(SVC_NET(rqstp))) { | 397 | if (locks_in_grace()) { |
| 403 | resp->status = nlm_lck_denied_grace_period; | 398 | resp->status = nlm_lck_denied_grace_period; |
| 404 | return rpc_success; | 399 | return rpc_success; |
| 405 | } | 400 | } |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 0deb5f6c9dd..1ca0679c80b 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
| @@ -309,8 +309,7 @@ nlm_release_file(struct nlm_file *file) | |||
| 309 | * Helpers function for resource traversal | 309 | * Helpers function for resource traversal |
| 310 | * | 310 | * |
| 311 | * nlmsvc_mark_host: | 311 | * nlmsvc_mark_host: |
| 312 | * used by the garbage collector; simply sets h_inuse only for those | 312 | * used by the garbage collector; simply sets h_inuse. |
| 313 | * hosts, which passed network check. | ||
| 314 | * Always returns 0. | 313 | * Always returns 0. |
| 315 | * | 314 | * |
| 316 | * nlmsvc_same_host: | 315 | * nlmsvc_same_host: |
| @@ -321,15 +320,12 @@ nlm_release_file(struct nlm_file *file) | |||
| 321 | * returns 1 iff the host is a client. | 320 | * returns 1 iff the host is a client. |
| 322 | * Used by nlmsvc_invalidate_all | 321 | * Used by nlmsvc_invalidate_all |
| 323 | */ | 322 | */ |
| 324 | |||
| 325 | static int | 323 | static int |
| 326 | nlmsvc_mark_host(void *data, struct nlm_host *hint) | 324 | nlmsvc_mark_host(void *data, struct nlm_host *dummy) |
| 327 | { | 325 | { |
| 328 | struct nlm_host *host = data; | 326 | struct nlm_host *host = data; |
| 329 | 327 | ||
| 330 | if ((hint->net == NULL) || | 328 | host->h_inuse = 1; |
| 331 | (host->net == hint->net)) | ||
| 332 | host->h_inuse = 1; | ||
| 333 | return 0; | 329 | return 0; |
| 334 | } | 330 | } |
| 335 | 331 | ||
| @@ -362,13 +358,10 @@ nlmsvc_is_client(void *data, struct nlm_host *dummy) | |||
| 362 | * Mark all hosts that still hold resources | 358 | * Mark all hosts that still hold resources |
| 363 | */ | 359 | */ |
| 364 | void | 360 | void |
| 365 | nlmsvc_mark_resources(struct net *net) | 361 | nlmsvc_mark_resources(void) |
| 366 | { | 362 | { |
| 367 | struct nlm_host hint; | 363 | dprintk("lockd: nlmsvc_mark_resources\n"); |
| 368 | 364 | nlm_traverse_files(NULL, nlmsvc_mark_host, NULL); | |
| 369 | dprintk("lockd: nlmsvc_mark_resources for net %p\n", net); | ||
| 370 | hint.net = net; | ||
| 371 | nlm_traverse_files(&hint, nlmsvc_mark_host, NULL); | ||
| 372 | } | 365 | } |
| 373 | 366 | ||
| 374 | /* | 367 | /* |
| @@ -410,7 +403,7 @@ nlmsvc_match_sb(void *datap, struct nlm_file *file) | |||
| 410 | { | 403 | { |
| 411 | struct super_block *sb = datap; | 404 | struct super_block *sb = datap; |
| 412 | 405 | ||
| 413 | return sb == file->f_file->f_path.dentry->d_sb; | 406 | return sb == file->f_file->f_path.mnt->mnt_sb; |
| 414 | } | 407 | } |
| 415 | 408 | ||
| 416 | /** | 409 | /** |
