Skip to content

Commit 539aad7

Browse files
Paulo AlcantaraSteve French
authored andcommitted
smb: client: introduce ->parse_reparse_point()
Parse reparse point into cifs_open_info_data structure and feed it through cifs_open_info_to_fattr(). Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent ed3e0a1 commit 539aad7

File tree

4 files changed

+56
-42
lines changed

4 files changed

+56
-42
lines changed

fs/smb/client/cifsglob.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,7 @@ struct smb_version_operations {
395395
struct cifs_tcon *tcon,
396396
struct cifs_sb_info *cifs_sb,
397397
const char *full_path,
398-
char **target_path,
399-
struct kvec *rsp_iov);
398+
char **target_path);
400399
/* open a file for non-posix mounts */
401400
int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
402401
void *buf);
@@ -551,6 +550,9 @@ struct smb_version_operations {
551550
bool (*is_status_io_timeout)(char *buf);
552551
/* Check for STATUS_NETWORK_NAME_DELETED */
553552
bool (*is_network_name_deleted)(char *buf, struct TCP_Server_Info *srv);
553+
int (*parse_reparse_point)(struct cifs_sb_info *cifs_sb,
554+
struct kvec *rsp_iov,
555+
struct cifs_open_info_data *data);
554556
};
555557

556558
struct smb_version_values {

fs/smb/client/inode.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,7 @@ static int cifs_get_unix_fattr(const unsigned char *full_path,
459459
return -EOPNOTSUPP;
460460
rc = server->ops->query_symlink(xid, tcon,
461461
cifs_sb, full_path,
462-
&fattr->cf_symlink_target,
463-
NULL);
462+
&fattr->cf_symlink_target);
464463
cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc);
465464
}
466465
return rc;
@@ -1035,22 +1034,28 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
10351034
if (!rc)
10361035
iov = &rsp_iov;
10371036
}
1037+
1038+
rc = -EOPNOTSUPP;
10381039
switch ((data->reparse_tag = tag)) {
10391040
case 0: /* SMB1 symlink */
1040-
iov = NULL;
1041-
fallthrough;
1042-
case IO_REPARSE_TAG_NFS:
1043-
case IO_REPARSE_TAG_SYMLINK:
1044-
if (!data->symlink_target && server->ops->query_symlink) {
1041+
if (server->ops->query_symlink) {
10451042
rc = server->ops->query_symlink(xid, tcon,
10461043
cifs_sb, full_path,
1047-
&data->symlink_target,
1048-
iov);
1044+
&data->symlink_target);
10491045
}
10501046
break;
10511047
case IO_REPARSE_TAG_MOUNT_POINT:
10521048
cifs_create_junction_fattr(fattr, sb);
1049+
rc = 0;
10531050
goto out;
1051+
default:
1052+
if (data->symlink_target) {
1053+
rc = 0;
1054+
} else if (server->ops->parse_reparse_point) {
1055+
rc = server->ops->parse_reparse_point(cifs_sb,
1056+
iov, data);
1057+
}
1058+
break;
10541059
}
10551060

10561061
cifs_open_info_to_fattr(fattr, data, sb);

fs/smb/client/smb1ops.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -976,32 +976,36 @@ static int cifs_query_symlink(const unsigned int xid,
976976
struct cifs_tcon *tcon,
977977
struct cifs_sb_info *cifs_sb,
978978
const char *full_path,
979-
char **target_path,
980-
struct kvec *rsp_iov)
979+
char **target_path)
981980
{
982-
struct reparse_data_buffer *buf;
983-
TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base;
984-
bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE);
985-
u32 plen = le16_to_cpu(io->ByteCount);
986981
int rc;
987982

988983
cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path);
989984

990-
/* Check for unix extensions */
991-
if (cap_unix(tcon->ses)) {
992-
rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
993-
cifs_sb->local_nls,
994-
cifs_remap(cifs_sb));
995-
if (rc == -EREMOTE)
996-
rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
997-
target_path,
998-
cifs_sb->local_nls);
999-
return rc;
1000-
}
985+
if (!cap_unix(tcon->ses))
986+
return -EOPNOTSUPP;
987+
988+
rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, target_path,
989+
cifs_sb->local_nls, cifs_remap(cifs_sb));
990+
if (rc == -EREMOTE)
991+
rc = cifs_unix_dfs_readlink(xid, tcon, full_path,
992+
target_path, cifs_sb->local_nls);
993+
return rc;
994+
}
995+
996+
static int cifs_parse_reparse_point(struct cifs_sb_info *cifs_sb,
997+
struct kvec *rsp_iov,
998+
struct cifs_open_info_data *data)
999+
{
1000+
struct reparse_data_buffer *buf;
1001+
TRANSACT_IOCTL_RSP *io = rsp_iov->iov_base;
1002+
bool unicode = !!(io->hdr.Flags2 & SMBFLG2_UNICODE);
1003+
u32 plen = le16_to_cpu(io->ByteCount);
10011004

10021005
buf = (struct reparse_data_buffer *)((__u8 *)&io->hdr.Protocol +
10031006
le32_to_cpu(io->DataOffset));
1004-
return parse_reparse_point(buf, plen, cifs_sb, unicode, target_path);
1007+
return parse_reparse_point(buf, plen, cifs_sb, unicode,
1008+
&data->symlink_target);
10051009
}
10061010

