Skip to content

Commit

Permalink
Merge tag '5.20-rc2-ksmbd-smb3-server-fixes' of git://git.samba.org/k…
Browse files Browse the repository at this point in the history
…smbd

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
  • Loading branch information
torvalds committed Aug 19, 2022
2 parents 963a70b + 17661ec commit a3a78b6
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 21 deletions.
2 changes: 2 additions & 0 deletions fs/ksmbd/ksmbd_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
6 changes: 5 additions & 1 deletion fs/ksmbd/mgmt/share_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions fs/ksmbd/mgmt/share_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 15 additions & 1 deletion fs/ksmbd/mgmt/tree_connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
35 changes: 16 additions & 19 deletions fs/ksmbd/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down

0 comments on commit a3a78b6

Please sign in to comment.