summaryrefslogtreecommitdiff
path: root/fs/smb/client/smb1ops.c
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@manguebit.com>2023-11-21 20:12:52 -0300
committerSteve French <stfrench@microsoft.com>2023-11-23 11:44:31 -0600
commited3e0a149b58ea8cfd10cc4f7cefb39877ff07ac (patch)
tree1e721dddddc5b11663aa19de52cd2bfee823fcbe /fs/smb/client/smb1ops.c
parenta15ccef82d3de9a37dc25898c60a394209368dc8 (diff)
smb: client: implement ->query_reparse_point() for SMB1
Reparse points are not limited to symlinks, so implement ->query_reparse_point() in order to handle different file types. Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb/client/smb1ops.c')
-rw-r--r--fs/smb/client/smb1ops.c49
1 files changed, 10 insertions, 39 deletions
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 9bf8735cdd1e..6b4d8effa79d 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -979,18 +979,13 @@ static int cifs_query_symlink(const unsigned int xid,
char **target_path,
struct kvec *rsp_iov)
{
+ struct reparse_data_buffer *buf;
+ TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base;
+ bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE);
+ u32 plen = le16_to_cpu(io->ByteCount);
int rc;
- int oplock = 0;
- bool is_reparse_point = !!rsp_iov;
- struct cifs_fid fid;
- struct cifs_open_parms oparms;
- cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
-
- if (is_reparse_point) {
- cifs_dbg(VFS, "reparse points not handled for SMB1 symlinks\n");
- return -EOPNOTSUPP;
- }
+ cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
/* Check for unix extensions */
if (cap_unix(tcon->ses)) {
@@ -1001,37 +996,12 @@ static int cifs_query_symlink(const unsigned int xid,
rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
target_path,
cifs_sb->local_nls);
-
- goto out;
+ return rc;
}
- oparms = (struct cifs_open_parms) {
- .tcon = tcon,
- .cifs_sb = cifs_sb,
- .desired_access = FILE_READ_ATTRIBUTES,
- .create_options = cifs_create_options(cifs_sb,
- OPEN_REPARSE_POINT),
- .disposition = FILE_OPEN,
- .path = full_path,
- .fid = &fid,
- };
-
- rc = CIFS_open(xid, &oparms, &oplock, NULL);
- if (rc)
- goto out;
-
- rc = CIFSSMBQuerySymLink(xid, tcon, fid.netfid, target_path,
- cifs_sb->local_nls);
- if (rc)
- goto out_close;
-
- convert_delimiter(*target_path, '/');
-out_close:
- CIFSSMBClose(xid, tcon, fid.netfid);
-out:
- if (!rc)
- cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
- return rc;
+ buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +
+ le32_to_cpu(io->DataOffset));
+ return parse_reparse_point(buf, plen, cifs_sb, unicode, target_path);
}
static bool
@@ -1214,6 +1184,7 @@ struct smb_version_operations smb1_operations = {
.is_path_accessible = cifs_is_path_accessible,
.can_echo = cifs_can_echo,
.query_path_info = cifs_query_path_info,
+ .query_reparse_point = cifs_query_reparse_point,
.query_file_info = cifs_query_file_info,
.get_srv_inum = cifs_get_srv_inum,
.set_path_size = CIFSSMBSetEOF,