Skip to content

Commit

Permalink
Merge tag '6.7-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd
Browse files Browse the repository at this point in the history
Pull smb server updates from Steve French:
 "Seven ksmbd server fixes:

   - logoff improvement for multichannel bound connections

   - unicode fix for surrogate pairs

   - RDMA (smbdirect) fix for IB devices

   - fix locking deadlock in kern_path_create during rename

   - iov memory allocation fix

   - two minor cleanup patches (doc cleanup, and unused variable)"

* tag '6.7-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: no need to wait for binded connection termination at logoff
  ksmbd: add support for surrogate pair conversion
  ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev()
  ksmbd: fix recursive locking in vfs helpers
  ksmbd: fix kernel-doc comment of ksmbd_vfs_setxattr()
  ksmbd: reorganize ksmbd_iov_pin_rsp()
  ksmbd: Remove unused field in ksmbd_user struct
  • Loading branch information
Linus Torvalds committed Nov 2, 2023
2 parents 71fb7b3 + 67797da commit 4652b8e
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 118 deletions.
16 changes: 0 additions & 16 deletions fs/smb/server/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,23 +167,7 @@ void ksmbd_all_conn_set_status(u64 sess_id, u32 status)

void ksmbd_conn_wait_idle(struct ksmbd_conn *conn, u64 sess_id)
{
struct ksmbd_conn *bind_conn;

wait_event(conn->req_running_q, atomic_read(&conn->req_running) < 2);

down_read(&conn_list_lock);
list_for_each_entry(bind_conn, &conn_list, conns_list) {
if (bind_conn == conn)
continue;

if ((bind_conn->binding || xa_load(&bind_conn->sessions, sess_id)) &&
!ksmbd_conn_releasing(bind_conn) &&
atomic_read(&bind_conn->req_running)) {
wait_event(bind_conn->req_running_q,
atomic_read(&bind_conn->req_running) == 0);
}
}
up_read(&conn_list_lock);
}

int ksmbd_conn_write(struct ksmbd_work *work)
Expand Down
43 changes: 22 additions & 21 deletions fs/smb/server/ksmbd_work.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,28 @@ bool ksmbd_queue_work(struct ksmbd_work *work)
return queue_work(ksmbd_wq, &work->work);
}

static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib,
unsigned int ib_len)
static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib,
unsigned int ib_len)
{
work->iov[++work->iov_idx].iov_base = ib;
work->iov[work->iov_idx].iov_len = ib_len;
work->iov_cnt++;
}

static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
void *aux_buf, unsigned int aux_size)
{
struct aux_read *ar;
int need_iov_cnt = 1;

if (work->iov_alloc_cnt <= work->iov_cnt) {
if (aux_size) {
need_iov_cnt++;
ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL);
if (!ar)
return -ENOMEM;
}

if (work->iov_alloc_cnt < work->iov_cnt + need_iov_cnt) {
struct kvec *new;

work->iov_alloc_cnt += 4;
Expand All @@ -111,16 +128,6 @@ static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib,
work->iov = new;
}

work->iov[++work->iov_idx].iov_base = ib;
work->iov[work->iov_idx].iov_len = ib_len;
work->iov_cnt++;

return 0;
}

static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
void *aux_buf, unsigned int aux_size)
{
/* Plus rfc_length size on first iov */
if (!work->iov_idx) {
work->iov[work->iov_idx].iov_base = work->response_buf;
Expand All @@ -129,19 +136,13 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
work->iov_cnt++;
}

ksmbd_realloc_iov_pin(work, ib, len);
__ksmbd_iov_pin(work, ib, len);
inc_rfc1001_len(work->iov[0].iov_base, len);

if (aux_size) {
struct aux_read *ar;

ksmbd_realloc_iov_pin(work, aux_buf, aux_size);
__ksmbd_iov_pin(work, aux_buf, aux_size);
inc_rfc1001_len(work->iov[0].iov_base, aux_size);

ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL);
if (!ar)
return -ENOMEM;

ar->buf = aux_buf;
list_add(&ar->entry, &work->aux_read_list);
}
Expand Down
1 change: 0 additions & 1 deletion fs/smb/server/mgmt/user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ struct ksmbd_user {

size_t passkey_sz;
char *passkey;
unsigned int failed_login_count;
};

static inline bool user_guest(struct ksmbd_user *user)
Expand Down
40 changes: 30 additions & 10 deletions fs/smb/server/transport_rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2140,8 +2140,7 @@ static int smb_direct_ib_client_add(struct ib_device *ib_dev)
if (ib_dev->node_type != RDMA_NODE_IB_CA)
smb_direct_port = SMB_DIRECT_PORT_IWARP;

if (!ib_dev->ops.get_netdev ||
!rdma_frwr_is_supported(&ib_dev->attrs))
if (!rdma_frwr_is_supported(&ib_dev->attrs))
return 0;

smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL);
Expand Down Expand Up @@ -2241,17 +2240,38 @@ bool ksmbd_rdma_capable_netdev(struct net_device *netdev)
for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) {
struct net_device *ndev;

ndev = smb_dev->ib_dev->ops.get_netdev(smb_dev->ib_dev,
i + 1);
if (!ndev)
continue;
if (smb_dev->ib_dev->ops.get_netdev) {
ndev = smb_dev->ib_dev->ops.get_netdev(
smb_dev->ib_dev, i + 1);
if (!ndev)
continue;

if (ndev == netdev) {
if (ndev == netdev) {
dev_put(ndev);
rdma_capable = true;
goto out;
}
dev_put(ndev);
rdma_capable = true;
goto out;
/* if ib_dev does not implement ops.get_netdev
* check for matching infiniband GUID in hw_addr
*/
} else if (netdev->type == ARPHRD_INFINIBAND) {
struct netdev_hw_addr *ha;
union ib_gid gid;
u32 port_num;
int ret;

netdev_hw_addr_list_for_each(
ha, &netdev->dev_addrs) {
memcpy(&gid, ha->addr + 4, sizeof(gid));
ret = ib_find_gid(smb_dev->ib_dev, &gid,
&port_num, NULL);
if (!ret) {
rdma_capable = true;
goto out;
}
}
}
dev_put(ndev);
}
}
out:
Expand Down
Loading

0 comments on commit 4652b8e

Please sign in to comment.