1 /****************************************************************************
2 * fs/vfs/fs_statfs.c
3 *
4 * Copyright (C) 2007-2009, 2012, 2017 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/statfs.h"
43 #include "string.h"
44 #include "sched.h"
45 #include "vnode.h"
46 #include "fs/mount.h"
47 #include "errno.h"
48 #include "stdlib.h"
49
50 /****************************************************************************
51 * Public Functions
52 ****************************************************************************/
53
54 /****************************************************************************
55 * Name: statfs
56 *
57 * Returned Value:
58 * Zero on success; -1 on failure with errno set:
59 *
60 * EACCES Search permission is denied for one of the directories in the
61 * path prefix of path.
62 * EFAULT Bad address.
63 * ENOENT A component of the path path does not exist, or the path is an
64 * empty string.
65 * ENOMEM Out of memory
66 * ENOTDIR A component of the path is not a directory.
67 * ENOSYS The file system does not support this call.
68 *
69 ****************************************************************************/
70
statfs(const char * path,struct statfs * buf)71 int statfs(const char *path, struct statfs *buf)
72 {
73 struct Vnode *vnode = NULL;
74 struct Mount *mnt = NULL;
75 int ret = OK;
76
77 /* Sanity checks */
78 if (!path || !buf)
79 {
80 ret = -EFAULT;
81 goto errout;
82 }
83 if (!path[0])
84 {
85 ret = -ENOENT;
86 goto errout;
87 }
88 /* Get an vnode for this file */
89 VnodeHold();
90 ret = VnodeLookup(path, &vnode, 0);
91 if (ret < 0)
92 {
93 VnodeDrop();
94 goto errout;
95 }
96 vnode->useCount++;
97 VnodeDrop();
98
99 mnt = vnode->originMount;
100 if (mnt == NULL || mnt->ops == NULL || mnt->ops->Statfs == NULL)
101 {
102 ret = -ENOSYS;
103 goto errout_with_useCount;
104 }
105 else
106 {
107 ret = mnt->ops->Statfs(mnt, buf);
108 if (ret < 0)
109 {
110 goto errout_with_useCount;
111 }
112 }
113
114 VnodeHold();
115 vnode->useCount--;
116 VnodeDrop();
117
118 return OK;
119
120 /* Failure conditions always set the errno appropriately */
121
122 errout_with_useCount:
123 VnodeHold();
124 vnode->useCount--;
125 VnodeDrop();
126 errout:
127 set_errno(-ret);
128 return VFS_ERROR;
129 }
130