Commit ba0d4aa2 authored by DidntRead's avatar DidntRead Committed by mohancm100
Browse files

Add sdcardfs support

parent cd8a83c7
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -15,9 +15,7 @@ source "fs/ext3/Kconfig"
source "fs/ext4/Kconfig"
source "fs/exfat/Kconfig"

# lenovo.sw : add for wrapfs
source "fs/sdcardfs/Kconfig"
# end


config FS_XIP
# execute in place
@@ -191,6 +189,7 @@ if MISC_FILESYSTEMS
source "fs/adfs/Kconfig"
source "fs/affs/Kconfig"
source "fs/ecryptfs/Kconfig"
source "fs/sdcardfs/Kconfig"
source "fs/hfs/Kconfig"
source "fs/hfsplus/Kconfig"
source "fs/befs/Kconfig"
+1 −4
Original line number Diff line number Diff line
@@ -83,10 +83,7 @@ obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
obj-$(CONFIG_HFS_FS)		+= hfs/
obj-$(CONFIG_ECRYPT_FS)		+= ecryptfs/

# ifeq ($(CONFIG_SDCARD_FS), yes)
obj-y		+= sdcardfs/
# endif

obj-$(CONFIG_SDCARD_FS)		+= sdcardfs/
obj-$(CONFIG_VXFS_FS)		+= freevxfs/
obj-$(CONFIG_NFS_FS)		+= nfs/
obj-$(CONFIG_EXPORTFS)		+= exportfs/

fs/sdcardfs/Kconfig

100755 → 100644
+2 −13
Original line number Diff line number Diff line
config SDCARD_FS
	tristate "sdcard file system"
	default y
	depends on CONFIGFS_FS
	default n
	help
	  Sdcardfs is based on Wrapfs file system.

@@ -10,15 +11,3 @@ config SDCARD_FS_FADV_NOACTIVE
	default y
	help
	  Sdcardfs supports fadvise noactive mode.

config SDCARD_FS_CI_SEARCH
	tristate "sdcardfs case-insensitive search support"
	depends on SDCARD_FS
	default y

config SDCARD_FS_XATTR
	bool "Sdcardfs extended attribute"
	default n
	depends on SDCARD_FS
	help
	  Modification of sdcard file system for xattr

fs/sdcardfs/Makefile

100755 → 100644
+4 −5
Original line number Diff line number Diff line
ifeq ($(CONFIG_SDCARD_FS_XATTR),y)
EXTRA_CFLAGS += -DSDCARD_FS_XATTR
endif
SDCARDFS_VERSION="0.1"

EXTRA_CFLAGS += -DSDCARDFS_VERSION=\"$(SDCARDFS_VERSION)\"

obj-$(CONFIG_SDCARD_FS) += sdcardfs.o

sdcardfs-y := dentry.o file.o inode.o main.o super.o lookup.o mmap.o packagelist.o derived_perm.o
sdcardfs-$(CONFIG_SDCARD_FS_XATTR) += xattr.o

fs/sdcardfs/dentry.c

100755 → 100644
+62 −67
Original line number Diff line number Diff line
/*
 * fs/sdcardfs/dentry.c
 *
 * Copyright (c) 2015 Lenovo Co. Ltd
 *   Authors: liaohs , jixj
                
 * Copyright (c) 2013 Samsung Electronics Co. Ltd
 *   Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
 *               Sunghwan Yun, Sungjong Seo
 *
 * This program has been developed as a stackable file system based on
 * the WrapFS which written by
 * Copyright (c) 1998-2014 Erez Zadok
 *
 * Copyright (c) 1998-2011 Erez Zadok
 * Copyright (c) 2009     Shrikar Archak
 * Copyright (c) 2003-2014 Stony Brook University
 * Copyright (c) 2003-2014 The Research Foundation of SUNY
 * Copyright (c) 2003-2011 Stony Brook University
 * Copyright (c) 2003-2011 The Research Foundation of SUNY
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 * This file is dual licensed.  It may be redistributed and/or modified
 * under the terms of the Apache 2.0 License OR version 2 of the GNU
 * General Public License.
 */

#include "sdcardfs.h"
@@ -32,6 +34,8 @@ static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
	struct dentry *parent_lower_dentry = NULL;
	struct dentry *lower_cur_parent_dentry = NULL;
	struct dentry *lower_dentry = NULL;
	struct inode *inode;
	struct sdcardfs_inode_data *data;

	if (flags & LOOKUP_RCU)
		return -ECHILD;
