@@ -97,6 +97,13 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf,
9797 return - ENOENT ;
9898 }
9999
100+ err = mnt_want_write (parent_path -> mnt );
101+ if (err ) {
102+ path_put (parent_path );
103+ putname (filename );
104+ return - ENOENT ;
105+ }
106+
100107 inode_lock_nested (parent_path -> dentry -> d_inode , I_MUTEX_PARENT );
101108 d = lookup_one_qstr_excl (& last , parent_path -> dentry , 0 );
102109 if (IS_ERR (d ))
@@ -123,6 +130,7 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf,
123130
124131err_out :
125132 inode_unlock (d_inode (parent_path -> dentry ));
133+ mnt_drop_write (parent_path -> mnt );
126134 path_put (parent_path );
127135 putname (filename );
128136 return - ENOENT ;
@@ -451,7 +459,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
451459 fp -> stream .name ,
452460 (void * )stream_buf ,
453461 size ,
454- 0 );
462+ 0 ,
463+ true);
455464 if (err < 0 )
456465 goto out ;
457466
@@ -593,10 +602,6 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
593602 goto out_err ;
594603 }
595604
596- err = mnt_want_write (path -> mnt );
597- if (err )
598- goto out_err ;
599-
600605 idmap = mnt_idmap (path -> mnt );
601606 if (S_ISDIR (d_inode (path -> dentry )-> i_mode )) {
602607 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)
607612 if (err )
608613 ksmbd_debug (VFS , "unlink failed, err %d\n" , err );
609614 }
610- mnt_drop_write (path -> mnt );
611615
612616out_err :
613617 ksmbd_revert_fsids (work );
@@ -907,18 +911,22 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
907911 * @attr_value: xattr value to set
908912 * @attr_size: size of xattr value
909913 * @flags: destination buffer length
914+ * @get_write: get write access to a mount
910915 *
911916 * Return: 0 on success, otherwise error
912917 */
913918int ksmbd_vfs_setxattr (struct mnt_idmap * idmap ,
914919 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 )
916922{
917923 int err ;
918924
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+ }
922930
923931 err = vfs_setxattr (idmap ,
924932 path -> dentry ,
@@ -928,7 +936,8 @@ int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
928936 flags );
929937 if (err )
930938 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 );
932941 return err ;
933942}
934943
@@ -1252,6 +1261,13 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
12521261 }
12531262
12541263 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+
12551271 err = ksmbd_vfs_lock_parent (parent_path -> dentry , path -> dentry );
12561272 if (err ) {
12571273 path_put (path );
@@ -1261,6 +1277,14 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
12611277 return err ;
12621278}
12631279
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+
12641288struct dentry * ksmbd_vfs_kern_path_create (struct ksmbd_work * work ,
12651289 const char * name ,
12661290 unsigned int flags ,
@@ -1415,7 +1439,8 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id
14151439int ksmbd_vfs_set_sd_xattr (struct ksmbd_conn * conn ,
14161440 struct mnt_idmap * idmap ,
14171441 const struct path * path ,
1418- struct smb_ntsd * pntsd , int len )
1442+ struct smb_ntsd * pntsd , int len ,
1443+ bool get_write )
14191444{
14201445 int rc ;
14211446 struct ndr sd_ndr = {0 }, acl_ndr = {0 };
@@ -1475,7 +1500,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
14751500
14761501 rc = ksmbd_vfs_setxattr (idmap , path ,
14771502 XATTR_NAME_SD , sd_ndr .data ,
1478- sd_ndr .offset , 0 );
1503+ sd_ndr .offset , 0 , get_write );
14791504 if (rc < 0 )
14801505 pr_err ("Failed to store XATTR ntacl :%d\n" , rc );
14811506
@@ -1564,7 +1589,8 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
15641589
15651590int ksmbd_vfs_set_dos_attrib_xattr (struct mnt_idmap * idmap ,
15661591 const struct path * path ,
1567- struct xattr_dos_attrib * da )
1592+ struct xattr_dos_attrib * da ,
1593+ bool get_write )
15681594{
15691595 struct ndr n ;
15701596 int err ;
@@ -1574,7 +1600,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
15741600 return err ;
15751601
15761602 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 );
15781604 if (err )
15791605 ksmbd_debug (SMB , "failed to store dos attribute in xattr\n" );
15801606 kfree (n .data );
@@ -1846,10 +1872,6 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
18461872 }
18471873 posix_state_to_acl (& acl_state , acls -> a_entries );
18481874
1849- rc = mnt_want_write (path -> mnt );
1850- if (rc )
1851- goto out_err ;
1852-
18531875 rc = set_posix_acl (idmap , dentry , ACL_TYPE_ACCESS , acls );
18541876 if (rc < 0 )
18551877 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,
18611883 ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n" ,
18621884 rc );
18631885 }
1864- mnt_drop_write (path -> mnt );
18651886
1866- out_err :
18671887 free_acl_state (& acl_state );
18681888 posix_acl_release (acls );
18691889 return rc ;
@@ -1893,10 +1913,6 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
18931913 }
18941914 }
18951915
1896- rc = mnt_want_write (path -> mnt );
1897- if (rc )
1898- goto out_err ;
1899-
19001916 rc = set_posix_acl (idmap , dentry , ACL_TYPE_ACCESS , acls );
19011917 if (rc < 0 )
19021918 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,
19081924 ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n" ,
19091925 rc );
19101926 }
1911- mnt_drop_write (path -> mnt );
19121927
1913- out_err :
19141928 posix_acl_release (acls );
19151929 return rc ;
19161930}
0 commit comments