1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

14 fixes to cifs client and to smbfs_common code

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmJGhDkACgkQiiy9cAdy
 T1EquQv/V05eD1EWZzW+Y5Q+cbYBPn8T3r6YqSw6hIvbgdF6W6U45UPyJ4ASHKvl
 +MvTPSJzEzSWKYfcDryUBsa7aAXaekPpxW6uZk7jMRuVIfkannTV9E+rZItwC/dS
 g8kDDjvcWrwN9iQUyVNX1JCybpq5YnwEIA5z0C8rpuCjDelNfK5DCaf02PweuRlY
 3pDlj8Jy4sY8mBvqzFiWheY6Xc3pbvheDIvHEieaZpAyPwF7r1hmwvMDkzbJfPjV
 Qrwcrwq2FahK4E98gJQZ5U0CeXvNPEHPcc8c4bAkRpnaa/v2oVSCW4FGjhA1Stp2
 0APC+AsjkY95DJ0GHerGfH5G0z6FAbRJjyXtt1NTkyKavEQZOqoQvi5yM/iXUEoA
 z+1bgN7s02IMLU15gLDilK6QObWtUwvNxuS19MQ80yFnqmjNNpSmRTfpwzDJQ6Lj
 B6Yml8tIvVPLtmuwehhljffMUv9lrdElDDjT50yTn/CTkQYUMBejitMGu8G4YwZI
 luAN1msJ
 =bNGL
 -----END PGP SIGNATURE-----

Merge tag '5.18-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6

Pull more cifs updates from Steve French:

 - three fixes for big endian issues in how Persistent and Volatile file
   ids were stored

 - Various misc. fixes: including some for oops, 2 for ioctls, 1 for
   writeback

 - cleanup of how tcon (tree connection) status is tracked

 - Four changesets to move various duplicated protocol definitions
   (defined both in cifs.ko and ksmbd) into smbfs_common/smb2pdu.h

 - important performance improvement to use cached handles in some key
   compounding code paths (reduces numbers of opens/closes sent in some
   workloads)

 - fix to allow alternate DFS target to be used to retry on a failed i/o

* tag '5.18-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
  cifs: prevent bad output lengths in smb2_ioctl_query_info()
  smb3: fix ksmbd bigendian bug in oplock break, and move its struct to smbfs_common
  smb3: cleanup and clarify status of tree connections
  smb3: move defines for query info and query fsinfo to smbfs_common
  smb3: move defines for ioctl protocol header and SMB2 sizes to smbfs_common
  [smb3] move more common protocol header definitions to smbfs_common
  cifs: fix incorrect use of list iterator after the loop
  ksmbd: store fids as opaque u64 integers
  cifs: fix bad fids sent over wire
  cifs: change smb2_query_info_compound to use a cached fid, if available
  cifs: convert the path to utf16 in smb2_query_info_compound
  cifs: writeback fix
  cifs: do not skip link targets when an I/O fails
This commit is contained in:
Linus Torvalds 2022-04-01 14:31:57 -07:00
commit 9a005bea4f
18 changed files with 924 additions and 1377 deletions

View file

@ -94,7 +94,7 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
le32_to_cpu(tcon->fsAttrInfo.Attributes), le32_to_cpu(tcon->fsAttrInfo.Attributes),
le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
tcon->tidStatus); tcon->status);
if (dev_type == FILE_DEVICE_DISK) if (dev_type == FILE_DEVICE_DISK)
seq_puts(m, " type: DISK "); seq_puts(m, " type: DISK ");
else if (dev_type == FILE_DEVICE_CD_ROM) else if (dev_type == FILE_DEVICE_CD_ROM)

View file

@ -699,14 +699,14 @@ static void cifs_umount_begin(struct super_block *sb)
tcon = cifs_sb_master_tcon(cifs_sb); tcon = cifs_sb_master_tcon(cifs_sb);
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
/* we have other mounts to same share or we have /* we have other mounts to same share or we have
already tried to force umount this and woken up already tried to force umount this and woken up
all waiting network requests, nothing to do */ all waiting network requests, nothing to do */
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
return; return;
} else if (tcon->tc_count == 1) } else if (tcon->tc_count == 1)
tcon->tidStatus = CifsExiting; tcon->status = TID_EXITING;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */

View file

