X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fstorage-external.c;h=65719d43cecaec0bc54a4eedc4eff7c7f6b50b40;hb=refs%2Ftags%2Faccepted%2Ftizen%2Funified%2F20230831.081041;hp=8fdde8cd24981cfb2545a9950dcf8a7510abe794;hpb=dd4cb30512c937ca15e6899edadb4f5d1b672d0b;p=platform%2Fcore%2Fsystem%2Flibstorage.git diff --git a/src/storage-external.c b/src/storage-external.c index 8fdde8c..65719d4 100755 --- a/src/storage-external.c +++ b/src/storage-external.c @@ -22,13 +22,19 @@ #include #include #include +#include #include "common.h" -#include "list.h" #include "log.h" #include "storage-external-dbus.h" -static dd_list *cb_list[STORAGE_CALLBACK_MAX]; +#define EXTERNAL_STORAGE_PATH "/run/storaged/external-storage" +#define EXTENDED_INTERNAL_PATH "/run/storaged/extended-internal-sd" +#define PATH_LEN 55 + +#define LUKS_NAME "crypto_LUKS" + +static GList *cb_list[STORAGE_CALLBACK_MAX]; static int storage_ext_get_dev_state(storage_ext_device *dev, enum storage_ext_state blk_state, @@ -38,6 +44,9 @@ static int storage_ext_get_dev_state(storage_ext_device *dev, return -EINVAL; switch (blk_state) { + case STORAGE_EXT_ADDED: + *state = STORAGE_STATE_UNMOUNTABLE; + return 0; case STORAGE_EXT_REMOVED: *state = STORAGE_STATE_REMOVED; return 0; @@ -55,37 +64,103 @@ static int storage_ext_get_dev_state(storage_ext_device *dev, default: return -EINVAL; } + case STORAGE_EXT_BLOCKED: + *state = STORAGE_STATE_UNMOUNTABLE; + return 0; default: return -EINVAL; } } -int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data) +int storage_ext_get_space(int storage_id, + unsigned long long *total, unsigned long long *available) { + storage_state_e state; + struct statvfs s; int ret; + unsigned long long t = 0, a = 0; + storage_ext_device *dev; + + if (storage_id < 0) + return -ENODEV; + + dev = calloc(1, sizeof(storage_ext_device)); + if (!dev) { +//LCOV_EXCL_START System Error + _E("calloc failed"); + return -ENOMEM; +//LCOV_EXCL_STOP + } + + ret = storage_ext_get_device_info(storage_id, dev); + if (ret < 0) { + _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE + goto out; //LCOV_EXCL_LINE + } + + ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state); + if (ret < 0) { + _E("Failed to get state of storage (id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE + goto out; //LCOV_EXCL_LINE + } + + if (state >= STORAGE_STATE_MOUNTED) { +#ifdef __USE_FILE_OFFSET64 + ret = storage_get_external_memory_size64_with_path(dev->mount_point, &s); +#else + ret = storage_get_external_memory_size_with_path(dev->mount_point, &s); +#endif + if (ret < 0) { + _E("Failed to get external memory size of (%s)(ret:%d)", dev->mount_point, ret); //LCOV_EXCL_LINE + goto out; //LCOV_EXCL_LINE + } + + t = (unsigned long long)s.f_frsize*s.f_blocks; + a = (unsigned long long)s.f_bsize*s.f_bavail; + } + + if (total) + *total = t; + if (available) + *available = a; + + ret = 0; +out: + storage_ext_release_device(&dev); + return ret; +} + +int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data) +{ + int ret_val; bool ret_cb; - dd_list *list = NULL, *elem; + GList *list = NULL, *elem; storage_ext_device *dev; storage_state_e state; if (!callback) return -EINVAL; - ret = storage_ext_get_list(&list); - if (ret < 0) { - _E("Failed to get external storage list from deviced (%d)", errno); - return ret; + ret_val = storage_ext_get_list(&list); + if (ret_val < 0) { + _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE + return ret_val; //LCOV_EXCL_LINE } - DD_LIST_FOREACH(list, elem, dev) { - ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state); - if (ret < 0) { - _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret); - continue; + SYS_G_LIST_FOREACH(list, elem, dev) { + ret_val = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state); + if (ret_val < 0) { + _E("Failed to get storage state (devnode:%s, ret_val:%d)", dev->devnode, ret_val); //LCOV_EXCL_LINE + continue; //LCOV_EXCL_LINE } - ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL, - state, dev->mount_point, user_data); + if (dev->type == STORAGE_EXT_MMC_EXTENDED_INTERNAL) + ret_cb = callback(dev->storage_id, + STORAGE_TYPE_EXTENDED_INTERNAL, + state, dev->mount_point, user_data); + else + ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL, + state, dev->mount_point, user_data); if (!ret_cb) break; } @@ -95,18 +170,19 @@ int storage_ext_foreach_device_list(storage_device_supported_cb callback, void * return 0; } -static int storage_ext_state_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data) +//LCOV_EXCL_START Not called Callback +static int storage_ext_id_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data) { enum storage_cb_type type = (enum storage_cb_type)data; struct storage_cb_info *cb_info; - dd_list *elem; + GList *elem; storage_state_e state; int ret; if (!dev) return -EINVAL; - if (type != STORAGE_CALLBACK_STATE) + if (type != STORAGE_CALLBACK_ID) return 0; ret = storage_ext_get_dev_state(dev, blk_state, &state); @@ -115,46 +191,145 @@ static int storage_ext_state_changed(storage_ext_device *dev, enum storage_ext_s return ret; } - DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_STATE], elem, cb_info) + SYS_G_LIST_FOREACH(cb_list[STORAGE_CALLBACK_ID], elem, cb_info) cb_info->state_cb(cb_info->id, state, cb_info->user_data); return 0; } -int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *info) +static int storage_ext_type_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data) { + enum storage_cb_type type = (enum storage_cb_type)data; struct storage_cb_info *cb_info; - dd_list *elem; - int ret, n; + GList *elem; + storage_state_e state; + int ret_val; + storage_dev_e strdev; + storage_type_e storage_type; + const char *fstype, *fsuuid, *mountpath; - if (type < 0 || type >= STORAGE_CALLBACK_MAX) + if (!dev) + return -EINVAL; + + if (type != STORAGE_CALLBACK_TYPE) return -EINVAL; + ret_val = storage_ext_get_dev_state(dev, blk_state, &state); + if (ret_val < 0) { + _E("Failed to get storage state (devnode:%s, ret_val:%d)", dev->devnode, ret_val); + return ret_val; + } + + if (dev->type == STORAGE_EXT_SCSI) { + strdev = STORAGE_DEV_EXT_USB_MASS_STORAGE; + storage_type = STORAGE_TYPE_EXTERNAL; + } else if (dev->type == STORAGE_EXT_MMC) { + strdev = STORAGE_DEV_EXT_SDCARD; + storage_type = STORAGE_TYPE_EXTERNAL; + } else if (dev->type == STORAGE_EXT_MMC_EXTENDED_INTERNAL) { + strdev = STORAGE_DEV_EXTENDED_INTERNAL; + storage_type = STORAGE_TYPE_EXTENDED_INTERNAL; + } else { + _E("Invalid dev type (%d)", dev->type); + return -EINVAL; + } + + fstype = (dev->fs_type ? (const char *)dev->fs_type : ""); + fsuuid = (dev->fs_uuid ? (const char *)dev->fs_uuid : ""); + mountpath = (dev->mount_point ? (const char *)dev->mount_point : ""); + + if (!strncmp(fstype, LUKS_NAME, strlen(LUKS_NAME))) + storage_type = STORAGE_TYPE_EXTENDED_INTERNAL; + + SYS_G_LIST_FOREACH(cb_list[STORAGE_CALLBACK_TYPE], elem, cb_info) { + if (cb_info->type != storage_type) + continue; + if (cb_info->type_cb) + cb_info->type_cb(dev->storage_id, strdev, state, + fstype, fsuuid, mountpath, dev->primary, + dev->flags, cb_info->user_data); + } + + return 0; +} + +//LCOV_EXCL_STOP + +static bool check_if_callback_exist(enum storage_cb_type type, + struct storage_cb_info *info, struct storage_cb_info **cb_data) +{ + struct storage_cb_info *cb_info; + GList *elem; + + if (!info) + return false; + + if (type == STORAGE_CALLBACK_ID) { + SYS_G_LIST_FOREACH(cb_list[type], elem, cb_info) { + if (cb_info->id == info->id && + cb_info->state_cb == info->state_cb) { + goto out; + } + } + } + + if (type == STORAGE_CALLBACK_TYPE) { + SYS_G_LIST_FOREACH(cb_list[type], elem, cb_info) { + if (cb_info->type == info->type && + cb_info->type_cb == info->type_cb) + goto out; + } + } + + return false; + +out: + if (cb_data) + *cb_data = cb_info; + + return true; +} + +int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *info) +{ + struct storage_cb_info *cb_info; + int n, ret_val; + storage_ext_changed_cb callback; + if (!info) return -EINVAL; - /* check if it is the first request */ - n = DD_LIST_LENGTH(cb_list[type]); + switch (type) { + case STORAGE_CALLBACK_ID: + callback = storage_ext_id_changed; + break; + case STORAGE_CALLBACK_TYPE: + callback = storage_ext_type_changed; + break; + default: + _E("Invalid callback type (%d)", type); + return -EINVAL; + } + + n = SYS_G_LIST_LENGTH(cb_list[type]); if (n == 0) { - ret = storage_ext_register_device_change(storage_ext_state_changed, (void *)type); - if (ret < 0) + ret_val = storage_ext_register_device_change(callback, (void *)type); + if (ret_val < 0) return -EPERM; } - /* check for the same request */ - DD_LIST_FOREACH(cb_list[type], elem, cb_info) { - if (cb_info->id == info->id && - cb_info->state_cb == info->state_cb) - return -EEXIST; + if (check_if_callback_exist(type, info, NULL)) { + _E("The callback is already registered"); + return 0; } /* add device changed callback to list (local) */ cb_info = malloc(sizeof(struct storage_cb_info)); if (!cb_info) - return -errno; + return -errno; //LCOV_EXCL_LINE memcpy(cb_info, info, sizeof(struct storage_cb_info)); - DD_LIST_APPEND(cb_list[type], cb_info); + SYS_G_LIST_APPEND(cb_list[type], cb_info); return 0; } @@ -162,62 +337,136 @@ int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *i int storage_ext_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info) { struct storage_cb_info *cb_info; - dd_list *elem; int n; - - if (type < 0 || type >= STORAGE_CALLBACK_MAX) - return -EINVAL; + storage_ext_changed_cb callback; if (!info) return -EINVAL; - /* search for the same element with callback */ - DD_LIST_FOREACH(cb_list[type], elem, cb_info) { - if (cb_info->id == info->id && - cb_info->state_cb == info->state_cb) - break; + switch (type) { + case STORAGE_CALLBACK_ID: + callback = storage_ext_id_changed; + break; + case STORAGE_CALLBACK_TYPE: + callback = storage_ext_type_changed; + break; + default: + _E("Invalid callback type (%d)", type); + return -EINVAL; } - if (!cb_info) - return -EINVAL; + if (!check_if_callback_exist(type, info, &cb_info)) { + //LCOV_EXCL_START Callbacked is not registered case + _E("The callback is not registered"); + return 0; + //LCOV_EXCL_STOP + } /* remove device callback from list (local) */ - DD_LIST_REMOVE(cb_list[type], cb_info); - free(cb_info); + if (cb_info) { + SYS_G_LIST_REMOVE(cb_list[type], cb_info); + free(cb_info); + } /* check if this callback is last element */ - n = DD_LIST_LENGTH(cb_list[type]); + n = SYS_G_LIST_LENGTH(cb_list[type]); if (n == 0) - storage_ext_unregister_device_change(storage_ext_state_changed); + storage_ext_unregister_device_change(callback); return 0; } -int storage_ext_get_root(int storage_id, char *path, size_t len) +int storage_ext_get_root(int storage_id, char *path, size_t len, bool *extendedinternal) { + FILE *fp; storage_ext_device *dev; - int ret; + char file_name[PATH_LEN]; + char file_name2[PATH_LEN]; + char *tmp; + int ret = 0; + + if (storage_id < 0) + return -ENODEV; - if (storage_id < 0 || !path) + if (!path) + return -EINVAL; + if (!extendedinternal) return -EINVAL; - dev = calloc(1, sizeof(storage_ext_device)); - if (!dev) { - _E("calloc failed"); - return -ENOMEM; - } + snprintf(file_name, PATH_LEN, EXTERNAL_STORAGE_PATH"/%d", storage_id); + snprintf(file_name2, PATH_LEN, EXTENDED_INTERNAL_PATH"/%d", storage_id); - ret = storage_ext_get_device_info(storage_id, dev); - if (ret < 0) { - _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); - goto out; + *extendedinternal = false; + + if (access(file_name, R_OK) == 0) { + fp = fopen(file_name, "r"); + if (!fp) { + //LCOV_EXCL_START File operation error + _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); + ret = -ENODEV; + goto out; + //LCOV_EXCL_STOP + } + + tmp = fgets(path, len, fp); + fclose(fp); + if (!tmp) { + //LCOV_EXCL_START File operation error + ret = -ENODEV; + _D("Failed to get path"); + goto out; + //LCOV_EXCL_STOP + } + *extendedinternal = false; + } else if (access(file_name2, R_OK) == 0) { + fp = fopen(file_name2, "r"); + if (!fp) { + //LCOV_EXCL_START File operation error + _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); + ret = -ENODEV; + goto out; + //LCOV_EXCL_STOP + } + + tmp = fgets(path, len, fp); + fclose(fp); + if (!tmp) { + //LCOV_EXCL_START File operation error + ret = -ENODEV; + _D("Failed to get path"); + goto out; + //LCOV_EXCL_STOP + } + *extendedinternal = true; + } else { + dev = calloc(1, sizeof(storage_ext_device)); + if (!dev) { +//LCOV_EXCL_START System Error + _E("calloc failed"); + return -ENOMEM; +//LCOV_EXCL_STOP + } + + ret = storage_ext_get_device_info(storage_id, dev); + if (ret < 0) { + //LCOV_EXCL_START + _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); + storage_ext_release_device(&dev); + goto out; + //LCOV_EXCL_STOP + } + + snprintf(path, len, "%s", dev->mount_point); + if (dev->type == STORAGE_EXT_MMC_EXTENDED_INTERNAL) + *extendedinternal = true; + else + *extendedinternal = false; + storage_ext_release_device(&dev); } - snprintf(path, len, "%s", dev->mount_point); ret = 0; out: - storage_ext_release_device(&dev); return ret; } @@ -226,26 +475,63 @@ int storage_ext_get_state(int storage_id, storage_state_e *state) storage_ext_device *dev; int ret; - if (storage_id < 0 || !state) + if (storage_id < 0) + return -ENODEV; + + if (!state) return -EINVAL; dev = calloc(1, sizeof(storage_ext_device)); if (!dev) { +//LCOV_EXCL_START System Error _E("calloc failed"); return -ENOMEM; +//LCOV_EXCL_STOP } ret = storage_ext_get_device_info(storage_id, dev); if (ret < 0) { + //LCOV_EXCL_START _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); goto out; + //LCOV_EXCL_STOP } ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, state); if (ret < 0) - _E("Failed to get state of storage id (%d, ret:%d)", storage_id, ret); + _E("Failed to get state of storage id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE out: storage_ext_release_device(&dev); return ret; } + +int storage_ext_get_primary_mmc_path(char *path, size_t len) +{ + GList *list = NULL, *elem; + storage_ext_device *dev; + int ret; + + ret = storage_ext_get_list(&list); + if (ret < 0) { + //LCOV_EXCL_START + _E("Failed to get external storage list from deviced (%d)", errno); + return ret; + //LCOV_EXCL_STOP + } + + SYS_G_LIST_FOREACH(list, elem, dev) { + if (dev->primary) { + snprintf(path, len, "%s", dev->mount_point); + ret = 0; + goto out; + } + } + + ret = -ENODEV; + +out: + if (list) + storage_ext_release_list(&list); + return ret; +}