blob: 3af113fe6a613b25a9486af90a01092d1890b9a4 [file] [log] [blame]
The Android Open Source Project8ac3a132009-01-20 14:04:01 -08001
2/*
3 * Copyright (C) 2008 The Android Open Source Project
4 *
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
17
The Android Open Source Project13f797d2009-02-10 15:44:07 -080018#include <fcntl.h>
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080019#include <errno.h>
20
The Android Open Source Project13f797d2009-02-10 15:44:07 -080021#include <sys/types.h>
22#include <sys/stat.h>
23#include <sys/mount.h>
24
25#include <linux/ext2_fs.h>
26#include <linux/ext3_fs.h>
27
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080028#include "vold.h"
29#include "volmgr.h"
30#include "volmgr_ext3.h"
The Android Open Source Project13f797d2009-02-10 15:44:07 -080031#include "logwrapper.h"
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080032
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080033
The Android Open Source Project13f797d2009-02-10 15:44:07 -080034#define EXT_DEBUG 0
35
36static char E2FSCK_PATH[] = "/system/bin/e2fsck";
37
38int ext_identify(blkdev_t *dev)
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080039{
The Android Open Source Project13f797d2009-02-10 15:44:07 -080040 int rc = -1;
41 int fd;
42 struct ext3_super_block sb;
43 char *devpath;
44
45#if EXT_DEBUG
46 LOG_VOL("ext_identify(%d:%d):\n", dev-major, dev->minor);
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080047#endif
The Android Open Source Project13f797d2009-02-10 15:44:07 -080048
49 devpath = blkdev_get_devpath(dev);
50
51 if ((fd = open(devpath, O_RDWR)) < 0) {
52 LOGE("Unable to open device '%s' (%s)\n", devpath,
53 strerror(errno));
54 free(devpath);
55 return -errno;
56 }
57
58 if (lseek(fd, 1024, SEEK_SET) < 0) {
59 LOGE("Unable to lseek to get superblock (%s)\n", strerror(errno));
60 rc = -errno;
61 goto out;
62 }
63
64 if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
65 LOGE("Unable to read superblock (%s)\n", strerror(errno));
66 rc = -errno;
67 goto out;
68 }
69
70 if (sb.s_magic == EXT2_SUPER_MAGIC ||
71 sb.s_magic == EXT3_SUPER_MAGIC)
72 rc = 0;
73 else
74 rc = -ENODATA;
75
76 out:
77#if EXT_DEBUG
78 LOG_VOL("ext_identify(%s): rc = %d\n", devpath, rc);
79#endif
80 free(devpath);
81 close(fd);
82 return rc;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080083}
84
The Android Open Source Project13f797d2009-02-10 15:44:07 -080085int ext_check(blkdev_t *dev)
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080086{
The Android Open Source Project13f797d2009-02-10 15:44:07 -080087 char *devpath;
88
89#if EXT_DEBUG
90 LOG_VOL("ext_check(%s):\n", dev->dev_fspath);
The Android Open Source Project8ac3a132009-01-20 14:04:01 -080091#endif
The Android Open Source Project13f797d2009-02-10 15:44:07 -080092
93 devpath = blkdev_get_devpath(dev);
94
95 if (access(E2FSCK_PATH, X_OK)) {
96 LOGE("ext_check(%s): %s not found (skipping checks)\n",
97 devpath, E2FSCK_PATH);
98 free(devpath);
99 return 0;
100 }
101
102 char *args[5];
103
104 args[0] = E2FSCK_PATH;
105 args[1] = "-v";
106 args[2] = "-p";
107 args[3] = devpath;
108 args[4] = NULL;
109
110 int rc = logwrap(4, args);
111
112 if (rc == 0) {
113 LOG_VOL("filesystem '%s' had no errors\n", devpath);
114 } else if (rc == 1) {
115 LOG_VOL("filesystem '%s' had corrected errors\n", devpath);
116 rc = 0;
117 } else if (rc == 2) {
118 LOGE("VOL volume '%s' had corrected errors (system should be rebooted)\n", devpath);
119 rc = -EIO;
120 } else if (rc == 4) {
121 LOGE("VOL volume '%s' had uncorrectable errors\n", devpath);
122 rc = -EIO;
123 } else if (rc == 8) {
124 LOGE("Operational error while checking volume '%s'\n", devpath);
125 rc = -EIO;
126 } else {
127 LOGE("Unknown e2fsck exit code (%d)\n", rc);
128 rc = -EIO;
129 }
130 free(devpath);
131 return rc;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -0800132}
133
The Android Open Source Project13f797d2009-02-10 15:44:07 -0800134int ext_mount(blkdev_t *dev, volume_t *vol, boolean safe_mode)
The Android Open Source Project8ac3a132009-01-20 14:04:01 -0800135{
The Android Open Source Project13f797d2009-02-10 15:44:07 -0800136#if EXT_DEBUG
137 LOG_VOL("ext_mount(%s, %s, %d):\n", dev->dev_fspath, vol->mount_point, safe_mode);
The Android Open Source Project8ac3a132009-01-20 14:04:01 -0800138#endif
The Android Open Source Project13f797d2009-02-10 15:44:07 -0800139
140 char *fs[] = { "ext3", "ext2", NULL };
141 char *devpath;
142
143 devpath = blkdev_get_devpath(dev);
144
145 int flags, rc = 0;
146
147 flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_NOATIME | MS_NODIRATIME;
148
149 if (safe_mode)
150 flags |= MS_SYNCHRONOUS;
151
152 if (vol->state == volstate_mounted) {
153 LOG_VOL("Remounting %s on %s, safe mode %d\n", devpath,
154 vol->mount_point, safe_mode);
155 flags |= MS_REMOUNT;
156 }
157
158 char **f;
159 for (f = fs; *f != NULL; f++) {
160 rc = mount(devpath, vol->mount_point, *f, flags, NULL);
161 if (rc && errno == EROFS) {
162 LOGE("ext_mount(%s, %s): Read only filesystem - retrying mount RO\n",
163 devpath, vol->mount_point);
164 flags |= MS_RDONLY;
165 rc = mount(devpath, vol->mount_point, *f, flags, NULL);
166 }
167#if EXT_DEBUG
168 LOG_VOL("ext_mount(%s, %s): %s mount rc = %d\n", devpath, *f,
169 vol->mount_point, rc);
170#endif
171 if (!rc)
172 break;
173 }
174 free(devpath);
175
176 // Chmod the mount point so that its a free-for-all.
177 // (required for consistency with VFAT.. sigh)
178 if (chmod(vol->mount_point, 0777) < 0) {
179 LOGE("Failed to chmod %s (%s)\n", vol->mount_point, strerror(errno));
180 return -errno;
181 }
182
183 return rc;
The Android Open Source Project8ac3a132009-01-20 14:04:01 -0800184}