diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-12-29 08:06:33 -0500 |
---|---|---|
committer | Pavel Shilovsky <pshilovsky@samba.org> | 2012-07-24 13:55:08 -0400 |
commit | be4cb9e3d4ef7af1aaf66cebab1391ff91b48beb (patch) | |
tree | d6cd1bc8f7ff8053c5917043b24e69c07f46594b | |
parent | 1208ef1f76540b621f80e6130c4fb7bed8ece360 (diff) |
CIFS: Query SMB2 inode info
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/Makefile | 2 | ||||
-rw-r--r-- | fs/cifs/smb2glob.h | 44 | ||||
-rw-r--r-- | fs/cifs/smb2inode.c | 124 | ||||
-rw-r--r-- | fs/cifs/smb2misc.c | 7 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 11 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 113 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 111 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 7 |
8 files changed, 417 insertions, 2 deletions
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index daf6837d9e0e..feee94309271 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
@@ -17,4 +17,4 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o | |||
17 | cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o | 17 | cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o |
18 | 18 | ||
19 | cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \ | 19 | cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \ |
20 | smb2misc.o smb2pdu.o | 20 | smb2misc.o smb2pdu.o smb2inode.o |
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h new file mode 100644 index 000000000000..33c1d89090c0 --- /dev/null +++ b/fs/cifs/smb2glob.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * fs/cifs/smb2glob.h | ||
3 | * | ||
4 | * Definitions for various global variables and structures | ||
5 | * | ||
6 | * Copyright (C) International Business Machines Corp., 2002, 2011 | ||
7 | * Etersoft, 2012 | ||
8 | * Author(s): Steve French (sfrench@us.ibm.com) | ||
9 | * Jeremy Allison (jra@samba.org) | ||
10 | * Pavel Shilovsky (pshilovsky@samba.org) 2012 | ||
11 | * | ||
12 | * This library is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU Lesser General Public License as published | ||
14 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This library is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
20 | * the GNU Lesser General Public License for more details. | ||
21 | * | ||
22 | */ | ||
23 | #ifndef _SMB2_GLOB_H | ||
24 | #define _SMB2_GLOB_H | ||
25 | |||
26 | /* | ||
27 | ***************************************************************** | ||
28 | * Constants go here | ||
29 | ***************************************************************** | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * Identifiers for functions that use the open, operation, close pattern | ||
34 | * in smb2inode.c:smb2_open_op_close() | ||
35 | */ | ||
36 | #define SMB2_OP_SET_DELETE 1 | ||
37 | #define SMB2_OP_SET_INFO 2 | ||
38 | #define SMB2_OP_QUERY_INFO 3 | ||
39 | #define SMB2_OP_QUERY_DIR 4 | ||
40 | #define SMB2_OP_MKDIR 5 | ||
41 | #define SMB2_OP_RENAME 6 | ||
42 | #define SMB2_OP_DELETE 7 | ||
43 | |||
44 | #endif /* _SMB2_GLOB_H */ | ||
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c new file mode 100644 index 000000000000..1ba5c405315c --- /dev/null +++ b/fs/cifs/smb2inode.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * fs/cifs/smb2inode.c | ||
3 | * | ||
4 | * Copyright (C) International Business Machines Corp., 2002, 2011 | ||
5 | * Etersoft, 2012 | ||
6 | * Author(s): Pavel Shilovsky (pshilovsky@samba.org), | ||
7 | * Steve French (sfrench@us.ibm.com) | ||
8 | * | ||
9 | * This library is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU Lesser General Public License as published | ||
11 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This library is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
17 | * the GNU Lesser General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU Lesser General Public License | ||
20 | * along with this library; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/stat.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/pagemap.h> | ||
27 | #include <asm/div64.h> | ||
28 | #include "cifsfs.h" | ||
29 | #include "cifspdu.h" | ||
30 | #include "cifsglob.h" | ||
31 | #include "cifsproto.h" | ||
32 | #include "cifs_debug.h" | ||
33 | #include "cifs_fs_sb.h" | ||
34 | #include "cifs_unicode.h" | ||
35 | #include "fscache.h" | ||
36 | #include "smb2glob.h" | ||
37 | #include "smb2pdu.h" | ||
38 | #include "smb2proto.h" | ||
39 | |||
40 | static int | ||
41 | smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon, | ||
42 | struct cifs_sb_info *cifs_sb, const char *full_path, | ||
43 | __u32 desired_access, __u32 create_disposition, | ||
44 | __u32 file_attributes, __u32 create_options, | ||
45 | void *data, int command) | ||
46 | { | ||
47 | int rc, tmprc = 0; | ||
48 | u64 persistent_fid, volatile_fid; | ||
49 | __le16 *utf16_path; | ||
50 | |||
51 | utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); | ||
52 | if (!utf16_path) | ||
53 | return -ENOMEM; | ||
54 | |||
55 | rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid, | ||
56 | desired_access, create_disposition, file_attributes, | ||
57 | create_options); | ||
58 | if (rc) { | ||
59 | kfree(utf16_path); | ||
60 | return rc; | ||
61 | } | ||
62 | |||
63 | switch (command) { | ||
64 | case SMB2_OP_DELETE: | ||
65 | break; | ||
66 | case SMB2_OP_QUERY_INFO: | ||
67 | tmprc = SMB2_query_info(xid, tcon, persistent_fid, | ||
68 | volatile_fid, | ||
69 | (struct smb2_file_all_info *)data); | ||
70 | break; | ||
71 | case SMB2_OP_MKDIR: | ||
72 | /* | ||
73 | * Directories are created through parameters in the | ||
74 | * SMB2_open() call. | ||
75 | */ | ||
76 | break; | ||
77 | default: | ||
78 | cERROR(1, "Invalid command"); | ||
79 | break; | ||
80 | } | ||
81 | |||
82 | rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid); | ||
83 | if (tmprc) | ||
84 | rc = tmprc; | ||
85 | kfree(utf16_path); | ||
86 | return rc; | ||
87 | } | ||
88 | |||
89 | static void | ||
90 | move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src) | ||
91 | { | ||
92 | memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src); | ||
93 | dst->CurrentByteOffset = src->CurrentByteOffset; | ||
94 | dst->Mode = src->Mode; | ||
95 | dst->AlignmentRequirement = src->AlignmentRequirement; | ||
96 | dst->IndexNumber1 = 0; /* we don't use it */ | ||
97 | } | ||
98 | |||
99 | int | ||
100 | smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
101 | struct cifs_sb_info *cifs_sb, const char *full_path, | ||
102 | FILE_ALL_INFO *data, bool *adjust_tz) | ||
103 | { | ||
104 | int rc; | ||
105 | struct smb2_file_all_info *smb2_data; | ||
106 | |||
107 | *adjust_tz = false; | ||
108 | |||
109 | smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2, | ||
110 | GFP_KERNEL); | ||
111 | if (smb2_data == NULL) | ||
112 | return -ENOMEM; | ||
113 | |||
114 | rc = smb2_open_op_close(xid, tcon, cifs_sb, full_path, | ||
115 | FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, | ||
116 | smb2_data, SMB2_OP_QUERY_INFO); | ||
117 | if (rc) | ||
118 | goto out; | ||
119 | |||
120 | move_smb2_info_to_cifs(data, smb2_data); | ||
121 | out: | ||
122 | kfree(smb2_data); | ||
123 | return rc; | ||
124 | } | ||
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index eb73a136641c..a4ff5d547554 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -235,8 +235,13 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr) | |||
235 | *len = le32_to_cpu( | 235 | *len = le32_to_cpu( |
236 | ((struct smb2_create_rsp *)hdr)->CreateContextsLength); | 236 | ((struct smb2_create_rsp *)hdr)->CreateContextsLength); |
237 | break; | 237 | break; |
238 | case SMB2_READ: | ||
239 | case SMB2_QUERY_INFO: | 238 | case SMB2_QUERY_INFO: |
239 | *off = le16_to_cpu( | ||
240 | ((struct smb2_query_info_rsp *)hdr)->OutputBufferOffset); | ||
241 | *len = le32_to_cpu( | ||
242 | ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength); | ||
243 | break; | ||
244 | case SMB2_READ: | ||
240 | case SMB2_QUERY_DIRECTORY: | 245 | case SMB2_QUERY_DIRECTORY: |
241 | case SMB2_IOCTL: | 246 | case SMB2_IOCTL: |
242 | case SMB2_CHANGE_NOTIFY: | 247 | case SMB2_CHANGE_NOTIFY: |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 1266137406fa..bcf310c8b784 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -181,6 +181,15 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, | |||
181 | return rc; | 181 | return rc; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int | ||
185 | smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, | ||
186 | struct cifs_sb_info *cifs_sb, const char *full_path, | ||
187 | u64 *uniqueid, FILE_ALL_INFO *data) | ||
188 | { | ||
189 | *uniqueid = le64_to_cpu(data->IndexNumber); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
184 | struct smb_version_operations smb21_operations = { | 193 | struct smb_version_operations smb21_operations = { |
185 | .setup_request = smb2_setup_request, | 194 | .setup_request = smb2_setup_request, |
186 | .check_receive = smb2_check_receive, | 195 | .check_receive = smb2_check_receive, |
@@ -199,6 +208,8 @@ struct smb_version_operations smb21_operations = { | |||
199 | .tree_connect = SMB2_tcon, | 208 | .tree_connect = SMB2_tcon, |
200 | .tree_disconnect = SMB2_tdis, | 209 | .tree_disconnect = SMB2_tdis, |
201 | .is_path_accessible = smb2_is_path_accessible, | 210 | .is_path_accessible = smb2_is_path_accessible, |
211 | .query_path_info = smb2_query_path_info, | ||
212 | .get_srv_inum = smb2_get_srv_inum, | ||
202 | }; | 213 | }; |
203 | 214 | ||
204 | struct smb_version_values smb21_values = { | 215 | struct smb_version_values smb21_values = { |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index ef0769c398a5..7ef5324786a6 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -961,3 +961,116 @@ close_exit: | |||
961 | free_rsp_buf(resp_buftype, rsp); | 961 | free_rsp_buf(resp_buftype, rsp); |
962 | return rc; | 962 | return rc; |
963 | } | 963 | } |
964 | |||
965 | static int | ||
966 | validate_buf(unsigned int offset, unsigned int buffer_length, | ||
967 | struct smb2_hdr *hdr, unsigned int min_buf_size) | ||
968 | |||
969 | { | ||
970 | unsigned int smb_len = be32_to_cpu(hdr->smb2_buf_length); | ||
971 | char *end_of_smb = smb_len + 4 /* RFC1001 length field */ + (char *)hdr; | ||
972 | char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr; | ||
973 | char *end_of_buf = begin_of_buf + buffer_length; | ||
974 | |||
975 | |||
976 | if (buffer_length < min_buf_size) { | ||
977 | cERROR(1, "buffer length %d smaller than minimum size %d", | ||
978 | buffer_length, min_buf_size); | ||
979 | return -EINVAL; | ||
980 | } | ||
981 | |||
982 | /* check if beyond RFC1001 maximum length */ | ||
983 | if ((smb_len > 0x7FFFFF) || (buffer_length > 0x7FFFFF)) { | ||
984 | cERROR(1, "buffer length %d or smb length %d too large", | ||
985 | buffer_length, smb_len); | ||
986 | return -EINVAL; | ||
987 | } | ||
988 | |||
989 | if ((begin_of_buf > end_of_smb) || (end_of_buf > end_of_smb)) { | ||
990 | cERROR(1, "illegal server response, bad offset to data"); | ||
991 | return -EINVAL; | ||
992 | } | ||
993 | |||
994 | return 0; | ||
995 | } | ||
996 | |||
997 | /* | ||
998 | * If SMB buffer fields are valid, copy into temporary buffer to hold result. | ||
999 | * Caller must free buffer. | ||
1000 | */ | ||
1001 | static int | ||
1002 | validate_and_copy_buf(unsigned int offset, unsigned int buffer_length, | ||
1003 | struct smb2_hdr *hdr, unsigned int minbufsize, | ||
1004 | char *data) | ||
1005 | |||
1006 | { | ||
1007 | char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr; | ||
1008 | int rc; | ||
1009 | |||
1010 | if (!data) | ||
1011 | return -EINVAL; | ||
1012 | |||
1013 | rc = validate_buf(offset, buffer_length, hdr, minbufsize); | ||
1014 | if (rc) | ||
1015 | return rc; | ||
1016 | |||
1017 | memcpy(data, begin_of_buf, buffer_length); | ||
1018 | |||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | int | ||
1023 | SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
1024 | u64 persistent_fid, u64 volatile_fid, | ||
1025 | struct smb2_file_all_info *data) | ||
1026 | { | ||
1027 | struct smb2_query_info_req *req; | ||
1028 | struct smb2_query_info_rsp *rsp = NULL; | ||
1029 | struct kvec iov[2]; | ||
1030 | int rc = 0; | ||
1031 | int resp_buftype; | ||
1032 | struct TCP_Server_Info *server; | ||
1033 | struct cifs_ses *ses = tcon->ses; | ||
1034 | |||
1035 | cFYI(1, "Query Info"); | ||
1036 | |||
1037 | if (ses && (ses->server)) | ||
1038 | server = ses->server; | ||
1039 | else | ||
1040 | return -EIO; | ||
1041 | |||
1042 | rc = small_smb2_init(SMB2_QUERY_INFO, tcon, (void **) &req); | ||
1043 | if (rc) | ||
1044 | return rc; | ||
1045 | |||
1046 | req->InfoType = SMB2_O_INFO_FILE; | ||
1047 | req->FileInfoClass = FILE_ALL_INFORMATION; | ||
1048 | req->PersistentFileId = persistent_fid; | ||
1049 | req->VolatileFileId = volatile_fid; | ||
1050 | /* 4 for rfc1002 length field and 1 for Buffer */ | ||
1051 | req->InputBufferOffset = | ||
1052 | cpu_to_le16(sizeof(struct smb2_query_info_req) - 1 - 4); | ||
1053 | req->OutputBufferLength = | ||
1054 | cpu_to_le32(sizeof(struct smb2_file_all_info) + MAX_NAME * 2); | ||
1055 | |||
1056 | iov[0].iov_base = (char *)req; | ||
1057 | /* 4 for rfc1002 length field */ | ||
1058 | iov[0].iov_len = get_rfc1002_length(req) + 4; | ||
1059 | |||
1060 | rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0); | ||
1061 | if (rc) { | ||
1062 | cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); | ||
1063 | goto qinf_exit; | ||
1064 | } | ||
1065 | |||
1066 | rsp = (struct smb2_query_info_rsp *)iov[0].iov_base; | ||
1067 | |||
1068 | rc = validate_and_copy_buf(le16_to_cpu(rsp->OutputBufferOffset), | ||
1069 | le32_to_cpu(rsp->OutputBufferLength), | ||
1070 | &rsp->hdr, sizeof(struct smb2_file_all_info), | ||
1071 | (char *)data); | ||
1072 | |||
1073 | qinf_exit: | ||
1074 | free_rsp_buf(resp_buftype, rsp); | ||
1075 | return rc; | ||
1076 | } | ||
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 5cd358ef312e..9151e9040b02 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -448,4 +448,115 @@ struct smb2_close_rsp { | |||
448 | __le32 Attributes; | 448 | __le32 Attributes; |
449 | } __packed; | 449 | } __packed; |
450 | 450 | ||
451 | /* Possible InfoType values */ | ||
452 | #define SMB2_O_INFO_FILE 0x01 | ||
453 | #define SMB2_O_INFO_FILESYSTEM 0x02 | ||
454 | #define SMB2_O_INFO_SECURITY 0x03 | ||
455 | #define SMB2_O_INFO_QUOTA 0x04 | ||
456 | |||
457 | struct smb2_query_info_req { | ||
458 | struct smb2_hdr hdr; | ||
459 | __le16 StructureSize; /* Must be 41 */ | ||
460 | __u8 InfoType; | ||
461 | __u8 FileInfoClass; | ||
462 | __le32 OutputBufferLength; | ||
463 | __le16 InputBufferOffset; | ||
464 | __u16 Reserved; | ||
465 | __le32 InputBufferLength; | ||
466 | __le32 AdditionalInformation; | ||
467 | __le32 Flags; | ||
468 | __u64 PersistentFileId; /* opaque endianness */ | ||
469 | __u64 VolatileFileId; /* opaque endianness */ | ||
470 | __u8 Buffer[1]; | ||
471 | } __packed; | ||
472 | |||
473 | struct smb2_query_info_rsp { | ||
474 | struct smb2_hdr hdr; | ||
475 | __le16 StructureSize; /* Must be 9 */ | ||
476 | __le16 OutputBufferOffset; | ||
477 | __le32 OutputBufferLength; | ||
478 | __u8 Buffer[1]; | ||
479 | } __packed; | ||
480 | |||
481 | /* | ||
482 | * PDU infolevel structure definitions | ||
483 | * BB consider moving to a different header | ||
484 | */ | ||
485 | |||
486 | /* partial list of QUERY INFO levels */ | ||
487 | #define FILE_DIRECTORY_INFORMATION 1 | ||
488 | #define FILE_FULL_DIRECTORY_INFORMATION 2 | ||
489 | #define FILE_BOTH_DIRECTORY_INFORMATION 3 | ||
490 | #define FILE_BASIC_INFORMATION 4 | ||
491 | #define FILE_STANDARD_INFORMATION 5 | ||
492 | #define FILE_INTERNAL_INFORMATION 6 | ||
493 | #define FILE_EA_INFORMATION 7 | ||
494 | #define FILE_ACCESS_INFORMATION 8 | ||
495 | #define FILE_NAME_INFORMATION 9 | ||
496 | #define FILE_RENAME_INFORMATION 10 | ||
497 | #define FILE_LINK_INFORMATION 11 | ||
498 | #define FILE_NAMES_INFORMATION 12 | ||
499 | #define FILE_DISPOSITION_INFORMATION 13 | ||
500 | #define FILE_POSITION_INFORMATION 14 | ||
501 | #define FILE_FULL_EA_INFORMATION 15 | ||
502 | #define FILE_MODE_INFORMATION 16 | ||
503 | #define FILE_ALIGNMENT_INFORMATION 17 | ||
504 | #define FILE_ALL_INFORMATION 18 | ||
505 | #define FILE_ALLOCATION_INFORMATION 19 | ||
506 | #define FILE_END_OF_FILE_INFORMATION 20 | ||
507 | #define FILE_ALTERNATE_NAME_INFORMATION 21 | ||
508 | #define FILE_STREAM_INFORMATION 22 | ||
509 | #define FILE_PIPE_INFORMATION 23 | ||
510 | #define FILE_PIPE_LOCAL_INFORMATION 24 | ||
511 | #define FILE_PIPE_REMOTE_INFORMATION 25 | ||
512 | #define FILE_MAILSLOT_QUERY_INFORMATION 26 | ||
513 | #define FILE_MAILSLOT_SET_INFORMATION 27 | ||
514 | #define FILE_COMPRESSION_INFORMATION 28 | ||
515 | #define FILE_OBJECT_ID_INFORMATION 29 | ||
516 | /* Number 30 not defined in documents */ | ||
517 | #define FILE_MOVE_CLUSTER_INFORMATION 31 | ||
518 | #define FILE_QUOTA_INFORMATION 32 | ||
519 | #define FILE_REPARSE_POINT_INFORMATION 33 | ||
520 | #define FILE_NETWORK_OPEN_INFORMATION 34 | ||
521 | #define FILE_ATTRIBUTE_TAG_INFORMATION 35 | ||
522 | #define FILE_TRACKING_INFORMATION 36 | ||
523 | #define FILEID_BOTH_DIRECTORY_INFORMATION 37 | ||
524 | #define FILEID_FULL_DIRECTORY_INFORMATION 38 | ||
525 | #define FILE_VALID_DATA_LENGTH_INFORMATION 39 | ||
526 | #define FILE_SHORT_NAME_INFORMATION 40 | ||
527 | #define FILE_SFIO_RESERVE_INFORMATION 44 | ||
528 | #define FILE_SFIO_VOLUME_INFORMATION 45 | ||
529 | #define FILE_HARD_LINK_INFORMATION 46 | ||
530 | #define FILE_NORMALIZED_NAME_INFORMATION 48 | ||
531 | #define FILEID_GLOBAL_TX_DIRECTORY_INFORMATION 50 | ||
532 | #define FILE_STANDARD_LINK_INFORMATION 54 | ||
533 | |||
534 | /* | ||
535 | * This level 18, although with struct with same name is different from cifs | ||
536 | * level 0x107. Level 0x107 has an extra u64 between AccessFlags and | ||
537 | * CurrentByteOffset. | ||
538 | */ | ||
539 | struct smb2_file_all_info { /* data block encoding of response to level 18 */ | ||
540 | __le64 CreationTime; /* Beginning of FILE_BASIC_INFO equivalent */ | ||
541 | __le64 LastAccessTime; | ||
542 | __le64 LastWriteTime; | ||
543 | __le64 ChangeTime; | ||
544 | __le32 Attributes; | ||
545 | __u32 Pad1; /* End of FILE_BASIC_INFO_INFO equivalent */ | ||
546 | __le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */ | ||
547 | __le64 EndOfFile; /* size ie offset to first free byte in file */ | ||
548 | __le32 NumberOfLinks; /* hard links */ | ||
549 | __u8 DeletePending; | ||
550 | __u8 Directory; | ||
551 | __u16 Pad2; /* End of FILE_STANDARD_INFO equivalent */ | ||
552 | __le64 IndexNumber; | ||
553 | __le32 EASize; | ||
554 | __le32 AccessFlags; | ||
555 | __le64 CurrentByteOffset; | ||
556 | __le32 Mode; | ||
557 | __le32 AlignmentRequirement; | ||
558 | __le32 FileNameLength; | ||
559 | char FileName[1]; | ||
560 | } __packed; /* level 18 Query */ | ||
561 | |||
451 | #endif /* _SMB2PDU_H */ | 562 | #endif /* _SMB2PDU_H */ |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 85aa8d5ea41a..1517b4c03c90 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -44,6 +44,10 @@ extern int smb2_check_receive(struct mid_q_entry *mid, | |||
44 | extern int smb2_setup_request(struct cifs_ses *ses, struct kvec *iov, | 44 | extern int smb2_setup_request(struct cifs_ses *ses, struct kvec *iov, |
45 | unsigned int nvec, struct mid_q_entry **ret_mid); | 45 | unsigned int nvec, struct mid_q_entry **ret_mid); |
46 | 46 | ||
47 | extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
48 | struct cifs_sb_info *cifs_sb, | ||
49 | const char *full_path, FILE_ALL_INFO *data, | ||
50 | bool *adjust_tz); | ||
47 | /* | 51 | /* |
48 | * SMB2 Worker functions - most of protocol specific implementation details | 52 | * SMB2 Worker functions - most of protocol specific implementation details |
49 | * are contained within these calls. | 53 | * are contained within these calls. |
@@ -62,5 +66,8 @@ extern int SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, | |||
62 | __u32 file_attributes, __u32 create_options); | 66 | __u32 file_attributes, __u32 create_options); |
63 | extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, | 67 | extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, |
64 | u64 persistent_file_id, u64 volatile_file_id); | 68 | u64 persistent_file_id, u64 volatile_file_id); |
69 | extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
70 | u64 persistent_file_id, u64 volatile_file_id, | ||
71 | struct smb2_file_all_info *data); | ||
65 | 72 | ||
66 | #endif /* _SMB2PROTO_H */ | 73 | #endif /* _SMB2PROTO_H */ |