aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/proc.c')
-rw-r--r--fs/nfs/proc.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index ef583854d8d0..0288be80444f 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -29,7 +29,6 @@
29 29
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/param.h> 31#include <linux/param.h>
32#include <linux/slab.h>
33#include <linux/time.h> 32#include <linux/time.h>
34#include <linux/mm.h> 33#include <linux/mm.h>
35#include <linux/errno.h> 34#include <linux/errno.h>
@@ -47,6 +46,39 @@
47#define NFSDBG_FACILITY NFSDBG_PROC 46#define NFSDBG_FACILITY NFSDBG_PROC
48 47
49/* 48/*
49 * wrapper to handle the -EKEYEXPIRED error message. This should generally
50 * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't
51 * support the NFSERR_JUKEBOX error code, but we handle this situation in the
52 * same way that we handle that error with NFSv3.
53 */
54static int
55nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
56{
57 int res;
58 do {
59 res = rpc_call_sync(clnt, msg, flags);
60 if (res != -EKEYEXPIRED)
61 break;
62 schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
63 res = -ERESTARTSYS;
64 } while (!fatal_signal_pending(current));
65 return res;
66}
67
68#define rpc_call_sync(clnt, msg, flags) nfs_rpc_wrapper(clnt, msg, flags)
69
70static int
71nfs_async_handle_expired_key(struct rpc_task *task)
72{
73 if (task->tk_status != -EKEYEXPIRED)
74 return 0;
75 task->tk_status = 0;
76 rpc_restart_call(task);
77 rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
78 return 1;
79}
80
81/*
50 * Bare-bones access to getattr: this is for nfs_read_super. 82 * Bare-bones access to getattr: this is for nfs_read_super.
51 */ 83 */
52static int 84static int
@@ -307,6 +339,8 @@ nfs_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
307 339
308static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) 340static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
309{ 341{
342 if (nfs_async_handle_expired_key(task))
343 return 0;
310 nfs_mark_for_revalidate(dir); 344 nfs_mark_for_revalidate(dir);
311 return 1; 345 return 1;
312} 346}
@@ -560,6 +594,9 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
560 594
561static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data) 595static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
562{ 596{
597 if (nfs_async_handle_expired_key(task))
598 return -EAGAIN;
599
563 nfs_invalidate_atime(data->inode); 600 nfs_invalidate_atime(data->inode);
564 if (task->tk_status >= 0) { 601 if (task->tk_status >= 0) {
565 nfs_refresh_inode(data->inode, data->res.fattr); 602 nfs_refresh_inode(data->inode, data->res.fattr);
@@ -579,6 +616,9 @@ static void nfs_proc_read_setup(struct nfs_read_data *data, struct rpc_message *
579 616
580static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data) 617static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
581{ 618{
619 if (nfs_async_handle_expired_key(task))
620 return -EAGAIN;
621
582 if (task->tk_status >= 0) 622 if (task->tk_status >= 0)
583 nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr); 623 nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
584 return 0; 624 return 0;