10071011
static bool
@@ -1200,6 +1204,7 @@ struct smb_version_operations smb1_operations = {
12001204
.rename = CIFSSMBRename,
12011205
.create_hardlink = CIFSCreateHardLink,
12021206
.query_symlink = cifs_query_symlink,
1207+
.parse_reparse_point = cifs_parse_reparse_point,
12031208
.open = cifs_open_file,
12041209
.set_fid = cifs_set_fid,
12051210
.close = cifs_close_file,

fs/smb/client/smb2ops.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2949,29 +2949,31 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
29492949
return parse_reparse_symlink(
29502950
(struct reparse_symlink_data_buffer *)buf,
29512951
plen, unicode, target_path, cifs_sb);
2952+
case IO_REPARSE_TAG_LX_SYMLINK:
2953+
case IO_REPARSE_TAG_AF_UNIX:
2954+
case IO_REPARSE_TAG_LX_FIFO:
2955+
case IO_REPARSE_TAG_LX_CHR:
2956+
case IO_REPARSE_TAG_LX_BLK:
2957+
return 0;
29522958
default:
29532959
cifs_dbg(VFS, "srv returned unknown symlink buffer tag:0x%08x\n",
29542960
le32_to_cpu(buf->ReparseTag));
29552961
return -EOPNOTSUPP;
29562962
}
29572963
}
29582964

2959-
static int smb2_query_symlink(const unsigned int xid,
2960-
struct cifs_tcon *tcon,
2961-
struct cifs_sb_info *cifs_sb,
2962-
const char *full_path,
2963-
char **target_path,
2964-
struct kvec *rsp_iov)
2965+
static int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
2966+
struct kvec *rsp_iov,
2967+
struct cifs_open_info_data *data)
29652968
{
29662969
struct reparse_data_buffer *buf;
29672970
struct smb2_ioctl_rsp *io = rsp_iov->iov_base;
29682971
u32 plen = le32_to_cpu(io->OutputCount);
29692972

2970-
cifs_tcon_dbg(FYI, "%s: path: %s\n", __func__, full_path);
2971-
29722973
buf = (struct reparse_data_buffer *)((u8 *)io +
29732974
le32_to_cpu(io->OutputOffset));
2974-
return parse_reparse_point(buf, plen, cifs_sb, true, target_path);
2975+
return parse_reparse_point(buf, plen, cifs_sb,
2976+
true, &data->symlink_target);
29752977
}
29762978

29772979
static int smb2_query_reparse_point(const unsigned int xid,
@@ -5206,7 +5208,7 @@ struct smb_version_operations smb20_operations = {
52065208
.unlink = smb2_unlink,
52075209
.rename = smb2_rename_path,
52085210
.create_hardlink = smb2_create_hardlink,
5209-
.query_symlink = smb2_query_symlink,
5211+
.parse_reparse_point = smb2_parse_reparse_point,
52105212
.query_mf_symlink = smb3_query_mf_symlink,
52115213
.create_mf_symlink = smb3_create_mf_symlink,
52125214
.open = smb2_open_file,
@@ -5308,7 +5310,7 @@ struct smb_version_operations smb21_operations = {
53085310
.unlink = smb2_unlink,
53095311
.rename = smb2_rename_path,
53105312
.create_hardlink = smb2_create_hardlink,
5311-
.query_symlink = smb2_query_symlink,
5313+
.parse_reparse_point = smb2_parse_reparse_point,
53125314
.query_mf_symlink = smb3_query_mf_symlink,
53135315
.create_mf_symlink = smb3_create_mf_symlink,
53145316
.open = smb2_open_file,
@@ -5413,7 +5415,7 @@ struct smb_version_operations smb30_operations = {
54135415
.unlink = smb2_unlink,
54145416
.rename = smb2_rename_path,
54155417
.create_hardlink = smb2_create_hardlink,
5416-
.query_symlink = smb2_query_symlink,
5418+
.parse_reparse_point = smb2_parse_reparse_point,
54175419
.query_mf_symlink = smb3_query_mf_symlink,
54185420
.create_mf_symlink = smb3_create_mf_symlink,
54195421
.open = smb2_open_file,
@@ -5527,7 +5529,7 @@ struct smb_version_operations smb311_operations = {
55275529
.unlink = smb2_unlink,
55285530
.rename = smb2_rename_path,
55295531
.create_hardlink = smb2_create_hardlink,
5530-
.query_symlink = smb2_query_symlink,
5532+
.parse_reparse_point = smb2_parse_reparse_point,
55315533
.query_mf_symlink = smb3_query_mf_symlink,
55325534
.create_mf_symlink = smb3_create_mf_symlink,
55335535
.open = smb2_open_file,

0 commit comments

Comments
 (0)