Initialize Tizen 2.3
[framework/system/deviced.git] / src / mmc / vfat.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <limits.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #include "core/common.h"
27 #include "core/log.h"
28 #include "mmc-handler.h"
29
30 #define FS_VFAT_NAME    "mkdosfs"
31
32 #define FS_VFAT_MOUNT_OPT       "uid=5000,gid=5000,dmask=0002,fmask=0002,iocharset=iso8859-1,utf8,shortname=mixed"
33
34 static const char *vfat_arg[] = {
35         "/sbin/mkfs.vfat",
36         NULL, NULL,
37 };
38
39 static const char *vfat_check_arg[] = {
40         "/usr/bin/fsck_msdosfs",
41         "-pf", NULL, NULL,
42 };
43
44 static struct fs_check vfat_info = {
45         FS_TYPE_VFAT,
46         "vfat",
47         0x1fe,
48         2,
49         {0x55, 0xAA},
50 };
51
52 static int vfat_check(const char *devpath)
53 {
54         int argc, r, pass = 0;
55
56         argc = ARRAY_SIZE(vfat_check_arg);
57         vfat_check_arg[argc - 2] = devpath;
58
59         do {
60                 r = run_child(argc, vfat_check_arg);
61
62                 switch (r) {
63                 case 0:
64                         _I("filesystem check completed OK");
65                         return 0;
66                 case 2:
67                         _I("file system check failed (not a FAT filesystem)");
68                         errno = ENODATA;
69                         return -1;
70                 case 4:
71                         if (pass++ <= 2) {
72                                 _I("filesystem modified - rechecking (pass : %d)", pass);
73                                 continue;
74                         }
75                         _I("failing check after rechecks, but file system modified");
76                         return 0;
77                 default:
78                         _I("filesystem check failed (unknown exit code %d)", r);
79                         errno = EIO;
80                         return -1;
81                 }
82         } while (1);
83
84         return 0;
85 }
86
87 static bool vfat_match(const char *devpath)
88 {
89         int r;
90
91         r = vfat_check(devpath);
92         if (r < 0) {
93                 _E("failed to match with vfat(%s)", devpath);
94                 return false;
95         }
96
97         _D("MMC type : %s", vfat_info.name);
98         return true;
99 }
100
101 static int vfat_mount(bool smack, const char *devpath, const char *mount_point)
102 {
103         char options[NAME_MAX];
104         int r, retry = RETRY_COUNT;
105
106         if (smack)
107                 snprintf(options, sizeof(options), "%s,%s", FS_VFAT_MOUNT_OPT, SMACKFS_MOUNT_OPT);
108         else
109                 snprintf(options, sizeof(options), "%s", FS_VFAT_MOUNT_OPT);
110
111         do {
112                 r = mount(devpath, mount_point, "vfat", 0, options);
113                 if (!r) {
114                         _D("Mounted mmc card [vfat]");
115                         return 0;
116                 }
117                 _D("mount fail : r = %d, err = %d", r, errno);
118                 usleep(100000);
119         } while (r < 0 && errno == ENOENT && retry-- > 0);
120
121         return -errno;
122 }
123
124 static int vfat_format(const char *devpath)
125 {
126         int argc;
127         argc = ARRAY_SIZE(vfat_arg);
128         vfat_arg[argc - 2] = devpath;
129         return run_child(argc, vfat_arg);
130 }
131
132 static const struct mmc_fs_ops vfat_ops = {
133         .type = FS_TYPE_VFAT,
134         .name = "vfat",
135         .match = vfat_match,
136         .check = vfat_check,
137         .mount = vfat_mount,
138         .format = vfat_format,
139 };
140
141 static void __CONSTRUCTOR__ module_init(void)
142 {
143         add_fs(&vfat_ops);
144 }
145 /*
146 static void __DESTRUCTOR__ module_exit(void)
147 {
148         _D("module exit");
149         remove_fs(&vfat_ops);
150 }
151 */