summaryrefslogtreecommitdiffstats
path: root/sdcard
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2011-01-17 21:06:26 -0800
committerMike Lockwood <lockwood@android.com>2011-01-17 21:06:26 -0800
commitb94d320b1e7e2a3493147f6763cd2825b111a4d8 (patch)
tree8d365677579b67b7b9c504c60628d4a02d316391 /sdcard
parent4e84d3bcf9af3452128fe2e8dc7607dff9016fac (diff)
downloadsystem_core-b94d320b1e7e2a3493147f6763cd2825b111a4d8.tar.gz
system_core-b94d320b1e7e2a3493147f6763cd2825b111a4d8.tar.bz2
system_core-b94d320b1e7e2a3493147f6763cd2825b111a4d8.zip
sdcard: Fix lower case squashing for case insensitivity support.
The fuse layer in the kernel does not support case insensitive file systems. But the sdcard daemon's fuse_lookup was returning the same file object for different file names, which caused problems in the kernel fuse layer's dcache, resulting in EBUSY errors if the same directory was opened twice under different names differing only by case. To fix this, the sdcard daemon will return different file objects for files or directories that differ only by case. Now the squashing occurs only in the interaction between the sdcard daemon and the underlying file system in /data/media, and sdcard maintains the illusion for the kernel fuse layer that there are two separate files. Example: Suppose both /mnt/sdcard/foo.txt and /mnt/sdcard/FOO.TXT are opened. Previously, the sdcard would squash this to a single node, and return the same node to the kernel fuse implementation twice, and would open the underlying file /data/media/foo.txt only once. Now sdcard will create two separate nodes will open /data/media/foo.txt twice, once for mnt/sdcard/foo.txt and again for /mnt/sdcard/FOO.TXT. Change-Id: I70e36b7822142750d3eeeb75edd6464ec7c79f2a Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'sdcard')
-rw-r--r--sdcard/sdcard.c31
1 files changed, 10 insertions, 21 deletions
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 21a44cea6..cc2cce7b7 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -116,6 +116,15 @@ static unsigned gid = -1;
#define PATH_BUFFER_SIZE 1024
+static void normalize_name(char *name)
+{
+ if (force_lower_case) {
+ char ch;
+ while ((ch = *name) != 0)
+ *name++ = tolower(ch);
+ }
+}
+
/*
* Get the real-life absolute path to a node.
* node: start at this node
@@ -146,6 +155,7 @@ char *node_get_path(struct node *node, char *buf, const char *name)
out[0] = '/';
}
+ normalize_name(out);
return out;
}
@@ -457,15 +467,6 @@ static int name_needs_normalizing(const char* name) {
return 0;
}
-static void normalize_name(char *name)
-{
- if (force_lower_case) {
- char ch;
- while ((ch = *name) != 0)
- *name++ = tolower(ch);
- }
-}
-
static void recursive_fix_files(const char* path) {
DIR* dir;
struct dirent* entry;
@@ -549,7 +550,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
switch (hdr->opcode) {
case FUSE_LOOKUP: { /* bytez[] -> entry_out */
- normalize_name((char*) data);
TRACE("LOOKUP %llx %s\n", hdr->nodeid, (char*) data);
lookup_entry(fuse, node, (char*) data, hdr->unique);
return;
@@ -609,8 +609,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
char *name = ((char*) data) + sizeof(*req);
int res;
- normalize_name(name);
-
TRACE("MKNOD %s @ %llx\n", name, hdr->nodeid);
path = node_get_path(node, buffer, name);
@@ -630,8 +628,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
char *name = ((char*) data) + sizeof(*req);
int res;
- normalize_name(name);
-
TRACE("MKDIR %s @ %llx 0%o\n", name, hdr->nodeid, req->mode);
path = node_get_path(node, buffer, name);
@@ -647,7 +643,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
case FUSE_UNLINK: { /* bytez[] -> */
char *path, buffer[PATH_BUFFER_SIZE];
int res;
- normalize_name((char*) data);
TRACE("UNLINK %s @ %llx\n", (char*) data, hdr->nodeid);
path = node_get_path(node, buffer, (char*) data);
res = unlink(path);
@@ -657,7 +652,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
case FUSE_RMDIR: { /* bytez[] -> */
char *path, buffer[PATH_BUFFER_SIZE];
int res;
- normalize_name((char*) data);
TRACE("RMDIR %s @ %llx\n", (char*) data, hdr->nodeid);
path = node_get_path(node, buffer, (char*) data);
res = rmdir(path);
@@ -674,9 +668,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
struct node *newparent;
int res;
- normalize_name(oldname);
- normalize_name(newname);
-
TRACE("RENAME %s->%s @ %llx\n", oldname, newname, hdr->nodeid);
target = lookup_child_by_name(node, oldname);
@@ -723,7 +714,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
return;
}
- normalize_name(buffer);
path = node_get_path(node, buffer, 0);
TRACE("OPEN %llx '%s' 0%o fh=%p\n", hdr->nodeid, path, req->flags, h);
h->fd = open(path, req->flags);
@@ -825,7 +815,6 @@ void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *da
return;
}
- normalize_name(buffer);
path = node_get_path(node, buffer, 0);
TRACE("OPENDIR %llx '%s'\n", hdr->nodeid, path);
h->d = opendir(path);