All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] NFSD: Return NFSERR_ISDIR for NFSv2 READ and WRITE on a non-regular file
@ 2026-08-28 23:18 Chuck Lever
  2026-08-28 23:28 ` Jeff Layton
  2026-08-28 23:50 ` NeilBrown
  0 siblings, 2 replies; 3+ messages in thread
From: Chuck Lever @ 2026-08-28 23:18 UTC (permalink / raw)
  To: NeilBrown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey
  Cc: linux-nfs, Jörg Sommer

Commit 0ac903d1bfdc ("NFS: NFSERR_INVAL is not defined by NFSv2")
changed the status NFSD returns for an NFSv2 READ or WRITE of a
symlink or other non-regular file from NFSERR_INVAL to NFSERR_IO.
RFC 1094 defines neither an INVAL nor a SYMLINK status.

U-Boot's NFS client follows a symlink only when READ fails with
NFSERR_ISDIR or NFSERR_INVAL. Since that commit it cannot load a
boot image through a symlink exported by a Linux NFS server: the
load completes with zero bytes transferred.

Solaris returns NFSERR_ISDIR when the target of an NFSv2 READ or
WRITE is not a regular file. Return the same status from NFSD.
Other NFSv2 procedures continue to return NFSERR_IO.

Fixes: 0ac903d1bfdc ("NFS: NFSERR_INVAL is not defined by NFSv2")
Reported-by: Jörg Sommer <joerg@jo-so.de>
Closes: https://lore.kernel.org/linux-nfs/apE90ZRZB8IW_AiS@jo-so.de/
Signed-off-by: Chuck Lever <cel@kernel.org>
---
 fs/nfsd/nfsproc.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 48541ef7644f..09d360839825 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -40,6 +40,21 @@ static __be32 nfsd_map_status(__be32 status)
 	return status;
 }
 
+/*
+ * Because NFSv2 does not have an NFSERR_SYMLINK, Solaris returns
+ * NFSERR_ISDIR when the target of a READ or WRITE is any object
+ * that is not a regular file.
+ */
+static __be32 nfsd_map_io_status(__be32 status)
+{
+	switch (status) {
+	case nfserr_symlink:
+	case nfserr_wrong_type:
+		return nfserr_isdir;
+	}
+	return nfsd_map_status(status);
+}
+
 static __be32
 nfsd_proc_null(struct svc_rqst *rqstp)
 {
@@ -238,7 +253,7 @@ nfsd_proc_read(struct svc_rqst *rqstp)
 		resp->status = fh_getattr(&resp->fh, &resp->stat);
 	else if (resp->status == nfserr_jukebox)
 		set_bit(RQ_DROPME, &rqstp->rq_flags);
-	resp->status = nfsd_map_status(resp->status);
+	resp->status = nfsd_map_io_status(resp->status);
 	return rpc_success;
 }
 
@@ -271,7 +286,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
 		resp->status = fh_getattr(&resp->fh, &resp->stat);
 	else if (resp->status == nfserr_jukebox)
 		set_bit(RQ_DROPME, &rqstp->rq_flags);
-	resp->status = nfsd_map_status(resp->status);
+	resp->status = nfsd_map_io_status(resp->status);
 	return rpc_success;
 }
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v1] NFSD: Return NFSERR_ISDIR for NFSv2 READ and WRITE on a non-regular file
  2026-08-28 23:18 [PATCH v1] NFSD: Return NFSERR_ISDIR for NFSv2 READ and WRITE on a non-regular file Chuck Lever
@ 2026-08-28 23:28 ` Jeff Layton
  2026-08-28 23:50 ` NeilBrown
  1 sibling, 0 replies; 3+ messages in thread
From: Jeff Layton @ 2026-08-28 23:28 UTC (permalink / raw)
  To: Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey
  Cc: linux-nfs, Jörg Sommer

On Fri, 2026-08-28 at 19:18 -0400, Chuck Lever wrote:
> Commit 0ac903d1bfdc ("NFS: NFSERR_INVAL is not defined by NFSv2")
> changed the status NFSD returns for an NFSv2 READ or WRITE of a
> symlink or other non-regular file from NFSERR_INVAL to NFSERR_IO.
> RFC 1094 defines neither an INVAL nor a SYMLINK status.
> 
> U-Boot's NFS client follows a symlink only when READ fails with
> NFSERR_ISDIR or NFSERR_INVAL. Since that commit it cannot load a
> boot image through a symlink exported by a Linux NFS server: the
> load completes with zero bytes transferred.
> 
> Solaris returns NFSERR_ISDIR when the target of an NFSv2 READ or
> WRITE is not a regular file. Return the same status from NFSD.
> Other NFSv2 procedures continue to return NFSERR_IO.
> 
> Fixes: 0ac903d1bfdc ("NFS: NFSERR_INVAL is not defined by NFSv2")
> Reported-by: Jörg Sommer <joerg@jo-so.de>
> Closes: https://lore.kernel.org/linux-nfs/apE90ZRZB8IW_AiS@jo-so.de/
> Signed-off-by: Chuck Lever <cel@kernel.org>
> ---
>  fs/nfsd/nfsproc.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
> index 48541ef7644f..09d360839825 100644
> --- a/fs/nfsd/nfsproc.c
> +++ b/fs/nfsd/nfsproc.c
> @@ -40,6 +40,21 @@ static __be32 nfsd_map_status(__be32 status)
>  	return status;
>  }
>  
> +/*
> + * Because NFSv2 does not have an NFSERR_SYMLINK, Solaris returns
> + * NFSERR_ISDIR when the target of a READ or WRITE is any object
> + * that is not a regular file.
> + */
> +static __be32 nfsd_map_io_status(__be32 status)
> +{
> +	switch (status) {
> +	case nfserr_symlink:
> +	case nfserr_wrong_type:
> +		return nfserr_isdir;
> +	}
> +	return nfsd_map_status(status);
> +}
> +
>  static __be32
>  nfsd_proc_null(struct svc_rqst *rqstp)
>  {
> @@ -238,7 +253,7 @@ nfsd_proc_read(struct svc_rqst *rqstp)
>  		resp->status = fh_getattr(&resp->fh, &resp->stat);
>  	else if (resp->status == nfserr_jukebox)
>  		set_bit(RQ_DROPME, &rqstp->rq_flags);
> -	resp->status = nfsd_map_status(resp->status);
> +	resp->status = nfsd_map_io_status(resp->status);
>  	return rpc_success;
>  }
>  
> @@ -271,7 +286,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
>  		resp->status = fh_getattr(&resp->fh, &resp->stat);
>  	else if (resp->status == nfserr_jukebox)
>  		set_bit(RQ_DROPME, &rqstp->rq_flags);
> -	resp->status = nfsd_map_status(resp->status);
> +	resp->status = nfsd_map_io_status(resp->status);
>  	return rpc_success;
>  }
>  

