LCOV - code coverage report
Current view: top level - spdk/examples/fsdev/hello_world - hello_fsdev.c (source / functions) Hit Total Coverage
Test: Combined Lines: 0 282 0.0 %
Date: 2024-08-13 08:37:22 Functions: 0 29 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 88 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "spdk/stdinc.h"
       6                 :            : #include "spdk/thread.h"
       7                 :            : #include "spdk/fsdev.h"
       8                 :            : #include "spdk/env.h"
       9                 :            : #include "spdk/event.h"
      10                 :            : #include "spdk/log.h"
      11                 :            : #include "spdk/string.h"
      12                 :            : 
      13                 :            : #define TEST_FILENAME "hello_file"
      14                 :            : #define DATA_SIZE 512
      15                 :            : #define ROOT_NODEID 1
      16                 :            : 
      17                 :            : static char *g_fsdev_name = "Fs0";
      18                 :            : int g_result = 0;
      19                 :            : 
      20                 :            : /*
      21                 :            :  * We'll use this struct to gather housekeeping hello_context to pass between
      22                 :            :  * our events and callbacks.
      23                 :            :  */
      24                 :            : struct hello_context_t {
      25                 :            :         struct spdk_thread *app_thread;
      26                 :            :         struct spdk_fsdev_desc *fsdev_desc;
      27                 :            :         struct spdk_io_channel *fsdev_io_channel;
      28                 :            :         struct spdk_fsdev_file_object *root_fobject;
      29                 :            :         char *fsdev_name;
      30                 :            :         int thread_count;
      31                 :            : };
      32                 :            : 
      33                 :            : struct hello_thread_t {
      34                 :            :         struct hello_context_t *hello_context;
      35                 :            :         struct spdk_thread *thread;
      36                 :            :         struct spdk_io_channel *fsdev_io_channel;
      37                 :            :         uint64_t unique;
      38                 :            :         uint8_t *buf;
      39                 :            :         char *file_name;
      40                 :            :         struct spdk_fsdev_file_object *fobject;
      41                 :            :         struct spdk_fsdev_file_handle *fhandle;
      42                 :            :         struct iovec iov[2];
      43                 :            : };
      44                 :            : 
      45                 :            : /*
      46                 :            :  * Usage function for printing parameters that are specific to this application
      47                 :            :  */
      48                 :            : static void
      49                 :          0 : hello_fsdev_usage(void)
      50                 :            : {
      51         [ #  # ]:          0 :         printf(" -f <fs>                 name of the fsdev to use\n");
      52                 :          0 : }
      53                 :            : 
      54                 :            : /*
      55                 :            :  * This function is called to parse the parameters that are specific to this application
      56                 :            :  */
      57                 :            : static int
      58                 :          0 : hello_fsdev_parse_arg(int ch, char *arg)
      59                 :            : {
      60         [ #  # ]:          0 :         switch (ch) {
      61                 :          0 :         case 'f':
      62                 :          0 :                 g_fsdev_name = arg;
      63                 :          0 :                 break;
      64                 :          0 :         default:
      65                 :          0 :                 return -EINVAL;
      66                 :            :         }
      67                 :          0 :         return 0;
      68                 :            : }
      69                 :            : 
      70                 :            : static void
      71                 :          0 : hello_app_done(struct hello_context_t *hello_context, int rc)
      72                 :            : {
      73                 :          0 :         spdk_put_io_channel(hello_context->fsdev_io_channel);
      74                 :          0 :         spdk_fsdev_close(hello_context->fsdev_desc);
      75                 :          0 :         SPDK_NOTICELOG("Stopping app: rc %d\n", rc);
      76                 :          0 :         spdk_app_stop(rc);
      77                 :          0 : }
      78                 :            : 
      79                 :            : static void
      80                 :          0 : root_forget_complete(void *cb_arg, struct spdk_io_channel *ch, int status)
      81                 :            : {
      82                 :          0 :         struct hello_context_t *hello_context = cb_arg;
      83                 :            : 
      84                 :          0 :         SPDK_NOTICELOG("Root forget complete (status=%d)\n", status);
      85         [ #  # ]:          0 :         if (status) {
      86                 :          0 :                 SPDK_ERRLOG("Root forget failed: error %d\n", status);
      87                 :          0 :                 g_result = EINVAL;
      88                 :            :         }
      89                 :            : 
      90                 :          0 :         hello_app_done(hello_context, g_result);
      91                 :          0 : }
      92                 :            : 
      93                 :            : static void
      94                 :          0 : hello_root_release(struct hello_context_t *hello_context)
      95                 :            : {
      96                 :            :         int res;
      97                 :            : 
      98                 :          0 :         SPDK_NOTICELOG("Forget root\n");
      99                 :          0 :         res = spdk_fsdev_forget(hello_context->fsdev_desc, hello_context->fsdev_io_channel, 0,
     100                 :            :                                 hello_context->root_fobject, 1,
     101                 :            :                                 root_forget_complete, hello_context);
     102         [ #  # ]:          0 :         if (res) {
     103                 :          0 :                 SPDK_ERRLOG("Failed to forget root (err=%d)\n", res);
     104                 :          0 :                 hello_app_done(hello_context, EINVAL);
     105                 :            :         }
     106                 :          0 : }
     107                 :            : 
     108                 :            : static void
     109                 :          0 : hello_app_notify_thread_done(void *ctx)
     110                 :            : {
     111                 :          0 :         struct hello_context_t *hello_context = (struct hello_context_t *)ctx;
     112                 :            : 
     113         [ #  # ]:          0 :         assert(hello_context->thread_count > 0);
     114                 :          0 :         hello_context->thread_count--;
     115         [ #  # ]:          0 :         if (hello_context->thread_count == 0) {
     116                 :          0 :                 hello_root_release(hello_context);
     117                 :            :         }
     118                 :          0 : }
     119                 :            : 
     120                 :            : static void
     121                 :          0 : hello_thread_done(struct hello_thread_t *hello_thread, int rc)
     122                 :            : {
     123                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     124                 :            : 
     125                 :          0 :         spdk_put_io_channel(hello_thread->fsdev_io_channel);
     126                 :          0 :         free(hello_thread->buf);
     127                 :          0 :         free(hello_thread->file_name);
     128                 :          0 :         SPDK_NOTICELOG("Thread %s done: rc %d\n",
     129                 :            :                        spdk_thread_get_name(hello_thread->thread), rc);
     130                 :          0 :         spdk_thread_exit(hello_thread->thread);
     131                 :          0 :         free(hello_thread);
     132         [ #  # ]:          0 :         if (rc) {
     133                 :          0 :                 g_result = rc;
     134                 :            :         }
     135                 :            : 
     136                 :          0 :         spdk_thread_send_msg(hello_context->app_thread, hello_app_notify_thread_done, hello_context);
     137                 :          0 : }
     138                 :            : 
     139                 :            : static bool
     140                 :          0 : hello_check_complete(struct hello_thread_t *hello_thread, int status, const char *op)
     141                 :            : {
     142                 :          0 :         hello_thread->unique++;
     143         [ #  # ]:          0 :         if (status) {
     144                 :          0 :                 SPDK_ERRLOG("%s failed with %d\n", op, status);
     145                 :          0 :                 hello_thread_done(hello_thread, EIO);
     146                 :          0 :                 return false;
     147                 :            :         }
     148                 :            : 
     149                 :          0 :         return true;
     150                 :            : }
     151                 :            : 
     152                 :            : static void
     153                 :          0 : unlink_complete(void *cb_arg, struct spdk_io_channel *ch, int status)
     154                 :            : {
     155                 :          0 :         struct hello_thread_t *hello_thread = cb_arg;
     156                 :            : 
     157                 :          0 :         SPDK_NOTICELOG("Unlink complete (status=%d)\n", status);
     158         [ #  # ]:          0 :         if (!hello_check_complete(hello_thread, status, "unlink")) {
     159                 :          0 :                 return;
     160                 :            :         }
     161                 :            : 
     162                 :          0 :         hello_thread->fobject = NULL;
     163                 :          0 :         hello_thread_done(hello_thread, 0);
     164                 :            : }
     165                 :            : 
     166                 :            : static void
     167                 :          0 : hello_unlink(struct hello_thread_t *hello_thread)
     168                 :            : {
     169                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     170                 :            :         int res;
     171                 :            : 
     172                 :          0 :         SPDK_NOTICELOG("Unlink file %s\n", hello_thread->file_name);
     173                 :            : 
     174                 :          0 :         res = spdk_fsdev_unlink(hello_context->fsdev_desc, hello_thread->fsdev_io_channel,
     175                 :          0 :                                 hello_thread->unique, hello_context->root_fobject, hello_thread->file_name,
     176                 :            :                                 unlink_complete, hello_thread);
     177         [ #  # ]:          0 :         if (res) {
     178                 :          0 :                 SPDK_ERRLOG("unlink failed with %d\n", res);
     179                 :          0 :                 hello_thread_done(hello_thread, EIO);
     180                 :            :         }
     181                 :          0 : }
     182                 :            : 
     183                 :            : static void
     184                 :          0 : release_complete(void *cb_arg, struct spdk_io_channel *ch, int status)
     185                 :            : {
     186                 :          0 :         struct hello_thread_t *hello_thread = cb_arg;
     187                 :            : 
     188                 :          0 :         SPDK_NOTICELOG("Release complete (status=%d)\n", status);
     189         [ #  # ]:          0 :         if (!hello_check_complete(hello_thread, status, "release")) {
     190                 :          0 :                 return;
     191                 :            :         }
     192                 :            : 
     193                 :          0 :         hello_thread->fhandle = NULL;
     194                 :          0 :         hello_unlink(hello_thread);
     195                 :            : }
     196                 :            : 
     197                 :            : static void
     198                 :          0 : hello_release(struct hello_thread_t *hello_thread)
     199                 :            : {
     200                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     201                 :            :         int res;
     202                 :            : 
     203                 :          0 :         SPDK_NOTICELOG("Release file handle %p\n", hello_thread->fhandle);
     204                 :            : 
     205                 :          0 :         res = spdk_fsdev_release(hello_context->fsdev_desc, hello_thread->fsdev_io_channel,
     206                 :            :                                  hello_thread->unique, hello_thread->fobject, hello_thread->fhandle,
     207                 :            :                                  release_complete, hello_thread);
     208         [ #  # ]:          0 :         if (res) {
     209                 :          0 :                 SPDK_ERRLOG("release failed with %d\n", res);
     210                 :          0 :                 hello_thread_done(hello_thread, EIO);
     211                 :            :         }
     212                 :          0 : }
     213                 :            : 
     214                 :            : static void
     215                 :          0 : read_complete(void *cb_arg, struct spdk_io_channel *ch, int status, uint32_t data_size)
     216                 :            : {
     217                 :          0 :         struct hello_thread_t *hello_thread = cb_arg;
     218                 :          0 :         uint8_t data = spdk_env_get_current_core();
     219                 :            :         uint32_t i;
     220                 :            : 
     221                 :          0 :         SPDK_NOTICELOG("Read complete (status=%d, %" PRIu32 "bytes read)\n", status, data_size);
     222         [ #  # ]:          0 :         if (!hello_check_complete(hello_thread, status, "read")) {
     223                 :          0 :                 return;
     224                 :            :         }
     225                 :            : 
     226         [ #  # ]:          0 :         assert(data_size == DATA_SIZE);
     227                 :            : 
     228         [ #  # ]:          0 :         for (i = 0; i < DATA_SIZE; ++i) {
     229         [ #  # ]:          0 :                 if (hello_thread->buf[i] != data) {
     230                 :          0 :                         SPDK_NOTICELOG("Bad read data at offset %d, 0x%02X != 0x%02X\n",
     231                 :            :                                        i, hello_thread->buf[i], data);
     232                 :          0 :                         break;
     233                 :            :                 }
     234                 :            :         }
     235                 :            : 
     236                 :          0 :         hello_release(hello_thread);
     237                 :            : }
     238                 :            : 
     239                 :            : static void
     240                 :          0 : hello_read(struct hello_thread_t *hello_thread)
     241                 :            : {
     242                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     243                 :            :         int res;
     244                 :            : 
     245                 :          0 :         SPDK_NOTICELOG("Read from file handle %p\n", hello_thread->fhandle);
     246                 :            : 
     247         [ #  # ]:          0 :         memset(hello_thread->buf, 0xFF, DATA_SIZE);
     248                 :            : 
     249                 :          0 :         hello_thread->iov[0].iov_base = hello_thread->buf;
     250                 :          0 :         hello_thread->iov[0].iov_len = DATA_SIZE / 4;
     251                 :          0 :         hello_thread->iov[1].iov_base = hello_thread->buf + hello_thread->iov[0].iov_len;
     252                 :          0 :         hello_thread->iov[1].iov_len = DATA_SIZE - hello_thread->iov[0].iov_len;
     253                 :            : 
     254                 :          0 :         res = spdk_fsdev_read(hello_context->fsdev_desc, hello_thread->fsdev_io_channel,
     255                 :            :                               hello_thread->unique, hello_thread->fobject, hello_thread->fhandle,
     256                 :          0 :                               DATA_SIZE, 0, 0, hello_thread->iov, 2, NULL,
     257                 :            :                               read_complete, hello_thread);
     258         [ #  # ]:          0 :         if (res) {
     259                 :          0 :                 SPDK_ERRLOG("write failed with %d\n", res);
     260                 :          0 :                 hello_thread_done(hello_thread, EIO);
     261                 :            :         }
     262                 :          0 : }
     263                 :            : 
     264                 :            : static void
     265                 :          0 : write_complete(void *cb_arg, struct spdk_io_channel *ch, int status, uint32_t data_size)
     266                 :            : {
     267                 :          0 :         struct hello_thread_t *hello_thread = cb_arg;
     268                 :            : 
     269                 :          0 :         SPDK_NOTICELOG("Write complete (status=%d, %" PRIu32 "bytes written)\n", status, data_size);
     270         [ #  # ]:          0 :         if (!hello_check_complete(hello_thread, status, "write")) {
     271                 :          0 :                 return;
     272                 :            :         }
     273                 :            : 
     274         [ #  # ]:          0 :         assert(data_size == DATA_SIZE);
     275                 :          0 :         hello_read(hello_thread);
     276                 :            : }
     277                 :            : 
     278                 :            : static void
     279                 :          0 : hello_write(struct hello_thread_t *hello_thread)
     280                 :            : {
     281                 :          0 :         uint8_t data = spdk_env_get_current_core();
     282                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     283                 :            :         int res;
     284                 :            : 
     285                 :          0 :         SPDK_NOTICELOG("Write to file handle %p\n", hello_thread->fhandle);
     286                 :            : 
     287         [ #  # ]:          0 :         memset(hello_thread->buf, data, DATA_SIZE);
     288                 :            : 
     289                 :          0 :         hello_thread->iov[0].iov_base = hello_thread->buf;
     290                 :          0 :         hello_thread->iov[0].iov_len = DATA_SIZE / 2;
     291                 :          0 :         hello_thread->iov[1].iov_base = hello_thread->buf + hello_thread->iov[0].iov_len;
     292                 :          0 :         hello_thread->iov[1].iov_len = DATA_SIZE - hello_thread->iov[0].iov_len;
     293                 :            : 
     294                 :          0 :         res = spdk_fsdev_write(hello_context->fsdev_desc, hello_thread->fsdev_io_channel,
     295                 :            :                                hello_thread->unique, hello_thread->fobject, hello_thread->fhandle,
     296                 :          0 :                                DATA_SIZE, 0, 0, hello_thread->iov, 2, NULL,
     297                 :            :                                write_complete, hello_thread);
     298         [ #  # ]:          0 :         if (res) {
     299                 :          0 :                 SPDK_ERRLOG("write failed with %d\n", res);
     300                 :          0 :                 hello_thread_done(hello_thread, EIO);
     301                 :            :         }
     302                 :          0 : }
     303                 :            : 
     304                 :            : static void
     305                 :          0 : fopen_complete(void *cb_arg, struct spdk_io_channel *ch, int status,
     306                 :            :                struct spdk_fsdev_file_handle *fhandle)
     307                 :            : {
     308                 :          0 :         struct hello_thread_t *hello_thread = cb_arg;
     309                 :            : 
     310                 :          0 :         SPDK_NOTICELOG("Open complete (status=%d)\n", status);
     311         [ #  # ]:          0 :         if (!hello_check_complete(hello_thread, status, "open")) {
     312                 :          0 :                 return;
     313                 :            :         }
     314                 :            : 
     315                 :          0 :         hello_thread->fhandle = fhandle;
     316                 :          0 :         hello_write(hello_thread);
     317                 :            : }
     318                 :            : 
     319                 :            : static void
     320                 :          0 : hello_open(struct hello_thread_t *hello_thread)
     321                 :            : {
     322                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     323                 :            :         int res;
     324                 :            : 
     325                 :          0 :         SPDK_NOTICELOG("Open fobject %p\n", hello_thread->fobject);
     326                 :            : 
     327                 :          0 :         res = spdk_fsdev_fopen(hello_context->fsdev_desc, hello_thread->fsdev_io_channel,
     328                 :            :                                hello_thread->unique, hello_thread->fobject, O_RDWR,
     329                 :            :                                fopen_complete, hello_thread);
     330         [ #  # ]:          0 :         if (res) {
     331                 :          0 :                 SPDK_ERRLOG("open failed with %d\n", res);
     332                 :          0 :                 hello_thread_done(hello_thread, EIO);
     333                 :            :         }
     334                 :          0 : }
     335                 :            : 
     336                 :            : static void
     337                 :          0 : lookup_complete(void *cb_arg, struct spdk_io_channel *ch, int status,
     338                 :            :                 struct spdk_fsdev_file_object *fobject, const struct spdk_fsdev_file_attr *attr)
     339                 :            : {
     340                 :          0 :         struct hello_thread_t *hello_thread = cb_arg;
     341                 :            : 
     342                 :          0 :         SPDK_NOTICELOG("Lookup complete (status=%d)\n", status);
     343         [ #  # ]:          0 :         if (!hello_check_complete(hello_thread, status, "lookup")) {
     344                 :          0 :                 return;
     345                 :            :         }
     346                 :            : 
     347         [ #  # ]:          0 :         assert(hello_thread->fobject == fobject);
     348                 :          0 :         hello_open(hello_thread);
     349                 :            : }
     350                 :            : 
     351                 :            : static void
     352                 :          0 : hello_lookup(struct hello_thread_t *hello_thread)
     353                 :            : {
     354                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     355                 :            :         int res;
     356                 :            : 
     357                 :          0 :         SPDK_NOTICELOG("Lookup file %s\n", hello_thread->file_name);
     358                 :            : 
     359                 :          0 :         res = spdk_fsdev_lookup(hello_context->fsdev_desc, hello_thread->fsdev_io_channel,
     360                 :          0 :                                 hello_thread->unique, hello_context->root_fobject, hello_thread->file_name,
     361                 :            :                                 lookup_complete, hello_thread);
     362         [ #  # ]:          0 :         if (res) {
     363                 :          0 :                 SPDK_ERRLOG("lookup failed with %d\n", res);
     364                 :          0 :                 hello_thread_done(hello_thread, EIO);
     365                 :            :         }
     366                 :          0 : }
     367                 :            : 
     368                 :            : static void
     369                 :          0 : mknod_complete(void *cb_arg, struct spdk_io_channel *ch, int status,
     370                 :            :                struct spdk_fsdev_file_object *fobject, const struct spdk_fsdev_file_attr *attr)
     371                 :            : {
     372                 :          0 :         struct hello_thread_t *hello_thread = cb_arg;
     373                 :            : 
     374                 :          0 :         SPDK_NOTICELOG("Mknod complete (status=%d)\n", status);
     375         [ #  # ]:          0 :         if (!hello_check_complete(hello_thread, status, "mknod")) {
     376                 :          0 :                 return;
     377                 :            :         }
     378                 :            : 
     379                 :          0 :         hello_thread->fobject = fobject;
     380                 :          0 :         hello_lookup(hello_thread);
     381                 :            : }
     382                 :            : 
     383                 :            : static void
     384                 :          0 : hello_mknod(void *ctx)
     385                 :            : {
     386                 :          0 :         struct hello_thread_t *hello_thread = (struct hello_thread_t *)ctx;
     387                 :          0 :         struct hello_context_t *hello_context = hello_thread->hello_context;
     388                 :            :         int res;
     389                 :            : 
     390                 :          0 :         SPDK_NOTICELOG("Mknod file %s\n", hello_thread->file_name);
     391                 :            : 
     392                 :          0 :         res = spdk_fsdev_mknod(hello_context->fsdev_desc, hello_thread->fsdev_io_channel,
     393                 :          0 :                                hello_thread->unique, hello_context->root_fobject, hello_thread->file_name,
     394                 :            :                                S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO, 0, 0, 0, mknod_complete, hello_thread);
     395         [ #  # ]:          0 :         if (res) {
     396                 :          0 :                 SPDK_ERRLOG("mknod failed with %d\n", res);
     397                 :          0 :                 hello_thread_done(hello_thread, EIO);
     398                 :            :         }
     399                 :          0 : }
     400                 :            : 
     401                 :            : static void
     402                 :          0 : hello_start_thread(void *ctx)
     403                 :            : {
     404                 :          0 :         struct hello_context_t *hello_context = (struct hello_context_t *)ctx;
     405                 :            :         struct hello_thread_t *hello_thread;
     406                 :            :         /* File name size assumes that core number will fit into 3 characters */
     407                 :          0 :         const int filename_size = strlen(TEST_FILENAME) + 5;
     408                 :            : 
     409                 :          0 :         hello_thread = calloc(1, sizeof(struct hello_thread_t));
     410         [ #  # ]:          0 :         if (!hello_thread) {
     411                 :          0 :                 SPDK_ERRLOG("Failed to allocate thread context\n");
     412                 :          0 :                 spdk_thread_send_msg(hello_context->app_thread, hello_app_notify_thread_done, hello_context);
     413                 :          0 :                 return;
     414                 :            :         }
     415                 :            : 
     416                 :          0 :         hello_thread->hello_context = hello_context;
     417                 :          0 :         hello_thread->thread = spdk_get_thread();
     418                 :          0 :         hello_thread->unique = 1;
     419                 :          0 :         hello_thread->buf = (char *)malloc(DATA_SIZE);
     420         [ #  # ]:          0 :         if (!hello_thread->buf) {
     421                 :          0 :                 SPDK_ERRLOG("Could not allocate data buffer\n");
     422                 :          0 :                 hello_thread_done(hello_thread, ENOMEM);
     423                 :          0 :                 return;
     424                 :            :         }
     425                 :            : 
     426                 :          0 :         hello_thread->file_name = (char *)malloc(filename_size);
     427         [ #  # ]:          0 :         if (!hello_thread->file_name) {
     428                 :          0 :                 SPDK_ERRLOG("Could not allocate file name buffer\n");
     429                 :          0 :                 hello_thread_done(hello_thread, ENOMEM);
     430                 :          0 :                 return;
     431                 :            :         }
     432                 :            : 
     433   [ #  #  #  # ]:          0 :         if (snprintf(hello_thread->file_name, filename_size, "%s_%u",
     434                 :            :                      TEST_FILENAME, spdk_env_get_current_core()) >= filename_size) {
     435                 :          0 :                 SPDK_ERRLOG("File name size doesn't fit into buffer\n");
     436                 :          0 :                 hello_thread_done(hello_thread, ENOMEM);
     437                 :          0 :                 return;
     438                 :            :         }
     439                 :            : 
     440                 :          0 :         hello_thread->fsdev_io_channel = spdk_fsdev_get_io_channel(hello_thread->hello_context->fsdev_desc);
     441         [ #  # ]:          0 :         if (!hello_thread->fsdev_io_channel) {
     442                 :          0 :                 SPDK_ERRLOG("Could not create fsdev I/O channel!\n");
     443                 :          0 :                 hello_thread_done(hello_thread, ENOMEM);
     444                 :          0 :                 return;
     445                 :            :         }
     446                 :            : 
     447                 :          0 :         SPDK_NOTICELOG("Started thread %s on core %u\n",
     448                 :            :                        spdk_thread_get_name(hello_thread->thread),
     449                 :            :                        spdk_env_get_current_core());
     450                 :          0 :         spdk_thread_send_msg(hello_thread->thread, hello_mknod, hello_thread);
     451                 :            : }
     452                 :            : 
     453                 :            : static void
     454                 :          0 : hello_create_threads(struct hello_context_t *hello_context)
     455                 :            : {
     456                 :            :         uint32_t cpu;
     457                 :          0 :         char thread_name[32];
     458                 :          0 :         struct spdk_cpuset mask = {};
     459                 :            :         struct spdk_thread *thread;
     460                 :            : 
     461         [ #  # ]:          0 :         SPDK_ENV_FOREACH_CORE(cpu) {
     462         [ #  # ]:          0 :                 snprintf(thread_name, sizeof(thread_name), "hello_fsdev_%u", cpu);
     463                 :          0 :                 spdk_cpuset_zero(&mask);
     464                 :          0 :                 spdk_cpuset_set_cpu(&mask, cpu, true);
     465                 :          0 :                 thread = spdk_thread_create(thread_name, &mask);
     466         [ #  # ]:          0 :                 assert(thread != NULL);
     467                 :          0 :                 hello_context->thread_count++;
     468                 :          0 :                 spdk_thread_send_msg(thread, hello_start_thread, hello_context);
     469                 :            :         }
     470                 :          0 : }
     471                 :            : 
     472                 :            : 
     473                 :            : static void
     474                 :          0 : root_lookup_complete(void *cb_arg, struct spdk_io_channel *ch, int status,
     475                 :            :                      struct spdk_fsdev_file_object *fobject, const struct spdk_fsdev_file_attr *attr)
     476                 :            : {
     477                 :          0 :         struct hello_context_t *hello_context = cb_arg;
     478                 :            : 
     479                 :          0 :         SPDK_NOTICELOG("Root lookup complete (status=%d)\n", status);
     480         [ #  # ]:          0 :         if (status) {
     481                 :          0 :                 SPDK_ERRLOG("Fuse init failed: error %d\n", status);
     482                 :          0 :                 hello_app_done(hello_context, status);
     483                 :          0 :                 return;
     484                 :            :         }
     485                 :            : 
     486                 :          0 :         hello_context->root_fobject = fobject;
     487                 :            : 
     488                 :          0 :         hello_create_threads(hello_context);
     489                 :            : }
     490                 :            : 
     491                 :            : static void
     492                 :          0 : root_lookup(struct hello_context_t *hello_context)
     493                 :            : {
     494                 :            :         int res;
     495                 :            : 
     496                 :          0 :         SPDK_NOTICELOG("Lookup for the root\n");
     497                 :            : 
     498                 :          0 :         res = spdk_fsdev_lookup(hello_context->fsdev_desc, hello_context->fsdev_io_channel, 0,
     499                 :            :                                 NULL /* root */, "" /* will be ignored */, root_lookup_complete, hello_context);
     500         [ #  # ]:          0 :         if (res) {
     501                 :          0 :                 SPDK_ERRLOG("Failed to initiate lookup for the root (err=%d)\n", res);
     502                 :          0 :                 hello_app_done(hello_context, res);
     503                 :          0 :                 return;
     504                 :            :         }
     505                 :            : }
     506                 :            : 
     507                 :            : static void
     508                 :          0 : hello_fsdev_event_cb(enum spdk_fsdev_event_type type, struct spdk_fsdev *fsdev, void *event_ctx)
     509                 :            : {
     510                 :          0 :         SPDK_NOTICELOG("Unsupported fsdev event: type %d\n", type);
     511                 :          0 : }
     512                 :            : 
     513                 :            : /*
     514                 :            :  * Our initial event that kicks off everything from main().
     515                 :            :  */
     516                 :            : static void
     517                 :          0 : hello_start(void *arg1)
     518                 :            : {
     519                 :          0 :         struct hello_context_t *hello_context = arg1;
     520                 :          0 :         int rc = 0;
     521                 :          0 :         hello_context->fsdev_desc = NULL;
     522                 :            : 
     523                 :          0 :         SPDK_NOTICELOG("Successfully started the application\n");
     524                 :            : 
     525                 :          0 :         hello_context->app_thread = spdk_get_thread();
     526                 :            : 
     527                 :            :         /*
     528                 :            :          * There can be many fsdevs configured, but this application will only use
     529                 :            :          * the one input by the user at runtime.
     530                 :            :          *
     531                 :            :          * Open the fs by calling spdk_fsdev_open() with its name.
     532                 :            :          * The function will return a descriptor
     533                 :            :          */
     534                 :          0 :         SPDK_NOTICELOG("Opening the fsdev %s\n", hello_context->fsdev_name);
     535                 :          0 :         rc = spdk_fsdev_open(hello_context->fsdev_name,
     536                 :            :                              hello_fsdev_event_cb, NULL, NULL,
     537                 :            :                              &hello_context->fsdev_desc);
     538         [ #  # ]:          0 :         if (rc) {
     539                 :          0 :                 SPDK_ERRLOG("Could not open fsdev: %s\n", hello_context->fsdev_name);
     540                 :          0 :                 spdk_app_stop(-1);
     541                 :          0 :                 return;
     542                 :            :         }
     543                 :            : 
     544                 :          0 :         SPDK_NOTICELOG("Opening io channel\n");
     545                 :            :         /* Open I/O channel */
     546                 :          0 :         hello_context->fsdev_io_channel = spdk_fsdev_get_io_channel(hello_context->fsdev_desc);
     547         [ #  # ]:          0 :         if (!hello_context->fsdev_io_channel) {
     548                 :          0 :                 SPDK_ERRLOG("Could not create fsdev I/O channel!\n");
     549                 :          0 :                 spdk_fsdev_close(hello_context->fsdev_desc);
     550                 :          0 :                 spdk_app_stop(-1);
     551                 :          0 :                 return;
     552                 :            :         }
     553                 :            : 
     554                 :          0 :         root_lookup(hello_context);
     555                 :            : }
     556                 :            : 
     557                 :            : int
     558                 :          0 : main(int argc, char **argv)
     559                 :            : {
     560                 :          0 :         struct spdk_app_opts opts = {};
     561                 :          0 :         int rc = 0;
     562                 :          0 :         struct hello_context_t hello_context = {};
     563                 :            : 
     564                 :            :         /* Set default values in opts structure. */
     565                 :          0 :         spdk_app_opts_init(&opts, sizeof(opts));
     566                 :          0 :         opts.name = "hello_fsdev";
     567                 :            : 
     568                 :            :         /*
     569                 :            :          * Parse built-in SPDK command line parameters as well
     570                 :            :          * as our custom one(s).
     571                 :            :          */
     572         [ #  # ]:          0 :         if ((rc = spdk_app_parse_args(argc, argv, &opts, "f:", NULL, hello_fsdev_parse_arg,
     573                 :            :                                       hello_fsdev_usage)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
     574                 :          0 :                 exit(rc);
     575                 :            :         }
     576                 :          0 :         hello_context.fsdev_name = g_fsdev_name;
     577                 :            : 
     578                 :            :         /*
     579                 :            :          * spdk_app_start() will initialize the SPDK framework, call hello_start(),
     580                 :            :          * and then block until spdk_app_stop() is called (or if an initialization
     581                 :            :          * error occurs, spdk_app_start() will return with rc even without calling
     582                 :            :          * hello_start().
     583                 :            :          */
     584                 :          0 :         rc = spdk_app_start(&opts, hello_start, &hello_context);
     585         [ #  # ]:          0 :         if (rc) {
     586                 :          0 :                 SPDK_ERRLOG("ERROR starting application\n");
     587                 :            :         }
     588                 :            : 
     589                 :            :         /* At this point either spdk_app_stop() was called, or spdk_app_start()
     590                 :            :          * failed because of internal error.
     591                 :            :          */
     592                 :            : 
     593                 :            :         /* Gracefully close out all of the SPDK subsystems. */
     594                 :          0 :         spdk_app_fini();
     595                 :          0 :         return rc;
     596                 :            : }

Generated by: LCOV version 1.14