• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * fs/vfs/fs_unlink.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 
27 #include "unistd.h"
28 #include "errno.h"
29 #include "fcntl.h"
30 
31 #include "vnode.h"
32 #include "stdlib.h"
33 #include "fs/mount.h"
34 
35 /****************************************************************************
36  * Private Functions
37  ****************************************************************************/
check_target(struct Vnode * vnode)38 static int check_target(struct Vnode *vnode)
39 {
40   if (vnode->type == VNODE_TYPE_DIR)
41     {
42       return -EISDIR;
43     }
44 
45   if ((vnode->originMount) && (vnode->originMount->mountFlags & MS_RDONLY))
46     {
47       return -EROFS;
48     }
49 
50   if (vnode->useCount > 0)
51     {
52       return -EBUSY;
53     }
54 
55   if (VfsVnodePermissionCheck(vnode->parent, (WRITE_OP | EXEC_OP)))
56     {
57       return -EACCES;
58     }
59   return OK;
60 }
61 /****************************************************************************
62  * Public Functions
63  ****************************************************************************/
64 
65 /****************************************************************************
66  * Name: do_unlink
67  *
68  * Description:  Remove a file managed a mountpoint
69  *
70  ****************************************************************************/
71 
do_unlink(int dirfd,const char * pathname)72 int do_unlink(int dirfd, const char *pathname)
73 {
74   struct Vnode *vnode = NULL;
75   int ret;
76   char *name = NULL;
77   char *fullpath = NULL;
78   char *relativepath = NULL;
79 
80   /* Get relative path by dirfd*/
81   ret = get_path_from_fd(dirfd, &relativepath);
82   if (ret < 0)
83     {
84       goto errout;
85     }
86 
87   ret = vfs_normalize_path((const char *)relativepath, pathname, &fullpath);
88   if (relativepath)
89     {
90       free(relativepath);
91     }
92 
93   if (ret < 0)
94     {
95       goto errout;
96     }
97 
98   VnodeHold();
99   ret = VnodeLookup(fullpath, &vnode, 0);
100   if (ret < 0)
101     {
102       goto errout_with_lock;
103     }
104 
105   ret = check_target(vnode);
106   if (ret < 0)
107     {
108       goto errout_with_lock;
109     }
110   name = strrchr(fullpath, '/') + 1;
111 
112   if (vnode && vnode->vop && vnode->vop->Unlink)
113     {
114       ret = vnode->vop->Unlink(vnode->parent, vnode, name);
115     }
116   else if (vnode && vnode->fop && vnode->fop->unlink)
117     {
118       ret = vnode->fop->unlink(vnode);
119       if (ret == OK) {
120         goto done;
121       }
122     }
123   else
124     {
125       ret = -ENOSYS;
126     }
127 
128   if (ret != OK)
129     {
130       goto errout_with_lock;
131     }
132 
133   VnodeFree(vnode);
134 
135 done:
136   VnodeDrop();
137 
138   /* Successfully unlinked */
139 
140   free(fullpath);
141   return OK;
142 
143 errout_with_lock:
144   VnodeDrop();
145 
146 errout:
147   if (fullpath)
148     {
149       free(fullpath);
150     }
151   set_errno(-ret);
152 
153   return VFS_ERROR;
154 }
155 
156 /****************************************************************************
157  * Name: unlink
158  *
159  * Description:  Remove a file managed a mountpoint
160  *
161  ****************************************************************************/
162 
unlink(const char * pathname)163 int unlink(const char *pathname)
164 {
165   return do_unlink(AT_FDCWD, pathname);
166 }
167 
168 /****************************************************************************
169  * Name: unlinkat
170  *
171  * Description:  Remove a file managed a mountpoint by dirfd
172  *
173  ****************************************************************************/
174 extern int do_rmdir(int dirfd, const char *pathname);
175 
unlinkat(int dirfd,const char * pathname,int flag)176 int unlinkat(int dirfd, const char *pathname, int flag)
177 {
178   int ret;
179 
180   if (pathname == NULL)
181     {
182       ret = -EINVAL;
183       goto errout;
184     }
185 
186   /* Now flag only support 0 && AT_REMOVEDIR */
187   if ((flag & ~AT_REMOVEDIR) != 0)
188     {
189       ret = -EINVAL;
190       goto errout;
191     }
192 
193   if (flag & AT_REMOVEDIR)
194     return do_rmdir(dirfd, pathname);
195 
196   return do_unlink(dirfd, pathname);
197 
198 errout:
199   set_errno(-ret);
200   return VFS_ERROR;
201 }
202