Merge branch 'for-linus' of git://git.samba.org/sfrench/cifs-2.6

Pull CIFS fixes from Steve French.

* 'for-linus' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: reinstate the forcegid option
  Convert properly UTF-8 to UTF-16
  [CIFS] WARN_ON_ONCE if kernel_sendmsg() returns -ENOSPC
This commit is contained in:
Linus Torvalds 2012-10-10 10:48:32 +09:00
commit fc81c038c2
3 changed files with 37 additions and 0 deletions

View file

@ -203,6 +203,27 @@ cifs_strtoUTF16(__le16 *to, const char *from, int len,
int i; int i;
wchar_t wchar_to; /* needed to quiet sparse */ wchar_t wchar_to; /* needed to quiet sparse */
/* special case for utf8 to handle no plane0 chars */
if (!strcmp(codepage->charset, "utf8")) {
/*
* convert utf8 -> utf16, we assume we have enough space
* as caller should have assumed conversion does not overflow
* in destination len is length in wchar_t units (16bits)
*/
i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN,
(wchar_t *) to, len);
/* if success terminate and exit */
if (i >= 0)
goto success;
/*
* if fails fall back to UCS encoding as this
* function should not return negative values
* currently can fail only if source contains
* invalid encoded characters
*/
}
for (i = 0; len && *from; i++, from += charlen, len -= charlen) { for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
charlen = codepage->char2uni(from, len, &wchar_to); charlen = codepage->char2uni(from, len, &wchar_to);
if (charlen < 1) { if (charlen < 1) {
@ -215,6 +236,7 @@ cifs_strtoUTF16(__le16 *to, const char *from, int len,
put_unaligned_le16(wchar_to, &to[i]); put_unaligned_le16(wchar_to, &to[i]);
} }
success:
put_unaligned_le16(0, &to[i]); put_unaligned_le16(0, &to[i]);
return i; return i;
} }

View file

@ -67,6 +67,7 @@ enum {
/* Mount options that take no arguments */ /* Mount options that take no arguments */
Opt_user_xattr, Opt_nouser_xattr, Opt_user_xattr, Opt_nouser_xattr,
Opt_forceuid, Opt_noforceuid, Opt_forceuid, Opt_noforceuid,
Opt_forcegid, Opt_noforcegid,
Opt_noblocksend, Opt_noautotune, Opt_noblocksend, Opt_noautotune,
Opt_hard, Opt_soft, Opt_perm, Opt_noperm, Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
Opt_mapchars, Opt_nomapchars, Opt_sfu, Opt_mapchars, Opt_nomapchars, Opt_sfu,
@ -117,6 +118,8 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_nouser_xattr, "nouser_xattr" }, { Opt_nouser_xattr, "nouser_xattr" },
{ Opt_forceuid, "forceuid" }, { Opt_forceuid, "forceuid" },
{ Opt_noforceuid, "noforceuid" }, { Opt_noforceuid, "noforceuid" },
{ Opt_forcegid, "forcegid" },
{ Opt_noforcegid, "noforcegid" },
{ Opt_noblocksend, "noblocksend" }, { Opt_noblocksend, "noblocksend" },
{ Opt_noautotune, "noautotune" }, { Opt_noautotune, "noautotune" },
{ Opt_hard, "hard" }, { Opt_hard, "hard" },
@ -1195,6 +1198,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
case Opt_noforceuid: case Opt_noforceuid:
override_uid = 0; override_uid = 0;
break; break;
case Opt_forcegid:
override_gid = 1;
break;
case Opt_noforcegid:
override_gid = 0;
break;
case Opt_noblocksend: case Opt_noblocksend:
vol->noblocksnd = 1; vol->noblocksnd = 1;
break; break;

View file

@ -183,6 +183,12 @@ smb_send_kvec(struct TCP_Server_Info *server, struct kvec *iov, size_t n_vec,
rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec], rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
n_vec - first_vec, remaining); n_vec - first_vec, remaining);
if (rc == -ENOSPC || rc == -EAGAIN) { if (rc == -ENOSPC || rc == -EAGAIN) {
/*
* Catch if a low level driver returns -ENOSPC. This
* WARN_ON will be removed by 3.10 if no one reports
* seeing this.
*/
WARN_ON_ONCE(rc == -ENOSPC);
i++; i++;
if (i >= 14 || (!server->noblocksnd && (i > 2))) { if (i >= 14 || (!server->noblocksnd && (i > 2))) {
cERROR(1, "sends on sock %p stuck for 15 " cERROR(1, "sends on sock %p stuck for 15 "