diff options
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r-- | fs/cifs/smb2pdu.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index f58e4dc3987b..c8cd7b6cdda2 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1873,10 +1873,21 @@ create_reconnect_durable_buf(struct cifs_fid *fid) | |||
1873 | return buf; | 1873 | return buf; |
1874 | } | 1874 | } |
1875 | 1875 | ||
1876 | __u8 | 1876 | static void |
1877 | smb2_parse_lease_state(struct TCP_Server_Info *server, | 1877 | parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf) |
1878 | { | ||
1879 | struct create_on_disk_id *pdisk_id = (struct create_on_disk_id *)cc; | ||
1880 | |||
1881 | cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n", | ||
1882 | pdisk_id->DiskFileId, pdisk_id->VolumeId); | ||
1883 | buf->IndexNumber = pdisk_id->DiskFileId; | ||
1884 | } | ||
1885 | |||
1886 | void | ||
1887 | smb2_parse_contexts(struct TCP_Server_Info *server, | ||
1878 | struct smb2_create_rsp *rsp, | 1888 | struct smb2_create_rsp *rsp, |
1879 | unsigned int *epoch, char *lease_key) | 1889 | unsigned int *epoch, char *lease_key, __u8 *oplock, |
1890 | struct smb2_file_all_info *buf) | ||
1880 | { | 1891 | { |
1881 | char *data_offset; | 1892 | char *data_offset; |
1882 | struct create_context *cc; | 1893 | struct create_context *cc; |
@@ -1884,15 +1895,24 @@ smb2_parse_lease_state(struct TCP_Server_Info *server, | |||
1884 | unsigned int remaining; | 1895 | unsigned int remaining; |
1885 | char *name; | 1896 | char *name; |
1886 | 1897 | ||
1898 | *oplock = 0; | ||
1887 | data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset); | 1899 | data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset); |
1888 | remaining = le32_to_cpu(rsp->CreateContextsLength); | 1900 | remaining = le32_to_cpu(rsp->CreateContextsLength); |
1889 | cc = (struct create_context *)data_offset; | 1901 | cc = (struct create_context *)data_offset; |
1902 | |||
1903 | /* Initialize inode number to 0 in case no valid data in qfid context */ | ||
1904 | if (buf) | ||
1905 | buf->IndexNumber = 0; | ||
1906 | |||
1890 | while (remaining >= sizeof(struct create_context)) { | 1907 | while (remaining >= sizeof(struct create_context)) { |
1891 | name = le16_to_cpu(cc->NameOffset) + (char *)cc; | 1908 | name = le16_to_cpu(cc->NameOffset) + (char *)cc; |
1892 | if (le16_to_cpu(cc->NameLength) == 4 && | 1909 | if (le16_to_cpu(cc->NameLength) == 4 && |
1893 | strncmp(name, "RqLs", 4) == 0) | 1910 | strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4) == 0) |
1894 | return server->ops->parse_lease_buf(cc, epoch, | 1911 | *oplock = server->ops->parse_lease_buf(cc, epoch, |
1895 | lease_key); | 1912 | lease_key); |
1913 | else if (buf && (le16_to_cpu(cc->NameLength) == 4) && | ||
1914 | strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0) | ||
1915 | parse_query_id_ctxt(cc, buf); | ||
1896 | 1916 | ||
1897 | next = le32_to_cpu(cc->Next); | 1917 | next = le32_to_cpu(cc->Next); |
1898 | if (!next) | 1918 | if (!next) |
@@ -1901,7 +1921,10 @@ smb2_parse_lease_state(struct TCP_Server_Info *server, | |||
1901 | cc = (struct create_context *)((char *)cc + next); | 1921 | cc = (struct create_context *)((char *)cc + next); |
1902 | } | 1922 | } |
1903 | 1923 | ||
1904 | return 0; | 1924 | if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) |
1925 | *oplock = rsp->OplockLevel; | ||
1926 | |||
1927 | return; | ||
1905 | } | 1928 | } |
1906 | 1929 | ||
1907 | static int | 1930 | static int |
@@ -2588,12 +2611,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | |||
2588 | buf->DeletePending = 0; | 2611 | buf->DeletePending = 0; |
2589 | } | 2612 | } |
2590 | 2613 | ||
2591 | if (rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) | 2614 | |
2592 | *oplock = smb2_parse_lease_state(server, rsp, | 2615 | smb2_parse_contexts(server, rsp, &oparms->fid->epoch, |
2593 | &oparms->fid->epoch, | 2616 | oparms->fid->lease_key, oplock, buf); |
2594 | oparms->fid->lease_key); | ||
2595 | else | ||
2596 | *oplock = rsp->OplockLevel; | ||
2597 | creat_exit: | 2617 | creat_exit: |
2598 | SMB2_open_free(&rqst); | 2618 | SMB2_open_free(&rqst); |
2599 | free_rsp_buf(resp_buftype, rsp); | 2619 | free_rsp_buf(resp_buftype, rsp); |