Skip to content

Commit 17d8428

Browse files
committed
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
2 parents fa75870 + fb2088c commit 17d8428

File tree

6 files changed

+55
-16
lines changed

6 files changed

+55
-16
lines changed

fs/nfs/nfs4_fs.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ enum nfs4_session_state {
5656
NFS4_SESSION_DRAINING,
5757
};
5858

59+
#define NFS4_RENEW_TIMEOUT 0x01
60+
#define NFS4_RENEW_DELEGATION_CB 0x02
61+
5962
struct nfs4_minor_version_ops {
6063
u32 minor_version;
6164

@@ -225,7 +228,7 @@ struct nfs4_state_recovery_ops {
225228
};
226229

227230
struct nfs4_state_maintenance_ops {
228-
int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *);
231+
int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *, unsigned);
229232
struct rpc_cred * (*get_state_renewal_cred_locked)(struct nfs_client *);
230233
int (*renew_lease)(struct nfs_client *, struct rpc_cred *);
231234
};
@@ -237,8 +240,6 @@ extern const struct inode_operations nfs4_dir_inode_operations;
237240
extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
238241
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
239242
extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
240-
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
241-
extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
242243
extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
243244
extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
244245
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);
349350
extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
350351
extern void nfs4_schedule_lease_recovery(struct nfs_client *);
351352
extern void nfs4_schedule_state_manager(struct nfs_client *);
353+
extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp);
352354
extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *);
353355
extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
354356
extern void nfs41_handle_recall_slot(struct nfs_client *clp);

fs/nfs/nfs4proc.c

+14-6
Original file line numberDiff line numberDiff line change
@@ -3374,9 +3374,13 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata)
33743374

33753375
if (task->tk_status < 0) {
33763376
/* Unless we're shutting down, schedule state recovery! */
3377-
if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0)
3377+
if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) == 0)
3378+
return;
3379+
if (task->tk_status != NFS4ERR_CB_PATH_DOWN) {
33783380
nfs4_schedule_lease_recovery(clp);
3379-
return;
3381+
return;
3382+
}
3383+
nfs4_schedule_path_down_recovery(clp);
33803384
}
33813385
do_renew_lease(clp, timestamp);
33823386
}
@@ -3386,7 +3390,7 @@ static const struct rpc_call_ops nfs4_renew_ops = {
33863390
.rpc_release = nfs4_renew_release,
33873391
};
33883392

3389-
int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
3393+
static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
33903394
{
33913395
struct rpc_message msg = {
33923396
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -3395,9 +3399,11 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
33953399
};
33963400
struct nfs4_renewdata *data;
33973401

3402+
if (renew_flags == 0)
3403+
return 0;
33983404
if (!atomic_inc_not_zero(&clp->cl_count))
33993405
return -EIO;
3400-
data = kmalloc(sizeof(*data), GFP_KERNEL);
3406+
data = kmalloc(sizeof(*data), GFP_NOFS);
34013407
if (data == NULL)
34023408
return -ENOMEM;
34033409
data->client = clp;
@@ -3406,7 +3412,7 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
34063412
&nfs4_renew_ops, data);
34073413
}
34083414

3409-
int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
3415+
static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
34103416
{
34113417
struct rpc_message msg = {
34123418
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -5504,11 +5510,13 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
55045510
return rpc_run_task(&task_setup_data);
55055511
}
55065512

5507-
static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred)
5513+
static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
55085514
{
55095515
struct rpc_task *task;
55105516
int ret = 0;
55115517

5518+
if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0)
5519+
return 0;
55125520
task = _nfs41_proc_sequence(clp, cred);
55135521
if (IS_ERR(task))
55145522
ret = PTR_ERR(task);

fs/nfs/nfs4renewd.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ nfs4_renew_state(struct work_struct *work)
6060
struct rpc_cred *cred;
6161
long lease;
6262
unsigned long last, now;
63+
unsigned renew_flags = 0;
6364

