Skip to content

Commit a746ca6

Browse files
committed
Merge tag 'nfsd-6.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd fixes from Chuck Lever: - Two minor bug fixes * tag 'nfsd-6.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: nfsd: fix double fget() bug in __write_ports_addfd() nfsd: make a copy of struct iattr before calling notify_change
2 parents 2b74977 + c034203 commit a746ca6

File tree

4 files changed

+19
-29
lines changed

4 files changed

+19
-29
lines changed

fs/nfsd/nfsctl.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -690,16 +690,11 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred
690690
if (err != 0 || fd < 0)
691691
return -EINVAL;
692692

693-
if (svc_alien_sock(net, fd)) {
694-
printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
695-
return -EINVAL;
696-
}
697-
698693
err = nfsd_create_serv(net);
699694
if (err != 0)
700695
return err;
701696

702-
err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
697+
err = svc_addsock(nn->nfsd_serv, net, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
703698

704699
if (err >= 0 &&
705700
!nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1))

fs/nfsd/vfs.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,15 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
536536

537537
inode_lock(inode);
538538
for (retries = 1;;) {
539-
host_err = __nfsd_setattr(dentry, iap);
539+
struct iattr attrs;
540+
541+
/*
542+
* notify_change() can alter its iattr argument, making
543+
* @iap unsuitable for submission multiple times. Make a
544+
* copy for every loop iteration.
545+
*/
546+
attrs = *iap;
547+
host_err = __nfsd_setattr(dentry, &attrs);
540548
if (host_err != -EAGAIN || !retries--)
541549
break;
542550
if (!nfsd_wait_for_delegreturn(rqstp, inode))

include/linux/sunrpc/svcsock.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,9 @@ int svc_recv(struct svc_rqst *, long);
6161
void svc_send(struct svc_rqst *rqstp);
6262
void svc_drop(struct svc_rqst *);
6363
void svc_sock_update_bufs(struct svc_serv *serv);
64-
bool svc_alien_sock(struct net *net, int fd);
65-
int svc_addsock(struct svc_serv *serv, const int fd,
66-
char *name_return, const size_t len,
67-
const struct cred *cred);
64+
int svc_addsock(struct svc_serv *serv, struct net *net,
65+
const int fd, char *name_return, const size_t len,
66+
const struct cred *cred);
6867
void svc_init_xprt_sock(void);
6968
void svc_cleanup_xprt_sock(void);
7069
struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot);

net/sunrpc/svcsock.c

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,25 +1480,10 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
14801480
return svsk;
14811481
}
14821482

1483-
bool svc_alien_sock(struct net *net, int fd)
1484-
{
1485-
int err;
1486-
struct socket *sock = sockfd_lookup(fd, &err);
1487-
bool ret = false;
1488-
1489-
if (!sock)
1490-
goto out;
1491-
if (sock_net(sock->sk) != net)
1492-
ret = true;
1493-
sockfd_put(sock);
1494-
out:
1495-
return ret;
1496-
}
1497-
EXPORT_SYMBOL_GPL(svc_alien_sock);
1498-
14991483
/**
15001484
* svc_addsock - add a listener socket to an RPC service
15011485
* @serv: pointer to RPC service to which to add a new listener
1486+
* @net: caller's network namespace
15021487
* @fd: file descriptor of the new listener
15031488
* @name_return: pointer to buffer to fill in with name of listener
15041489
* @len: size of the buffer
@@ -1508,8 +1493,8 @@ EXPORT_SYMBOL_GPL(svc_alien_sock);
15081493
* Name is terminated with '\n'. On error, returns a negative errno
15091494
* value.
15101495
*/
1511-
int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
1512-
const size_t len, const struct cred *cred)
1496+
int svc_addsock(struct svc_serv *serv, struct net *net, const int fd,
1497+
char *name_return, const size_t len, const struct cred *cred)
15131498
{
15141499
int err = 0;
15151500
struct socket *so = sockfd_lookup(fd, &err);
@@ -1520,6 +1505,9 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
15201505

15211506
if (!so)
15221507
return err;
1508+
err = -EINVAL;
1509+
if (sock_net(so->sk) != net)
1510+
goto out;
15231511
err = -EAFNOSUPPORT;
15241512
if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6))
15251513
goto out;

0 commit comments

Comments
 (0)