0001
0002
0003
0004
0005
0006 #include <linux/list.h>
0007 #include <linux/mm.h>
0008 #include <linux/slab.h>
0009 #include <linux/workqueue.h>
0010
0011 #include "server.h"
0012 #include "connection.h"
0013 #include "ksmbd_work.h"
0014 #include "mgmt/ksmbd_ida.h"
0015
0016 static struct kmem_cache *work_cache;
0017 static struct workqueue_struct *ksmbd_wq;
0018
0019 struct ksmbd_work *ksmbd_alloc_work_struct(void)
0020 {
0021 struct ksmbd_work *work = kmem_cache_zalloc(work_cache, GFP_KERNEL);
0022
0023 if (work) {
0024 work->compound_fid = KSMBD_NO_FID;
0025 work->compound_pfid = KSMBD_NO_FID;
0026 INIT_LIST_HEAD(&work->request_entry);
0027 INIT_LIST_HEAD(&work->async_request_entry);
0028 INIT_LIST_HEAD(&work->fp_entry);
0029 INIT_LIST_HEAD(&work->interim_entry);
0030 }
0031 return work;
0032 }
0033
0034 void ksmbd_free_work_struct(struct ksmbd_work *work)
0035 {
0036 WARN_ON(work->saved_cred != NULL);
0037
0038 kvfree(work->response_buf);
0039 kvfree(work->aux_payload_buf);
0040 kfree(work->tr_buf);
0041 kvfree(work->request_buf);
0042 if (work->async_id)
0043 ksmbd_release_id(&work->conn->async_ida, work->async_id);
0044 kmem_cache_free(work_cache, work);
0045 }
0046
0047 void ksmbd_work_pool_destroy(void)
0048 {
0049 kmem_cache_destroy(work_cache);
0050 }
0051
0052 int ksmbd_work_pool_init(void)
0053 {
0054 work_cache = kmem_cache_create("ksmbd_work_cache",
0055 sizeof(struct ksmbd_work), 0,
0056 SLAB_HWCACHE_ALIGN, NULL);
0057 if (!work_cache)
0058 return -ENOMEM;
0059 return 0;
0060 }
0061
0062 int ksmbd_workqueue_init(void)
0063 {
0064 ksmbd_wq = alloc_workqueue("ksmbd-io", 0, 0);
0065 if (!ksmbd_wq)
0066 return -ENOMEM;
0067 return 0;
0068 }
0069
0070 void ksmbd_workqueue_destroy(void)
0071 {
0072 destroy_workqueue(ksmbd_wq);
0073 ksmbd_wq = NULL;
0074 }
0075
0076 bool ksmbd_queue_work(struct ksmbd_work *work)
0077 {
0078 return queue_work(ksmbd_wq, &work->work);
0079 }