Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfs-for-3.10-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:

- Stable fix to prevent an rpc_task wakeup race
- Fix a NFSv4.1 session drain deadlock
- Fix a NFSv4/v4.1 mount regression when not running rpc.gssd
- Ensure auth_gss pipe detection works in namespaces
- Fix SETCLIENTID fallback if rpcsec_gss is not available

* tag 'nfs-for-3.10-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFS: Fix SETCLIENTID fallback if GSS is not available
SUNRPC: Prevent an rpc_task wakeup race
NFSv4.1 Fix a pNFS session draining deadlock
SUNRPC: Convert auth_gss pipe detection to work in namespaces
SUNRPC: Faster detection if gssd is actually running
SUNRPC: Fix a bug in gss_create_upcall

+78 -41
+1 -1
fs/nfs/callback_proc.c
··· 414 414 415 415 spin_lock(&tbl->slot_tbl_lock); 416 416 /* state manager is resetting the session */ 417 - if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) { 417 + if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { 418 418 spin_unlock(&tbl->slot_tbl_lock); 419 419 status = htonl(NFS4ERR_DELAY); 420 420 /* Return NFS4ERR_BADSESSION if we're draining the session
+1 -1
fs/nfs/callback_xdr.c
··· 763 763 * A single slot, so highest used slotid is either 0 or -1 764 764 */ 765 765 tbl->highest_used_slotid = NFS4_NO_SLOT; 766 - nfs4_session_drain_complete(session, tbl); 766 + nfs4_slot_tbl_drain_complete(tbl); 767 767 spin_unlock(&tbl->slot_tbl_lock); 768 768 } 769 769
+1 -1
fs/nfs/nfs4client.c
··· 203 203 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); 204 204 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); 205 205 if (error == -EINVAL) 206 - error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_NULL); 206 + error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); 207 207 if (error < 0) 208 208 goto error; 209 209
+1 -1
fs/nfs/nfs4proc.c
··· 572 572 task->tk_timeout = 0; 573 573 574 574 spin_lock(&tbl->slot_tbl_lock); 575 - if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && 575 + if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state) && 576 576 !args->sa_privileged) { 577 577 /* The state manager will wait until the slot table is empty */ 578 578 dprintk("%s session is draining\n", __func__);
+2 -2
fs/nfs/nfs4session.c
··· 73 73 tbl->highest_used_slotid = new_max; 74 74 else { 75 75 tbl->highest_used_slotid = NFS4_NO_SLOT; 76 - nfs4_session_drain_complete(tbl->session, tbl); 76 + nfs4_slot_tbl_drain_complete(tbl); 77 77 } 78 78 } 79 79 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__, ··· 226 226 struct nfs4_slot *slot = pslot; 227 227 struct nfs4_slot_table *tbl = slot->table; 228 228 229 - if (nfs4_session_draining(tbl->session) && !args->sa_privileged) 229 + if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged) 230 230 return false; 231 231 slot->generation = tbl->generation; 232 232 args->sa_slot = slot;
+8 -5
fs/nfs/nfs4session.h
··· 25 25 }; 26 26 27 27 /* Sessions */ 28 + enum nfs4_slot_tbl_state { 29 + NFS4_SLOT_TBL_DRAINING, 30 + }; 31 + 28 32 #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) 29 33 struct nfs4_slot_table { 30 34 struct nfs4_session *session; /* Parent session */ ··· 47 43 unsigned long generation; /* Generation counter for 48 44 target_highest_slotid */ 49 45 struct completion complete; 46 + unsigned long slot_tbl_state; 50 47 }; 51 48 52 49 /* ··· 73 68 74 69 enum nfs4_session_state { 75 70 NFS4_SESSION_INITING, 76 - NFS4_SESSION_DRAINING, 77 71 }; 78 72 79 73 #if defined(CONFIG_NFS_V4_1) ··· 92 88 extern int nfs4_init_session(struct nfs_server *server); 93 89 extern int nfs4_init_ds_session(struct nfs_client *, unsigned long); 94 90 95 - extern void nfs4_session_drain_complete(struct nfs4_session *session, 96 - struct nfs4_slot_table *tbl); 91 + extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); 97 92 98 - static inline bool nfs4_session_draining(struct nfs4_session *session) 93 + static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl) 99 94 { 100 - return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state); 95 + return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); 101 96 } 102 97 103 98 bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
+7 -8
fs/nfs/nfs4state.c
··· 241 241 if (ses == NULL) 242 242 return; 243 243 tbl = &ses->fc_slot_table; 244 - if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) { 244 + if (test_and_clear_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) { 245 245 spin_lock(&tbl->slot_tbl_lock); 246 246 nfs41_wake_slot_table(tbl); 247 247 spin_unlock(&tbl->slot_tbl_lock); ··· 251 251 /* 252 252 * Signal state manager thread if session fore channel is drained 253 253 */ 254 - void nfs4_session_drain_complete(struct nfs4_session *session, 255 - struct nfs4_slot_table *tbl) 254 + void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl) 256 255 { 257 - if (nfs4_session_draining(session)) 256 + if (nfs4_slot_tbl_draining(tbl)) 258 257 complete(&tbl->complete); 259 258 } 260 259 261 - static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl) 260 + static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl) 262 261 { 262 + set_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state); 263 263 spin_lock(&tbl->slot_tbl_lock); 264 264 if (tbl->highest_used_slotid != NFS4_NO_SLOT) { 265 265 INIT_COMPLETION(tbl->complete); ··· 275 275 struct nfs4_session *ses = clp->cl_session; 276 276 int ret = 0; 277 277 278 - set_bit(NFS4_SESSION_DRAINING, &ses->session_state); 279 278 /* back channel */ 280 - ret = nfs4_wait_on_slot_tbl(&ses->bc_slot_table); 279 + ret = nfs4_drain_slot_tbl(&ses->bc_slot_table); 281 280 if (ret) 282 281 return ret; 283 282 /* fore channel */ 284 - return nfs4_wait_on_slot_tbl(&ses->fc_slot_table); 283 + return nfs4_drain_slot_tbl(&ses->fc_slot_table); 285 284 } 286 285 287 286 static void nfs41_finish_session_reset(struct nfs_client *clp)
+41 -21
net/sunrpc/auth_gss/auth_gss.c
··· 52 52 #include <linux/sunrpc/gss_api.h> 53 53 #include <asm/uaccess.h> 54 54 55 + #include "../netns.h" 56 + 55 57 static const struct rpc_authops authgss_ops; 56 58 57 59 static const struct rpc_credops gss_credops; ··· 87 85 }; 88 86 89 87 /* pipe_version >= 0 if and only if someone has a pipe open. */ 90 - static int pipe_version = -1; 91 - static atomic_t pipe_users = ATOMIC_INIT(0); 92 88 static DEFINE_SPINLOCK(pipe_version_lock); 93 89 static struct rpc_wait_queue pipe_version_rpc_waitqueue; 94 90 static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); ··· 266 266 char databuf[UPCALL_BUF_LEN]; 267 267 }; 268 268 269 - static int get_pipe_version(void) 269 + static int get_pipe_version(struct net *net) 270 270 { 271 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 271 272 int ret; 272 273 273 274 spin_lock(&pipe_version_lock); 274 - if (pipe_version >= 0) { 275 - atomic_inc(&pipe_users); 276 - ret = pipe_version; 275 + if (sn->pipe_version >= 0) { 276 + atomic_inc(&sn->pipe_users); 277 + ret = sn->pipe_version; 277 278 } else 278 279 ret = -EAGAIN; 279 280 spin_unlock(&pipe_version_lock); 280 281 return ret; 281 282 } 282 283 283 - static void put_pipe_version(void) 284 + static void put_pipe_version(struct net *net) 284 285 { 285 - if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) { 286 - pipe_version = -1; 286 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 287 + 288 + if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) { 289 + sn->pipe_version = -1; 287 290 spin_unlock(&pipe_version_lock); 288 291 } 289 292 } ··· 294 291 static void 295 292 gss_release_msg(struct gss_upcall_msg *gss_msg) 296 293 { 294 + struct net *net = rpc_net_ns(gss_msg->auth->client); 297 295 if (!atomic_dec_and_test(&gss_msg->count)) 298 296 return; 299 - put_pipe_version(); 297 + put_pipe_version(net); 300 298 BUG_ON(!list_empty(&gss_msg->list)); 301 299 if (gss_msg->ctx != NULL) 302 300 gss_put_ctx(gss_msg->ctx); ··· 443 439 struct rpc_clnt *clnt, 444 440 const char *service_name) 445 441 { 446 - if (pipe_version == 0) 442 + struct net *net = rpc_net_ns(clnt); 443 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 444 + 445 + if (sn->pipe_version == 0) 447 446 gss_encode_v0_msg(gss_msg); 448 447 else /* pipe_version == 1 */ 449 448 gss_encode_v1_msg(gss_msg, clnt, service_name); ··· 462 455 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); 463 456 if (gss_msg == NULL) 464 457 return ERR_PTR(-ENOMEM); 465 - vers = get_pipe_version(); 458 + vers = get_pipe_version(rpc_net_ns(clnt)); 466 459 if (vers < 0) { 467 460 kfree(gss_msg); 468 461 return ERR_PTR(vers); ··· 566 559 static inline int 567 560 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 568 561 { 562 + struct net *net = rpc_net_ns(gss_auth->client); 563 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 569 564 struct rpc_pipe *pipe; 570 565 struct rpc_cred *cred = &gss_cred->gc_base; 571 566 struct gss_upcall_msg *gss_msg; 567 + unsigned long timeout; 572 568 DEFINE_WAIT(wait); 573 - int err = 0; 569 + int err; 574 570 575 571 dprintk("RPC: %s for uid %u\n", 576 572 __func__, from_kuid(&init_user_ns, cred->cr_uid)); 577 573 retry: 574 + err = 0; 575 + /* Default timeout is 15s unless we know that gssd is not running */ 576 + timeout = 15 * HZ; 577 + if (!sn->gssd_running) 578 + timeout = HZ >> 2; 578 579 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); 579 580 if (PTR_ERR(gss_msg) == -EAGAIN) { 580 581 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 581 - pipe_version >= 0, 15*HZ); 582 - if (pipe_version < 0) { 582 + sn->pipe_version >= 0, timeout); 583 + if (sn->pipe_version < 0) { 584 + if (err == 0) 585 + sn->gssd_running = 0; 583 586 warn_gssd(); 584 587 err = -EACCES; 585 588 } 586 - if (err) 589 + if (err < 0) 587 590 goto out; 588 591 goto retry; 589 592 } ··· 724 707 725 708 static int gss_pipe_open(struct inode *inode, int new_version) 726 709 { 710 + struct net *net = inode->i_sb->s_fs_info; 711 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 727 712 int ret = 0; 728 713 729 714 spin_lock(&pipe_version_lock); 730 - if (pipe_version < 0) { 715 + if (sn->pipe_version < 0) { 731 716 /* First open of any gss pipe determines the version: */ 732 - pipe_version = new_version; 717 + sn->pipe_version = new_version; 733 718 rpc_wake_up(&pipe_version_rpc_waitqueue); 734 719 wake_up(&pipe_version_waitqueue); 735 - } else if (pipe_version != new_version) { 720 + } else if (sn->pipe_version != new_version) { 736 721 /* Trying to open a pipe of a different version */ 737 722 ret = -EBUSY; 738 723 goto out; 739 724 } 740 - atomic_inc(&pipe_users); 725 + atomic_inc(&sn->pipe_users); 741 726 out: 742 727 spin_unlock(&pipe_version_lock); 743 728 return ret; ··· 759 740 static void 760 741 gss_pipe_release(struct inode *inode) 761 742 { 743 + struct net *net = inode->i_sb->s_fs_info; 762 744 struct rpc_pipe *pipe = RPC_I(inode)->pipe; 763 745 struct gss_upcall_msg *gss_msg; 764 746 ··· 778 758 } 779 759 spin_unlock(&pipe->lock); 780 760 781 - put_pipe_version(); 761 + put_pipe_version(net); 782 762 } 783 763 784 764 static void
+4
net/sunrpc/netns.h
··· 28 28 wait_queue_head_t gssp_wq; 29 29 struct rpc_clnt *gssp_clnt; 30 30 int use_gss_proxy; 31 + int pipe_version; 32 + atomic_t pipe_users; 31 33 struct proc_dir_entry *use_gssp_proc; 34 + 35 + unsigned int gssd_running; 32 36 }; 33 37 34 38 extern int sunrpc_net_id;
+5
net/sunrpc/rpc_pipe.c
··· 216 216 static int 217 217 rpc_pipe_open(struct inode *inode, struct file *filp) 218 218 { 219 + struct net *net = inode->i_sb->s_fs_info; 220 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 219 221 struct rpc_pipe *pipe; 220 222 int first_open; 221 223 int res = -ENXIO; 222 224 223 225 mutex_lock(&inode->i_mutex); 226 + sn->gssd_running = 1; 224 227 pipe = RPC_I(inode)->pipe; 225 228 if (pipe == NULL) 226 229 goto out; ··· 1072 1069 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1073 1070 1074 1071 mutex_init(&sn->pipefs_sb_lock); 1072 + sn->gssd_running = 1; 1073 + sn->pipe_version = -1; 1075 1074 } 1076 1075 1077 1076 /*
+7 -1
net/sunrpc/sched.c
··· 324 324 * Note: If the task is ASYNC, and is being made runnable after sitting on an 325 325 * rpc_wait_queue, this must be called with the queue spinlock held to protect 326 326 * the wait queue operation. 327 + * Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(), 328 + * which is needed to ensure that __rpc_execute() doesn't loop (due to the 329 + * lockless RPC_IS_QUEUED() test) before we've had a chance to test 330 + * the RPC_TASK_RUNNING flag. 327 331 */ 328 332 static void rpc_make_runnable(struct rpc_task *task) 329 333 { 334 + bool need_wakeup = !rpc_test_and_set_running(task); 335 + 330 336 rpc_clear_queued(task); 331 - if (rpc_test_and_set_running(task)) 337 + if (!need_wakeup) 332 338 return; 333 339 if (RPC_IS_ASYNC(task)) { 334 340 INIT_WORK(&task->u.tk_work, rpc_async_schedule);