Reviewed-by: Jeff Layton <jlayton@kernel.org>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v1] NFSD: Return NFSERR_ISDIR for NFSv2 READ and WRITE on a non-regular file
  2026-08-28 23:18 [PATCH v1] NFSD: Return NFSERR_ISDIR for NFSv2 READ and WRITE on a non-regular file Chuck Lever
  2026-08-28 23:28 ` Jeff Layton
@ 2026-08-28 23:50 ` NeilBrown
  1 sibling, 0 replies; 3+ messages in thread
From: NeilBrown @ 2026-08-28 23:50 UTC (permalink / raw)
  To: Chuck Lever
  Cc: Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey, linux-nfs,
	Jörg Sommer

On Sat, 29 Aug 2026, Chuck Lever wrote:
> Commit 0ac903d1bfdc ("NFS: NFSERR_INVAL is not defined by NFSv2")
> changed the status NFSD returns for an NFSv2 READ or WRITE of a
> symlink or other non-regular file from NFSERR_INVAL to NFSERR_IO.
> RFC 1094 defines neither an INVAL nor a SYMLINK status.
> 
> U-Boot's NFS client follows a symlink only when READ fails with
> NFSERR_ISDIR or NFSERR_INVAL. Since that commit it cannot load a
> boot image through a symlink exported by a Linux NFS server: the
> load completes with zero bytes transferred.
> 
> Solaris returns NFSERR_ISDIR when the target of an NFSv2 READ or
> WRITE is not a regular file. Return the same status from NFSD.
> Other NFSv2 procedures continue to return NFSERR_IO.
> 
> Fixes: 0ac903d1bfdc ("NFS: NFSERR_INVAL is not defined by NFSv2")
> Reported-by: Jörg Sommer <joerg@jo-so.de>
> Closes: https://lore.kernel.org/linux-nfs/apE90ZRZB8IW_AiS@jo-so.de/
> Signed-off-by: Chuck Lever <cel@kernel.org>

Reviewed-by: NeilBrown <neil@brown.name>

The only places that openSolaris returns NFSERR_ISDIR when the object
might not be a directory are in rfs_read(), rfs_write(), and
rfs_write_sync(), which is called for rfs_write().

So adding this special handling only for nfsd_proc_read() and
nfsd_proc_write() makes sense.

Thanks,
NeilBrown


> ---
>  fs/nfsd/nfsproc.c | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
> index 48541ef7644f..09d360839825 100644
> --- a/fs/nfsd/nfsproc.c
> +++ b/fs/nfsd/nfsproc.c
> @@ -40,6 +40,21 @@ static __be32 nfsd_map_status(__be32 status)
>  	return status;
>  }
>  
> +/*
> + * Because NFSv2 does not have an NFSERR_SYMLINK, Solaris returns
> + * NFSERR_ISDIR when the target of a READ or WRITE is any object
> + * that is not a regular file.
> + */
> +static __be32 nfsd_map_io_status(__be32 status)
> +{
> +	switch (status) {
> +	case nfserr_symlink:
> +	case nfserr_wrong_type:
> +		return nfserr_isdir;
> +	}
> +	return nfsd_map_status(status);
> +}
> +
>  static __be32
>  nfsd_proc_null(struct svc_rqst *rqstp)
>  {
> @@ -238,7 +253,7 @@ nfsd_proc_read(struct svc_rqst *rqstp)
>  		resp->status = fh_getattr(&resp->fh, &resp->stat);
>  	else if (resp->status == nfserr_jukebox)
>  		set_bit(RQ_DROPME, &rqstp->rq_flags);
> -	resp->status = nfsd_map_status(resp->status);
> +	resp->status = nfsd_map_io_status(resp->status);
>  	return rpc_success;
>  }
>  
> @@ -271,7 +286,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
>  		resp->status = fh_getattr(&resp->fh, &resp->stat);
>  	else if (resp->status == nfserr_jukebox)
>  		set_bit(RQ_DROPME, &rqstp->rq_flags);
> -	resp->status = nfsd_map_status(resp->status);
> +	resp->status = nfsd_map_io_status(resp->status);
>  	return rpc_success;
>  }
>  
> -- 
> 2.55.0
> 
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-28 23:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-28 23:18 [PATCH v1] NFSD: Return NFSERR_ISDIR for NFSv2 READ and WRITE on a non-regular file Chuck Lever
2026-08-28 23:28 ` Jeff Layton
2026-08-28 23:50 ` NeilBrown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.