@@ -687,7 +687,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
687687 }
688688
689689 for (i = 0 ; i < num_cmds ; i ++ ) {
690- char * buf = rsp_iov [i + i ].iov_base ;
690+ char * buf = rsp_iov [i + 1 ].iov_base ;
691691
692692 if (buf && resp_buftype [i + 1 ] != CIFS_NO_BUFFER )
693693 rc = server -> ops -> map_error (buf , false);
@@ -1175,30 +1175,107 @@ int
11751175smb2_unlink (const unsigned int xid , struct cifs_tcon * tcon , const char * name ,
11761176 struct cifs_sb_info * cifs_sb , struct dentry * dentry )
11771177{
1178+ struct kvec open_iov [SMB2_CREATE_IOV_SIZE ];
1179+ __le16 * utf16_path __free (kfree ) = NULL ;
1180+ int retries = 0 , cur_sleep = 1 ;
1181+ struct TCP_Server_Info * server ;
11781182 struct cifs_open_parms oparms ;
1183+ struct smb2_create_req * creq ;
11791184 struct inode * inode = NULL ;
1185+ struct smb_rqst rqst [2 ];
1186+ struct kvec rsp_iov [2 ];
1187+ struct kvec close_iov ;
1188+ int resp_buftype [2 ];
1189+ struct cifs_fid fid ;
1190+ int flags = 0 ;
1191+ __u8 oplock ;
11801192 int rc ;
11811193
1182- if (dentry )
1194+ utf16_path = cifs_convert_path_to_utf16 (name , cifs_sb );
1195+ if (!utf16_path )
1196+ return - ENOMEM ;
1197+
1198+ if (smb3_encryption_required (tcon ))
1199+ flags |= CIFS_TRANSFORM_REQ ;
1200+ again :
1201+ oplock = SMB2_OPLOCK_LEVEL_NONE ;
1202+ server = cifs_pick_channel (tcon -> ses );
1203+
1204+ memset (rqst , 0 , sizeof (rqst ));
1205+ memset (resp_buftype , 0 , sizeof (resp_buftype ));
1206+ memset (rsp_iov , 0 , sizeof (rsp_iov ));
1207+
1208+ rqst [0 ].rq_iov = open_iov ;
1209+ rqst [0 ].rq_nvec = ARRAY_SIZE (open_iov );
1210+
1211+ oparms = CIFS_OPARMS (cifs_sb , tcon , name , DELETE | FILE_READ_ATTRIBUTES ,
1212+ FILE_OPEN , CREATE_DELETE_ON_CLOSE |
1213+ OPEN_REPARSE_POINT , ACL_NO_MODE );
1214+ oparms .fid = & fid ;
1215+
1216+ if (dentry ) {
11831217 inode = d_inode (dentry );
1218+ if (CIFS_I (inode )-> lease_granted && server -> ops -> get_lease_key ) {
1219+ oplock = SMB2_OPLOCK_LEVEL_LEASE ;
1220+ server -> ops -> get_lease_key (inode , & fid );
1221+ }
1222+ }
11841223
1185- oparms = CIFS_OPARMS (cifs_sb , tcon , name , DELETE ,
1186- FILE_OPEN , OPEN_REPARSE_POINT , ACL_NO_MODE );
1187- rc = smb2_compound_op (xid , tcon , cifs_sb , name , & oparms ,
1188- NULL , & (int ){SMB2_OP_UNLINK },
1189- 1 , NULL , NULL , NULL , dentry );
1190- if (rc == - EINVAL ) {
1191- cifs_dbg (FYI , "invalid lease key, resending request without lease" );
1192- rc = smb2_compound_op (xid , tcon , cifs_sb , name , & oparms ,
1193- NULL , & (int ){SMB2_OP_UNLINK },
1194- 1 , NULL , NULL , NULL , NULL );
1224+ rc = SMB2_open_init (tcon , server ,
1225+ & rqst [0 ], & oplock , & oparms , utf16_path );
1226+ if (rc )
1227+ goto err_free ;
1228+ smb2_set_next_command (tcon , & rqst [0 ]);
1229+ creq = rqst [0 ].rq_iov [0 ].iov_base ;
1230+ creq -> ShareAccess = FILE_SHARE_DELETE_LE ;
1231+
1232+ rqst [1 ].rq_iov = & close_iov ;
1233+ rqst [1 ].rq_nvec = 1 ;
1234+
1235+ rc = SMB2_close_init (tcon , server , & rqst [1 ],
1236+ COMPOUND_FID , COMPOUND_FID , false);
1237+ smb2_set_related (& rqst [1 ]);
1238+ if (rc )
1239+ goto err_free ;
1240+
1241+ if (retries ) {
1242+ for (int i = 0 ; i < ARRAY_SIZE (rqst ); i ++ )
1243+ smb2_set_replay (server , & rqst [i ]);
1244+ }
1245+
1246+ rc = compound_send_recv (xid , tcon -> ses , server , flags ,
1247+ ARRAY_SIZE (rqst ), rqst ,
1248+ resp_buftype , rsp_iov );
1249+ SMB2_open_free (& rqst [0 ]);
1250+ SMB2_close_free (& rqst [1 ]);
1251+ free_rsp_buf (resp_buftype [0 ], rsp_iov [0 ].iov_base );
1252+ free_rsp_buf (resp_buftype [1 ], rsp_iov [1 ].iov_base );
1253+
1254+ if (is_replayable_error (rc ) &&
1255+ smb2_should_replay (tcon , & retries , & cur_sleep ))
1256+ goto again ;
1257+
1258+ /* Retry compound request without lease */
1259+ if (rc == - EINVAL && dentry ) {
1260+ dentry = NULL ;
1261+ retries = 0 ;
1262+ cur_sleep = 1 ;
1263+ goto again ;
11951264 }
11961265 /*
11971266 * If dentry (hence, inode) is NULL, lease break is going to
11981267 * take care of degrading leases on handles for deleted files.
11991268 */
12001269 if (!rc && inode )
12011270 cifs_mark_open_handles_for_deleted_file (inode , name );
1271+
1272+ return rc ;
1273+
1274+ err_free :
1275+ SMB2_open_free (& rqst [0 ]);
1276+ SMB2_close_free (& rqst [1 ]);
1277+ free_rsp_buf (resp_buftype [0 ], rsp_iov [0 ].iov_base );
1278+ free_rsp_buf (resp_buftype [1 ], rsp_iov [1 ].iov_base );
12021279 return rc ;
12031280}
12041281
0 commit comments