NFS client updates for Linux 6.10
Highlights include: Stable fixes: - nfs: fix undefined behavior in nfs_block_bits() - NFSv4.2: Fix READ_PLUS when server doesn't support OP_READ_PLUS Bugfixes: - Fix mixing of the lock/nolock and local_lock mount options - NFSv4: Fixup smatch warning for ambiguous return - NFSv3: Fix remount when using the legacy binary mount api - SUNRPC: Fix the handling of expired RPCSEC_GSS contexts - SUNRPC: fix the NFSACL RPC retries when soft mounts are enabled - rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL Features and cleanups: - NFSv3: Use the atomic_open API to fix open(O_CREAT|O_TRUNC) - pNFS/filelayout: S layout segment range in LAYOUTGET - pNFS: rework pnfs_generic_pg_check_layout to check IO range - NFSv2: Turn off enabling of NFS v2 by default -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEESQctxSBg8JpV8KqEZwvnipYKAPIFAmZPpYMACgkQZwvnipYK APITOw//acjE9YTZcST9kgkf2bfwuHFcdxvMZAr4MV0YsfqMesU2MYmaK/5YMLyo iNCHjLmlfE2iLAUqvFtakc1F3guACJqqFfMdnMHa1MwPznrL3yNNClGnBamovbPd XK2MBgpQBXb+xLxqH0A2TtOK2ofk0CFzb3x9eaziox8omBM2j3v6ZARsDHYehuhM Hig8IxW/kZ7kx5jxqSVktrgW3gDKqIuLssF6fJVINzh45jHC5QO98cuSwetx6Mi1 Aw04HbOE6B66ORrzC1wyGN3PwOkTW2kgAiyB6UNNt+Hnvr0RD5TEqf3s3mzmhP9N 7LJ3H1Okxdcpn0G/bR4LBUg26r5BWxhfPiTYG/l9vAQk65yt2LO1kFzXbECBEfaG ctGG7/7mMLVPs05kIFYm5S0cIYW2dYNuE20JY50LMaCIopjThdfruQj3yR4xibSt bHrAbG9wW4qg/cgx860t5h7nbZnD5OOYIqKOCDRNrUfP7P0mK/tD49HggLjDo47M vIMlYS3bTNSF7uEPTrv6bFr8XOD1I3BVXDQwGaJMZ8zyhkUIQtKO70+i4xM1E/Wl Jw5Z6NpM8saDD449ZqX4IRUPDAhvz4v00QqD3Tqr4MHEc5sWi898S7XcJgL3bEai QMJmBkAK8aDAP/suPw8VQc9wqplFNlB+QEh87p2WO+yRoEucn+A= =HMSC -----END PGP SIGNATURE----- Merge tag 'nfs-for-6.10-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs Pull NFS client updates from Trond Myklebust: "Stable fixes: - nfs: fix undefined behavior in nfs_block_bits() - NFSv4.2: Fix READ_PLUS when server doesn't support OP_READ_PLUS Bugfixes: - Fix mixing of the lock/nolock and local_lock mount options - NFSv4: Fixup smatch warning for ambiguous return - NFSv3: Fix remount when using the legacy binary mount api - SUNRPC: Fix the handling of expired RPCSEC_GSS contexts - SUNRPC: fix the NFSACL RPC retries when soft mounts are enabled - rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL Features and cleanups: - NFSv3: Use the atomic_open API to fix open(O_CREAT|O_TRUNC) - pNFS/filelayout: S layout segment range in LAYOUTGET - pNFS: rework pnfs_generic_pg_check_layout to check IO range - NFSv2: Turn off enabling of NFS v2 by default" * tag 'nfs-for-6.10-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: nfs: fix undefined behavior in nfs_block_bits() pNFS: rework pnfs_generic_pg_check_layout to check IO range pNFS/filelayout: check layout segment range pNFS/filelayout: fixup pNfs allocation modes rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL NFS: Don't enable NFS v2 by default NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS sunrpc: fix NFSACL RPC retry on soft mount SUNRPC: fix handling expired GSS context nfs: keep server info for remounts NFSv4: Fixup smatch warning for ambiguous return NFS: make sure lock/nolock overriding local_lock mount option NFS: add atomic_open for NFSv3 to handle O_TRUNC correctly. pNFS/filelayout: Specify the layout segment range in LAYOUTGET pNFS/filelayout: Remove the whole file layout requirement
This commit is contained in:
commit
6d69b6c12f
@ -33,12 +33,12 @@ config NFS_FS
|
||||
config NFS_V2
|
||||
tristate "NFS client support for NFS version 2"
|
||||
depends on NFS_FS
|
||||
default y
|
||||
default n
|
||||
help
|
||||
This option enables support for version 2 of the NFS protocol
|
||||
(RFC 1094) in the kernel's NFS client.
|
||||
|
||||
If unsure, say Y.
|
||||
If unsure, say N.
|
||||
|
||||
config NFS_V3
|
||||
tristate "NFS client support for NFS version 3"
|
||||
|
54
fs/nfs/dir.c
54
fs/nfs/dir.c
@ -56,6 +56,8 @@ static int nfs_readdir(struct file *, struct dir_context *);
|
||||
static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
|
||||
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
|
||||
static void nfs_readdir_clear_array(struct folio *);
|
||||
static int nfs_do_create(struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode, int open_flags);
|
||||
|
||||
const struct file_operations nfs_dir_operations = {
|
||||
.llseek = nfs_llseek_dir,
|
||||
@ -2243,6 +2245,41 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
|
||||
#endif /* CONFIG_NFSV4 */
|
||||
|
||||
int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
|
||||
struct file *file, unsigned int open_flags,
|
||||
umode_t mode)
|
||||
{
|
||||
|
||||
/* Same as look+open from lookup_open(), but with different O_TRUNC
|
||||
* handling.
|
||||
*/
|
||||
int error = 0;
|
||||
|
||||
if (open_flags & O_CREAT) {
|
||||
file->f_mode |= FMODE_CREATED;
|
||||
error = nfs_do_create(dir, dentry, mode, open_flags);
|
||||
if (error)
|
||||
return error;
|
||||
return finish_open(file, dentry, NULL);
|
||||
} else if (d_in_lookup(dentry)) {
|
||||
/* The only flags nfs_lookup considers are
|
||||
* LOOKUP_EXCL and LOOKUP_RENAME_TARGET, and
|
||||
* we want those to be zero so the lookup isn't skipped.
|
||||
*/
|
||||
struct dentry *res = nfs_lookup(dir, dentry, 0);
|
||||
|
||||
d_lookup_done(dentry);
|
||||
if (unlikely(res)) {
|
||||
if (IS_ERR(res))
|
||||
return PTR_ERR(res);
|
||||
return finish_no_open(file, res);
|
||||
}
|
||||
}
|
||||
return finish_no_open(file, NULL);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_atomic_open_v23);
|
||||
|
||||
struct dentry *
|
||||
nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||
struct nfs_fattr *fattr)
|
||||
@ -2303,18 +2340,23 @@ EXPORT_SYMBOL_GPL(nfs_instantiate);
|
||||
* that the operation succeeded on the server, but an error in the
|
||||
* reply path made it appear to have failed.
|
||||
*/
|
||||
int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode, bool excl)
|
||||
static int nfs_do_create(struct inode *dir, struct dentry *dentry,
|
||||
umode_t mode, int open_flags)
|
||||
{
|
||||
struct iattr attr;
|
||||
int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT;
|
||||
int error;
|
||||
|
||||
open_flags |= O_CREAT;
|
||||
|
||||
dfprintk(VFS, "NFS: create(%s/%lu), %pd\n",
|
||||
dir->i_sb->s_id, dir->i_ino, dentry);
|
||||
|
||||
attr.ia_mode = mode;
|
||||
attr.ia_valid = ATTR_MODE;
|
||||
if (open_flags & O_TRUNC) {
|
||||
attr.ia_size = 0;
|
||||
attr.ia_valid |= ATTR_SIZE;
|
||||
}
|
||||
|
||||
trace_nfs_create_enter(dir, dentry, open_flags);
|
||||
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
|
||||
@ -2326,6 +2368,12 @@ out_err:
|
||||
d_drop(dentry);
|
||||
return error;
|
||||
}
|
||||
|
||||
int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
|
||||
struct dentry *dentry, umode_t mode, bool excl)
|
||||
{
|
||||
return nfs_do_create(dir, dentry, mode, excl ? O_EXCL : 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_create);
|
||||
|
||||
/*
|
||||
|
@ -605,14 +605,6 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
|
||||
|
||||
dprintk("--> %s\n", __func__);
|
||||
|
||||
/* FIXME: remove this check when layout segment support is added */
|
||||
if (lgr->range.offset != 0 ||
|
||||
lgr->range.length != NFS4_MAX_UINT64) {
|
||||
dprintk("%s Only whole file layouts supported. Use MDS i/o\n",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fl->pattern_offset > lgr->range.offset) {
|
||||
dprintk("%s pattern_offset %lld too large\n",
|
||||
__func__, fl->pattern_offset);
|
||||
@ -875,15 +867,15 @@ static void
|
||||
filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
pnfs_generic_pg_check_layout(pgio, req);
|
||||
if (!pgio->pg_lseg) {
|
||||
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
|
||||
nfs_req_openctx(req),
|
||||
0,
|
||||
NFS4_MAX_UINT64,
|
||||
req_offset(req),
|
||||
req->wb_bytes,
|
||||
IOMODE_READ,
|
||||
false,
|
||||
GFP_KERNEL);
|
||||
nfs_io_gfp_mask());
|
||||
if (IS_ERR(pgio->pg_lseg)) {
|
||||
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
|
||||
pgio->pg_lseg = NULL;
|
||||
@ -899,15 +891,15 @@ static void
|
||||
filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
pnfs_generic_pg_check_layout(pgio, req);
|
||||
if (!pgio->pg_lseg) {
|
||||
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
|
||||
nfs_req_openctx(req),
|
||||
0,
|
||||
NFS4_MAX_UINT64,
|
||||
req_offset(req),
|
||||
req->wb_bytes,
|
||||
IOMODE_RW,
|
||||
false,
|
||||
GFP_NOFS);
|
||||
nfs_io_gfp_mask());
|
||||
if (IS_ERR(pgio->pg_lseg)) {
|
||||
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
|
||||
pgio->pg_lseg = NULL;
|
||||
|
@ -822,14 +822,6 @@ ff_layout_pg_get_read(struct nfs_pageio_descriptor *pgio,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ff_layout_pg_check_layout(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
pnfs_generic_pg_check_range(pgio, req);
|
||||
}
|
||||
|
||||
static void
|
||||
ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req)
|
||||
@ -840,7 +832,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
|
||||
u32 ds_idx;
|
||||
|
||||
retry:
|
||||
ff_layout_pg_check_layout(pgio, req);
|
||||
pnfs_generic_pg_check_layout(pgio, req);
|
||||
/* Use full layout for now */
|
||||
if (!pgio->pg_lseg) {
|
||||
ff_layout_pg_get_read(pgio, req, false);
|
||||
@ -895,7 +887,7 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
u32 i;
|
||||
|
||||
retry:
|
||||
ff_layout_pg_check_layout(pgio, req);
|
||||
pnfs_generic_pg_check_layout(pgio, req);
|
||||
if (!pgio->pg_lseg) {
|
||||
pgio->pg_lseg =
|
||||
pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),
|
||||
|
@ -600,9 +600,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
|
||||
break;
|
||||
case Opt_lock:
|
||||
if (result.negated) {
|
||||
ctx->lock_status = NFS_LOCK_NOLOCK;
|
||||
ctx->flags |= NFS_MOUNT_NONLM;
|
||||
ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
|
||||
} else {
|
||||
ctx->lock_status = NFS_LOCK_LOCK;
|
||||
ctx->flags &= ~NFS_MOUNT_NONLM;
|
||||
ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
|
||||
}
|
||||
@ -1112,9 +1114,12 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
|
||||
ctx->acdirmax = data->acdirmax;
|
||||
ctx->need_mount = false;
|
||||
|
||||
memcpy(sap, &data->addr, sizeof(data->addr));
|
||||
ctx->nfs_server.addrlen = sizeof(data->addr);
|
||||
ctx->nfs_server.port = ntohs(data->addr.sin_port);
|
||||
if (!is_remount_fc(fc)) {
|
||||
memcpy(sap, &data->addr, sizeof(data->addr));
|
||||
ctx->nfs_server.addrlen = sizeof(data->addr);
|
||||
ctx->nfs_server.port = ntohs(data->addr.sin_port);
|
||||
}
|
||||
|
||||
if (sap->ss_family != AF_INET ||
|
||||
!nfs_verify_server_address(sap))
|
||||
goto out_no_address;
|
||||
|
@ -112,6 +112,7 @@ struct nfs_fs_context {
|
||||
unsigned short protofamily;
|
||||
unsigned short mountfamily;
|
||||
bool has_sec_mnt_opts;
|
||||
int lock_status;
|
||||
|
||||
struct {
|
||||
union {
|
||||
@ -153,6 +154,12 @@ struct nfs_fs_context {
|
||||
} clone_data;
|
||||
};
|
||||
|
||||
enum nfs_lock_status {
|
||||
NFS_LOCK_NOT_SET = 0,
|
||||
NFS_LOCK_LOCK = 1,
|
||||
NFS_LOCK_NOLOCK = 2,
|
||||
};
|
||||
|
||||
#define nfs_errorf(fc, fmt, ...) ((fc)->log.log ? \
|
||||
errorf(fc, fmt, ## __VA_ARGS__) : \
|
||||
({ dprintk(fmt "\n", ## __VA_ARGS__); }))
|
||||
@ -710,9 +717,9 @@ unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
|
||||
if ((bsize & (bsize - 1)) || nrbitsp) {
|
||||
unsigned char nrbits;
|
||||
|
||||
for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
|
||||
for (nrbits = 31; nrbits && !(bsize & (1UL << nrbits)); nrbits--)
|
||||
;
|
||||
bsize = 1 << nrbits;
|
||||
bsize = 1UL << nrbits;
|
||||
if (nrbitsp)
|
||||
*nrbitsp = nrbits;
|
||||
}
|
||||
|
@ -986,6 +986,7 @@ static int nfs3_have_delegation(struct inode *inode, fmode_t flags)
|
||||
|
||||
static const struct inode_operations nfs3_dir_inode_operations = {
|
||||
.create = nfs_create,
|
||||
.atomic_open = nfs_atomic_open_v23,
|
||||
.lookup = nfs_lookup,
|
||||
.link = nfs_link,
|
||||
.unlink = nfs_unlink,
|
||||
|
@ -5456,7 +5456,7 @@ static bool nfs4_read_plus_not_supported(struct rpc_task *task,
|
||||
struct rpc_message *msg = &task->tk_msg;
|
||||
|
||||
if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS] &&
|
||||
server->caps & NFS_CAP_READ_PLUS && task->tk_status == -ENOTSUPP) {
|
||||
task->tk_status == -ENOTSUPP) {
|
||||
server->caps &= ~NFS_CAP_READ_PLUS;
|
||||
msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
|
||||
rpc_restart_call_prepare(task);
|
||||
|
@ -2116,6 +2116,7 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
|
||||
{
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
struct nfs4_fs_locations *locations = NULL;
|
||||
struct nfs_fattr *fattr;
|
||||
struct inode *inode;
|
||||
struct page *page;
|
||||
int status, result;
|
||||
@ -2125,19 +2126,16 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
|
||||
(unsigned long long)server->fsid.minor,
|
||||
clp->cl_hostname);
|
||||
|
||||
result = 0;
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
|
||||
if (page == NULL || locations == NULL) {
|
||||
dprintk("<-- %s: no memory\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
locations->fattr = nfs_alloc_fattr();
|
||||
if (locations->fattr == NULL) {
|
||||
fattr = nfs_alloc_fattr();
|
||||
if (page == NULL || locations == NULL || fattr == NULL) {
|
||||
dprintk("<-- %s: no memory\n", __func__);
|
||||
result = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
locations->fattr = fattr;
|
||||
inode = d_inode(server->super->s_root);
|
||||
result = nfs4_proc_get_locations(server, NFS_FH(inode), locations,
|
||||
page, cred);
|
||||
|
@ -2705,38 +2705,28 @@ pnfs_layout_return_unused_byclid(struct nfs_client *clp,
|
||||
&range);
|
||||
}
|
||||
|
||||
/* Check if we have we have a valid layout but if there isn't an intersection
|
||||
* between the request and the pgio->pg_lseg, put this pgio->pg_lseg away.
|
||||
*/
|
||||
void
|
||||
pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio)
|
||||
pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
if (pgio->pg_lseg == NULL ||
|
||||
test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags))
|
||||
(test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags) &&
|
||||
pnfs_lseg_request_intersecting(pgio->pg_lseg, req)))
|
||||
return;
|
||||
pnfs_put_lseg(pgio->pg_lseg);
|
||||
pgio->pg_lseg = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_layout);
|
||||
|
||||
/*
|
||||
* Check for any intersection between the request and the pgio->pg_lseg,
|
||||
* and if none, put this pgio->pg_lseg away.
|
||||
*/
|
||||
void
|
||||
pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
|
||||
{
|
||||
if (pgio->pg_lseg && !pnfs_lseg_request_intersecting(pgio->pg_lseg, req)) {
|
||||
pnfs_put_lseg(pgio->pg_lseg);
|
||||
pgio->pg_lseg = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_range);
|
||||
|
||||
void
|
||||
pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
|
||||
{
|
||||
u64 rd_size;
|
||||
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
pnfs_generic_pg_check_range(pgio, req);
|
||||
pnfs_generic_pg_check_layout(pgio, req);
|
||||
if (pgio->pg_lseg == NULL) {
|
||||
if (pgio->pg_dreq == NULL)
|
||||
rd_size = i_size_read(pgio->pg_inode) - req_offset(req);
|
||||
@ -2766,8 +2756,7 @@ void
|
||||
pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req, u64 wb_size)
|
||||
{
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
pnfs_generic_pg_check_range(pgio, req);
|
||||
pnfs_generic_pg_check_layout(pgio, req);
|
||||
if (pgio->pg_lseg == NULL) {
|
||||
pgio->pg_lseg =
|
||||
pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),
|
||||
|
@ -257,8 +257,7 @@ void pnfs_put_lseg(struct pnfs_layout_segment *lseg);
|
||||
|
||||
void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, struct nfs_fsinfo *);
|
||||
void unset_pnfs_layoutdriver(struct nfs_server *);
|
||||
void pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio);
|
||||
void pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req);
|
||||
void pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio, struct nfs_page *req);
|
||||
void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
|
||||
int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
|
||||
void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
|
@ -695,6 +695,7 @@ static int nfs_have_delegation(struct inode *inode, fmode_t flags)
|
||||
static const struct inode_operations nfs_dir_inode_operations = {
|
||||
.create = nfs_create,
|
||||
.lookup = nfs_lookup,
|
||||
.atomic_open = nfs_atomic_open_v23,
|
||||
.link = nfs_link,
|
||||
.unlink = nfs_unlink,
|
||||
.symlink = nfs_symlink,
|
||||
|
@ -901,6 +901,16 @@ static struct nfs_server *nfs_try_mount_request(struct fs_context *fc)
|
||||
rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS];
|
||||
unsigned int authlist_len = ARRAY_SIZE(authlist);
|
||||
|
||||
/* make sure 'nolock'/'lock' override the 'local_lock' mount option */
|
||||
if (ctx->lock_status) {
|
||||
if (ctx->lock_status == NFS_LOCK_NOLOCK) {
|
||||
ctx->flags |= NFS_MOUNT_NONLM;
|
||||
ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
|
||||
} else {
|
||||
ctx->flags &= ~NFS_MOUNT_NONLM;
|
||||
ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
|
||||
}
|
||||
}
|
||||
status = nfs_request_mount(fc, ctx->mntfh, authlist, &authlist_len);
|
||||
if (status)
|
||||
return ERR_PTR(status);
|
||||
|
@ -561,6 +561,9 @@ extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openfl
|
||||
extern void nfs_access_zap_cache(struct inode *inode);
|
||||
extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred,
|
||||
u32 *mask, bool may_block);
|
||||
extern int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
|
||||
struct file *file, unsigned int open_flags,
|
||||
umode_t mode);
|
||||
|
||||
/*
|
||||
* linux/fs/nfs/symlink.c
|
||||
|
@ -1071,6 +1071,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
|
||||
.authflavor = old->cl_auth->au_flavor,
|
||||
.cred = old->cl_cred,
|
||||
.stats = old->cl_stats,
|
||||
.timeout = old->cl_timeout,
|
||||
};
|
||||
struct rpc_clnt *clnt;
|
||||
int err;
|
||||
@ -2698,8 +2699,19 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
|
||||
goto out_msg_denied;
|
||||
|
||||
error = rpcauth_checkverf(task, xdr);
|
||||
if (error)
|
||||
if (error) {
|
||||
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
|
||||
|
||||
if (!test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) {
|
||||
rpcauth_invalcred(task);
|
||||
if (!task->tk_cred_retry)
|
||||
goto out_err;
|
||||
task->tk_cred_retry--;
|
||||
trace_rpc__stale_creds(task);
|
||||
return -EKEYREJECTED;
|
||||
}
|
||||
goto out_verifier;
|
||||
}
|
||||
|
||||
p = xdr_inline_decode(xdr, sizeof(*p));
|
||||
if (!p)
|
||||
|
@ -244,7 +244,11 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
|
||||
case RDMA_CM_EVENT_DEVICE_REMOVAL:
|
||||
pr_info("rpcrdma: removing device %s for %pISpc\n",
|
||||
ep->re_id->device->name, sap);
|
||||
fallthrough;
|
||||
switch (xchg(&ep->re_connect_status, -ENODEV)) {
|
||||
case 0: goto wake_connect_worker;
|
||||
case 1: goto disconnected;
|
||||
}
|
||||
return 0;
|
||||
case RDMA_CM_EVENT_ADDR_CHANGE:
|
||||
ep->re_connect_status = -ENODEV;
|
||||
goto disconnected;
|
||||
|
Loading…
Reference in New Issue
Block a user