Skip to content

Commit dbc0b90

Browse files
author
CKI KWF Bot
committed
Merge: CIFS: fix regression with rename14 LTP test [rhel-10.2]
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1680 - fix regression with rename14 LTP test JIRA: https://issues.redhat.com/browse/RHEL-124956 Signed-off-by: Paulo Alcantara <paalcant@redhat.com> Approved-by: Scott Mayhew <smayhew@redhat.com> Approved-by: Olga Kornievskaia <okorniev@redhat.com> Approved-by: David Howells <dhowells@redhat.com> Approved-by: Jay Shin <jaeshin@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 9f65111 + 63ef776 commit dbc0b90

File tree

4 files changed

+116
-45
lines changed

4 files changed

+116
-45
lines changed

fs/smb/client/cifsproto.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,8 @@ extern void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
312312

313313
extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
314314

315-
extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
316-
const char *path);
315+
void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
316+
struct dentry *dentry);
317317

318318
extern void cifs_mark_open_handles_for_deleted_file(struct inode *inode,
319319
const char *path);

fs/smb/client/inode.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,7 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
19841984
}
19851985

19861986
netfs_wait_for_outstanding_io(inode);
1987-
cifs_close_deferred_file_under_dentry(tcon, full_path);
1987+
cifs_close_deferred_file_under_dentry(tcon, dentry);
19881988
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
19891989
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
19901990
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
@@ -2482,11 +2482,8 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
24822482
}
24832483
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
24842484
do_rename_exit:
2485-
if (rc == 0) {
2485+
if (rc == 0)
24862486
d_move(from_dentry, to_dentry);
2487-
/* Force a new lookup */
2488-
d_drop(from_dentry);
2489-
}
24902487
cifs_put_tlink(tlink);
24912488
return rc;
24922489
}
@@ -2551,10 +2548,10 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
25512548
goto cifs_rename_exit;
25522549
}
25532550

2554-
cifs_close_deferred_file_under_dentry(tcon, from_name);
2551+
cifs_close_deferred_file_under_dentry(tcon, source_dentry);
25552552
if (d_inode(target_dentry) != NULL) {
25562553
netfs_wait_for_outstanding_io(d_inode(target_dentry));
2557-
cifs_close_deferred_file_under_dentry(tcon, to_name);
2554+
cifs_close_deferred_file_under_dentry(tcon, target_dentry);
25582555
}
25592556

25602557
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,

fs/smb/client/misc.c

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -832,33 +832,28 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
832832
kfree(tmp_list);
833833
}
834834
}
835-
void
836-
cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
835+
836+
void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon,
837+
struct dentry *dentry)
837838
{
838-
struct cifsFileInfo *cfile;
839839
struct file_list *tmp_list, *tmp_next_list;
840-
void *page;
841-
const char *full_path;
840+
struct cifsFileInfo *cfile;
842841
LIST_HEAD(file_head);
843842

844-
page = alloc_dentry_path();
845843
spin_lock(&tcon->open_file_lock);
846844
list_for_each_entry(cfile, &tcon->openFileList, tlist) {
847-
full_path = build_path_from_dentry(cfile->dentry, page);
848-
if (strstr(full_path, path)) {
849-
if (delayed_work_pending(&cfile->deferred)) {
850-
if (cancel_delayed_work(&cfile->deferred)) {
851-
spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
852-
cifs_del_deferred_close(cfile);
853-
spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
854-
855-
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
856-
if (tmp_list == NULL)
857-
break;
858-
tmp_list->cfile = cfile;
859-
list_add_tail(&tmp_list->list, &file_head);
860-
}
861-
}
845+
if ((cfile->dentry == dentry) &&
846+
delayed_work_pending(&cfile->deferred) &&
847+
cancel_delayed_work(&cfile->deferred)) {
848+
spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
849+
cifs_del_deferred_close(cfile);
850+
spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
851+
852+
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
853+
if (tmp_list == NULL)
854+
break;
855+
tmp_list->cfile = cfile;
856+
list_add_tail(&tmp_list->list, &file_head);
862857
}
863858
}
864859
spin_unlock(&tcon->open_file_lock);
@@ -868,7 +863,6 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
868863
list_del(&tmp_list->list);
869864
kfree(tmp_list);
870865
}
871-
free_dentry_path(page);
872866
}
873867

874868
/*

fs/smb/client/smb2inode.c

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,10 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
207207
server = cifs_pick_channel(ses);
208208

209209
vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
210-
if (vars == NULL)
211-
return -ENOMEM;
210+
if (vars == NULL) {
211+
rc = -ENOMEM;
212+
goto out;
213+
}
212214
rqst = &vars->rqst[0];
213215
rsp_iov = &vars->rsp_iov[0];
214216

@@ -685,7 +687,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
685687
}
686688

687689
for (i = 0; i < num_cmds; i++) {
688-
char *buf = rsp_iov[i + i].iov_base;
690+
char *buf = rsp_iov[i + 1].iov_base;
689691

690692
if (buf && resp_buftype[i + 1] != CIFS_NO_BUFFER)
691693
rc = server->ops->map_error(buf, false);
@@ -865,6 +867,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
865867
smb2_should_replay(tcon, &retries, &cur_sleep))
866868
goto replay_again;
867869

870+
out:
868871
if (cfile)
869872
cifsFileInfo_put(cfile);
870873

@@ -1172,30 +1175,107 @@ int
11721175
smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
11731176
struct cifs_sb_info *cifs_sb, struct dentry *dentry)
11741177
{
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;
11751182
struct cifs_open_parms oparms;
1183+
struct smb2_create_req *creq;
11761184
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;
11771192
int rc;
11781193

1179-
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) {
11801217
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+
}
11811223

1182-
oparms = CIFS_OPARMS(cifs_sb, tcon, name, DELETE,
1183-
FILE_OPEN, OPEN_REPARSE_POINT, ACL_NO_MODE);
1184-
rc = smb2_compound_op(xid, tcon, cifs_sb, name, &oparms,
1185-
NULL, &(int){SMB2_OP_UNLINK},
1186-
1, NULL, NULL, NULL, dentry);
1187-
if (rc == -EINVAL) {
1188-
cifs_dbg(FYI, "invalid lease key, resending request without lease");
1189-
rc = smb2_compound_op(xid, tcon, cifs_sb, name, &oparms,
1190-
NULL, &(int){SMB2_OP_UNLINK},
1191-
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;
11921264
}
11931265
/*
11941266
* If dentry (hence, inode) is NULL, lease break is going to
11951267
* take care of degrading leases on handles for deleted files.
11961268
*/
11971269
if (!rc && inode)
11981270
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);
11991279
return rc;
12001280
}
12011281

0 commit comments

Comments
 (0)