3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
23 #include <sys/statvfs.h>
28 #include <tzplatform_config.h>
29 #include <libsyscommon/ini-parser.h>
33 #include "storage-external.h"
35 #define MEMORY_GIGABYTE_VALUE 1073741824
36 #define MEMORY_MEGABYTE_VALUE 1048576
38 #define EXTERNAL_MEMORY_NODE "sdcard"
39 #define STORAGE_CONF_FILE "/etc/storage/libstorage.conf"
42 #define MATCH(a, b) (!strncmp(a, b, strlen(a)))
43 #define SET_CONF(a, b) (a = (b > 0.0 ? b : a))
45 struct storage_config_info {
51 static struct storage_config_info storage_info;
53 static int load_config(struct parse_result *result, void *user_data)
55 static int check_size = -1;
56 struct storage_config_info *info = (struct storage_config_info *)user_data;
63 if (!MATCH(result->section, "STORAGE"))
67 value = result->value;
69 if (info->check_size > 0 && check_size < 0)
70 check_size = (storage_info.total_size < info->check_size) ? 1 : 0;
71 if (MATCH(name, "CHECK_SIZE"))
72 info->check_size = atoi(value);
73 else if (check_size == 0 && MATCH(name, "RESERVE"))
74 info->reserved_size = atoi(value);
75 else if (check_size == 1 && MATCH(name, "RESERVE_LITE"))
76 info->reserved_size = atoi(value);
81 static void storage_config_load(struct storage_config_info *info)
85 ret_val = config_parse(STORAGE_CONF_FILE, load_config, info);
87 _E("Failed to load %s, %d Use default value!", STORAGE_CONF_FILE, ret_val); //LCOV_EXCL_LINE
90 static int get_memory_size(const char *path, struct statvfs_32 *buf)
97 ret_val = statvfs(path, &s);
99 return -errno; //LCOV_EXCL_LINE System Error
101 memset(buf, 0, sizeof(struct statvfs_32));
103 buf->f_bsize = s.f_bsize;
104 buf->f_frsize = s.f_frsize;
105 buf->f_blocks = (unsigned long)s.f_blocks;
106 buf->f_bfree = (unsigned long)s.f_bfree;
107 buf->f_bavail = (unsigned long)s.f_bavail;
108 buf->f_files = (unsigned long)s.f_files;
109 buf->f_ffree = (unsigned long)s.f_ffree;
110 buf->f_favail = (unsigned long)s.f_favail;
111 buf->f_fsid = s.f_fsid;
112 buf->f_flag = s.f_flag;
113 buf->f_namemax = s.f_namemax;
118 /* This api is intended for binaries built with _FILE_OFFSET_BITS=32 */
119 API int storage_get_internal_memory_size(struct statvfs *buf)
121 struct statvfs_32 temp = { 0, };
122 static unsigned long reserved = 0;
126 _E("input param error");
127 return STORAGE_ERROR_INVALID_PARAMETER;
130 ret_val = get_memory_size(tzplatform_getenv(TZ_SYS_USER), &temp);
131 if (ret_val || temp.f_bsize == 0) {
132 _E("fail to get memory size %d", ret_val); //LCOV_EXCL_LINE
133 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
137 storage_info.total_size = (double)temp.f_frsize * temp.f_blocks;
138 storage_config_load(&storage_info);
139 reserved = (unsigned long)storage_info.reserved_size;
140 reserved = reserved/temp.f_bsize;
141 _I("total %4.4lf check %4.4lf reserved %4.4lf",
142 storage_info.total_size, storage_info.check_size, storage_info.reserved_size);
144 if (temp.f_bavail < reserved)
147 temp.f_bavail -= reserved;
149 memcpy(buf, &temp, sizeof(temp));
150 return STORAGE_ERROR_NONE;
153 /* This api is intended for binaries built with __USE_FILE_OFFSET64(_FILE_OFFSET_BITS=64) */
154 API int storage_get_internal_memory_size64(struct statvfs *buf)
156 static unsigned long reserved = 0;
160 _E("input param error");
161 return STORAGE_ERROR_INVALID_PARAMETER;
164 ret_val = statvfs(tzplatform_getenv(TZ_SYS_USER), buf);
166 _E("fail to get memory size"); //LCOV_EXCL_LINE
167 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
171 storage_info.total_size = (double)(buf->f_frsize * buf->f_blocks);
172 storage_config_load(&storage_info);
173 reserved = (unsigned long)storage_info.reserved_size;
174 reserved = reserved/buf->f_bsize;
175 _I("total %4.4lf check %4.4lf reserved %4.4lf",
176 storage_info.total_size, storage_info.check_size, storage_info.reserved_size);
178 if (buf->f_bavail < reserved)
181 buf->f_bavail -= reserved;
182 return STORAGE_ERROR_NONE;
185 int mount_check(const char *path)
189 const char *table = "/etc/mtab";
192 fp = setmntent(table, "r");
195 while ((mnt = getmntent(fp))) {
196 if (!strcmp(mnt->mnt_dir, path)) {
205 static int get_external_path(char *path, size_t len)
207 return storage_ext_get_primary_mmc_path(path, len);
210 /* This api is intended for binaries built with _FILE_OFFSET_BITS=32 */
211 int storage_get_external_memory_size_with_path(char *path, struct statvfs *buf)
213 struct statvfs_32 temp;
217 _D("storage_get_external_memory_size");
219 _E("input param error");
220 return STORAGE_ERROR_INVALID_PARAMETER;
224 snprintf(ext_path, sizeof(ext_path), "%s", path);
226 if (!storage_ext_is_supported()) {
227 _D("Block module is not enabled"); //LCOV_EXCL_LINE
228 return STORAGE_ERROR_NOT_SUPPORTED; //LCOV_EXCL_LINE
230 ret_val = get_external_path(ext_path, sizeof(ext_path));
231 if (ret_val == -ENODEV)
234 _E("Failed to get external path(%d)", ret_val); //LCOV_EXCL_LINE
235 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
239 if (!mount_check((const char *)ext_path))
242 ret_val = storage_ext_get_statvfs(ext_path, &temp);
244 _E("fail to get memory size"); //LCOV_EXCL_LINE
245 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
248 memcpy(buf, &temp, sizeof(temp));
252 memset(buf, 0, sizeof(struct statvfs_32));
253 return STORAGE_ERROR_NONE;
256 /* This api is intended for binaries built with __USE_FILE_OFFSET64(_FILE_OFFSET_BITS=64) */
257 int storage_get_external_memory_size64_with_path(char *path, struct statvfs *buf)
262 _D("storage_get_external_memory_size64");
264 _E("input param error");
265 return STORAGE_ERROR_INVALID_PARAMETER;
269 snprintf(ext_path, sizeof(ext_path), "%s", path);
271 if (!storage_ext_is_supported()) {
272 _D("Block module is not enabled"); //LCOV_EXCL_LINE
273 return STORAGE_ERROR_NOT_SUPPORTED; //LCOV_EXCL_LINE
275 ret_val = get_external_path(ext_path, sizeof(ext_path));
276 if (ret_val == -ENODEV)
279 _E("Failed to get external path(%d)", ret_val); //LCOV_EXCL_LINE
280 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
284 if (!mount_check((const char *)ext_path))
287 ret_val = storage_ext_get_statvfs_size64(ext_path, buf);
289 //LCOV_EXCL_START System Error
290 _E("fail to get memory size");
291 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
295 return STORAGE_ERROR_NONE;
298 memset(buf, 0, sizeof(struct statvfs));
302 API int storage_get_external_memory_size(struct statvfs *buf)
304 return storage_get_external_memory_size_with_path(NULL, buf);
307 API int storage_get_external_memory_size64(struct statvfs *buf)
309 return storage_get_external_memory_size64_with_path(NULL, buf);