summaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index eb24653612bc..7ae03283bd61 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3485,6 +3485,44 @@ cifs_get_volume_info(char *mount_data, const char *devname)
3485 return volume_info; 3485 return volume_info;
3486} 3486}
3487 3487
3488static int
3489cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
3490 unsigned int xid,
3491 struct cifs_tcon *tcon,
3492 struct cifs_sb_info *cifs_sb,
3493 char *full_path)
3494{
3495 int rc;
3496 char *s;
3497 char sep, tmp;
3498
3499 sep = CIFS_DIR_SEP(cifs_sb);
3500 s = full_path;
3501
3502 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, "");
3503 while (rc == 0) {
3504 /* skip separators */
3505 while (*s == sep)
3506 s++;
3507 if (!*s)
3508 break;
3509 /* next separator */
3510 while (*s && *s != sep)
3511 s++;
3512
3513 /*
3514 * temporarily null-terminate the path at the end of
3515 * the current component
3516 */
3517 tmp = *s;
3518 *s = 0;
3519 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
3520 full_path);
3521 *s = tmp;
3522 }
3523 return rc;
3524}
3525
3488int 3526int
3489cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) 3527cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
3490{ 3528{
@@ -3622,6 +3660,16 @@ remote_path_check:
3622 kfree(full_path); 3660 kfree(full_path);
3623 goto mount_fail_check; 3661 goto mount_fail_check;
3624 } 3662 }
3663
3664 rc = cifs_are_all_path_components_accessible(server,
3665 xid, tcon, cifs_sb,
3666 full_path);
3667 if (rc != 0) {
3668 cifs_dbg(VFS, "cannot query dirs between root and final path, "
3669 "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
3670 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
3671 rc = 0;
3672 }
3625 kfree(full_path); 3673 kfree(full_path);
3626 } 3674 }
3627 3675
@@ -3891,6 +3939,7 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
3891 3939
3892 bdi_destroy(&cifs_sb->bdi); 3940 bdi_destroy(&cifs_sb->bdi);
3893 kfree(cifs_sb->mountdata); 3941 kfree(cifs_sb->mountdata);
3942 kfree(cifs_sb->prepath);
3894 call_rcu(&cifs_sb->rcu, delayed_free); 3943 call_rcu(&cifs_sb->rcu, delayed_free);
3895} 3944}
3896 3945