mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-13 01:08:50 +00:00
CIFS: Move is_path_accessible to ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
af4281dc22
commit
68889f269b
@ -215,6 +215,9 @@ struct smb_version_operations {
|
|||||||
unsigned int *, const struct nls_table *, int);
|
unsigned int *, const struct nls_table *, int);
|
||||||
/* informational QFS call */
|
/* informational QFS call */
|
||||||
void (*qfs_tcon)(const unsigned int, struct cifs_tcon *);
|
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 {
|
struct smb_version_values {
|
||||||
|
@ -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,
|
extern int CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
u16 netfid, FILE_ALL_INFO *pFindData);
|
u16 netfid, FILE_ALL_INFO *pFindData);
|
||||||
extern int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
extern int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
const unsigned char *searchName,
|
const char *search_Name, FILE_ALL_INFO *data,
|
||||||
FILE_ALL_INFO *findData,
|
|
||||||
int legacy /* whether to use old info level */,
|
int legacy /* whether to use old info level */,
|
||||||
const struct nls_table *nls_codepage, int remap);
|
const struct nls_table *nls_codepage, int remap);
|
||||||
extern int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
|
extern int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
const unsigned char *searchName,
|
const char *search_name, FILE_ALL_INFO *data,
|
||||||
FILE_ALL_INFO *findData,
|
|
||||||
const struct nls_table *nls_codepage, int remap);
|
const struct nls_table *nls_codepage, int remap);
|
||||||
|
|
||||||
extern int CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
extern int CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
|
@ -3853,9 +3853,9 @@ setCifsAclRetry:
|
|||||||
|
|
||||||
/* Legacy Query Path Information call for lookup to old servers such
|
/* Legacy Query Path Information call for lookup to old servers such
|
||||||
as Win9x/WinME */
|
as Win9x/WinME */
|
||||||
int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
|
int
|
||||||
const unsigned char *searchName,
|
SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
FILE_ALL_INFO *pFinfo,
|
const char *search_name, FILE_ALL_INFO *data,
|
||||||
const struct nls_table *nls_codepage, int remap)
|
const struct nls_table *nls_codepage, int remap)
|
||||||
{
|
{
|
||||||
QUERY_INFORMATION_REQ *pSMB;
|
QUERY_INFORMATION_REQ *pSMB;
|
||||||
@ -3864,7 +3864,7 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
int bytes_returned;
|
int bytes_returned;
|
||||||
int name_len;
|
int name_len;
|
||||||
|
|
||||||
cFYI(1, "In SMBQPath path %s", searchName);
|
cFYI(1, "In SMBQPath path %s", search_name);
|
||||||
QInfRetry:
|
QInfRetry:
|
||||||
rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
|
rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
|
||||||
(void **) &pSMBr);
|
(void **) &pSMBr);
|
||||||
@ -3874,14 +3874,14 @@ QInfRetry:
|
|||||||
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
|
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
|
||||||
name_len =
|
name_len =
|
||||||
cifsConvertToUTF16((__le16 *) pSMB->FileName,
|
cifsConvertToUTF16((__le16 *) pSMB->FileName,
|
||||||
searchName, PATH_MAX, nls_codepage,
|
search_name, PATH_MAX, nls_codepage,
|
||||||
remap);
|
remap);
|
||||||
name_len++; /* trailing null */
|
name_len++; /* trailing null */
|
||||||
name_len *= 2;
|
name_len *= 2;
|
||||||
} else {
|
} else {
|
||||||
name_len = strnlen(searchName, PATH_MAX);
|
name_len = strnlen(search_name, PATH_MAX);
|
||||||
name_len++; /* trailing null */
|
name_len++; /* trailing null */
|
||||||
strncpy(pSMB->FileName, searchName, name_len);
|
strncpy(pSMB->FileName, search_name, name_len);
|
||||||
}
|
}
|
||||||
pSMB->BufferFormat = 0x04;
|
pSMB->BufferFormat = 0x04;
|
||||||
name_len++; /* account for buffer type byte */
|
name_len++; /* account for buffer type byte */
|
||||||
@ -3892,23 +3892,23 @@ QInfRetry:
|
|||||||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, "Send error in QueryInfo = %d", rc);
|
cFYI(1, "Send error in QueryInfo = %d", rc);
|
||||||
} else if (pFinfo) {
|
} else if (data) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
__u32 time = le32_to_cpu(pSMBr->last_write_time);
|
__u32 time = le32_to_cpu(pSMBr->last_write_time);
|
||||||
|
|
||||||
/* decode response */
|
/* decode response */
|
||||||
/* BB FIXME - add time zone adjustment BB */
|
/* 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_nsec = 0;
|
||||||
ts.tv_sec = time;
|
ts.tv_sec = time;
|
||||||
/* decode time fields */
|
/* decode time fields */
|
||||||
pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
|
data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
|
||||||
pFinfo->LastWriteTime = pFinfo->ChangeTime;
|
data->LastWriteTime = data->ChangeTime;
|
||||||
pFinfo->LastAccessTime = 0;
|
data->LastAccessTime = 0;
|
||||||
pFinfo->AllocationSize =
|
data->AllocationSize =
|
||||||
cpu_to_le64(le32_to_cpu(pSMBr->size));
|
cpu_to_le64(le32_to_cpu(pSMBr->size));
|
||||||
pFinfo->EndOfFile = pFinfo->AllocationSize;
|
data->EndOfFile = data->AllocationSize;
|
||||||
pFinfo->Attributes =
|
data->Attributes =
|
||||||
cpu_to_le32(le16_to_cpu(pSMBr->attr));
|
cpu_to_le32(le16_to_cpu(pSMBr->attr));
|
||||||
} else
|
} else
|
||||||
rc = -EIO; /* bad buffer passed in */
|
rc = -EIO; /* bad buffer passed in */
|
||||||
@ -3990,12 +3990,11 @@ QFileInfoRetry:
|
|||||||
|
|
||||||
int
|
int
|
||||||
CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
const unsigned char *searchName,
|
const char *search_name, FILE_ALL_INFO *data,
|
||||||
FILE_ALL_INFO *pFindData,
|
|
||||||
int legacy /* old style infolevel */,
|
int legacy /* old style infolevel */,
|
||||||
const struct nls_table *nls_codepage, int remap)
|
const struct nls_table *nls_codepage, int remap)
|
||||||
{
|
{
|
||||||
/* level 263 SMB_QUERY_FILE_ALL_INFO */
|
/* level 263 SMB_QUERY_FILE_ALL_INFO */
|
||||||
TRANSACTION2_QPI_REQ *pSMB = NULL;
|
TRANSACTION2_QPI_REQ *pSMB = NULL;
|
||||||
TRANSACTION2_QPI_RSP *pSMBr = NULL;
|
TRANSACTION2_QPI_RSP *pSMBr = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@ -4003,7 +4002,7 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
int name_len;
|
int name_len;
|
||||||
__u16 params, byte_count;
|
__u16 params, byte_count;
|
||||||
|
|
||||||
/* cFYI(1, "In QPathInfo path %s", searchName); */
|
/* cFYI(1, "In QPathInfo path %s", search_name); */
|
||||||
QPathInfoRetry:
|
QPathInfoRetry:
|
||||||
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
|
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
|
||||||
(void **) &pSMBr);
|
(void **) &pSMBr);
|
||||||
@ -4012,14 +4011,14 @@ QPathInfoRetry:
|
|||||||
|
|
||||||
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
|
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
|
||||||
name_len =
|
name_len =
|
||||||
cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
|
cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name,
|
||||||
PATH_MAX, nls_codepage, remap);
|
PATH_MAX, nls_codepage, remap);
|
||||||
name_len++; /* trailing null */
|
name_len++; /* trailing null */
|
||||||
name_len *= 2;
|
name_len *= 2;
|
||||||
} else { /* BB improve the check for buffer overruns BB */
|
} 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 */
|
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 */;
|
params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
|
||||||
@ -4064,20 +4063,21 @@ QPathInfoRetry:
|
|||||||
else if (legacy && get_bcc(&pSMBr->hdr) < 24)
|
else if (legacy && get_bcc(&pSMBr->hdr) < 24)
|
||||||
rc = -EIO; /* 24 or 26 expected but we do not read
|
rc = -EIO; /* 24 or 26 expected but we do not read
|
||||||
last field */
|
last field */
|
||||||
else if (pFindData) {
|
else if (data) {
|
||||||
int size;
|
int size;
|
||||||
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
__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
|
* On legacy responses we do not read the last field,
|
||||||
also note it differs on Set vs. Get, ie two bytes or 4
|
* EAsize, fortunately since it varies by subdialect and
|
||||||
bytes depending but we don't care here */
|
* also note it differs on Set vs Get, ie two bytes or 4
|
||||||
|
* bytes depending but we don't care here.
|
||||||
|
*/
|
||||||
if (legacy)
|
if (legacy)
|
||||||
size = sizeof(FILE_INFO_STANDARD);
|
size = sizeof(FILE_INFO_STANDARD);
|
||||||
else
|
else
|
||||||
size = sizeof(FILE_ALL_INFO);
|
size = sizeof(FILE_ALL_INFO);
|
||||||
memcpy((char *) pFindData,
|
memcpy((char *) data, (char *) &pSMBr->hdr.Protocol +
|
||||||
(char *) &pSMBr->hdr.Protocol +
|
|
||||||
data_offset, size);
|
data_offset, size);
|
||||||
} else
|
} else
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
|
@ -3402,30 +3402,6 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
|
|||||||
return rsize;
|
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
|
static void
|
||||||
cleanup_volume_info_contents(struct smb_vol *volume_info)
|
cleanup_volume_info_contents(struct smb_vol *volume_info)
|
||||||
{
|
{
|
||||||
@ -3703,13 +3679,18 @@ remote_path_check:
|
|||||||
|
|
||||||
/* check if a whole path is not remote */
|
/* check if a whole path is not remote */
|
||||||
if (!rc && tcon) {
|
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 */
|
/* build_path_to_root works only when we have a valid tcon */
|
||||||
full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
|
full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
|
||||||
if (full_path == NULL) {
|
if (full_path == NULL) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto mount_fail_check;
|
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) {
|
if (rc != 0 && rc != -EREMOTE) {
|
||||||
kfree(full_path);
|
kfree(full_path);
|
||||||
goto mount_fail_check;
|
goto mount_fail_check;
|
||||||
|
@ -417,6 +417,30 @@ cifs_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
|||||||
CIFSSMBQFSAttributeInfo(xid, 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 = {
|
struct smb_version_operations smb1_operations = {
|
||||||
.send_cancel = send_nt_cancel,
|
.send_cancel = send_nt_cancel,
|
||||||
.compare_fids = cifs_compare_fids,
|
.compare_fids = cifs_compare_fids,
|
||||||
@ -443,6 +467,7 @@ struct smb_version_operations smb1_operations = {
|
|||||||
.tree_disconnect = CIFSSMBTDis,
|
.tree_disconnect = CIFSSMBTDis,
|
||||||
.get_dfs_refer = CIFSGetDFSRefer,
|
.get_dfs_refer = CIFSGetDFSRefer,
|
||||||
.qfs_tcon = cifs_qfs_tcon,
|
.qfs_tcon = cifs_qfs_tcon,
|
||||||
|
.is_path_accessible = cifs_is_path_accessible,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct smb_version_values smb1_values = {
|
struct smb_version_values smb1_values = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user