6465
ops = clp->cl_mvops->state_renewal_ops;
6566
dprintk("%s: start\n", __func__);
@@ -72,18 +73,23 @@ nfs4_renew_state(struct work_struct *work)
7273
last = clp->cl_last_renewal;
7374
now = jiffies;
7475
/* Are we close to a lease timeout? */
75-
if (time_after(now, last + lease/3)) {
76+
if (time_after(now, last + lease/3))
77+
renew_flags |= NFS4_RENEW_TIMEOUT;
78+
if (nfs_delegations_present(clp))
79+
renew_flags |= NFS4_RENEW_DELEGATION_CB;
80+
81+
if (renew_flags != 0) {
7682
cred = ops->get_state_renewal_cred_locked(clp);
7783
spin_unlock(&clp->cl_lock);
7884
if (cred == NULL) {
79-
if (!nfs_delegations_present(clp)) {
85+
if (!(renew_flags & NFS4_RENEW_DELEGATION_CB)) {
8086
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
8187
goto out;
8288
}
8389
nfs_expire_all_delegations(clp);
8490
} else {
8591
/* Queue an asynchronous RENEW. */
86-
ops->sched_state_renewal(clp, cred);
92+
ops->sched_state_renewal(clp, cred, renew_flags);
8793
put_rpccred(cred);
8894
goto out_exp;
8995
}

fs/nfs/nfs4state.c

+6
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,12 @@ void nfs4_schedule_lease_recovery(struct nfs_client *clp)
10381038
nfs4_schedule_state_manager(clp);
10391039
}
10401040

1041+
void nfs4_schedule_path_down_recovery(struct nfs_client *clp)
1042+
{
1043+
nfs_handle_cb_pathdown(clp);
1044+
nfs4_schedule_state_manager(clp);
1045+
}
1046+
10411047
static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
10421048
{
10431049

fs/nfs/super.c

+20-3
Original file line numberDiff line numberDiff line change
@@ -2035,9 +2035,6 @@ static inline void nfs_initialise_sb(struct super_block *sb)
20352035
sb->s_blocksize = nfs_block_bits(server->wsize,
20362036
&sb->s_blocksize_bits);
20372037

2038-
if (server->flags & NFS_MOUNT_NOAC)
2039-
sb->s_flags |= MS_SYNCHRONOUS;
2040-
20412038
sb->s_bdi = &server->backing_dev_info;
20422039

20432040
nfs_super_set_maxbytes(sb, server->maxfilesize);
@@ -2249,6 +2246,10 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
22492246
if (server->flags & NFS_MOUNT_UNSHARED)
22502247
compare_super = NULL;
22512248

2249+
/* -o noac implies -o sync */
2250+
if (server->flags & NFS_MOUNT_NOAC)
2251+
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2252+
22522253
/* Get a superblock - note that we may end up sharing one that already exists */
22532254
s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata);
22542255
if (IS_ERR(s)) {
@@ -2361,6 +2362,10 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
23612362
if (server->flags & NFS_MOUNT_UNSHARED)
23622363
compare_super = NULL;
23632364

2365+
/* -o noac implies -o sync */
2366+
if (server->flags & NFS_MOUNT_NOAC)
2367+
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2368+
23642369
/* Get a superblock - note that we may end up sharing one that already exists */
23652370
s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
23662371
if (IS_ERR(s)) {
@@ -2628,6 +2633,10 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
26282633
if (server->flags & NFS4_MOUNT_UNSHARED)
26292634
compare_super = NULL;
26302635

2636+
/* -o noac implies -o sync */
2637+
if (server->flags & NFS_MOUNT_NOAC)
2638+
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2639+
26312640
/* Get a superblock - note that we may end up sharing one that already exists */
26322641
s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
26332642
if (IS_ERR(s)) {
@@ -2916,6 +2925,10 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
29162925
if (server->flags & NFS4_MOUNT_UNSHARED)
29172926
compare_super = NULL;
29182927

2928+
/* -o noac implies -o sync */
2929+
if (server->flags & NFS_MOUNT_NOAC)
2930+
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2931+
29192932
/* Get a superblock - note that we may end up sharing one that already exists */
29202933
s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
29212934
if (IS_ERR(s)) {
@@ -3003,6 +3016,10 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
30033016
if (server->flags & NFS4_MOUNT_UNSHARED)
30043017
compare_super = NULL;
30053018

3019+
/* -o noac implies -o sync */
3020+
if (server->flags & NFS_MOUNT_NOAC)
3021+
sb_mntdata.mntflags |= MS_SYNCHRONOUS;
3022+
30063023
/* Get a superblock - note that we may end up sharing one that already exists */
30073024
s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
30083025
if (IS_ERR(s)) {

fs/nfs/write.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, struct list_head
958958
if (!data)
959959
goto out_bad;
960960
data->pagevec[0] = page;
961-
nfs_write_rpcsetup(req, data, wsize, offset, desc->pg_ioflags);
961+
nfs_write_rpcsetup(req, data, len, offset, desc->pg_ioflags);
962962
list_add(&data->list, res);
963963
requests++;
964964
nbytes -= len;

0 commit comments

Comments
 (0)