smb: client: ensure to try all targets when finding nested links
authorPaulo Alcantara <pc@manguebit.com>
Thu, 17 Aug 2023 15:34:00 +0000 (12:34 -0300)
committerSteve French <stfrench@microsoft.com>
Sun, 20 Aug 2023 21:05:50 +0000 (16:05 -0500)
commitce04127c5849af610d395b5b9552ef31d83c0189
tree2b289f02fa29ba93bd9ea9e5c882d33d06442b32
parent3fea12f3c67de30fd2e6a3f5da2b5354aa22348e
smb: client: ensure to try all targets when finding nested links

With current implementation, when a nested DFS link is found during
mount(2), the client follows the referral and then try to connect to
all of its targets.  If all targets failed, the client bails out
rather than retrying remaining targets from previous referral.

Fix this by stacking all referrals and targets so the client can retry
remaining targets from previous referrals in case all targets of
current referral have failed.

Thanks to samba, this can be easily tested like below

* Run the following under dfs folder in samba server

  $ ln -s "msdfs:srv\\bad-share" link1
  $ ln -s "msdfs:srv\\dfs\\link1,srv\\good-share" link0

* Before patch

  $ mount.cifs //srv/dfs/link0 /mnt -o ...
  mount error(2): No such file or directory
  Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)...

* After patch

  $ mount.cifs //srv/dfs/link0 /mnt -o ...
  # ls /mnt
  bar  fileshare1  sub

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifsglob.h
fs/smb/client/dfs.c
fs/smb/client/dfs.h
fs/smb/client/dfs_cache.c
fs/smb/client/dfs_cache.h