Merge branches 'core-urgent-for-linus', 'irq-urgent-for-linus' and 'sched-urgent...
[cascardo/linux.git] / fs / cifs / connect.c
index 2e4f4ba..aab5227 100644 (file)
@@ -63,7 +63,6 @@ extern mempool_t *cifs_req_poolp;
 #define TLINK_IDLE_EXPIRE      (600 * HZ)
 
 enum {
-
        /* Mount options that take no arguments */
        Opt_user_xattr, Opt_nouser_xattr,
        Opt_forceuid, Opt_noforceuid,
@@ -76,7 +75,7 @@ enum {
        Opt_noposixpaths, Opt_nounix,
        Opt_nocase,
        Opt_brl, Opt_nobrl,
-       Opt_forcemandatorylock, Opt_setuids,
+       Opt_forcemandatorylock, Opt_setuidfromacl, Opt_setuids,
        Opt_nosetuids, Opt_dynperm, Opt_nodynperm,
        Opt_nohard, Opt_nosoft,
        Opt_nointr, Opt_intr,
@@ -95,7 +94,7 @@ enum {
        Opt_cruid, Opt_gid, Opt_file_mode,
        Opt_dirmode, Opt_port,
        Opt_rsize, Opt_wsize, Opt_actimeo,
-       Opt_echo_interval,
+       Opt_echo_interval, Opt_max_credits,
 
        /* Mount options which take string value */
        Opt_user, Opt_pass, Opt_ip,
@@ -148,6 +147,7 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_forcemandatorylock, "forcemand" },
        { Opt_setuids, "setuids" },
        { Opt_nosetuids, "nosetuids" },
+       { Opt_setuidfromacl, "idsfromsid" },
        { Opt_dynperm, "dynperm" },
        { Opt_nodynperm, "nodynperm" },
        { Opt_nohard, "nohard" },
@@ -190,6 +190,7 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_wsize, "wsize=%s" },
        { Opt_actimeo, "actimeo=%s" },
        { Opt_echo_interval, "echo_interval=%s" },
+       { Opt_max_credits, "max_credits=%s" },
 
        { Opt_blank_user, "user=" },
        { Opt_blank_user, "username=" },
@@ -1376,6 +1377,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                case Opt_nosetuids:
                        vol->setuids = 0;
                        break;
+               case Opt_setuidfromacl:
+                       vol->setuidfromacl = 1;
+                       break;
                case Opt_dynperm:
                        vol->dynperm = true;
                        break;
@@ -1586,6 +1590,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        }
                        vol->echo_interval = option;
                        break;
+               case Opt_max_credits:
+                       if (get_option_ul(args, &option) || (option < 20) ||
+                           (option > 60000)) {
+                               cifs_dbg(VFS, "%s: Invalid max_credits value\n",
+                                        __func__);
+                               goto cifs_parse_mount_err;
+                       }
+                       vol->max_credits = option;
+                       break;
 
                /* String Arguments */
 
@@ -2163,7 +2176,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
                sizeof(tcp_ses->dstaddr));
 #ifdef CONFIG_CIFS_SMB2
-       get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE);
+       generate_random_uuid(tcp_ses->client_guid);
 #endif
        /*
         * at this point we are the only ones with the pointer
@@ -3270,6 +3283,8 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
        if (pvolume_info->setuids)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
+       if (pvolume_info->setuidfromacl)
+               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL;
        if (pvolume_info->server_ino)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
        if (pvolume_info->remap)
@@ -3598,7 +3613,11 @@ try_mount_again:
                bdi_destroy(&cifs_sb->bdi);
                goto out;
        }
-
+       if ((volume_info->max_credits < 20) ||
+            (volume_info->max_credits > 60000))
+               server->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
+       else
+               server->max_credits = volume_info->max_credits;
        /* get a reference to a SMB session */
        ses = cifs_get_smb_ses(server, volume_info);
        if (IS_ERR(ses)) {
@@ -3688,14 +3707,16 @@ remote_path_check:
                        goto mount_fail_check;
                }
 
-               rc = cifs_are_all_path_components_accessible(server,
+               if (rc != -EREMOTE) {
+                       rc = cifs_are_all_path_components_accessible(server,
                                                             xid, tcon, cifs_sb,
                                                             full_path);
-               if (rc != 0) {
-                       cifs_dbg(VFS, "cannot query dirs between root and final path, "
-                                "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
-                       cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
-                       rc = 0;
+                       if (rc != 0) {
+                               cifs_dbg(VFS, "cannot query dirs between root and final path, "
+                                        "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
+                               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
+                               rc = 0;
+                       }
                }
                kfree(full_path);
        }