Skip to content

Commit 4108e10

Browse files
committed
Merge tag 'nfsd-5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd fixes from Chuck Lever: "Miscellaneous NFSD fixes for v5.12-rc" * tag 'nfsd-5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: svcrdma: Revert "svcrdma: Reduce Receive doorbell rate" NFSD: fix error handling in NFSv4.0 callbacks NFSD: fix dest to src mount in inter-server COPY Revert "nfsd4: a client's own opens needn't prevent delegations" Revert "nfsd4: remove check_conflicting_opens warning" rpc: fix NULL dereference on kmalloc failure sunrpc: fix refcount leak for rpc auth modules NFSD: Repair misuse of sv_lock in 5.10.16-rt30. nfsd: don't abort copies early fs: nfsd: fix kconfig dependency warning for NFSD_V4 svcrdma: disable timeouts on rdma backchannel nfsd: Don't keep looking up unhashed files in the nfsd file cache
2 parents 1a4431a + bade4be commit 4108e10

File tree

12 files changed

+75
-99
lines changed

12 files changed

+75
-99
lines changed

fs/locks.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,9 +1808,6 @@ check_conflicting_open(struct file *filp, const long arg, int flags)
18081808

18091809
if (flags & FL_LAYOUT)
18101810
return 0;
1811-
if (flags & FL_DELEG)
1812-
/* We leave these checks to the caller. */
1813-
return 0;
18141811

18151812
if (arg == F_RDLCK)
18161813
return inode_is_open_for_write(inode) ? -EAGAIN : 0;

fs/nfsd/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ config NFSD_V4
7373
select NFSD_V3
7474
select FS_POSIX_ACL
7575
select SUNRPC_GSS
76+
select CRYPTO
7677
select CRYPTO_MD5
7778
select CRYPTO_SHA256
7879
select GRACE_PERIOD

fs/nfsd/filecache.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,8 @@ nfsd_file_find_locked(struct inode *inode, unsigned int may_flags,
898898
continue;
899899
if (!nfsd_match_cred(nf->nf_cred, current_cred()))
900900
continue;
901+
if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags))
902+
continue;
901903
if (nfsd_file_get(nf) != NULL)
902904
return nf;
903905
}

fs/nfsd/nfs4callback.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,7 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
11891189
switch (task->tk_status) {
11901190
case -EIO:
11911191
case -ETIMEDOUT:
1192+
case -EACCES:
11921193
nfsd4_mark_cb_down(clp, task->tk_status);
11931194
}
11941195
break;

fs/nfsd/nfs4proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src,
13021302
struct nfsd_file *dst)
13031303
{
13041304
nfs42_ssc_close(src->nf_file);
1305-
/* 'src' is freed by nfsd4_do_async_copy */
1305+
fput(src->nf_file);
13061306
nfsd_file_put(dst);
13071307
mntput(ss_mnt);
13081308
}

fs/nfsd/nfs4state.c

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4940,31 +4940,6 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp,
49404940
return fl;
49414941
}
49424942

4943-
static int nfsd4_check_conflicting_opens(struct nfs4_client *clp,
4944-
struct nfs4_file *fp)
4945-
{
4946-
struct nfs4_clnt_odstate *co;
4947-
struct file *f = fp->fi_deleg_file->nf_file;
4948-
struct inode *ino = locks_inode(f);
4949-
int writes = atomic_read(&ino->i_writecount);
4950-
4951-
if (fp->fi_fds[O_WRONLY])
4952-
writes--;
4953-
if (fp->fi_fds[O_RDWR])
4954-
writes--;
4955-
if (writes > 0)
4956-
return -EAGAIN;
4957-
spin_lock(&fp->fi_lock);
4958-
list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) {
4959-
if (co->co_client != clp) {
4960-
spin_unlock(&fp->fi_lock);
4961-
return -EAGAIN;
4962-
}
4963-
}
4964-
spin_unlock(&fp->fi_lock);
4965-
return 0;
4966-
}
4967-
49684943
static struct nfs4_delegation *
49694944
nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
49704945
struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate)
@@ -4984,12 +4959,9 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
49844959

49854960
nf = find_readable_file(fp);
49864961
if (!nf) {
4987-
/*
4988-
* We probably could attempt another open and get a read
4989-
* delegation, but for now, don't bother until the
4990-
* client actually sends us one.
4991-
*/
4992-
return ERR_PTR(-EAGAIN);
4962+
/* We should always have a readable file here */
4963+
WARN_ON_ONCE(1);
4964+
return ERR_PTR(-EBADF);
49934965
}
49944966
spin_lock(&state_lock);
49954967
spin_lock(&fp->fi_lock);
@@ -5019,19 +4991,11 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
50194991
if (!fl)
50204992
goto out_clnt_odstate;
50214993

