Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68889f26 authored by Pavel Shilovsky's avatar Pavel Shilovsky
Browse files

CIFS: Move is_path_accessible to ops struct

parent af4281dc
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -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 {
+5 −7
Original line number Original line Diff line number Diff line
@@ -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,
+30 −30
Original line number Original line Diff line number Diff line
@@ -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
/* 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 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
	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 @@ int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
			 (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,8 +3990,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,


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)
{
{
@@ -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 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,


	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 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
		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;
+6 −25
Original line number Original line Diff line number Diff line
@@ -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 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)


	/* 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;
+25 −0
Original line number Original line Diff line number Diff line
@@ -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 = {