Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: nfs: Do not allow multiple mounts on same mountpoint when using -o noac NFS: Fix a typo in nfs_flush_multi NFSv4: renewd needs to be able to handle the NFS4ERR_CB_PATH_DOWN error NFSv4: The NFSv4.0 client must send RENEW calls if it holds a delegation NFSv4: nfs4_proc_renew should be declared static NFSv4: nfs4_proc_async_renew should use a GFP_NOFS allocation
This commit is contained in:
commit
17d8428e4c
|
@ -56,6 +56,9 @@ enum nfs4_session_state {
|
|||
NFS4_SESSION_DRAINING,
|
||||
};
|
||||
|
||||
#define NFS4_RENEW_TIMEOUT 0x01
|
||||
#define NFS4_RENEW_DELEGATION_CB 0x02
|
||||
|
||||
struct nfs4_minor_version_ops {
|
||||
u32 minor_version;
|
||||
|
||||
|
@ -225,7 +228,7 @@ struct nfs4_state_recovery_ops {
|
|||
};
|
||||
|
||||
struct nfs4_state_maintenance_ops {
|
||||
int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *);
|
||||
int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *, unsigned);
|
||||
struct rpc_cred * (*get_state_renewal_cred_locked)(struct nfs_client *);
|
||||
int (*renew_lease)(struct nfs_client *, struct rpc_cred *);
|
||||
};
|
||||
|
@ -237,8 +240,6 @@ extern const struct inode_operations nfs4_dir_inode_operations;
|
|||
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
|
||||
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
|
||||
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
|
||||
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
|
||||
extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc);
|
||||
|
@ -349,6 +350,7 @@ extern void nfs4_close_sync(struct nfs4_state *, fmode_t);
|
|||
extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
|
||||
extern void nfs4_schedule_lease_recovery(struct nfs_client *);
|
||||
extern void nfs4_schedule_state_manager(struct nfs_client *);
|
||||
extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
|
||||
extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
|
||||
extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
|
||||
extern void nfs41_handle_recall_slot(struct nfs_client *clp);
|
||||
|
|
|
@ -3374,9 +3374,13 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata)
|
|||
|
||||
if (task->tk_status < 0) {
|
||||
/* Unless we're shutting down, schedule state recovery! */
|
||||
if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0)
|
||||
if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0)
|
||||
return;
|
||||
if (task->tk_status != NFS4ERR_CB_PATH_DOWN) {
|
||||
nfs4_schedule_lease_recovery(clp);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
nfs4_schedule_path_down_recovery(clp);
|
||||
}
|
||||
do_renew_lease(clp, timestamp);
|
||||
}
|
||||
|
@ -3386,7 +3390,7 @@ static const struct rpc_call_ops nfs4_renew_ops = {
|
|||
.rpc_release = nfs4_renew_release,
|
||||
};
|
||||
|
||||
int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
|
||||
|
@ -3395,9 +3399,11 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
|||
};
|
||||
struct nfs4_renewdata *data;
|
||||
|
||||
if (renew_flags == 0)
|
||||
return 0;
|
||||
if (!atomic_inc_not_zero(&clp->cl_count))
|
||||
return -EIO;
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
data = kmalloc(sizeof(*data), GFP_NOFS);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
data->client = clp;
|
||||
|
@ -3406,7 +3412,7 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
|||
&nfs4_renew_ops, data);
|
||||
}
|
||||
|
||||
int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
{
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
|
||||
|
@ -5504,11 +5510,13 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
|
|||
return rpc_run_task(&task_setup_data);
|
||||
}
|
||||
|
||||
static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
int ret = 0;
|
||||
|
||||
if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
|
||||
return 0;
|
||||
task = _nfs41_proc_sequence(clp, cred);
|
||||
if (IS_ERR(task))
|
||||
ret = PTR_ERR(task);
|
||||
|
|
|
@ -60,6 +60,7 @@ nfs4_renew_state(struct work_struct *work)
|
|||
struct rpc_cred *cred;
|
||||
long lease;
|
||||
unsigned long last, now;
|
||||
unsigned renew_flags = 0;
|
||||
|
||||
ops = clp->cl_mvops->state_renewal_ops;
|
||||
dprintk("%s: start\n", __func__);
|
||||
|
@ -72,18 +73,23 @@ nfs4_renew_state(struct work_struct *work)
|
|||
last = clp->cl_last_renewal;
|
||||
now = jiffies;
|
||||
/* Are we close to a lease timeout? */
|
||||
if (time_after(now, last + lease/3)) {
|
||||
if (time_after(now, last + lease/3))
|
||||
renew_flags |= NFS4_RENEW_TIMEOUT;
|
||||
if (nfs_delegations_present(clp))
|
||||
renew_flags |= NFS4_RENEW_DELEGATION_CB;
|
||||
|
||||
if (renew_flags != 0) {
|
||||
cred = ops->get_state_renewal_cred_locked(clp);
|
||||
spin_unlock(&clp->cl_lock);
|
||||
if (cred == NULL) {
|
||||
if (!nfs_delegations_present(clp)) {
|
||||
if (!(renew_flags & NFS4_RENEW_DELEGATION_CB)) {
|
||||
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
|
||||
goto out;
|
||||
}
|
||||
nfs_expire_all_delegations(clp);
|
||||
} else {
|
||||
/* Queue an asynchronous RENEW. */
|
||||
ops->sched_state_renewal(clp, cred);
|
||||
ops->sched_state_renewal(clp, cred, renew_flags);
|
||||
put_rpccred(cred);
|
||||
goto out_exp;
|
||||
}
|
||||
|
|
|
@ -1038,6 +1038,12 @@ void nfs4_schedule_lease_recovery(struct nfs_client *clp)
|
|||
nfs4_schedule_state_manager(clp);
|
||||
}
|
||||
|
||||
void nfs4_schedule_path_down_recovery(struct nfs_client *clp)
|
||||
{
|
||||
nfs_handle_cb_pathdown(clp);
|
||||
nfs4_schedule_state_manager(clp);
|
||||
}
|
||||
|
||||
static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
|
||||
{
|
||||
|
||||
|
|
|
@ -2035,9 +2035,6 @@ static inline void nfs_initialise_sb(struct super_block *sb)
|
|||
sb->s_blocksize = nfs_block_bits(server->wsize,
|
||||
&sb->s_blocksize_bits);
|
||||
|
||||
if (server->flags & NFS_MOUNT_NOAC)
|
||||
sb->s_flags |= MS_SYNCHRONOUS;
|
||||
|
||||
sb->s_bdi = &server->backing_dev_info;
|
||||
|
||||
nfs_super_set_maxbytes(sb, server->maxfilesize);
|
||||
|
@ -2249,6 +2246,10 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
|||
if (server->flags & NFS_MOUNT_UNSHARED)
|
||||
compare_super = NULL;
|
||||
|
||||
/* -o noac implies -o sync */
|
||||
if (server->flags & NFS_MOUNT_NOAC)
|
||||
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
|
||||
|
||||
/* Get a superblock - note that we may end up sharing one that already exists */
|
||||
s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata);
|
||||
if (IS_ERR(s)) {
|
||||
|
@ -2361,6 +2362,10 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
|
|||
if (server->flags & NFS_MOUNT_UNSHARED)
|
||||
compare_super = NULL;
|
||||
|
||||
/* -o noac implies -o sync */
|
||||
if (server->flags & NFS_MOUNT_NOAC)
|
||||
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
|
||||
|
||||
/* Get a superblock - note that we may end up sharing one that already exists */
|
||||
s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
|
||||
if (IS_ERR(s)) {
|
||||
|
@ -2628,6 +2633,10 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
|
|||
if (server->flags & NFS4_MOUNT_UNSHARED)
|
||||
compare_super = NULL;
|
||||
|
||||
/* -o noac implies -o sync */
|
||||
if (server->flags & NFS_MOUNT_NOAC)
|
||||
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
|
||||
|
||||
/* Get a superblock - note that we may end up sharing one that already exists */
|
||||
s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
|
||||
if (IS_ERR(s)) {
|
||||
|
@ -2916,6 +2925,10 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
|
|||
if (server->flags & NFS4_MOUNT_UNSHARED)
|
||||
compare_super = NULL;
|
||||
|
||||
/* -o noac implies -o sync */
|
||||
if (server->flags & NFS_MOUNT_NOAC)
|
||||
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
|
||||
|
||||
/* Get a superblock - note that we may end up sharing one that already exists */
|
||||
s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
|
||||
if (IS_ERR(s)) {
|
||||
|
@ -3003,6 +3016,10 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
|
|||
if (server->flags & NFS4_MOUNT_UNSHARED)
|
||||
compare_super = NULL;
|
||||
|
||||
/* -o noac implies -o sync */
|
||||
if (server->flags & NFS_MOUNT_NOAC)
|
||||
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
|
||||
|
||||
/* Get a superblock - note that we may end up sharing one that already exists */
|
||||
s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
|
||||
if (IS_ERR(s)) {
|
||||
|
|
|
@ -958,7 +958,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, struct list_head
|
|||
if (!data)
|
||||
goto out_bad;
|
||||
data->pagevec[0] = page;
|
||||
nfs_write_rpcsetup(req, data, wsize, offset, desc->pg_ioflags);
|
||||
nfs_write_rpcsetup(req, data, len, offset, desc->pg_ioflags);
|
||||
list_add(&data->list, res);
|
||||
requests++;
|
||||
nbytes -= len;
|
||||
|
|
Loading…
Reference in a new issue