| From 6f8a394aa952257575910d57cf0a63627fa949a2 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> |
| Date: Sat, 5 Apr 2025 19:51:07 +0200 |
| Subject: cifs: Ensure that all non-client-specific reparse points are processed by the server |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Pali Rohár <pali@kernel.org> |
| |
| commit 6f8a394aa952257575910d57cf0a63627fa949a2 upstream. |
| |
| Fix regression in mounts to e.g. onedrive shares. |
| |
| Generally, reparse points are processed by the SMB server during the |
| SMB OPEN request, but there are few reparse points which do not have |
| OPEN-like meaning for the SMB server and has to be processed by the SMB |
| client. Those are symlinks and special files (fifo, socket, block, char). |
| |
| For Linux SMB client, it is required to process also name surrogate reparse |
| points as they represent another entity on the SMB server system. Linux |
| client will mark them as separate mount points. Examples of name surrogate |
| reparse points are NTFS junction points (e.g. created by the "mklink" tool |
| on Windows servers). |
| |
| So after processing the name surrogate reparse points, clear the |
| -EOPNOTSUPP error code returned from the parse_reparse_point() to let SMB |
| server to process reparse points. |
| |
| And remove printing misleading error message "unhandled reparse tag:" as |
| reparse points are handled by SMB server and hence unhandled fact is normal |
| operation. |
| |
| Fixes: cad3fc0a4c8c ("cifs: Throw -EOPNOTSUPP error on unsupported reparse point type from parse_reparse_point()") |
| Fixes: b587fd128660 ("cifs: Treat unhandled directory name surrogate reparse points as mount directory nodes") |
| Cc: stable@vger.kernel.org |
| Reported-by: Junwen Sun <sunjw8888@gmail.com> |
| Tested-by: Junwen Sun <sunjw8888@gmail.com> |
| Signed-off-by: Pali Rohár <pali@kernel.org> |
| Signed-off-by: Steve French <stfrench@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/smb/client/inode.c | 10 ++++++++++ |
| fs/smb/client/reparse.c | 4 ---- |
| 2 files changed, 10 insertions(+), 4 deletions(-) |
| |
| --- a/fs/smb/client/inode.c |
| +++ b/fs/smb/client/inode.c |
| @@ -1206,6 +1206,16 @@ static int reparse_info_to_fattr(struct |
| cifs_create_junction_fattr(fattr, sb); |
| goto out; |
| } |
| + /* |
| + * If the reparse point is unsupported by the Linux SMB |
| + * client then let it process by the SMB server. So mask |
| + * the -EOPNOTSUPP error code. This will allow Linux SMB |
| + * client to send SMB OPEN request to server. If server |
| + * does not support this reparse point too then server |
| + * will return error during open the path. |
| + */ |
| + if (rc == -EOPNOTSUPP) |
| + rc = 0; |
| } |
| break; |
| } |
| --- a/fs/smb/client/reparse.c |
| +++ b/fs/smb/client/reparse.c |
| @@ -633,8 +633,6 @@ int parse_reparse_point(struct reparse_d |
| const char *full_path, |
| bool unicode, struct cifs_open_info_data *data) |
| { |
| - struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
| - |
| data->reparse.buf = buf; |
| |
| /* See MS-FSCC 2.1.2 */ |
| @@ -658,8 +656,6 @@ int parse_reparse_point(struct reparse_d |
| } |
| return 0; |
| default: |
| - cifs_tcon_dbg(VFS | ONCE, "unhandled reparse tag: 0x%08x\n", |
| - le32_to_cpu(buf->ReparseTag)); |
| return -EOPNOTSUPP; |
| } |
| } |