#define BLOCK_CONF_FILE "/etc/storaged/block.conf"
#define EXTERNAL_STORAGE_PATH "/run/external-storage"
+#define EXTENDED_INTERNAL_PATH "/run/extended-internal-sd"
#define PATH_LEN 55
+#define EXTENDED_SD_PATH "/opt/media/extendedsd"
+#define EXTENDED_SD_STRING "ExtendedInternalSD"
+
/* Minimum value of block id */
#define BLOCK_ID_MIN 10
/* For 2.4 Backward Compatibility */
static struct block_conf {
bool multimount;
-} block_conf[BLOCK_MMC_DEV + 1];
+ bool extendedinternal;
+} block_conf[BLOCK_MMC_EXTENDED_INTERNAL_DEV + 1];
static struct manage_thread {
dd_list *th_node_list; /* List of devnode which thread dealt with. Only main thread access */
DD_LIST_FOREACH(block_ops_list, elem, ops) {
if (ops->block_type != data->block_type)
continue;
+ // TODO What happend on extended internal storage case?
if (op == BLOCK_DEV_MOUNT)
ops->mounted(data, result);
else if (op == BLOCK_DEV_UNMOUNT)
return -ENOENT;
}
-static void remove_file(int id)
+static void remove_file(int id, bool extendedsd)
{
char file_name[PATH_LEN];
int ret;
if (id < 0)
return;
- snprintf(file_name, sizeof(file_name), EXTERNAL_STORAGE_PATH"/%d", id);
+ if (extendedsd)
+ snprintf(file_name, PATH_LEN, EXTENDED_INTERNAL_PATH"/%d", id);
+ else
+ snprintf(file_name, sizeof(file_name), EXTERNAL_STORAGE_PATH"/%d", id);
ret = remove(file_name);
if (ret < 0)
_E("Fail to remove %s. errno: %d", file_name, errno);
}
-static void create_file(int id, char *mount_point)
+static void create_file(int id, char *mount_point, bool extendedsd)
{
FILE *fp;
char file_name[PATH_LEN];
if (id < 0)
return;
- snprintf(file_name, PATH_LEN, EXTERNAL_STORAGE_PATH"/%d", id);
+ if (extendedsd)
+ snprintf(file_name, PATH_LEN, EXTENDED_INTERNAL_PATH"/%d", id);
+ else
+ snprintf(file_name, PATH_LEN, EXTERNAL_STORAGE_PATH"/%d", id);
fp = fopen(file_name, "w+");
if (fp) {
case BLOCK_SCSI_DEV:
ret = get_scsi_mount_node(name, node, sizeof(node));
break;
+ case BLOCK_MMC_EXTENDED_INTERNAL_DEV:
+ return strdup(EXTENDED_SD_PATH);
default:
_E("Invalid block type (%d)", data->block_type);
return NULL;
if (thread_id < 0 || thread_id >= THREAD_MAX)
return;
- /* Remove file for block device /run/external-storage/id */
- remove_file(bdev->data->id);
+ /* Remove file for block device /run/xxxxxx/id */
+ if (bdev->data->block_type == BLOCK_MMC_EXTENDED_INTERNAL_DEV)
+ remove_file(bdev->data->id, true);
+ else
+ remove_file(bdev->data->id, false);
pthread_mutex_lock(&(th_manager[thread_id].mutex));
if (pdata.bdev->data->state == BLOCK_UNMOUNT) {
ret = change_mount_point(pdata.bdev, "");
/* Modify /run/external-storage/id file */
- if (ret == 0)
- create_file(pdata.bdev->data->id, pdata.bdev->data->mount_point);
+ if (ret == 0) {
+ if (pdata.bdev->data->block_type == BLOCK_MMC_EXTENDED_INTERNAL_DEV)
+ create_file(pdata.bdev->data->id, pdata.bdev->data->mount_point, true);
+ else
+ create_file(pdata.bdev->data->id, pdata.bdev->data->mount_point, false);
+ }
}
goto out;
}
pdata.bdev->data->block_type == BLOCK_MMC_DEV &&
pdata.bdev->data->primary)
create_external_apps_directory();
+ if (pdata.op == BLOCK_DEV_UNMOUNT) {
+ if (pdata.bdev->data->block_type == BLOCK_MMC_EXTENDED_INTERNAL_DEV)
+ remove_file(pdata.bdev->data->id, true);
+ else
+ remove_file(pdata.bdev->data->id, false);
+ }
/* Broadcast to mmc and usb storage module */
broadcast_block_info(pdata.op, pdata.bdev->data, pdata.result);
case 0:
/* Mobile specific:
* should unmount the below vconf key. */
- if (data->block_type == BLOCK_MMC_DEV && data->primary) {
+ if ((data->block_type == BLOCK_MMC_DEV ||
+ data->block_type == BLOCK_MMC_EXTENDED_INTERNAL_DEV) &&
+ data->primary) {
/* At first, notify to other app
* who already access sdcard */
_I("Notify to other app who already access sdcard");
th_manager[thread_id].num_dev++;
DD_LIST_APPEND(th_manager[thread_id].block_dev_list, bdev);
- /* Create file for block device /run/external-storage/id */
- create_file(bdev->data->id, bdev->data->mount_point);
-
pthread_mutex_unlock(&(th_manager[thread_id].mutex));
ret = add_operation(bdev, BLOCK_DEV_INSERT, NULL, (void *)data);
return ret;
}
+// TODO Check this sdcard is already formatted for extended internal sdcard
+ if (block_conf[bdev->data->block_type].extendedinternal &&
+ bdev->data->block_type == BLOCK_MMC_DEV &&
+ bdev->data->primary) {
+ _I("Check whether sdcard will be used as extended internal storage");
+ return 0;
+ }
+
ret = add_operation(bdev, BLOCK_DEV_MOUNT, NULL, NULL);
if (ret < 0) {
_E("Failed to add operation (mount %s)", devnode);
return ret;
}
-
return 0;
}
continue;
_D("%s:", data->devnode);
_D("\tSyspath: %s", data->syspath);
- _D("\tBlock type: %s",
- (data->block_type == BLOCK_MMC_DEV ?
- BLOCK_TYPE_MMC : BLOCK_TYPE_SCSI));
+ _D("\tBlock type: %d", data->block_type);
_D("\tFs type: %s", data->fs_type);
_D("\tFs usage: %s", data->fs_usage);
_D("\tFs version: %s", data->fs_version);
}
/* if requester want to use a specific mount point */
- if (mount_point && strncmp(mount_point, "", 1) != 0) {
+ if (mount_point &&
+ !strncmp(mount_point, EXTENDED_SD_STRING, strlen(EXTENDED_SD_STRING) + 1) != 0) {
+ if (!block_conf[bdev->data->block_type].extendedinternal ||
+ !bdev->data->primary) {
+ _E("Not support extended internal storage");
+ ret = -EPERM;
+ goto out;
+ } else {
+ bdev->data->block_type = BLOCK_MMC_EXTENDED_INTERNAL_DEV;
+ ret = change_mount_point(bdev, EXTENDED_SD_PATH);
+ if (ret < 0) {
+ ret = -EPERM;
+ goto out;
+ }
+
+ create_file(bdev->data->id, bdev->data->mount_point, true);
+ }
+ } else if (mount_point && strncmp(mount_point, "", 1) != 0) {
ret = change_mount_point(bdev, mount_point);
if (ret < 0) {
ret = -EPERM;
goto out;
}
- /* Modify /run/external-storage/id file */
- create_file(bdev->data->id, bdev->data->mount_point);
+ /* Create /run/external-storage/id file */
+ create_file(bdev->data->id, bdev->data->mount_point, false);
+ } else {
+ /* Create file for block device /run/external-storage/id */
+ create_file(bdev->data->id, bdev->data->mount_point, false);
}
ret = add_operation(bdev, BLOCK_DEV_MOUNT, reply_handle, NULL);
ret = -ENOENT;
goto out;
}
+ if (bdev->data->block_type == BLOCK_MMC_EXTENDED_INTERNAL_DEV) {
+ _I("Impossible to request unmount extended internal sdcard");
+ ret = -EPERM;
+ goto out;
+ }
if (onprivate) {
pid = get_dbus_method_sender_pid(reply_handle);
if (MATCH(result->name, "Multimount"))
block_conf[index].multimount =
(MATCH(result->value, "yes") ? true : false);
+ if (MATCH(result->name, "ExtendedInternalStorage"))
+ block_conf[index].extendedinternal =
+ (MATCH(result->value, "yes") ? true : false);
+
+ if (index == BLOCK_MMC_DEV) {
+ block_conf[index + 1].multimount = block_conf[index].multimount;
+ block_conf[index + 1].extendedinternal = block_conf[index].extendedinternal;
+ }
return 0;
}
if (ret < 0)
_E("Fail to change permissions of a file");
}
+
+ ret = stat(EXTENDED_INTERNAL_PATH, &buf);
+ if (ret < 0) {
+ ret = mkdir(EXTENDED_INTERNAL_PATH, 0755);
+ if (ret < 0)
+ _E("Failed to make directory: %d", errno);
+ } else if (!S_ISDIR(buf.st_mode)) {
+ ret = remove(EXTENDED_INTERNAL_PATH);
+ if (ret < 0)
+ _E("Fail to remove %s. errno: %d", EXTENDED_INTERNAL_PATH, errno);
+ ret = mkdir(EXTENDED_INTERNAL_PATH, 0755);
+ if (ret < 0)
+ _E("Failed to make directory: %d", errno);
+ } else {
+ ret = chmod(EXTENDED_INTERNAL_PATH, 644);
+ if (ret < 0)
+ _E("Fail to change permissions of a file");
+ }
}
static void block_exit(void *data)