1 /****************************************************************************
2  * fs/driver/fs_registerblockdriver.c
3  *
4  * Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved.
5  * Based on NuttX originally from nuttx source (nuttx/fs/ and nuttx/drivers/)
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ****************************************************************************/
20 
21 /****************************************************************************
22  * Included Files
23  ****************************************************************************/
24 
25 #include "vfs_config.h"
26 #include "sys/types.h"
27 #include "errno.h"
28 #include "fs/driver.h"
29 #include "vnode.h"
30 #include "string.h"
31 #include "path_cache.h"
32 #include "vnode.h"
33 #include "limits.h"
34 
35 /****************************************************************************
36  * Public Functions
37  ****************************************************************************/
38 
39 /****************************************************************************
40  * Name: register_blockdriver
41  *
42  * Description:
43  *   Register a block driver vnode the pseudo file system.
44  *
45  * Input parameters:
46  *   path - The path to the vnode to create
47  *   bops - The block driver operations structure
48  *   mode - inmode priviledges (not used)
49  *   priv - Private, user data that will be associated with the vnode.
50  *
51  * Returned Value:
52  *   Zero on success (with the vnode point in 'vnode'); A negated errno
53  *   value is returned on a failure (all error values returned by
54  *   vnode_reserve):
55  *
56  *   EINVAL - 'path' is invalid for this operation
57  *   EEXIST - An vnode already exists at 'path'
58  *   ENOMEM - Failed to allocate in-memory resources for the operation
59  *
60  ****************************************************************************/
61 
register_blockdriver(const char *path, const struct block_operations *bops, mode_t mode, void *priv)62 int register_blockdriver(const char *path,
63                          const struct block_operations *bops,
64                          mode_t mode, void *priv)
65 {
66   struct Vnode *vp = NULL;
67   int ret;
68 
69   if (path == NULL || strlen(path) >= PATH_MAX || strncmp("/dev/", path, DEV_PATH_LEN) != 0)
70     {
71       return -EINVAL;
72     }
73 
74   /* Insert an vnode for the device driver -- we need to hold the vnode
75    * semaphore to prevent access to the tree while we this.  This is because
76    * we will have a momentarily bad true until we populate the vnode with
77    * valid data.
78    */
79 
80   struct drv_data *data = (struct drv_data *)zalloc(sizeof(struct drv_data));
81 
82   data->ops = (void *)bops;
83   data->mode = mode;
84   data->priv = priv;
85 
86   VnodeHold();
87   ret = VnodeLookup(path, &vp, V_CREATE | V_DUMMY);
88   if (ret == OK)
89     {
90       /* We have it, now populate it with block driver specific information. */
91 
92       vp->type = VNODE_TYPE_BLK;
93       vp->data = data;
94       vp->mode = mode;
95     }
96 
97   VnodeDrop();
98   return ret;
99 }
100