Skip to content

Commit 25f6184

Browse files
paliSteve French
authored andcommitted
cifs: Remove intermediate object of failed create SFU call
Check if the server honored ATTR_SYSTEM flag by CREATE_OPTION_SPECIAL option. If not then server does not support ATTR_SYSTEM and newly created file is not SFU compatible, which means that the call failed. If CREATE was successful but either setting ATTR_SYSTEM failed or writing type/data information failed then remove the intermediate object created by CREATE. Otherwise intermediate empty object stay on the server. This ensures that if the creating of SFU files with system attribute is unsupported by the server then no empty file stay on the server as a result of unsupported operation. This is for example case with Samba server and Linux tmpfs storage without enabled xattr support (where Samba stores ATTR_SYSTEM bit). Cc: stable@vger.kernel.org Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent ef201e8 commit 25f6184

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

fs/smb/client/smb2ops.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5077,6 +5077,7 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
50775077
{
50785078
struct TCP_Server_Info *server = tcon->ses->server;
50795079
struct cifs_open_parms oparms;
5080+
struct cifs_open_info_data idata;
50805081
struct cifs_io_parms io_parms = {};
50815082
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
50825083
struct cifs_fid fid;
@@ -5146,10 +5147,20 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
51465147
CREATE_OPTION_SPECIAL, ACL_NO_MODE);
51475148
oparms.fid = &fid;
51485149

5149-
rc = server->ops->open(xid, &oparms, &oplock, NULL);
5150+
rc = server->ops->open(xid, &oparms, &oplock, &idata);
51505151
if (rc)
51515152
goto out;
51525153

5154+
/*
5155+
* Check if the server honored ATTR_SYSTEM flag by CREATE_OPTION_SPECIAL
5156+
* option. If not then server does not support ATTR_SYSTEM and newly
5157+
* created file is not SFU compatible, which means that the call failed.
5158+
*/
5159+
if (!(le32_to_cpu(idata.fi.Attributes) & ATTR_SYSTEM)) {
5160+
rc = -EOPNOTSUPP;
5161+
goto out_close;
5162+
}
5163+
51535164
if (type_len + data_len > 0) {
51545165
io_parms.pid = current->tgid;
51555166
io_parms.tcon = tcon;
@@ -5164,8 +5175,18 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
51645175
iov, ARRAY_SIZE(iov)-1);
51655176
}
51665177

5178+
out_close:
51675179
server->ops->close(xid, tcon, &fid);
51685180

5181+
/*
5182+
* If CREATE was successful but either setting ATTR_SYSTEM failed or
5183+
* writing type/data information failed then remove the intermediate
5184+
* object created by CREATE. Otherwise intermediate empty object stay
5185+
* on the server.
5186+
*/
5187+
if (rc)
5188+
server->ops->unlink(xid, tcon, full_path, cifs_sb, NULL);
5189+
51695190
out:
51705191
kfree(symname_utf16);
51715192
return rc;

0 commit comments

Comments
 (0)