Add FormatFirstPrimary dbus method resf/for/tizen
authorHyotaek Shim <hyotaek.shim@samsung.com>
Fri, 15 Oct 2021 10:45:48 +0000 (19:45 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Fri, 15 Oct 2021 11:48:48 +0000 (20:48 +0900)
Change-Id: I5e2e21d3798821f7176b83966246b5c65667d0c8
Signed-off-by: Hyotaek Shim <hyotaek.shim@samsung.com>
src/block/block.c

index 6c0568d431de6efd40bbc8fca6be35b5cdae0895..1531114b74196e17e370b88247b1685e4659b785 100644 (file)
@@ -901,6 +901,30 @@ static struct block_device *find_block_device_by_id(int id)
        return NULL;
 }
 
+static struct block_device *find_first_primary_block()
+{
+       struct block_device *bdev;
+       GList *elem;
+       int i;
+
+       for (i = 0; i < THREAD_MAX; i++) {
+               pthread_mutex_lock(&(th_manager[i].mutex));
+               SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
+                       if (!bdev->data)
+                               continue;
+                       if (bdev->removed)
+                               continue;
+                       if (bdev->data->primary) {
+                               pthread_mutex_unlock(&(th_manager[i].mutex));
+                               return bdev;
+                       }
+               }
+               pthread_mutex_unlock(&(th_manager[i].mutex));
+       }
+
+       return NULL;
+}
+
 static const char *get_operation_char(enum block_dev_operation op)
 {
        switch (op) {
@@ -3155,7 +3179,7 @@ static GVariant *request_format_block(GDBusConnection *conn,
 
        if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV ||
            !strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
-               _D("Format dbus request for extended internal storage is blocked.");
+               _D("Format request for extended internal storage is not allowed.");
                ret = -EPERM;
                goto out;
        }
@@ -3236,7 +3260,7 @@ static GVariant *request_format_block_type(GDBusConnection *conn,
 
        /* FormatwithType dbus call is needed when app proceeds extended internal -> portable storage */
        if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV) {
-               _D("FormatwithType dbus request for extended internal storage is blocked.");
+               _D("FormatwithType request for extended internal storage is not allowed.");
                ret = -EPERM;
                goto out;
        }
@@ -3290,6 +3314,91 @@ out:
        return g_variant_new("(i)", ret);
 }
 
+static GVariant *request_format_first_primary_block(GDBusConnection *conn,
+               const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+               GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       struct block_device *bdev;
+       struct format_data *fdata;
+       pid_t pid;
+       int option;
+       int ret = -EBADMSG;
+       int prev_state;
+
+       if (!block_control) {
+               _D("Block module is disabled.");
+               ret = -EPERM;
+               goto out;
+       }
+
+       g_variant_get(param, "(i)", &option);
+
+       bdev = find_first_primary_block();
+       _E("FORMAT=%d", bdev->data->id);
+       if (!bdev) {
+               _E("Failed to find the first primary block in the device list.");
+               goto out;
+       }
+
+       if (strncmp(bdev->data->fs_type, VFAT_NAME, strlen(VFAT_NAME))) {
+               _D("Format request for non-VFAT first primary storage is not allowed.");
+               goto out;
+       }
+
+       if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV ||
+           !strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
+               _D("Format request for extended internal storage is not allowed.");
+               ret = -EPERM;
+               goto out;
+       }
+
+       pid = gdbus_connection_get_sender_pid(NULL, sender);
+       if (bdev->on_private_op != REQ_NORMAL && pid != bdev->private_pid) {
+               _E("Failed to format on private state.");
+               ret = -EPERM;
+               goto out;
+       }
+
+       fdata = get_format_data(NULL, option);
+       if (!fdata) {
+               _E("Failed to get format data.");
+               goto out;
+       }
+
+       prev_state = bdev->data->state;
+       if (prev_state == BLOCK_MOUNT) {
+               if (bdev->on_private_op == REQ_PRIVATE) {
+                       bdev->on_private_op = REQ_PRIVATE_FORMAT;
+                       _D("Private operation state(%d)", bdev->on_private_op);
+               }
+               ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE);
+               if (ret < 0) {
+                       _E("Failed to add operation(unmount, %s).", bdev->data->devnode);
+                       release_format_data(fdata);
+                       goto out;
+               }
+       }
+
+       ret = add_operation(bdev, BLOCK_DEV_FORMAT, invocation, (void *)fdata);
+       if (ret < 0) {
+               _E("Failed to add operation(format, %s).", bdev->data->devnode);
+               release_format_data(fdata);
+       }
+
+       /* Maintain previous state of mount/unmount */
+       if (prev_state == BLOCK_MOUNT) {
+               if (add_operation(bdev, BLOCK_DEV_MOUNT, NULL, NULL) < 0) {
+                       _E("Failed to add operation(mount, %s).", bdev->data->devnode);
+                       goto out;
+               }
+       }
+
+       return NULL;
+
+out:
+       return g_variant_new("(i)", ret);
+}
+
 static GVariant *block_data_to_gvariant(struct block_data *data, int flags)
 {
        if (!data)
@@ -3715,43 +3824,6 @@ static GVariant *request_getcontrol_block(GDBusConnection *conn,
        return g_variant_new("(i)", result);
 }
 
-/*
-  Method name      Method call format string  Reply format string
-{ "ShowDeviceList",                      NULL,               NULL, request_show_device_list },
-{ "GetDeviceList",                        "s", "a(issssssisibii)", request_get_device_list },
-{ "GetDeviceList2",                       "s",  "a(issssssisibi)", request_get_device_list_2 },
-{ "Mount",                               "is",                "i", request_public_mount_block },
-{ "Unmoun,                               "ii",                "i", request_public_unmount_block },
-{ "Format",                              "ii",                "i", request_format_block },
-{ "GetDeviceInfo",                        "i",  "(issssssisibii)", request_get_device_info },
-{ "GetMmcPrimary",                       NULL, "(issssssisibii)" , request_get_mmc_primary },
-{ "PrivateMount",                        "is",                "i", request_private_mount_block },
-{ "PrivateUnmount",                      "ii",                "i", request_private_unmount_block },
-*/
-
-static const dbus_method_s manager_methods[] = {
-       { "ShowDeviceList",   NULL,                 NULL, request_show_device_list },
-       { "GetDeviceList" ,    "s",   "a(issssssisibii)", request_get_device_list },
-       { "GetDeviceList2",    "s",    "a(issssssisibi)", request_get_device_list_2 },
-       { "Mount",            "is",                  "i", request_public_mount_block },
-       { "Unmount",          "ii",                  "i", request_public_unmount_block },
-       { "Format",           "ii",                  "i", request_format_block },
-       { "FormatwithType",  "iis",                  "i", request_format_block_type },
-       { "GetDeviceInfo",     "i",      "issssssisibii", request_get_device_info },
-       { "GetMmcPrimary",    NULL,      "issssssisibii", request_get_mmc_primary },
-       { "PrivateMount",     "is",                  "i", request_private_mount_block },
-       { "PrivateUnmount",   "ii",                  "i", request_private_unmount_block },
-       { "CheckSpeed",        "i",                  "i", request_check_speed },
-       { "Control",           "i",                  "i", request_control_block },
-       { "GetControl",       NULL,                  "i", request_getcontrol_block },
-};
-
-static const dbus_interface_u block_interface = {
-       .name = STORAGED_INTERFACE_BLOCK_MANAGER,
-       .methods = manager_methods,
-       .nr_methods = ARRAY_SIZE(manager_methods),
-};
-
 static int load_config(struct parse_result *result, void *user_data)
 {
        int index;
@@ -3807,6 +3879,44 @@ static int mount_root_path_tmpfs(void)
 #define mount_root_path_tmpfs() 0
 #endif
 
+/*
+  Method name      Method call format string  Reply format string
+{ "ShowDeviceList",                      NULL,               NULL, request_show_device_list },
+{ "GetDeviceList",                        "s", "a(issssssisibii)", request_get_device_list },
+{ "GetDeviceList2",                       "s",  "a(issssssisibi)", request_get_device_list_2 },
+{ "Mount",                               "is",                "i", request_public_mount_block },
+{ "Unmoun,                               "ii",                "i", request_public_unmount_block },
+{ "Format",                              "ii",                "i", request_format_block },
+{ "GetDeviceInfo",                        "i",  "(issssssisibii)", request_get_device_info },
+{ "GetMmcPrimary",                       NULL, "(issssssisibii)" , request_get_mmc_primary },
+{ "PrivateMount",                        "is",                "i", request_private_mount_block },
+{ "PrivateUnmount",                      "ii",                "i", request_private_unmount_block },
+*/
+
+static const dbus_method_s manager_methods[] = {
+       { "ShowDeviceList",     NULL,                 NULL, request_show_device_list },
+       { "GetDeviceList" ,      "s",   "a(issssssisibii)", request_get_device_list },
+       { "GetDeviceList2",      "s",    "a(issssssisibi)", request_get_device_list_2 },
+       { "Mount",              "is",                  "i", request_public_mount_block },
+       { "Unmount",            "ii",                  "i", request_public_unmount_block },
+       { "Format",             "ii",                  "i", request_format_block },
+       { "FormatwithType",    "iis",                  "i", request_format_block_type },
+       { "FormatFirstPrimary",  "i",                  "i", request_format_first_primary_block },
+       { "GetDeviceInfo",       "i",      "issssssisibii", request_get_device_info },
+       { "GetMmcPrimary",      NULL,      "issssssisibii", request_get_mmc_primary },
+       { "PrivateMount",       "is",                  "i", request_private_mount_block },
+       { "PrivateUnmount",     "ii",                  "i", request_private_unmount_block },
+       { "CheckSpeed",          "i",                  "i", request_check_speed },
+       { "Control",             "i",                  "i", request_control_block },
+       { "GetControl",         NULL,                  "i", request_getcontrol_block },
+};
+
+static const dbus_interface_u block_interface = {
+       .name = STORAGED_INTERFACE_BLOCK_MANAGER,
+       .methods = manager_methods,
+       .nr_methods = ARRAY_SIZE(manager_methods),
+};
+
 static guint id_block_poweroff;
 
 static void block_init(void *data)
@@ -3869,6 +3979,7 @@ static void block_init(void *data)
 
        booting_done();
 }
+
 static void terminate_threads(void)
 {
        GList *elem, *elem_next;