Skip to content

Commit

Permalink
EXFAT: merge Samsung Galaxy source update! and BUMP to 1.2.8
Browse files Browse the repository at this point in the history
  • Loading branch information
dorimanx committed Mar 6, 2014
1 parent b0abdd6 commit 5e12cbb
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 1 deletion.
172 changes: 172 additions & 0 deletions exfat_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,150 @@ static void __set_sb_clean(struct super_block *sb)
#endif
}

static int __exfat_revalidate(struct dentry *dentry)
{
return 0;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00)
static int exfat_revalidate(struct dentry *dentry, unsigned int flags)
#else
static int exfat_revalidate(struct dentry *dentry, struct nameidata *nd)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00)
if (flags & LOOKUP_RCU)
return -ECHILD;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,00)
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;
#endif

if (dentry->d_inode)
return 1;
return __exfat_revalidate(dentry);
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00)
static int exfat_revalidate_ci(struct dentry *dentry, unsigned int flags)
#else
static int exfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00)
if (flags & LOOKUP_RCU)
return -ECHILD;
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,00)
unsigned int flags;

if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;

flags = nd ? nd->flags : 0;
#else
flags = nd ? nd->flags : 0;
#endif

if (dentry->d_inode)
return 1;

if (!flags)
return 0;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,00)
if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
return 0;
#else
if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
return 0;
}
#endif

return __exfat_revalidate(dentry);
}

static unsigned int __exfat_striptail_len(unsigned int len, const char *name)
{
while (len && name[len - 1] == '.')
len--;
return len;
}

static unsigned int exfat_striptail_len(const struct qstr *qstr)
{
return __exfat_striptail_len(qstr->len, qstr->name);
}

static int exfat_d_hash(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{
qstr->hash = full_name_hash(qstr->name, exfat_striptail_len(qstr));
return 0;
}

static int exfat_d_hashi(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{
struct nls_table *t = EXFAT_SB(dentry->d_sb)->nls_io;
const unsigned char *name;
unsigned int len;
unsigned long hash;

name = qstr->name;
len = exfat_striptail_len(qstr);

hash = init_name_hash();
while (len--)
hash = partial_name_hash(nls_tolower(t, *name++), hash);
qstr->hash = end_name_hash(hash);

return 0;
}

static int exfat_cmpi(const struct dentry *parent, const struct inode *pinode,
const struct dentry *dentry, const struct inode *inode,
unsigned int len, const char *str, const struct qstr *name)
{
struct nls_table *t = EXFAT_SB(parent->d_sb)->nls_io;
unsigned int alen, blen;

alen = exfat_striptail_len(name);
blen = __exfat_striptail_len(len, str);
if (alen == blen) {
if (nls_strnicmp(t, name->name, str, alen) == 0)
return 0;
}
return 1;
}

static int exfat_cmp(const struct dentry *parent, const struct inode *pinode,
const struct dentry *dentry, const struct inode *inode,
unsigned int len, const char *str, const struct qstr *name)
{
unsigned int alen, blen;

alen = exfat_striptail_len(name);
blen = __exfat_striptail_len(len, str);
if (alen == blen) {
if (strncmp(name->name, str, alen) == 0)
return 0;
}
return 1;
}

static const struct dentry_operations exfat_ci_dentry_ops = {
.d_revalidate = exfat_revalidate_ci,
.d_hash = exfat_d_hashi,
.d_compare = exfat_cmpi,
};

static const struct dentry_operations exfat_dentry_ops = {
.d_revalidate = exfat_revalidate,
.d_hash = exfat_d_hash,
.d_compare = exfat_cmp,
};

/*======================================================================*/
/* Directory Entry Operations */
/*======================================================================*/
Expand Down Expand Up @@ -1409,9 +1553,13 @@ static ssize_t exfat_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter
loff_t offset)
#else
static ssize_t exfat_direct_IO(int rw, struct kiocb *iocb,
#ifdef CONFIG_AIO_OPTIMIZATION
struct iov_iter *iter, loff_t offset)
#else
const struct iovec *iov,
loff_t offset, unsigned long nr_segs)
#endif
#endif
{
struct inode *inode = iocb->ki_filp->f_mapping->host;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,34)
Expand All @@ -1422,19 +1570,29 @@ static ssize_t exfat_direct_IO(int rw, struct kiocb *iocb,
if (rw == WRITE) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
if (EXFAT_I(inode)->mmu_private < (offset + iov_iter_count(iter)))
#else
#ifdef CONFIG_AIO_OPTIMIZATION
if (EXFAT_I(inode)->mmu_private <
(offset + iov_iter_count(iter)))
#else
if (EXFAT_I(inode)->mmu_private < (offset + iov_length(iov, nr_segs)))
#endif
#endif
return 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,00)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
ret = blockdev_direct_IO(rw, iocb, inode, iter,
offset, exfat_get_block);
#else
#ifdef CONFIG_AIO_OPTIMIZATION
ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
exfat_get_block);
#else
ret = blockdev_direct_IO(rw, iocb, inode, iov,
offset, nr_segs, exfat_get_block);
#endif
#endif
#else
ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, exfat_get_block, NULL);
Expand All @@ -1444,9 +1602,13 @@ static ssize_t exfat_direct_IO(int rw, struct kiocb *iocb,
if ((ret < 0) && (rw & WRITE))
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
exfat_write_failed(mapping, offset+iov_iter_count(iter));
#else
#ifdef CONFIG_AIO_OPTIMIZATION
exfat_write_failed(mapping, offset+iov_iter_count(iter));
#else
exfat_write_failed(mapping, offset+iov_length(iov, nr_segs));
#endif
#endif
#endif
return ret;
}
Expand Down Expand Up @@ -2080,6 +2242,14 @@ static int exfat_read_root(struct inode *inode)
return 0;
}

static void setup_dops(struct super_block *sb)
{
if (EXFAT_SB(sb)->options.casesensitive == 0)
sb->s_d_op = &exfat_ci_dentry_ops;
else
sb->s_d_op = &exfat_dentry_ops;
}

static int exfat_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *root_inode = NULL;
Expand Down Expand Up @@ -2109,6 +2279,8 @@ static int exfat_fill_super(struct super_block *sb, void *data, int silent)
if (error)
goto out_fail;

setup_dops(sb);

error = -EIO;
sb_min_blocksize(sb, 512);
sb->s_maxbytes = 0x7fffffffffffffffLL; /* maximum file size */
Expand Down
2 changes: 1 addition & 1 deletion exfat_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
/* */
/************************************************************************/

#define EXFAT_VERSION "1.2.7"
#define EXFAT_VERSION "1.2.8"

0 comments on commit 5e12cbb

Please sign in to comment.