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