Commit a3a78b63 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '5.20-rc2-ksmbd-smb3-server-fixes' of git://git.samba.org/ksmbd

Pull ksmbd server fixes from Steve French:

 - important sparse file fix

 - allocation size fix

 - fix incorrect rc on bad share

 - share config fix

* tag '5.20-rc2-ksmbd-smb3-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: don't remove dos attribute xattr on O_TRUNC open
  ksmbd: remove unnecessary generic_fillattr in smb2_open
  ksmbd: request update to stale share config
  ksmbd: return STATUS_BAD_NETWORK_NAME error status if share is not configured
parents 963a70be 17661ecf
......@@ -349,6 +349,7 @@ enum KSMBD_TREE_CONN_STATUS {
#define KSMBD_SHARE_FLAG_STREAMS BIT(11)
#define KSMBD_SHARE_FLAG_FOLLOW_SYMLINKS BIT(12)
#define KSMBD_SHARE_FLAG_ACL_XATTR BIT(13)
#define KSMBD_SHARE_FLAG_UPDATE BIT(14)
/*
* Tree connect request flags.
......@@ -364,6 +365,7 @@ enum KSMBD_TREE_CONN_STATUS {
#define KSMBD_TREE_CONN_FLAG_READ_ONLY BIT(1)
#define KSMBD_TREE_CONN_FLAG_WRITABLE BIT(2)
#define KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT BIT(3)
#define KSMBD_TREE_CONN_FLAG_UPDATE BIT(4)
/*
* RPC over IPC.
......
......@@ -51,12 +51,16 @@ static void kill_share(struct ksmbd_share_config *share)
kfree(share);
}
void __ksmbd_share_config_put(struct ksmbd_share_config *share)
void ksmbd_share_config_del(struct ksmbd_share_config *share)
{
down_write(&shares_table_lock);
hash_del(&share->hlist);
up_write(&shares_table_lock);
}
void __ksmbd_share_config_put(struct ksmbd_share_config *share)
{
ksmbd_share_config_del(share);
kill_share(share);
}
......
......@@ -64,6 +64,7 @@ static inline int test_share_config_flag(struct ksmbd_share_config *share,
return share->flags & flag;
}
void ksmbd_share_config_del(struct ksmbd_share_config *share);
void __ksmbd_share_config_put(struct ksmbd_share_config *share);
static inline void ksmbd_share_config_put(struct ksmbd_share_config *share)
......
......@@ -19,7 +19,7 @@ struct ksmbd_tree_conn_status
ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
char *share_name)
{
struct ksmbd_tree_conn_status status = {-EINVAL, NULL};
struct ksmbd_tree_conn_status status = {-ENOENT, NULL};
struct ksmbd_tree_connect_response *resp = NULL;
struct ksmbd_share_config *sc;
struct ksmbd_tree_connect *tree_conn = NULL;
......@@ -57,6 +57,20 @@ ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
goto out_error;
tree_conn->flags = resp->connection_flags;
if (test_tree_conn_flag(tree_conn, KSMBD_TREE_CONN_FLAG_UPDATE)) {
struct ksmbd_share_config *new_sc;
ksmbd_share_config_del(sc);
new_sc = ksmbd_share_config_get(share_name);
if (!new_sc) {
pr_err("Failed to update stale share config\n");
status.ret = -ESTALE;
goto out_error;
}
ksmbd_share_config_put(sc);
sc = new_sc;
}
tree_conn->user = sess->user;
tree_conn->share_conf = sc;
status.tree_conn = tree_conn;
......
......@@ -1944,8 +1944,10 @@ int smb2_tree_connect(struct ksmbd_work *work)
rsp->hdr.Status = STATUS_SUCCESS;
rc = 0;
break;
case -ESTALE:
case -ENOENT:
case KSMBD_TREE_CONN_STATUS_NO_SHARE:
rsp->hdr.Status = STATUS_BAD_NETWORK_PATH;
rsp->hdr.Status = STATUS_BAD_NETWORK_NAME;
break;
case -ENOMEM:
case KSMBD_TREE_CONN_STATUS_NOMEM:
......@@ -2328,15 +2330,15 @@ static int smb2_remove_smb_xattrs(struct path *path)
name += strlen(name) + 1) {
ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
strncmp(&name[XATTR_USER_PREFIX_LEN], DOS_ATTRIBUTE_PREFIX,
DOS_ATTRIBUTE_PREFIX_LEN) &&
strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX, STREAM_PREFIX_LEN))
continue;
err = ksmbd_vfs_remove_xattr(user_ns, path->dentry, name);
if (err)
ksmbd_debug(SMB, "remove xattr failed : %s\n", name);
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
!strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
STREAM_PREFIX_LEN)) {
err = ksmbd_vfs_remove_xattr(user_ns, path->dentry,
name);
if (err)
ksmbd_debug(SMB, "remove xattr failed : %s\n",
name);
}
}
out:
kvfree(xattr_list);
......@@ -3042,12 +3044,6 @@ int smb2_open(struct ksmbd_work *work)
list_add(&fp->node, &fp->f_ci->m_fp_list);
write_unlock(&fp->f_ci->m_lock);
rc = ksmbd_vfs_getattr(&path, &stat);
if (rc) {
generic_fillattr(user_ns, d_inode(path.dentry), &stat);
rc = 0;
}
/* Check delete pending among previous fp before oplock break */
if (ksmbd_inode_pending_delete(fp)) {
rc = -EBUSY;
......@@ -3134,6 +3130,10 @@ int smb2_open(struct ksmbd_work *work)
}
}
rc = ksmbd_vfs_getattr(&path, &stat);
if (rc)
goto err_out;
if (stat.result_mask & STATX_BTIME)
fp->create_time = ksmbd_UnixTimeToNT(stat.btime);
else
......@@ -3149,9 +3149,6 @@ int smb2_open(struct ksmbd_work *work)
memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
generic_fillattr(user_ns, file_inode(fp->filp),
&stat);
rsp->StructureSize = cpu_to_le16(89);
rcu_read_lock();
opinfo = rcu_dereference(fp->f_opinfo);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment