Home | History | Annotate | Download | only in fs_mgr
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdio.h>
     18 #include <unistd.h>
     19 #include <sys/types.h>
     20 #include <sys/stat.h>
     21 #include <fcntl.h>
     22 #include <sys/wait.h>
     23 #include <errno.h>
     24 #include <cutils/partition_utils.h>
     25 #include <sys/mount.h>
     26 #include "ext4_utils.h"
     27 #include "ext4.h"
     28 #include "make_ext4fs.h"
     29 #include "fs_mgr_priv.h"
     30 
     31 extern struct fs_info info;     /* magic global from ext4_utils */
     32 extern void reset_ext4fs_info();
     33 
     34 static int format_ext4(char *fs_blkdev, char *fs_mnt_point)
     35 {
     36     unsigned int nr_sec;
     37     int fd, rc = 0;
     38 
     39     if ((fd = open(fs_blkdev, O_WRONLY, 0644)) < 0) {
     40         ERROR("Cannot open block device.  %s\n", strerror(errno));
     41         return -1;
     42     }
     43 
     44     if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
     45         ERROR("Cannot get block device size.  %s\n", strerror(errno));
     46         close(fd);
     47         return -1;
     48     }
     49 
     50     /* Format the partition using the calculated length */
     51     reset_ext4fs_info();
     52     info.len = ((off64_t)nr_sec * 512);
     53 
     54     /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
     55     rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
     56     if (rc) {
     57         ERROR("make_ext4fs returned %d.\n", rc);
     58     }
     59     close(fd);
     60 
     61     return rc;
     62 }
     63 
     64 static int format_f2fs(char *fs_blkdev)
     65 {
     66     char * args[3];
     67     int pid;
     68     int rc = 0;
     69 
     70     args[0] = (char *)"/sbin/mkfs.f2fs";
     71     args[1] = fs_blkdev;
     72     args[2] = (char *)0;
     73 
     74     pid = fork();
     75     if (pid < 0) {
     76        return pid;
     77     }
     78     if (!pid) {
     79         /* This doesn't return */
     80         execv("/sbin/mkfs.f2fs", args);
     81         exit(1);
     82     }
     83     for(;;) {
     84         pid_t p = waitpid(pid, &rc, 0);
     85         if (p != pid) {
     86             ERROR("Error waiting for child process - %d\n", p);
     87             rc = -1;
     88             break;
     89         }
     90         if (WIFEXITED(rc)) {
     91             rc = WEXITSTATUS(rc);
     92             INFO("%s done, status %d\n", args[0], rc);
     93             if (rc) {
     94                 rc = -1;
     95             }
     96             break;
     97         }
     98         ERROR("Still waiting for %s...\n", args[0]);
     99     }
    100 
    101     return rc;
    102 }
    103 
    104 int fs_mgr_do_format(struct fstab_rec *fstab)
    105 {
    106     int rc = -EINVAL;
    107 
    108     ERROR("%s: Format %s as '%s'.\n", __func__, fstab->blk_device, fstab->fs_type);
    109 
    110     if (!strncmp(fstab->fs_type, "f2fs", 4)) {
    111         rc = format_f2fs(fstab->blk_device);
    112     } else if (!strncmp(fstab->fs_type, "ext4", 4)) {
    113         rc = format_ext4(fstab->blk_device, fstab->mount_point);
    114     } else {
    115         ERROR("File system type '%s' is not supported\n", fstab->fs_type);
    116     }
    117 
    118     return rc;
    119 }
    120