Samsung SPH-L720 (Sprint) source updates
/fs/ext4/namei.c
blob:1636f7886719f0e28cd7437917ec5b30b84fe7f1 -> blob:141637ece67299b67150d13e9da4b95d7f30de17
--- fs/ext4/namei.c
+++ fs/ext4/namei.c
@@ -30,6 +30,10 @@
#include <linux/time.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+#include <linux/namei.h>
+#include <linux/dcache.h>
+#endif
#include <linux/string.h>
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
@@ -797,6 +801,18 @@ static inline int ext4_match (int len, c
return !memcmp(name, de->name, len);
}
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+static inline int ext4_ci_match (int len, const char * const name,
+ struct ext4_dir_entry_2 * de)
+{
+ if (len != de->name_len)
+ return 0;
+ if (!de->inode)
+ return 0;
+ return !strncasecmp(name, de->name, len);
+}
+#endif
+
/*
* Returns 0 if not found, -1 on failure, and 1 on success
*/
@@ -804,7 +820,12 @@ static inline int search_dirblock(struct
struct inode *dir,
const struct qstr *d_name,
unsigned int offset,
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ struct ext4_dir_entry_2 ** res_dir,
+ char *ci_name_buf)
+#else
struct ext4_dir_entry_2 ** res_dir)
+#endif
{
struct ext4_dir_entry_2 * de;
char * dlimit;
@@ -818,14 +839,38 @@ static inline int search_dirblock(struct
/* this code is executed quadratically often */
/* do minimal checking `by hand' */
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ if ((char *) de + namelen <= dlimit) {
+ if (ci_name_buf) {
+ if (ext4_ci_match (namelen, name, de)) {
+ /* found a match - just to be sure, do a full check */
+ if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
+ return -1;
+ *res_dir = de;
+ memcpy(ci_name_buf, de->name, namelen);
+ ci_name_buf[namelen] = '\0';
+ return 1;
+ }
+ } else {
+ if (ext4_match (namelen, name, de)) {
+ /* found a match - just to be sure, do a full check */
+ if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
+ return -1;
+ *res_dir = de;
+ return 1;
+ }
+ }
+ }
+#else
if ((char *) de + namelen <= dlimit &&
- ext4_match (namelen, name, de)) {
+ ext4_match (namelen, name, de)) {
/* found a match - just to be sure, do a full check */
if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
return -1;
*res_dir = de;
return 1;
}
+#endif
/* prevent looping on a bad block */
de_len = ext4_rec_len_from_disk(de->rec_len,
dir->i_sb->s_blocksize);
@@ -851,7 +896,12 @@ static inline int search_dirblock(struct
*/
static struct buffer_head * ext4_find_entry (struct inode *dir,
const struct qstr *d_name,
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ struct ext4_dir_entry_2 ** res_dir,
+ char *ci_name_buf)
+#else
struct ext4_dir_entry_2 ** res_dir)
+#endif
{
struct super_block *sb;
struct buffer_head *bh_use[NAMEI_RA_SIZE];
@@ -936,8 +986,14 @@ restart:
brelse(bh);
goto next;
}
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ i = search_dirblock(bh, dir, d_name,
+ block << EXT4_BLOCK_SIZE_BITS(sb), res_dir,
+ ci_name_buf);
+#else
i = search_dirblock(bh, dir, d_name,
block << EXT4_BLOCK_SIZE_BITS(sb), res_dir);
+#endif
if (i == 1) {
EXT4_I(dir)->i_dir_start_lookup = block;
ret = bh;
@@ -987,9 +1043,15 @@ static struct buffer_head * ext4_dx_find
if (!(bh = ext4_bread(NULL, dir, block, 0, err)))
goto errout;
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ retval = search_dirblock(bh, dir, d_name,
+ block << EXT4_BLOCK_SIZE_BITS(sb),
+ res_dir, NULL);
+#else
retval = search_dirblock(bh, dir, d_name,
block << EXT4_BLOCK_SIZE_BITS(sb),
res_dir);
+#endif
if (retval == 1) { /* Success! */
dx_release(frames);
return bh;
@@ -1024,11 +1086,23 @@ static struct dentry *ext4_lookup(struct
struct inode *inode;
struct ext4_dir_entry_2 *de;
struct buffer_head *bh;
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ struct qstr ci_name;
+ char ci_name_buf[EXT4_NAME_LEN+1];
+#endif
if (dentry->d_name.len > EXT4_NAME_LEN)
return ERR_PTR(-ENAMETOOLONG);
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ ci_name_buf[0] = '\0';
+ if (nd->flags & LOOKUP_CASE_INSENSITIVE)
+ bh = ext4_find_entry(dir, &dentry->d_name, &de, ci_name_buf);
+ else
+ bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
+#else
bh = ext4_find_entry(dir, &dentry->d_name, &de);
+#endif
inode = NULL;
if (bh) {
__u32 ino = le32_to_cpu(de->inode);
@@ -1051,7 +1125,16 @@ static struct dentry *ext4_lookup(struct
return ERR_PTR(-EIO);
}
}
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ if (ci_name_buf[0] != '\0') {
+ ci_name.name = ci_name_buf;
+ ci_name.len = dentry->d_name.len;
+ return d_add_ci(dentry, inode, &ci_name);
+ } else
+ return d_splice_alias(inode, dentry);
+#else
return d_splice_alias(inode, dentry);
+#endif
}
@@ -1065,7 +1148,11 @@ struct dentry *ext4_get_parent(struct de
struct ext4_dir_entry_2 * de;
struct buffer_head *bh;
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ bh = ext4_find_entry(child->d_inode, &dotdot, &de, NULL);
+#else
bh = ext4_find_entry(child->d_inode, &dotdot, &de);
+#endif
if (!bh)
return ERR_PTR(-ENOENT);
ino = le32_to_cpu(de->inode);
@@ -2140,7 +2227,11 @@ static int ext4_rmdir(struct inode *dir,
return PTR_ERR(handle);
retval = -ENOENT;
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
+#else
bh = ext4_find_entry(dir, &dentry->d_name, &de);
+#endif
if (!bh)
goto end_rmdir;
@@ -2205,7 +2296,11 @@ static int ext4_unlink(struct inode *dir
ext4_handle_sync(handle);
retval = -ENOENT;
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL);
+#else
bh = ext4_find_entry(dir, &dentry->d_name, &de);
+#endif
if (!bh)
goto end_unlink;
@@ -2421,7 +2516,11 @@ static int ext4_rename(struct inode *old
if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
ext4_handle_sync(handle);
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de, NULL);
+#else
old_bh = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de);
+#endif
/*
* Check for inode number is _not_ due to possible IO errors.
* We might rmdir the source, keep it as pwd of some process
@@ -2434,7 +2533,11 @@ static int ext4_rename(struct inode *old
goto end_rename;
new_inode = new_dentry->d_inode;
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ new_bh = ext4_find_entry(new_dir, &new_dentry->d_name, &new_de, NULL);
+#else
new_bh = ext4_find_entry(new_dir, &new_dentry->d_name, &new_de);
+#endif
if (new_bh) {
if (!new_inode) {
brelse(new_bh);
@@ -2512,7 +2615,11 @@ static int ext4_rename(struct inode *old
struct buffer_head *old_bh2;
struct ext4_dir_entry_2 *old_de2;
+#ifdef CONFIG_SDCARD_FS_CI_SEARCH
+ old_bh2 = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de2, NULL);
+#else
old_bh2 = ext4_find_entry(old_dir, &old_dentry->d_name, &old_de2);
+#endif
if (old_bh2) {
retval = ext4_delete_entry(handle, old_dir,
old_de2, old_bh2);