@@ -44,7 +48,8 @@ static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
	spin_unlock(&dentry->d_lock);

	/* check uninitialized obb_dentry and
	 * whether the base obbpath has been changed or not */
	 * whether the base obbpath has been changed or not
	 */
	if (is_obbpath_invalid(dentry)) {
		d_drop(dentry);
		return 0;
@@ -57,6 +62,14 @@ static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
	lower_dentry = lower_path.dentry;
	lower_cur_parent_dentry = dget_parent(lower_dentry);

	if ((lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) {
		err = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
		if (err == 0) {
			d_drop(dentry);
			goto out;
		}
	}

	spin_lock(&lower_dentry->d_lock);
	if (d_unhashed(lower_dentry)) {
		spin_unlock(&lower_dentry->d_lock);
@@ -72,39 +85,15 @@ static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
		goto out;
	}

/* ######## ATTENTION ########
~~~ spin_lock(&lower_dentry->d_lock);  //here call spin_lock , will cause follow DEADLOCK ~~

4>[   38.406030]-(1)[829:zygote] (&(&dentry->d_lock)->rlock){+.+...}, at: [<c026a6c4>] sdcardfs_d_revalidate+0x1b8/0x258
<4>[   38.406057]-(1)[829:zygote]
<4>[   38.406062]-(1)[829:zygote]but task is already holding lock:
<4>[   38.406069]-(1)[829:zygote] (&(&dentry->d_lock)->rlock){+.+...}, at: [<c026a6bc>] sdcardfs_d_revalidate+0x1b0/0x258
<4>[   38.406094]-(1)[829:zygote]
<4>[   38.406098]-(1)[829:zygote]other info that might help us debug this:
<4>[   38.406107]-(1)[829:zygote] Possible unsafe locking scenario:
<4>[   38.406113]-(1)[829:zygote]
<4>[   38.406119]-(1)[829:zygote]       CPU0
<4>[   38.406125]-(1)[829:zygote]       ----
<4>[   38.406132]-(1)[829:zygote]  lock(&(&dentry->d_lock)->rlock);
<4>[   38.406143]-(1)[829:zygote]  lock(&(&dentry->d_lock)->rlock);
<4>[   38.406153]-(1)[829:zygote]
<4>[   38.406158]-(1)[829:zygote] *** DEADLOCK ***
<4>[   38.406163]-(1)[829:zygote]
<4>[   38.406169]-(1)[829:zygote] May be due to missing lock nesting notation
 */
	if (dentry < lower_dentry) {
		spin_lock(&dentry->d_lock);
		spin_lock_nested(&lower_dentry->d_lock, 1);
		spin_lock_nested(&lower_dentry->d_lock, DENTRY_D_LOCK_NESTED);
	} else {
		spin_lock(&lower_dentry->d_lock);
		spin_lock_nested(&dentry->d_lock, 1);
		spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
	}

	if (dentry->d_name.len != lower_dentry->d_name.len) {
		__d_drop(dentry);
		err = 0;
	} else if (strncasecmp(dentry->d_name.name, lower_dentry->d_name.name,
				dentry->d_name.len) != 0) {
	if (!qstr_case_eq(&dentry->d_name, &lower_dentry->d_name)) {
		__d_drop(dentry);
		err = 0;
	}
@@ -116,6 +105,21 @@ static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
		spin_unlock(&dentry->d_lock);
		spin_unlock(&lower_dentry->d_lock);
	}
	if (!err)
		goto out;

	/* If our top's inode is gone, we may be out of date */
	inode = igrab(dentry->d_inode);
	if (inode) {
		data = top_data_get(SDCARDFS_I(inode));
		if (!data || data->abandoned) {
			d_drop(dentry);
			err = 0;
		}
		if (data)
			data_put(data);
		iput(inode);
	}

out:
	dput(parent_dentry);
@@ -128,12 +132,10 @@ out:
static void sdcardfs_d_release(struct dentry *dentry)
{
	/* release and reset the lower paths */
	if(has_graft_path(dentry)) {
	if (has_graft_path(dentry))
		sdcardfs_put_reset_orig_path(dentry);
	}
	sdcardfs_put_reset_lower_path(dentry);
	free_dentry_private_data(dentry);
	return;
}

static int sdcardfs_hash_ci(const struct dentry *dentry,
@@ -150,12 +152,10 @@ static int sdcardfs_hash_ci(const struct dentry *dentry,
	unsigned long hash;

	name = qstr->name;
	//len = vfat_striptail_len(qstr);
	len = qstr->len;

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

@@ -169,31 +169,26 @@ static int sdcardfs_cmp_ci(const struct dentry *parent,
		const struct dentry *dentry,
		unsigned int len, const char *str, const struct qstr *name)
{
	/* This function is copy of vfat_cmpi */
	// FIXME Should we support national language? 
	//struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io;
	//unsigned int alen, blen;
	/* FIXME Should we support national language? */

	/* A filename cannot end in '.' or we treat it like it has none */
	/*
	alen = vfat_striptail_len(name);
	blen = __vfat_striptail_len(len, str);
	if (alen == blen) {
		if (nls_strnicmp(t, name->name, str, alen) == 0)
			return 0;
	}
	*/
	if (name->len == len) {
		if (strncasecmp(name->name, str, len) == 0)
		if (str_n_case_eq(name->name, str, len))
			return 0;
	}
	return 1;
}

static void sdcardfs_canonical_path(const struct path *path,
				struct path *actual_path)
{
	sdcardfs_get_real_lower(path->dentry, actual_path);
}

const struct dentry_operations sdcardfs_ci_dops = {
	.d_revalidate	= sdcardfs_d_revalidate,
	.d_release	= sdcardfs_d_release,
	.d_hash	= sdcardfs_hash_ci,
	.d_compare	= sdcardfs_cmp_ci,
	.d_canonical_path = sdcardfs_canonical_path,
};
Loading