Loading fs/cifs/cifsglob.h +3 −0 Original line number Diff line number Diff line Loading @@ -215,6 +215,9 @@ struct smb_version_operations { unsigned int *, const struct nls_table *, int); /* informational QFS call */ void (*qfs_tcon)(const unsigned int, struct cifs_tcon *); /* check if a path is accessible or not */ int (*is_path_accessible)(const unsigned int, struct cifs_tcon *, struct cifs_sb_info *, const char *); }; struct smb_version_values { Loading fs/cifs/cifsproto.h +5 −7 Original line number Diff line number Diff line Loading @@ -208,13 +208,11 @@ extern int CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, extern int CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, u16 netfid, FILE_ALL_INFO *pFindData); extern int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *findData, const char *search_Name, FILE_ALL_INFO *data, int legacy /* whether to use old info level */, const struct nls_table *nls_codepage, int remap); extern int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *findData, const char *search_name, FILE_ALL_INFO *data, const struct nls_table *nls_codepage, int remap); extern int CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, Loading fs/cifs/cifssmb.c +30 −30 Original line number Diff line number Diff line Loading @@ -3853,9 +3853,9 @@ CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, /* Legacy Query Path Information call for lookup to old servers such as Win9x/WinME */ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *pFinfo, int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, const char *search_name, FILE_ALL_INFO *data, const struct nls_table *nls_codepage, int remap) { QUERY_INFORMATION_REQ *pSMB; Loading @@ -3864,7 +3864,7 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, int bytes_returned; int name_len; cFYI(1, "In SMBQPath path %s", searchName); cFYI(1, "In SMBQPath path %s", search_name); QInfRetry: rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, (void **) &pSMBr); Loading @@ -3874,14 +3874,14 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, search_name, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; } else { name_len = strnlen(searchName, PATH_MAX); name_len = strnlen(search_name, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, search_name, name_len); } pSMB->BufferFormat = 0x04; name_len++; /* account for buffer type byte */ Loading @@ -3892,23 +3892,23 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cFYI(1, "Send error in QueryInfo = %d", rc); } else if (pFinfo) { } else if (data) { struct timespec ts; __u32 time = le32_to_cpu(pSMBr->last_write_time); /* decode response */ /* BB FIXME - add time zone adjustment BB */ memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); memset(data, 0, sizeof(FILE_ALL_INFO)); ts.tv_nsec = 0; ts.tv_sec = time; /* decode time fields */ pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); pFinfo->LastWriteTime = pFinfo->ChangeTime; pFinfo->LastAccessTime = 0; pFinfo->AllocationSize = data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); data->LastWriteTime = data->ChangeTime; data->LastAccessTime = 0; data->AllocationSize = cpu_to_le64(le32_to_cpu(pSMBr->size)); pFinfo->EndOfFile = pFinfo->AllocationSize; pFinfo->Attributes = data->EndOfFile = data->AllocationSize; data->Attributes = cpu_to_le32(le16_to_cpu(pSMBr->attr)); } else rc = -EIO; /* bad buffer passed in */ Loading Loading @@ -3990,8 +3990,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *pFindData, const char *search_name, FILE_ALL_INFO *data, int legacy /* old style infolevel */, const struct nls_table *nls_codepage, int remap) { Loading @@ -4003,7 +4002,7 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, int name_len; __u16 params, byte_count; /* cFYI(1, "In QPathInfo path %s", searchName); */ /* cFYI(1, "In QPathInfo path %s", search_name); */ QPathInfoRetry: rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); Loading @@ -4012,14 +4011,14 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ name_len = strnlen(searchName, PATH_MAX); name_len = strnlen(search_name, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, search_name, name_len); } params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; Loading Loading @@ -4064,20 +4063,21 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, else if (legacy && get_bcc(&pSMBr->hdr) < 24) rc = -EIO; /* 24 or 26 expected but we do not read last field */ else if (pFindData) { else if (data) { int size; __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); /* On legacy responses we do not read the last field, EAsize, fortunately since it varies by subdialect and also note it differs on Set vs. Get, ie two bytes or 4 bytes depending but we don't care here */ /* * On legacy responses we do not read the last field, * EAsize, fortunately since it varies by subdialect and * also note it differs on Set vs Get, ie two bytes or 4 * bytes depending but we don't care here. */ if (legacy) size = sizeof(FILE_INFO_STANDARD); else size = sizeof(FILE_ALL_INFO); memcpy((char *) pFindData, (char *) &pSMBr->hdr.Protocol + memcpy((char *) data, (char *) &pSMBr->hdr.Protocol + data_offset, size); } else rc = -ENOMEM; Loading fs/cifs/connect.c +6 −25 Original line number Diff line number Diff line Loading @@ -3402,30 +3402,6 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) return rsize; } static int is_path_accessible(unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path) { int rc; FILE_ALL_INFO *pfile_info; pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); if (pfile_info == NULL) return -ENOMEM; rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, 0 /* not legacy */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == -EOPNOTSUPP || rc == -EINVAL) rc = SMBQueryInformation(xid, tcon, full_path, pfile_info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); kfree(pfile_info); return rc; } static void cleanup_volume_info_contents(struct smb_vol *volume_info) { Loading Loading @@ -3703,13 +3679,18 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) /* check if a whole path is not remote */ if (!rc && tcon) { if (!server->ops->is_path_accessible) { rc = -ENOSYS; goto mount_fail_check; } /* build_path_to_root works only when we have a valid tcon */ full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon); if (full_path == NULL) { rc = -ENOMEM; goto mount_fail_check; } rc = is_path_accessible(xid, tcon, cifs_sb, full_path); rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, full_path); if (rc != 0 && rc != -EREMOTE) { kfree(full_path); goto mount_fail_check; Loading fs/cifs/smb1ops.c +25 −0 Original line number Diff line number Diff line Loading @@ -417,6 +417,30 @@ cifs_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) CIFSSMBQFSAttributeInfo(xid, tcon); } static int cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path) { int rc; FILE_ALL_INFO *file_info; file_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); if (file_info == NULL) return -ENOMEM; rc = CIFSSMBQPathInfo(xid, tcon, full_path, file_info, 0 /* not legacy */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == -EOPNOTSUPP || rc == -EINVAL) rc = SMBQueryInformation(xid, tcon, full_path, file_info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); kfree(file_info); return rc; } struct smb_version_operations smb1_operations = { .send_cancel = send_nt_cancel, .compare_fids = cifs_compare_fids, Loading @@ -443,6 +467,7 @@ struct smb_version_operations smb1_operations = { .tree_disconnect = CIFSSMBTDis, .get_dfs_refer = CIFSGetDFSRefer, .qfs_tcon = cifs_qfs_tcon, .is_path_accessible = cifs_is_path_accessible, }; struct smb_version_values smb1_values = { Loading Loading
fs/cifs/cifsglob.h +3 −0 Original line number Diff line number Diff line Loading @@ -215,6 +215,9 @@ struct smb_version_operations { unsigned int *, const struct nls_table *, int); /* informational QFS call */ void (*qfs_tcon)(const unsigned int, struct cifs_tcon *); /* check if a path is accessible or not */ int (*is_path_accessible)(const unsigned int, struct cifs_tcon *, struct cifs_sb_info *, const char *); }; struct smb_version_values { Loading
fs/cifs/cifsproto.h +5 −7 Original line number Diff line number Diff line Loading @@ -208,13 +208,11 @@ extern int CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, extern int CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, u16 netfid, FILE_ALL_INFO *pFindData); extern int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *findData, const char *search_Name, FILE_ALL_INFO *data, int legacy /* whether to use old info level */, const struct nls_table *nls_codepage, int remap); extern int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *findData, const char *search_name, FILE_ALL_INFO *data, const struct nls_table *nls_codepage, int remap); extern int CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, Loading
fs/cifs/cifssmb.c +30 −30 Original line number Diff line number Diff line Loading @@ -3853,9 +3853,9 @@ CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, /* Legacy Query Path Information call for lookup to old servers such as Win9x/WinME */ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *pFinfo, int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, const char *search_name, FILE_ALL_INFO *data, const struct nls_table *nls_codepage, int remap) { QUERY_INFORMATION_REQ *pSMB; Loading @@ -3864,7 +3864,7 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, int bytes_returned; int name_len; cFYI(1, "In SMBQPath path %s", searchName); cFYI(1, "In SMBQPath path %s", search_name); QInfRetry: rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, (void **) &pSMBr); Loading @@ -3874,14 +3874,14 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, PATH_MAX, nls_codepage, search_name, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; } else { name_len = strnlen(searchName, PATH_MAX); name_len = strnlen(search_name, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, search_name, name_len); } pSMB->BufferFormat = 0x04; name_len++; /* account for buffer type byte */ Loading @@ -3892,23 +3892,23 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cFYI(1, "Send error in QueryInfo = %d", rc); } else if (pFinfo) { } else if (data) { struct timespec ts; __u32 time = le32_to_cpu(pSMBr->last_write_time); /* decode response */ /* BB FIXME - add time zone adjustment BB */ memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); memset(data, 0, sizeof(FILE_ALL_INFO)); ts.tv_nsec = 0; ts.tv_sec = time; /* decode time fields */ pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); pFinfo->LastWriteTime = pFinfo->ChangeTime; pFinfo->LastAccessTime = 0; pFinfo->AllocationSize = data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); data->LastWriteTime = data->ChangeTime; data->LastAccessTime = 0; data->AllocationSize = cpu_to_le64(le32_to_cpu(pSMBr->size)); pFinfo->EndOfFile = pFinfo->AllocationSize; pFinfo->Attributes = data->EndOfFile = data->AllocationSize; data->Attributes = cpu_to_le32(le16_to_cpu(pSMBr->attr)); } else rc = -EIO; /* bad buffer passed in */ Loading Loading @@ -3990,8 +3990,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, const unsigned char *searchName, FILE_ALL_INFO *pFindData, const char *search_name, FILE_ALL_INFO *data, int legacy /* old style infolevel */, const struct nls_table *nls_codepage, int remap) { Loading @@ -4003,7 +4002,7 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, int name_len; __u16 params, byte_count; /* cFYI(1, "In QPathInfo path %s", searchName); */ /* cFYI(1, "In QPathInfo path %s", search_name); */ QPathInfoRetry: rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); Loading @@ -4012,14 +4011,14 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name, PATH_MAX, nls_codepage, remap); name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ name_len = strnlen(searchName, PATH_MAX); name_len = strnlen(search_name, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, search_name, name_len); } params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; Loading Loading @@ -4064,20 +4063,21 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, else if (legacy && get_bcc(&pSMBr->hdr) < 24) rc = -EIO; /* 24 or 26 expected but we do not read last field */ else if (pFindData) { else if (data) { int size; __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); /* On legacy responses we do not read the last field, EAsize, fortunately since it varies by subdialect and also note it differs on Set vs. Get, ie two bytes or 4 bytes depending but we don't care here */ /* * On legacy responses we do not read the last field, * EAsize, fortunately since it varies by subdialect and * also note it differs on Set vs Get, ie two bytes or 4 * bytes depending but we don't care here. */ if (legacy) size = sizeof(FILE_INFO_STANDARD); else size = sizeof(FILE_ALL_INFO); memcpy((char *) pFindData, (char *) &pSMBr->hdr.Protocol + memcpy((char *) data, (char *) &pSMBr->hdr.Protocol + data_offset, size); } else rc = -ENOMEM; Loading
fs/cifs/connect.c +6 −25 Original line number Diff line number Diff line Loading @@ -3402,30 +3402,6 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) return rsize; } static int is_path_accessible(unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path) { int rc; FILE_ALL_INFO *pfile_info; pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); if (pfile_info == NULL) return -ENOMEM; rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, 0 /* not legacy */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == -EOPNOTSUPP || rc == -EINVAL) rc = SMBQueryInformation(xid, tcon, full_path, pfile_info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); kfree(pfile_info); return rc; } static void cleanup_volume_info_contents(struct smb_vol *volume_info) { Loading Loading @@ -3703,13 +3679,18 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) /* check if a whole path is not remote */ if (!rc && tcon) { if (!server->ops->is_path_accessible) { rc = -ENOSYS; goto mount_fail_check; } /* build_path_to_root works only when we have a valid tcon */ full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon); if (full_path == NULL) { rc = -ENOMEM; goto mount_fail_check; } rc = is_path_accessible(xid, tcon, cifs_sb, full_path); rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, full_path); if (rc != 0 && rc != -EREMOTE) { kfree(full_path); goto mount_fail_check; Loading
fs/cifs/smb1ops.c +25 −0 Original line number Diff line number Diff line Loading @@ -417,6 +417,30 @@ cifs_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) CIFSSMBQFSAttributeInfo(xid, tcon); } static int cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path) { int rc; FILE_ALL_INFO *file_info; file_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); if (file_info == NULL) return -ENOMEM; rc = CIFSSMBQPathInfo(xid, tcon, full_path, file_info, 0 /* not legacy */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == -EOPNOTSUPP || rc == -EINVAL) rc = SMBQueryInformation(xid, tcon, full_path, file_info, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); kfree(file_info); return rc; } struct smb_version_operations smb1_operations = { .send_cancel = send_nt_cancel, .compare_fids = cifs_compare_fids, Loading @@ -443,6 +467,7 @@ struct smb_version_operations smb1_operations = { .tree_disconnect = CIFSSMBTDis, .get_dfs_refer = CIFSGetDFSRefer, .qfs_tcon = cifs_qfs_tcon, .is_path_accessible = cifs_is_path_accessible, }; struct smb_version_values smb1_values = { Loading