1 /****************************************************************************
2 * fs/driver/fs_openblockdriver.c
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership. The
7 * ASF licenses this file to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance with the
9 * License. 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, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 * License for the specific language governing permissions and limitations
17 * under the License.
18 *
19 ****************************************************************************/
20
21 /****************************************************************************
22 * Included Files
23 ****************************************************************************/
24
25 #include "vfs_config.h"
26 #include "errno.h"
27 #include "fs/driver.h"
28 #include "vnode.h"
29 #include "disk.h"
30 #include <linux/kernel.h>
31
32 /****************************************************************************
33 * Public Functions
34 ****************************************************************************/
35
36 /****************************************************************************
37 * Name: open_blockdriver
38 *
39 * Description:
40 * Return the vnode of the block driver specified by 'pathname'
41 *
42 * Input Parameters:
43 * pathname - the full path to the block driver to be opened
44 * mountflags - if MS_RDONLY is not set, then driver must support write
45 * operations (see include/sys/mount.h)
46 * ppvnode - address of the location to return the vnode reference
47 *
48 * Returned Value:
49 * Returns zero on success or a negated errno on failure:
50 *
51 * EINVAL - pathname or pvnode is NULL
52 * ENOENT - No block driver of this name is registered
53 * ENOTBLK - The vnode associated with the pathname is not a block driver
54 * EACCESS - The MS_RDONLY option was not set but this driver does not
55 * support write access
56 *
57 ****************************************************************************/
58
59
60 extern int find_blockdriver(const char *pathname, int mountflags, struct Vnode **vpp);
61
open_blockdriver(const char * pathname,int mountflags,struct Vnode ** ppvnode)62 int open_blockdriver(const char *pathname, int mountflags,
63 struct Vnode **ppvnode)
64 {
65 struct Vnode *vnode_ptr = NULL;
66 los_part *part = NULL;
67 los_disk *disk = NULL;
68 int ret;
69
70 /* Minimal sanity checks */
71
72 #ifdef CONFIG_DEBUG
73 if (ppvnode == NULL)
74 {
75 ret = -EINVAL;
76 goto errout;
77 }
78 #endif
79
80 /* Find the vnode associated with this block driver name. find_blockdriver
81 * will perform all additional error checking.
82 */
83
84 ret = find_blockdriver(pathname, mountflags, &vnode_ptr);
85 if (ret < 0)
86 {
87 PRINT_DEBUG("Failed to file %s block driver\n", pathname);
88 goto errout;
89 }
90
91 /* Open the block driver. Note that no mutually exclusive access
92 * to the driver is enforced here. That must be done in the driver
93 * if needed.
94 */
95
96 struct drv_data* drv = (struct drv_data*)vnode_ptr->data;
97 struct block_operations *ops = (struct block_operations *)drv->ops;
98
99 part = los_part_find(vnode_ptr);
100 if (part != NULL)
101 {
102 disk = get_disk(part->disk_id);
103 if (disk == NULL)
104 {
105 ret = -EINVAL;
106 goto errout_with_vnode;
107 }
108
109 if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR)
110 {
111 PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__);
112 return -1;
113 }
114 if (disk->disk_status == STAT_INUSED)
115 {
116
117 if (ops->open != NULL)
118 {
119 ret = ops->open(vnode_ptr);
120 if (ret < 0)
121 {
122 PRINT_DEBUG("%s driver open failed\n", pathname);
123 (void)pthread_mutex_unlock(&disk->disk_mutex);
124 goto errout_with_vnode;
125 }
126 }
127 }
128
129 if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR)
130 {
131 PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__);
132 return -1;
133 }
134
135 }
136 else
137 {
138 if (ops->open != NULL)
139 {
140 ret = ops->open(vnode_ptr);
141 if (ret < 0)
142 {
143 PRINT_DEBUG("%s driver open failed\n", pathname);
144 goto errout_with_vnode;
145 }
146 }
147 }
148
149 *ppvnode = vnode_ptr;
150 return OK;
151
152 errout_with_vnode:
153 errout:
154 return ret;
155 }
156