@@ -97,6 +97,13 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf,
97
97
return - ENOENT ;
98
98
}
99
99
100
+ err = mnt_want_write (parent_path -> mnt );
101
+ if (err ) {
102
+ path_put (parent_path );
103
+ putname (filename );
104
+ return - ENOENT ;
105
+ }
106
+
100
107
inode_lock_nested (parent_path -> dentry -> d_inode , I_MUTEX_PARENT );
101
108
d = lookup_one_qstr_excl (& last , parent_path -> dentry , 0 );
102
109
if (IS_ERR (d ))
@@ -123,6 +130,7 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf,
123
130
124
131
err_out :
125
132
inode_unlock (d_inode (parent_path -> dentry ));
133
+ mnt_drop_write (parent_path -> mnt );
126
134
path_put (parent_path );
127
135
putname (filename );
128
136
return - ENOENT ;
@@ -451,7 +459,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
451
459
fp -> stream .name ,
452
460
(void * )stream_buf ,
453
461
size ,
454
- 0 );
462
+ 0 ,
463
+ true);
455
464
if (err < 0 )
456
465
goto out ;
457
466
@@ -593,10 +602,6 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
593
602
goto out_err ;
594
603
}
595
604
596
- err = mnt_want_write (path -> mnt );
597
- if (err )
598
- goto out_err ;
599
-
600
605
idmap = mnt_idmap (path -> mnt );
601
606
if (S_ISDIR (d_inode (path -> dentry )-> i_mode )) {
602
607
err = vfs_rmdir (idmap , d_inode (parent ), path -> dentry );
@@ -607,7 +612,6 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
607
612
if (err )
608
613
ksmbd_debug (VFS , "unlink failed, err %d\n" , err );
609
614
}
610
- mnt_drop_write (path -> mnt );
611
615
612
616
out_err :
613
617
ksmbd_revert_fsids (work );
@@ -907,18 +911,22 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
907
911
* @attr_value: xattr value to set
908
912
* @attr_size: size of xattr value
909
913
* @flags: destination buffer length
914
+ * @get_write: get write access to a mount
910
915
*
911
916
* Return: 0 on success, otherwise error
912
917
*/
913
918
int ksmbd_vfs_setxattr (struct mnt_idmap * idmap ,
914
919
const struct path * path , const char * attr_name ,
915
- void * attr_value , size_t attr_size , int flags )
920
+ void * attr_value , size_t attr_size , int flags ,
921
+ bool get_write )
916
922
{
917
923
int err ;
918
924
919
- err = mnt_want_write (path -> mnt );
920
- if (err )
921
- return err ;
925
+ if (get_write == true) {
926
+ err = mnt_want_write (path -> mnt );
927
+ if (err )
928
+ return err ;
929
+ }
922
930
923
931
err = vfs_setxattr (idmap ,
924
932
path -> dentry ,
@@ -928,7 +936,8 @@ int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
928
936
flags );
929
937
if (err )
930
938
ksmbd_debug (VFS , "setxattr failed, err %d\n" , err );
931
- mnt_drop_write (path -> mnt );
939
+ if (get_write == true)
940
+ mnt_drop_write (path -> mnt );
932
941
return err ;
933
942
}
934
943
@@ -1252,6 +1261,13 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
1252
1261
}
1253
1262
1254
1263
if (!err ) {
1264
+ err = mnt_want_write (parent_path -> mnt );
1265
+ if (err ) {
1266
+ path_put (path );
1267
+ path_put (parent_path );
1268
+ return err ;
1269
+ }
1270
+
1255
1271
err = ksmbd_vfs_lock_parent (parent_path -> dentry , path -> dentry );
1256
1272
if (err ) {
1257
1273
path_put (path );
@@ -1261,6 +1277,14 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
1261
1277
return err ;
1262
1278
}
1263
1279
1280
+ void ksmbd_vfs_kern_path_unlock (struct path * parent_path , struct path * path )
1281
+ {
1282
+ inode_unlock (d_inode (parent_path -> dentry ));
1283
+ mnt_drop_write (parent_path -> mnt );
1284
+ path_put (path );
1285
+ path_put (parent_path );
1286
+ }
1287
+
1264
1288
struct dentry * ksmbd_vfs_kern_path_create (struct ksmbd_work * work ,
1265
1289
const char * name ,
1266
1290
unsigned int flags ,
@@ -1415,7 +1439,8 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id
1415
1439
int ksmbd_vfs_set_sd_xattr (struct ksmbd_conn * conn ,
1416
1440
struct mnt_idmap * idmap ,
1417
1441
const struct path * path ,
1418
- struct smb_ntsd * pntsd , int len )
1442
+ struct smb_ntsd * pntsd , int len ,
1443
+ bool get_write )
1419
1444
{
1420
1445
int rc ;
1421
1446
struct ndr sd_ndr = {0 }, acl_ndr = {0 };
@@ -1475,7 +1500,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
1475
1500
1476
1501
rc = ksmbd_vfs_setxattr (idmap , path ,
1477
1502
XATTR_NAME_SD , sd_ndr .data ,
1478
- sd_ndr .offset , 0 );
1503
+ sd_ndr .offset , 0 , get_write );
1479
1504
if (rc < 0 )
1480
1505
pr_err ("Failed to store XATTR ntacl :%d\n" , rc );
1481
1506
@@ -1564,7 +1589,8 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
1564
1589
1565
1590
int ksmbd_vfs_set_dos_attrib_xattr (struct mnt_idmap * idmap ,
1566
1591
const struct path * path ,
1567
- struct xattr_dos_attrib * da )
1592
+ struct xattr_dos_attrib * da ,
1593
+ bool get_write )
1568
1594
{
1569
1595
struct ndr n ;
1570
1596
int err ;
@@ -1574,7 +1600,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
1574
1600
return err ;
1575
1601
1576
1602
err = ksmbd_vfs_setxattr (idmap , path , XATTR_NAME_DOS_ATTRIBUTE ,
1577
- (void * )n .data , n .offset , 0 );
1603
+ (void * )n .data , n .offset , 0 , get_write );
1578
1604
if (err )
1579
1605
ksmbd_debug (SMB , "failed to store dos attribute in xattr\n" );
1580
1606
kfree (n .data );
@@ -1846,10 +1872,6 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
1846
1872
}
1847
1873
posix_state_to_acl (& acl_state , acls -> a_entries );
1848
1874
1849
- rc = mnt_want_write (path -> mnt );
1850
- if (rc )
1851
- goto out_err ;
1852
-
1853
1875
rc = set_posix_acl (idmap , dentry , ACL_TYPE_ACCESS , acls );
1854
1876
if (rc < 0 )
1855
1877
ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n" ,
@@ -1861,9 +1883,7 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
1861
1883
ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n" ,
1862
1884
rc );
1863
1885
}
1864
- mnt_drop_write (path -> mnt );
1865
1886
1866
- out_err :
1867
1887
free_acl_state (& acl_state );
1868
1888
posix_acl_release (acls );
1869
1889
return rc ;
@@ -1893,10 +1913,6 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
1893
1913
}
1894
1914
}
1895
1915
1896
- rc = mnt_want_write (path -> mnt );
1897
- if (rc )
1898
- goto out_err ;
1899
-
1900
1916
rc = set_posix_acl (idmap , dentry , ACL_TYPE_ACCESS , acls );
1901
1917
if (rc < 0 )
1902
1918
ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n" ,
@@ -1908,9 +1924,7 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
1908
1924
ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n" ,
1909
1925
rc );
1910
1926
}
1911
- mnt_drop_write (path -> mnt );
1912
1927
1913
- out_err :
1914
1928
posix_acl_release (acls );
1915
1929
return rc ;
1916
1930
}
0 commit comments