Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 6d69b6c

Browse files
committed
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
2 parents b4d88a6 + 3c0a2e0 commit 6d69b6c

File tree

16 files changed

+129
-68
lines changed

16 files changed

+129
-68
lines changed

fs/nfs/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ config NFS_FS
3333
config NFS_V2
3434
tristate "NFS client support for NFS version 2"
3535
depends on NFS_FS
36-
default y
36+
default n
3737
help
3838
This option enables support for version 2 of the NFS protocol
3939
(RFC 1094) in the kernel's NFS client.
4040

41-
If unsure, say Y.
41+
If unsure, say N.
4242

4343
config NFS_V3
4444
tristate "NFS client support for NFS version 3"

fs/nfs/dir.c

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ static int nfs_readdir(struct file *, struct dir_context *);
5656
static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
5757
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
5858
static void nfs_readdir_clear_array(struct folio *);
59+
static int nfs_do_create(struct inode *dir, struct dentry *dentry,
60+
umode_t mode, int open_flags);
5961

6062
const struct file_operations nfs_dir_operations = {
6163
.llseek = nfs_llseek_dir,
@@ -2243,6 +2245,41 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
22432245

22442246
#endif /* CONFIG_NFSV4 */
22452247

2248+
int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
2249+
struct file *file, unsigned int open_flags,
2250+
umode_t mode)
2251+
{
2252+
2253+
/* Same as look+open from lookup_open(), but with different O_TRUNC
2254+
* handling.
2255+
*/
2256+
int error = 0;
2257+
2258+
if (open_flags & O_CREAT) {
2259+
file->f_mode |= FMODE_CREATED;
2260+
error = nfs_do_create(dir, dentry, mode, open_flags);
2261+
if (error)
2262+
return error;
2263+
return finish_open(file, dentry, NULL);
2264+
} else if (d_in_lookup(dentry)) {
2265+
/* The only flags nfs_lookup considers are
2266+
* LOOKUP_EXCL and LOOKUP_RENAME_TARGET, and
2267+
* we want those to be zero so the lookup isn't skipped.
2268+
*/
2269+
struct dentry *res = nfs_lookup(dir, dentry, 0);
2270+
2271+
d_lookup_done(dentry);
2272+
if (unlikely(res)) {
2273+
if (IS_ERR(res))
2274+
return PTR_ERR(res);
2275+
return finish_no_open(file, res);
2276+
}
2277+
}
2278+
return finish_no_open(file, NULL);
2279+
2280+
}
2281+
EXPORT_SYMBOL_GPL(nfs_atomic_open_v23);
2282+
22462283
struct dentry *
22472284
nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
22482285
struct nfs_fattr *fattr)
@@ -2303,18 +2340,23 @@ EXPORT_SYMBOL_GPL(nfs_instantiate);
23032340
* that the operation succeeded on the server, but an error in the
23042341
* reply path made it appear to have failed.
23052342
*/
2306-
int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
2307-
struct dentry *dentry, umode_t mode, bool excl)
2343+
static int nfs_do_create(struct inode *dir, struct dentry *dentry,
2344+
umode_t mode, int open_flags)
23082345
{
23092346
struct iattr attr;
2310-
int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT;
23112347
int error;
23122348

2349+
open_flags |= O_CREAT;
2350+
23132351
dfprintk(VFS, "NFS: create(%s/%lu), %pd\n",
23142352
dir->i_sb->s_id, dir->i_ino, dentry);
23152353

23162354
attr.ia_mode = mode;
23172355
attr.ia_valid = ATTR_MODE;
2356+
if (open_flags & O_TRUNC) {
2357+
attr.ia_size = 0;
2358+
attr.ia_valid |= ATTR_SIZE;
2359+
}
23182360

23192361
trace_nfs_create_enter(dir, dentry, open_flags);
23202362
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
@@ -2326,6 +2368,12 @@ int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
23262368
d_drop(dentry);
23272369
return error;
23282370
}
2371+
2372+
int nfs_create(struct mnt_idmap *idmap, struct inode *dir,
2373+
struct dentry *dentry, umode_t mode, bool excl)
2374+
{
2375+
return nfs_do_create(dir, dentry, mode, excl ? O_EXCL : 0);
2376+
}
23292377
EXPORT_SYMBOL_GPL(nfs_create);
23302378

