• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * fs/mount/fs_umount.c
3  *
4  *   Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved.
5  *   Author: Gregory Nutt <gnutt@nuttx.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source 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 
42 #include "sys/mount.h"
43 #include "errno.h"
44 #include "vnode.h"
45 #include "stdlib.h"
46 #include "unistd.h"
47 #include "string.h"
48 #include "disk.h"
49 #include "fs/mount.h"
50 
51 /****************************************************************************
52  * Public Functions
53  ****************************************************************************/
54 
55 /****************************************************************************
56  * Name: umount
57  *
58  * Description:
59  *   umount() detaches the filesystem mounted at the path specified by
60  *  'target.'
61  *
62  * Return:
63  *   Zero is returned on success; -1 is returned on an error and errno is
64  *   set appropriately:
65  *
66  *   EACCES A component of a path was not searchable or mounting a read-only
67  *      filesystem was attempted without giving the MS_RDONLY flag.
68  *   EBUSY The target could not be unmounted because it is busy.
69  *   EFAULT The pointer argument points outside the user address space.
70  *
71  ****************************************************************************/
72 
fs_in_use(struct Mount * mnt,const char * target)73 BOOL fs_in_use(struct Mount *mnt, const char *target)
74 {
75   char cwd[PATH_MAX];
76   char *pret = getcwd(cwd, PATH_MAX);
77   if (pret != NULL)
78     {
79       if (!strncmp(target, cwd, strlen(target)))
80         {
81           return TRUE;
82         }
83     }
84     return VnodeInUseIter(mnt);
85 }
86 
umount(const char * target)87 int umount(const char *target)
88 {
89   struct Vnode *mountpt_vnode = NULL;
90   struct Vnode *blkdrvr_vnode = NULL;
91   struct Vnode *covered_vnode = NULL;
92   struct Mount *mnt = NULL;
93   int ret;
94 
95   /* Verify required pointer arguments */
96 
97   if (target == NULL)
98     {
99       ret = -EFAULT;
100       goto errout;
101     }
102 
103   /* Find the mountpt */
104   VnodeHold();
105   ret = VnodeLookup(target, &mountpt_vnode, 0);
106   if (ret != OK || !mountpt_vnode)
107     {
108       goto errout;
109     }
110   /* Verify that the vnode is a mountpoint */
111   if (!mountpt_vnode || !(mountpt_vnode->flag & VNODE_FLAG_MOUNT_NEW))
112     {
113       ret = -EINVAL;
114       goto errout;
115     }
116 
117   /* Get mount point covered vnode and mount structure */
118   mnt = mountpt_vnode->originMount;
119   if (!mnt)
120     {
121       ret = -EINVAL;
122       goto errout;
123     }
124   covered_vnode = mnt->vnodeBeCovered;
125   if (!covered_vnode || !(covered_vnode->flag & VNODE_FLAG_MOUNT_ORIGIN))
126     {
127       ret = -EINVAL;
128       goto errout;
129     }
130 
131   /* Unbind the block driver from the file system (destroying any fs
132    * private data.
133    */
134 
135   if (mnt->ops == NULL || mnt->ops->Unmount == NULL)
136     {
137       /* The filesystem does not support the unbind operation ??? */
138 
139       ret = -EINVAL;
140       goto errout;
141     }
142 
143   /* Release the vnode under the mount point */
144   if (fs_in_use(mnt, target))
145     {
146       ret = -EBUSY;
147       goto errout;
148     }
149 
150   ret = VnodeFreeAll(mnt);
151   if (ret != OK)
152     {
153       goto errout;
154     }
155   /* Umount the filesystem */
156   ret = mnt->ops->Unmount(mnt, &blkdrvr_vnode);
157   if (ret != OK)
158     {
159       goto errout;
160     }
161 
162   VnodeFree(mountpt_vnode);
163   LOS_ListDelete(&mnt->mountList);
164   free(mnt);
165 
166   /* Did the unbind method return a contained block driver */
167   if (blkdrvr_vnode)
168     {
169       ; /* block driver operations after umount */
170     }
171 
172   covered_vnode->newMount = NULL;
173   covered_vnode->flag &= ~(VNODE_FLAG_MOUNT_ORIGIN);
174   VnodeDrop();
175 
176   return OK;
177 
178   /* A lot of goto's!  But they make the error handling much simpler */
179 errout:
180   VnodeDrop();
181   set_errno(-ret);
182   return VFS_ERROR;
183 }
184 
umount2(const char * __target,int __flags)185 int umount2(const char* __target, int __flags)
186 {
187     /* TODO: __flags need to be support */
188     if (__flags) {
189         set_errno(ENOSYS);
190         return VFS_ERROR;
191     }
192     return umount(__target);
193 }
194