diff options
author | Dave Airlie <airlied@redhat.com> | 2013-02-07 21:10:18 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-02-07 21:10:18 -0500 |
commit | 6dc1c49da6dd3bf020a66b2a135b9625ac01c2c7 (patch) | |
tree | 38a6c5d4896de01449e9d224088ae223161fcd3c /fs/nfs | |
parent | cd17ef4114ad5c514b17e6a0bb02a309ab90b692 (diff) | |
parent | 5845b81bdad374f98f809a658ec747d92c9595c4 (diff) |
Merge branch 'fbcon-locking-fixes' of ssh://people.freedesktop.org/~airlied/linux into drm-next
This pulls in most of Linus tree up to -rc6, this fixes the worst lockdep
reported issues and re-enables fbcon lockdep.
(not the fbcon maintainer)
* 'fbcon-locking-fixes' of ssh://people.freedesktop.org/~airlied/linux: (529 commits)
Revert "Revert "console: implement lockdep support for console_lock""
fbcon: fix locking harder
fb: Yet another band-aid for fixing lockdep mess
fb: rework locking to fix lock ordering on takeover
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/namespace.c | 20 | ||||
-rw-r--r-- | fs/nfs/nfs4client.c | 62 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 22 | ||||
-rw-r--r-- | fs/nfs/super.c | 22 |
4 files changed, 69 insertions, 57 deletions
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index dd057bc6b65b..fc8dc20fdeb9 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
@@ -177,11 +177,31 @@ out_nofree: | |||
177 | return mnt; | 177 | return mnt; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int | ||
181 | nfs_namespace_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | ||
182 | { | ||
183 | if (NFS_FH(dentry->d_inode)->size != 0) | ||
184 | return nfs_getattr(mnt, dentry, stat); | ||
185 | generic_fillattr(dentry->d_inode, stat); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int | ||
190 | nfs_namespace_setattr(struct dentry *dentry, struct iattr *attr) | ||
191 | { | ||
192 | if (NFS_FH(dentry->d_inode)->size != 0) | ||
193 | return nfs_setattr(dentry, attr); | ||
194 | return -EACCES; | ||
195 | } | ||
196 | |||
180 | const struct inode_operations nfs_mountpoint_inode_operations = { | 197 | const struct inode_operations nfs_mountpoint_inode_operations = { |
181 | .getattr = nfs_getattr, | 198 | .getattr = nfs_getattr, |
199 | .setattr = nfs_setattr, | ||
182 | }; | 200 | }; |
183 | 201 | ||
184 | const struct inode_operations nfs_referral_inode_operations = { | 202 | const struct inode_operations nfs_referral_inode_operations = { |
203 | .getattr = nfs_namespace_getattr, | ||
204 | .setattr = nfs_namespace_setattr, | ||
185 | }; | 205 | }; |
186 | 206 | ||
187 | static void nfs_expire_automounts(struct work_struct *work) | 207 | static void nfs_expire_automounts(struct work_struct *work) |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index acc347268124..2e9779b58b7a 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -236,11 +236,10 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, | |||
236 | error = nfs4_discover_server_trunking(clp, &old); | 236 | error = nfs4_discover_server_trunking(clp, &old); |
237 | if (error < 0) | 237 | if (error < 0) |
238 | goto error; | 238 | goto error; |
239 | nfs_put_client(clp); | ||
239 | if (clp != old) { | 240 | if (clp != old) { |
240 | clp->cl_preserve_clid = true; | 241 | clp->cl_preserve_clid = true; |
241 | nfs_put_client(clp); | ||
242 | clp = old; | 242 | clp = old; |
243 | atomic_inc(&clp->cl_count); | ||
244 | } | 243 | } |
245 | 244 | ||
246 | return clp; | 245 | return clp; |
@@ -306,7 +305,7 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
306 | .clientid = new->cl_clientid, | 305 | .clientid = new->cl_clientid, |
307 | .confirm = new->cl_confirm, | 306 | .confirm = new->cl_confirm, |
308 | }; | 307 | }; |
309 | int status; | 308 | int status = -NFS4ERR_STALE_CLIENTID; |
310 | 309 | ||
311 | spin_lock(&nn->nfs_client_lock); | 310 | spin_lock(&nn->nfs_client_lock); |
312 | list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { | 311 | list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { |
@@ -332,40 +331,33 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
332 | 331 | ||
333 | if (prev) | 332 | if (prev) |
334 | nfs_put_client(prev); | 333 | nfs_put_client(prev); |
334 | prev = pos; | ||
335 | 335 | ||
336 | status = nfs4_proc_setclientid_confirm(pos, &clid, cred); | 336 | status = nfs4_proc_setclientid_confirm(pos, &clid, cred); |
337 | if (status == 0) { | 337 | switch (status) { |
338 | case -NFS4ERR_STALE_CLIENTID: | ||
339 | break; | ||
340 | case 0: | ||
338 | nfs4_swap_callback_idents(pos, new); | 341 | nfs4_swap_callback_idents(pos, new); |
339 | 342 | ||
340 | nfs_put_client(pos); | 343 | prev = NULL; |
341 | *result = pos; | 344 | *result = pos; |
342 | dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", | 345 | dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", |
343 | __func__, pos, atomic_read(&pos->cl_count)); | 346 | __func__, pos, atomic_read(&pos->cl_count)); |
344 | return 0; | 347 | default: |
345 | } | 348 | goto out; |
346 | if (status != -NFS4ERR_STALE_CLIENTID) { | ||
347 | nfs_put_client(pos); | ||
348 | dprintk("NFS: <-- %s status = %d, no result\n", | ||
349 | __func__, status); | ||
350 | return status; | ||
351 | } | 349 | } |
352 | 350 | ||
353 | spin_lock(&nn->nfs_client_lock); | 351 | spin_lock(&nn->nfs_client_lock); |
354 | prev = pos; | ||
355 | } | 352 | } |
353 | spin_unlock(&nn->nfs_client_lock); | ||
356 | 354 | ||
357 | /* | 355 | /* No match found. The server lost our clientid */ |
358 | * No matching nfs_client found. This should be impossible, | 356 | out: |
359 | * because the new nfs_client has already been added to | ||
360 | * nfs_client_list by nfs_get_client(). | ||
361 | * | ||
362 | * Don't BUG(), since the caller is holding a mutex. | ||
363 | */ | ||
364 | if (prev) | 357 | if (prev) |
365 | nfs_put_client(prev); | 358 | nfs_put_client(prev); |
366 | spin_unlock(&nn->nfs_client_lock); | 359 | dprintk("NFS: <-- %s status = %d\n", __func__, status); |
367 | pr_err("NFS: %s Error: no matching nfs_client found\n", __func__); | 360 | return status; |
368 | return -NFS4ERR_STALE_CLIENTID; | ||
369 | } | 361 | } |
370 | 362 | ||
371 | #ifdef CONFIG_NFS_V4_1 | 363 | #ifdef CONFIG_NFS_V4_1 |
@@ -432,7 +424,7 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
432 | { | 424 | { |
433 | struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); | 425 | struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); |
434 | struct nfs_client *pos, *n, *prev = NULL; | 426 | struct nfs_client *pos, *n, *prev = NULL; |
435 | int error; | 427 | int status = -NFS4ERR_STALE_CLIENTID; |
436 | 428 | ||
437 | spin_lock(&nn->nfs_client_lock); | 429 | spin_lock(&nn->nfs_client_lock); |
438 | list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { | 430 | list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { |
@@ -448,14 +440,17 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
448 | nfs_put_client(prev); | 440 | nfs_put_client(prev); |
449 | prev = pos; | 441 | prev = pos; |
450 | 442 | ||
451 | error = nfs_wait_client_init_complete(pos); | 443 | nfs4_schedule_lease_recovery(pos); |
452 | if (error < 0) { | 444 | status = nfs_wait_client_init_complete(pos); |
445 | if (status < 0) { | ||
453 | nfs_put_client(pos); | 446 | nfs_put_client(pos); |
454 | spin_lock(&nn->nfs_client_lock); | 447 | spin_lock(&nn->nfs_client_lock); |
455 | continue; | 448 | continue; |
456 | } | 449 | } |
457 | 450 | status = pos->cl_cons_state; | |
458 | spin_lock(&nn->nfs_client_lock); | 451 | spin_lock(&nn->nfs_client_lock); |
452 | if (status < 0) | ||
453 | continue; | ||
459 | } | 454 | } |
460 | 455 | ||
461 | if (pos->rpc_ops != new->rpc_ops) | 456 | if (pos->rpc_ops != new->rpc_ops) |
@@ -473,6 +468,7 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
473 | if (!nfs4_match_serverowners(pos, new)) | 468 | if (!nfs4_match_serverowners(pos, new)) |
474 | continue; | 469 | continue; |
475 | 470 | ||
471 | atomic_inc(&pos->cl_count); | ||
476 | spin_unlock(&nn->nfs_client_lock); | 472 | spin_unlock(&nn->nfs_client_lock); |
477 | dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", | 473 | dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", |
478 | __func__, pos, atomic_read(&pos->cl_count)); | 474 | __func__, pos, atomic_read(&pos->cl_count)); |
@@ -481,16 +477,10 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
481 | return 0; | 477 | return 0; |
482 | } | 478 | } |
483 | 479 | ||
484 | /* | 480 | /* No matching nfs_client found. */ |
485 | * No matching nfs_client found. This should be impossible, | ||
486 | * because the new nfs_client has already been added to | ||
487 | * nfs_client_list by nfs_get_client(). | ||
488 | * | ||
489 | * Don't BUG(), since the caller is holding a mutex. | ||
490 | */ | ||
491 | spin_unlock(&nn->nfs_client_lock); | 481 | spin_unlock(&nn->nfs_client_lock); |
492 | pr_err("NFS: %s Error: no matching nfs_client found\n", __func__); | 482 | dprintk("NFS: <-- %s status = %d\n", __func__, status); |
493 | return -NFS4ERR_STALE_CLIENTID; | 483 | return status; |
494 | } | 484 | } |
495 | #endif /* CONFIG_NFS_V4_1 */ | 485 | #endif /* CONFIG_NFS_V4_1 */ |
496 | 486 | ||
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 9448c579d41a..e61f68d5ef21 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -136,16 +136,11 @@ int nfs40_discover_server_trunking(struct nfs_client *clp, | |||
136 | clp->cl_confirm = clid.confirm; | 136 | clp->cl_confirm = clid.confirm; |
137 | 137 | ||
138 | status = nfs40_walk_client_list(clp, result, cred); | 138 | status = nfs40_walk_client_list(clp, result, cred); |
139 | switch (status) { | 139 | if (status == 0) { |
140 | case -NFS4ERR_STALE_CLIENTID: | ||
141 | set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); | ||
142 | case 0: | ||
143 | /* Sustain the lease, even if it's empty. If the clientid4 | 140 | /* Sustain the lease, even if it's empty. If the clientid4 |
144 | * goes stale it's of no use for trunking discovery. */ | 141 | * goes stale it's of no use for trunking discovery. */ |
145 | nfs4_schedule_state_renewal(*result); | 142 | nfs4_schedule_state_renewal(*result); |
146 | break; | ||
147 | } | 143 | } |
148 | |||
149 | out: | 144 | out: |
150 | return status; | 145 | return status; |
151 | } | 146 | } |
@@ -1863,6 +1858,7 @@ again: | |||
1863 | case -ETIMEDOUT: | 1858 | case -ETIMEDOUT: |
1864 | case -EAGAIN: | 1859 | case -EAGAIN: |
1865 | ssleep(1); | 1860 | ssleep(1); |
1861 | case -NFS4ERR_STALE_CLIENTID: | ||
1866 | dprintk("NFS: %s after status %d, retrying\n", | 1862 | dprintk("NFS: %s after status %d, retrying\n", |
1867 | __func__, status); | 1863 | __func__, status); |
1868 | goto again; | 1864 | goto again; |
@@ -2022,8 +2018,18 @@ static int nfs4_reset_session(struct nfs_client *clp) | |||
2022 | nfs4_begin_drain_session(clp); | 2018 | nfs4_begin_drain_session(clp); |
2023 | cred = nfs4_get_exchange_id_cred(clp); | 2019 | cred = nfs4_get_exchange_id_cred(clp); |
2024 | status = nfs4_proc_destroy_session(clp->cl_session, cred); | 2020 | status = nfs4_proc_destroy_session(clp->cl_session, cred); |
2025 | if (status && status != -NFS4ERR_BADSESSION && | 2021 | switch (status) { |
2026 | status != -NFS4ERR_DEADSESSION) { | 2022 | case 0: |
2023 | case -NFS4ERR_BADSESSION: | ||
2024 | case -NFS4ERR_DEADSESSION: | ||
2025 | break; | ||
2026 | case -NFS4ERR_BACK_CHAN_BUSY: | ||
2027 | case -NFS4ERR_DELAY: | ||
2028 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
2029 | status = 0; | ||
2030 | ssleep(1); | ||
2031 | goto out; | ||
2032 | default: | ||
2027 | status = nfs4_recovery_handle_error(clp, status); | 2033 | status = nfs4_recovery_handle_error(clp, status); |
2028 | goto out; | 2034 | goto out; |
2029 | } | 2035 | } |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2e7e8c878e5d..b056b1628722 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2589,27 +2589,23 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, | |||
2589 | struct nfs_server *server; | 2589 | struct nfs_server *server; |
2590 | struct dentry *mntroot = ERR_PTR(-ENOMEM); | 2590 | struct dentry *mntroot = ERR_PTR(-ENOMEM); |
2591 | struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod; | 2591 | struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod; |
2592 | int error; | ||
2593 | 2592 | ||
2594 | dprintk("--> nfs_xdev_mount_common()\n"); | 2593 | dprintk("--> nfs_xdev_mount()\n"); |
2595 | 2594 | ||
2596 | mount_info.mntfh = mount_info.cloned->fh; | 2595 | mount_info.mntfh = mount_info.cloned->fh; |
2597 | 2596 | ||
2598 | /* create a new volume representation */ | 2597 | /* create a new volume representation */ |
2599 | server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); | 2598 | server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); |
2600 | if (IS_ERR(server)) { | ||
2601 | error = PTR_ERR(server); | ||
2602 | goto out_err; | ||
2603 | } | ||
2604 | 2599 | ||
2605 | mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod); | 2600 | if (IS_ERR(server)) |
2606 | dprintk("<-- nfs_xdev_mount_common() = 0\n"); | 2601 | mntroot = ERR_CAST(server); |
2607 | out: | 2602 | else |
2608 | return mntroot; | 2603 | mntroot = nfs_fs_mount_common(server, flags, |
2604 | dev_name, &mount_info, nfs_mod); | ||
2609 | 2605 | ||
2610 | out_err: | 2606 | dprintk("<-- nfs_xdev_mount() = %ld\n", |
2611 | dprintk("<-- nfs_xdev_mount_common() = %d [error]\n", error); | 2607 | IS_ERR(mntroot) ? PTR_ERR(mntroot) : 0L); |
2612 | goto out; | 2608 | return mntroot; |
2613 | } | 2609 | } |
2614 | 2610 | ||
2615 | #if IS_ENABLED(CONFIG_NFS_V4) | 2611 | #if IS_ENABLED(CONFIG_NFS_V4) |