Opt_sloppy,
        Opt_soft,
        Opt_softerr,
+       Opt_softreval,
        Opt_source,
        Opt_tcp,
        Opt_timeo,
        fsparam_flag  ("sloppy",        Opt_sloppy),
        fsparam_flag  ("soft",          Opt_soft),
        fsparam_flag  ("softerr",       Opt_softerr),
+       fsparam_flag  ("softreval",     Opt_softreval),
        fsparam_string("source",        Opt_source),
        fsparam_flag  ("tcp",           Opt_tcp),
        fsparam_u32   ("timeo",         Opt_timeo),
                ctx->flags &= ~NFS_MOUNT_SOFTERR;
                break;
        case Opt_softerr:
-               ctx->flags |= NFS_MOUNT_SOFTERR;
+               ctx->flags |= NFS_MOUNT_SOFTERR | NFS_MOUNT_SOFTREVAL;
                ctx->flags &= ~NFS_MOUNT_SOFT;
                break;
        case Opt_hard:
-               ctx->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR);
+               ctx->flags &= ~(NFS_MOUNT_SOFT |
+                               NFS_MOUNT_SOFTERR |
+                               NFS_MOUNT_SOFTREVAL);
+               break;
+       case Opt_softreval:
+               if (result.negated)
+                       ctx->flags &= ~NFS_MOUNT_SOFTREVAL;
+               else
+                       ctx->flags &= NFS_MOUNT_SOFTREVAL;
                break;
        case Opt_posix:
                if (result.negated)
 
                dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n",
                         inode->i_sb->s_id,
                         (unsigned long long)NFS_FILEID(inode), status);
-               if (status == -ESTALE) {
+               switch (status) {
+               case -ETIMEDOUT:
+                       /* A soft timeout occurred. Use cached information? */
+                       if (server->flags & NFS_MOUNT_SOFTREVAL)
+                               status = 0;
+                       break;
+               case -ESTALE:
                        nfs_zap_caches(inode);
                        if (!S_ISDIR(inode->i_mode))
                                set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
 
                .rpc_resp       = fattr,
        };
        int     status;
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        dprintk("NFS call  getattr\n");
        nfs_fattr_init(fattr);
-       status = rpc_call_sync(server->client, &msg, 0);
+       status = rpc_call_sync(server->client, &msg, task_flags);
        dprintk("NFS reply getattr: %d\n", status);
        return status;
 }
 
        return ret;
 }
 
-static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
-                                  struct nfs_server *server,
-                                  struct rpc_message *msg,
-                                  struct nfs4_sequence_args *args,
-                                  struct nfs4_sequence_res *res)
+static int nfs4_do_call_sync(struct rpc_clnt *clnt,
+                            struct nfs_server *server,
+                            struct rpc_message *msg,
+                            struct nfs4_sequence_args *args,
+                            struct nfs4_sequence_res *res,
+                            unsigned short task_flags)
 {
        struct nfs_client *clp = server->nfs_client;
        struct nfs4_call_sync_data data = {
                .rpc_client = clnt,
                .rpc_message = msg,
                .callback_ops = clp->cl_mvops->call_sync_ops,
-               .callback_data = &data
+               .callback_data = &data,
+               .flags = task_flags,
        };
 
        return nfs4_call_sync_custom(&task_setup);
 }
 
+static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
+                                  struct nfs_server *server,
+                                  struct rpc_message *msg,
+                                  struct nfs4_sequence_args *args,
+                                  struct nfs4_sequence_res *res)
+{
+       return nfs4_do_call_sync(clnt, server, msg, args, res, 0);
+}
+
+
 int nfs4_call_sync(struct rpc_clnt *clnt,
                   struct nfs_server *server,
                   struct rpc_message *msg,
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode);
 
        nfs_fattr_init(fattr);
-       return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
+       return nfs4_do_call_sync(server->client, server, &msg,
+                       &args.seq_args, &res.seq_res, task_flags);
 }
 
 int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
 
                .rpc_resp       = fattr,
        };
        int     status;
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        dprintk("NFS call  getattr\n");
        nfs_fattr_init(fattr);
-       status = rpc_call_sync(server->client, &msg, 0);
+       status = rpc_call_sync(server->client, &msg, task_flags);
        dprintk("NFS reply getattr: %d\n", status);
        return status;
 }
 
        } nfs_info[] = {
                { NFS_MOUNT_SOFT, ",soft", "" },
                { NFS_MOUNT_SOFTERR, ",softerr", "" },
+               { NFS_MOUNT_SOFTREVAL, ",softreval", "" },
                { NFS_MOUNT_POSIX, ",posix", "" },
                { NFS_MOUNT_NOCTO, ",nocto", "" },
                { NFS_MOUNT_NOAC, ",noac", "" },
 
 #define NFS_MOUNT_LOCAL_FLOCK          0x100000
 #define NFS_MOUNT_LOCAL_FCNTL          0x200000
 #define NFS_MOUNT_SOFTERR              0x400000
+#define NFS_MOUNT_SOFTREVAL            0x800000
 
        unsigned int            caps;           /* server capabilities */
        unsigned int            rsize;          /* read size */