fs/smb/client/smb1maperror.c

Source file repositories/reference/linux-study-clean/fs/smb/client/smb1maperror.c

File Facts

System
Linux kernel
Corpus path
fs/smb/client/smb1maperror.c
Extension
.c
Size
7975 bytes
Lines
287
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (map) {
			if ((logErr && err != NT_STATUS_MORE_PROCESSING_REQUIRED) ||
			    (cifsFYI & CIFS_RC))
				pr_notice("Status code returned 0x%08x %s\n",
					  map->ntstatus, map->nt_errstr);

			smberrclass = map->dos_class;
			smberrcode = map->dos_code;
		} else {
			smberrclass = ERRHRD;
			smberrcode = ERRgeneral;
		}
	} else {
		smberrclass = smb->Status.DosError.ErrorClass;
		smberrcode = le16_to_cpu(smb->Status.DosError.Error);
	}

	/* old style errors */

	if (smberrclass == ERRDOS) {
		/* DOS class smb error codes - map DOS */
		/* 1 byte field no need to byte reverse */
		err_map = search_mapping_table_ERRDOS(smberrcode);
	} else if (smberrclass == ERRSRV) {
		/* server class of error codes */
		err_map = search_mapping_table_ERRSRV(smberrcode);
	}
	if (err_map)
		rc = err_map->posix_code;
	/* else ERRHRD class errors or junk  - return EIO */

	/* special cases for NT status codes which cannot be translated to DOS codes */
	if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
		__u32 err = le32_to_cpu(smb->Status.CifsError);
		if (err == (NT_STATUS_NOT_A_REPARSE_POINT))
			rc = -ENODATA;
		else if (err == (NT_STATUS_PRIVILEGE_NOT_HELD))
			rc = -EPERM;
	}

	cifs_dbg(FYI, "Mapping smb error code 0x%x to POSIX err %d\n",
		 le32_to_cpu(smb->Status.CifsError), rc);

	/* generic corrective action e.g. reconnect SMB session on
	 * ERRbaduid could be added */

	if (rc == -EIO)
		smb_EIO2(smb_eio_trace_smb1_received_error,
			 le32_to_cpu(smb->Status.CifsError),
			 le16_to_cpu(smb->Flags2));
	return rc;
}

int
map_and_check_smb_error(struct TCP_Server_Info *server,
			struct mid_q_entry *mid, bool logErr)
{
	int rc;
	struct smb_hdr *smb = (struct smb_hdr *)mid->resp_buf;

	rc = map_smb_to_linux_error((char *)smb, logErr);
	if (rc == -EACCES && !(smb->Flags2 & SMBFLG2_ERR_STATUS)) {
		/* possible ERRBaduid */
		__u8 class = smb->Status.DosError.ErrorClass;
		__u16 code = le16_to_cpu(smb->Status.DosError.Error);

		/* switch can be used to handle different errors */
		if (class == ERRSRV && code == ERRbaduid) {
			cifs_dbg(FYI, "Server returned 0x%x, reconnecting session...\n",
				code);
			cifs_signal_cifsd_for_reconnect(server, false);
		}
	}

	return rc;
}

#define DEFINE_CHECK_SORT_FUNC(__array, __field)			\
static int __init __array ## _is_sorted(void)				\
{									\
	unsigned int i;							\
									\
	/* Check whether the array is sorted in ascending order */	\
	for (i = 1; i < ARRAY_SIZE(__array); i++) {			\
		if (__array[i].__field >=				\
		    __array[i - 1].__field)				\
			continue;					\
									\
		pr_err(#__array " array order is incorrect\n");		\
		return -EINVAL;						\

Annotation

Implementation Notes