diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2013-08-14 11:25:21 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-09-08 15:27:34 -0400 |
commit | b42bf88828cde60772dc08201d0a4f1a0663d7bc (patch) | |
tree | 3b019e905c83aba6578b56ae5a49669f59db23cf | |
parent | 3ae35cde67c1ec50267bcc55d81f4953b5f637c2 (diff) |
CIFS: Implement follow_link for SMB2
that allows to access files through symlink created on a server.
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/cifsglob.h | 3 | ||||
-rw-r--r-- | fs/cifs/inode.c | 4 | ||||
-rw-r--r-- | fs/cifs/link.c | 24 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 3 | ||||
-rw-r--r-- | fs/cifs/smb2file.c | 2 | ||||
-rw-r--r-- | fs/cifs/smb2inode.c | 9 | ||||
-rw-r--r-- | fs/cifs/smb2misc.c | 4 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 60 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 6 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 14 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 3 |
11 files changed, 103 insertions, 29 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 52ca861ed35e..ec6c3fbb29eb 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -308,6 +308,9 @@ struct smb_version_operations { | |||
308 | int (*create_hardlink)(const unsigned int, struct cifs_tcon *, | 308 | int (*create_hardlink)(const unsigned int, struct cifs_tcon *, |
309 | const char *, const char *, | 309 | const char *, const char *, |
310 | struct cifs_sb_info *); | 310 | struct cifs_sb_info *); |
311 | /* query symlink target */ | ||
312 | int (*query_symlink)(const unsigned int, struct cifs_tcon *, | ||
313 | const char *, char **, struct cifs_sb_info *); | ||
311 | /* open a file for non-posix mounts */ | 314 | /* open a file for non-posix mounts */ |
312 | int (*open)(const unsigned int, struct cifs_open_parms *, | 315 | int (*open)(const unsigned int, struct cifs_open_parms *, |
313 | __u32 *, FILE_ALL_INFO *); | 316 | __u32 *, FILE_ALL_INFO *); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 449b6cf09b09..ec0f3423cdac 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -549,6 +549,10 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | |||
549 | * when Unix extensions are disabled - fake it. | 549 | * when Unix extensions are disabled - fake it. |
550 | */ | 550 | */ |
551 | fattr->cf_nlink = 2; | 551 | fattr->cf_nlink = 2; |
552 | } else if (fattr->cf_cifsattrs & ATTR_REPARSE) { | ||
553 | fattr->cf_mode = S_IFLNK; | ||
554 | fattr->cf_dtype = DT_LNK; | ||
555 | fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); | ||
552 | } else { | 556 | } else { |
553 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; | 557 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; |
554 | fattr->cf_dtype = DT_REG; | 558 | fattr->cf_dtype = DT_REG; |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 562044f700e5..7e36ceba0c7a 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -509,6 +509,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
509 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 509 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
510 | struct tcon_link *tlink = NULL; | 510 | struct tcon_link *tlink = NULL; |
511 | struct cifs_tcon *tcon; | 511 | struct cifs_tcon *tcon; |
512 | struct TCP_Server_Info *server; | ||
512 | 513 | ||
513 | xid = get_xid(); | 514 | xid = get_xid(); |
514 | 515 | ||
@@ -519,25 +520,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
519 | goto out; | 520 | goto out; |
520 | } | 521 | } |
521 | tcon = tlink_tcon(tlink); | 522 | tcon = tlink_tcon(tlink); |
522 | 523 | server = tcon->ses->server; | |
523 | /* | ||
524 | * For now, we just handle symlinks with unix extensions enabled. | ||
525 | * Eventually we should handle NTFS reparse points, and MacOS | ||
526 | * symlink support. For instance... | ||
527 | * | ||
528 | * rc = CIFSSMBQueryReparseLinkInfo(...) | ||
529 | * | ||
530 | * For now, just return -EACCES when the server doesn't support posix | ||
531 | * extensions. Note that we still allow querying symlinks when posix | ||
532 | * extensions are manually disabled. We could disable these as well | ||
533 | * but there doesn't seem to be any harm in allowing the client to | ||
534 | * read them. | ||
535 | */ | ||
536 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) && | ||
537 | !cap_unix(tcon->ses)) { | ||
538 | rc = -EACCES; | ||
539 | goto out; | ||
540 | } | ||
541 | 524 | ||
542 | full_path = build_path_from_dentry(direntry); | 525 | full_path = build_path_from_dentry(direntry); |
543 | if (!full_path) | 526 | if (!full_path) |
@@ -559,6 +542,9 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
559 | if ((rc != 0) && cap_unix(tcon->ses)) | 542 | if ((rc != 0) && cap_unix(tcon->ses)) |
560 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, | 543 | rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, |
561 | cifs_sb->local_nls); | 544 | cifs_sb->local_nls); |
545 | else if (rc != 0 && server->ops->query_symlink) | ||
546 | rc = server->ops->query_symlink(xid, tcon, full_path, | ||
547 | &target_path, cifs_sb); | ||
562 | 548 | ||
563 | kfree(full_path); | 549 | kfree(full_path); |
564 | out: | 550 | out: |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 69d2c826a23b..42ef03be089f 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -172,6 +172,9 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) | |||
172 | if (cifs_dfs_is_possible(cifs_sb) && | 172 | if (cifs_dfs_is_possible(cifs_sb) && |
173 | (fattr->cf_cifsattrs & ATTR_REPARSE)) | 173 | (fattr->cf_cifsattrs & ATTR_REPARSE)) |
174 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; | 174 | fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
175 | } else if (fattr->cf_cifsattrs & ATTR_REPARSE) { | ||
176 | fattr->cf_mode = S_IFLNK; | ||
177 | fattr->cf_dtype = DT_LNK; | ||
175 | } else { | 178 | } else { |
176 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; | 179 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; |
177 | fattr->cf_dtype = DT_REG; | 180 | fattr->cf_dtype = DT_REG; |
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c index 04a81a4142c3..020245d5c9a7 100644 --- a/fs/cifs/smb2file.c +++ b/fs/cifs/smb2file.c | |||
@@ -86,7 +86,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, | |||
86 | if (oparms->tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) | 86 | if (oparms->tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) |
87 | memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE); | 87 | memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE); |
88 | 88 | ||
89 | rc = SMB2_open(xid, oparms, smb2_path, smb2_oplock, smb2_data); | 89 | rc = SMB2_open(xid, oparms, smb2_path, smb2_oplock, smb2_data, NULL); |
90 | if (rc) | 90 | if (rc) |
91 | goto out; | 91 | goto out; |
92 | 92 | ||
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index c6ec1633309a..78ff88c467b9 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c | |||
@@ -60,7 +60,7 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon, | |||
60 | oparms.fid = &fid; | 60 | oparms.fid = &fid; |
61 | oparms.reconnect = false; | 61 | oparms.reconnect = false; |
62 | 62 | ||
63 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL); | 63 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); |
64 | if (rc) { | 64 | if (rc) { |
65 | kfree(utf16_path); | 65 | kfree(utf16_path); |
66 | return rc; | 66 | return rc; |
@@ -136,7 +136,8 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
136 | return -ENOMEM; | 136 | return -ENOMEM; |
137 | 137 | ||
138 | rc = smb2_open_op_close(xid, tcon, cifs_sb, full_path, | 138 | rc = smb2_open_op_close(xid, tcon, cifs_sb, full_path, |
139 | FILE_READ_ATTRIBUTES, FILE_OPEN, 0, smb2_data, | 139 | FILE_READ_ATTRIBUTES, FILE_OPEN, |
140 | OPEN_REPARSE_POINT, smb2_data, | ||
140 | SMB2_OP_QUERY_INFO); | 141 | SMB2_OP_QUERY_INFO); |
141 | if (rc) | 142 | if (rc) |
142 | goto out; | 143 | goto out; |
@@ -191,8 +192,8 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, | |||
191 | struct cifs_sb_info *cifs_sb) | 192 | struct cifs_sb_info *cifs_sb) |
192 | { | 193 | { |
193 | return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, | 194 | return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, |
194 | CREATE_DELETE_ON_CLOSE, NULL, | 195 | CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT, |
195 | SMB2_OP_DELETE); | 196 | NULL, SMB2_OP_DELETE); |
196 | } | 197 | } |
197 | 198 | ||
198 | static int | 199 | static int |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index b0c43345cd98..6103359fb598 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -171,6 +171,10 @@ smb2_check_message(char *buf, unsigned int length) | |||
171 | if (4 + len != clc_len) { | 171 | if (4 + len != clc_len) { |
172 | cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n", | 172 | cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n", |
173 | clc_len, 4 + len, mid); | 173 | clc_len, 4 + len, mid); |
174 | /* create failed on symlink */ | ||
175 | if (command == SMB2_CREATE_HE && | ||
176 | hdr->Status == STATUS_STOPPED_ON_SYMLINK) | ||
177 | return 0; | ||
174 | /* Windows 7 server returns 24 bytes more */ | 178 | /* Windows 7 server returns 24 bytes more */ |
175 | if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE) | 179 | if (clc_len + 20 == len && command == SMB2_OPLOCK_BREAK_HE) |
176 | return 0; | 180 | return 0; |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index f259e6cc8357..91b9e5422e9a 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "smb2proto.h" | 24 | #include "smb2proto.h" |
25 | #include "cifsproto.h" | 25 | #include "cifsproto.h" |
26 | #include "cifs_debug.h" | 26 | #include "cifs_debug.h" |
27 | #include "cifs_unicode.h" | ||
27 | #include "smb2status.h" | 28 | #include "smb2status.h" |
28 | #include "smb2glob.h" | 29 | #include "smb2glob.h" |
29 | 30 | ||
@@ -229,7 +230,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, | |||
229 | oparms.fid = &fid; | 230 | oparms.fid = &fid; |
230 | oparms.reconnect = false; | 231 | oparms.reconnect = false; |
231 | 232 | ||
232 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL); | 233 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); |
233 | if (rc) { | 234 | if (rc) { |
234 | kfree(utf16_path); | 235 | kfree(utf16_path); |
235 | return rc; | 236 | return rc; |
@@ -463,7 +464,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, | |||
463 | oparms.fid = fid; | 464 | oparms.fid = fid; |
464 | oparms.reconnect = false; | 465 | oparms.reconnect = false; |
465 | 466 | ||
466 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL); | 467 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); |
467 | kfree(utf16_path); | 468 | kfree(utf16_path); |
468 | if (rc) { | 469 | if (rc) { |
469 | cifs_dbg(VFS, "open dir failed\n"); | 470 | cifs_dbg(VFS, "open dir failed\n"); |
@@ -550,7 +551,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, | |||
550 | oparms.fid = &fid; | 551 | oparms.fid = &fid; |
551 | oparms.reconnect = false; | 552 | oparms.reconnect = false; |
552 | 553 | ||
553 | rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL); | 554 | rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL); |
554 | if (rc) | 555 | if (rc) |
555 | return rc; | 556 | return rc; |
556 | buf->f_type = SMB2_MAGIC_NUMBER; | 557 | buf->f_type = SMB2_MAGIC_NUMBER; |
@@ -596,6 +597,57 @@ smb2_new_lease_key(struct cifs_fid *fid) | |||
596 | get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE); | 597 | get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE); |
597 | } | 598 | } |
598 | 599 | ||
600 | static int | ||
601 | smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | ||
602 | const char *full_path, char **target_path, | ||
603 | struct cifs_sb_info *cifs_sb) | ||
604 | { | ||
605 | int rc; | ||
606 | __le16 *utf16_path; | ||
607 | __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; | ||
608 | struct cifs_open_parms oparms; | ||
609 | struct cifs_fid fid; | ||
610 | struct smb2_err_rsp *err_buf = NULL; | ||
611 | struct smb2_symlink_err_rsp *symlink; | ||
612 | unsigned int sub_len, sub_offset; | ||
613 | |||
614 | cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); | ||
615 | |||
616 | utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); | ||
617 | if (!utf16_path) | ||
618 | return -ENOMEM; | ||
619 | |||
620 | oparms.tcon = tcon; | ||
621 | oparms.desired_access = FILE_READ_ATTRIBUTES; | ||
622 | oparms.disposition = FILE_OPEN; | ||
623 | oparms.create_options = 0; | ||
624 | oparms.fid = &fid; | ||
625 | oparms.reconnect = false; | ||
626 | |||
627 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf); | ||
628 | |||
629 | if (!rc || !err_buf) { | ||
630 | kfree(utf16_path); | ||
631 | return -ENOENT; | ||
632 | } | ||
633 | /* open must fail on symlink - reset rc */ | ||
634 | rc = 0; | ||
635 | symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; | ||
636 | sub_len = le16_to_cpu(symlink->SubstituteNameLength); | ||
637 | sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); | ||
638 | *target_path = cifs_strndup_from_utf16( | ||
639 | (char *)symlink->PathBuffer + sub_offset, | ||
640 | sub_len, true, cifs_sb->local_nls); | ||
641 | if (!(*target_path)) { | ||
642 | kfree(utf16_path); | ||
643 | return -ENOMEM; | ||
644 | } | ||
645 | convert_delimiter(*target_path, '/'); | ||
646 | cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path); | ||
647 | kfree(utf16_path); | ||
648 | return rc; | ||
649 | } | ||
650 | |||
599 | struct smb_version_operations smb21_operations = { | 651 | struct smb_version_operations smb21_operations = { |
600 | .compare_fids = smb2_compare_fids, | 652 | .compare_fids = smb2_compare_fids, |
601 | .setup_request = smb2_setup_request, | 653 | .setup_request = smb2_setup_request, |
@@ -638,6 +690,7 @@ struct smb_version_operations smb21_operations = { | |||
638 | .unlink = smb2_unlink, | 690 | .unlink = smb2_unlink, |
639 | .rename = smb2_rename_path, | 691 | .rename = smb2_rename_path, |
640 | .create_hardlink = smb2_create_hardlink, | 692 | .create_hardlink = smb2_create_hardlink, |
693 | .query_symlink = smb2_query_symlink, | ||
641 | .open = smb2_open_file, | 694 | .open = smb2_open_file, |
642 | .set_fid = smb2_set_fid, | 695 | .set_fid = smb2_set_fid, |
643 | .close = smb2_close_file, | 696 | .close = smb2_close_file, |
@@ -706,6 +759,7 @@ struct smb_version_operations smb30_operations = { | |||
706 | .unlink = smb2_unlink, | 759 | .unlink = smb2_unlink, |
707 | .rename = smb2_rename_path, | 760 | .rename = smb2_rename_path, |
708 | .create_hardlink = smb2_create_hardlink, | 761 | .create_hardlink = smb2_create_hardlink, |
762 | .query_symlink = smb2_query_symlink, | ||
709 | .open = smb2_open_file, | 763 | .open = smb2_open_file, |
710 | .set_fid = smb2_set_fid, | 764 | .set_fid = smb2_set_fid, |
711 | .close = smb2_close_file, | 765 | .close = smb2_close_file, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index abc9c2809b51..5a49861633a6 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -977,7 +977,8 @@ add_durable_context(struct kvec *iov, unsigned int *num_iovec, | |||
977 | 977 | ||
978 | int | 978 | int |
979 | SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | 979 | SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, |
980 | __u8 *oplock, struct smb2_file_all_info *buf) | 980 | __u8 *oplock, struct smb2_file_all_info *buf, |
981 | struct smb2_err_rsp **err_buf) | ||
981 | { | 982 | { |
982 | struct smb2_create_req *req; | 983 | struct smb2_create_req *req; |
983 | struct smb2_create_rsp *rsp; | 984 | struct smb2_create_rsp *rsp; |
@@ -1082,6 +1083,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | |||
1082 | 1083 | ||
1083 | if (rc != 0) { | 1084 | if (rc != 0) { |
1084 | cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); | 1085 | cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); |
1086 | if (err_buf) | ||
1087 | *err_buf = kmemdup(rsp, get_rfc1002_length(rsp) + 4, | ||
1088 | GFP_KERNEL); | ||
1085 | goto creat_exit; | 1089 | goto creat_exit; |
1086 | } | 1090 | } |
1087 | 1091 | ||
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 36b0d37ea69b..40baeae60b08 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -150,6 +150,20 @@ struct smb2_err_rsp { | |||
150 | __u8 ErrorData[1]; /* variable length */ | 150 | __u8 ErrorData[1]; /* variable length */ |
151 | } __packed; | 151 | } __packed; |
152 | 152 | ||
153 | struct smb2_symlink_err_rsp { | ||
154 | __le32 SymLinkLength; | ||
155 | __le32 SymLinkErrorTag; | ||
156 | __le32 ReparseTag; | ||
157 | __le16 ReparseDataLength; | ||
158 | __le16 UnparsedPathLength; | ||
159 | __le16 SubstituteNameOffset; | ||
160 | __le16 SubstituteNameLength; | ||
161 | __le16 PrintNameOffset; | ||
162 | __le16 PrintNameLength; | ||
163 | __le32 Flags; | ||
164 | __u8 PathBuffer[0]; | ||
165 | } __packed; | ||
166 | |||
153 | #define SMB2_CLIENT_GUID_SIZE 16 | 167 | #define SMB2_CLIENT_GUID_SIZE 16 |
154 | 168 | ||
155 | extern __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; | 169 | extern __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 1a5ecbed40ed..1db89fda1392 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -106,7 +106,8 @@ extern int SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, | |||
106 | extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon); | 106 | extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon); |
107 | extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, | 107 | extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, |
108 | __le16 *path, __u8 *oplock, | 108 | __le16 *path, __u8 *oplock, |
109 | struct smb2_file_all_info *buf); | 109 | struct smb2_file_all_info *buf, |
110 | struct smb2_err_rsp **err_buf); | ||
110 | extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, | 111 | extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, |
111 | u64 persistent_fid, u64 volatile_fid, u32 opcode, | 112 | u64 persistent_fid, u64 volatile_fid, u32 opcode, |
112 | bool is_fsctl, char *in_data, u32 indatalen, | 113 | bool is_fsctl, char *in_data, u32 indatalen, |