1 /****************************************************************************
2 * fs/driver/fs_openblockdriver.c
3 *
4 * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
5 * Author: Gregory Nutt <gnutt@nuttx.org>
6 *
7 * Redistribution and use in pathname and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of pathname code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name NuttX nor the names of its contributors may be
18 * used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ****************************************************************************/
35
36 /****************************************************************************
37 * Included Files
38 ****************************************************************************/
39
40 #include "vfs_config.h"
41 #include "errno.h"
42 #include "fs/driver.h"
43 #include "vnode.h"
44 #include "disk.h"
45 #include <linux/kernel.h>
46
47 /****************************************************************************
48 * Public Functions
49 ****************************************************************************/
50
51 /****************************************************************************
52 * Name: open_blockdriver
53 *
54 * Description:
55 * Return the vnode of the block driver specified by 'pathname'
56 *
57 * Input Parameters:
58 * pathname - the full path to the block driver to be opened
59 * mountflags - if MS_RDONLY is not set, then driver must support write
60 * operations (see include/sys/mount.h)
61 * ppvnode - address of the location to return the vnode reference
62 *
63 * Returned Value:
64 * Returns zero on success or a negated errno on failure:
65 *
66 * EINVAL - pathname or pvnode is NULL
67 * ENOENT - No block driver of this name is registered
68 * ENOTBLK - The vnode associated with the pathname is not a block driver
69 * EACCESS - The MS_RDONLY option was not set but this driver does not
70 * support write access
71 *
72 ****************************************************************************/
73
74
75 extern int find_blockdriver(const char *pathname, int mountflags, struct Vnode **vpp);
76
open_blockdriver(const char * pathname,int mountflags,struct Vnode ** ppvnode)77 int open_blockdriver(const char *pathname, int mountflags,
78 struct Vnode **ppvnode)
79 {
80 struct Vnode *vnode_ptr = NULL;
81 los_part *part = NULL;
82 los_disk *disk = NULL;
83 int ret;
84
85 /* Minimal sanity checks */
86
87 #ifdef CONFIG_DEBUG
88 if (ppvnode == NULL)
89 {
90 ret = -EINVAL;
91 goto errout;
92 }
93 #endif
94
95 /* Find the vnode associated with this block driver name. find_blockdriver
96 * will perform all additional error checking.
97 */
98
99 ret = find_blockdriver(pathname, mountflags, &vnode_ptr);
100 if (ret < 0)
101 {
102 PRINT_DEBUG("Failed to file %s block driver\n", pathname);
103 goto errout;
104 }
105
106 /* Open the block driver. Note that no mutually exclusive access
107 * to the driver is enforced here. That must be done in the driver
108 * if needed.
109 */
110
111 struct drv_data* drv = (struct drv_data*)vnode_ptr->data;
112 struct block_operations *ops = (struct block_operations *)drv->ops;
113
114 part = los_part_find(vnode_ptr);
115 if (part != NULL)
116 {
117 disk = get_disk(part->disk_id);
118 if (disk == NULL)
119 {
120 ret = -EINVAL;
121 goto errout_with_vnode;
122 }
123
124 if (pthread_mutex_lock(&disk->disk_mutex) != ENOERR)
125 {
126 PRINT_ERR("%s %d, mutex lock fail!\n", __FUNCTION__, __LINE__);
127 return -1;
128 }
129 if (disk->disk_status == STAT_INUSED)
130 {
131
132 if (ops->open != NULL)
133 {
134 ret = ops->open(vnode_ptr);
135 if (ret < 0)
136 {
137 PRINT_DEBUG("%s driver open failed\n", pathname);
138 (void)pthread_mutex_unlock(&disk->disk_mutex);
139 goto errout_with_vnode;
140 }
141 }
142 }
143
144 if (pthread_mutex_unlock(&disk->disk_mutex) != ENOERR)
145 {
146 PRINT_ERR("%s %d, mutex unlock fail!\n", __FUNCTION__, __LINE__);
147 return -1;
148 }
149
150 }
151 else
152 {
153 if (ops->open != NULL)
154 {
155 ret = ops->open(vnode_ptr);
156 if (ret < 0)
157 {
158 PRINT_DEBUG("%s driver open failed\n", pathname);
159 goto errout_with_vnode;
160 }
161 }
162 }
163
164 *ppvnode = vnode_ptr;
165 return OK;
166
167 errout_with_vnode:
168 errout:
169 return ret;
170 }
171