@@ -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
@@ -1251,6 +1260,13 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
12511260 }
12521261
12531262 if (!err ) {
1263+ err = mnt_want_write (parent_path -> mnt );
1264+ if (err ) {
1265+ path_put (path );
1266+ path_put (parent_path );
1267+ return err ;
1268+ }
1269+
12541270 err = ksmbd_vfs_lock_parent (parent_path -> dentry , path -> dentry );
12551271 if (err ) {
12561272 path_put (path );
@@ -1260,6 +1276,14 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
12601276 return err ;
12611277}
12621278
1279+ void ksmbd_vfs_kern_path_unlock (struct path * parent_path , struct path * path )
1280+ {
1281+ inode_unlock (d_inode (parent_path -> dentry ));
1282+ mnt_drop_write (parent_path -> mnt );
1283+ path_put (path );
1284+ path_put (parent_path );
1285+ }
1286+
12631287struct dentry * ksmbd_vfs_kern_path_create (struct ksmbd_work * work ,
12641288 const char * name ,
12651289 unsigned int flags ,
@@ -1414,7 +1438,8 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id
14141438int ksmbd_vfs_set_sd_xattr (struct ksmbd_conn * conn ,
14151439 struct mnt_idmap * idmap ,
14161440 const struct path * path ,
1417- struct smb_ntsd * pntsd , int len )
1441+ struct smb_ntsd * pntsd , int len ,
1442+ bool get_write )
14181443{
14191444 int rc ;
14201445 struct ndr sd_ndr = {0 }, acl_ndr = {0 };
@@ -1474,7 +1499,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
14741499
14751500 rc = ksmbd_vfs_setxattr (idmap , path ,
14761501 XATTR_NAME_SD , sd_ndr .data ,
1477- sd_ndr .offset , 0 );
1502+ sd_ndr .offset , 0 , get_write );
14781503 if (rc < 0 )
14791504 pr_err ("Failed to store XATTR ntacl :%d\n" , rc );
14801505
@@ -1563,7 +1588,8 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
15631588
15641589int ksmbd_vfs_set_dos_attrib_xattr (struct mnt_idmap * idmap ,
15651590 const struct path * path ,
1566- struct xattr_dos_attrib * da )
1591+ struct xattr_dos_attrib * da ,
1592+ bool get_write )
15671593{
15681594 struct ndr n ;
15691595 int err ;
@@ -1573,7 +1599,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
15731599 return err ;
15741600
15751601 err = ksmbd_vfs_setxattr (idmap , path , XATTR_NAME_DOS_ATTRIBUTE ,
1576- (void * )n .data , n .offset , 0 );
1602+ (void * )n .data , n .offset , 0 , get_write );
15771603 if (err )
15781604 ksmbd_debug (SMB , "failed to store dos attribute in xattr\n" );
15791605 kfree (n .data );
@@ -1845,10 +1871,6 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
18451871 }
18461872 posix_state_to_acl (& acl_state , acls -> a_entries );
18471873
1848- rc = mnt_want_write (path -> mnt );
1849- if (rc )
1850- goto out_err ;
1851-
18521874 rc = set_posix_acl (idmap , dentry , ACL_TYPE_ACCESS , acls );
18531875 if (rc < 0 )
18541876 ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n" ,
@@ -1860,9 +1882,7 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
18601882 ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n" ,
18611883 rc );
18621884 }
1863- mnt_drop_write (path -> mnt );
18641885
1865- out_err :
18661886 free_acl_state (& acl_state );
18671887 posix_acl_release (acls );
18681888 return rc ;
@@ -1892,10 +1912,6 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
18921912 }
18931913 }
18941914
1895- rc = mnt_want_write (path -> mnt );
1896- if (rc )
1897- goto out_err ;
1898-
18991915 rc = set_posix_acl (idmap , dentry , ACL_TYPE_ACCESS , acls );
19001916 if (rc < 0 )
19011917 ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n" ,
@@ -1907,9 +1923,7 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
19071923 ksmbd_debug (SMB , "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n" ,
19081924 rc );
19091925 }
1910- mnt_drop_write (path -> mnt );
19111926
1912- out_err :
19131927 posix_acl_release (acls );
19141928 return rc ;
19151929}
0 commit comments