aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2pdu.c
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-12-26 13:58:46 -0500
committerPavel Shilovsky <pshilovsky@samba.org>2012-07-24 13:55:05 -0400
commit2503a0dba989486c59523a947a1dcb50ad90fee9 (patch)
tree1e79a740d744cee1a1981e4d0a355303ffc9a4d2 /fs/cifs/smb2pdu.c
parent68889f269b16a11866f4ec71e8177bdd0c184a3f (diff)
CIFS: Add SMB2 support for is_path_accessible
that needs for a successful mount through SMB2 protocol. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r--fs/cifs/smb2pdu.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 48c04b2832e2..ef0769c398a5 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -829,3 +829,135 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
829 829
830 return rc; 830 return rc;
831} 831}
832
833int
834SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
835 u64 *persistent_fid, u64 *volatile_fid, __u32 desired_access,
836 __u32 create_disposition, __u32 file_attributes, __u32 create_options)
837{
838 struct smb2_create_req *req;
839 struct smb2_create_rsp *rsp;
840 struct TCP_Server_Info *server;
841 struct cifs_ses *ses = tcon->ses;
842 struct kvec iov[2];
843 int resp_buftype;
844 int uni_path_len;
845 int rc = 0;
846 int num_iovecs = 2;
847
848 cFYI(1, "create/open");
849
850 if (ses && (ses->server))
851 server = ses->server;
852 else
853 return -EIO;
854
855 rc = small_smb2_init(SMB2_CREATE, tcon, (void **) &req);
856 if (rc)
857 return rc;
858
859 if (enable_oplocks)
860 req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_BATCH;
861 else
862 req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE;
863 req->ImpersonationLevel = IL_IMPERSONATION;
864 req->DesiredAccess = cpu_to_le32(desired_access);
865 /* File attributes ignored on open (used in create though) */
866 req->FileAttributes = cpu_to_le32(file_attributes);
867 req->ShareAccess = FILE_SHARE_ALL_LE;
868 req->CreateDisposition = cpu_to_le32(create_disposition);
869 req->CreateOptions = cpu_to_le32(create_options);
870 uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
871 req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req)
872 - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
873
874 iov[0].iov_base = (char *)req;
875 /* 4 for rfc1002 length field */
876 iov[0].iov_len = get_rfc1002_length(req) + 4;
877
878 /* MUST set path len (NameLength) to 0 opening root of share */
879 if (uni_path_len >= 4) {
880 req->NameLength = cpu_to_le16(uni_path_len - 2);
881 /* -1 since last byte is buf[0] which is sent below (path) */
882 iov[0].iov_len--;
883 iov[1].iov_len = uni_path_len;
884 iov[1].iov_base = path;
885 /*
886 * -1 since last byte is buf[0] which was counted in
887 * smb2_buf_len.
888 */
889 inc_rfc1001_len(req, uni_path_len - 1);
890 } else {
891 num_iovecs = 1;
892 req->NameLength = 0;
893 }
894
895 rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0);
896 rsp = (struct smb2_create_rsp *)iov[0].iov_base;
897
898 if (rc != 0) {
899 cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
900 goto creat_exit;
901 }
902
903 if (rsp == NULL) {
904 rc = -EIO;
905 goto creat_exit;
906 }
907 *persistent_fid = rsp->PersistentFileId;
908 *volatile_fid = rsp->VolatileFileId;
909creat_exit:
910 free_rsp_buf(resp_buftype, rsp);
911 return rc;
912}
913
914int
915SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
916 u64 persistent_fid, u64 volatile_fid)
917{
918 struct smb2_close_req *req;
919 struct smb2_close_rsp *rsp;
920 struct TCP_Server_Info *server;
921 struct cifs_ses *ses = tcon->ses;
922 struct kvec iov[1];
923 int resp_buftype;
924 int rc = 0;
925
926 cFYI(1, "Close");
927
928 if (ses && (ses->server))
929 server = ses->server;
930 else
931 return -EIO;
932
933 rc = small_smb2_init(SMB2_CLOSE, tcon, (void **) &req);
934 if (rc)
935 return rc;
936
937 req->PersistentFileId = persistent_fid;
938 req->VolatileFileId = volatile_fid;
939
940 iov[0].iov_base = (char *)req;
941 /* 4 for rfc1002 length field */
942 iov[0].iov_len = get_rfc1002_length(req) + 4;
943
944 rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0);
945 rsp = (struct smb2_close_rsp *)iov[0].iov_base;
946
947 if (rc != 0) {
948 if (tcon)
949 cifs_stats_fail_inc(tcon, SMB2_CLOSE_HE);
950 goto close_exit;
951 }
952
953 if (rsp == NULL) {
954 rc = -EIO;
955 goto close_exit;
956 }
957
958 /* BB FIXME - decode close response, update inode for caching */
959
960close_exit:
961 free_rsp_buf(resp_buftype, rsp);
962 return rc;
963}