diff options
Diffstat (limited to 'fs/cifs/netmisc.c')
| -rw-r--r-- | fs/cifs/netmisc.c | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index bd6d6895730..6834b9c3bec 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -51,7 +51,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = { {ERRnoaccess, -EACCES}, {ERRbadfid, -EBADF}, {ERRbadmcb, -EIO}, - {ERRnomem, -ENOMEM}, + {ERRnomem, -EREMOTEIO}, {ERRbadmem, -EFAULT}, {ERRbadenv, -EFAULT}, {ERRbadformat, -EINVAL}, @@ -61,7 +61,8 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = { {ERRremcd, -EACCES}, {ERRdiffdevice, -EXDEV}, {ERRnofiles, -ENOENT}, - {ERRbadshare, -ETXTBSY}, + {ERRwriteprot, -EROFS}, + {ERRbadshare, -EBUSY}, {ERRlock, -EACCES}, {ERRunsup, -EINVAL}, {ERRnosuchshare, -ENXIO}, @@ -109,7 +110,7 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = { {ERRnoroom, -ENOSPC}, {ERRrmuns, -EUSERS}, {ERRtimeout, -ETIME}, - {ERRnoresource, -ENOBUFS}, + {ERRnoresource, -EREMOTEIO}, {ERRtoomanyuids, -EUSERS}, {ERRbaduid, -EACCES}, {ERRusempx, -EIO}, @@ -139,17 +140,18 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { * Returns 0 on failure. */ static int -cifs_inet_pton(const int address_family, const char *cp, void *dst) +cifs_inet_pton(const int address_family, const char *cp, int len, void *dst) { int ret = 0; /* calculate length by finding first slash or NULL */ if (address_family == AF_INET) - ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL); + ret = in4_pton(cp, len, dst, '\\', NULL); else if (address_family == AF_INET6) - ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); + ret = in6_pton(cp, len, dst , '\\', NULL); - cFYI(DBG2, ("address conversion returned %d for %s", ret, cp)); + cifs_dbg(NOISY, "address conversion returned %d for %*.*s\n", + ret, len, len, cp); if (ret > 0) ret = 1; return ret; @@ -164,43 +166,57 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst) * Returns 0 on failure. */ int -cifs_convert_address(char *src, void *dst) +cifs_convert_address(struct sockaddr *dst, const char *src, int len) { - int rc; - char *pct, *endp; + int rc, alen, slen; + const char *pct; + char scope_id[13]; struct sockaddr_in *s4 = (struct sockaddr_in *) dst; struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst; /* IPv4 address */ - if (cifs_inet_pton(AF_INET, src, &s4->sin_addr.s_addr)) { + if (cifs_inet_pton(AF_INET, src, len, &s4->sin_addr.s_addr)) { s4->sin_family = AF_INET; return 1; } - /* temporarily terminate string */ - pct = strchr(src, '%'); - if (pct) - *pct = '\0'; - - rc = cifs_inet_pton(AF_INET6, src, &s6->sin6_addr.s6_addr); - - /* repair temp termination (if any) and make pct point to scopeid */ - if (pct) - *pct++ = '%'; + /* attempt to exclude the scope ID from the address part */ + pct = memchr(src, '%', len); + alen = pct ? pct - src : len; + rc = cifs_inet_pton(AF_INET6, src, alen, &s6->sin6_addr.s6_addr); if (!rc) return rc; s6->sin6_family = AF_INET6; if (pct) { - s6->sin6_scope_id = (u32) simple_strtoul(pct, &endp, 0); - if (!*pct || *endp) + /* grab the scope ID */ + slen = len - (alen + 1); + if (slen <= 0 || slen > 12) return 0; + memcpy(scope_id, pct + 1, slen); + scope_id[slen] = '\0'; + + rc = kstrtouint(scope_id, 0, &s6->sin6_scope_id); + rc = (rc == 0) ? 1 : 0; } return rc; } +void +cifs_set_port(struct sockaddr *addr, const unsigned short int port) +{ + switch (addr->sa_family) { + case AF_INET: + ((struct sockaddr_in *)addr)->sin_port = htons(port); + break; + case AF_INET6: + ((struct sockaddr_in6 *)addr)->sin6_port = htons(port); + break; + } +} + /***************************************************************************** convert a NT status code to a dos class/code *****************************************************************************/ @@ -384,7 +400,7 @@ static const struct { from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */ { - ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, { + ERRDOS, ERRnoresource, NT_STATUS_INSUFFICIENT_RESOURCES}, { ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, { ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, { ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, { @@ -654,7 +670,7 @@ static const struct { ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, { ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, { ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, { - ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, { + ERRDOS, ERRnoresource, NT_STATUS_INSUFF_SERVER_RESOURCES}, { ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, { ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, { ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, { @@ -764,7 +780,9 @@ static const struct { ERRDOS, ERRnoaccess, 0xc0000290}, { ERRDOS, ERRbadfunc, 0xc000029c}, { ERRDOS, ERRsymlink, NT_STATUS_STOPPED_ON_SYMLINK}, { - ERRDOS, ERRinvlevel, 0x007c0001}, }; + ERRDOS, ERRinvlevel, 0x007c0001}, { + 0, 0, 0 } +}; /***************************************************************************** Print an error message from the status code @@ -777,8 +795,8 @@ cifs_print_status(__u32 status_code) while (nt_errs[idx].nt_errstr != NULL) { if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) == (status_code & 0xFFFFFF)) { - printk(KERN_NOTICE "Status code returned 0x%08x %s\n", - status_code, nt_errs[idx].nt_errstr); + pr_notice("Status code returned 0x%08x %s\n", + status_code, nt_errs[idx].nt_errstr); } idx++; } @@ -807,8 +825,9 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode) } int -map_smb_to_linux_error(struct smb_hdr *smb, int logErr) +map_smb_to_linux_error(char *buf, bool logErr) { + struct smb_hdr *smb = (struct smb_hdr *)buf; unsigned int i; int rc = -EIO; /* if transport error smb error may not be set */ __u8 smberrclass; @@ -870,8 +889,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) } /* else ERRHRD class errors or junk - return EIO */ - cFYI(1, ("Mapping smb error code %d to POSIX err %d", - smberrcode, rc)); + 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 */ @@ -884,17 +903,11 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) * portion, the number of word parameters and the data portion of the message */ unsigned int -smbCalcSize(struct smb_hdr *ptr) +smbCalcSize(void *buf) { + struct smb_hdr *ptr = (struct smb_hdr *)buf; return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + - 2 /* size of the bcc field */ + BCC(ptr)); -} - -unsigned int -smbCalcSize_LE(struct smb_hdr *ptr) -{ - return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) + - 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr))); + 2 /* size of the bcc field */ + get_bcc(ptr)); } /* The following are taken from fs/ntfs/util.c */ @@ -928,8 +941,9 @@ cifs_UnixTimeToNT(struct timespec t) return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; } -static int total_days_of_prev_months[] = -{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +static const int total_days_of_prev_months[] = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 +}; struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) { @@ -940,20 +954,20 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) SMB_TIME *st = (SMB_TIME *)&time; SMB_DATE *sd = (SMB_DATE *)&date; - cFYI(1, ("date %d time %d", date, time)); + cifs_dbg(FYI, "date %d time %d\n", date, time); sec = 2 * st->TwoSeconds; min = st->Minutes; if ((sec > 59) || (min > 59)) - cERROR(1, ("illegal time min %d sec %d", min, sec)); + cifs_dbg(VFS, "illegal time min %d sec %d\n", min, sec); sec += (min * 60); sec += 60 * 60 * st->Hours; if (st->Hours > 24) - cERROR(1, ("illegal hours %d", st->Hours)); + cifs_dbg(VFS, "illegal hours %d\n", st->Hours); days = sd->Day; month = sd->Month; if ((days > 31) || (month > 12)) { - cERROR(1, ("illegal date, month %d day: %d", month, days)); + cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days); if (month > 12) month = 12; } @@ -979,7 +993,7 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) ts.tv_sec = sec + offset; - /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ + /* cifs_dbg(FYI, "sec after cnvrt dos to unix time %d\n",sec); */ ts.tv_nsec = 0; return ts; |
