From beffb8feb6e26851165ee927e0eb963d6db334b0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 20 Jul 2016 16:34:42 -0400 Subject: qstr: constify instances in nfs Signed-off-by: Al Viro --- fs/nfs/nfs3proc.c | 8 ++++---- fs/nfs/nfs4_fs.h | 5 +++-- fs/nfs/nfs4namespace.c | 4 ++-- fs/nfs/nfs4proc.c | 16 ++++++++-------- fs/nfs/proc.c | 8 ++++---- fs/nfs/unlink.c | 2 +- 6 files changed, 22 insertions(+), 21 deletions(-) (limited to 'fs/nfs') diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index cb28cceefebe..698be9361280 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -144,7 +144,7 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, } static int -nfs3_proc_lookup(struct inode *dir, struct qstr *name, +nfs3_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label) { @@ -404,7 +404,7 @@ out: } static int -nfs3_proc_remove(struct inode *dir, struct qstr *name) +nfs3_proc_remove(struct inode *dir, const struct qstr *name) { struct nfs_removeargs arg = { .fh = NFS_FH(dir), @@ -480,7 +480,7 @@ nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir, } static int -nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) +nfs3_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name) { struct nfs3_linkargs arg = { .fromfh = NFS_FH(inode), @@ -582,7 +582,7 @@ out: } static int -nfs3_proc_rmdir(struct inode *dir, struct qstr *name) +nfs3_proc_rmdir(struct inode *dir, const struct qstr *name) { struct nfs_fattr *dir_attr; struct nfs3_diropargs arg = { diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 768456fa1b17..81e938554f10 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -224,7 +224,8 @@ int nfs_atomic_open(struct inode *, struct dentry *, struct file *, extern struct file_system_type nfs4_fs_type; /* nfs4namespace.c */ -struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *, struct qstr *); +struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *, + const struct qstr *); struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *, struct nfs_fh *, struct nfs_fattr *); int nfs4_replace_transport(struct nfs_server *server, @@ -251,7 +252,7 @@ extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struc extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *, struct page *page, struct rpc_cred *); extern int nfs4_proc_fsid_present(struct inode *, struct rpc_cred *); -extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *, +extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, const struct qstr *, struct nfs_fh *, struct nfs_fattr *); extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); extern const struct xattr_handler *nfs4_xattr_handlers[]; diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index f592672373cb..d21104912676 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c @@ -208,7 +208,7 @@ static struct rpc_clnt *nfs_find_best_sec(struct rpc_clnt *clnt, */ struct rpc_clnt * nfs4_negotiate_security(struct rpc_clnt *clnt, struct inode *inode, - struct qstr *name) + const struct qstr *name) { struct page *page; struct nfs4_secinfo_flavors *flavors; @@ -397,7 +397,7 @@ struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry, rpc_authflavor_t flavor = server->client->cl_auth->au_flavor; struct dentry *parent = dget_parent(dentry); struct inode *dir = d_inode(parent); - struct qstr *name = &dentry->d_name; + const struct qstr *name = &dentry->d_name; struct rpc_clnt *client; struct vfsmount *mnt; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ff416d0e24bc..e75815c69d17 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3530,7 +3530,7 @@ static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr) } static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, - struct qstr *name, struct nfs_fh *fhandle, + const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label) { struct nfs4_exception exception = { }; @@ -3572,7 +3572,7 @@ out: return err; } -static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, +static int nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label) { @@ -3588,7 +3588,7 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, } struct rpc_clnt * -nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name, +nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { struct rpc_clnt *client = NFS_CLIENT(dir); @@ -3747,7 +3747,7 @@ out: return status; } -static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) +static int _nfs4_proc_remove(struct inode *dir, const struct qstr *name) { struct nfs_server *server = NFS_SERVER(dir); struct nfs_removeargs args = { @@ -3770,7 +3770,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) return status; } -static int nfs4_proc_remove(struct inode *dir, struct qstr *name) +static int nfs4_proc_remove(struct inode *dir, const struct qstr *name) { struct nfs4_exception exception = { }; int err; @@ -3853,7 +3853,7 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, return 1; } -static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) +static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name) { struct nfs_server *server = NFS_SERVER(inode); struct nfs4_link_arg arg = { @@ -3900,7 +3900,7 @@ out: return status; } -static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) +static int nfs4_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name) { struct nfs4_exception exception = { }; int err; @@ -3922,7 +3922,7 @@ struct nfs4_createdata { }; static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, - struct qstr *name, struct iattr *sattr, u32 ftype) + const struct qstr *name, struct iattr *sattr, u32 ftype) { struct nfs4_createdata *data; diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index b417bbcd9704..b7bca8303989 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -145,7 +145,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, } static int -nfs_proc_lookup(struct inode *dir, struct qstr *name, +nfs_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label) { @@ -299,7 +299,7 @@ out: } static int -nfs_proc_remove(struct inode *dir, struct qstr *name) +nfs_proc_remove(struct inode *dir, const struct qstr *name) { struct nfs_removeargs arg = { .fh = NFS_FH(dir), @@ -357,7 +357,7 @@ nfs_proc_rename_done(struct rpc_task *task, struct inode *old_dir, } static int -nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) +nfs_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name) { struct nfs_linkargs arg = { .fromfh = NFS_FH(inode), @@ -456,7 +456,7 @@ out: } static int -nfs_proc_rmdir(struct inode *dir, struct qstr *name) +nfs_proc_rmdir(struct inode *dir, const struct qstr *name) { struct nfs_diropargs arg = { .fh = NFS_FH(dir), diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 1868246f56e6..191aa577dd1f 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -162,7 +162,7 @@ static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data) * @dentry: dentry to unlink */ static int -nfs_async_unlink(struct dentry *dentry, struct qstr *name) +nfs_async_unlink(struct dentry *dentry, const struct qstr *name) { struct nfs_unlinkdata *data; int status = -ENOMEM; -- cgit From 206b3bb57481758b5fe98e90f47abb0f3fc0954e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 5 Aug 2016 12:16:19 -0400 Subject: NFSv4.2: LAYOUTSTATS may return NFS4ERR_ADMIN/DELEG_REVOKED We should handle those errors in the same way we handle the other stateid errors: by invalidating the faulty layout stateid. Signed-off-by: Trond Myklebust --- fs/nfs/nfs42proc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs/nfs') diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 33da841a21bb..6f4752734804 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -338,6 +338,8 @@ nfs42_layoutstat_done(struct rpc_task *task, void *calldata) case 0: break; case -NFS4ERR_EXPIRED: + case -NFS4ERR_ADMIN_REVOKED: + case -NFS4ERR_DELEG_REVOKED: case -NFS4ERR_STALE_STATEID: case -NFS4ERR_OLD_STATEID: case -NFS4ERR_BAD_STATEID: -- cgit From fb10fb67ad2ce43d5e5b8ad22d2ba826844acc56 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 5 Aug 2016 19:13:08 -0400 Subject: NFSv4: Cleanup the setting of the nfs4 lease period Make a helper function nfs4_set_lease_period() and have nfs41_setup_state_renewal() and nfs4_do_fsinfo() use it. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4_fs.h | 4 ++++ fs/nfs/nfs4proc.c | 9 +++------ fs/nfs/nfs4renewd.c | 17 +++++++++++++++++ fs/nfs/nfs4state.c | 9 +++------ 4 files changed, 27 insertions(+), 12 deletions(-) (limited to 'fs/nfs') diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 4be567a54958..74a0e34e5ded 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -395,6 +395,10 @@ extern void nfs4_schedule_state_renewal(struct nfs_client *); extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); extern void nfs4_kill_renewd(struct nfs_client *); extern void nfs4_renew_state(struct work_struct *); +extern void nfs4_set_lease_period(struct nfs_client *clp, + unsigned long lease, + unsigned long lastrenewed); + /* nfs4state.c */ struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index da5c9e58e907..b9e18679af50 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4237,12 +4237,9 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str err = _nfs4_do_fsinfo(server, fhandle, fsinfo); trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err); if (err == 0) { - struct nfs_client *clp = server->nfs_client; - - spin_lock(&clp->cl_lock); - clp->cl_lease_time = fsinfo->lease_time * HZ; - clp->cl_last_renewal = now; - spin_unlock(&clp->cl_lock); + nfs4_set_lease_period(server->nfs_client, + fsinfo->lease_time * HZ, + now); break; } err = nfs4_handle_exception(server, err, &exception); diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index e1ba58c3d1ad..062029ab344a 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c @@ -136,6 +136,23 @@ nfs4_kill_renewd(struct nfs_client *clp) cancel_delayed_work_sync(&clp->cl_renewd); } +/** + * nfs4_set_lease_period - Sets the lease period on a nfs_client + * + * @clp: pointer to nfs_client + * @lease: new value for lease period + * @lastrenewed: time at which lease was last renewed + */ +void nfs4_set_lease_period(struct nfs_client *clp, + unsigned long lease, + unsigned long lastrenewed) +{ + spin_lock(&clp->cl_lock); + clp->cl_lease_time = lease; + clp->cl_last_renewal = lastrenewed; + spin_unlock(&clp->cl_lock); +} + /* * Local variables: * c-basic-offset: 8 diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 834b875900d6..cada00aa5096 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -277,20 +277,17 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp) { int status; struct nfs_fsinfo fsinfo; + unsigned long now; if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) { nfs4_schedule_state_renewal(clp); return 0; } + now = jiffies; status = nfs4_proc_get_lease_time(clp, &fsinfo); if (status == 0) { - /* Update lease time and schedule renewal */ - spin_lock(&clp->cl_lock); - clp->cl_lease_time = fsinfo.lease_time * HZ; - clp->cl_last_renewal = jiffies; - spin_unlock(&clp->cl_lock); - + nfs4_set_lease_period(clp, fsinfo.lease_time * HZ, now); nfs4_schedule_state_renewal(clp); } -- cgit From 8d480326c3d6921ff5f1cc988c993bd572248deb Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 5 Aug 2016 19:03:31 -0400 Subject: NFSv4: Cap the transport reconnection timer at 1/2 lease period We don't want to miss a lease period renewal due to the TCP connection failing to reconnect in a timely fashion. To ensure this doesn't happen, cap the reconnection timer so that we retry the connection attempt at least every 1/2 lease period. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4renewd.c | 3 +++ include/linux/sunrpc/clnt.h | 2 ++ net/sunrpc/clnt.c | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+) (limited to 'fs/nfs') diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 062029ab344a..82e77198d17e 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c @@ -151,6 +151,9 @@ void nfs4_set_lease_period(struct nfs_client *clp, clp->cl_lease_time = lease; clp->cl_last_renewal = lastrenewed; spin_unlock(&clp->cl_lock); + + /* Cap maximum reconnect timeout at 1/2 lease period */ + rpc_cap_max_reconnect_timeout(clp->cl_rpcclient, lease >> 1); } /* diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index b6810c92b8bb..5c02b0691587 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -195,6 +195,8 @@ int rpc_clnt_add_xprt(struct rpc_clnt *, struct xprt_create *, struct rpc_xprt *, void *), void *data); +void rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt, + unsigned long timeo); const char *rpc_proc_name(const struct rpc_task *task); #endif /* __KERNEL__ */ diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index faac5472d14d..7f79fb7dc6a0 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2676,6 +2676,27 @@ out_put_switch: } EXPORT_SYMBOL_GPL(rpc_clnt_add_xprt); +static int +rpc_xprt_cap_max_reconnect_timeout(struct rpc_clnt *clnt, + struct rpc_xprt *xprt, + void *data) +{ + unsigned long timeout = *((unsigned long *)data); + + if (timeout < xprt->max_reconnect_timeout) + xprt->max_reconnect_timeout = timeout; + return 0; +} + +void +rpc_cap_max_reconnect_timeout(struct rpc_clnt *clnt, unsigned long timeo) +{ + rpc_clnt_iterate_for_each_xprt(clnt, + rpc_xprt_cap_max_reconnect_timeout, + &timeo); +} +EXPORT_SYMBOL_GPL(rpc_cap_max_reconnect_timeout); + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) static void rpc_show_header(void) { -- cgit