23312379
/*

fs/nfs/filelayout/filelayout.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -605,14 +605,6 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
605605

606606
dprintk("--> %s\n", __func__);
607607

608-
/* FIXME: remove this check when layout segment support is added */
609-
if (lgr->range.offset != 0 ||
610-
lgr->range.length != NFS4_MAX_UINT64) {
611-
dprintk("%s Only whole file layouts supported. Use MDS i/o\n",
612-
__func__);
613-
goto out;
614-
}
615-
616608
if (fl->pattern_offset > lgr->range.offset) {
617609
dprintk("%s pattern_offset %lld too large\n",
618610
__func__, fl->pattern_offset);
@@ -875,15 +867,15 @@ static void
875867
filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
876868
struct nfs_page *req)
877869
{
878-
pnfs_generic_pg_check_layout(pgio);
870+
pnfs_generic_pg_check_layout(pgio, req);
879871
if (!pgio->pg_lseg) {
880872
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
881873
nfs_req_openctx(req),
882-
0,
883-
NFS4_MAX_UINT64,
874+
req_offset(req),
875+
req->wb_bytes,
884876
IOMODE_READ,
885877
false,
886-
GFP_KERNEL);
878+
nfs_io_gfp_mask());
887879
if (IS_ERR(pgio->pg_lseg)) {
888880
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
889881
pgio->pg_lseg = NULL;
@@ -899,15 +891,15 @@ static void
899891
filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
900892
struct nfs_page *req)
901893
{
902-
pnfs_generic_pg_check_layout(pgio);
894+
pnfs_generic_pg_check_layout(pgio, req);
903895
if (!pgio->pg_lseg) {
904896
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
905897
nfs_req_openctx(req),
906-
0,
907-
NFS4_MAX_UINT64,
898+
req_offset(req),
899+
req->wb_bytes,
908900
IOMODE_RW,
909901
false,
910-
GFP_NOFS);
902+
nfs_io_gfp_mask());
911903
if (IS_ERR(pgio->pg_lseg)) {
912904
pgio->pg_error = PTR_ERR(pgio->pg_lseg);
913905
pgio->pg_lseg = NULL;

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -822,14 +822,6 @@ ff_layout_pg_get_read(struct nfs_pageio_descriptor *pgio,
822822
}
823823
}
824824

825-
static void
826-
ff_layout_pg_check_layout(struct nfs_pageio_descriptor *pgio,
827-
struct nfs_page *req)
828-
{
829-
pnfs_generic_pg_check_layout(pgio);
830-
pnfs_generic_pg_check_range(pgio, req);
831-
}
832-
833825
static void
834826
ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
835827
struct nfs_page *req)
@@ -840,7 +832,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
840832
u32 ds_idx;
841833

