diff options
| -rw-r--r-- | fs/cifs/cifs_unicode.c | 22 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 9 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 6 |
3 files changed, 37 insertions, 0 deletions
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 53cf2aabce87..71d5d0a5f6b2 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
| @@ -203,6 +203,27 @@ cifs_strtoUTF16(__le16 *to, const char *from, int len, | |||
| 203 | int i; | 203 | int i; |
| 204 | wchar_t wchar_to; /* needed to quiet sparse */ | 204 | wchar_t wchar_to; /* needed to quiet sparse */ |
| 205 | 205 | ||
| 206 | /* special case for utf8 to handle no plane0 chars */ | ||
| 207 | if (!strcmp(codepage->charset, "utf8")) { | ||
| 208 | /* | ||
| 209 | * convert utf8 -> utf16, we assume we have enough space | ||
| 210 | * as caller should have assumed conversion does not overflow | ||
| 211 | * in destination len is length in wchar_t units (16bits) | ||
| 212 | */ | ||
| 213 | i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN, | ||
| 214 | (wchar_t *) to, len); | ||
| 215 | |||
| 216 | /* if success terminate and exit */ | ||
| 217 | if (i >= 0) | ||
| 218 | goto success; | ||
| 219 | /* | ||
| 220 | * if fails fall back to UCS encoding as this | ||
| 221 | * function should not return negative values | ||
| 222 | * currently can fail only if source contains | ||
| 223 | * invalid encoded characters | ||
| 224 | */ | ||
| 225 | } | ||
| 226 | |||
| 206 | for (i = 0; len && *from; i++, from += charlen, len -= charlen) { | 227 | for (i = 0; len && *from; i++, from += charlen, len -= charlen) { |
| 207 | charlen = codepage->char2uni(from, len, &wchar_to); | 228 | charlen = codepage->char2uni(from, len, &wchar_to); |
| 208 | if (charlen < 1) { | 229 | if (charlen < 1) { |
| @@ -215,6 +236,7 @@ cifs_strtoUTF16(__le16 *to, const char *from, int len, | |||
| 215 | put_unaligned_le16(wchar_to, &to[i]); | 236 | put_unaligned_le16(wchar_to, &to[i]); |
| 216 | } | 237 | } |
| 217 | 238 | ||
| 239 | success: | ||
| 218 | put_unaligned_le16(0, &to[i]); | 240 | put_unaligned_le16(0, &to[i]); |
| 219 | return i; | 241 | return i; |
| 220 | } | 242 | } |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 2fdbe08a7a23..5c670b998ffb 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -67,6 +67,7 @@ enum { | |||
| 67 | /* Mount options that take no arguments */ | 67 | /* Mount options that take no arguments */ |
| 68 | Opt_user_xattr, Opt_nouser_xattr, | 68 | Opt_user_xattr, Opt_nouser_xattr, |
| 69 | Opt_forceuid, Opt_noforceuid, | 69 | Opt_forceuid, Opt_noforceuid, |
| 70 | Opt_forcegid, Opt_noforcegid, | ||
| 70 | Opt_noblocksend, Opt_noautotune, | 71 | Opt_noblocksend, Opt_noautotune, |
| 71 | Opt_hard, Opt_soft, Opt_perm, Opt_noperm, | 72 | Opt_hard, Opt_soft, Opt_perm, Opt_noperm, |
| 72 | Opt_mapchars, Opt_nomapchars, Opt_sfu, | 73 | Opt_mapchars, Opt_nomapchars, Opt_sfu, |
| @@ -117,6 +118,8 @@ static const match_table_t cifs_mount_option_tokens = { | |||
| 117 | { Opt_nouser_xattr, "nouser_xattr" }, | 118 | { Opt_nouser_xattr, "nouser_xattr" }, |
| 118 | { Opt_forceuid, "forceuid" }, | 119 | { Opt_forceuid, "forceuid" }, |
| 119 | { Opt_noforceuid, "noforceuid" }, | 120 | { Opt_noforceuid, "noforceuid" }, |
| 121 | { Opt_forcegid, "forcegid" }, | ||
| 122 | { Opt_noforcegid, "noforcegid" }, | ||
| 120 | { Opt_noblocksend, "noblocksend" }, | 123 | { Opt_noblocksend, "noblocksend" }, |
| 121 | { Opt_noautotune, "noautotune" }, | 124 | { Opt_noautotune, "noautotune" }, |
| 122 | { Opt_hard, "hard" }, | 125 | { Opt_hard, "hard" }, |
| @@ -1195,6 +1198,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
| 1195 | case Opt_noforceuid: | 1198 | case Opt_noforceuid: |
| 1196 | override_uid = 0; | 1199 | override_uid = 0; |
| 1197 | break; | 1200 | break; |
| 1201 | case Opt_forcegid: | ||
| 1202 | override_gid = 1; | ||
| 1203 | break; | ||
| 1204 | case Opt_noforcegid: | ||
| 1205 | override_gid = 0; | ||
| 1206 | break; | ||
| 1198 | case Opt_noblocksend: | 1207 | case Opt_noblocksend: |
| 1199 | vol->noblocksnd = 1; | 1208 | vol->noblocksnd = 1; |
| 1200 | break; | 1209 | break; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 2126ab185045..76d974c952fe 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -183,6 +183,12 @@ smb_send_kvec(struct TCP_Server_Info *server, struct kvec *iov, size_t n_vec, | |||
| 183 | rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec], | 183 | rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec], |
| 184 | n_vec - first_vec, remaining); | 184 | n_vec - first_vec, remaining); |
| 185 | if (rc == -ENOSPC || rc == -EAGAIN) { | 185 | if (rc == -ENOSPC || rc == -EAGAIN) { |
| 186 | /* | ||
| 187 | * Catch if a low level driver returns -ENOSPC. This | ||
| 188 | * WARN_ON will be removed by 3.10 if no one reports | ||
| 189 | * seeing this. | ||
| 190 | */ | ||
| 191 | WARN_ON_ONCE(rc == -ENOSPC); | ||
| 186 | i++; | 192 | i++; |
| 187 | if (i >= 14 || (!server->noblocksnd && (i > 2))) { | 193 | if (i >= 14 || (!server->noblocksnd && (i > 2))) { |
| 188 | cERROR(1, "sends on sock %p stuck for 15 " | 194 | cERROR(1, "sends on sock %p stuck for 15 " |
