@@ -1229,6 +1229,30 @@ void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id)
1229
1229
kref_put (& mg -> refcount , mount_group_release );
1230
1230
}
1231
1231
1232
+ /* Extract share from DFS target and return a pointer to prefix path or NULL */
1233
+ static const char * parse_target_share (const char * target , char * * share )
1234
+ {
1235
+ const char * s , * seps = "/\\" ;
1236
+ size_t len ;
1237
+
1238
+ s = strpbrk (target + 1 , seps );
1239
+ if (!s )
1240
+ return ERR_PTR (- EINVAL );
1241
+
1242
+ len = strcspn (s + 1 , seps );
1243
+ if (!len )
1244
+ return ERR_PTR (- EINVAL );
1245
+ s += len ;
1246
+
1247
+ len = s - target + 1 ;
1248
+ * share = kstrndup (target , len , GFP_KERNEL );
1249
+ if (!* share )
1250
+ return ERR_PTR (- ENOMEM );
1251
+
1252
+ s = target + len ;
1253
+ return s + strspn (s , seps );
1254
+ }
1255
+
1232
1256
/**
1233
1257
* dfs_cache_get_tgt_share - parse a DFS target
1234
1258
*
@@ -1242,56 +1266,45 @@ void dfs_cache_put_refsrv_sessions(const uuid_t *mount_id)
1242
1266
int dfs_cache_get_tgt_share (char * path , const struct dfs_cache_tgt_iterator * it , char * * share ,
1243
1267
char * * prefix )
1244
1268
{
1245
- char * s , sep , * p ;
1246
- size_t len ;
1247
- size_t plen1 , plen2 ;
1269
+ char sep ;
1270
+ char * target_share , * ppath ;
1271
+ const char * target_ppath , * dfsref_ppath ;
1272
+ size_t target_pplen , dfsref_pplen ;
1273
+ size_t len , c ;
1248
1274
1249
1275
if (!it || !path || !share || !prefix || strlen (path ) < it -> it_path_consumed )
1250
1276
return - EINVAL ;
1251
1277
1252
- * share = NULL ;
1253
- * prefix = NULL ;
1254
-
1255
1278
sep = it -> it_name [0 ];
1256
1279
if (sep != '\\' && sep != '/' )
1257
1280
return - EINVAL ;
1258
1281
1259
- s = strchr (it -> it_name + 1 , sep );
1260
- if (! s )
1261
- return - EINVAL ;
1282
+ target_ppath = parse_target_share (it -> it_name , & target_share );
1283
+ if (IS_ERR ( target_ppath ) )
1284
+ return PTR_ERR ( target_ppath ) ;
1262
1285
1263
- /* point to prefix in target node */
1264
- s = strchrnul (s + 1 , sep );
1286
+ /* point to prefix in DFS referral path */
1287
+ dfsref_ppath = path + it -> it_path_consumed ;
1288
+ dfsref_ppath += strspn (dfsref_ppath , "/\\" );
1265
1289
1266
- /* extract target share */
1267
- * share = kstrndup (it -> it_name , s - it -> it_name , GFP_KERNEL );
1268
- if (!* share )
1269
- return - ENOMEM ;
1290
+ target_pplen = strlen (target_ppath );
1291
+ dfsref_pplen = strlen (dfsref_ppath );
1270
1292
1271
- /* skip separator */
1272
- if (* s )
1273
- s ++ ;
1274
- /* point to prefix in DFS path */
1275
- p = path + it -> it_path_consumed ;
1276
- if (* p == sep )
1277
- p ++ ;
1278
-
1279
- /* merge prefix paths from DFS path and target node */
1280
- plen1 = it -> it_name + strlen (it -> it_name ) - s ;
1281
- plen2 = path + strlen (path ) - p ;
1282
- if (plen1 || plen2 ) {
1283
- len = plen1 + plen2 + 2 ;
1284
- * prefix = kmalloc (len , GFP_KERNEL );
1285
- if (!* prefix ) {
1286
- kfree (* share );
1287
- * share = NULL ;
1293
+ /* merge prefix paths from DFS referral path and target node */
1294
+ if (target_pplen || dfsref_pplen ) {
1295
+ len = target_pplen + dfsref_pplen + 2 ;
1296
+ ppath = kzalloc (len , GFP_KERNEL );
1297
+ if (!ppath ) {
1298
+ kfree (target_share );
1288
1299
return - ENOMEM ;
1289
1300
}
1290
- if ( plen1 )
1291
- scnprintf ( * prefix , len , "%.*s%c%.*s" , ( int ) plen1 , s , sep , ( int ) plen2 , p );
1292
- else
1293
- strscpy ( * prefix , p , len );
1301
+ c = strscpy ( ppath , target_ppath , len );
1302
+ if ( c && dfsref_pplen )
1303
+ ppath [ c ] = sep ;
1304
+ strlcat ( ppath , dfsref_ppath , len );
1294
1305
}
1306
+ * share = target_share ;
1307
+ * prefix = ppath ;
1295
1308
return 0 ;
1296
1309
}
1297
1310
0 commit comments