842834
retry:
843-
ff_layout_pg_check_layout(pgio, req);
835+
pnfs_generic_pg_check_layout(pgio, req);
844836
/* Use full layout for now */
845837
if (!pgio->pg_lseg) {
846838
ff_layout_pg_get_read(pgio, req, false);
@@ -895,7 +887,7 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
895887
u32 i;
896888

897889
retry:
898-
ff_layout_pg_check_layout(pgio, req);
890+
pnfs_generic_pg_check_layout(pgio, req);
899891
if (!pgio->pg_lseg) {
900892
pgio->pg_lseg =
901893
pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),

fs/nfs/fs_context.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,11 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
600600
break;
601601
case Opt_lock:
602602
if (result.negated) {
603+
ctx->lock_status = NFS_LOCK_NOLOCK;
603604
ctx->flags |= NFS_MOUNT_NONLM;
604605
ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
605606
} else {
607+
ctx->lock_status = NFS_LOCK_LOCK;
606608
ctx->flags &= ~NFS_MOUNT_NONLM;
607609
ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
608610
}
@@ -1112,9 +1114,12 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
11121114
ctx->acdirmax = data->acdirmax;
11131115
ctx->need_mount = false;
11141116

1115-
memcpy(sap, &data->addr, sizeof(data->addr));
1116-
ctx->nfs_server.addrlen = sizeof(data->addr);
1117-
ctx->nfs_server.port = ntohs(data->addr.sin_port);
1117+
if (!is_remount_fc(fc)) {
1118+
memcpy(sap, &data->addr, sizeof(data->addr));
1119+
ctx->nfs_server.addrlen = sizeof(data->addr);
1120+
ctx->nfs_server.port = ntohs(data->addr.sin_port);
1121+
}
1122+
11181123
if (sap->ss_family != AF_INET ||
11191124
!nfs_verify_server_address(sap))
11201125
goto out_no_address;

fs/nfs/internal.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct nfs_fs_context {
112112
unsigned short protofamily;
113113
unsigned short mountfamily;
114114
bool has_sec_mnt_opts;
115+
int lock_status;
115116

116117
struct {
117118
union {
@@ -153,6 +154,12 @@ struct nfs_fs_context {
153154
} clone_data;
154155
};
155156

157+
enum nfs_lock_status {
158+
NFS_LOCK_NOT_SET = 0,
159+
NFS_LOCK_LOCK = 1,
160+
NFS_LOCK_NOLOCK = 2,
161+
};
162+
156163
#define nfs_errorf(fc, fmt, ...) ((fc)->log.log ? \
157164
errorf(fc, fmt, ## __VA_ARGS__) : \
158165
({ dprintk(fmt "\n", ## __VA_ARGS__); }))
@@ -710,9 +717,9 @@ unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
710717
if ((bsize & (bsize - 1)) || nrbitsp) {
711718
unsigned char nrbits;
712719

713-
for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
720+
for (nrbits = 31; nrbits && !(bsize & (1UL << nrbits)); nrbits--)
714721
;
715-
bsize = 1 << nrbits;
722+
bsize = 1UL << nrbits;
716723
if (nrbitsp)
717724
*nrbitsp = nrbits;
718725
}

fs/nfs/nfs3proc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,7 @@ static int nfs3_have_delegation(struct inode *inode, fmode_t flags)
986986

987987
static const struct inode_operations nfs3_dir_inode_operations = {
988988
.create = nfs_create,
989+
.atomic_open = nfs_atomic_open_v23,
989990
.lookup = nfs_lookup,
990991
.link = nfs_link,
991992
.unlink = nfs_unlink,

fs/nfs/nfs4proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5456,7 +5456,7 @@ static bool nfs4_read_plus_not_supported(struct rpc_task *task,
54565456
struct rpc_message *msg = &task->tk_msg;
54575457

54585458
if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS] &&
5459-
server->caps & NFS_CAP_READ_PLUS && task->tk_status == -ENOTSUPP) {
5459+
task->tk_status == -ENOTSUPP) {
54605460
server->caps &= ~NFS_CAP_READ_PLUS;
54615461
msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
54625462
rpc_restart_call_prepare(task);

fs/nfs/nfs4state.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,7 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
21162116
{
21172117
struct nfs_client *clp = server->nfs_client;
21182118
struct nfs4_fs_locations *locations = NULL;
2119+
struct nfs_fattr *fattr;
21192120
struct inode *inode;
21202121
struct page *page;
21212122
int status, result;
@@ -2125,19 +2126,16 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
21252126
(unsigned long long)server->fsid.minor,
21262127
clp->cl_hostname);
21272128

2128-
result = 0;
21292129
page = alloc_page(GFP_KERNEL);
21302130
locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
2131-
if (page == NULL || locations == NULL) {
2132-
dprintk("<-- %s: no memory\n", __func__);
2133-
goto out;
2134-
}
2135-
locations->fattr = nfs_alloc_fattr();
2136-
if (locations->fattr == NULL) {
2131+
fattr = nfs_alloc_fattr();
2132+
if (page == NULL || locations == NULL || fattr == NULL) {
21372133
dprintk("<-- %s: no memory\n", __func__);
2134+
result = 0;
21382135
goto out;
21392136
}
21402137

2138+
locations->fattr = fattr;
21412139
inode = d_inode(server->super->s_root);
21422140
result = nfs4_proc_get_locations(server, NFS_FH(inode), locations,
21432141
page, cred);

fs/nfs/pnfs.c

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,38 +2705,28 @@ pnfs_layout_return_unused_byclid(struct nfs_client *clp,
27052705
&range);
27062706
}
27072707

2708+
/* Check if we have we have a valid layout but if there isn't an intersection
2709+
* between the request and the pgio->pg_lseg, put this pgio->pg_lseg away.
2710+
*/
27082711
void
2709-
pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio)
2712+
pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio,
2713+
struct nfs_page *req)
27102714
{
27112715
if (pgio->pg_lseg == NULL ||
2712-
test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags))
2716+
(test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags) &&
2717+
pnfs_lseg_request_intersecting(pgio->pg_lseg, req)))
27132718
return;
27142719
pnfs_put_lseg(pgio->pg_lseg);
27152720
pgio->pg_lseg = NULL;
27162721
}
27172722
EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_layout);
27182723

2719-
/*
2720-
* Check for any intersection between the request and the pgio->pg_lseg,
2721-
* and if none, put this pgio->pg_lseg away.
2722-
*/
2723-
void
2724-
pnfs_generic_pg_check_range(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
2725-
{
2726-
if (pgio->pg_lseg && !pnfs_lseg_request_intersecting(pgio->pg_lseg, req)) {
2727-
pnfs_put_lseg(pgio->pg_lseg);
2728-
pgio->pg_lseg = NULL;
2729-
}
2730-
}
2731-
EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_range);
2732-
27332724
void
27342725
pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
27352726
{
27362727
u64 rd_size;
27372728

2738-
pnfs_generic_pg_check_layout(pgio);
2739-
pnfs_generic_pg_check_range(pgio, req);
2729+
pnfs_generic_pg_check_layout(pgio, req);
27402730
if (pgio->pg_lseg == NULL) {
27412731
if (pgio->pg_dreq == NULL)
27422732
rd_size = i_size_read(pgio->pg_inode) - req_offset(req);
@@ -2766,8 +2756,7 @@ void
27662756
pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
27672757
struct nfs_page *req, u64 wb_size)
27682758
{
2769-
pnfs_generic_pg_check_layout(pgio);
2770-
pnfs_generic_pg_check_range(pgio, req);
2759+
pnfs_generic_pg_check_layout(pgio, req);
27712760
if (pgio->pg_lseg == NULL) {
27722761
pgio->pg_lseg =
27732762
pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req),

0 commit comments

Comments
 (0)