@ -116,10 +116,18 @@ enum statusEnum {
CifsInNegotiate, CifsInNegotiate,
CifsNeedSessSetup, CifsNeedSessSetup,
CifsInSessSetup, CifsInSessSetup,
CifsNeedTcon, };
CifsInTcon,
CifsNeedFilesInvalidate, /* associated with each tree connection to the server */
CifsInFilesInvalidate enum tid_status_enum {
TID_NEW = 0,
TID_GOOD,
TID_EXITING,
TID_NEED_RECON,
TID_NEED_TCON,
TID_IN_TCON,
TID_NEED_FILES_INVALIDATE, /* currently unused */
TID_IN_FILES_INVALIDATE
}; };
enum securityEnum { enum securityEnum {
@ -853,13 +861,7 @@ compare_mid(__u16 mid, const struct smb_hdr *smb)
#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4) #define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4)
#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4) #define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4)
/*
* The default wsize is 1M. find_get_pages seems to return a maximum of 256
* pages in a single call. With PAGE_SIZE == 4k, this means we can fill
* a single wsize request with a single call.
*/
#define CIFS_DEFAULT_IOSIZE (1024 * 1024) #define CIFS_DEFAULT_IOSIZE (1024 * 1024)
#define SMB3_DEFAULT_IOSIZE (4 * 1024 * 1024)
/* /*
* Windows only supports a max of 60kb reads and 65535 byte writes. Default to * Windows only supports a max of 60kb reads and 65535 byte writes. Default to
@ -1039,7 +1041,7 @@ struct cifs_tcon {
char *password; /* for share-level security */ char *password; /* for share-level security */
__u32 tid; /* The 4 byte tree id */ __u32 tid; /* The 4 byte tree id */
__u16 Flags; /* optional support bits */ __u16 Flags; /* optional support bits */
enum statusEnum tidStatus; enum tid_status_enum status;
atomic_t num_smbs_sent; atomic_t num_smbs_sent;
union { union {
struct { struct {

View file

@ -123,18 +123,6 @@
*/ */
#define CIFS_SESS_KEY_SIZE (16) #define CIFS_SESS_KEY_SIZE (16)
/*
* Size of the smb3 signing key
*/
#define SMB3_SIGN_KEY_SIZE (16)
/*
* Size of the smb3 encryption/decryption key storage.
* This size is big enough to store any cipher key types.
*/
#define SMB3_ENC_DEC_KEY_SIZE (32)
#define CIFS_CLIENT_CHALLENGE_SIZE (8)
#define CIFS_SERVER_CHALLENGE_SIZE (8) #define CIFS_SERVER_CHALLENGE_SIZE (8)
#define CIFS_HMAC_MD5_HASH_SIZE (16) #define CIFS_HMAC_MD5_HASH_SIZE (16)
#define CIFS_CPHTXT_SIZE (16) #define CIFS_CPHTXT_SIZE (16)
@ -1658,7 +1646,7 @@ struct smb_t2_rsp {
#define SMB_FIND_FILE_ID_FULL_DIR_INFO 0x105 #define SMB_FIND_FILE_ID_FULL_DIR_INFO 0x105
#define SMB_FIND_FILE_ID_BOTH_DIR_INFO 0x106 #define SMB_FIND_FILE_ID_BOTH_DIR_INFO 0x106
#define SMB_FIND_FILE_UNIX 0x202 #define SMB_FIND_FILE_UNIX 0x202
#define SMB_FIND_FILE_POSIX_INFO 0x064 /* #define SMB_FIND_FILE_POSIX_INFO 0x064 */
typedef struct smb_com_transaction2_qpi_req { typedef struct smb_com_transaction2_qpi_req {
struct smb_hdr hdr; /* wct = 14+ */ struct smb_hdr hdr; /* wct = 14+ */

View file

@ -75,12 +75,11 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
/* only send once per connect */ /* only send once per connect */
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->ses->status != CifsGood || if ((tcon->ses->status != CifsGood) || (tcon->status != TID_NEED_RECON)) {
tcon->tidStatus != CifsNeedReconnect) {
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
return; return;
} }
tcon->tidStatus = CifsInFilesInvalidate; tcon->status = TID_IN_FILES_INVALIDATE;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
/* list all files open on tree connection and mark them invalid */ /* list all files open on tree connection and mark them invalid */
@ -100,8 +99,8 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
mutex_unlock(&tcon->crfid.fid_mutex); mutex_unlock(&tcon->crfid.fid_mutex);
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInFilesInvalidate) if (tcon->status == TID_IN_FILES_INVALIDATE)
tcon->tidStatus = CifsNeedTcon; tcon->status = TID_NEED_TCON;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
/* /*
@ -136,7 +135,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
* have tcon) are allowed as we start force umount * have tcon) are allowed as we start force umount
*/ */
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsExiting) { if (tcon->status == TID_EXITING) {
if (smb_command != SMB_COM_WRITE_ANDX && if (smb_command != SMB_COM_WRITE_ANDX &&
smb_command != SMB_COM_OPEN_ANDX && smb_command != SMB_COM_OPEN_ANDX &&
smb_command != SMB_COM_TREE_DISCONNECT) { smb_command != SMB_COM_TREE_DISCONNECT) {

View file

@ -245,7 +245,7 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
tcon->need_reconnect = true; tcon->need_reconnect = true;
tcon->tidStatus = CifsNeedReconnect; tcon->status = TID_NEED_RECON;
} }
if (ses->tcon_ipc) if (ses->tcon_ipc)
ses->tcon_ipc->need_reconnect = true; ses->tcon_ipc->need_reconnect = true;
@ -2207,7 +2207,7 @@ get_ses_fail:
static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
{ {
if (tcon->tidStatus == CifsExiting) if (tcon->status == TID_EXITING)
return 0; return 0;
if (strncmp(tcon->treeName, ctx->UNC, MAX_TREE_SIZE)) if (strncmp(tcon->treeName, ctx->UNC, MAX_TREE_SIZE))
return 0; return 0;
@ -3513,6 +3513,9 @@ static int connect_dfs_target(struct mount_ctx *mnt_ctx, const char *full_path,
struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
char *oldmnt = cifs_sb->ctx->mount_options; char *oldmnt = cifs_sb->ctx->mount_options;
cifs_dbg(FYI, "%s: full_path=%s ref_path=%s target=%s\n", __func__, full_path, ref_path,
dfs_cache_get_tgt_name(tit));
rc = dfs_cache_get_tgt_referral(ref_path, tit, &ref); rc = dfs_cache_get_tgt_referral(ref_path, tit, &ref);
if (rc) if (rc)
goto out; goto out;
@ -3611,13 +3614,18 @@ static int __follow_dfs_link(struct mount_ctx *mnt_ctx)
if (rc) if (rc)
goto out; goto out;
/* Try all dfs link targets */ /* Try all dfs link targets. If an I/O fails from currently connected DFS target with an
* error other than STATUS_PATH_NOT_COVERED (-EREMOTE), then retry it from other targets as
* specified in MS-DFSC "3.1.5.2 I/O Operation to Target Fails with an Error Other Than
* STATUS_PATH_NOT_COVERED."
*/
for (rc = -ENOENT, tit = dfs_cache_get_tgt_iterator(&tl); for (rc = -ENOENT, tit = dfs_cache_get_tgt_iterator(&tl);
tit; tit = dfs_cache_get_next_tgt(&tl, tit)) { tit; tit = dfs_cache_get_next_tgt(&tl, tit)) {
rc = connect_dfs_target(mnt_ctx, full_path, mnt_ctx->leaf_fullpath + 1, tit); rc = connect_dfs_target(mnt_ctx, full_path, mnt_ctx->leaf_fullpath + 1, tit);
if (!rc) { if (!rc) {
rc = is_path_remote(mnt_ctx); rc = is_path_remote(mnt_ctx);
break; if (!rc || rc == -EREMOTE)
break;
} }
} }
@ -3691,7 +3699,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
goto error; goto error;
rc = is_path_remote(&mnt_ctx); rc = is_path_remote(&mnt_ctx);
if (rc == -EREMOTE) if (rc)
rc = follow_dfs_link(&mnt_ctx); rc = follow_dfs_link(&mnt_ctx);
if (rc) if (rc)
goto error; goto error;
@ -4478,12 +4486,12 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
/* only send once per connect */ /* only send once per connect */
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->ses->status != CifsGood || if (tcon->ses->status != CifsGood ||
(tcon->tidStatus != CifsNew && (tcon->status != TID_NEW &&
tcon->tidStatus != CifsNeedTcon)) { tcon->status != TID_NEED_TCON)) {
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
return 0; return 0;
} }
tcon->tidStatus = CifsInTcon; tcon->status = TID_IN_TCON;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL); tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
@ -4524,13 +4532,13 @@ out:
if (rc) { if (rc) {
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon) if (tcon->status == TID_IN_TCON)
tcon->tidStatus = CifsNeedTcon; tcon->status = TID_NEED_TCON;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
} else { } else {
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon) if (tcon->status == TID_IN_TCON)
tcon->tidStatus = CifsGood; tcon->status = TID_GOOD;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
tcon->need_reconnect = false; tcon->need_reconnect = false;
} }
@ -4546,24 +4554,24 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
/* only send once per connect */ /* only send once per connect */
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->ses->status != CifsGood || if (tcon->ses->status != CifsGood ||
(tcon->tidStatus != CifsNew && (tcon->status != TID_NEW &&
tcon->tidStatus != CifsNeedTcon)) { tcon->status != TID_NEED_TCON)) {
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
return 0; return 0;
} }
tcon->tidStatus = CifsInTcon; tcon->status = TID_IN_TCON;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
if (rc) { if (rc) {
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon) if (tcon->status == TID_IN_TCON)
tcon->tidStatus = CifsNeedTcon; tcon->status = TID_NEED_TCON;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
} else { } else {
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsInTcon) if (tcon->status == TID_IN_TCON)
tcon->tidStatus = CifsGood; tcon->status = TID_GOOD;
spin_unlock(&cifs_tcp_ses_lock); spin_unlock(&cifs_tcp_ses_lock);
tcon->need_reconnect = false; tcon->need_reconnect = false;
} }

View file

@ -4210,13 +4210,19 @@ cifs_page_mkwrite(struct vm_fault *vmf)
{ {
struct page *page = vmf->page; struct page *page = vmf->page;
/* Wait for the page to be written to the cache before we allow it to
* be modified. We then assume the entire page will need writing back.
*/
#ifdef CONFIG_CIFS_FSCACHE #ifdef CONFIG_CIFS_FSCACHE
if (PageFsCache(page) && if (PageFsCache(page) &&
wait_on_page_fscache_killable(page) < 0) wait_on_page_fscache_killable(page) < 0)
return VM_FAULT_RETRY; return VM_FAULT_RETRY;
#endif #endif
lock_page(page); wait_on_page_writeback(page);
if (lock_page_killable(page) < 0)
return VM_FAULT_RETRY;
return VM_FAULT_LOCKED; return VM_FAULT_LOCKED;
} }

View file

@ -116,7 +116,7 @@ tconInfoAlloc(void)
} }
atomic_inc(&tconInfoAllocCount); atomic_inc(&tconInfoAllocCount);
ret_buf->tidStatus = CifsNew; ret_buf->status = TID_NEW;
++ret_buf->tc_count; ++ret_buf->tc_count;
INIT_LIST_HEAD(&ret_buf->openFileList); INIT_LIST_HEAD(&ret_buf->openFileList);
INIT_LIST_HEAD(&ret_buf->tcon_list); INIT_LIST_HEAD(&ret_buf->tcon_list);

View file

@ -41,15 +41,4 @@
#define END_OF_CHAIN 4 #define END_OF_CHAIN 4
#define RELATED_REQUEST 8 #define RELATED_REQUEST 8
#define SMB2_SIGNATURE_SIZE (16)
#define SMB2_NTLMV2_SESSKEY_SIZE (16)
#define SMB2_HMACSHA256_SIZE (32)
#define SMB2_CMACAES_SIZE (16)
#define SMB3_SIGNKEY_SIZE (16)
#define SMB3_GCM128_CRYPTKEY_SIZE (16)
#define SMB3_GCM256_CRYPTKEY_SIZE (32)
/* Maximum buffer size value we can send with 1 credit */
#define SMB2_MAX_BUFFER_SIZE 65536
#endif /* _SMB2_GLOB_H */ #endif /* _SMB2_GLOB_H */

View file

@ -203,7 +203,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) { if (smb2_rsp_struct_sizes[command] != pdu->StructureSize2) {
if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 || if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) { pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2_LE)) {
/* error packets have 9 byte structure size */ /* error packets have 9 byte structure size */
cifs_dbg(VFS, "Invalid response size %u for command %d\n", cifs_dbg(VFS, "Invalid response size %u for command %d\n",
le16_to_cpu(pdu->StructureSize2), command); le16_to_cpu(pdu->StructureSize2), command);
@ -303,7 +303,7 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr)
/* error responses do not have data area */ /* error responses do not have data area */
if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED && if (shdr->Status && shdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
(((struct smb2_err_rsp *)shdr)->StructureSize) == (((struct smb2_err_rsp *)shdr)->StructureSize) ==
SMB2_ERROR_STRUCTURE_SIZE2) SMB2_ERROR_STRUCTURE_SIZE2_LE)
return NULL; return NULL;
/* /*
@ -478,11 +478,11 @@ smb2_get_lease_state(struct cifsInodeInfo *cinode)
__le32 lease = 0; __le32 lease = 0;
if (CIFS_CACHE_WRITE(cinode)) if (CIFS_CACHE_WRITE(cinode))
lease |= SMB2_LEASE_WRITE_CACHING; lease |= SMB2_LEASE_WRITE_CACHING_LE;
if (CIFS_CACHE_HANDLE(cinode)) if (CIFS_CACHE_HANDLE(cinode))
lease |= SMB2_LEASE_HANDLE_CACHING; lease |= SMB2_LEASE_HANDLE_CACHING_LE;
if (CIFS_CACHE_READ(cinode)) if (CIFS_CACHE_READ(cinode))
lease |= SMB2_LEASE_READ_CACHING; lease |= SMB2_LEASE_READ_CACHING_LE;
return lease; return lease;
} }
@ -832,8 +832,8 @@ smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *serve
rc = __smb2_handle_cancelled_cmd(tcon, rc = __smb2_handle_cancelled_cmd(tcon,
le16_to_cpu(hdr->Command), le16_to_cpu(hdr->Command),
le64_to_cpu(hdr->MessageId), le64_to_cpu(hdr->MessageId),
le64_to_cpu(rsp->PersistentFileId), rsp->PersistentFileId,
le64_to_cpu(rsp->VolatileFileId)); rsp->VolatileFileId);
if (rc) if (rc)
cifs_put_tcon(tcon); cifs_put_tcon(tcon);

View file

@ -897,8 +897,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
atomic_inc(&tcon->num_remote_opens); atomic_inc(&tcon->num_remote_opens);
o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base; o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
oparms.fid->persistent_fid = le64_to_cpu(o_rsp->PersistentFileId); oparms.fid->persistent_fid = o_rsp->PersistentFileId;
oparms.fid->volatile_fid = le64_to_cpu(o_rsp->VolatileFileId); oparms.fid->volatile_fid = o_rsp->VolatileFileId;
#ifdef CONFIG_CIFS_DEBUG2 #ifdef CONFIG_CIFS_DEBUG2
oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId); oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
#endif /* CIFS_DEBUG2 */ #endif /* CIFS_DEBUG2 */
@ -1192,17 +1192,12 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb) struct cifs_sb_info *cifs_sb)
{ {
int rc; int rc;
__le16 *utf16_path;
struct kvec rsp_iov = {NULL, 0}; struct kvec rsp_iov = {NULL, 0};
int buftype = CIFS_NO_BUFFER; int buftype = CIFS_NO_BUFFER;
struct smb2_query_info_rsp *rsp; struct smb2_query_info_rsp *rsp;
struct smb2_file_full_ea_info *info = NULL; struct smb2_file_full_ea_info *info = NULL;
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); rc = smb2_query_info_compound(xid, tcon, path,
if (!utf16_path)
return -ENOMEM;
rc = smb2_query_info_compound(xid, tcon, utf16_path,
FILE_READ_EA, FILE_READ_EA,
FILE_FULL_EA_INFORMATION, FILE_FULL_EA_INFORMATION,
SMB2_O_INFO_FILE, SMB2_O_INFO_FILE,
@ -1235,7 +1230,6 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
le32_to_cpu(rsp->OutputBufferLength), ea_name); le32_to_cpu(rsp->OutputBufferLength), ea_name);
qeas_exit: qeas_exit:
kfree(utf16_path);
free_rsp_buf(buftype, rsp_iov.iov_base); free_rsp_buf(buftype, rsp_iov.iov_base);
return rc; return rc;
} }
@ -1295,7 +1289,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
* the new EA. If not we should not add it since we * the new EA. If not we should not add it since we
* would not be able to even read the EAs back. * would not be able to even read the EAs back.
*/ */
rc = smb2_query_info_compound(xid, tcon, utf16_path, rc = smb2_query_info_compound(xid, tcon, path,
FILE_READ_EA, FILE_READ_EA,
FILE_FULL_EA_INFORMATION, FILE_FULL_EA_INFORMATION,
SMB2_O_INFO_FILE, SMB2_O_INFO_FILE,
@ -1643,6 +1637,7 @@ smb2_ioctl_query_info(const unsigned int xid,
unsigned int size[2]; unsigned int size[2];
void *data[2]; void *data[2];
int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR; int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR;
void (*free_req1_func)(struct smb_rqst *r);
vars = kzalloc(sizeof(*vars), GFP_ATOMIC); vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
if (vars == NULL) if (vars == NULL)
@ -1652,27 +1647,29 @@ smb2_ioctl_query_info(const unsigned int xid,
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
if (copy_from_user(&qi, arg, sizeof(struct smb_query_info))) if (copy_from_user(&qi, arg, sizeof(struct smb_query_info))) {
goto e_fault; rc = -EFAULT;
goto free_vars;
}
if (qi.output_buffer_length > 1024) { if (qi.output_buffer_length > 1024) {
kfree(vars); rc = -EINVAL;
return -EINVAL; goto free_vars;
} }
if (!ses || !server) { if (!ses || !server) {
kfree(vars); rc = -EIO;
return -EIO; goto free_vars;
} }
if (smb3_encryption_required(tcon)) if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ; flags |= CIFS_TRANSFORM_REQ;
buffer = memdup_user(arg + sizeof(struct smb_query_info), if (qi.output_buffer_length) {
qi.output_buffer_length); buffer = memdup_user(arg + sizeof(struct smb_query_info), qi.output_buffer_length);
if (IS_ERR(buffer)) { if (IS_ERR(buffer)) {
kfree(vars); rc = PTR_ERR(buffer);
return PTR_ERR(buffer); goto free_vars;
}
} }
/* Open */ /* Open */
@ -1710,45 +1707,45 @@ smb2_ioctl_query_info(const unsigned int xid,
rc = SMB2_open_init(tcon, server, rc = SMB2_open_init(tcon, server,
&rqst[0], &oplock, &oparms, path); &rqst[0], &oplock, &oparms, path);
if (rc) if (rc)
goto iqinf_exit; goto free_output_buffer;
smb2_set_next_command(tcon, &rqst[0]); smb2_set_next_command(tcon, &rqst[0]);
/* Query */ /* Query */
if (qi.flags & PASSTHRU_FSCTL) { if (qi.flags & PASSTHRU_FSCTL) {
/* Can eventually relax perm check since server enforces too */ /* Can eventually relax perm check since server enforces too */
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN)) {
rc = -EPERM; rc = -EPERM;
else { goto free_open_req;
rqst[1].rq_iov = &vars->io_iov[0];
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
rc = SMB2_ioctl_init(tcon, server,
&rqst[1],
COMPOUND_FID, COMPOUND_FID,
qi.info_type, true, buffer,
qi.output_buffer_length,
CIFSMaxBufSize -
MAX_SMB2_CREATE_RESPONSE_SIZE -
MAX_SMB2_CLOSE_RESPONSE_SIZE);
} }
rqst[1].rq_iov = &vars->io_iov[0];
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
rc = SMB2_ioctl_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID,
qi.info_type, true, buffer, qi.output_buffer_length,
CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE -
MAX_SMB2_CLOSE_RESPONSE_SIZE);
free_req1_func = SMB2_ioctl_free;
} else if (qi.flags == PASSTHRU_SET_INFO) { } else if (qi.flags == PASSTHRU_SET_INFO) {
/* Can eventually relax perm check since server enforces too */ /* Can eventually relax perm check since server enforces too */
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN)) {
rc = -EPERM; rc = -EPERM;
else { goto free_open_req;
rqst[1].rq_iov = &vars->si_iov[0];
rqst[1].rq_nvec = 1;
size[0] = 8;
data[0] = buffer;
rc = SMB2_set_info_init(tcon, server,
&rqst[1],
COMPOUND_FID, COMPOUND_FID,
current->tgid,
FILE_END_OF_FILE_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
} }
if (qi.output_buffer_length < 8) {
rc = -EINVAL;
goto free_open_req;
}
rqst[1].rq_iov = &vars->si_iov[0];
rqst[1].rq_nvec = 1;
/* MS-FSCC 2.4.13 FileEndOfFileInformation */
size[0] = 8;
data[0] = buffer;
rc = SMB2_set_info_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID,
current->tgid, FILE_END_OF_FILE_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
free_req1_func = SMB2_set_info_free;
} else if (qi.flags == PASSTHRU_QUERY_INFO) { } else if (qi.flags == PASSTHRU_QUERY_INFO) {
rqst[1].rq_iov = &vars->qi_iov[0]; rqst[1].rq_iov = &vars->qi_iov[0];
rqst[1].rq_nvec = 1; rqst[1].rq_nvec = 1;
@ -1759,6 +1756,7 @@ smb2_ioctl_query_info(const unsigned int xid,
qi.info_type, qi.additional_information, qi.info_type, qi.additional_information,
qi.input_buffer_length, qi.input_buffer_length,
qi.output_buffer_length, buffer); qi.output_buffer_length, buffer);
free_req1_func = SMB2_query_info_free;
} else { /* unknown flags */ } else { /* unknown flags */
cifs_tcon_dbg(VFS, "Invalid passthru query flags: 0x%x\n", cifs_tcon_dbg(VFS, "Invalid passthru query flags: 0x%x\n",
qi.flags); qi.flags);
@ -1766,7 +1764,7 @@ smb2_ioctl_query_info(const unsigned int xid,
} }
if (rc) if (rc)
goto iqinf_exit; goto free_open_req;
smb2_set_next_command(tcon, &rqst[1]); smb2_set_next_command(tcon, &rqst[1]);
smb2_set_related(&rqst[1]); smb2_set_related(&rqst[1]);
@ -1777,14 +1775,14 @@ smb2_ioctl_query_info(const unsigned int xid,
rc = SMB2_close_init(tcon, server, rc = SMB2_close_init(tcon, server,
&rqst[2], COMPOUND_FID, COMPOUND_FID, false); &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
if (rc) if (rc)
goto iqinf_exit; goto free_req_1;
smb2_set_related(&rqst[2]); smb2_set_related(&rqst[2]);
rc = compound_send_recv(xid, ses, server, rc = compound_send_recv(xid, ses, server,
flags, 3, rqst, flags, 3, rqst,
resp_buftype, rsp_iov); resp_buftype, rsp_iov);
if (rc) if (rc)
goto iqinf_exit; goto out;
/* No need to bump num_remote_opens since handle immediately closed */ /* No need to bump num_remote_opens since handle immediately closed */
if (qi.flags & PASSTHRU_FSCTL) { if (qi.flags & PASSTHRU_FSCTL) {
@ -1794,18 +1792,22 @@ smb2_ioctl_query_info(const unsigned int xid,
qi.input_buffer_length = le32_to_cpu(io_rsp->OutputCount); qi.input_buffer_length = le32_to_cpu(io_rsp->OutputCount);
if (qi.input_buffer_length > 0 && if (qi.input_buffer_length > 0 &&
le32_to_cpu(io_rsp->OutputOffset) + qi.input_buffer_length le32_to_cpu(io_rsp->OutputOffset) + qi.input_buffer_length
> rsp_iov[1].iov_len) > rsp_iov[1].iov_len) {
goto e_fault; rc = -EFAULT;
goto out;
}
if (copy_to_user(&pqi->input_buffer_length, if (copy_to_user(&pqi->input_buffer_length,
&qi.input_buffer_length, &qi.input_buffer_length,
sizeof(qi.input_buffer_length))) sizeof(qi.input_buffer_length))) {
goto e_fault; rc = -EFAULT;
goto out;
}
if (copy_to_user((void __user *)pqi + sizeof(struct smb_query_info), if (copy_to_user((void __user *)pqi + sizeof(struct smb_query_info),
(const void *)io_rsp + le32_to_cpu(io_rsp->OutputOffset), (const void *)io_rsp + le32_to_cpu(io_rsp->OutputOffset),
qi.input_buffer_length)) qi.input_buffer_length))
goto e_fault; rc = -EFAULT;
} else { } else {
pqi = (struct smb_query_info __user *)arg; pqi = (struct smb_query_info __user *)arg;
qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
@ -1813,28 +1815,30 @@ smb2_ioctl_query_info(const unsigned int xid,
qi.input_buffer_length = le32_to_cpu(qi_rsp->OutputBufferLength); qi.input_buffer_length = le32_to_cpu(qi_rsp->OutputBufferLength);
if (copy_to_user(&pqi->input_buffer_length, if (copy_to_user(&pqi->input_buffer_length,
&qi.input_buffer_length, &qi.input_buffer_length,
sizeof(qi.input_buffer_length))) sizeof(qi.input_buffer_length))) {
goto e_fault; rc = -EFAULT;
goto out;
}
if (copy_to_user(pqi + 1, qi_rsp->Buffer, if (copy_to_user(pqi + 1, qi_rsp->Buffer,
qi.input_buffer_length)) qi.input_buffer_length))
goto e_fault; rc = -EFAULT;
} }
iqinf_exit: out:
cifs_small_buf_release(rqst[0].rq_iov[0].iov_base);
cifs_small_buf_release(rqst[1].rq_iov[0].iov_base);
cifs_small_buf_release(rqst[2].rq_iov[0].iov_base);
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
kfree(vars); SMB2_close_free(&rqst[2]);
free_req_1:
free_req1_func(&rqst[1]);
free_open_req:
SMB2_open_free(&rqst[0]);
free_output_buffer:
kfree(buffer); kfree(buffer);
free_vars:
kfree(vars);
return rc; return rc;
e_fault:
rc = -EFAULT;
goto iqinf_exit;
} }
static ssize_t static ssize_t
@ -2407,8 +2411,8 @@ again:
cifs_dbg(FYI, "query_dir_first: open failed rc=%d\n", rc); cifs_dbg(FYI, "query_dir_first: open failed rc=%d\n", rc);
goto qdf_free; goto qdf_free;
} }
fid->persistent_fid = le64_to_cpu(op_rsp->PersistentFileId); fid->persistent_fid = op_rsp->PersistentFileId;
fid->volatile_fid = le64_to_cpu(op_rsp->VolatileFileId); fid->volatile_fid = op_rsp->VolatileFileId;
/* Anything else than ENODATA means a genuine error */ /* Anything else than ENODATA means a genuine error */
if (rc && rc != -ENODATA) { if (rc && rc != -ENODATA) {
@ -2646,7 +2650,7 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
*/ */
int int
smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
__le16 *utf16_path, u32 desired_access, const char *path, u32 desired_access,
u32 class, u32 type, u32 output_len, u32 class, u32 type, u32 output_len,
struct kvec *rsp, int *buftype, struct kvec *rsp, int *buftype,
struct cifs_sb_info *cifs_sb) struct cifs_sb_info *cifs_sb)
@ -2664,6 +2668,14 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_open_parms oparms; struct cifs_open_parms oparms;
struct cifs_fid fid; struct cifs_fid fid;
int rc; int rc;
__le16 *utf16_path;
struct cached_fid *cfid = NULL;
if (!path)
path = "";
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
if (!utf16_path)
return -ENOMEM;
if (smb3_encryption_required(tcon)) if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ; flags |= CIFS_TRANSFORM_REQ;
@ -2672,6 +2684,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
memset(rsp_iov, 0, sizeof(rsp_iov)); memset(rsp_iov, 0, sizeof(rsp_iov));
rc = open_cached_dir(xid, tcon, path, cifs_sb, &cfid);
memset(&open_iov, 0, sizeof(open_iov)); memset(&open_iov, 0, sizeof(open_iov));
rqst[0].rq_iov = open_iov; rqst[0].rq_iov = open_iov;
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
@ -2693,15 +2707,29 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
rqst[1].rq_iov = qi_iov; rqst[1].rq_iov = qi_iov;
rqst[1].rq_nvec = 1; rqst[1].rq_nvec = 1;
rc = SMB2_query_info_init(tcon, server, if (cfid) {
&rqst[1], COMPOUND_FID, COMPOUND_FID, rc = SMB2_query_info_init(tcon, server,
class, type, 0, &rqst[1],
output_len, 0, cfid->fid->persistent_fid,
NULL); cfid->fid->volatile_fid,
class, type, 0,
output_len, 0,
NULL);
} else {
rc = SMB2_query_info_init(tcon, server,
&rqst[1],
COMPOUND_FID,
COMPOUND_FID,
class, type, 0,
output_len, 0,
NULL);
}
if (rc) if (rc)
goto qic_exit; goto qic_exit;
smb2_set_next_command(tcon, &rqst[1]); if (!cfid) {
smb2_set_related(&rqst[1]); smb2_set_next_command(tcon, &rqst[1]);
smb2_set_related(&rqst[1]);
}
memset(&close_iov, 0, sizeof(close_iov)); memset(&close_iov, 0, sizeof(close_iov));
rqst[2].rq_iov = close_iov; rqst[2].rq_iov = close_iov;
@ -2713,9 +2741,15 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
goto qic_exit; goto qic_exit;
smb2_set_related(&rqst[2]); smb2_set_related(&rqst[2]);
rc = compound_send_recv(xid, ses, server, if (cfid) {
flags, 3, rqst, rc = compound_send_recv(xid, ses, server,
resp_buftype, rsp_iov); flags, 1, &rqst[1],
&resp_buftype[1], &rsp_iov[1]);
} else {
rc = compound_send_recv(xid, ses, server,
flags, 3, rqst,
resp_buftype, rsp_iov);
}
if (rc) { if (rc) {
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
if (rc == -EREMCHG) { if (rc == -EREMCHG) {
@ -2729,11 +2763,14 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
*buftype = resp_buftype[1]; *buftype = resp_buftype[1];
qic_exit: qic_exit:
kfree(utf16_path);
SMB2_open_free(&rqst[0]); SMB2_open_free(&rqst[0]);
SMB2_query_info_free(&rqst[1]); SMB2_query_info_free(&rqst[1]);
SMB2_close_free(&rqst[2]); SMB2_close_free(&rqst[2]);
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
if (cfid)
close_cached_dir(cfid);
return rc; return rc;
} }
@ -2743,13 +2780,12 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
{ {
struct smb2_query_info_rsp *rsp; struct smb2_query_info_rsp *rsp;
struct smb2_fs_full_size_info *info = NULL; struct smb2_fs_full_size_info *info = NULL;
__le16 utf16_path = 0; /* Null - open root of share */
struct kvec rsp_iov = {NULL, 0}; struct kvec rsp_iov = {NULL, 0};
int buftype = CIFS_NO_BUFFER; int buftype = CIFS_NO_BUFFER;
int rc; int rc;
rc = smb2_query_info_compound(xid, tcon, &utf16_path, rc = smb2_query_info_compound(xid, tcon, "",
FILE_READ_ATTRIBUTES, FILE_READ_ATTRIBUTES,
FS_FULL_SIZE_INFORMATION, FS_FULL_SIZE_INFORMATION,
SMB2_O_INFO_FILESYSTEM, SMB2_O_INFO_FILESYSTEM,
@ -4293,12 +4329,12 @@ static __le32
map_oplock_to_lease(u8 oplock) map_oplock_to_lease(u8 oplock)
{ {
if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING; return SMB2_LEASE_WRITE_CACHING_LE | SMB2_LEASE_READ_CACHING_LE;
else if (oplock == SMB2_OPLOCK_LEVEL_II) else if (oplock == SMB2_OPLOCK_LEVEL_II)
return SMB2_LEASE_READ_CACHING; return SMB2_LEASE_READ_CACHING_LE;
else if (oplock == SMB2_OPLOCK_LEVEL_BATCH) else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING | return SMB2_LEASE_HANDLE_CACHING_LE | SMB2_LEASE_READ_CACHING_LE |
SMB2_LEASE_WRITE_CACHING; SMB2_LEASE_WRITE_CACHING_LE;
return 0; return 0;
} }
@ -4360,7 +4396,7 @@ smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
struct create_lease *lc = (struct create_lease *)buf; struct create_lease *lc = (struct create_lease *)buf;
*epoch = 0; /* not used */ *epoch = 0; /* not used */
if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS) if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
return SMB2_OPLOCK_LEVEL_NOCHANGE; return SMB2_OPLOCK_LEVEL_NOCHANGE;
return le32_to_cpu(lc->lcontext.LeaseState); return le32_to_cpu(lc->lcontext.LeaseState);
} }
@ -4371,7 +4407,7 @@ smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
struct create_lease_v2 *lc = (struct create_lease_v2 *)buf; struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
*epoch = le16_to_cpu(lc->lcontext.Epoch); *epoch = le16_to_cpu(lc->lcontext.Epoch);
if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS) if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
return SMB2_OPLOCK_LEVEL_NOCHANGE; return SMB2_OPLOCK_LEVEL_NOCHANGE;
if (lease_key) if (lease_key)
memcpy(lease_key, &lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); memcpy(lease_key, &lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
@ -5814,8 +5850,8 @@ struct smb_version_values smb20_values = {
.protocol_id = SMB20_PROT_ID, .protocol_id = SMB20_PROT_ID,
.req_capabilities = 0, /* MBZ */ .req_capabilities = 0, /* MBZ */
.large_lock_type = 0, .large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, .shared_lock_type = SMB2_LOCKFLAG_SHARED,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr), .header_size = sizeof(struct smb2_hdr),
.header_preamble_size = 0, .header_preamble_size = 0,
@ -5835,8 +5871,8 @@ struct smb_version_values smb21_values = {
.protocol_id = SMB21_PROT_ID, .protocol_id = SMB21_PROT_ID,
.req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */ .req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */
.large_lock_type = 0, .large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, .shared_lock_type = SMB2_LOCKFLAG_SHARED,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr), .header_size = sizeof(struct smb2_hdr),
.header_preamble_size = 0, .header_preamble_size = 0,
@ -5856,8 +5892,8 @@ struct smb_version_values smb3any_values = {
.protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */ .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
.large_lock_type = 0, .large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, .shared_lock_type = SMB2_LOCKFLAG_SHARED,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr), .header_size = sizeof(struct smb2_hdr),
.header_preamble_size = 0, .header_preamble_size = 0,
@ -5877,8 +5913,8 @@ struct smb_version_values smbdefault_values = {
.protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */ .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
.large_lock_type = 0, .large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, .shared_lock_type = SMB2_LOCKFLAG_SHARED,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr), .header_size = sizeof(struct smb2_hdr),
.header_preamble_size = 0, .header_preamble_size = 0,
@ -5898,8 +5934,8 @@ struct smb_version_values smb30_values = {
.protocol_id = SMB30_PROT_ID, .protocol_id = SMB30_PROT_ID,
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
.large_lock_type = 0, .large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, .shared_lock_type = SMB2_LOCKFLAG_SHARED,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr), .header_size = sizeof(struct smb2_hdr),
.header_preamble_size = 0, .header_preamble_size = 0,
@ -5919,8 +5955,8 @@ struct smb_version_values smb302_values = {
.protocol_id = SMB302_PROT_ID, .protocol_id = SMB302_PROT_ID,
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
.large_lock_type = 0, .large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, .shared_lock_type = SMB2_LOCKFLAG_SHARED,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr), .header_size = sizeof(struct smb2_hdr),
.header_preamble_size = 0, .header_preamble_size = 0,
@ -5940,8 +5976,8 @@ struct smb_version_values smb311_values = {
.protocol_id = SMB311_PROT_ID, .protocol_id = SMB311_PROT_ID,
.req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
.large_lock_type = 0, .large_lock_type = 0,
.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
.shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, .shared_lock_type = SMB2_LOCKFLAG_SHARED,
.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK, .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
.header_size = sizeof(struct smb2_hdr), .header_size = sizeof(struct smb2_hdr),
.header_preamble_size = 0, .header_preamble_size = 0,

View file

@ -163,7 +163,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
return 0; return 0;
spin_lock(&cifs_tcp_ses_lock); spin_lock(&cifs_tcp_ses_lock);
if (tcon->tidStatus == CifsExiting) { if (tcon->status == TID_EXITING) {
/* /*
* only tree disconnect, open, and write, * only tree disconnect, open, and write,
* (and ulogoff which does not have tcon) * (and ulogoff which does not have tcon)
@ -2734,13 +2734,10 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
goto err_free_req; goto err_free_req;
} }
trace_smb3_posix_mkdir_done(xid, le64_to_cpu(rsp->PersistentFileId), trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
tcon->tid, CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES);
ses->Suid, CREATE_NOT_FILE,
FILE_WRITE_ATTRIBUTES);
SMB2_close(xid, tcon, le64_to_cpu(rsp->PersistentFileId), SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId);
le64_to_cpu(rsp->VolatileFileId));
/* Eventually save off posix specific response info and timestaps */ /* Eventually save off posix specific response info and timestaps */
@ -3009,14 +3006,12 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
} else if (rsp == NULL) /* unlikely to happen, but safer to check */ } else if (rsp == NULL) /* unlikely to happen, but safer to check */
goto creat_exit; goto creat_exit;
else else
trace_smb3_open_done(xid, le64_to_cpu(rsp->PersistentFileId), trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
tcon->tid, oparms->create_options, oparms->desired_access);
ses->Suid, oparms->create_options,
oparms->desired_access);
atomic_inc(&tcon->num_remote_opens); atomic_inc(&tcon->num_remote_opens);
oparms->fid->persistent_fid = le64_to_cpu(rsp->PersistentFileId); oparms->fid->persistent_fid = rsp->PersistentFileId;
oparms->fid->volatile_fid = le64_to_cpu(rsp->VolatileFileId); oparms->fid->volatile_fid = rsp->VolatileFileId;
oparms->fid->access = oparms->desired_access; oparms->fid->access = oparms->desired_access;
#ifdef CONFIG_CIFS_DEBUG2 #ifdef CONFIG_CIFS_DEBUG2
oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId); oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId);
@ -3313,8 +3308,8 @@ SMB2_close_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
if (rc) if (rc)
return rc; return rc;
req->PersistentFileId = cpu_to_le64(persistent_fid); req->PersistentFileId = persistent_fid;
req->VolatileFileId = cpu_to_le64(volatile_fid); req->VolatileFileId = volatile_fid;
if (query_attrs) if (query_attrs)
req->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB; req->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
else else
@ -3677,8 +3672,8 @@ SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst,
if (rc) if (rc)
return rc; return rc;
req->PersistentFileId = cpu_to_le64(persistent_fid); req->PersistentFileId = persistent_fid;
req->VolatileFileId = cpu_to_le64(volatile_fid); req->VolatileFileId = volatile_fid;
/* See note 354 of MS-SMB2, 64K max */ /* See note 354 of MS-SMB2, 64K max */
req->OutputBufferLength = req->OutputBufferLength =
cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE); cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE);
@ -3858,12 +3853,14 @@ void smb2_reconnect_server(struct work_struct *work)
tcon = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL); tcon = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
if (!tcon) { if (!tcon) {
resched = true; resched = true;
list_del_init(&ses->rlist); list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) {
cifs_put_smb_ses(ses); list_del_init(&ses->rlist);
cifs_put_smb_ses(ses);
}
goto done; goto done;
} }
tcon->tidStatus = CifsGood; tcon->status = TID_GOOD;
tcon->retry = false; tcon->retry = false;
tcon->need_reconnect = false; tcon->need_reconnect = false;
@ -3951,8 +3948,8 @@ SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
if (rc) if (rc)
return rc; return rc;
req->PersistentFileId = cpu_to_le64(persistent_fid); req->PersistentFileId = persistent_fid;
req->VolatileFileId = cpu_to_le64(volatile_fid); req->VolatileFileId = volatile_fid;
iov[0].iov_base = (char *)req; iov[0].iov_base = (char *)req;
iov[0].iov_len = total_len; iov[0].iov_len = total_len;
@ -4033,8 +4030,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
shdr = &req->hdr; shdr = &req->hdr;
shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid); shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
req->PersistentFileId = cpu_to_le64(io_parms->persistent_fid); req->PersistentFileId = io_parms->persistent_fid;
req->VolatileFileId = cpu_to_le64(io_parms->volatile_fid); req->VolatileFileId = io_parms->volatile_fid;
req->ReadChannelInfoOffset = 0; /* reserved */ req->ReadChannelInfoOffset = 0; /* reserved */
req->ReadChannelInfoLength = 0; /* reserved */ req->ReadChannelInfoLength = 0; /* reserved */
req->Channel = 0; /* reserved */ req->Channel = 0; /* reserved */
@ -4094,8 +4091,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
*/ */
shdr->SessionId = cpu_to_le64(0xFFFFFFFFFFFFFFFF); shdr->SessionId = cpu_to_le64(0xFFFFFFFFFFFFFFFF);
shdr->Id.SyncId.TreeId = cpu_to_le32(0xFFFFFFFF); shdr->Id.SyncId.TreeId = cpu_to_le32(0xFFFFFFFF);
req->PersistentFileId = cpu_to_le64(0xFFFFFFFFFFFFFFFF); req->PersistentFileId = (u64)-1;
req->VolatileFileId = cpu_to_le64(0xFFFFFFFFFFFFFFFF); req->VolatileFileId = (u64)-1;
} }
} }
if (remaining_bytes > io_parms->length) if (remaining_bytes > io_parms->length)
@ -4307,21 +4304,19 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE);
cifs_dbg(VFS, "Send error in read = %d\n", rc); cifs_dbg(VFS, "Send error in read = %d\n", rc);
trace_smb3_read_err(xid, trace_smb3_read_err(xid,
le64_to_cpu(req->PersistentFileId), req->PersistentFileId,
io_parms->tcon->tid, ses->Suid, io_parms->tcon->tid, ses->Suid,
io_parms->offset, io_parms->length, io_parms->offset, io_parms->length,
rc); rc);
} else } else
trace_smb3_read_done(xid, trace_smb3_read_done(xid, req->PersistentFileId, io_parms->tcon->tid,
le64_to_cpu(req->PersistentFileId), ses->Suid, io_parms->offset, 0);
io_parms->tcon->tid, ses->Suid,
io_parms->offset, 0);
free_rsp_buf(resp_buftype, rsp_iov.iov_base); free_rsp_buf(resp_buftype, rsp_iov.iov_base);
cifs_small_buf_release(req); cifs_small_buf_release(req);
return rc == -ENODATA ? 0 : rc; return rc == -ENODATA ? 0 : rc;
} else } else
trace_smb3_read_done(xid, trace_smb3_read_done(xid,
le64_to_cpu(req->PersistentFileId), req->PersistentFileId,
io_parms->tcon->tid, ses->Suid, io_parms->tcon->tid, ses->Suid,
io_parms->offset, io_parms->length); io_parms->offset, io_parms->length);
@ -4463,8 +4458,8 @@ smb2_async_writev(struct cifs_writedata *wdata,
shdr = (struct smb2_hdr *)req; shdr = (struct smb2_hdr *)req;
shdr->Id.SyncId.ProcessId = cpu_to_le32(wdata->cfile->pid); shdr->Id.SyncId.ProcessId = cpu_to_le32(wdata->cfile->pid);
req->PersistentFileId = cpu_to_le64(wdata->cfile->fid.persistent_fid); req->PersistentFileId = wdata->cfile->fid.persistent_fid;
req->VolatileFileId = cpu_to_le64(wdata->cfile->fid.volatile_fid); req->VolatileFileId = wdata->cfile->fid.volatile_fid;
req->WriteChannelInfoOffset = 0; req->WriteChannelInfoOffset = 0;
req->WriteChannelInfoLength = 0; req->WriteChannelInfoLength = 0;
req->Channel = 0; req->Channel = 0;
@ -4562,7 +4557,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
if (rc) { if (rc) {
trace_smb3_write_err(0 /* no xid */, trace_smb3_write_err(0 /* no xid */,
le64_to_cpu(req->PersistentFileId), req->PersistentFileId,
tcon->tid, tcon->ses->Suid, wdata->offset, tcon->tid, tcon->ses->Suid, wdata->offset,
wdata->bytes, rc); wdata->bytes, rc);
kref_put(&wdata->refcount, release); kref_put(&wdata->refcount, release);
@ -4615,8 +4610,8 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
req->hdr.Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid); req->hdr.Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
req->PersistentFileId = cpu_to_le64(io_parms->persistent_fid); req->PersistentFileId = io_parms->persistent_fid;
req->VolatileFileId = cpu_to_le64(io_parms->volatile_fid); req->VolatileFileId = io_parms->volatile_fid;
req->WriteChannelInfoOffset = 0; req->WriteChannelInfoOffset = 0;
req->WriteChannelInfoLength = 0; req->WriteChannelInfoLength = 0;
req->Channel = 0; req->Channel = 0;
@ -4645,7 +4640,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
if (rc) { if (rc) {
trace_smb3_write_err(xid, trace_smb3_write_err(xid,
le64_to_cpu(req->PersistentFileId), req->PersistentFileId,
io_parms->tcon->tid, io_parms->tcon->tid,
io_parms->tcon->ses->Suid, io_parms->tcon->ses->Suid,
io_parms->offset, io_parms->length, rc); io_parms->offset, io_parms->length, rc);
@ -4654,7 +4649,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
} else { } else {
*nbytes = le32_to_cpu(rsp->DataLength); *nbytes = le32_to_cpu(rsp->DataLength);
trace_smb3_write_done(xid, trace_smb3_write_done(xid,
le64_to_cpu(req->PersistentFileId), req->PersistentFileId,
io_parms->tcon->tid, io_parms->tcon->tid,
io_parms->tcon->ses->Suid, io_parms->tcon->ses->Suid,
io_parms->offset, *nbytes); io_parms->offset, *nbytes);

View file

@ -56,16 +56,6 @@ struct smb2_rdma_crypto_transform {
#define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL #define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL
#define SMB2_ERROR_STRUCTURE_SIZE2 cpu_to_le16(9)
struct smb2_err_rsp {
struct smb2_hdr hdr;
__le16 StructureSize;
__le16 Reserved; /* MBZ */
__le32 ByteCount; /* even if zero, at least one byte follows */
__u8 ErrorData[1]; /* variable length */
} __packed;
#define SYMLINK_ERROR_TAG 0x4c4d5953 #define SYMLINK_ERROR_TAG 0x4c4d5953
struct smb2_symlink_err_rsp { struct smb2_symlink_err_rsp {
@ -139,47 +129,6 @@ struct share_redirect_error_context_rsp {
#define SMB2_LEASE_HANDLE_CACHING_HE 0x02 #define SMB2_LEASE_HANDLE_CACHING_HE 0x02
#define SMB2_LEASE_WRITE_CACHING_HE 0x04 #define SMB2_LEASE_WRITE_CACHING_HE 0x04
#define SMB2_LEASE_NONE cpu_to_le32(0x00)
#define SMB2_LEASE_READ_CACHING cpu_to_le32(0x01)
#define SMB2_LEASE_HANDLE_CACHING cpu_to_le32(0x02)
#define SMB2_LEASE_WRITE_CACHING cpu_to_le32(0x04)
#define SMB2_LEASE_FLAG_BREAK_IN_PROGRESS cpu_to_le32(0x00000002)
#define SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET cpu_to_le32(0x00000004)
#define SMB2_LEASE_KEY_SIZE 16
struct lease_context {
u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
__le32 LeaseFlags;
__le64 LeaseDuration;
} __packed;
struct lease_context_v2 {
u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
__le32 LeaseFlags;
__le64 LeaseDuration;
__le64 ParentLeaseKeyLow;
__le64 ParentLeaseKeyHigh;
__le16 Epoch;
__le16 Reserved;
} __packed;
struct create_lease {
struct create_context ccontext;
__u8 Name[8];
struct lease_context lcontext;
} __packed;
struct create_lease_v2 {
struct create_context ccontext;
__u8 Name[8];
struct lease_context_v2 lcontext;
__u8 Pad[4];
} __packed;
struct create_durable { struct create_durable {
struct create_context ccontext; struct create_context ccontext;
__u8 Name[8]; __u8 Name[8];
@ -192,13 +141,6 @@ struct create_durable {
} Data; } Data;
} __packed; } __packed;
struct create_posix {
struct create_context ccontext;
__u8 Name[16];
__le32 Mode;
__u32 Reserved;
} __packed;
/* See MS-SMB2 2.2.13.2.11 */ /* See MS-SMB2 2.2.13.2.11 */
/* Flags */ /* Flags */
#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002 #define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
@ -287,12 +229,6 @@ struct copychunk_ioctl {
__u32 Reserved2; __u32 Reserved2;
} __packed; } __packed;
/* this goes in the ioctl buffer when doing FSCTL_SET_ZERO_DATA */
struct file_zero_data_information {
__le64 FileOffset;
__le64 BeyondFinalZero;
} __packed;
struct copychunk_ioctl_rsp { struct copychunk_ioctl_rsp {
__le32 ChunksWritten; __le32 ChunksWritten;
__le32 ChunkBytesWritten; __le32 ChunkBytesWritten;
@ -338,11 +274,6 @@ struct fsctl_get_integrity_information_rsp {
__le32 ClusterSizeInBytes; __le32 ClusterSizeInBytes;
} __packed; } __packed;
struct file_allocated_range_buffer {
__le64 file_offset;
__le64 length;
} __packed;
/* Integrity ChecksumAlgorithm choices for above */ /* Integrity ChecksumAlgorithm choices for above */
#define CHECKSUM_TYPE_NONE 0x0000 #define CHECKSUM_TYPE_NONE 0x0000
#define CHECKSUM_TYPE_CRC64 0x0002 #define CHECKSUM_TYPE_CRC64 0x0002
@ -351,53 +282,6 @@ struct file_allocated_range_buffer {
/* Integrity flags for above */ /* Integrity flags for above */
#define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001
/* Reparse structures - see MS-FSCC 2.1.2 */
/* struct fsctl_reparse_info_req is empty, only response structs (see below) */
struct reparse_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 DataBuffer[]; /* Variable Length */
} __packed;
struct reparse_guid_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 ReparseGuid[16];
__u8 DataBuffer[]; /* Variable Length */
} __packed;
struct reparse_mount_point_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__le16 SubstituteNameOffset;
__le16 SubstituteNameLength;
__le16 PrintNameOffset;
__le16 PrintNameLength;
__u8 PathBuffer[]; /* Variable Length */
} __packed;
#define SYMLINK_FLAG_RELATIVE 0x00000001
struct reparse_symlink_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__le16 SubstituteNameOffset;
__le16 SubstituteNameLength;
__le16 PrintNameOffset;
__le16 PrintNameLength;
__le32 Flags;
__u8 PathBuffer[]; /* Variable Length */
} __packed;
/* See MS-FSCC 2.1.2.6 and cifspdu.h for struct reparse_posix_data */
/* See MS-DFSC 2.2.2 */ /* See MS-DFSC 2.2.2 */
struct fsctl_get_dfs_referral_req { struct fsctl_get_dfs_referral_req {
__le16 MaxReferralLevel; __le16 MaxReferralLevel;
@ -413,22 +297,6 @@ struct network_resiliency_req {
} __packed; } __packed;
/* There is no buffer for the response ie no struct network_resiliency_rsp */ /* There is no buffer for the response ie no struct network_resiliency_rsp */
struct validate_negotiate_info_req {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 DialectCount;
__le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
} __packed;
struct validate_negotiate_info_rsp {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 Dialect; /* Dialect in use for the connection */
} __packed;
#define RSS_CAPABLE cpu_to_le32(0x00000001) #define RSS_CAPABLE cpu_to_le32(0x00000001)
#define RDMA_CAPABLE cpu_to_le32(0x00000002) #define RDMA_CAPABLE cpu_to_le32(0x00000002)
@ -464,14 +332,6 @@ struct compress_ioctl {
__le16 CompressionState; /* See cifspdu.h for possible flag values */ __le16 CompressionState; /* See cifspdu.h for possible flag values */
} __packed; } __packed;
struct duplicate_extents_to_file {
__u64 PersistentFileHandle; /* source file handle, opaque endianness */
__u64 VolatileFileHandle;
__le64 SourceFileOffset;
__le64 TargetFileOffset;
__le64 ByteCount; /* Bytes to be copied */
} __packed;
/* /*
* Maximum number of iovs we need for an ioctl request. * Maximum number of iovs we need for an ioctl request.
* [0] : struct smb2_ioctl_req * [0] : struct smb2_ioctl_req
@ -479,370 +339,11 @@ struct duplicate_extents_to_file {
*/ */
#define SMB2_IOCTL_IOV_SIZE 2 #define SMB2_IOCTL_IOV_SIZE 2
struct smb2_ioctl_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 57 */
__u16 Reserved;
__le32 CtlCode;
__u64 PersistentFileId; /* opaque endianness */
__u64 VolatileFileId; /* opaque endianness */
__le32 InputOffset;
__le32 InputCount;
__le32 MaxInputResponse;
__le32 OutputOffset;
__le32 OutputCount;
__le32 MaxOutputResponse;
__le32 Flags;
__u32 Reserved2;
__u8 Buffer[];
} __packed;
struct smb2_ioctl_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 57 */
__u16 Reserved;
__le32 CtlCode;
__u64 PersistentFileId; /* opaque endianness */
__u64 VolatileFileId; /* opaque endianness */
__le32 InputOffset;
__le32 InputCount;
__le32 OutputOffset;
__le32 OutputCount;
__le32 Flags;
__u32 Reserved2;
/* char * buffer[] */
} __packed;
#define SMB2_LOCKFLAG_SHARED_LOCK 0x0001
#define SMB2_LOCKFLAG_EXCLUSIVE_LOCK 0x0002
#define SMB2_LOCKFLAG_UNLOCK 0x0004
#define SMB2_LOCKFLAG_FAIL_IMMEDIATELY 0x0010
struct smb2_lock_element {
__le64 Offset;
__le64 Length;
__le32 Flags;
__le32 Reserved;
} __packed;
struct smb2_lock_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 48 */
__le16 LockCount;
/*
* The least significant four bits are the index, the other 28 bits are
* the lock sequence number (0 to 64). See MS-SMB2 2.2.26
*/
__le32 LockSequenceNumber;
__u64 PersistentFileId; /* opaque endianness */
__u64 VolatileFileId; /* opaque endianness */
/* Followed by at least one */
struct smb2_lock_element locks[1];
} __packed;
struct smb2_lock_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__le16 Reserved;
} __packed;
struct smb2_echo_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__u16 Reserved;
} __packed;
struct smb2_echo_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__u16 Reserved;
} __packed;
/* search (query_directory) Flags field */
#define SMB2_RESTART_SCANS 0x01
#define SMB2_RETURN_SINGLE_ENTRY 0x02
#define SMB2_INDEX_SPECIFIED 0x04
#define SMB2_REOPEN 0x10
#define SMB2_QUERY_DIRECTORY_IOV_SIZE 2
/* /*
* Valid FileInformation classes. * PDU query infolevel structure definitions
*
* Note that these are a subset of the (file) QUERY_INFO levels defined
* later in this file (but since QUERY_DIRECTORY uses equivalent numbers
* we do not redefine them here)
*
* FileDirectoryInfomation 0x01
* FileFullDirectoryInformation 0x02
* FileIdFullDirectoryInformation 0x26
* FileBothDirectoryInformation 0x03
* FileIdBothDirectoryInformation 0x25
* FileNamesInformation 0x0C
* FileIdExtdDirectoryInformation 0x3C
*/
struct smb2_query_directory_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 33 */
__u8 FileInformationClass;
__u8 Flags;
__le32 FileIndex;
__u64 PersistentFileId; /* opaque endianness */
__u64 VolatileFileId; /* opaque endianness */
__le16 FileNameOffset;
__le16 FileNameLength;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
struct smb2_query_directory_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
/* Possible InfoType values */
#define SMB2_O_INFO_FILE 0x01
#define SMB2_O_INFO_FILESYSTEM 0x02
#define SMB2_O_INFO_SECURITY 0x03
#define SMB2_O_INFO_QUOTA 0x04
/* Security info type additionalinfo flags. See MS-SMB2 (2.2.37) or MS-DTYP */
#define OWNER_SECINFO 0x00000001
#define GROUP_SECINFO 0x00000002
#define DACL_SECINFO 0x00000004
#define SACL_SECINFO 0x00000008
#define LABEL_SECINFO 0x00000010
#define ATTRIBUTE_SECINFO 0x00000020
#define SCOPE_SECINFO 0x00000040
#define BACKUP_SECINFO 0x00010000
#define UNPROTECTED_SACL_SECINFO 0x10000000
#define UNPROTECTED_DACL_SECINFO 0x20000000
#define PROTECTED_SACL_SECINFO 0x40000000
#define PROTECTED_DACL_SECINFO 0x80000000
/* Flags used for FileFullEAinfo */
#define SL_RESTART_SCAN 0x00000001
#define SL_RETURN_SINGLE_ENTRY 0x00000002
#define SL_INDEX_SPECIFIED 0x00000004
struct smb2_query_info_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 41 */
__u8 InfoType;
__u8 FileInfoClass;
__le32 OutputBufferLength;
__le16 InputBufferOffset;
__u16 Reserved;
__le32 InputBufferLength;
__le32 AdditionalInformation;
__le32 Flags;
__u64 PersistentFileId; /* opaque endianness */
__u64 VolatileFileId; /* opaque endianness */
__u8 Buffer[1];
} __packed;
struct smb2_query_info_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
/*
* Maximum number of iovs we need for a set-info request.
* The largest one is rename/hardlink
* [0] : struct smb2_set_info_req + smb2_file_[rename|link]_info
* [1] : path
* [2] : compound padding
*/
#define SMB2_SET_INFO_IOV_SIZE 3
struct smb2_set_info_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 33 */
__u8 InfoType;
__u8 FileInfoClass;
__le32 BufferLength;
__le16 BufferOffset;
__u16 Reserved;
__le32 AdditionalInformation;
__u64 PersistentFileId; /* opaque endianness */
__u64 VolatileFileId; /* opaque endianness */
__u8 Buffer[1];
} __packed;
struct smb2_set_info_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 2 */
} __packed;
struct smb2_oplock_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 24 */
__u8 OplockLevel;
__u8 Reserved;
__le32 Reserved2;
__u64 PersistentFid;
__u64 VolatileFid;
} __packed;
#define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED cpu_to_le32(0x01)
struct smb2_lease_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 44 */
__le16 Epoch;
__le32 Flags;
__u8 LeaseKey[16];
__le32 CurrentLeaseState;
__le32 NewLeaseState;
__le32 BreakReason;
__le32 AccessMaskHint;
__le32 ShareMaskHint;
} __packed;
struct smb2_lease_ack {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 36 */
__le16 Reserved;
__le32 Flags;
__u8 LeaseKey[16];
__le32 LeaseState;
__le64 LeaseDuration;
} __packed;
/*
* PDU infolevel structure definitions
* BB consider moving to a different header * BB consider moving to a different header
*/ */
/* File System Information Classes */
#define FS_VOLUME_INFORMATION 1 /* Query */
#define FS_LABEL_INFORMATION 2 /* Local only */
#define FS_SIZE_INFORMATION 3 /* Query */
#define FS_DEVICE_INFORMATION 4 /* Query */
#define FS_ATTRIBUTE_INFORMATION 5 /* Query */
#define FS_CONTROL_INFORMATION 6 /* Query, Set */
#define FS_FULL_SIZE_INFORMATION 7 /* Query */
#define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */
#define FS_DRIVER_PATH_INFORMATION 9 /* Local only */
#define FS_VOLUME_FLAGS_INFORMATION 10 /* Local only */
#define FS_SECTOR_SIZE_INFORMATION 11 /* SMB3 or later. Query */
#define FS_POSIX_INFORMATION 100 /* SMB3.1.1 POSIX. Query */
struct smb2_fs_full_size_info {
__le64 TotalAllocationUnits;
__le64 CallerAvailableAllocationUnits;
__le64 ActualAvailableAllocationUnits;
__le32 SectorsPerAllocationUnit;
__le32 BytesPerSector;
} __packed;
#define SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001
#define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002
#define SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004
#define SSINFO_FLAGS_TRIM_ENABLED 0x00000008
/* sector size info struct */
struct smb3_fs_ss_info {
__le32 LogicalBytesPerSector;
__le32 PhysicalBytesPerSectorForAtomicity;
__le32 PhysicalBytesPerSectorForPerf;
__le32 FileSystemEffectivePhysicalBytesPerSectorForAtomicity;
__le32 Flags;
__le32 ByteOffsetForSectorAlignment;
__le32 ByteOffsetForPartitionAlignment;
} __packed;
/* volume info struct - see MS-FSCC 2.5.9 */
#define MAX_VOL_LABEL_LEN 32
struct smb3_fs_vol_info {
__le64 VolumeCreationTime;
__u32 VolumeSerialNumber;
__le32 VolumeLabelLength; /* includes trailing null */
__u8 SupportsObjects; /* True if eg like NTFS, supports objects */
__u8 Reserved;
__u8 VolumeLabel[]; /* variable len */
} __packed;
/* partial list of QUERY INFO levels */
#define FILE_DIRECTORY_INFORMATION 1
#define FILE_FULL_DIRECTORY_INFORMATION 2
#define FILE_BOTH_DIRECTORY_INFORMATION 3
#define FILE_BASIC_INFORMATION 4
#define FILE_STANDARD_INFORMATION 5
#define FILE_INTERNAL_INFORMATION 6
#define FILE_EA_INFORMATION 7
#define FILE_ACCESS_INFORMATION 8
#define FILE_NAME_INFORMATION 9
#define FILE_RENAME_INFORMATION 10
#define FILE_LINK_INFORMATION 11
#define FILE_NAMES_INFORMATION 12
#define FILE_DISPOSITION_INFORMATION 13
#define FILE_POSITION_INFORMATION 14
#define FILE_FULL_EA_INFORMATION 15
#define FILE_MODE_INFORMATION 16
#define FILE_ALIGNMENT_INFORMATION 17
#define FILE_ALL_INFORMATION 18
#define FILE_ALLOCATION_INFORMATION 19
#define FILE_END_OF_FILE_INFORMATION 20
#define FILE_ALTERNATE_NAME_INFORMATION 21
#define FILE_STREAM_INFORMATION 22
#define FILE_PIPE_INFORMATION 23
#define FILE_PIPE_LOCAL_INFORMATION 24
#define FILE_PIPE_REMOTE_INFORMATION 25
#define FILE_MAILSLOT_QUERY_INFORMATION 26
#define FILE_MAILSLOT_SET_INFORMATION 27
#define FILE_COMPRESSION_INFORMATION 28
#define FILE_OBJECT_ID_INFORMATION 29
/* Number 30 not defined in documents */
#define FILE_MOVE_CLUSTER_INFORMATION 31
#define FILE_QUOTA_INFORMATION 32
#define FILE_REPARSE_POINT_INFORMATION 33
#define FILE_NETWORK_OPEN_INFORMATION 34
#define FILE_ATTRIBUTE_TAG_INFORMATION 35
#define FILE_TRACKING_INFORMATION 36
#define FILEID_BOTH_DIRECTORY_INFORMATION 37
#define FILEID_FULL_DIRECTORY_INFORMATION 38
#define FILE_VALID_DATA_LENGTH_INFORMATION 39
#define FILE_SHORT_NAME_INFORMATION 40
#define FILE_SFIO_RESERVE_INFORMATION 44
#define FILE_SFIO_VOLUME_INFORMATION 45
#define FILE_HARD_LINK_INFORMATION 46
#define FILE_NORMALIZED_NAME_INFORMATION 48
#define FILEID_GLOBAL_TX_DIRECTORY_INFORMATION 50
#define FILE_STANDARD_LINK_INFORMATION 54
#define FILE_ID_INFORMATION 59
#define FILE_ID_EXTD_DIRECTORY_INFORMATION 60
struct smb2_file_internal_info {
__le64 IndexNumber;
} __packed; /* level 6 Query */
struct smb2_file_rename_info { /* encoding of request for level 10 */
__u8 ReplaceIfExists; /* 1 = replace existing target with new */
/* 0 = fail if target already exists */
__u8 Reserved[7];
__u64 RootDirectory; /* MBZ for network operations (why says spec?) */
__le32 FileNameLength;
char FileName[]; /* New name to be assigned */
/* padding - overall struct size must be >= 24 so filename + pad >= 6 */
} __packed; /* level 10 Set */
struct smb2_file_link_info { /* encoding of request for level 11 */
__u8 ReplaceIfExists; /* 1 = replace existing link with new */
/* 0 = fail if link already exists */
__u8 Reserved[7];
__u64 RootDirectory; /* MBZ for network operations (why says spec?) */
__le32 FileNameLength;
char FileName[]; /* Name to be assigned to new link */
} __packed; /* level 11 Set */
struct smb2_file_full_ea_info { /* encoding of response for level 15 */ struct smb2_file_full_ea_info { /* encoding of response for level 15 */
__le32 next_entry_offset; __le32 next_entry_offset;
__u8 flags; __u8 flags;
@ -851,38 +352,6 @@ struct smb2_file_full_ea_info { /* encoding of response for level 15 */
char ea_data[]; /* \0 terminated name plus value */ char ea_data[]; /* \0 terminated name plus value */
} __packed; /* level 15 Set */ } __packed; /* level 15 Set */
/*
* This level 18, although with struct with same name is different from cifs
* level 0x107. Level 0x107 has an extra u64 between AccessFlags and
* CurrentByteOffset.
*/
struct smb2_file_all_info { /* data block encoding of response to level 18 */
__le64 CreationTime; /* Beginning of FILE_BASIC_INFO equivalent */
__le64 LastAccessTime;
__le64 LastWriteTime;
__le64 ChangeTime;
__le32 Attributes;
__u32 Pad1; /* End of FILE_BASIC_INFO_INFO equivalent */
__le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */
__le64 EndOfFile; /* size ie offset to first free byte in file */
__le32 NumberOfLinks; /* hard links */
__u8 DeletePending;
__u8 Directory;
__u16 Pad2; /* End of FILE_STANDARD_INFO equivalent */
__le64 IndexNumber;
__le32 EASize;
__le32 AccessFlags;
__le64 CurrentByteOffset;
__le32 Mode;
__le32 AlignmentRequirement;
__le32 FileNameLength;
char FileName[1];
} __packed; /* level 18 Query */
struct smb2_file_eof_info { /* encoding of request for level 10 */
__le64 EndOfFile; /* new end of file value */
} __packed; /* level 20 Set */
struct smb2_file_reparse_point_info { struct smb2_file_reparse_point_info {
__le64 IndexNumber; __le64 IndexNumber;
__le32 Tag; __le32 Tag;
@ -935,6 +404,8 @@ struct create_posix_rsp {
struct cifs_sid group; /* var-sized on the wire */ struct cifs_sid group; /* var-sized on the wire */
} __packed; } __packed;
#define SMB2_QUERY_DIRECTORY_IOV_SIZE 2
/* /*
* SMB2-only POSIX info level for query dir * SMB2-only POSIX info level for query dir
* *
@ -966,31 +437,6 @@ struct smb2_posix_info {
*/ */
} __packed; } __packed;
/* Level 100 query info */
struct smb311_posix_qinfo {
__le64 CreationTime;
__le64 LastAccessTime;
__le64 LastWriteTime;
__le64 ChangeTime;
__le64 EndOfFile;
__le64 AllocationSize;
__le32 DosAttributes;
__le64 Inode;
__le32 DeviceId;
__le32 Zero;
/* beginning of POSIX Create Context Response */
__le32 HardLinks;
__le32 ReparseTag;
__le32 Mode;
u8 Sids[];
/*
* var sized owner SID
* var sized group SID
* le32 filenamelength
* u8 filename[]
*/
} __packed;
/* /*
* Parsed version of the above struct. Allows direct access to the * Parsed version of the above struct. Allows direct access to the
* variable length fields * variable length fields

View file

@ -283,7 +283,7 @@ extern int smb311_update_preauth_hash(struct cifs_ses *ses,
struct kvec *iov, int nvec); struct kvec *iov, int nvec);
extern int smb2_query_info_compound(const unsigned int xid, extern int smb2_query_info_compound(const unsigned int xid,
struct cifs_tcon *tcon, struct cifs_tcon *tcon,
__le16 *utf16_path, u32 desired_access, const char *path, u32 desired_access,
u32 class, u32 type, u32 output_len, u32 class, u32 type, u32 output_len,
struct kvec *rsp, int *buftype, struct kvec *rsp, int *buftype,
struct cifs_sb_info *cifs_sb); struct cifs_sb_info *cifs_sb);

View file

@ -656,8 +656,8 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE; rsp->OplockLevel = SMB2_OPLOCK_LEVEL_NONE;
rsp->Reserved = 0; rsp->Reserved = 0;
rsp->Reserved2 = 0; rsp->Reserved2 = 0;
rsp->PersistentFid = cpu_to_le64(fp->persistent_id); rsp->PersistentFid = fp->persistent_id;
rsp->VolatileFid = cpu_to_le64(fp->volatile_id); rsp->VolatileFid = fp->volatile_id;
inc_rfc1001_len(work->response_buf, 24); inc_rfc1001_len(work->response_buf, 24);

View file

@ -377,12 +377,8 @@ static void init_chained_smb2_rsp(struct ksmbd_work *work)
* command in the compound request * command in the compound request
*/ */
if (req->Command == SMB2_CREATE && rsp->Status == STATUS_SUCCESS) { if (req->Command == SMB2_CREATE && rsp->Status == STATUS_SUCCESS) {
work->compound_fid = work->compound_fid = ((struct smb2_create_rsp *)rsp)->VolatileFileId;
le64_to_cpu(((struct smb2_create_rsp *)rsp)-> work->compound_pfid = ((struct smb2_create_rsp *)rsp)->PersistentFileId;
VolatileFileId);
work->compound_pfid =
le64_to_cpu(((struct smb2_create_rsp *)rsp)->
PersistentFileId);
work->compound_sid = le64_to_cpu(rsp->SessionId); work->compound_sid = le64_to_cpu(rsp->SessionId);
} }
@ -2129,7 +2125,7 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work)
rsp->EndofFile = cpu_to_le64(0); rsp->EndofFile = cpu_to_le64(0);
rsp->FileAttributes = FILE_ATTRIBUTE_NORMAL_LE; rsp->FileAttributes = FILE_ATTRIBUTE_NORMAL_LE;
rsp->Reserved2 = 0; rsp->Reserved2 = 0;
rsp->VolatileFileId = cpu_to_le64(id); rsp->VolatileFileId = id;
rsp->PersistentFileId = 0; rsp->PersistentFileId = 0;
rsp->CreateContextsOffset = 0; rsp->CreateContextsOffset = 0;
rsp->CreateContextsLength = 0; rsp->CreateContextsLength = 0;
@ -3157,8 +3153,8 @@ int smb2_open(struct ksmbd_work *work)
rsp->Reserved2 = 0; rsp->Reserved2 = 0;
rsp->PersistentFileId = cpu_to_le64(fp->persistent_id); rsp->PersistentFileId = fp->persistent_id;
rsp->VolatileFileId = cpu_to_le64(fp->volatile_id); rsp->VolatileFileId = fp->volatile_id;
rsp->CreateContextsOffset = 0; rsp->CreateContextsOffset = 0;
rsp->CreateContextsLength = 0; rsp->CreateContextsLength = 0;
@ -3865,9 +3861,7 @@ int smb2_query_dir(struct ksmbd_work *work)
goto err_out2; goto err_out2;
} }
dir_fp = ksmbd_lookup_fd_slow(work, dir_fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId));
if (!dir_fp) { if (!dir_fp) {
rc = -EBADF; rc = -EBADF;
goto err_out2; goto err_out2;
@ -4088,12 +4082,12 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
* Windows can sometime send query file info request on * Windows can sometime send query file info request on
* pipe without opening it, checking error condition here * pipe without opening it, checking error condition here
*/ */
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
if (!ksmbd_session_rpc_method(sess, id)) if (!ksmbd_session_rpc_method(sess, id))
return -ENOENT; return -ENOENT;
ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n", ksmbd_debug(SMB, "FileInfoClass %u, FileId 0x%llx\n",
req->FileInfoClass, le64_to_cpu(req->VolatileFileId)); req->FileInfoClass, req->VolatileFileId);
switch (req->FileInfoClass) { switch (req->FileInfoClass) {
case FILE_STANDARD_INFORMATION: case FILE_STANDARD_INFORMATION:
@ -4738,7 +4732,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
} }
if (work->next_smb2_rcv_hdr_off) { if (work->next_smb2_rcv_hdr_off) {
if (!has_file_id(le64_to_cpu(req->VolatileFileId))) { if (!has_file_id(req->VolatileFileId)) {
ksmbd_debug(SMB, "Compound request set FID = %llu\n", ksmbd_debug(SMB, "Compound request set FID = %llu\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
@ -4747,8 +4741,8 @@ static int smb2_get_info_file(struct ksmbd_work *work,
} }
if (!has_file_id(id)) { if (!has_file_id(id)) {
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
pid = le64_to_cpu(req->PersistentFileId); pid = req->PersistentFileId;
} }
fp = ksmbd_lookup_fd_slow(work, id, pid); fp = ksmbd_lookup_fd_slow(work, id, pid);
@ -5113,7 +5107,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
} }
if (work->next_smb2_rcv_hdr_off) { if (work->next_smb2_rcv_hdr_off) {
if (!has_file_id(le64_to_cpu(req->VolatileFileId))) { if (!has_file_id(req->VolatileFileId)) {
ksmbd_debug(SMB, "Compound request set FID = %llu\n", ksmbd_debug(SMB, "Compound request set FID = %llu\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
@ -5122,8 +5116,8 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
} }
if (!has_file_id(id)) { if (!has_file_id(id)) {
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
pid = le64_to_cpu(req->PersistentFileId); pid = req->PersistentFileId;
} }
fp = ksmbd_lookup_fd_slow(work, id, pid); fp = ksmbd_lookup_fd_slow(work, id, pid);
@ -5221,7 +5215,7 @@ static noinline int smb2_close_pipe(struct ksmbd_work *work)
struct smb2_close_req *req = smb2_get_msg(work->request_buf); struct smb2_close_req *req = smb2_get_msg(work->request_buf);
struct smb2_close_rsp *rsp = smb2_get_msg(work->response_buf); struct smb2_close_rsp *rsp = smb2_get_msg(work->response_buf);
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
ksmbd_session_rpc_close(work->sess, id); ksmbd_session_rpc_close(work->sess, id);
rsp->StructureSize = cpu_to_le16(60); rsp->StructureSize = cpu_to_le16(60);
@ -5280,7 +5274,7 @@ int smb2_close(struct ksmbd_work *work)
} }
if (work->next_smb2_rcv_hdr_off && if (work->next_smb2_rcv_hdr_off &&
!has_file_id(le64_to_cpu(req->VolatileFileId))) { !has_file_id(req->VolatileFileId)) {
if (!has_file_id(work->compound_fid)) { if (!has_file_id(work->compound_fid)) {
/* file already closed, return FILE_CLOSED */ /* file already closed, return FILE_CLOSED */
ksmbd_debug(SMB, "file already closed\n"); ksmbd_debug(SMB, "file already closed\n");
@ -5299,7 +5293,7 @@ int smb2_close(struct ksmbd_work *work)
work->compound_pfid = KSMBD_NO_FID; work->compound_pfid = KSMBD_NO_FID;
} }
} else { } else {
volatile_id = le64_to_cpu(req->VolatileFileId); volatile_id = req->VolatileFileId;
} }
ksmbd_debug(SMB, "volatile_id = %llu\n", volatile_id); ksmbd_debug(SMB, "volatile_id = %llu\n", volatile_id);
@ -5988,7 +5982,7 @@ int smb2_set_info(struct ksmbd_work *work)
if (work->next_smb2_rcv_hdr_off) { if (work->next_smb2_rcv_hdr_off) {
req = ksmbd_req_buf_next(work); req = ksmbd_req_buf_next(work);
rsp = ksmbd_resp_buf_next(work); rsp = ksmbd_resp_buf_next(work);
if (!has_file_id(le64_to_cpu(req->VolatileFileId))) { if (!has_file_id(req->VolatileFileId)) {
ksmbd_debug(SMB, "Compound request set FID = %llu\n", ksmbd_debug(SMB, "Compound request set FID = %llu\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
@ -6000,8 +5994,8 @@ int smb2_set_info(struct ksmbd_work *work)
} }
if (!has_file_id(id)) { if (!has_file_id(id)) {
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
pid = le64_to_cpu(req->PersistentFileId); pid = req->PersistentFileId;
} }
fp = ksmbd_lookup_fd_slow(work, id, pid); fp = ksmbd_lookup_fd_slow(work, id, pid);
@ -6079,7 +6073,7 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
struct smb2_read_req *req = smb2_get_msg(work->request_buf); struct smb2_read_req *req = smb2_get_msg(work->request_buf);
struct smb2_read_rsp *rsp = smb2_get_msg(work->response_buf); struct smb2_read_rsp *rsp = smb2_get_msg(work->response_buf);
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
inc_rfc1001_len(work->response_buf, 16); inc_rfc1001_len(work->response_buf, 16);
rpc_resp = ksmbd_rpc_read(work->sess, id); rpc_resp = ksmbd_rpc_read(work->sess, id);
@ -6215,8 +6209,7 @@ int smb2_read(struct ksmbd_work *work)
goto out; goto out;
} }
fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId), fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
err = -ENOENT; err = -ENOENT;
goto out; goto out;
@ -6335,7 +6328,7 @@ static noinline int smb2_write_pipe(struct ksmbd_work *work)
size_t length; size_t length;
length = le32_to_cpu(req->Length); length = le32_to_cpu(req->Length);
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
if (le16_to_cpu(req->DataOffset) == if (le16_to_cpu(req->DataOffset) ==
offsetof(struct smb2_write_req, Buffer)) { offsetof(struct smb2_write_req, Buffer)) {
@ -6471,8 +6464,7 @@ int smb2_write(struct ksmbd_work *work)
goto out; goto out;
} }
fp = ksmbd_lookup_fd_slow(work, le64_to_cpu(req->VolatileFileId), fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
err = -ENOENT; err = -ENOENT;
goto out; goto out;
@ -6584,12 +6576,9 @@ int smb2_flush(struct ksmbd_work *work)
WORK_BUFFERS(work, req, rsp); WORK_BUFFERS(work, req, rsp);
ksmbd_debug(SMB, "SMB2_FLUSH called for fid %llu\n", ksmbd_debug(SMB, "SMB2_FLUSH called for fid %llu\n", req->VolatileFileId);
le64_to_cpu(req->VolatileFileId));
err = ksmbd_vfs_fsync(work, err = ksmbd_vfs_fsync(work, req->VolatileFileId, req->PersistentFileId);
le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId));
if (err) if (err)
goto out; goto out;
@ -6804,12 +6793,9 @@ int smb2_lock(struct ksmbd_work *work)
int prior_lock = 0; int prior_lock = 0;
ksmbd_debug(SMB, "Received lock request\n"); ksmbd_debug(SMB, "Received lock request\n");
fp = ksmbd_lookup_fd_slow(work, fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId));
if (!fp) { if (!fp) {
ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", ksmbd_debug(SMB, "Invalid file id for lock : %llu\n", req->VolatileFileId);
le64_to_cpu(req->VolatileFileId));
err = -ENOENT; err = -ENOENT;
goto out2; goto out2;
} }
@ -7164,8 +7150,8 @@ static int fsctl_copychunk(struct ksmbd_work *work,
ci_rsp = (struct copychunk_ioctl_rsp *)&rsp->Buffer[0]; ci_rsp = (struct copychunk_ioctl_rsp *)&rsp->Buffer[0];
rsp->VolatileFileId = cpu_to_le64(volatile_id); rsp->VolatileFileId = volatile_id;
rsp->PersistentFileId = cpu_to_le64(persistent_id); rsp->PersistentFileId = persistent_id;
ci_rsp->ChunksWritten = ci_rsp->ChunksWritten =
cpu_to_le32(ksmbd_server_side_copy_max_chunk_count()); cpu_to_le32(ksmbd_server_side_copy_max_chunk_count());
ci_rsp->ChunkBytesWritten = ci_rsp->ChunkBytesWritten =
@ -7379,8 +7365,8 @@ ipv6_retry:
if (nii_rsp) if (nii_rsp)
nii_rsp->Next = 0; nii_rsp->Next = 0;
rsp->PersistentFileId = cpu_to_le64(SMB2_NO_FID); rsp->PersistentFileId = SMB2_NO_FID;
rsp->VolatileFileId = cpu_to_le64(SMB2_NO_FID); rsp->VolatileFileId = SMB2_NO_FID;
return nbytes; return nbytes;
} }
@ -7547,9 +7533,7 @@ static int fsctl_request_resume_key(struct ksmbd_work *work,
{ {
struct ksmbd_file *fp; struct ksmbd_file *fp;
fp = ksmbd_lookup_fd_slow(work, fp = ksmbd_lookup_fd_slow(work, req->VolatileFileId, req->PersistentFileId);
le64_to_cpu(req->VolatileFileId),
le64_to_cpu(req->PersistentFileId));
if (!fp) if (!fp)
return -ENOENT; return -ENOENT;
@ -7579,7 +7563,7 @@ int smb2_ioctl(struct ksmbd_work *work)
if (work->next_smb2_rcv_hdr_off) { if (work->next_smb2_rcv_hdr_off) {
req = ksmbd_req_buf_next(work); req = ksmbd_req_buf_next(work);
rsp = ksmbd_resp_buf_next(work); rsp = ksmbd_resp_buf_next(work);
if (!has_file_id(le64_to_cpu(req->VolatileFileId))) { if (!has_file_id(req->VolatileFileId)) {
ksmbd_debug(SMB, "Compound request set FID = %llu\n", ksmbd_debug(SMB, "Compound request set FID = %llu\n",
work->compound_fid); work->compound_fid);
id = work->compound_fid; id = work->compound_fid;
@ -7590,14 +7574,14 @@ int smb2_ioctl(struct ksmbd_work *work)
} }
if (!has_file_id(id)) if (!has_file_id(id))
id = le64_to_cpu(req->VolatileFileId); id = req->VolatileFileId;
if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) { if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) {
rsp->hdr.Status = STATUS_NOT_SUPPORTED; rsp->hdr.Status = STATUS_NOT_SUPPORTED;
goto out; goto out;
} }
cnt_code = le32_to_cpu(req->CntCode); cnt_code = le32_to_cpu(req->CtlCode);
ret = smb2_calc_max_out_buf_len(work, 48, ret = smb2_calc_max_out_buf_len(work, 48,
le32_to_cpu(req->MaxOutputResponse)); le32_to_cpu(req->MaxOutputResponse));
if (ret < 0) { if (ret < 0) {
@ -7656,8 +7640,8 @@ int smb2_ioctl(struct ksmbd_work *work)
goto out; goto out;
nbytes = sizeof(struct validate_negotiate_info_rsp); nbytes = sizeof(struct validate_negotiate_info_rsp);
rsp->PersistentFileId = cpu_to_le64(SMB2_NO_FID); rsp->PersistentFileId = SMB2_NO_FID;
rsp->VolatileFileId = cpu_to_le64(SMB2_NO_FID); rsp->VolatileFileId = SMB2_NO_FID;
break; break;
case FSCTL_QUERY_NETWORK_INTERFACE_INFO: case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
ret = fsctl_query_iface_info_ioctl(conn, rsp, out_buf_len); ret = fsctl_query_iface_info_ioctl(conn, rsp, out_buf_len);
@ -7703,10 +7687,10 @@ int smb2_ioctl(struct ksmbd_work *work)
rsp->PersistentFileId = req->PersistentFileId; rsp->PersistentFileId = req->PersistentFileId;
fsctl_copychunk(work, fsctl_copychunk(work,
(struct copychunk_ioctl_req *)&req->Buffer[0], (struct copychunk_ioctl_req *)&req->Buffer[0],
le32_to_cpu(req->CntCode), le32_to_cpu(req->CtlCode),
le32_to_cpu(req->InputCount), le32_to_cpu(req->InputCount),
le64_to_cpu(req->VolatileFileId), req->VolatileFileId,
le64_to_cpu(req->PersistentFileId), req->PersistentFileId,
rsp); rsp);
break; break;
case FSCTL_SET_SPARSE: case FSCTL_SET_SPARSE:
@ -7857,7 +7841,7 @@ dup_ext_out:
goto out; goto out;
} }
rsp->CntCode = cpu_to_le32(cnt_code); rsp->CtlCode = cpu_to_le32(cnt_code);
rsp->InputCount = cpu_to_le32(0); rsp->InputCount = cpu_to_le32(0);
rsp->InputOffset = cpu_to_le32(112); rsp->InputOffset = cpu_to_le32(112);
rsp->OutputOffset = cpu_to_le32(112); rsp->OutputOffset = cpu_to_le32(112);
@ -7903,8 +7887,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
char req_oplevel = 0, rsp_oplevel = 0; char req_oplevel = 0, rsp_oplevel = 0;
unsigned int oplock_change_type; unsigned int oplock_change_type;
volatile_id = le64_to_cpu(req->VolatileFid); volatile_id = req->VolatileFid;
persistent_id = le64_to_cpu(req->PersistentFid); persistent_id = req->PersistentFid;
req_oplevel = req->OplockLevel; req_oplevel = req->OplockLevel;
ksmbd_debug(OPLOCK, "v_id %llu, p_id %llu request oplock level %d\n", ksmbd_debug(OPLOCK, "v_id %llu, p_id %llu request oplock level %d\n",
volatile_id, persistent_id, req_oplevel); volatile_id, persistent_id, req_oplevel);
@ -7999,8 +7983,8 @@ static void smb20_oplock_break_ack(struct ksmbd_work *work)
rsp->OplockLevel = rsp_oplevel; rsp->OplockLevel = rsp_oplevel;
rsp->Reserved = 0; rsp->Reserved = 0;
rsp->Reserved2 = 0; rsp->Reserved2 = 0;
rsp->VolatileFid = cpu_to_le64(volatile_id); rsp->VolatileFid = volatile_id;
rsp->PersistentFid = cpu_to_le64(persistent_id); rsp->PersistentFid = persistent_id;
inc_rfc1001_len(work->response_buf, 24); inc_rfc1001_len(work->response_buf, 24);
return; return;

View file

@ -16,42 +16,13 @@
#define FILE_CREATED 0x00000002 #define FILE_CREATED 0x00000002
#define FILE_OVERWRITTEN 0x00000003 #define FILE_OVERWRITTEN 0x00000003
/*
* Size of the session key (crypto key encrypted with the password
*/
#define SMB2_NTLMV2_SESSKEY_SIZE 16
#define SMB2_SIGNATURE_SIZE 16
#define SMB2_HMACSHA256_SIZE 32
#define SMB2_CMACAES_SIZE 16
#define SMB3_GCM128_CRYPTKEY_SIZE 16
#define SMB3_GCM256_CRYPTKEY_SIZE 32
/*
* Size of the smb3 encryption/decryption keys
*/
#define SMB3_ENC_DEC_KEY_SIZE 32
/*
* Size of the smb3 signing key
*/
#define SMB3_SIGN_KEY_SIZE 16
#define CIFS_CLIENT_CHALLENGE_SIZE 8
#define SMB_SERVER_CHALLENGE_SIZE 8
/* SMB2 Max Credits */ /* SMB2 Max Credits */
#define SMB2_MAX_CREDITS 8192 #define SMB2_MAX_CREDITS 8192
/* Maximum buffer size value we can send with 1 credit */
#define SMB2_MAX_BUFFER_SIZE 65536
#define NUMBER_OF_SMB2_COMMANDS 0x0013
/* BB FIXME - analyze following length BB */ /* BB FIXME - analyze following length BB */
#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */ #define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */
#define SMB21_DEFAULT_IOSIZE (1024 * 1024) #define SMB21_DEFAULT_IOSIZE (1024 * 1024)
#define SMB3_DEFAULT_IOSIZE (4 * 1024 * 1024)
#define SMB3_DEFAULT_TRANS_SIZE (1024 * 1024) #define SMB3_DEFAULT_TRANS_SIZE (1024 * 1024)
#define SMB3_MIN_IOSIZE (64 * 1024) #define SMB3_MIN_IOSIZE (64 * 1024)
#define SMB3_MAX_IOSIZE (8 * 1024 * 1024) #define SMB3_MAX_IOSIZE (8 * 1024 * 1024)
@ -65,18 +36,6 @@
* *
*/ */
#define SMB2_ERROR_STRUCTURE_SIZE2 9
#define SMB2_ERROR_STRUCTURE_SIZE2_LE cpu_to_le16(SMB2_ERROR_STRUCTURE_SIZE2)
struct smb2_err_rsp {
struct smb2_hdr hdr;
__le16 StructureSize;
__u8 ErrorContextCount;
__u8 Reserved;
__le32 ByteCount; /* even if zero, at least one byte follows */
__u8 ErrorData[1]; /* variable length */
} __packed;
struct preauth_integrity_info { struct preauth_integrity_info {
/* PreAuth integrity Hash ID */ /* PreAuth integrity Hash ID */
__le16 Preauth_HashId; __le16 Preauth_HashId;
@ -116,8 +75,8 @@ struct create_durable_reconn_req {
union { union {
__u8 Reserved[16]; __u8 Reserved[16];
struct { struct {
__le64 PersistentFileId; __u64 PersistentFileId;
__le64 VolatileFileId; __u64 VolatileFileId;
} Fid; } Fid;
} Data; } Data;
} __packed; } __packed;
@ -126,8 +85,8 @@ struct create_durable_reconn_v2_req {
struct create_context ccontext; struct create_context ccontext;
__u8 Name[8]; __u8 Name[8];
struct { struct {
__le64 PersistentFileId; __u64 PersistentFileId;
__le64 VolatileFileId; __u64 VolatileFileId;
} Fid; } Fid;
__u8 CreateGuid[16]; __u8 CreateGuid[16];
__le32 Flags; __le32 Flags;
@ -161,13 +120,6 @@ struct create_alloc_size_req {
__le64 AllocationSize; __le64 AllocationSize;
} __packed; } __packed;
struct create_posix {
struct create_context ccontext;
__u8 Name[16];
__le32 Mode;
__u32 Reserved;
} __packed;
struct create_durable_rsp { struct create_durable_rsp {
struct create_context ccontext; struct create_context ccontext;
__u8 Name[8]; __u8 Name[8];
@ -209,45 +161,6 @@ struct create_posix_rsp {
u8 SidBuffer[40]; u8 SidBuffer[40];
} __packed; } __packed;
#define SMB2_LEASE_NONE_LE cpu_to_le32(0x00)
#define SMB2_LEASE_READ_CACHING_LE cpu_to_le32(0x01)
#define SMB2_LEASE_HANDLE_CACHING_LE cpu_to_le32(0x02)
#define SMB2_LEASE_WRITE_CACHING_LE cpu_to_le32(0x04)
#define SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE cpu_to_le32(0x02)
#define SMB2_LEASE_KEY_SIZE 16
struct lease_context {
__u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
__le32 LeaseFlags;
__le64 LeaseDuration;
} __packed;
struct lease_context_v2 {
__u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
__le32 LeaseFlags;
__le64 LeaseDuration;
__u8 ParentLeaseKey[SMB2_LEASE_KEY_SIZE];
__le16 Epoch;
__le16 Reserved;
} __packed;
struct create_lease {
struct create_context ccontext;
__u8 Name[8];
struct lease_context lcontext;
} __packed;
struct create_lease_v2 {
struct create_context ccontext;
__u8 Name[8];
struct lease_context_v2 lcontext;
__u8 Pad[4];
} __packed;
struct smb2_buffer_desc_v1 { struct smb2_buffer_desc_v1 {
__le64 offset; __le64 offset;
__le32 token; __le32 token;
@ -256,63 +169,6 @@ struct smb2_buffer_desc_v1 {
#define SMB2_0_IOCTL_IS_FSCTL 0x00000001 #define SMB2_0_IOCTL_IS_FSCTL 0x00000001
struct duplicate_extents_to_file {
__u64 PersistentFileHandle; /* source file handle, opaque endianness */
__u64 VolatileFileHandle;
__le64 SourceFileOffset;
__le64 TargetFileOffset;
__le64 ByteCount; /* Bytes to be copied */
} __packed;
struct smb2_ioctl_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 57 */
__le16 Reserved; /* offset from start of SMB2 header to write data */
__le32 CntCode;
__le64 PersistentFileId;
__le64 VolatileFileId;
__le32 InputOffset; /* Reserved MBZ */
__le32 InputCount;
__le32 MaxInputResponse;
__le32 OutputOffset;
__le32 OutputCount;
__le32 MaxOutputResponse;
__le32 Flags;
__le32 Reserved2;
__u8 Buffer[1];
} __packed;
struct smb2_ioctl_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 49 */
__le16 Reserved; /* offset from start of SMB2 header to write data */
__le32 CntCode;
__le64 PersistentFileId;
__le64 VolatileFileId;
__le32 InputOffset; /* Reserved MBZ */
__le32 InputCount;
__le32 OutputOffset;
__le32 OutputCount;
__le32 Flags;
__le32 Reserved2;
__u8 Buffer[1];
} __packed;
struct validate_negotiate_info_req {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 DialectCount;
__le16 Dialects[1]; /* dialect (someday maybe list) client asked for */
} __packed;
struct validate_negotiate_info_rsp {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 Dialect; /* Dialect in use for the connection */
} __packed;
struct smb_sockaddr_in { struct smb_sockaddr_in {
__be16 Port; __be16 Port;
__be32 IPv4address; __be32 IPv4address;
@ -357,7 +213,7 @@ struct file_object_buf_type1_ioctl_rsp {
} __packed; } __packed;
struct resume_key_ioctl_rsp { struct resume_key_ioctl_rsp {
__le64 ResumeKey[3]; __u64 ResumeKey[3];
__le32 ContextLength; __le32 ContextLength;
__u8 Context[4]; /* ignored, Windows sets to 4 bytes of zero */ __u8 Context[4]; /* ignored, Windows sets to 4 bytes of zero */
} __packed; } __packed;
@ -386,167 +242,6 @@ struct file_sparse {
__u8 SetSparse; __u8 SetSparse;
} __packed; } __packed;
struct file_zero_data_information {
__le64 FileOffset;
__le64 BeyondFinalZero;
} __packed;
struct file_allocated_range_buffer {
__le64 file_offset;
__le64 length;
} __packed;
struct reparse_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 DataBuffer[]; /* Variable Length */
} __packed;
/* SMB2 Notify Action Flags */
#define FILE_ACTION_ADDED 0x00000001
#define FILE_ACTION_REMOVED 0x00000002
#define FILE_ACTION_MODIFIED 0x00000003
#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004
#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005
#define FILE_ACTION_ADDED_STREAM 0x00000006
#define FILE_ACTION_REMOVED_STREAM 0x00000007
#define FILE_ACTION_MODIFIED_STREAM 0x00000008
#define FILE_ACTION_REMOVED_BY_DELETE 0x00000009
#define SMB2_LOCKFLAG_SHARED 0x0001
#define SMB2_LOCKFLAG_EXCLUSIVE 0x0002
#define SMB2_LOCKFLAG_UNLOCK 0x0004
#define SMB2_LOCKFLAG_FAIL_IMMEDIATELY 0x0010
#define SMB2_LOCKFLAG_MASK 0x0007
struct smb2_lock_element {
__le64 Offset;
__le64 Length;
__le32 Flags;
__le32 Reserved;
} __packed;
struct smb2_lock_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 48 */
__le16 LockCount;
__le32 Reserved;
__le64 PersistentFileId;
__le64 VolatileFileId;
/* Followed by at least one */
struct smb2_lock_element locks[1];
} __packed;
struct smb2_lock_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__le16 Reserved;
} __packed;
struct smb2_echo_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__u16 Reserved;
} __packed;
struct smb2_echo_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__u16 Reserved;
} __packed;
/* search (query_directory) Flags field */
#define SMB2_RESTART_SCANS 0x01
#define SMB2_RETURN_SINGLE_ENTRY 0x02
#define SMB2_INDEX_SPECIFIED 0x04
#define SMB2_REOPEN 0x10
struct smb2_query_directory_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 33 */
__u8 FileInformationClass;
__u8 Flags;
__le32 FileIndex;
__le64 PersistentFileId;
__le64 VolatileFileId;
__le16 FileNameOffset;
__le16 FileNameLength;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
struct smb2_query_directory_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
/* Possible InfoType values */
#define SMB2_O_INFO_FILE 0x01
#define SMB2_O_INFO_FILESYSTEM 0x02
#define SMB2_O_INFO_SECURITY 0x03
#define SMB2_O_INFO_QUOTA 0x04
/* Security info type additionalinfo flags. See MS-SMB2 (2.2.37) or MS-DTYP */
#define OWNER_SECINFO 0x00000001
#define GROUP_SECINFO 0x00000002
#define DACL_SECINFO 0x00000004
#define SACL_SECINFO 0x00000008
#define LABEL_SECINFO 0x00000010
#define ATTRIBUTE_SECINFO 0x00000020
#define SCOPE_SECINFO 0x00000040
#define BACKUP_SECINFO 0x00010000
#define UNPROTECTED_SACL_SECINFO 0x10000000
#define UNPROTECTED_DACL_SECINFO 0x20000000
#define PROTECTED_SACL_SECINFO 0x40000000
#define PROTECTED_DACL_SECINFO 0x80000000
struct smb2_query_info_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 41 */
__u8 InfoType;
__u8 FileInfoClass;
__le32 OutputBufferLength;
__le16 InputBufferOffset;
__u16 Reserved;
__le32 InputBufferLength;
__le32 AdditionalInformation;
__le32 Flags;
__le64 PersistentFileId;
__le64 VolatileFileId;
__u8 Buffer[1];
} __packed;
struct smb2_query_info_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
struct smb2_set_info_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 33 */
__u8 InfoType;
__u8 FileInfoClass;
__le32 BufferLength;
__le16 BufferOffset;
__u16 Reserved;
__le32 AdditionalInformation;
__le64 PersistentFileId;
__le64 VolatileFileId;
__u8 Buffer[1];
} __packed;
struct smb2_set_info_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 2 */
} __packed;
/* FILE Info response size */ /* FILE Info response size */
#define FILE_DIRECTORY_INFORMATION_SIZE 1 #define FILE_DIRECTORY_INFORMATION_SIZE 1
#define FILE_FULL_DIRECTORY_INFORMATION_SIZE 2 #define FILE_FULL_DIRECTORY_INFORMATION_SIZE 2
@ -602,145 +297,11 @@ struct fs_type_info {
long magic_number; long magic_number;
} __packed; } __packed;
struct smb2_oplock_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 24 */
__u8 OplockLevel;
__u8 Reserved;
__le32 Reserved2;
__le64 PersistentFid;
__le64 VolatileFid;
} __packed;
#define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED cpu_to_le32(0x01)
struct smb2_lease_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 44 */
__le16 Epoch;
__le32 Flags;
__u8 LeaseKey[16];
__le32 CurrentLeaseState;
__le32 NewLeaseState;
__le32 BreakReason;
__le32 AccessMaskHint;
__le32 ShareMaskHint;
} __packed;
struct smb2_lease_ack {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 36 */
__le16 Reserved;
__le32 Flags;
__u8 LeaseKey[16];
__le32 LeaseState;
__le64 LeaseDuration;
} __packed;
/* /*
* PDU infolevel structure definitions * PDU query infolevel structure definitions
* BB consider moving to a different header * BB consider moving to a different header
*/ */
/* File System Information Classes */
#define FS_VOLUME_INFORMATION 1 /* Query */
#define FS_LABEL_INFORMATION 2 /* Set */
#define FS_SIZE_INFORMATION 3 /* Query */
#define FS_DEVICE_INFORMATION 4 /* Query */
#define FS_ATTRIBUTE_INFORMATION 5 /* Query */
#define FS_CONTROL_INFORMATION 6 /* Query, Set */
#define FS_FULL_SIZE_INFORMATION 7 /* Query */
#define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */
#define FS_DRIVER_PATH_INFORMATION 9 /* Query */
#define FS_SECTOR_SIZE_INFORMATION 11 /* SMB3 or later. Query */
#define FS_POSIX_INFORMATION 100 /* SMB3.1.1 POSIX. Query */
struct smb2_fs_full_size_info {
__le64 TotalAllocationUnits;
__le64 CallerAvailableAllocationUnits;
__le64 ActualAvailableAllocationUnits;
__le32 SectorsPerAllocationUnit;
__le32 BytesPerSector;
} __packed;
#define SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001
#define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002
#define SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004
#define SSINFO_FLAGS_TRIM_ENABLED 0x00000008
/* sector size info struct */
struct smb3_fs_ss_info {
__le32 LogicalBytesPerSector;
__le32 PhysicalBytesPerSectorForAtomicity;
__le32 PhysicalBytesPerSectorForPerf;
__le32 FSEffPhysicalBytesPerSectorForAtomicity;
__le32 Flags;
__le32 ByteOffsetForSectorAlignment;
__le32 ByteOffsetForPartitionAlignment;
} __packed;
/* File System Control Information */
struct smb2_fs_control_info {
__le64 FreeSpaceStartFiltering;
__le64 FreeSpaceThreshold;
__le64 FreeSpaceStopFiltering;
__le64 DefaultQuotaThreshold;
__le64 DefaultQuotaLimit;
__le32 FileSystemControlFlags;
__le32 Padding;
} __packed;
/* partial list of QUERY INFO levels */
#define FILE_DIRECTORY_INFORMATION 1
#define FILE_FULL_DIRECTORY_INFORMATION 2
#define FILE_BOTH_DIRECTORY_INFORMATION 3
#define FILE_BASIC_INFORMATION 4
#define FILE_STANDARD_INFORMATION 5
#define FILE_INTERNAL_INFORMATION 6
#define FILE_EA_INFORMATION 7
#define FILE_ACCESS_INFORMATION 8
#define FILE_NAME_INFORMATION 9
#define FILE_RENAME_INFORMATION 10
#define FILE_LINK_INFORMATION 11
#define FILE_NAMES_INFORMATION 12
#define FILE_DISPOSITION_INFORMATION 13
#define FILE_POSITION_INFORMATION 14
#define FILE_FULL_EA_INFORMATION 15
#define FILE_MODE_INFORMATION 16
#define FILE_ALIGNMENT_INFORMATION 17
#define FILE_ALL_INFORMATION 18
#define FILE_ALLOCATION_INFORMATION 19
#define FILE_END_OF_FILE_INFORMATION 20
#define FILE_ALTERNATE_NAME_INFORMATION 21
#define FILE_STREAM_INFORMATION 22
#define FILE_PIPE_INFORMATION 23
#define FILE_PIPE_LOCAL_INFORMATION 24
#define FILE_PIPE_REMOTE_INFORMATION 25
#define FILE_MAILSLOT_QUERY_INFORMATION 26
#define FILE_MAILSLOT_SET_INFORMATION 27
#define FILE_COMPRESSION_INFORMATION 28
#define FILE_OBJECT_ID_INFORMATION 29
/* Number 30 not defined in documents */
#define FILE_MOVE_CLUSTER_INFORMATION 31
#define FILE_QUOTA_INFORMATION 32
#define FILE_REPARSE_POINT_INFORMATION 33
#define FILE_NETWORK_OPEN_INFORMATION 34
#define FILE_ATTRIBUTE_TAG_INFORMATION 35
#define FILE_TRACKING_INFORMATION 36
#define FILEID_BOTH_DIRECTORY_INFORMATION 37
#define FILEID_FULL_DIRECTORY_INFORMATION 38
#define FILE_VALID_DATA_LENGTH_INFORMATION 39
#define FILE_SHORT_NAME_INFORMATION 40
#define FILE_SFIO_RESERVE_INFORMATION 44
#define FILE_SFIO_VOLUME_INFORMATION 45
#define FILE_HARD_LINK_INFORMATION 46
#define FILE_NORMALIZED_NAME_INFORMATION 48
#define FILEID_GLOBAL_TX_DIRECTORY_INFORMATION 50
#define FILE_STANDARD_LINK_INFORMATION 54
#define OP_BREAK_STRUCT_SIZE_20 24
#define OP_BREAK_STRUCT_SIZE_21 36
struct smb2_file_access_info { struct smb2_file_access_info {
__le32 AccessFlags; __le32 AccessFlags;
} __packed; } __packed;
@ -749,56 +310,6 @@ struct smb2_file_alignment_info {
__le32 AlignmentRequirement; __le32 AlignmentRequirement;
} __packed; } __packed;
struct smb2_file_internal_info {
__le64 IndexNumber;
} __packed; /* level 6 Query */
struct smb2_file_rename_info { /* encoding of request for level 10 */
__u8 ReplaceIfExists; /* 1 = replace existing target with new */
/* 0 = fail if target already exists */
__u8 Reserved[7];
__u64 RootDirectory; /* MBZ for network operations (why says spec?) */
__le32 FileNameLength;
char FileName[]; /* New name to be assigned */
} __packed; /* level 10 Set */
struct smb2_file_link_info { /* encoding of request for level 11 */
__u8 ReplaceIfExists; /* 1 = replace existing link with new */
/* 0 = fail if link already exists */
__u8 Reserved[7];
__u64 RootDirectory; /* MBZ for network operations (why says spec?) */
__le32 FileNameLength;
char FileName[]; /* Name to be assigned to new link */
} __packed; /* level 11 Set */
/*
* This level 18, although with struct with same name is different from cifs
* level 0x107. Level 0x107 has an extra u64 between AccessFlags and
* CurrentByteOffset.
*/
struct smb2_file_all_info { /* data block encoding of response to level 18 */
__le64 CreationTime; /* Beginning of FILE_BASIC_INFO equivalent */
__le64 LastAccessTime;
__le64 LastWriteTime;
__le64 ChangeTime;
__le32 Attributes;
__u32 Pad1; /* End of FILE_BASIC_INFO_INFO equivalent */
__le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */
__le64 EndOfFile; /* size ie offset to first free byte in file */
__le32 NumberOfLinks; /* hard links */
__u8 DeletePending;
__u8 Directory;
__u16 Pad2; /* End of FILE_STANDARD_INFO equivalent */
__le64 IndexNumber;
__le32 EASize;
__le32 AccessFlags;
__le64 CurrentByteOffset;
__le32 Mode;
__le32 AlignmentRequirement;
__le32 FileNameLength;
char FileName[1];
} __packed; /* level 18 Query */
struct smb2_file_basic_info { /* data block encoding of response to level 18 */ struct smb2_file_basic_info { /* data block encoding of response to level 18 */
__le64 CreationTime; /* Beginning of FILE_BASIC_INFO equivalent */ __le64 CreationTime; /* Beginning of FILE_BASIC_INFO equivalent */
__le64 LastAccessTime; __le64 LastAccessTime;
@ -821,10 +332,6 @@ struct smb2_file_stream_info {
char StreamName[]; char StreamName[];
} __packed; } __packed;
struct smb2_file_eof_info { /* encoding of request for level 10 */
__le64 EndOfFile; /* new end of file value */
} __packed; /* level 20 Set */
struct smb2_file_ntwrk_info { struct smb2_file_ntwrk_info {
__le64 CreationTime; __le64 CreationTime;
__le64 LastAccessTime; __le64 LastAccessTime;
@ -915,34 +422,6 @@ struct create_sd_buf_req {
struct smb_ntsd ntsd; struct smb_ntsd ntsd;
} __packed; } __packed;
/* Find File infolevels */
#define SMB_FIND_FILE_POSIX_INFO 0x064
/* Level 100 query info */
struct smb311_posix_qinfo {
__le64 CreationTime;
__le64 LastAccessTime;
__le64 LastWriteTime;
__le64 ChangeTime;
__le64 EndOfFile;
__le64 AllocationSize;
__le32 DosAttributes;
__le64 Inode;
__le32 DeviceId;
__le32 Zero;
/* beginning of POSIX Create Context Response */
__le32 HardLinks;
__le32 ReparseTag;
__le32 Mode;
u8 Sids[];
/*
* var sized owner SID
* var sized group SID
* le32 filenamelength
* u8 filename[]
*/
} __packed;
struct smb2_posix_info { struct smb2_posix_info {
__le32 NextEntryOffset; __le32 NextEntryOffset;
__u32 Ignored; __u32 Ignored;

View file

@ -60,6 +60,40 @@
#define NUMBER_OF_SMB2_COMMANDS 0x0013 #define NUMBER_OF_SMB2_COMMANDS 0x0013
/*
* Size of the session key (crypto key encrypted with the password
*/
#define SMB2_NTLMV2_SESSKEY_SIZE 16
#define SMB2_SIGNATURE_SIZE 16
#define SMB2_HMACSHA256_SIZE 32
#define SMB2_CMACAES_SIZE 16
#define SMB3_GCM128_CRYPTKEY_SIZE 16
#define SMB3_GCM256_CRYPTKEY_SIZE 32
/*
* Size of the smb3 encryption/decryption keys
* This size is big enough to store any cipher key types.
*/
#define SMB3_ENC_DEC_KEY_SIZE 32
/*
* Size of the smb3 signing key
*/
#define SMB3_SIGN_KEY_SIZE 16
#define CIFS_CLIENT_CHALLENGE_SIZE 8
/* Maximum buffer size value we can send with 1 credit */
#define SMB2_MAX_BUFFER_SIZE 65536
/*
* The default wsize is 1M for SMB2 (and for some CIFS cases).
* find_get_pages seems to return a maximum of 256
* pages in a single call. With PAGE_SIZE == 4k, this means we can
* fill a single wsize request with a single call.
*/
#define SMB3_DEFAULT_IOSIZE (4 * 1024 * 1024)
/* /*
* SMB2 Header Definition * SMB2 Header Definition
* *
@ -88,6 +122,15 @@
#define SMB2_FLAGS_DFS_OPERATIONS cpu_to_le32(0x10000000) #define SMB2_FLAGS_DFS_OPERATIONS cpu_to_le32(0x10000000)
#define SMB2_FLAGS_REPLAY_OPERATION cpu_to_le32(0x20000000) /* SMB3 & up */ #define SMB2_FLAGS_REPLAY_OPERATION cpu_to_le32(0x20000000) /* SMB3 & up */
/*
* Definitions for SMB2 Protocol Data Units (network frames)
*
* See MS-SMB2.PDF specification for protocol details.
* The Naming convention is the lower case version of the SMB2
* command code name for the struct. Note that structures must be packed.
*
*/
/* See MS-SMB2 section 2.2.1 */ /* See MS-SMB2 section 2.2.1 */
struct smb2_hdr { struct smb2_hdr {
__le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */ __le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */
@ -115,6 +158,18 @@ struct smb2_pdu {
__le16 StructureSize2; /* size of wct area (varies, request specific) */ __le16 StructureSize2; /* size of wct area (varies, request specific) */
} __packed; } __packed;
#define SMB2_ERROR_STRUCTURE_SIZE2 9
#define SMB2_ERROR_STRUCTURE_SIZE2_LE cpu_to_le16(SMB2_ERROR_STRUCTURE_SIZE2)
struct smb2_err_rsp {
struct smb2_hdr hdr;
__le16 StructureSize;
__u8 ErrorContextCount;
__u8 Reserved;
__le32 ByteCount; /* even if zero, at least one byte follows */
__u8 ErrorData[1]; /* variable length */
} __packed;
#define SMB3_AES_CCM_NONCE 11 #define SMB3_AES_CCM_NONCE 11
#define SMB3_AES_GCM_NONCE 12 #define SMB3_AES_GCM_NONCE 12
@ -608,8 +663,8 @@ struct smb2_close_req {
__le16 StructureSize; /* Must be 24 */ __le16 StructureSize; /* Must be 24 */
__le16 Flags; __le16 Flags;
__le32 Reserved; __le32 Reserved;
__le64 PersistentFileId; /* opaque endianness */ __u64 PersistentFileId; /* opaque endianness */
__le64 VolatileFileId; /* opaque endianness */ __u64 VolatileFileId; /* opaque endianness */
} __packed; } __packed;
/* /*
@ -653,8 +708,8 @@ struct smb2_read_req {
__u8 Flags; /* MBZ unless SMB3.02 or later */ __u8 Flags; /* MBZ unless SMB3.02 or later */
__le32 Length; __le32 Length;
__le64 Offset; __le64 Offset;
__le64 PersistentFileId; __u64 PersistentFileId;
__le64 VolatileFileId; __u64 VolatileFileId;
__le32 MinimumCount; __le32 MinimumCount;
__le32 Channel; /* MBZ except for SMB3 or later */ __le32 Channel; /* MBZ except for SMB3 or later */
__le32 RemainingBytes; __le32 RemainingBytes;
@ -692,8 +747,8 @@ struct smb2_write_req {
__le16 DataOffset; /* offset from start of SMB2 header to write data */ __le16 DataOffset; /* offset from start of SMB2 header to write data */
__le32 Length; __le32 Length;
__le64 Offset; __le64 Offset;
__le64 PersistentFileId; /* opaque endianness */ __u64 PersistentFileId; /* opaque endianness */
__le64 VolatileFileId; /* opaque endianness */ __u64 VolatileFileId; /* opaque endianness */
__le32 Channel; /* MBZ unless SMB3.02 or later */ __le32 Channel; /* MBZ unless SMB3.02 or later */
__le32 RemainingBytes; __le32 RemainingBytes;
__le16 WriteChannelInfoOffset; __le16 WriteChannelInfoOffset;
@ -722,8 +777,8 @@ struct smb2_flush_req {
__le16 StructureSize; /* Must be 24 */ __le16 StructureSize; /* Must be 24 */
__le16 Reserved1; __le16 Reserved1;
__le32 Reserved2; __le32 Reserved2;
__le64 PersistentFileId; __u64 PersistentFileId;
__le64 VolatileFileId; __u64 VolatileFileId;
} __packed; } __packed;
struct smb2_flush_rsp { struct smb2_flush_rsp {
@ -732,6 +787,123 @@ struct smb2_flush_rsp {
__le16 Reserved; __le16 Reserved;
} __packed; } __packed;
#define SMB2_LOCKFLAG_SHARED 0x0001
#define SMB2_LOCKFLAG_EXCLUSIVE 0x0002
#define SMB2_LOCKFLAG_UNLOCK 0x0004
#define SMB2_LOCKFLAG_FAIL_IMMEDIATELY 0x0010
#define SMB2_LOCKFLAG_MASK 0x0007
struct smb2_lock_element {
__le64 Offset;
__le64 Length;
__le32 Flags;
__le32 Reserved;
} __packed;
struct smb2_lock_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 48 */
__le16 LockCount;
/*
* The least significant four bits are the index, the other 28 bits are
* the lock sequence number (0 to 64). See MS-SMB2 2.2.26
*/
__le32 LockSequenceNumber;
__u64 PersistentFileId;
__u64 VolatileFileId;
/* Followed by at least one */
struct smb2_lock_element locks[1];
} __packed;
struct smb2_lock_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__le16 Reserved;
} __packed;
struct smb2_echo_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__u16 Reserved;
} __packed;
struct smb2_echo_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 4 */
__u16 Reserved;
} __packed;
/*
* Valid FileInformation classes for query directory
*
* Note that these are a subset of the (file) QUERY_INFO levels defined
* later in this file (but since QUERY_DIRECTORY uses equivalent numbers
* we do not redefine them here)
*
* FileDirectoryInfomation 0x01
* FileFullDirectoryInformation 0x02
* FileIdFullDirectoryInformation 0x26
* FileBothDirectoryInformation 0x03
* FileIdBothDirectoryInformation 0x25
* FileNamesInformation 0x0C
* FileIdExtdDirectoryInformation 0x3C
*/
/* search (query_directory) Flags field */
#define SMB2_RESTART_SCANS 0x01
#define SMB2_RETURN_SINGLE_ENTRY 0x02
#define SMB2_INDEX_SPECIFIED 0x04
#define SMB2_REOPEN 0x10
struct smb2_query_directory_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 33 */
__u8 FileInformationClass;
__u8 Flags;
__le32 FileIndex;
__u64 PersistentFileId;
__u64 VolatileFileId;
__le16 FileNameOffset;
__le16 FileNameLength;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
struct smb2_query_directory_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
/*
* Maximum number of iovs we need for a set-info request.
* The largest one is rename/hardlink
* [0] : struct smb2_set_info_req + smb2_file_[rename|link]_info
* [1] : path
* [2] : compound padding
*/
#define SMB2_SET_INFO_IOV_SIZE 3
struct smb2_set_info_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 33 */
__u8 InfoType;
__u8 FileInfoClass;
__le32 BufferLength;
__le16 BufferOffset;
__u16 Reserved;
__le32 AdditionalInformation;
__u64 PersistentFileId;
__u64 VolatileFileId;
__u8 Buffer[1];
} __packed;
struct smb2_set_info_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 2 */
} __packed;
/* /*
* SMB2_NOTIFY See MS-SMB2 section 2.2.35 * SMB2_NOTIFY See MS-SMB2 section 2.2.35
@ -769,8 +941,8 @@ struct smb2_change_notify_req {
__le16 StructureSize; __le16 StructureSize;
__le16 Flags; __le16 Flags;
__le32 OutputBufferLength; __le32 OutputBufferLength;
__le64 PersistentFileId; /* opaque endianness */ __u64 PersistentFileId; /* opaque endianness */
__le64 VolatileFileId; /* opaque endianness */ __u64 VolatileFileId; /* opaque endianness */
__le32 CompletionFilter; __le32 CompletionFilter;
__u32 Reserved; __u32 Reserved;
} __packed; } __packed;
@ -978,12 +1150,455 @@ struct smb2_create_rsp {
__le64 EndofFile; __le64 EndofFile;
__le32 FileAttributes; __le32 FileAttributes;
__le32 Reserved2; __le32 Reserved2;
__le64 PersistentFileId; __u64 PersistentFileId;
__le64 VolatileFileId; __u64 VolatileFileId;
__le32 CreateContextsOffset; __le32 CreateContextsOffset;
__le32 CreateContextsLength; __le32 CreateContextsLength;
__u8 Buffer[1]; __u8 Buffer[1];
} __packed; } __packed;
struct create_posix {
struct create_context ccontext;
__u8 Name[16];
__le32 Mode;
__u32 Reserved;
} __packed;
#define SMB2_LEASE_NONE_LE cpu_to_le32(0x00)
#define SMB2_LEASE_READ_CACHING_LE cpu_to_le32(0x01)
#define SMB2_LEASE_HANDLE_CACHING_LE cpu_to_le32(0x02)
#define SMB2_LEASE_WRITE_CACHING_LE cpu_to_le32(0x04)
#define SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE cpu_to_le32(0x02)
#define SMB2_LEASE_KEY_SIZE 16
struct lease_context {
__u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
__le32 LeaseFlags;
__le64 LeaseDuration;
} __packed;
struct lease_context_v2 {
__u8 LeaseKey[SMB2_LEASE_KEY_SIZE];
__le32 LeaseState;
__le32 LeaseFlags;
__le64 LeaseDuration;
__u8 ParentLeaseKey[SMB2_LEASE_KEY_SIZE];
__le16 Epoch;
__le16 Reserved;
} __packed;
struct create_lease {
struct create_context ccontext;
__u8 Name[8];
struct lease_context lcontext;
} __packed;
struct create_lease_v2 {
struct create_context ccontext;
__u8 Name[8];
struct lease_context_v2 lcontext;
__u8 Pad[4];
} __packed;
/* See MS-SMB2 2.2.31 and 2.2.32 */
struct smb2_ioctl_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 57 */
__le16 Reserved; /* offset from start of SMB2 header to write data */
__le32 CtlCode;
__u64 PersistentFileId;
__u64 VolatileFileId;
__le32 InputOffset; /* Reserved MBZ */
__le32 InputCount;
__le32 MaxInputResponse;
__le32 OutputOffset;
__le32 OutputCount;
__le32 MaxOutputResponse;
__le32 Flags;
__le32 Reserved2;
__u8 Buffer[];
} __packed;
struct smb2_ioctl_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 49 */
__le16 Reserved;
__le32 CtlCode;
__u64 PersistentFileId;
__u64 VolatileFileId;
__le32 InputOffset; /* Reserved MBZ */
__le32 InputCount;
__le32 OutputOffset;
__le32 OutputCount;
__le32 Flags;
__le32 Reserved2;
__u8 Buffer[];
} __packed;
/* this goes in the ioctl buffer when doing FSCTL_SET_ZERO_DATA */
struct file_zero_data_information {
__le64 FileOffset;
__le64 BeyondFinalZero;
} __packed;
/* Reparse structures - see MS-FSCC 2.1.2 */
/* struct fsctl_reparse_info_req is empty, only response structs (see below) */
struct reparse_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 DataBuffer[]; /* Variable Length */
} __packed;
struct reparse_guid_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__u8 ReparseGuid[16];
__u8 DataBuffer[]; /* Variable Length */
} __packed;
struct reparse_mount_point_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__le16 SubstituteNameOffset;
__le16 SubstituteNameLength;
__le16 PrintNameOffset;
__le16 PrintNameLength;
__u8 PathBuffer[]; /* Variable Length */
} __packed;
#define SYMLINK_FLAG_RELATIVE 0x00000001
struct reparse_symlink_data_buffer {
__le32 ReparseTag;
__le16 ReparseDataLength;
__u16 Reserved;
__le16 SubstituteNameOffset;
__le16 SubstituteNameLength;
__le16 PrintNameOffset;
__le16 PrintNameLength;
__le32 Flags;
__u8 PathBuffer[]; /* Variable Length */
} __packed;
/* See MS-FSCC 2.1.2.6 and cifspdu.h for struct reparse_posix_data */
struct validate_negotiate_info_req {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 DialectCount;
__le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
} __packed;
struct validate_negotiate_info_rsp {
__le32 Capabilities;
__u8 Guid[SMB2_CLIENT_GUID_SIZE];
__le16 SecurityMode;
__le16 Dialect; /* Dialect in use for the connection */
} __packed;
struct duplicate_extents_to_file {
__u64 PersistentFileHandle; /* source file handle, opaque endianness */
__u64 VolatileFileHandle;
__le64 SourceFileOffset;
__le64 TargetFileOffset;
__le64 ByteCount; /* Bytes to be copied */
} __packed;
/* Possible InfoType values */
#define SMB2_O_INFO_FILE 0x01
#define SMB2_O_INFO_FILESYSTEM 0x02
#define SMB2_O_INFO_SECURITY 0x03
#define SMB2_O_INFO_QUOTA 0x04
/* SMB2 Query Info see MS-SMB2 (2.2.37) or MS-DTYP */
/* List of QUERY INFO levels (those also valid for QUERY_DIR are noted below */
#define FILE_DIRECTORY_INFORMATION 1 /* also for QUERY_DIR */
#define FILE_FULL_DIRECTORY_INFORMATION 2 /* also for QUERY_DIR */
#define FILE_BOTH_DIRECTORY_INFORMATION 3 /* also for QUERY_DIR */
#define FILE_BASIC_INFORMATION 4
#define FILE_STANDARD_INFORMATION 5
#define FILE_INTERNAL_INFORMATION 6
#define FILE_EA_INFORMATION 7
#define FILE_ACCESS_INFORMATION 8
#define FILE_NAME_INFORMATION 9
#define FILE_RENAME_INFORMATION 10
#define FILE_LINK_INFORMATION 11
#define FILE_NAMES_INFORMATION 12 /* also for QUERY_DIR */
#define FILE_DISPOSITION_INFORMATION 13
#define FILE_POSITION_INFORMATION 14
#define FILE_FULL_EA_INFORMATION 15
#define FILE_MODE_INFORMATION 16
#define FILE_ALIGNMENT_INFORMATION 17
#define FILE_ALL_INFORMATION 18
#define FILE_ALLOCATION_INFORMATION 19
#define FILE_END_OF_FILE_INFORMATION 20
#define FILE_ALTERNATE_NAME_INFORMATION 21
#define FILE_STREAM_INFORMATION 22
#define FILE_PIPE_INFORMATION 23
#define FILE_PIPE_LOCAL_INFORMATION 24
#define FILE_PIPE_REMOTE_INFORMATION 25
#define FILE_MAILSLOT_QUERY_INFORMATION 26
#define FILE_MAILSLOT_SET_INFORMATION 27
#define FILE_COMPRESSION_INFORMATION 28
#define FILE_OBJECT_ID_INFORMATION 29
/* Number 30 not defined in documents */
#define FILE_MOVE_CLUSTER_INFORMATION 31
#define FILE_QUOTA_INFORMATION 32
#define FILE_REPARSE_POINT_INFORMATION 33
#define FILE_NETWORK_OPEN_INFORMATION 34
#define FILE_ATTRIBUTE_TAG_INFORMATION 35
#define FILE_TRACKING_INFORMATION 36
#define FILEID_BOTH_DIRECTORY_INFORMATION 37 /* also for QUERY_DIR */
#define FILEID_FULL_DIRECTORY_INFORMATION 38 /* also for QUERY_DIR */
#define FILE_VALID_DATA_LENGTH_INFORMATION 39
#define FILE_SHORT_NAME_INFORMATION 40
#define FILE_SFIO_RESERVE_INFORMATION 44
#define FILE_SFIO_VOLUME_INFORMATION 45
#define FILE_HARD_LINK_INFORMATION 46
#define FILE_NORMALIZED_NAME_INFORMATION 48
#define FILEID_GLOBAL_TX_DIRECTORY_INFORMATION 50
#define FILE_STANDARD_LINK_INFORMATION 54
#define FILE_ID_INFORMATION 59
#define FILE_ID_EXTD_DIRECTORY_INFORMATION 60 /* also for QUERY_DIR */
/* Used for Query Info and Find File POSIX Info for SMB3.1.1 and SMB1 */
#define SMB_FIND_FILE_POSIX_INFO 0x064
/* Security info type additionalinfo flags. */
#define OWNER_SECINFO 0x00000001
#define GROUP_SECINFO 0x00000002
#define DACL_SECINFO 0x00000004
#define SACL_SECINFO 0x00000008
#define LABEL_SECINFO 0x00000010
#define ATTRIBUTE_SECINFO 0x00000020
#define SCOPE_SECINFO 0x00000040
#define BACKUP_SECINFO 0x00010000
#define UNPROTECTED_SACL_SECINFO 0x10000000
#define UNPROTECTED_DACL_SECINFO 0x20000000
#define PROTECTED_SACL_SECINFO 0x40000000
#define PROTECTED_DACL_SECINFO 0x80000000
/* Flags used for FileFullEAinfo */
#define SL_RESTART_SCAN 0x00000001
#define SL_RETURN_SINGLE_ENTRY 0x00000002
#define SL_INDEX_SPECIFIED 0x00000004
struct smb2_query_info_req {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 41 */
__u8 InfoType;
__u8 FileInfoClass;
__le32 OutputBufferLength;
__le16 InputBufferOffset;
__u16 Reserved;
__le32 InputBufferLength;
__le32 AdditionalInformation;
__le32 Flags;
__u64 PersistentFileId;
__u64 VolatileFileId;
__u8 Buffer[1];
} __packed;
struct smb2_query_info_rsp {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 9 */
__le16 OutputBufferOffset;
__le32 OutputBufferLength;
__u8 Buffer[1];
} __packed;
/*
* PDU query infolevel structure definitions
*/
struct file_allocated_range_buffer {
__le64 file_offset;
__le64 length;
} __packed;
struct smb2_file_internal_info {
__le64 IndexNumber;
} __packed; /* level 6 Query */
struct smb2_file_rename_info { /* encoding of request for level 10 */
__u8 ReplaceIfExists; /* 1 = replace existing target with new */
/* 0 = fail if target already exists */
__u8 Reserved[7];
__u64 RootDirectory; /* MBZ for network operations (why says spec?) */
__le32 FileNameLength;
char FileName[]; /* New name to be assigned */
/* padding - overall struct size must be >= 24 so filename + pad >= 6 */
} __packed; /* level 10 Set */
struct smb2_file_link_info { /* encoding of request for level 11 */
__u8 ReplaceIfExists; /* 1 = replace existing link with new */
/* 0 = fail if link already exists */
__u8 Reserved[7];
__u64 RootDirectory; /* MBZ for network operations (why says spec?) */
__le32 FileNameLength;
char FileName[]; /* Name to be assigned to new link */
} __packed; /* level 11 Set */
/*
* This level 18, although with struct with same name is different from cifs
* level 0x107. Level 0x107 has an extra u64 between AccessFlags and
* CurrentByteOffset.
*/
struct smb2_file_all_info { /* data block encoding of response to level 18 */
__le64 CreationTime; /* Beginning of FILE_BASIC_INFO equivalent */
__le64 LastAccessTime;
__le64 LastWriteTime;
__le64 ChangeTime;
__le32 Attributes;
__u32 Pad1; /* End of FILE_BASIC_INFO_INFO equivalent */
__le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */
__le64 EndOfFile; /* size ie offset to first free byte in file */
__le32 NumberOfLinks; /* hard links */
__u8 DeletePending;
__u8 Directory;
__u16 Pad2; /* End of FILE_STANDARD_INFO equivalent */
__le64 IndexNumber;
__le32 EASize;
__le32 AccessFlags;
__le64 CurrentByteOffset;
__le32 Mode;
__le32 AlignmentRequirement;
__le32 FileNameLength;
char FileName[1];
} __packed; /* level 18 Query */
struct smb2_file_eof_info { /* encoding of request for level 10 */
__le64 EndOfFile; /* new end of file value */
} __packed; /* level 20 Set */
/* Level 100 query info */
struct smb311_posix_qinfo {
__le64 CreationTime;
__le64 LastAccessTime;
__le64 LastWriteTime;
__le64 ChangeTime;
__le64 EndOfFile;
__le64 AllocationSize;
__le32 DosAttributes;
__le64 Inode;
__le32 DeviceId;
__le32 Zero;
/* beginning of POSIX Create Context Response */
__le32 HardLinks;
__le32 ReparseTag;
__le32 Mode;
u8 Sids[];
/*
* var sized owner SID
* var sized group SID
* le32 filenamelength
* u8 filename[]
*/
} __packed;
/* File System Information Classes */
#define FS_VOLUME_INFORMATION 1 /* Query */
#define FS_LABEL_INFORMATION 2 /* Set */
#define FS_SIZE_INFORMATION 3 /* Query */
#define FS_DEVICE_INFORMATION 4 /* Query */
#define FS_ATTRIBUTE_INFORMATION 5 /* Query */
#define FS_CONTROL_INFORMATION 6 /* Query, Set */
#define FS_FULL_SIZE_INFORMATION 7 /* Query */
#define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */
#define FS_DRIVER_PATH_INFORMATION 9 /* Query */
#define FS_SECTOR_SIZE_INFORMATION 11 /* SMB3 or later. Query */
#define FS_POSIX_INFORMATION 100 /* SMB3.1.1 POSIX. Query */
struct smb2_fs_full_size_info {
__le64 TotalAllocationUnits;
__le64 CallerAvailableAllocationUnits;
__le64 ActualAvailableAllocationUnits;
__le32 SectorsPerAllocationUnit;
__le32 BytesPerSector;
} __packed;
#define SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001
#define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002
#define SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004
#define SSINFO_FLAGS_TRIM_ENABLED 0x00000008
/* sector size info struct */
struct smb3_fs_ss_info {
__le32 LogicalBytesPerSector;
__le32 PhysicalBytesPerSectorForAtomicity;
__le32 PhysicalBytesPerSectorForPerf;
__le32 FSEffPhysicalBytesPerSectorForAtomicity;
__le32 Flags;
__le32 ByteOffsetForSectorAlignment;
__le32 ByteOffsetForPartitionAlignment;
} __packed;
/* File System Control Information */
struct smb2_fs_control_info {
__le64 FreeSpaceStartFiltering;
__le64 FreeSpaceThreshold;
__le64 FreeSpaceStopFiltering;
__le64 DefaultQuotaThreshold;
__le64 DefaultQuotaLimit;
__le32 FileSystemControlFlags;
__le32 Padding;
} __packed;
/* volume info struct - see MS-FSCC 2.5.9 */
#define MAX_VOL_LABEL_LEN 32
struct smb3_fs_vol_info {
__le64 VolumeCreationTime;
__u32 VolumeSerialNumber;
__le32 VolumeLabelLength; /* includes trailing null */
__u8 SupportsObjects; /* True if eg like NTFS, supports objects */
__u8 Reserved;
__u8 VolumeLabel[]; /* variable len */
} __packed;
/* See MS-SMB2 2.2.23 through 2.2.25 */
struct smb2_oplock_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 24 */
__u8 OplockLevel;
__u8 Reserved;
__le32 Reserved2;
__u64 PersistentFid;
__u64 VolatileFid;
} __packed;
#define SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED cpu_to_le32(0x01)
struct smb2_lease_break {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 44 */
__le16 Epoch;
__le32 Flags;
__u8 LeaseKey[16];
__le32 CurrentLeaseState;
__le32 NewLeaseState;
__le32 BreakReason;
__le32 AccessMaskHint;
__le32 ShareMaskHint;
} __packed;
struct smb2_lease_ack {
struct smb2_hdr hdr;
__le16 StructureSize; /* Must be 36 */
__le16 Reserved;
__le32 Flags;
__u8 LeaseKey[16];
__le32 LeaseState;
__le64 LeaseDuration;
} __packed;
#define OP_BREAK_STRUCT_SIZE_20 24
#define OP_BREAK_STRUCT_SIZE_21 36
#endif /* _COMMON_SMB2PDU_H */ #endif /* _COMMON_SMB2PDU_H */