@@ -1025,59 +1025,107 @@ int copy_path_name(char *dst, const char *src)
10251025}
10261026
10271027struct super_cb_data {
1028- struct TCP_Server_Info * server ;
1028+ void * data ;
10291029 struct super_block * sb ;
10301030};
10311031
1032- static void super_cb (struct super_block * sb , void * arg )
1032+ static void tcp_super_cb (struct super_block * sb , void * arg )
10331033{
1034- struct super_cb_data * d = arg ;
1034+ struct super_cb_data * sd = arg ;
1035+ struct TCP_Server_Info * server = sd -> data ;
10351036 struct cifs_sb_info * cifs_sb ;
10361037 struct cifs_tcon * tcon ;
10371038
1038- if (d -> sb )
1039+ if (sd -> sb )
10391040 return ;
10401041
10411042 cifs_sb = CIFS_SB (sb );
10421043 tcon = cifs_sb_master_tcon (cifs_sb );
1043- if (tcon -> ses -> server == d -> server )
1044- d -> sb = sb ;
1044+ if (tcon -> ses -> server == server )
1045+ sd -> sb = sb ;
10451046}
10461047
1047- struct super_block * cifs_get_tcp_super (struct TCP_Server_Info * server )
1048+ static struct super_block * __cifs_get_super (void (* f )(struct super_block * , void * ),
1049+ void * data )
10481050{
1049- struct super_cb_data d = {
1050- .server = server ,
1051+ struct super_cb_data sd = {
1052+ .data = data ,
10511053 .sb = NULL ,
10521054 };
10531055
1054- iterate_supers_type (& cifs_fs_type , super_cb , & d );
1056+ iterate_supers_type (& cifs_fs_type , f , & sd );
10551057
1056- if (unlikely (! d .sb ) )
1057- return ERR_PTR (- ENOENT );
1058+ if (! sd .sb )
1059+ return ERR_PTR (- EINVAL );
10581060 /*
10591061 * Grab an active reference in order to prevent automounts (DFS links)
10601062 * of expiring and then freeing up our cifs superblock pointer while
10611063 * we're doing failover.
10621064 */
1063- cifs_sb_active (d .sb );
1064- return d .sb ;
1065+ cifs_sb_active (sd .sb );
1066+ return sd .sb ;
10651067}
10661068
1067- void cifs_put_tcp_super (struct super_block * sb )
1069+ static void __cifs_put_super (struct super_block * sb )
10681070{
10691071 if (!IS_ERR_OR_NULL (sb ))
10701072 cifs_sb_deactive (sb );
10711073}
10721074
1075+ struct super_block * cifs_get_tcp_super (struct TCP_Server_Info * server )
1076+ {
1077+ return __cifs_get_super (tcp_super_cb , server );
1078+ }
1079+
1080+ void cifs_put_tcp_super (struct super_block * sb )
1081+ {
1082+ __cifs_put_super (sb );
1083+ }
1084+
1085+ #ifdef CONFIG_CIFS_DFS_UPCALL
1086+ static void tcon_super_cb (struct super_block * sb , void * arg )
1087+ {
1088+ struct super_cb_data * sd = arg ;
1089+ struct cifs_tcon * tcon = sd -> data ;
1090+ struct cifs_sb_info * cifs_sb ;
1091+
1092+ if (sd -> sb )
1093+ return ;
1094+
1095+ cifs_sb = CIFS_SB (sb );
1096+ if (tcon -> dfs_path && cifs_sb -> origin_fullpath &&
1097+ !strcasecmp (tcon -> dfs_path , cifs_sb -> origin_fullpath ))
1098+ sd -> sb = sb ;
1099+ }
1100+
1101+ static inline struct super_block * cifs_get_tcon_super (struct cifs_tcon * tcon )
1102+ {
1103+ return __cifs_get_super (tcon_super_cb , tcon );
1104+ }
1105+
1106+ static inline void cifs_put_tcon_super (struct super_block * sb )
1107+ {
1108+ __cifs_put_super (sb );
1109+ }
1110+ #else
1111+ static inline struct super_block * cifs_get_tcon_super (struct cifs_tcon * tcon )
1112+ {
1113+ return ERR_PTR (- EOPNOTSUPP );
1114+ }
1115+
1116+ static inline void cifs_put_tcon_super (struct super_block * sb )
1117+ {
1118+ }
1119+ #endif
1120+
10731121int update_super_prepath (struct cifs_tcon * tcon , const char * prefix ,
10741122 size_t prefix_len )
10751123{
10761124 struct super_block * sb ;
10771125 struct cifs_sb_info * cifs_sb ;
10781126 int rc = 0 ;
10791127
1080- sb = cifs_get_tcp_super (tcon -> ses -> server );
1128+ sb = cifs_get_tcon_super (tcon );
10811129 if (IS_ERR (sb ))
10821130 return PTR_ERR (sb );
10831131
@@ -1099,6 +1147,6 @@ int update_super_prepath(struct cifs_tcon *tcon, const char *prefix,
10991147 cifs_sb -> mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH ;
11001148
11011149out :
1102- cifs_put_tcp_super (sb );
1150+ cifs_put_tcon_super (sb );
11031151 return rc ;
11041152}
0 commit comments