tizen 2.3 release
[framework/system/deviced.git] / src / mmc / exfat.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_EXFAT_NAME "EXFAT"
31
32 #define FS_EXFAT_MOUNT_OPT      "uid=5000,gid=5000,dmask=0002,fmask=0002"
33
34 static const char *exfat_arg[] = {
35         "/sbin/mkfs.exfat",
36         "-t", "exfat", "-s", "9", "-c", "8", "-b", "11", "-f", "1", "-l", "tizen", NULL, NULL,
37 };
38
39 static const char *exfat_check_arg[] = {
40         "/sbin/fsck.exfat",
41         "-f", "-R", NULL, NULL,
42 };
43
44 static struct fs_check exfat_info = {
45         FS_TYPE_EXFAT,
46         "exfat",
47 };
48
49 static bool exfat_match(const char *devpath)
50 {
51         int fd, len, r;
52         int argc;
53         char buf[BUF_LEN];
54         char *tmpbuf;
55
56         argc = ARRAY_SIZE(exfat_check_arg);
57         exfat_check_arg[argc - 2] = devpath;
58
59         fd = open(devpath, O_RDONLY);
60         if (fd < 0) {
61                 _E("failed to open fd(%s) : %s", devpath, strerror(errno));
62                 return false;
63         }
64
65         /* check file system name */
66         len = sizeof(buf);
67         tmpbuf = buf;
68         while (len != 0 && (r = read(fd, tmpbuf, len)) != 0) {
69                 if (r < 0) {
70                         if (errno == EINTR)
71                                 continue;
72                         goto error;
73                 }
74                 len -= r;
75                 tmpbuf += r;
76         }
77
78         if (strncmp((buf + 3), FS_EXFAT_NAME, strlen(FS_EXFAT_NAME)))
79                 goto error;
80
81         close(fd);
82         _I("MMC type : %s", exfat_info.name);
83         return true;
84
85 error:
86         close(fd);
87         _E("failed to match with exfat(%s %s)", devpath, buf);
88         return false;
89 }
90
91 static int exfat_check(const char *devpath)
92 {
93         int argc;
94         argc = ARRAY_SIZE(exfat_check_arg);
95         exfat_check_arg[argc - 2] = devpath;
96         return run_child(argc, exfat_check_arg);
97 }
98
99 static int exfat_mount(bool smack, const char *devpath, const char *mount_point)
100 {
101         char options[NAME_MAX];
102         int r, retry = RETRY_COUNT;
103
104         if (smack)
105                 snprintf(options, sizeof(options), "%s,%s", FS_EXFAT_MOUNT_OPT, SMACKFS_MOUNT_OPT);
106         else
107                 snprintf(options, sizeof(options), "%s", FS_EXFAT_MOUNT_OPT);
108
109         do {
110                 r = mount(devpath, mount_point, "exfat", 0, options);
111                 if (!r) {
112                         _I("Mounted mmc card [exfat]");
113                         return 0;
114                 }
115                 usleep(100000);
116         } while (r < 0 && errno == ENOENT && retry-- > 0);
117
118         return -errno;
119 }
120
121 static int exfat_format(const char *devpath)
122 {
123         int argc;
124         argc = ARRAY_SIZE(exfat_arg);
125         exfat_arg[argc - 2] = devpath;
126         return run_child(argc, exfat_arg);
127 }
128
129 static const struct mmc_fs_ops exfat_ops = {
130         .type = FS_TYPE_EXFAT,
131         .name = "exfat",
132         .match = exfat_match,
133         .check = exfat_check,
134         .mount = exfat_mount,
135         .format = exfat_format,
136 };
137
138 static void __CONSTRUCTOR__ module_init(void)
139 {
140         add_fs(&exfat_ops);
141 }
142 /*
143 static void __DESTRUCTOR__ module_exit(void)
144 {
145         remove_fs(&exfat_ops);
146 }
147 */