linux/fs/ksmbd/mgmt/tree_connect.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
   4 */
   5
   6#include <linux/list.h>
   7#include <linux/slab.h>
   8#include <linux/xarray.h>
   9
  10#include "../transport_ipc.h"
  11#include "../connection.h"
  12
  13#include "tree_connect.h"
  14#include "user_config.h"
  15#include "share_config.h"
  16#include "user_session.h"
  17
  18struct ksmbd_tree_conn_status
  19ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name)
  20{
  21        struct ksmbd_tree_conn_status status = {-EINVAL, NULL};
  22        struct ksmbd_tree_connect_response *resp = NULL;
  23        struct ksmbd_share_config *sc;
  24        struct ksmbd_tree_connect *tree_conn = NULL;
  25        struct sockaddr *peer_addr;
  26        int ret;
  27
  28        sc = ksmbd_share_config_get(share_name);
  29        if (!sc)
  30                return status;
  31
  32        tree_conn = kzalloc(sizeof(struct ksmbd_tree_connect), GFP_KERNEL);
  33        if (!tree_conn) {
  34                status.ret = -ENOMEM;
  35                goto out_error;
  36        }
  37
  38        tree_conn->id = ksmbd_acquire_tree_conn_id(sess);
  39        if (tree_conn->id < 0) {
  40                status.ret = -EINVAL;
  41                goto out_error;
  42        }
  43
  44        peer_addr = KSMBD_TCP_PEER_SOCKADDR(sess->conn);
  45        resp = ksmbd_ipc_tree_connect_request(sess,
  46                                              sc,
  47                                              tree_conn,
  48                                              peer_addr);
  49        if (!resp) {
  50                status.ret = -EINVAL;
  51                goto out_error;
  52        }
  53
  54        status.ret = resp->status;
  55        if (status.ret != KSMBD_TREE_CONN_STATUS_OK)
  56                goto out_error;
  57
  58        tree_conn->flags = resp->connection_flags;
  59        tree_conn->user = sess->user;
  60        tree_conn->share_conf = sc;
  61        status.tree_conn = tree_conn;
  62
  63        ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn,
  64                              GFP_KERNEL));
  65        if (ret) {
  66                status.ret = -ENOMEM;
  67                goto out_error;
  68        }
  69        kvfree(resp);
  70        return status;
  71
  72out_error:
  73        if (tree_conn)
  74                ksmbd_release_tree_conn_id(sess, tree_conn->id);
  75        ksmbd_share_config_put(sc);
  76        kfree(tree_conn);
  77        kvfree(resp);
  78        return status;
  79}
  80
  81int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
  82                               struct ksmbd_tree_connect *tree_conn)
  83{
  84        int ret;
  85
  86        ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id);
  87        ksmbd_release_tree_conn_id(sess, tree_conn->id);
  88        xa_erase(&sess->tree_conns, tree_conn->id);
  89        ksmbd_share_config_put(tree_conn->share_conf);
  90        kfree(tree_conn);
  91        return ret;
  92}
  93
  94struct ksmbd_tree_connect *ksmbd_tree_conn_lookup(struct ksmbd_session *sess,
  95                                                  unsigned int id)
  96{
  97        return xa_load(&sess->tree_conns, id);
  98}
  99
 100struct ksmbd_share_config *ksmbd_tree_conn_share(struct ksmbd_session *sess,
 101                                                 unsigned int id)
 102{
 103        struct ksmbd_tree_connect *tc;
 104
 105        tc = ksmbd_tree_conn_lookup(sess, id);
 106        if (tc)
 107                return tc->share_conf;
 108        return NULL;
 109}
 110
 111int ksmbd_tree_conn_session_logoff(struct ksmbd_session *sess)
 112{
 113        int ret = 0;
 114        struct ksmbd_tree_connect *tc;
 115        unsigned long id;
 116
 117        xa_for_each(&sess->tree_conns, id, tc)
 118                ret |= ksmbd_tree_conn_disconnect(sess, tc);
 119        xa_destroy(&sess->tree_conns);
 120        return ret;
 121}
 122