@@ -1061,7 +1061,9 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
10611061 const unsigned int xid ,
10621062 struct cifs_tcon * tcon ,
10631063 const char * full_path ,
1064- struct cifs_fattr * fattr )
1064+ struct cifs_fattr * fattr ,
1065+ struct cifs_sid * owner ,
1066+ struct cifs_sid * group )
10651067{
10661068 struct TCP_Server_Info * server = tcon -> ses -> server ;
10671069 struct cifs_sb_info * cifs_sb = CIFS_SB (sb );
@@ -1092,7 +1094,8 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
10921094 rc = 0 ;
10931095 goto out ;
10941096 default :
1095- if (data -> symlink_target ) {
1097+ /* Check for cached reparse point data */
1098+ if (data -> symlink_target || data -> reparse .buf ) {
10961099 rc = 0 ;
10971100 } else if (server -> ops -> parse_reparse_point ) {
10981101 rc = server -> ops -> parse_reparse_point (cifs_sb ,
@@ -1101,7 +1104,10 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
11011104 break ;
11021105 }
11031106
1104- cifs_open_info_to_fattr (fattr , data , sb );
1107+ if (tcon -> posix_extensions )
1108+ smb311_posix_info_to_fattr (fattr , data , owner , group , sb );
1109+ else
1110+ cifs_open_info_to_fattr (fattr , data , sb );
11051111out :
11061112 free_rsp_buf (rsp_buftype , rsp_iov .iov_base );
11071113 return rc ;
@@ -1152,7 +1158,8 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
11521158 */
11531159 if (cifs_open_data_reparse (data )) {
11541160 rc = reparse_info_to_fattr (data , sb , xid , tcon ,
1155- full_path , fattr );
1161+ full_path , fattr ,
1162+ NULL , NULL );
11561163 } else {
11571164 cifs_open_info_to_fattr (fattr , data , sb );
11581165 }
@@ -1290,39 +1297,49 @@ int cifs_get_inode_info(struct inode **inode,
12901297 return rc ;
12911298}
12921299
1293- static int smb311_posix_get_fattr (struct cifs_fattr * fattr ,
1300+ static int smb311_posix_get_fattr (struct cifs_open_info_data * data ,
1301+ struct cifs_fattr * fattr ,
12941302 const char * full_path ,
12951303 struct super_block * sb ,
12961304 const unsigned int xid )
12971305{
1298- struct cifs_open_info_data data = {};
1306+ struct cifs_open_info_data tmp_data = {};
12991307 struct cifs_sb_info * cifs_sb = CIFS_SB (sb );
13001308 struct cifs_tcon * tcon ;
13011309 struct tcon_link * tlink ;
13021310 struct cifs_sid owner , group ;
13031311 int tmprc ;
1304- int rc ;
1312+ int rc = 0 ;
13051313
13061314 tlink = cifs_sb_tlink (cifs_sb );
13071315 if (IS_ERR (tlink ))
13081316 return PTR_ERR (tlink );
13091317 tcon = tlink_tcon (tlink );
13101318
13111319 /*
1312- * 1. Fetch file metadata
1320+ * 1. Fetch file metadata if not provided (data)
13131321 */
1314-
1315- rc = smb311_posix_query_path_info (xid , tcon , cifs_sb ,
1316- full_path , & data ,
1317- & owner , & group );
1322+ if (!data ) {
1323+ rc = smb311_posix_query_path_info (xid , tcon , cifs_sb ,
1324+ full_path , & tmp_data ,
1325+ & owner , & group );
1326+ data = & tmp_data ;
1327+ }
13181328
13191329 /*
13201330 * 2. Convert it to internal cifs metadata (fattr)
13211331 */
13221332
13231333 switch (rc ) {
13241334 case 0 :
1325- smb311_posix_info_to_fattr (fattr , & data , & owner , & group , sb );
1335+ if (cifs_open_data_reparse (data )) {
1336+ rc = reparse_info_to_fattr (data , sb , xid , tcon ,
1337+ full_path , fattr ,
1338+ & owner , & group );
1339+ } else {
1340+ smb311_posix_info_to_fattr (fattr , data ,
1341+ & owner , & group , sb );
1342+ }
13261343 break ;
13271344 case - EREMOTE :
13281345 /* DFS link, no metadata available on this server */
@@ -1353,12 +1370,15 @@ static int smb311_posix_get_fattr(struct cifs_fattr *fattr,
13531370
13541371out :
13551372 cifs_put_tlink (tlink );
1356- cifs_free_open_info (& data );
1373+ cifs_free_open_info (data );
13571374 return rc ;
13581375}
13591376
1360- int smb311_posix_get_inode_info (struct inode * * inode , const char * full_path ,
1361- struct super_block * sb , const unsigned int xid )
1377+ int smb311_posix_get_inode_info (struct inode * * inode ,
1378+ const char * full_path ,
1379+ struct cifs_open_info_data * data ,
1380+ struct super_block * sb ,
1381+ const unsigned int xid )
13621382{
13631383 struct cifs_fattr fattr = {};
13641384 int rc ;
@@ -1368,7 +1388,7 @@ int smb311_posix_get_inode_info(struct inode **inode, const char *full_path,
13681388 return 0 ;
13691389 }
13701390
1371- rc = smb311_posix_get_fattr (& fattr , full_path , sb , xid );
1391+ rc = smb311_posix_get_fattr (data , & fattr , full_path , sb , xid );
13721392 if (rc )
13731393 goto out ;
13741394
@@ -1516,7 +1536,7 @@ struct inode *cifs_root_iget(struct super_block *sb)
15161536
15171537 convert_delimiter (path , CIFS_DIR_SEP (cifs_sb ));
15181538 if (tcon -> posix_extensions )
1519- rc = smb311_posix_get_fattr (& fattr , path , sb , xid );
1539+ rc = smb311_posix_get_fattr (NULL , & fattr , path , sb , xid );
15201540 else
15211541 rc = cifs_get_fattr (NULL , sb , xid , NULL , & fattr , & inode , path );
15221542
@@ -1889,16 +1909,18 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
18891909 int rc = 0 ;
18901910 struct inode * inode = NULL ;
18911911
1892- if (tcon -> posix_extensions )
1893- rc = smb311_posix_get_inode_info (& inode , full_path , parent -> i_sb , xid );
1912+ if (tcon -> posix_extensions ) {
1913+ rc = smb311_posix_get_inode_info (& inode , full_path ,
1914+ NULL , parent -> i_sb , xid );
18941915#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1895- else if (tcon -> unix_ext )
1916+ } else if (tcon -> unix_ext ) {
18961917 rc = cifs_get_inode_info_unix (& inode , full_path , parent -> i_sb ,
18971918 xid );
18981919#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1899- else
1920+ } else {
19001921 rc = cifs_get_inode_info (& inode , full_path , NULL , parent -> i_sb ,
19011922 xid , NULL );
1923+ }
19021924
19031925 if (rc )
19041926 return rc ;
@@ -2579,13 +2601,15 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
25792601 dentry , cifs_get_time (dentry ), jiffies );
25802602
25812603again :
2582- if (cifs_sb_master_tcon (CIFS_SB (sb ))-> posix_extensions )
2583- rc = smb311_posix_get_inode_info (& inode , full_path , sb , xid );
2584- else if (cifs_sb_master_tcon (CIFS_SB (sb ))-> unix_ext )
2604+ if (cifs_sb_master_tcon (CIFS_SB (sb ))-> posix_extensions ) {
2605+ rc = smb311_posix_get_inode_info (& inode , full_path ,
2606+ NULL , sb , xid );
2607+ } else if (cifs_sb_master_tcon (CIFS_SB (sb ))-> unix_ext ) {
25852608 rc = cifs_get_inode_info_unix (& inode , full_path , sb , xid );
2586- else
2609+ } else {
25872610 rc = cifs_get_inode_info (& inode , full_path , NULL , sb ,
25882611 xid , NULL );
2612+ }
25892613 if (rc == - EAGAIN && count ++ < 10 )
25902614 goto again ;
25912615out :
0 commit comments