5022-
status = nfsd4_check_conflicting_opens(clp, fp);
5023-
if (status) {
5024-
locks_free_lock(fl);
5025-
goto out_clnt_odstate;
5026-
}
50274994
status = vfs_setlease(fp->fi_deleg_file->nf_file, fl->fl_type, &fl, NULL);
50284995
if (fl)
50294996
locks_free_lock(fl);
50304997
if (status)
50314998
goto out_clnt_odstate;
5032-
status = nfsd4_check_conflicting_opens(clp, fp);
5033-
if (status)
5034-
goto out_clnt_odstate;
50354999

50365000
spin_lock(&state_lock);
50375001
spin_lock(&fp->fi_lock);
@@ -5113,6 +5077,17 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
51135077
goto out_no_deleg;
51145078
if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED))
51155079
goto out_no_deleg;
5080+
/*
5081+
* Also, if the file was opened for write or
5082+
* create, there's a good chance the client's
5083+
* about to write to it, resulting in an
5084+
* immediate recall (since we don't support
5085+
* write delegations):
5086+
*/
5087+
if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
5088+
goto out_no_deleg;
5089+
if (open->op_create == NFS4_OPEN_CREATE)
5090+
goto out_no_deleg;
51165091
break;
51175092
default:
51185093
goto out_no_deleg;
@@ -5389,7 +5364,7 @@ nfs4_laundromat(struct nfsd_net *nn)
53895364
idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) {
53905365
cps = container_of(cps_t, struct nfs4_cpntf_state, cp_stateid);
53915366
if (cps->cp_stateid.sc_type == NFS4_COPYNOTIFY_STID &&
5392-
cps->cpntf_time > cutoff)
5367+
cps->cpntf_time < cutoff)
53935368
_free_cpntf_state_locked(nn, cps);
53945369
}
53955370
spin_unlock(&nn->s2s_cp_lock);

include/linux/sunrpc/svc_rdma.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ struct svcxprt_rdma {
104104

105105
wait_queue_head_t sc_send_wait; /* SQ exhaustion waitlist */
106106
unsigned long sc_flags;
107-
u32 sc_pending_recvs;
108107
struct list_head sc_read_complete_q;
109108
struct work_struct sc_work;
110109

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,11 +1825,14 @@ static int
18251825
svcauth_gss_release(struct svc_rqst *rqstp)
18261826
{
18271827
struct gss_svc_data *gsd = (struct gss_svc_data *)rqstp->rq_auth_data;
1828-
struct rpc_gss_wire_cred *gc = &gsd->clcred;
1828+
struct rpc_gss_wire_cred *gc;
18291829
struct xdr_buf *resbuf = &rqstp->rq_res;
18301830
int stat = -EINVAL;
18311831
struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
18321832

1833+
if (!gsd)
1834+
goto out;
1835+
gc = &gsd->clcred;
18331836
if (gc->gc_proc != RPC_GSS_PROC_DATA)
18341837
goto out;
18351838
/* Release can be called twice, but we only wrap once. */
@@ -1870,10 +1873,10 @@ svcauth_gss_release(struct svc_rqst *rqstp)
18701873
if (rqstp->rq_cred.cr_group_info)
18711874
put_group_info(rqstp->rq_cred.cr_group_info);
18721875
rqstp->rq_cred.cr_group_info = NULL;
1873-
if (gsd->rsci)
1876+
if (gsd && gsd->rsci) {
18741877
cache_put(&gsd->rsci->h, sn->rsc_cache);
1875-
gsd->rsci = NULL;
1876-
1878+
gsd->rsci = NULL;
1879+
}
18771880
return stat;
18781881
}
18791882

net/sunrpc/svc.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
14131413

14141414
sendit:
14151415
if (svc_authorise(rqstp))
1416-
goto close;
1416+
goto close_xprt;
14171417
return 1; /* Caller can now send it */
14181418

14191419
release_dropit:
@@ -1425,6 +1425,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
14251425
return 0;
14261426

14271427
close:
1428+
svc_authorise(rqstp);
1429+
close_xprt:
14281430
if (rqstp->rq_xprt && test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
14291431
svc_close_xprt(rqstp->rq_xprt);
14301432
dprintk("svc: svc_process close\n");
@@ -1433,7 +1435,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
14331435
err_short_len:
14341436
svc_printk(rqstp, "short len %zd, dropping request\n",
14351437
argv->iov_len);
1436-
goto close;
1438+
goto close_xprt;
14371439

14381440
err_bad_rpc:
14391441
serv->sv_stats->rpcbadfmt++;

net/sunrpc/svc_xprt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,15 +1060,15 @@ static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, st
10601060
struct svc_xprt *xprt;
10611061
int ret = 0;
10621062

1063-
spin_lock(&serv->sv_lock);
1063+
spin_lock_bh(&serv->sv_lock);
10641064
list_for_each_entry(xprt, xprt_list, xpt_list) {
10651065
if (xprt->xpt_net != net)
10661066
continue;
10671067
ret++;
10681068
set_bit(XPT_CLOSE, &xprt->xpt_flags);
10691069
svc_xprt_enqueue(xprt);
10701070
}
1071-
spin_unlock(&serv->sv_lock);
1071+
spin_unlock_bh(&serv->sv_lock);
10721072
return ret;
10731073
}
10741074

0 commit comments

Comments
 (0)