@@ -2691,7 +2691,7 @@ int smb2_open(struct ksmbd_work *work)
26912691 * (char * )req -> Buffer == '\\' ) {
26922692 pr_err ("not allow directory name included leading slash\n" );
26932693 rc = - EINVAL ;
2694- goto err_out1 ;
2694+ goto err_out2 ;
26952695 }
26962696
26972697 name = smb2_get_name (req -> Buffer ,
@@ -2702,36 +2702,36 @@ int smb2_open(struct ksmbd_work *work)
27022702 if (rc != - ENOMEM )
27032703 rc = - ENOENT ;
27042704 name = NULL ;
2705- goto err_out1 ;
2705+ goto err_out2 ;
27062706 }
27072707
27082708 ksmbd_debug (SMB , "converted name = %s\n" , name );
27092709 if (strchr (name , ':' )) {
27102710 if (!test_share_config_flag (work -> tcon -> share_conf ,
27112711 KSMBD_SHARE_FLAG_STREAMS )) {
27122712 rc = - EBADF ;
2713- goto err_out1 ;
2713+ goto err_out2 ;
27142714 }
27152715 rc = parse_stream_name (name , & stream_name , & s_type );
27162716 if (rc < 0 )
2717- goto err_out1 ;
2717+ goto err_out2 ;
27182718 }
27192719
27202720 rc = ksmbd_validate_filename (name );
27212721 if (rc < 0 )
2722- goto err_out1 ;
2722+ goto err_out2 ;
27232723
27242724 if (ksmbd_share_veto_filename (share , name )) {
27252725 rc = - ENOENT ;
27262726 ksmbd_debug (SMB , "Reject open(), vetoed file: %s\n" ,
27272727 name );
2728- goto err_out1 ;
2728+ goto err_out2 ;
27292729 }
27302730 } else {
27312731 name = kstrdup ("" , GFP_KERNEL );
27322732 if (!name ) {
27332733 rc = - ENOMEM ;
2734- goto err_out1 ;
2734+ goto err_out2 ;
27352735 }
27362736 }
27372737
@@ -2744,14 +2744,14 @@ int smb2_open(struct ksmbd_work *work)
27442744 le32_to_cpu (req -> ImpersonationLevel ));
27452745 rc = - EIO ;
27462746 rsp -> hdr .Status = STATUS_BAD_IMPERSONATION_LEVEL ;
2747- goto err_out1 ;
2747+ goto err_out2 ;
27482748 }
27492749
27502750 if (req -> CreateOptions && !(req -> CreateOptions & CREATE_OPTIONS_MASK_LE )) {
27512751 pr_err ("Invalid create options : 0x%x\n" ,
27522752 le32_to_cpu (req -> CreateOptions ));
27532753 rc = - EINVAL ;
2754- goto err_out1 ;
2754+ goto err_out2 ;
27552755 } else {
27562756 if (req -> CreateOptions & FILE_SEQUENTIAL_ONLY_LE &&
27572757 req -> CreateOptions & FILE_RANDOM_ACCESS_LE )
@@ -2761,13 +2761,13 @@ int smb2_open(struct ksmbd_work *work)
27612761 (FILE_OPEN_BY_FILE_ID_LE | CREATE_TREE_CONNECTION |
27622762 FILE_RESERVE_OPFILTER_LE )) {
27632763 rc = - EOPNOTSUPP ;
2764- goto err_out1 ;
2764+ goto err_out2 ;
27652765 }
27662766
27672767 if (req -> CreateOptions & FILE_DIRECTORY_FILE_LE ) {
27682768 if (req -> CreateOptions & FILE_NON_DIRECTORY_FILE_LE ) {
27692769 rc = - EINVAL ;
2770- goto err_out1 ;
2770+ goto err_out2 ;
27712771 } else if (req -> CreateOptions & FILE_NO_COMPRESSION_LE ) {
27722772 req -> CreateOptions = ~(FILE_NO_COMPRESSION_LE );
27732773 }
@@ -2779,49 +2779,49 @@ int smb2_open(struct ksmbd_work *work)
27792779 pr_err ("Invalid create disposition : 0x%x\n" ,
27802780 le32_to_cpu (req -> CreateDisposition ));
27812781 rc = - EINVAL ;
2782- goto err_out1 ;
2782+ goto err_out2 ;
27832783 }
27842784
27852785 if (!(req -> DesiredAccess & DESIRED_ACCESS_MASK )) {
27862786 pr_err ("Invalid desired access : 0x%x\n" ,
27872787 le32_to_cpu (req -> DesiredAccess ));
27882788 rc = - EACCES ;
2789- goto err_out1 ;
2789+ goto err_out2 ;
27902790 }
27912791
27922792 if (req -> FileAttributes && !(req -> FileAttributes & FILE_ATTRIBUTE_MASK_LE )) {
27932793 pr_err ("Invalid file attribute : 0x%x\n" ,
27942794 le32_to_cpu (req -> FileAttributes ));
27952795 rc = - EINVAL ;
2796- goto err_out1 ;
2796+ goto err_out2 ;
27972797 }
27982798
27992799 if (req -> CreateContextsOffset ) {
28002800 /* Parse non-durable handle create contexts */
28012801 context = smb2_find_context_vals (req , SMB2_CREATE_EA_BUFFER , 4 );
28022802 if (IS_ERR (context )) {
28032803 rc = PTR_ERR (context );
2804- goto err_out1 ;
2804+ goto err_out2 ;
28052805 } else if (context ) {
28062806 ea_buf = (struct create_ea_buf_req * )context ;
28072807 if (le16_to_cpu (context -> DataOffset ) +
28082808 le32_to_cpu (context -> DataLength ) <
28092809 sizeof (struct create_ea_buf_req )) {
28102810 rc = - EINVAL ;
2811- goto err_out1 ;
2811+ goto err_out2 ;
28122812 }
28132813 if (req -> CreateOptions & FILE_NO_EA_KNOWLEDGE_LE ) {
28142814 rsp -> hdr .Status = STATUS_ACCESS_DENIED ;
28152815 rc = - EACCES ;
2816- goto err_out1 ;
2816+ goto err_out2 ;
28172817 }
28182818 }
28192819
28202820 context = smb2_find_context_vals (req ,
28212821 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST , 4 );
28222822 if (IS_ERR (context )) {
28232823 rc = PTR_ERR (context );
2824- goto err_out1 ;
2824+ goto err_out2 ;
28252825 } else if (context ) {
28262826 ksmbd_debug (SMB ,
28272827 "get query maximal access context\n" );
@@ -2832,27 +2832,27 @@ int smb2_open(struct ksmbd_work *work)
28322832 SMB2_CREATE_TIMEWARP_REQUEST , 4 );
28332833 if (IS_ERR (context )) {
28342834 rc = PTR_ERR (context );
2835- goto err_out1 ;
2835+ goto err_out2 ;
28362836 } else if (context ) {
28372837 ksmbd_debug (SMB , "get timewarp context\n" );
28382838 rc = - EBADF ;
2839- goto err_out1 ;
2839+ goto err_out2 ;
28402840 }
28412841
28422842 if (tcon -> posix_extensions ) {
28432843 context = smb2_find_context_vals (req ,
28442844 SMB2_CREATE_TAG_POSIX , 16 );
28452845 if (IS_ERR (context )) {
28462846 rc = PTR_ERR (context );
2847- goto err_out1 ;
2847+ goto err_out2 ;
28482848 } else if (context ) {
28492849 struct create_posix * posix =
28502850 (struct create_posix * )context ;
28512851 if (le16_to_cpu (context -> DataOffset ) +
28522852 le32_to_cpu (context -> DataLength ) <
28532853 sizeof (struct create_posix ) - 4 ) {
28542854 rc = - EINVAL ;
2855- goto err_out1 ;
2855+ goto err_out2 ;
28562856 }
28572857 ksmbd_debug (SMB , "get posix context\n" );
28582858
@@ -2864,7 +2864,7 @@ int smb2_open(struct ksmbd_work *work)
28642864
28652865 if (ksmbd_override_fsids (work )) {
28662866 rc = - ENOMEM ;
2867- goto err_out1 ;
2867+ goto err_out2 ;
28682868 }
28692869
28702870 rc = ksmbd_vfs_kern_path_locked (work , name , LOOKUP_NO_SYMLINKS ,
@@ -3177,11 +3177,6 @@ int smb2_open(struct ksmbd_work *work)
31773177
31783178 fp -> attrib_only = !(req -> DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE |
31793179 FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE ));
3180- if (!S_ISDIR (file_inode (filp )-> i_mode ) && open_flags & O_TRUNC &&
3181- !fp -> attrib_only && !stream_name ) {
3182- smb_break_all_oplock (work , fp );
3183- need_truncate = 1 ;
3184- }
31853180
31863181 /* fp should be searchable through ksmbd_inode.m_fp_list
31873182 * after daccess, saccess, attrib_only, and stream are
@@ -3197,13 +3192,39 @@ int smb2_open(struct ksmbd_work *work)
31973192 goto err_out ;
31983193 }
31993194
3195+ rc = ksmbd_vfs_getattr (& path , & stat );
3196+ if (rc )
3197+ goto err_out ;
3198+
3199+ if (stat .result_mask & STATX_BTIME )
3200+ fp -> create_time = ksmbd_UnixTimeToNT (stat .btime );
3201+ else
3202+ fp -> create_time = ksmbd_UnixTimeToNT (stat .ctime );
3203+ if (req -> FileAttributes || fp -> f_ci -> m_fattr == 0 )
3204+ fp -> f_ci -> m_fattr =
3205+ cpu_to_le32 (smb2_get_dos_mode (& stat , le32_to_cpu (req -> FileAttributes )));
3206+
3207+ if (!created )
3208+ smb2_update_xattrs (tcon , & path , fp );
3209+ else
3210+ smb2_new_xattrs (tcon , & path , fp );
3211+
3212+ if (file_present || created )
3213+ ksmbd_vfs_kern_path_unlock (& parent_path , & path );
3214+
3215+ if (!S_ISDIR (file_inode (filp )-> i_mode ) && open_flags & O_TRUNC &&
3216+ !fp -> attrib_only && !stream_name ) {
3217+ smb_break_all_oplock (work , fp );
3218+ need_truncate = 1 ;
3219+ }
3220+
32003221 share_ret = ksmbd_smb_check_shared_mode (fp -> filp , fp );
32013222 if (!test_share_config_flag (work -> tcon -> share_conf , KSMBD_SHARE_FLAG_OPLOCKS ) ||
32023223 (req_op_level == SMB2_OPLOCK_LEVEL_LEASE &&
32033224 !(conn -> vals -> capabilities & SMB2_GLOBAL_CAP_LEASING ))) {
32043225 if (share_ret < 0 && !S_ISDIR (file_inode (fp -> filp )-> i_mode )) {
32053226 rc = share_ret ;
3206- goto err_out ;
3227+ goto err_out1 ;
32073228 }
32083229 } else {
32093230 if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE ) {
@@ -3213,7 +3234,7 @@ int smb2_open(struct ksmbd_work *work)
32133234 name , req_op_level , lc -> req_state );
32143235 rc = find_same_lease_key (sess , fp -> f_ci , lc );
32153236 if (rc )
3216- goto err_out ;
3237+ goto err_out1 ;
32173238 } else if (open_flags == O_RDONLY &&
32183239 (req_op_level == SMB2_OPLOCK_LEVEL_BATCH ||
32193240 req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE ))
@@ -3224,20 +3245,26 @@ int smb2_open(struct ksmbd_work *work)
32243245 le32_to_cpu (req -> hdr .Id .SyncId .TreeId ),
32253246 lc , share_ret );
32263247 if (rc < 0 )
3227- goto err_out ;
3248+ goto err_out1 ;
32283249 }
32293250
32303251 if (req -> CreateOptions & FILE_DELETE_ON_CLOSE_LE )
32313252 ksmbd_fd_set_delete_on_close (fp , file_info );
32323253
3254+ if (need_truncate ) {
3255+ rc = smb2_create_truncate (& fp -> filp -> f_path );
3256+ if (rc )
3257+ goto err_out1 ;
3258+ }
3259+
32333260 if (req -> CreateContextsOffset ) {
32343261 struct create_alloc_size_req * az_req ;
32353262
32363263 az_req = (struct create_alloc_size_req * )smb2_find_context_vals (req ,
32373264 SMB2_CREATE_ALLOCATION_SIZE , 4 );
32383265 if (IS_ERR (az_req )) {
32393266 rc = PTR_ERR (az_req );
3240- goto err_out ;
3267+ goto err_out1 ;
32413268 } else if (az_req ) {
32423269 loff_t alloc_size ;
32433270 int err ;
@@ -3246,7 +3273,7 @@ int smb2_open(struct ksmbd_work *work)
32463273 le32_to_cpu (az_req -> ccontext .DataLength ) <
32473274 sizeof (struct create_alloc_size_req )) {
32483275 rc = - EINVAL ;
3249- goto err_out ;
3276+ goto err_out1 ;
32503277 }
32513278 alloc_size = le64_to_cpu (az_req -> AllocationSize );
32523279 ksmbd_debug (SMB ,
@@ -3264,30 +3291,13 @@ int smb2_open(struct ksmbd_work *work)
32643291 context = smb2_find_context_vals (req , SMB2_CREATE_QUERY_ON_DISK_ID , 4 );
32653292 if (IS_ERR (context )) {
32663293 rc = PTR_ERR (context );
3267- goto err_out ;
3294+ goto err_out1 ;
32683295 } else if (context ) {
32693296 ksmbd_debug (SMB , "get query on disk id context\n" );
32703297 query_disk_id = 1 ;
32713298 }
32723299 }
32733300
3274- rc = ksmbd_vfs_getattr (& path , & stat );
3275- if (rc )
3276- goto err_out ;
3277-
3278- if (stat .result_mask & STATX_BTIME )
3279- fp -> create_time = ksmbd_UnixTimeToNT (stat .btime );
3280- else
3281- fp -> create_time = ksmbd_UnixTimeToNT (stat .ctime );
3282- if (req -> FileAttributes || fp -> f_ci -> m_fattr == 0 )
3283- fp -> f_ci -> m_fattr =
3284- cpu_to_le32 (smb2_get_dos_mode (& stat , le32_to_cpu (req -> FileAttributes )));
3285-
3286- if (!created )
3287- smb2_update_xattrs (tcon , & path , fp );
3288- else
3289- smb2_new_xattrs (tcon , & path , fp );
3290-
32913301 memcpy (fp -> client_guid , conn -> ClientGUID , SMB2_CLIENT_GUID_SIZE );
32923302
32933303 rsp -> StructureSize = cpu_to_le16 (89 );
@@ -3394,14 +3404,13 @@ int smb2_open(struct ksmbd_work *work)
33943404 }
33953405
33963406err_out :
3397- if (file_present || created )
3407+ if (rc && ( file_present || created ) )
33983408 ksmbd_vfs_kern_path_unlock (& parent_path , & path );
33993409
3400- if (fp && need_truncate )
3401- rc = smb2_create_truncate (& fp -> filp -> f_path );
3402-
3403- ksmbd_revert_fsids (work );
34043410err_out1 :
3411+ ksmbd_revert_fsids (work );
3412+
3413+ err_out2 :
34053414 if (!rc ) {
34063415 ksmbd_update_fstate (& work -> sess -> file_table , fp , FP_INITED );
34073416 rc = ksmbd_iov_pin_rsp (work , (void * )rsp , iov_len );
0 commit comments