Bluetooth: Add SCO fallback for eSCO connection attempts
[pandora-kernel.git] / fs / cifs / cifs_dfs_ref.c
index e1c1836..85c0a74 100644 (file)
@@ -122,7 +122,7 @@ static char *compose_mount_options(const char *sb_mountdata,
                                   char **devname)
 {
        int rc;
-       char *mountdata;
+       char *mountdata = NULL;
        int md_len;
        char *tkn_e;
        char *srvIP = NULL;
@@ -136,10 +136,9 @@ static char *compose_mount_options(const char *sb_mountdata,
        *devname = cifs_get_share_name(ref->node_name);
        rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
        if (rc != 0) {
-               cERROR(1, ("%s: Failed to resolve server part of %s to IP",
-                         __func__, *devname));
-               mountdata = ERR_PTR(rc);
-               goto compose_mount_options_out;
+               cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
+                         __func__, *devname, rc));;
+               goto compose_mount_options_err;
        }
        /* md_len = strlen(...) + 12 for 'sep+prefixpath='
         * assuming that we have 'unc=' and 'ip=' in
@@ -149,8 +148,8 @@ static char *compose_mount_options(const char *sb_mountdata,
                strlen(ref->node_name) + 12;
        mountdata = kzalloc(md_len+1, GFP_KERNEL);
        if (mountdata == NULL) {
-               mountdata = ERR_PTR(-ENOMEM);
-               goto compose_mount_options_out;
+               rc = -ENOMEM;
+               goto compose_mount_options_err;
        }
 
        /* copy all options except of unc,ip,prefixpath */
@@ -197,18 +196,32 @@ static char *compose_mount_options(const char *sb_mountdata,
 
        /* find & copy prefixpath */
        tkn_e = strchr(ref->node_name + 2, '\\');
-       if (tkn_e == NULL) /* invalid unc, missing share name*/
-               goto compose_mount_options_out;
+       if (tkn_e == NULL) {
+               /* invalid unc, missing share name*/
+               rc = -EINVAL;
+               goto compose_mount_options_err;
+       }
 
+       /*
+        * this function gives us a path with a double backslash prefix. We
+        * require a single backslash for DFS. Temporarily increment fullpath
+        * to put it in the proper form and decrement before freeing it.
+        */
        fullpath = build_path_from_dentry(dentry);
+       if (!fullpath) {
+               rc = -ENOMEM;
+               goto compose_mount_options_err;
+       }
+       ++fullpath;
        tkn_e = strchr(tkn_e + 1, '\\');
-       if (tkn_e || strlen(fullpath) - (ref->path_consumed)) {
+       if (tkn_e || (strlen(fullpath) - ref->path_consumed)) {
                strncat(mountdata, &sep, 1);
                strcat(mountdata, "prefixpath=");
                if (tkn_e)
                        strcat(mountdata, tkn_e + 1);
-               strcat(mountdata, fullpath + (ref->path_consumed));
+               strcat(mountdata, fullpath + ref->path_consumed);
        }
+       --fullpath;
        kfree(fullpath);
 
        /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/
@@ -217,6 +230,11 @@ static char *compose_mount_options(const char *sb_mountdata,
 compose_mount_options_out:
        kfree(srvIP);
        return mountdata;
+
+compose_mount_options_err:
+       kfree(mountdata);
+       mountdata = ERR_PTR(rc);
+       goto compose_mount_options_out;
 }
 
 
@@ -309,13 +327,19 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
                goto out_err;
        }
 
+       /*
+        * The MSDFS spec states that paths in DFS referral requests and
+        * responses must be prefixed by a single '\' character instead of
+        * the double backslashes usually used in the UNC. This function
+        * gives us the latter, so we must adjust the result.
+        */
        full_path = build_path_from_dentry(dentry);
        if (full_path == NULL) {
                rc = -ENOMEM;
                goto out_err;
        }
 
-       rc = get_dfs_path(xid, ses , full_path, cifs_sb->local_nls,
+       rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls,
                &num_referrals, &referrals,
                cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);