2010-01-04 19:09:16 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
2018-09-18 22:30:21 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
Add time_offset=<UTC offset> to mount arguments
Add time_offset=<UTC offset> to mount arguments for the vfat driver.
This is not being release flagged as it's a fix for a regression but is
a cosmetic fix that shouldn't affect anything besides reported file
timestamps.
Changes for issue 246256335 in Android U stopped Android syncing the
current time zone UTC offset to the kernel because doing so is
discouraged. It is discouraged because the current offset alone is not
very useful - it tells the kernel nothing of DST or historic UTC
offsets. Converting to and from local times are are best left to
userspace where time zone rules information is available, and different
users can use different time zones.
However, because FAT32 is poorly designed WRT timestamps, the kernel
FAT32 driver, vfat, does use the kernel offset when available and when
it isn't given a fixed offset to use at volume mount time. This means
that Android devices after the change from issue 246256335 displayed
more obviously incorrect times.
This change adds the argument necessary to vold when mounting a FAT32
volume to set a fixed UTC offset to adjust FAT32 local times
to a UTC-like time ("UTC time" from now on). Userspace then uses the UTC
offset for that UTC time, calculated using TZDB rules, to convert back
to a local time. This is still prone to generating some incorrect times,
e.g. due to DST or other historic offset changes, or a user time zone
change on device after mounting the volume. FAT32 lacks the information
about "what was the UTC offset at file time X?" (unlike exFAT) AND the
vfat driver has no way to look up the time zone rules itself. This
change is a reasonable "better than nothing" change to address times
being obviously wrong after the change from issue 246256335, especially
when a user copies a file from a desktop computer to USB / sd card
storage and immediately plugs the device into an Android device. It does
this without reverting to kernel UTC offset syncing, which is flawed
(i.e. it would never work completely), discouraged, and more effort/code
to improve, e.g. because userspace would have to schedule alarms for
offset changes.
Testing:
1) Obtain a USB FAT32 formatted USB storage device that can be plugged into
a pixel device, e.g. with an OTG USB adapter.
2) On a desktop computer, mount the device and write some files / note
times associated with existing files. These times will already be
adjusted by this OS to be "local time" based on its own logic, but if
it's working correctly that time will be exactly the local time value
stored in the FAT32 volume itself.
3) On a rooted Android device where you can use adb via Wifi (adb tcpip
/ adb connect), leaving the USB port free for external USB devices....
a) $ adb root
b) Insert the USB storage
c) $ mount | grep 'fat'
d) For the USB storage drive, observe the time_offset argument (or
tz=UTC when time_offset == 0) reported (this would not be reported
without this patch)
e) ls -l /mnt/<mount location from (3c)>
f) Confirm the local time displayed is as expected. e.g. the time
should be the same as shown in (2), regardless of the device's time
zone.
4) To observe the "fixed offset behavior" at mount time, alter the time
zone setting on the device via Settings -> System -> Date & Time
a) Repeat 3c-3e.
b) The times shown will have changed by the difference between
the original and new time zone chosen.
c) Extract / re-insert the USB storage device.
d) Repeat 3c-3e
e) The times shown should match the times from (2) again
5) Confirm the write behavior:
a) $ touch /mnt/<mount location from (3c)>/foobar
b) $ ls -l /mnt/<mount location from (3c)>
c) The time should match the device's displayed local time (status
bar)
d) Unmount the USB device and insert the USB device into a desktop computer
e) Confirm the timestamp matches the Android device's local time when
(5a) took place, e.g. using "ls -lT" on MacOS.
Testing was done with numerous zones with positive, negative and zero offsets.
Interesting zones like India (UTC+5:30), Kiribati (UTC+14), Wake Island
(UTC-11), the various fixed offset zones like Etc/GMT+12, Etc/GMT-14
were tried.
Note: Depending on the time zones being used on devices (Android and
desktop) and when the files were written / testing took place during the
year, you may see file times shifting by 1 hour from the "ls -l" step
depending on whether they were written in summer or winter time. This
is because the userspace code for rendering times knows about DST but
the kernel driver is applying a fixed offset and does not. This is
expected and illustrates the points at the top of this comment about
FAT32 integration never being perfect.
See https://www.google.com/search?q=fat32+dst for other examples.
Bug: 319417938
Bug: 315058275
Bug: 246256335
Test: See above
Change-Id: Ic7ce159d88db5d5cf5894bcc26ea60bd7c44917d
2024-01-09 13:45:42 +01:00
|
|
|
#include <time.h>
|
2018-09-18 22:30:21 +02:00
|
|
|
#include <unistd.h>
|
2010-01-04 19:09:16 +01:00
|
|
|
|
2018-09-18 22:30:21 +02:00
|
|
|
#include <linux/fs.h>
|
|
|
|
#include <sys/ioctl.h>
|
2010-01-04 19:09:16 +01:00
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/mount.h>
|
2018-09-18 22:30:21 +02:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2013-01-16 21:29:28 +01:00
|
|
|
#include <sys/wait.h>
|
2010-01-04 19:09:16 +01:00
|
|
|
|
|
|
|
#include <linux/kdev_t.h>
|
|
|
|
|
2015-12-05 00:50:53 +01:00
|
|
|
#include <android-base/logging.h>
|
|
|
|
#include <android-base/stringprintf.h>
|
2015-04-01 20:54:32 +02:00
|
|
|
#include <selinux/selinux.h>
|
2010-01-04 19:09:16 +01:00
|
|
|
|
2013-01-16 21:29:28 +01:00
|
|
|
#include <logwrap/logwrap.h>
|
|
|
|
|
2015-04-01 20:54:32 +02:00
|
|
|
#include "Utils.h"
|
2018-09-18 22:30:21 +02:00
|
|
|
#include "Vfat.h"
|
2012-12-21 21:41:43 +01:00
|
|
|
#include "VoldUtil.h"
|
2010-01-04 19:09:16 +01:00
|
|
|
|
2015-04-09 06:07:21 +02:00
|
|
|
using android::base::StringPrintf;
|
|
|
|
|
2015-05-22 07:35:42 +02:00
|
|
|
namespace android {
|
|
|
|
namespace vold {
|
|
|
|
namespace vfat {
|
|
|
|
|
2015-04-09 06:07:21 +02:00
|
|
|
static const char* kMkfsPath = "/system/bin/newfs_msdos";
|
|
|
|
static const char* kFsckPath = "/system/bin/fsck_msdos";
|
2010-01-04 19:09:16 +01:00
|
|
|
|
2015-05-22 07:35:42 +02:00
|
|
|
bool IsSupported() {
|
2018-09-18 22:30:21 +02:00
|
|
|
return access(kMkfsPath, X_OK) == 0 && access(kFsckPath, X_OK) == 0 &&
|
|
|
|
IsFilesystemSupported("vfat");
|
2015-05-22 07:35:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
status_t Check(const std::string& source) {
|
2010-01-04 19:09:16 +01:00
|
|
|
int pass = 1;
|
|
|
|
int rc = 0;
|
|
|
|
do {
|
2015-04-09 06:07:21 +02:00
|
|
|
std::vector<std::string> cmd;
|
|
|
|
cmd.push_back(kFsckPath);
|
|
|
|
cmd.push_back("-p");
|
|
|
|
cmd.push_back("-f");
|
2019-06-06 20:33:51 +02:00
|
|
|
cmd.push_back("-y");
|
2015-05-22 07:35:42 +02:00
|
|
|
cmd.push_back(source);
|
2010-01-04 19:09:16 +01:00
|
|
|
|
2015-04-01 20:54:32 +02:00
|
|
|
// Fat devices are currently always untrusted
|
2021-09-15 02:32:06 +02:00
|
|
|
rc = ForkExecvpTimeout(cmd, kUntrustedFsckSleepTime, sFsckUntrustedContext);
|
2015-04-09 06:07:21 +02:00
|
|
|
if (rc < 0) {
|
2021-09-15 02:32:06 +02:00
|
|
|
LOG(ERROR) << "Filesystem check failed due to fork error";
|
2013-01-16 21:29:28 +01:00
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-09-18 22:30:21 +02:00
|
|
|
switch (rc) {
|
|
|
|
case 0:
|
|
|
|
LOG(INFO) << "Filesystem check completed OK";
|
|
|
|
return 0;
|
|
|
|
|
2021-09-15 02:32:06 +02:00
|
|
|
case 1:
|
|
|
|
LOG(INFO) << "Failed to check filesystem";
|
|
|
|
return -1;
|
|
|
|
|
2018-09-18 22:30:21 +02:00
|
|
|
case 2:
|
|
|
|
LOG(ERROR) << "Filesystem check failed (not a FAT filesystem)";
|
|
|
|
errno = ENODATA;
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
if (pass++ <= 3) {
|
|
|
|
LOG(WARNING) << "Filesystem modified - rechecking (pass " << pass << ")";
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
LOG(ERROR) << "Failing check after too many rechecks";
|
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
LOG(ERROR) << "Filesystem check failed (no filesystem)";
|
|
|
|
errno = ENODATA;
|
|
|
|
return -1;
|
|
|
|
|
2021-09-15 02:32:06 +02:00
|
|
|
case ETIMEDOUT:
|
|
|
|
LOG(ERROR) << "Filesystem check timed out";
|
|
|
|
errno = ETIMEDOUT;
|
|
|
|
return -1;
|
|
|
|
|
2018-09-18 22:30:21 +02:00
|
|
|
default:
|
|
|
|
LOG(ERROR) << "Filesystem check failed (unknown exit code " << rc << ")";
|
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
2010-01-04 19:09:16 +01:00
|
|
|
}
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Add time_offset=<UTC offset> to mount arguments
Add time_offset=<UTC offset> to mount arguments for the vfat driver.
This is not being release flagged as it's a fix for a regression but is
a cosmetic fix that shouldn't affect anything besides reported file
timestamps.
Changes for issue 246256335 in Android U stopped Android syncing the
current time zone UTC offset to the kernel because doing so is
discouraged. It is discouraged because the current offset alone is not
very useful - it tells the kernel nothing of DST or historic UTC
offsets. Converting to and from local times are are best left to
userspace where time zone rules information is available, and different
users can use different time zones.
However, because FAT32 is poorly designed WRT timestamps, the kernel
FAT32 driver, vfat, does use the kernel offset when available and when
it isn't given a fixed offset to use at volume mount time. This means
that Android devices after the change from issue 246256335 displayed
more obviously incorrect times.
This change adds the argument necessary to vold when mounting a FAT32
volume to set a fixed UTC offset to adjust FAT32 local times
to a UTC-like time ("UTC time" from now on). Userspace then uses the UTC
offset for that UTC time, calculated using TZDB rules, to convert back
to a local time. This is still prone to generating some incorrect times,
e.g. due to DST or other historic offset changes, or a user time zone
change on device after mounting the volume. FAT32 lacks the information
about "what was the UTC offset at file time X?" (unlike exFAT) AND the
vfat driver has no way to look up the time zone rules itself. This
change is a reasonable "better than nothing" change to address times
being obviously wrong after the change from issue 246256335, especially
when a user copies a file from a desktop computer to USB / sd card
storage and immediately plugs the device into an Android device. It does
this without reverting to kernel UTC offset syncing, which is flawed
(i.e. it would never work completely), discouraged, and more effort/code
to improve, e.g. because userspace would have to schedule alarms for
offset changes.
Testing:
1) Obtain a USB FAT32 formatted USB storage device that can be plugged into
a pixel device, e.g. with an OTG USB adapter.
2) On a desktop computer, mount the device and write some files / note
times associated with existing files. These times will already be
adjusted by this OS to be "local time" based on its own logic, but if
it's working correctly that time will be exactly the local time value
stored in the FAT32 volume itself.
3) On a rooted Android device where you can use adb via Wifi (adb tcpip
/ adb connect), leaving the USB port free for external USB devices....
a) $ adb root
b) Insert the USB storage
c) $ mount | grep 'fat'
d) For the USB storage drive, observe the time_offset argument (or
tz=UTC when time_offset == 0) reported (this would not be reported
without this patch)
e) ls -l /mnt/<mount location from (3c)>
f) Confirm the local time displayed is as expected. e.g. the time
should be the same as shown in (2), regardless of the device's time
zone.
4) To observe the "fixed offset behavior" at mount time, alter the time
zone setting on the device via Settings -> System -> Date & Time
a) Repeat 3c-3e.
b) The times shown will have changed by the difference between
the original and new time zone chosen.
c) Extract / re-insert the USB storage device.
d) Repeat 3c-3e
e) The times shown should match the times from (2) again
5) Confirm the write behavior:
a) $ touch /mnt/<mount location from (3c)>/foobar
b) $ ls -l /mnt/<mount location from (3c)>
c) The time should match the device's displayed local time (status
bar)
d) Unmount the USB device and insert the USB device into a desktop computer
e) Confirm the timestamp matches the Android device's local time when
(5a) took place, e.g. using "ls -lT" on MacOS.
Testing was done with numerous zones with positive, negative and zero offsets.
Interesting zones like India (UTC+5:30), Kiribati (UTC+14), Wake Island
(UTC-11), the various fixed offset zones like Etc/GMT+12, Etc/GMT-14
were tried.
Note: Depending on the time zones being used on devices (Android and
desktop) and when the files were written / testing took place during the
year, you may see file times shifting by 1 hour from the "ls -l" step
depending on whether they were written in summer or winter time. This
is because the userspace code for rendering times knows about DST but
the kernel driver is applying a fixed offset and does not. This is
expected and illustrates the points at the top of this comment about
FAT32 integration never being perfect.
See https://www.google.com/search?q=fat32+dst for other examples.
Bug: 319417938
Bug: 315058275
Bug: 246256335
Test: See above
Change-Id: Ic7ce159d88db5d5cf5894bcc26ea60bd7c44917d
2024-01-09 13:45:42 +01:00
|
|
|
int16_t currentUtcOffsetMinutes() {
|
|
|
|
time_t now = time(NULL);
|
|
|
|
|
|
|
|
struct tm nowTm;
|
|
|
|
localtime_r(&now, &nowTm);
|
|
|
|
|
|
|
|
int32_t utcOffsetSeconds = nowTm.tm_gmtoff;
|
|
|
|
return (int16_t)(utcOffsetSeconds / 60);
|
|
|
|
}
|
|
|
|
|
2018-09-18 22:30:21 +02:00
|
|
|
status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount,
|
|
|
|
bool executable, int ownerUid, int ownerGid, int permMask, bool createLost) {
|
2010-01-04 19:09:16 +01:00
|
|
|
int rc;
|
|
|
|
unsigned long flags;
|
|
|
|
|
2015-05-22 07:35:42 +02:00
|
|
|
const char* c_source = source.c_str();
|
|
|
|
const char* c_target = target.c_str();
|
|
|
|
|
2017-07-03 04:25:33 +02:00
|
|
|
flags = MS_NODEV | MS_NOSUID | MS_DIRSYNC | MS_NOATIME;
|
2010-01-04 19:09:16 +01:00
|
|
|
|
2010-08-27 17:31:35 +02:00
|
|
|
flags |= (executable ? 0 : MS_NOEXEC);
|
2010-01-06 19:33:53 +01:00
|
|
|
flags |= (ro ? MS_RDONLY : 0);
|
|
|
|
flags |= (remount ? MS_REMOUNT : 0);
|
|
|
|
|
2018-09-18 22:30:21 +02:00
|
|
|
auto mountData =
|
|
|
|
android::base::StringPrintf("utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed",
|
|
|
|
ownerUid, ownerGid, permMask, permMask);
|
2010-01-07 04:19:46 +01:00
|
|
|
|
Add time_offset=<UTC offset> to mount arguments
Add time_offset=<UTC offset> to mount arguments for the vfat driver.
This is not being release flagged as it's a fix for a regression but is
a cosmetic fix that shouldn't affect anything besides reported file
timestamps.
Changes for issue 246256335 in Android U stopped Android syncing the
current time zone UTC offset to the kernel because doing so is
discouraged. It is discouraged because the current offset alone is not
very useful - it tells the kernel nothing of DST or historic UTC
offsets. Converting to and from local times are are best left to
userspace where time zone rules information is available, and different
users can use different time zones.
However, because FAT32 is poorly designed WRT timestamps, the kernel
FAT32 driver, vfat, does use the kernel offset when available and when
it isn't given a fixed offset to use at volume mount time. This means
that Android devices after the change from issue 246256335 displayed
more obviously incorrect times.
This change adds the argument necessary to vold when mounting a FAT32
volume to set a fixed UTC offset to adjust FAT32 local times
to a UTC-like time ("UTC time" from now on). Userspace then uses the UTC
offset for that UTC time, calculated using TZDB rules, to convert back
to a local time. This is still prone to generating some incorrect times,
e.g. due to DST or other historic offset changes, or a user time zone
change on device after mounting the volume. FAT32 lacks the information
about "what was the UTC offset at file time X?" (unlike exFAT) AND the
vfat driver has no way to look up the time zone rules itself. This
change is a reasonable "better than nothing" change to address times
being obviously wrong after the change from issue 246256335, especially
when a user copies a file from a desktop computer to USB / sd card
storage and immediately plugs the device into an Android device. It does
this without reverting to kernel UTC offset syncing, which is flawed
(i.e. it would never work completely), discouraged, and more effort/code
to improve, e.g. because userspace would have to schedule alarms for
offset changes.
Testing:
1) Obtain a USB FAT32 formatted USB storage device that can be plugged into
a pixel device, e.g. with an OTG USB adapter.
2) On a desktop computer, mount the device and write some files / note
times associated with existing files. These times will already be
adjusted by this OS to be "local time" based on its own logic, but if
it's working correctly that time will be exactly the local time value
stored in the FAT32 volume itself.
3) On a rooted Android device where you can use adb via Wifi (adb tcpip
/ adb connect), leaving the USB port free for external USB devices....
a) $ adb root
b) Insert the USB storage
c) $ mount | grep 'fat'
d) For the USB storage drive, observe the time_offset argument (or
tz=UTC when time_offset == 0) reported (this would not be reported
without this patch)
e) ls -l /mnt/<mount location from (3c)>
f) Confirm the local time displayed is as expected. e.g. the time
should be the same as shown in (2), regardless of the device's time
zone.
4) To observe the "fixed offset behavior" at mount time, alter the time
zone setting on the device via Settings -> System -> Date & Time
a) Repeat 3c-3e.
b) The times shown will have changed by the difference between
the original and new time zone chosen.
c) Extract / re-insert the USB storage device.
d) Repeat 3c-3e
e) The times shown should match the times from (2) again
5) Confirm the write behavior:
a) $ touch /mnt/<mount location from (3c)>/foobar
b) $ ls -l /mnt/<mount location from (3c)>
c) The time should match the device's displayed local time (status
bar)
d) Unmount the USB device and insert the USB device into a desktop computer
e) Confirm the timestamp matches the Android device's local time when
(5a) took place, e.g. using "ls -lT" on MacOS.
Testing was done with numerous zones with positive, negative and zero offsets.
Interesting zones like India (UTC+5:30), Kiribati (UTC+14), Wake Island
(UTC-11), the various fixed offset zones like Etc/GMT+12, Etc/GMT-14
were tried.
Note: Depending on the time zones being used on devices (Android and
desktop) and when the files were written / testing took place during the
year, you may see file times shifting by 1 hour from the "ls -l" step
depending on whether they were written in summer or winter time. This
is because the userspace code for rendering times knows about DST but
the kernel driver is applying a fixed offset and does not. This is
expected and illustrates the points at the top of this comment about
FAT32 integration never being perfect.
See https://www.google.com/search?q=fat32+dst for other examples.
Bug: 319417938
Bug: 315058275
Bug: 246256335
Test: See above
Change-Id: Ic7ce159d88db5d5cf5894bcc26ea60bd7c44917d
2024-01-09 13:45:42 +01:00
|
|
|
// b/315058275: Set this to false if you don't want to use a fixed offset
|
|
|
|
// determined at mount time. When this is false, the vfat driver will fall
|
|
|
|
// back to using sys_tz, which Android does not set by default, then assume
|
|
|
|
// local time == UTC.
|
|
|
|
if (true) {
|
|
|
|
// Calculate the offset to use to adjust FAT timestamps to convert them
|
|
|
|
// from "local time" into unix epoch time. This assumes the current UTC
|
|
|
|
// offset of this device is the same as the device that wrote them. User
|
|
|
|
// space code, e.g. ls -l, will then apply the UTC offset for the UTC
|
|
|
|
// time to convert times from unix epoch time to local time for display.
|
|
|
|
// Before Android U (b/246256335), Android platform code informed the
|
|
|
|
// Linux kernel about the UTC offset under some circumstances, but not
|
|
|
|
// for all, e.g. DST changes. The kernel vfat driver is one of the few
|
|
|
|
// things in the kernel that tries to use kernel UTC offset information.
|
|
|
|
// Setting time zone offset in the Linux kernel is discouraged and so
|
|
|
|
// Android no longer informs the kernel. Instead, the offset for vfat
|
|
|
|
// to use is now set at volume mount time. This means that if the time
|
|
|
|
// zone offset changes while the device is mounted, or if files were
|
|
|
|
// written in opposing daylight saving time, then incorrect file times
|
|
|
|
// will be displayed until the volume is remounted. Even then, the vfat
|
|
|
|
// driver has to assume a fixed offset to apply to all files, so files
|
|
|
|
// written at different times of the year can have incorrect times
|
|
|
|
// calculated, e.g. offset incorrectly by one hour.
|
|
|
|
int16_t timeOffsetArg = currentUtcOffsetMinutes();
|
|
|
|
mountData += android::base::StringPrintf(",time_offset=%d", timeOffsetArg);
|
|
|
|
}
|
|
|
|
|
2017-10-07 02:02:53 +02:00
|
|
|
rc = mount(c_source, c_target, "vfat", flags, mountData.c_str());
|
2010-01-07 04:19:46 +01:00
|
|
|
|
2010-01-04 19:09:16 +01:00
|
|
|
if (rc && errno == EROFS) {
|
2017-10-07 02:02:53 +02:00
|
|
|
LOG(ERROR) << source << " appears to be a read only filesystem - retrying mount RO";
|
2010-01-04 19:09:16 +01:00
|
|
|
flags |= MS_RDONLY;
|
2017-10-07 02:02:53 +02:00
|
|
|
rc = mount(c_source, c_target, "vfat", flags, mountData.c_str());
|
2010-01-04 19:09:16 +01:00
|
|
|
}
|
|
|
|
|
2010-01-07 04:19:46 +01:00
|
|
|
if (rc == 0 && createLost) {
|
2017-10-07 02:02:53 +02:00
|
|
|
auto lost_path = android::base::StringPrintf("%s/LOST.DIR", target.c_str());
|
|
|
|
if (access(lost_path.c_str(), F_OK)) {
|
2010-01-04 19:09:16 +01:00
|
|
|
/*
|
|
|
|
* Create a LOST.DIR in the root so we have somewhere to put
|
|
|
|
* lost cluster chains (fsck_msdos doesn't currently do this)
|
|
|
|
*/
|
2017-10-07 02:02:53 +02:00
|
|
|
if (mkdir(lost_path.c_str(), 0755)) {
|
|
|
|
PLOG(ERROR) << "Unable to create LOST.DIR";
|
2010-01-04 19:09:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2015-08-03 18:06:39 +02:00
|
|
|
status_t Format(const std::string& source, unsigned long numSectors) {
|
2015-04-09 06:07:21 +02:00
|
|
|
std::vector<std::string> cmd;
|
|
|
|
cmd.push_back(kMkfsPath);
|
|
|
|
cmd.push_back("-O");
|
|
|
|
cmd.push_back("android");
|
|
|
|
cmd.push_back("-A");
|
2010-03-03 21:37:32 +01:00
|
|
|
|
|
|
|
if (numSectors) {
|
2015-04-09 06:07:21 +02:00
|
|
|
cmd.push_back("-s");
|
2015-08-03 18:06:39 +02:00
|
|
|
cmd.push_back(StringPrintf("%lu", numSectors));
|
2010-03-03 21:37:32 +01:00
|
|
|
}
|
2010-01-04 19:09:16 +01:00
|
|
|
|
2015-05-22 07:35:42 +02:00
|
|
|
cmd.push_back(source);
|
2013-01-16 21:29:28 +01:00
|
|
|
|
2015-05-22 07:35:42 +02:00
|
|
|
int rc = ForkExecvp(cmd);
|
2015-04-09 06:07:21 +02:00
|
|
|
if (rc < 0) {
|
2017-10-07 02:02:53 +02:00
|
|
|
LOG(ERROR) << "Filesystem format failed due to logwrap error";
|
2013-01-16 21:29:28 +01:00
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-04-09 06:07:21 +02:00
|
|
|
if (rc == 0) {
|
2017-10-07 02:02:53 +02:00
|
|
|
LOG(INFO) << "Filesystem formatted OK";
|
2010-01-04 19:09:16 +01:00
|
|
|
return 0;
|
|
|
|
} else {
|
2017-10-07 02:02:53 +02:00
|
|
|
LOG(ERROR) << "Format failed (unknown exit code " << rc << ")";
|
2010-01-04 19:09:16 +01:00
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2013-06-12 04:10:20 +02:00
|
|
|
|
2015-05-22 07:35:42 +02:00
|
|
|
} // namespace vfat
|
|
|
|
} // namespace vold
|
|
|
|
} // namespace android
|