• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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