diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 117 |
1 files changed, 68 insertions, 49 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 6d88b82537c3..7f540df52527 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -152,7 +152,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
152 | mid_entry->callback(mid_entry); | 152 | mid_entry->callback(mid_entry); |
153 | } | 153 | } |
154 | 154 | ||
155 | while (server->tcpStatus == CifsNeedReconnect) { | 155 | do { |
156 | try_to_freeze(); | 156 | try_to_freeze(); |
157 | 157 | ||
158 | /* we should try only the port we connected to before */ | 158 | /* we should try only the port we connected to before */ |
@@ -167,7 +167,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
167 | server->tcpStatus = CifsNeedNegotiate; | 167 | server->tcpStatus = CifsNeedNegotiate; |
168 | spin_unlock(&GlobalMid_Lock); | 168 | spin_unlock(&GlobalMid_Lock); |
169 | } | 169 | } |
170 | } | 170 | } while (server->tcpStatus == CifsNeedReconnect); |
171 | 171 | ||
172 | return rc; | 172 | return rc; |
173 | } | 173 | } |
@@ -784,7 +784,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
784 | struct smb_vol *vol) | 784 | struct smb_vol *vol) |
785 | { | 785 | { |
786 | char *value, *data, *end; | 786 | char *value, *data, *end; |
787 | char *mountdata_copy, *options; | 787 | char *mountdata_copy = NULL, *options; |
788 | unsigned int temp_len, i, j; | 788 | unsigned int temp_len, i, j; |
789 | char separator[2]; | 789 | char separator[2]; |
790 | short int override_uid = -1; | 790 | short int override_uid = -1; |
@@ -1391,7 +1391,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1391 | "/proc/fs/cifs/LookupCacheEnabled to 0\n"); | 1391 | "/proc/fs/cifs/LookupCacheEnabled to 0\n"); |
1392 | } else if (strnicmp(data, "fsc", 3) == 0) { | 1392 | } else if (strnicmp(data, "fsc", 3) == 0) { |
1393 | #ifndef CONFIG_CIFS_FSCACHE | 1393 | #ifndef CONFIG_CIFS_FSCACHE |
1394 | cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE" | 1394 | cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE " |
1395 | "kernel config option set"); | 1395 | "kernel config option set"); |
1396 | goto cifs_parse_mount_err; | 1396 | goto cifs_parse_mount_err; |
1397 | #endif | 1397 | #endif |
@@ -1976,7 +1976,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1976 | warned_on_ntlm = true; | 1976 | warned_on_ntlm = true; |
1977 | cERROR(1, "default security mechanism requested. The default " | 1977 | cERROR(1, "default security mechanism requested. The default " |
1978 | "security mechanism will be upgraded from ntlm to " | 1978 | "security mechanism will be upgraded from ntlm to " |
1979 | "ntlmv2 in kernel release 2.6.41"); | 1979 | "ntlmv2 in kernel release 3.1"); |
1980 | } | 1980 | } |
1981 | ses->overrideSecFlg = volume_info->secFlg; | 1981 | ses->overrideSecFlg = volume_info->secFlg; |
1982 | 1982 | ||
@@ -2149,7 +2149,10 @@ cifs_put_tlink(struct tcon_link *tlink) | |||
2149 | } | 2149 | } |
2150 | 2150 | ||
2151 | static inline struct tcon_link * | 2151 | static inline struct tcon_link * |
2152 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb); | 2152 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) |
2153 | { | ||
2154 | return cifs_sb->master_tlink; | ||
2155 | } | ||
2153 | 2156 | ||
2154 | static int | 2157 | static int |
2155 | compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) | 2158 | compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) |
@@ -2543,7 +2546,7 @@ ip_connect(struct TCP_Server_Info *server) | |||
2543 | } | 2546 | } |
2544 | 2547 | ||
2545 | void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, | 2548 | void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, |
2546 | struct super_block *sb, struct smb_vol *vol_info) | 2549 | struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info) |
2547 | { | 2550 | { |
2548 | /* if we are reconnecting then should we check to see if | 2551 | /* if we are reconnecting then should we check to see if |
2549 | * any requested capabilities changed locally e.g. via | 2552 | * any requested capabilities changed locally e.g. via |
@@ -2597,22 +2600,23 @@ void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, | |||
2597 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; | 2600 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
2598 | else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { | 2601 | else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { |
2599 | cFYI(1, "negotiated posix acl support"); | 2602 | cFYI(1, "negotiated posix acl support"); |
2600 | if (sb) | 2603 | if (cifs_sb) |
2601 | sb->s_flags |= MS_POSIXACL; | 2604 | cifs_sb->mnt_cifs_flags |= |
2605 | CIFS_MOUNT_POSIXACL; | ||
2602 | } | 2606 | } |
2603 | 2607 | ||
2604 | if (vol_info && vol_info->posix_paths == 0) | 2608 | if (vol_info && vol_info->posix_paths == 0) |
2605 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; | 2609 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; |
2606 | else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { | 2610 | else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { |
2607 | cFYI(1, "negotiate posix pathnames"); | 2611 | cFYI(1, "negotiate posix pathnames"); |
2608 | if (sb) | 2612 | if (cifs_sb) |
2609 | CIFS_SB(sb)->mnt_cifs_flags |= | 2613 | cifs_sb->mnt_cifs_flags |= |
2610 | CIFS_MOUNT_POSIX_PATHS; | 2614 | CIFS_MOUNT_POSIX_PATHS; |
2611 | } | 2615 | } |
2612 | 2616 | ||
2613 | if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { | 2617 | if (cifs_sb && (cifs_sb->rsize > 127 * 1024)) { |
2614 | if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { | 2618 | if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { |
2615 | CIFS_SB(sb)->rsize = 127 * 1024; | 2619 | cifs_sb->rsize = 127 * 1024; |
2616 | cFYI(DBG2, "larger reads not supported by srv"); | 2620 | cFYI(DBG2, "larger reads not supported by srv"); |
2617 | } | 2621 | } |
2618 | } | 2622 | } |
@@ -2659,6 +2663,9 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
2659 | { | 2663 | { |
2660 | INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); | 2664 | INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); |
2661 | 2665 | ||
2666 | spin_lock_init(&cifs_sb->tlink_tree_lock); | ||
2667 | cifs_sb->tlink_tree = RB_ROOT; | ||
2668 | |||
2662 | if (pvolume_info->rsize > CIFSMaxBufSize) { | 2669 | if (pvolume_info->rsize > CIFSMaxBufSize) { |
2663 | cERROR(1, "rsize %d too large, using MaxBufSize", | 2670 | cERROR(1, "rsize %d too large, using MaxBufSize", |
2664 | pvolume_info->rsize); | 2671 | pvolume_info->rsize); |
@@ -2747,21 +2754,21 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
2747 | 2754 | ||
2748 | /* | 2755 | /* |
2749 | * When the server supports very large writes via POSIX extensions, we can | 2756 | * When the server supports very large writes via POSIX extensions, we can |
2750 | * allow up to 2^24 - PAGE_CACHE_SIZE. | 2757 | * allow up to 2^24-1, minus the size of a WRITE_AND_X header, not including |
2758 | * the RFC1001 length. | ||
2751 | * | 2759 | * |
2752 | * Note that this might make for "interesting" allocation problems during | 2760 | * Note that this might make for "interesting" allocation problems during |
2753 | * writeback however (as we have to allocate an array of pointers for the | 2761 | * writeback however as we have to allocate an array of pointers for the |
2754 | * pages). A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. | 2762 | * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. |
2755 | */ | 2763 | */ |
2756 | #define CIFS_MAX_WSIZE ((1<<24) - PAGE_CACHE_SIZE) | 2764 | #define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4) |
2757 | 2765 | ||
2758 | /* | 2766 | /* |
2759 | * When the server doesn't allow large posix writes, default to a wsize of | 2767 | * When the server doesn't allow large posix writes, only allow a wsize of |
2760 | * 128k - PAGE_CACHE_SIZE -- one page less than the largest frame size | 2768 | * 128k minus the size of the WRITE_AND_X header. That allows for a write up |
2761 | * described in RFC1001. This allows space for the header without going over | 2769 | * to the maximum size described by RFC1002. |
2762 | * that by default. | ||
2763 | */ | 2770 | */ |
2764 | #define CIFS_MAX_RFC1001_WSIZE (128 * 1024 - PAGE_CACHE_SIZE) | 2771 | #define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4) |
2765 | 2772 | ||
2766 | /* | 2773 | /* |
2767 | * The default wsize is 1M. find_get_pages seems to return a maximum of 256 | 2774 | * The default wsize is 1M. find_get_pages seems to return a maximum of 256 |
@@ -2780,11 +2787,18 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
2780 | 2787 | ||
2781 | /* can server support 24-bit write sizes? (via UNIX extensions) */ | 2788 | /* can server support 24-bit write sizes? (via UNIX extensions) */ |
2782 | if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) | 2789 | if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) |
2783 | wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1001_WSIZE); | 2790 | wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE); |
2784 | 2791 | ||
2785 | /* no CAP_LARGE_WRITE_X? Limit it to 16 bits */ | 2792 | /* |
2786 | if (!(server->capabilities & CAP_LARGE_WRITE_X)) | 2793 | * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set? |
2787 | wsize = min_t(unsigned int, wsize, USHRT_MAX); | 2794 | * Limit it to max buffer offered by the server, minus the size of the |
2795 | * WRITEX header, not including the 4 byte RFC1001 length. | ||
2796 | */ | ||
2797 | if (!(server->capabilities & CAP_LARGE_WRITE_X) || | ||
2798 | (!(server->capabilities & CAP_UNIX) && | ||
2799 | (server->sec_mode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)))) | ||
2800 | wsize = min_t(unsigned int, wsize, | ||
2801 | server->maxBuf - sizeof(WRITE_REQ) + 4); | ||
2788 | 2802 | ||
2789 | /* hard limit of CIFS_MAX_WSIZE */ | 2803 | /* hard limit of CIFS_MAX_WSIZE */ |
2790 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); | 2804 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); |
@@ -2934,7 +2948,11 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
2934 | 2948 | ||
2935 | if (volume_info->nullauth) { | 2949 | if (volume_info->nullauth) { |
2936 | cFYI(1, "null user"); | 2950 | cFYI(1, "null user"); |
2937 | volume_info->username = ""; | 2951 | volume_info->username = kzalloc(1, GFP_KERNEL); |
2952 | if (volume_info->username == NULL) { | ||
2953 | rc = -ENOMEM; | ||
2954 | goto out; | ||
2955 | } | ||
2938 | } else if (volume_info->username) { | 2956 | } else if (volume_info->username) { |
2939 | /* BB fixme parse for domain name here */ | 2957 | /* BB fixme parse for domain name here */ |
2940 | cFYI(1, "Username: %s", volume_info->username); | 2958 | cFYI(1, "Username: %s", volume_info->username); |
@@ -2968,8 +2986,7 @@ out: | |||
2968 | } | 2986 | } |
2969 | 2987 | ||
2970 | int | 2988 | int |
2971 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | 2989 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) |
2972 | struct smb_vol *volume_info, const char *devname) | ||
2973 | { | 2990 | { |
2974 | int rc = 0; | 2991 | int rc = 0; |
2975 | int xid; | 2992 | int xid; |
@@ -2980,6 +2997,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2980 | struct tcon_link *tlink; | 2997 | struct tcon_link *tlink; |
2981 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2998 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2982 | int referral_walks_count = 0; | 2999 | int referral_walks_count = 0; |
3000 | |||
3001 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | ||
3002 | if (rc) | ||
3003 | return rc; | ||
3004 | |||
3005 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; | ||
3006 | |||
2983 | try_mount_again: | 3007 | try_mount_again: |
2984 | /* cleanup activities if we're chasing a referral */ | 3008 | /* cleanup activities if we're chasing a referral */ |
2985 | if (referral_walks_count) { | 3009 | if (referral_walks_count) { |
@@ -3004,6 +3028,7 @@ try_mount_again: | |||
3004 | srvTcp = cifs_get_tcp_session(volume_info); | 3028 | srvTcp = cifs_get_tcp_session(volume_info); |
3005 | if (IS_ERR(srvTcp)) { | 3029 | if (IS_ERR(srvTcp)) { |
3006 | rc = PTR_ERR(srvTcp); | 3030 | rc = PTR_ERR(srvTcp); |
3031 | bdi_destroy(&cifs_sb->bdi); | ||
3007 | goto out; | 3032 | goto out; |
3008 | } | 3033 | } |
3009 | 3034 | ||
@@ -3015,14 +3040,6 @@ try_mount_again: | |||
3015 | goto mount_fail_check; | 3040 | goto mount_fail_check; |
3016 | } | 3041 | } |
3017 | 3042 | ||
3018 | if (pSesInfo->capabilities & CAP_LARGE_FILES) | ||
3019 | sb->s_maxbytes = MAX_LFS_FILESIZE; | ||
3020 | else | ||
3021 | sb->s_maxbytes = MAX_NON_LFS; | ||
3022 | |||
3023 | /* BB FIXME fix time_gran to be larger for LANMAN sessions */ | ||
3024 | sb->s_time_gran = 100; | ||
3025 | |||
3026 | /* search for existing tcon to this server share */ | 3043 | /* search for existing tcon to this server share */ |
3027 | tcon = cifs_get_tcon(pSesInfo, volume_info); | 3044 | tcon = cifs_get_tcon(pSesInfo, volume_info); |
3028 | if (IS_ERR(tcon)) { | 3045 | if (IS_ERR(tcon)) { |
@@ -3035,7 +3052,7 @@ try_mount_again: | |||
3035 | if (tcon->ses->capabilities & CAP_UNIX) { | 3052 | if (tcon->ses->capabilities & CAP_UNIX) { |
3036 | /* reset of caps checks mount to see if unix extensions | 3053 | /* reset of caps checks mount to see if unix extensions |
3037 | disabled for just this mount */ | 3054 | disabled for just this mount */ |
3038 | reset_cifs_unix_caps(xid, tcon, sb, volume_info); | 3055 | reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info); |
3039 | if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && | 3056 | if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && |
3040 | (le64_to_cpu(tcon->fsUnixInfo.Capability) & | 3057 | (le64_to_cpu(tcon->fsUnixInfo.Capability) & |
3041 | CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { | 3058 | CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { |
@@ -3158,6 +3175,7 @@ mount_fail_check: | |||
3158 | cifs_put_smb_ses(pSesInfo); | 3175 | cifs_put_smb_ses(pSesInfo); |
3159 | else | 3176 | else |
3160 | cifs_put_tcp_session(srvTcp); | 3177 | cifs_put_tcp_session(srvTcp); |
3178 | bdi_destroy(&cifs_sb->bdi); | ||
3161 | goto out; | 3179 | goto out; |
3162 | } | 3180 | } |
3163 | 3181 | ||
@@ -3171,6 +3189,10 @@ out: | |||
3171 | return rc; | 3189 | return rc; |
3172 | } | 3190 | } |
3173 | 3191 | ||
3192 | /* | ||
3193 | * Issue a TREE_CONNECT request. Note that for IPC$ shares, that the tcon | ||
3194 | * pointer may be NULL. | ||
3195 | */ | ||
3174 | int | 3196 | int |
3175 | CIFSTCon(unsigned int xid, struct cifs_ses *ses, | 3197 | CIFSTCon(unsigned int xid, struct cifs_ses *ses, |
3176 | const char *tree, struct cifs_tcon *tcon, | 3198 | const char *tree, struct cifs_tcon *tcon, |
@@ -3205,7 +3227,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
3205 | pSMB->AndXCommand = 0xFF; | 3227 | pSMB->AndXCommand = 0xFF; |
3206 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); | 3228 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); |
3207 | bcc_ptr = &pSMB->Password[0]; | 3229 | bcc_ptr = &pSMB->Password[0]; |
3208 | if ((ses->server->sec_mode) & SECMODE_USER) { | 3230 | if (!tcon || (ses->server->sec_mode & SECMODE_USER)) { |
3209 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ | 3231 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ |
3210 | *bcc_ptr = 0; /* password is null byte */ | 3232 | *bcc_ptr = 0; /* password is null byte */ |
3211 | bcc_ptr++; /* skip password */ | 3233 | bcc_ptr++; /* skip password */ |
@@ -3328,8 +3350,8 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
3328 | return rc; | 3350 | return rc; |
3329 | } | 3351 | } |
3330 | 3352 | ||
3331 | int | 3353 | void |
3332 | cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | 3354 | cifs_umount(struct cifs_sb_info *cifs_sb) |
3333 | { | 3355 | { |
3334 | struct rb_root *root = &cifs_sb->tlink_tree; | 3356 | struct rb_root *root = &cifs_sb->tlink_tree; |
3335 | struct rb_node *node; | 3357 | struct rb_node *node; |
@@ -3350,7 +3372,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | |||
3350 | } | 3372 | } |
3351 | spin_unlock(&cifs_sb->tlink_tree_lock); | 3373 | spin_unlock(&cifs_sb->tlink_tree_lock); |
3352 | 3374 | ||
3353 | return 0; | 3375 | bdi_destroy(&cifs_sb->bdi); |
3376 | kfree(cifs_sb->mountdata); | ||
3377 | unload_nls(cifs_sb->local_nls); | ||
3378 | kfree(cifs_sb); | ||
3354 | } | 3379 | } |
3355 | 3380 | ||
3356 | int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) | 3381 | int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) |
@@ -3371,7 +3396,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) | |||
3371 | } | 3396 | } |
3372 | if (rc == 0) { | 3397 | if (rc == 0) { |
3373 | spin_lock(&GlobalMid_Lock); | 3398 | spin_lock(&GlobalMid_Lock); |
3374 | if (server->tcpStatus != CifsExiting) | 3399 | if (server->tcpStatus == CifsNeedNegotiate) |
3375 | server->tcpStatus = CifsGood; | 3400 | server->tcpStatus = CifsGood; |
3376 | else | 3401 | else |
3377 | rc = -EHOSTDOWN; | 3402 | rc = -EHOSTDOWN; |
@@ -3484,12 +3509,6 @@ out: | |||
3484 | return tcon; | 3509 | return tcon; |
3485 | } | 3510 | } |
3486 | 3511 | ||
3487 | static inline struct tcon_link * | ||
3488 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) | ||
3489 | { | ||
3490 | return cifs_sb->master_tlink; | ||
3491 | } | ||
3492 | |||
3493 | struct cifs_tcon * | 3512 | struct cifs_tcon * |
3494 | cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) | 3513 | cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) |
3495 | { | 3514 | { |