Advertisement
Guest User

Patch for ext4 support in AOSP vold, ported from Cyanogenmod

a guest
Dec 22nd, 2013
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 12.78 KB | None | 0 0
  1. diff -ru .system.old/vold.old/DirectVolume.cpp system/vold/DirectVolume.cpp
  2. --- .system.old/vold.old/DirectVolume.cpp   2013-12-21 13:36:04.000000000 +0100
  3. +++ system/vold/DirectVolume.cpp    2013-12-22 01:21:55.321891444 +0100
  4. @@ -31,7 +31,7 @@
  5.  #include "ResponseCode.h"
  6.  #include "cryptfs.h"
  7.  
  8. -// #define PARTITION_DEBUG
  9. +#define PARTITION_DEBUG
  10.  
  11.  DirectVolume::DirectVolume(VolumeManager *vm, const char *label,
  12.                             const char *mount_point, int partIdx) :
  13. diff -ru .system.old/vold.old/Ext4.cpp system/vold/Ext4.cpp
  14. --- .system.old/vold.old/Ext4.cpp   2013-12-21 13:36:04.000000000 +0100
  15. +++ system/vold/Ext4.cpp    2013-12-21 21:47:15.058638366 +0100
  16. @@ -40,7 +40,8 @@
  17.  
  18.  #include "Ext4.h"
  19.  
  20. -#define MKEXT4FS_PATH "/system/bin/make_ext4fs";
  21. +static char E2FSCK_PATH[] = "/system/bin/e2fsck";
  22. +static char MKEXT4FS_PATH[] = "/system/bin/make_ext4fs";
  23.  
  24.  extern "C" int logwrap(int argc, const char **argv, int background);
  25.  
  26. @@ -67,6 +68,50 @@
  27.      return rc;
  28.  }
  29.  
  30. +int Ext4::check(const char *fsPath) {
  31. +    bool rw = true;
  32. +    if (access(E2FSCK_PATH, X_OK)) {
  33. +        SLOGW("Skipping fs checks.\n");
  34. +        return 0;
  35. +    }
  36. +
  37. +    int rc = -1;
  38. +    do {
  39. +        const char *args[5];
  40. +        args[0] = E2FSCK_PATH;
  41. +        args[1] = "-p";
  42. +        args[2] = "-f";
  43. +        args[3] = fsPath;
  44. +        args[4] = NULL;
  45. +
  46. +        rc = logwrap(4, args, 1);
  47. +
  48. +        switch(rc) {
  49. +        case 0:
  50. +            SLOGI("EXT4 Filesystem check completed OK.\n");
  51. +            return 0;
  52. +        case 1:
  53. +            SLOGI("EXT4 Filesystem check completed, errors corrected OK.\n");
  54. +            return 0;
  55. +        case 2:
  56. +            SLOGE("EXT4 Filesystem check completed, errors corrected, need reboot.\n");
  57. +            return 0;
  58. +        case 4:
  59. +            SLOGE("EXT4 Filesystem errors left uncorrected.\n");
  60. +            return 0;
  61. +        case 8:
  62. +            SLOGE("E2FSCK Operational error.\n");
  63. +            errno = EIO;
  64. +            return -1;
  65. +        default:
  66. +            SLOGE("EXT4 Filesystem check failed (unknown exit code %d).\n", rc);
  67. +            errno = EIO;
  68. +            return -1;
  69. +        }
  70. +    } while (0);
  71. +    return 0;
  72. +}
  73. +
  74.  int Ext4::format(const char *fsPath) {
  75.      int fd;
  76.      const char *args[4];
  77. diff -ru .system.old/vold.old/Ext4.h system/vold/Ext4.h
  78. --- .system.old/vold.old/Ext4.h 2013-12-21 13:36:04.000000000 +0100
  79. +++ system/vold/Ext4.h  2013-12-21 21:47:44.191971531 +0100
  80. @@ -23,6 +23,7 @@
  81.  public:
  82.      static int doMount(const char *fsPath, const char *mountPoint, bool ro, bool remount,
  83.              bool executable);
  84. +    static int check(const char *fsPath);
  85.      static int format(const char *fsPath);
  86.  };
  87.  
  88. diff -ru .system.old/vold.old/Volume.cpp system/vold/Volume.cpp
  89. --- .system.old/vold.old/Volume.cpp 2013-12-21 13:36:04.000000000 +0100
  90. +++ system/vold/Volume.cpp  2013-12-22 10:03:00.985029967 +0100
  91. @@ -43,10 +43,25 @@
  92.  #include "Volume.h"
  93.  #include "VolumeManager.h"
  94.  #include "ResponseCode.h"
  95. +#include "Ext4.h"
  96.  #include "Fat.h"
  97.  #include "Process.h"
  98.  #include "cryptfs.h"
  99.  
  100. +
  101. +#ifndef FUSE_SDCARD_UID
  102. +#define FUSE_SDCARD_UID 1023
  103. +#endif
  104. +#ifndef FUSE_SDCARD_GID
  105. +#define FUSE_SDCARD_GID 1023
  106. +#endif
  107. +
  108. +// Stringify defined values
  109. +#define DO_STRINGIFY(str) #str
  110. +#define STRINGIFY(str) DO_STRINGIFY(str)
  111. +
  112. +static char SDCARD_DAEMON_PATH[] = "/system/bin/sdcard";
  113. +
  114.  extern "C" void dos_partition_dec(void const *pp, struct dos_partition *d);
  115.  extern "C" void dos_partition_enc(void *pp, struct dos_partition *d);
  116.  
  117. @@ -87,6 +102,12 @@
  118.   */
  119.  const char *Volume::LOOPDIR           = "/mnt/obb";
  120.  
  121. +/*
  122. + * Path for fuse
  123. + */
  124. +const char *Volume::FUSEDIR           = "/mnt/obb";
  125. +
  126. +
  127.  static const char *stateToStr(int state) {
  128.      if (state == Volume::State_Init)
  129.          return "Initializing";
  130. @@ -290,6 +311,7 @@
  131.  }
  132.  
  133.  int Volume::mountVol() {
  134. +    SLOGI("Volume::mountVol called");
  135.      dev_t deviceNodes[4];
  136.      int n, i, rc = 0;
  137.      char errmsg[255];
  138. @@ -389,6 +411,9 @@
  139.  
  140.      for (i = 0; i < n; i++) {
  141.          char devicePath[255];
  142. +        bool isUnixFs = false;
  143. +        bool isFAT    = false;
  144. +        bool isEXT4   = false;
  145.  
  146.          sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]),
  147.                  MINOR(deviceNodes[i]));
  148. @@ -401,13 +426,36 @@
  149.          if (Fat::check(devicePath)) {
  150.              if (errno == ENODATA) {
  151.                  SLOGW("%s does not contain a FAT filesystem\n", devicePath);
  152. -                continue;
  153. +                if (Ext4::check(devicePath)) {
  154. +                    // EXT4 failed
  155. +                    if (errno == ENODATA) {
  156. +                        SLOGW("%s does not contain a EXT4 filesystem\n", devicePath);
  157. +                        continue;
  158. +                    }
  159. +                    errno = EIO;
  160. +                    /* Badness - abort the mount */
  161. +                    SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
  162. +                    setState(Volume::State_Idle);
  163. +                    return -1;
  164. +                } else {
  165. +                    // EXT4 found
  166. +                    SLOGI("%s (%s) detected as EXT4 volume\n", devicePath, getLabel());
  167. +                    isUnixFs = true;
  168. +                    isEXT4 = true;
  169. +                    errno = 0;
  170. +                }
  171. +            } else {
  172. +                errno = EIO;
  173. +                /* Badness - abort the mount */
  174. +                SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
  175. +                setState(Volume::State_Idle);
  176. +                // FAT failed
  177. +                return -1;
  178.              }
  179. -            errno = EIO;
  180. -            /* Badness - abort the mount */
  181. -            SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno));
  182. -            setState(Volume::State_Idle);
  183. -            return -1;
  184. +        } else {
  185. +            // FAT found
  186. +            isFAT = true;
  187. +            isUnixFs = false;
  188.          }
  189.  
  190.          /*
  191. @@ -425,9 +473,21 @@
  192.              // For secondary external storage we keep things locked up.
  193.              gid = AID_MEDIA_RW;
  194.          }
  195. -        if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false,
  196. -                AID_SYSTEM, gid, 0702, true)) {
  197. -            SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
  198. +        
  199. +        
  200. +        if (isFAT) {
  201. +            if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false,
  202. +                    AID_SYSTEM, gid, 0702, true)) {
  203. +                SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno));
  204. +                continue;
  205. +            }
  206. +        } else if (isEXT4) {
  207. +            if (Ext4::doMount(devicePath, "/mnt/secure/staging", false, false, false)) {
  208. +                SLOGE("%s failed to mount via EXT4 (%s)\n", devicePath, strerror(errno));
  209. +                continue;
  210. +            }
  211. +        } else {
  212. +            SLOGE("%s has unknown filesystem\n", devicePath);
  213.              continue;
  214.          }
  215.  
  216. @@ -447,12 +507,66 @@
  217.           * Now that the bindmount trickery is done, atomically move the
  218.           * whole subtree to expose it to non priviledged users.
  219.           */
  220. -        if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {
  221. -            SLOGE("Failed to move mount (%s)", strerror(errno));
  222. -            umount("/mnt/secure/staging");
  223. -            setState(Volume::State_Idle);
  224. -            return -1;
  225. +        if (isUnixFs) {
  226. +            /*
  227. +             * In case of a unix filesystem we're using the sdcard daemon
  228. +             * to expose the subtree to non privileged users to avoid
  229. +             * permission issues for data created by apps.
  230. +             */
  231. +            
  232. +            const char* label = getLabel();
  233. +            char* fuseSrc = (char*) malloc(strlen(FUSEDIR) + strlen("/") + strlen(label) + 1);
  234. +            sprintf(fuseSrc, "%s/%s", FUSEDIR, label);
  235. +            bool failed = false;
  236. +            
  237. +            // Create fuse dir if not exists
  238. +            if (access(fuseSrc, R_OK | W_OK)) {
  239. +                if (mkdir(fuseSrc, 0775)) {
  240. +                    SLOGE("Failed to create %s (%s)", fuseSrc, strerror(errno));
  241. +                    failed = true;
  242. +                }
  243. +            }
  244. +            
  245. +            // Move subtree to fuse dir
  246. +            if (!failed && doMoveMount("/mnt/secure/staging", fuseSrc, false)) {
  247. +                SLOGE("Failed to move mount (%s)", strerror(errno));
  248. +                umount("/mnt/secure/staging");
  249. +                failed = true;
  250. +            }
  251. +            
  252. +            // Set owner and group on fuse dir
  253. +            if (!failed && chown(fuseSrc, FUSE_SDCARD_UID, FUSE_SDCARD_GID)) {
  254. +                SLOGE("Failed to set owner/group on %s (%s)", fuseSrc, strerror(errno));
  255. +                failed = true;
  256. +            }
  257. +            
  258. +            // Set permissions (775) on fuse dir
  259. +            if (!failed && chmod(fuseSrc, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH)) {
  260. +                SLOGE("Failed to set permissions on %s (%s)", fuseSrc, strerror(errno));
  261. +                failed = true;
  262. +            }
  263. +            
  264. +            // Invoke the sdcard daemon to expose it
  265. +            if(!failed && doFuseMount(fuseSrc, getMountpoint())) {
  266. +                SLOGE("Failed to fuse mount (%s) -> (%s)", fuseSrc, getMountpoint());
  267. +                failed = true;
  268. +            }
  269. +            
  270. +            free(fuseSrc);
  271. +            
  272. +            if (failed) {
  273. +                setState(Volume::State_Idle);
  274. +                return -1;
  275. +            }
  276. +        } else {
  277. +            if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) {
  278. +                SLOGE("Failed to move mount (%s)", strerror(errno));
  279. +                umount("/mnt/secure/staging");
  280. +                setState(Volume::State_Idle);
  281. +                return -1;
  282. +            }
  283.          }
  284. +        
  285.          setState(Volume::State_Mounted);
  286.          mCurrentlyMountedKdev = deviceNodes[i];
  287.          return 0;
  288. @@ -561,6 +675,27 @@
  289.      return -1;
  290.  }
  291.  
  292. +int Volume::doFuseMount(const char *src, const char *dst) {
  293. +    if (access(SDCARD_DAEMON_PATH, X_OK)) {
  294. +        SLOGE("Can't invoke sdcard daemon.\n");
  295. +        return -1;
  296. +    }
  297. +    const char* const args[] = { "sdcard", src, dst, STRINGIFY(FUSE_SDCARD_UID), STRINGIFY(FUSE_SDCARD_GID), NULL };
  298. +    pid_t fusePid;
  299. +
  300. +    fusePid=fork();
  301. +    
  302. +    if (fusePid == 0) {
  303. +        SLOGW("Invoking sdcard daemon (%s) -> (%s)", src, dst);
  304. +        if (execv(SDCARD_DAEMON_PATH, (char* const*)args) == -1) {
  305. +            SLOGE("Failed to invoke the sdcard daemon!");
  306. +            return -1;
  307. +        }
  308. +    }
  309. +    
  310. +    return 0;
  311. +}
  312. +
  313.  int Volume::doUnmount(const char *path, bool force) {
  314.      int retries = 10;
  315.  
  316. @@ -597,6 +732,9 @@
  317.  
  318.  int Volume::unmountVol(bool force, bool revert) {
  319.      int i, rc;
  320. +    const char* label = getLabel();
  321. +    char* fuseSrc = (char*) malloc(strlen(FUSEDIR) + strlen("/") + strlen(label) + 1);
  322. +    sprintf(fuseSrc, "%s/%s", FUSEDIR, label);
  323.  
  324.      if (getState() != Volume::State_Mounted) {
  325.          SLOGE("Volume %s unmount request when not mounted", getLabel());
  326. @@ -626,7 +764,7 @@
  327.          SLOGE("Failed to unmount tmpfs on %s (%s)", secure_dir, strerror(errno));
  328.          goto fail_republish;
  329.      }
  330. -
  331. +    
  332.      /*
  333.       * Finally, unmount the actual block device from the staging dir
  334.       */
  335. @@ -635,6 +773,16 @@
  336.          goto fail_recreate_bindmount;
  337.      }
  338.  
  339. +    /*
  340. +     * Unmount the actual block device from fuse dir if exists
  341. +     */
  342. +    if (!access(fuseSrc, R_OK | W_OK)) {
  343. +        if (doUnmount(fuseSrc, force)) {
  344. +            SLOGE("Failed to unmount %s (%s)", fuseSrc, strerror(errno));
  345. +            goto out_nomedia;
  346. +        }
  347. +    }
  348. +
  349.      SLOGI("%s unmounted sucessfully", getMountpoint());
  350.  
  351.      /* If this is an encrypted volume, and we've been asked to undo
  352. @@ -649,6 +797,7 @@
  353.  
  354.      setState(Volume::State_Idle);
  355.      mCurrentlyMountedKdev = -1;
  356. +    free(fuseSrc);
  357.      return 0;
  358.  
  359.      /*
  360. @@ -675,6 +824,7 @@
  361.  
  362.  out_nomedia:
  363.      setState(Volume::State_NoMedia);
  364. +    free(fuseSrc);
  365.      return -1;
  366.  }
  367.  int Volume::initializeMbr(const char *deviceNode) {
  368. diff -ru .system.old/vold.old/Volume.h system/vold/Volume.h
  369. --- .system.old/vold.old/Volume.h   2013-12-21 13:36:04.000000000 +0100
  370. +++ system/vold/Volume.h    2013-12-21 21:48:33.071971214 +0100
  371. @@ -46,6 +46,7 @@
  372.      static const char *ASECDIR;
  373.  
  374.      static const char *LOOPDIR;
  375. +    static const char *FUSEDIR;
  376.  
  377.  protected:
  378.      char *mLabel;
  379. @@ -99,6 +100,7 @@
  380.      int createBindMounts();
  381.      int doUnmount(const char *path, bool force);
  382.      int doMoveMount(const char *src, const char *dst, bool force);
  383. +    int doFuseMount(const char *src, const char *dst);
  384.      void protectFromAutorunStupidity();
  385.  };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement