diff options
| author | Ingo Molnar <mingo@kernel.org> | 2015-01-28 09:30:32 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2015-01-28 09:30:32 -0500 |
| commit | 41ca5d4e9be11ea6ae040b51d9628a189fd82896 (patch) | |
| tree | f9c35cc37b9622f6cccd91b94548f44b9a534029 /fs | |
| parent | 0fcedc8631ec28ca25d3c0b116e8fa0c19dd5f6d (diff) | |
| parent | 3669ef9fa7d35f573ec9c0e0341b29251c2734a7 (diff) | |
Merge commit 3669ef9fa7d3 ("x86, tls: Interpret an all-zero struct user_desc as 'no segment'") into x86/asm
Pick up the latestest asm fixes before advancing it any further.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/fuse/dev.c | 51 | ||||
| -rw-r--r-- | fs/fuse/dir.c | 31 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 2 | ||||
| -rw-r--r-- | fs/fuse/inode.c | 5 | ||||
| -rw-r--r-- | fs/kernfs/dir.c | 12 | ||||
| -rw-r--r-- | fs/lockd/svc.c | 8 | ||||
| -rw-r--r-- | fs/nfs/nfs4client.c | 42 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 21 |
8 files changed, 114 insertions, 58 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ba1107977f2e..ed19a7d622fa 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -131,6 +131,13 @@ static void fuse_req_init_context(struct fuse_req *req) | |||
| 131 | req->in.h.pid = current->pid; | 131 | req->in.h.pid = current->pid; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | void fuse_set_initialized(struct fuse_conn *fc) | ||
| 135 | { | ||
| 136 | /* Make sure stores before this are seen on another CPU */ | ||
| 137 | smp_wmb(); | ||
| 138 | fc->initialized = 1; | ||
| 139 | } | ||
| 140 | |||
| 134 | static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) | 141 | static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) |
| 135 | { | 142 | { |
| 136 | return !fc->initialized || (for_background && fc->blocked); | 143 | return !fc->initialized || (for_background && fc->blocked); |
| @@ -155,6 +162,8 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, | |||
| 155 | if (intr) | 162 | if (intr) |
| 156 | goto out; | 163 | goto out; |
| 157 | } | 164 | } |
| 165 | /* Matches smp_wmb() in fuse_set_initialized() */ | ||
| 166 | smp_rmb(); | ||
| 158 | 167 | ||
| 159 | err = -ENOTCONN; | 168 | err = -ENOTCONN; |
| 160 | if (!fc->connected) | 169 | if (!fc->connected) |
| @@ -253,6 +262,8 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, | |||
| 253 | 262 | ||
| 254 | atomic_inc(&fc->num_waiting); | 263 | atomic_inc(&fc->num_waiting); |
| 255 | wait_event(fc->blocked_waitq, fc->initialized); | 264 | wait_event(fc->blocked_waitq, fc->initialized); |
| 265 | /* Matches smp_wmb() in fuse_set_initialized() */ | ||
| 266 | smp_rmb(); | ||
| 256 | req = fuse_request_alloc(0); | 267 | req = fuse_request_alloc(0); |
| 257 | if (!req) | 268 | if (!req) |
| 258 | req = get_reserved_req(fc, file); | 269 | req = get_reserved_req(fc, file); |
| @@ -511,6 +522,39 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) | |||
| 511 | } | 522 | } |
| 512 | EXPORT_SYMBOL_GPL(fuse_request_send); | 523 | EXPORT_SYMBOL_GPL(fuse_request_send); |
| 513 | 524 | ||
| 525 | static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args) | ||
| 526 | { | ||
| 527 | if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS) | ||
| 528 | args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE; | ||
| 529 | |||
| 530 | if (fc->minor < 9) { | ||
| 531 | switch (args->in.h.opcode) { | ||
| 532 | case FUSE_LOOKUP: | ||
| 533 | case FUSE_CREATE: | ||
| 534 | case FUSE_MKNOD: | ||
| 535 | case FUSE_MKDIR: | ||
| 536 | case FUSE_SYMLINK: | ||
| 537 | case FUSE_LINK: | ||
| 538 | args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
| 539 | break; | ||
| 540 | case FUSE_GETATTR: | ||
| 541 | case FUSE_SETATTR: | ||
| 542 | args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; | ||
| 543 | break; | ||
| 544 | } | ||
| 545 | } | ||
| 546 | if (fc->minor < 12) { | ||
| 547 | switch (args->in.h.opcode) { | ||
| 548 | case FUSE_CREATE: | ||
| 549 | args->in.args[0].size = sizeof(struct fuse_open_in); | ||
| 550 | break; | ||
| 551 | case FUSE_MKNOD: | ||
| 552 | args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE; | ||
| 553 | break; | ||
| 554 | } | ||
| 555 | } | ||
| 556 | } | ||
| 557 | |||
| 514 | ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) | 558 | ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) |
| 515 | { | 559 | { |
| 516 | struct fuse_req *req; | 560 | struct fuse_req *req; |
| @@ -520,6 +564,9 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) | |||
| 520 | if (IS_ERR(req)) | 564 | if (IS_ERR(req)) |
| 521 | return PTR_ERR(req); | 565 | return PTR_ERR(req); |
| 522 | 566 | ||
| 567 | /* Needs to be done after fuse_get_req() so that fc->minor is valid */ | ||
| 568 | fuse_adjust_compat(fc, args); | ||
| 569 | |||
| 523 | req->in.h.opcode = args->in.h.opcode; | 570 | req->in.h.opcode = args->in.h.opcode; |
| 524 | req->in.h.nodeid = args->in.h.nodeid; | 571 | req->in.h.nodeid = args->in.h.nodeid; |
| 525 | req->in.numargs = args->in.numargs; | 572 | req->in.numargs = args->in.numargs; |
| @@ -2127,7 +2174,7 @@ void fuse_abort_conn(struct fuse_conn *fc) | |||
| 2127 | if (fc->connected) { | 2174 | if (fc->connected) { |
| 2128 | fc->connected = 0; | 2175 | fc->connected = 0; |
| 2129 | fc->blocked = 0; | 2176 | fc->blocked = 0; |
| 2130 | fc->initialized = 1; | 2177 | fuse_set_initialized(fc); |
| 2131 | end_io_requests(fc); | 2178 | end_io_requests(fc); |
| 2132 | end_queued_requests(fc); | 2179 | end_queued_requests(fc); |
| 2133 | end_polls(fc); | 2180 | end_polls(fc); |
| @@ -2146,7 +2193,7 @@ int fuse_dev_release(struct inode *inode, struct file *file) | |||
| 2146 | spin_lock(&fc->lock); | 2193 | spin_lock(&fc->lock); |
| 2147 | fc->connected = 0; | 2194 | fc->connected = 0; |
| 2148 | fc->blocked = 0; | 2195 | fc->blocked = 0; |
| 2149 | fc->initialized = 1; | 2196 | fuse_set_initialized(fc); |
| 2150 | end_queued_requests(fc); | 2197 | end_queued_requests(fc); |
| 2151 | end_polls(fc); | 2198 | end_polls(fc); |
| 2152 | wake_up_all(&fc->blocked_waitq); | 2199 | wake_up_all(&fc->blocked_waitq); |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 252b8a5de8b5..08e7b1a9d5d0 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -156,10 +156,7 @@ static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args, | |||
| 156 | args->in.args[0].size = name->len + 1; | 156 | args->in.args[0].size = name->len + 1; |
| 157 | args->in.args[0].value = name->name; | 157 | args->in.args[0].value = name->name; |
| 158 | args->out.numargs = 1; | 158 | args->out.numargs = 1; |
| 159 | if (fc->minor < 9) | 159 | args->out.args[0].size = sizeof(struct fuse_entry_out); |
| 160 | args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
| 161 | else | ||
| 162 | args->out.args[0].size = sizeof(struct fuse_entry_out); | ||
| 163 | args->out.args[0].value = outarg; | 160 | args->out.args[0].value = outarg; |
| 164 | } | 161 | } |
| 165 | 162 | ||
| @@ -422,16 +419,12 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
| 422 | args.in.h.opcode = FUSE_CREATE; | 419 | args.in.h.opcode = FUSE_CREATE; |
| 423 | args.in.h.nodeid = get_node_id(dir); | 420 | args.in.h.nodeid = get_node_id(dir); |
| 424 | args.in.numargs = 2; | 421 | args.in.numargs = 2; |
| 425 | args.in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) : | 422 | args.in.args[0].size = sizeof(inarg); |
| 426 | sizeof(inarg); | ||
| 427 | args.in.args[0].value = &inarg; | 423 | args.in.args[0].value = &inarg; |
| 428 | args.in.args[1].size = entry->d_name.len + 1; | 424 | args.in.args[1].size = entry->d_name.len + 1; |
| 429 | args.in.args[1].value = entry->d_name.name; | 425 | args.in.args[1].value = entry->d_name.name; |
| 430 | args.out.numargs = 2; | 426 | args.out.numargs = 2; |
| 431 | if (fc->minor < 9) | 427 | args.out.args[0].size = sizeof(outentry); |
| 432 | args.out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
| 433 | else | ||
| 434 | args.out.args[0].size = sizeof(outentry); | ||
| 435 | args.out.args[0].value = &outentry; | 428 | args.out.args[0].value = &outentry; |
| 436 | args.out.args[1].size = sizeof(outopen); | 429 | args.out.args[1].size = sizeof(outopen); |
| 437 | args.out.args[1].value = &outopen; | 430 | args.out.args[1].value = &outopen; |
| @@ -539,10 +532,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, | |||
| 539 | memset(&outarg, 0, sizeof(outarg)); | 532 | memset(&outarg, 0, sizeof(outarg)); |
| 540 | args->in.h.nodeid = get_node_id(dir); | 533 | args->in.h.nodeid = get_node_id(dir); |
| 541 | args->out.numargs = 1; | 534 | args->out.numargs = 1; |
| 542 | if (fc->minor < 9) | 535 | args->out.args[0].size = sizeof(outarg); |
| 543 | args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
| 544 | else | ||
| 545 | args->out.args[0].size = sizeof(outarg); | ||
| 546 | args->out.args[0].value = &outarg; | 536 | args->out.args[0].value = &outarg; |
| 547 | err = fuse_simple_request(fc, args); | 537 | err = fuse_simple_request(fc, args); |
| 548 | if (err) | 538 | if (err) |
| @@ -592,8 +582,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode, | |||
| 592 | inarg.umask = current_umask(); | 582 | inarg.umask = current_umask(); |
| 593 | args.in.h.opcode = FUSE_MKNOD; | 583 | args.in.h.opcode = FUSE_MKNOD; |
| 594 | args.in.numargs = 2; | 584 | args.in.numargs = 2; |
| 595 | args.in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE : | 585 | args.in.args[0].size = sizeof(inarg); |
| 596 | sizeof(inarg); | ||
| 597 | args.in.args[0].value = &inarg; | 586 | args.in.args[0].value = &inarg; |
| 598 | args.in.args[1].size = entry->d_name.len + 1; | 587 | args.in.args[1].size = entry->d_name.len + 1; |
| 599 | args.in.args[1].value = entry->d_name.name; | 588 | args.in.args[1].value = entry->d_name.name; |
| @@ -899,10 +888,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat, | |||
| 899 | args.in.args[0].size = sizeof(inarg); | 888 | args.in.args[0].size = sizeof(inarg); |
| 900 | args.in.args[0].value = &inarg; | 889 | args.in.args[0].value = &inarg; |
| 901 | args.out.numargs = 1; | 890 | args.out.numargs = 1; |
| 902 | if (fc->minor < 9) | 891 | args.out.args[0].size = sizeof(outarg); |
| 903 | args.out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; | ||
| 904 | else | ||
| 905 | args.out.args[0].size = sizeof(outarg); | ||
| 906 | args.out.args[0].value = &outarg; | 892 | args.out.args[0].value = &outarg; |
| 907 | err = fuse_simple_request(fc, &args); | 893 | err = fuse_simple_request(fc, &args); |
| 908 | if (!err) { | 894 | if (!err) { |
| @@ -1574,10 +1560,7 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args, | |||
| 1574 | args->in.args[0].size = sizeof(*inarg_p); | 1560 | args->in.args[0].size = sizeof(*inarg_p); |
| 1575 | args->in.args[0].value = inarg_p; | 1561 | args->in.args[0].value = inarg_p; |
| 1576 | args->out.numargs = 1; | 1562 | args->out.numargs = 1; |
| 1577 | if (fc->minor < 9) | 1563 | args->out.args[0].size = sizeof(*outarg_p); |
| 1578 | args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; | ||
| 1579 | else | ||
| 1580 | args->out.args[0].size = sizeof(*outarg_p); | ||
| 1581 | args->out.args[0].value = outarg_p; | 1564 | args->out.args[0].value = outarg_p; |
| 1582 | } | 1565 | } |
| 1583 | 1566 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e0fc6725d1d0..1cdfb07c1376 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -906,4 +906,6 @@ int fuse_write_inode(struct inode *inode, struct writeback_control *wbc); | |||
| 906 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, | 906 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, |
| 907 | struct file *file); | 907 | struct file *file); |
| 908 | 908 | ||
| 909 | void fuse_set_initialized(struct fuse_conn *fc); | ||
| 910 | |||
| 909 | #endif /* _FS_FUSE_I_H */ | 911 | #endif /* _FS_FUSE_I_H */ |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 6749109f255d..f38256e4476e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
| @@ -424,8 +424,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 424 | args.in.h.opcode = FUSE_STATFS; | 424 | args.in.h.opcode = FUSE_STATFS; |
| 425 | args.in.h.nodeid = get_node_id(dentry->d_inode); | 425 | args.in.h.nodeid = get_node_id(dentry->d_inode); |
| 426 | args.out.numargs = 1; | 426 | args.out.numargs = 1; |
| 427 | args.out.args[0].size = | 427 | args.out.args[0].size = sizeof(outarg); |
| 428 | fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); | ||
| 429 | args.out.args[0].value = &outarg; | 428 | args.out.args[0].value = &outarg; |
| 430 | err = fuse_simple_request(fc, &args); | 429 | err = fuse_simple_request(fc, &args); |
| 431 | if (!err) | 430 | if (!err) |
| @@ -898,7 +897,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
| 898 | fc->max_write = max_t(unsigned, 4096, fc->max_write); | 897 | fc->max_write = max_t(unsigned, 4096, fc->max_write); |
| 899 | fc->conn_init = 1; | 898 | fc->conn_init = 1; |
| 900 | } | 899 | } |
| 901 | fc->initialized = 1; | 900 | fuse_set_initialized(fc); |
| 902 | wake_up_all(&fc->blocked_waitq); | 901 | wake_up_all(&fc->blocked_waitq); |
| 903 | } | 902 | } |
| 904 | 903 | ||
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 37989f02a226..2d881b381d2b 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
| @@ -201,10 +201,14 @@ static unsigned int kernfs_name_hash(const char *name, const void *ns) | |||
| 201 | static int kernfs_name_compare(unsigned int hash, const char *name, | 201 | static int kernfs_name_compare(unsigned int hash, const char *name, |
| 202 | const void *ns, const struct kernfs_node *kn) | 202 | const void *ns, const struct kernfs_node *kn) |
| 203 | { | 203 | { |
| 204 | if (hash != kn->hash) | 204 | if (hash < kn->hash) |
| 205 | return hash - kn->hash; | 205 | return -1; |
| 206 | if (ns != kn->ns) | 206 | if (hash > kn->hash) |
| 207 | return ns - kn->ns; | 207 | return 1; |
| 208 | if (ns < kn->ns) | ||
| 209 | return -1; | ||
| 210 | if (ns > kn->ns) | ||
| 211 | return 1; | ||
| 208 | return strcmp(name, kn->name); | 212 | return strcmp(name, kn->name); |
| 209 | } | 213 | } |
| 210 | 214 | ||
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index e94c887da2d7..55505cbe11af 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
| @@ -138,10 +138,6 @@ lockd(void *vrqstp) | |||
| 138 | 138 | ||
| 139 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); | 139 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); |
| 140 | 140 | ||
| 141 | if (!nlm_timeout) | ||
| 142 | nlm_timeout = LOCKD_DFLT_TIMEO; | ||
| 143 | nlmsvc_timeout = nlm_timeout * HZ; | ||
| 144 | |||
| 145 | /* | 141 | /* |
| 146 | * The main request loop. We don't terminate until the last | 142 | * The main request loop. We don't terminate until the last |
| 147 | * NFS mount or NFS daemon has gone away. | 143 | * NFS mount or NFS daemon has gone away. |
| @@ -350,6 +346,10 @@ static struct svc_serv *lockd_create_svc(void) | |||
| 350 | printk(KERN_WARNING | 346 | printk(KERN_WARNING |
| 351 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | 347 | "lockd_up: no pid, %d users??\n", nlmsvc_users); |
| 352 | 348 | ||
| 349 | if (!nlm_timeout) | ||
| 350 | nlm_timeout = LOCKD_DFLT_TIMEO; | ||
| 351 | nlmsvc_timeout = nlm_timeout * HZ; | ||
| 352 | |||
| 353 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, svc_rpcb_cleanup); | 353 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, svc_rpcb_cleanup); |
| 354 | if (!serv) { | 354 | if (!serv) { |
| 355 | printk(KERN_WARNING "lockd_up: create service failed\n"); | 355 | printk(KERN_WARNING "lockd_up: create service failed\n"); |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 03311259b0c4..953daa44a282 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
| @@ -228,6 +228,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp) | |||
| 228 | kfree(clp->cl_serverowner); | 228 | kfree(clp->cl_serverowner); |
| 229 | kfree(clp->cl_serverscope); | 229 | kfree(clp->cl_serverscope); |
| 230 | kfree(clp->cl_implid); | 230 | kfree(clp->cl_implid); |
| 231 | kfree(clp->cl_owner_id); | ||
| 231 | } | 232 | } |
| 232 | 233 | ||
| 233 | void nfs4_free_client(struct nfs_client *clp) | 234 | void nfs4_free_client(struct nfs_client *clp) |
| @@ -452,6 +453,14 @@ static void nfs4_swap_callback_idents(struct nfs_client *keep, | |||
| 452 | spin_unlock(&nn->nfs_client_lock); | 453 | spin_unlock(&nn->nfs_client_lock); |
| 453 | } | 454 | } |
| 454 | 455 | ||
| 456 | static bool nfs4_match_client_owner_id(const struct nfs_client *clp1, | ||
| 457 | const struct nfs_client *clp2) | ||
| 458 | { | ||
| 459 | if (clp1->cl_owner_id == NULL || clp2->cl_owner_id == NULL) | ||
| 460 | return true; | ||
| 461 | return strcmp(clp1->cl_owner_id, clp2->cl_owner_id) == 0; | ||
| 462 | } | ||
| 463 | |||
| 455 | /** | 464 | /** |
| 456 | * nfs40_walk_client_list - Find server that recognizes a client ID | 465 | * nfs40_walk_client_list - Find server that recognizes a client ID |
| 457 | * | 466 | * |
| @@ -483,9 +492,6 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
| 483 | if (pos->rpc_ops != new->rpc_ops) | 492 | if (pos->rpc_ops != new->rpc_ops) |
| 484 | continue; | 493 | continue; |
| 485 | 494 | ||
| 486 | if (pos->cl_proto != new->cl_proto) | ||
| 487 | continue; | ||
| 488 | |||
| 489 | if (pos->cl_minorversion != new->cl_minorversion) | 495 | if (pos->cl_minorversion != new->cl_minorversion) |
| 490 | continue; | 496 | continue; |
| 491 | 497 | ||
| @@ -510,6 +516,9 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
| 510 | if (pos->cl_clientid != new->cl_clientid) | 516 | if (pos->cl_clientid != new->cl_clientid) |
| 511 | continue; | 517 | continue; |
| 512 | 518 | ||
| 519 | if (!nfs4_match_client_owner_id(pos, new)) | ||
| 520 | continue; | ||
| 521 | |||
| 513 | atomic_inc(&pos->cl_count); | 522 | atomic_inc(&pos->cl_count); |
| 514 | spin_unlock(&nn->nfs_client_lock); | 523 | spin_unlock(&nn->nfs_client_lock); |
| 515 | 524 | ||
| @@ -566,20 +575,14 @@ static bool nfs4_match_clientids(struct nfs_client *a, struct nfs_client *b) | |||
| 566 | } | 575 | } |
| 567 | 576 | ||
| 568 | /* | 577 | /* |
| 569 | * Returns true if the server owners match | 578 | * Returns true if the server major ids match |
| 570 | */ | 579 | */ |
| 571 | static bool | 580 | static bool |
| 572 | nfs4_match_serverowners(struct nfs_client *a, struct nfs_client *b) | 581 | nfs4_check_clientid_trunking(struct nfs_client *a, struct nfs_client *b) |
| 573 | { | 582 | { |
| 574 | struct nfs41_server_owner *o1 = a->cl_serverowner; | 583 | struct nfs41_server_owner *o1 = a->cl_serverowner; |
| 575 | struct nfs41_server_owner *o2 = b->cl_serverowner; | 584 | struct nfs41_server_owner *o2 = b->cl_serverowner; |
| 576 | 585 | ||
| 577 | if (o1->minor_id != o2->minor_id) { | ||
| 578 | dprintk("NFS: --> %s server owner minor IDs do not match\n", | ||
| 579 | __func__); | ||
| 580 | return false; | ||
| 581 | } | ||
| 582 | |||
| 583 | if (o1->major_id_sz != o2->major_id_sz) | 586 | if (o1->major_id_sz != o2->major_id_sz) |
| 584 | goto out_major_mismatch; | 587 | goto out_major_mismatch; |
| 585 | if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) | 588 | if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) |
| @@ -621,9 +624,6 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
| 621 | if (pos->rpc_ops != new->rpc_ops) | 624 | if (pos->rpc_ops != new->rpc_ops) |
| 622 | continue; | 625 | continue; |
| 623 | 626 | ||
| 624 | if (pos->cl_proto != new->cl_proto) | ||
| 625 | continue; | ||
| 626 | |||
| 627 | if (pos->cl_minorversion != new->cl_minorversion) | 627 | if (pos->cl_minorversion != new->cl_minorversion) |
| 628 | continue; | 628 | continue; |
| 629 | 629 | ||
| @@ -654,7 +654,19 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
| 654 | if (!nfs4_match_clientids(pos, new)) | 654 | if (!nfs4_match_clientids(pos, new)) |
| 655 | continue; | 655 | continue; |
| 656 | 656 | ||
| 657 | if (!nfs4_match_serverowners(pos, new)) | 657 | /* |
| 658 | * Note that session trunking is just a special subcase of | ||
| 659 | * client id trunking. In either case, we want to fall back | ||
| 660 | * to using the existing nfs_client. | ||
| 661 | */ | ||
| 662 | if (!nfs4_check_clientid_trunking(pos, new)) | ||
| 663 | continue; | ||
| 664 | |||
| 665 | /* Unlike NFSv4.0, we know that NFSv4.1 always uses the | ||
| 666 | * uniform string, however someone might switch the | ||
| 667 | * uniquifier string on us. | ||
| 668 | */ | ||
| 669 | if (!nfs4_match_client_owner_id(pos, new)) | ||
| 658 | continue; | 670 | continue; |
| 659 | 671 | ||
| 660 | atomic_inc(&pos->cl_count); | 672 | atomic_inc(&pos->cl_count); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e7f8d5ff2581..c347705b0161 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -1117,8 +1117,6 @@ static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode) | |||
| 1117 | return 0; | 1117 | return 0; |
| 1118 | if ((delegation->type & fmode) != fmode) | 1118 | if ((delegation->type & fmode) != fmode) |
| 1119 | return 0; | 1119 | return 0; |
| 1120 | if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags)) | ||
| 1121 | return 0; | ||
| 1122 | if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) | 1120 | if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) |
| 1123 | return 0; | 1121 | return 0; |
| 1124 | nfs_mark_delegation_referenced(delegation); | 1122 | nfs_mark_delegation_referenced(delegation); |
| @@ -4917,11 +4915,14 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp, | |||
| 4917 | } | 4915 | } |
| 4918 | 4916 | ||
| 4919 | static unsigned int | 4917 | static unsigned int |
| 4920 | nfs4_init_nonuniform_client_string(const struct nfs_client *clp, | 4918 | nfs4_init_nonuniform_client_string(struct nfs_client *clp, |
| 4921 | char *buf, size_t len) | 4919 | char *buf, size_t len) |
| 4922 | { | 4920 | { |
| 4923 | unsigned int result; | 4921 | unsigned int result; |
| 4924 | 4922 | ||
| 4923 | if (clp->cl_owner_id != NULL) | ||
| 4924 | return strlcpy(buf, clp->cl_owner_id, len); | ||
| 4925 | |||
| 4925 | rcu_read_lock(); | 4926 | rcu_read_lock(); |
| 4926 | result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s", | 4927 | result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s", |
| 4927 | clp->cl_ipaddr, | 4928 | clp->cl_ipaddr, |
| @@ -4930,24 +4931,32 @@ nfs4_init_nonuniform_client_string(const struct nfs_client *clp, | |||
| 4930 | rpc_peeraddr2str(clp->cl_rpcclient, | 4931 | rpc_peeraddr2str(clp->cl_rpcclient, |
| 4931 | RPC_DISPLAY_PROTO)); | 4932 | RPC_DISPLAY_PROTO)); |
| 4932 | rcu_read_unlock(); | 4933 | rcu_read_unlock(); |
| 4934 | clp->cl_owner_id = kstrdup(buf, GFP_KERNEL); | ||
| 4933 | return result; | 4935 | return result; |
| 4934 | } | 4936 | } |
| 4935 | 4937 | ||
| 4936 | static unsigned int | 4938 | static unsigned int |
| 4937 | nfs4_init_uniform_client_string(const struct nfs_client *clp, | 4939 | nfs4_init_uniform_client_string(struct nfs_client *clp, |
| 4938 | char *buf, size_t len) | 4940 | char *buf, size_t len) |
| 4939 | { | 4941 | { |
| 4940 | const char *nodename = clp->cl_rpcclient->cl_nodename; | 4942 | const char *nodename = clp->cl_rpcclient->cl_nodename; |
| 4943 | unsigned int result; | ||
| 4944 | |||
| 4945 | if (clp->cl_owner_id != NULL) | ||
| 4946 | return strlcpy(buf, clp->cl_owner_id, len); | ||
| 4941 | 4947 | ||
| 4942 | if (nfs4_client_id_uniquifier[0] != '\0') | 4948 | if (nfs4_client_id_uniquifier[0] != '\0') |
| 4943 | return scnprintf(buf, len, "Linux NFSv%u.%u %s/%s", | 4949 | result = scnprintf(buf, len, "Linux NFSv%u.%u %s/%s", |
| 4944 | clp->rpc_ops->version, | 4950 | clp->rpc_ops->version, |
| 4945 | clp->cl_minorversion, | 4951 | clp->cl_minorversion, |
| 4946 | nfs4_client_id_uniquifier, | 4952 | nfs4_client_id_uniquifier, |
| 4947 | nodename); | 4953 | nodename); |
| 4948 | return scnprintf(buf, len, "Linux NFSv%u.%u %s", | 4954 | else |
| 4955 | result = scnprintf(buf, len, "Linux NFSv%u.%u %s", | ||
| 4949 | clp->rpc_ops->version, clp->cl_minorversion, | 4956 | clp->rpc_ops->version, clp->cl_minorversion, |
| 4950 | nodename); | 4957 | nodename); |
| 4958 | clp->cl_owner_id = kstrdup(buf, GFP_KERNEL); | ||
| 4959 | return result; | ||
| 4951 | } | 4960 | } |
| 4952 | 4961 | ||
| 4953 | /* | 4962 | /* |
