summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/sdcardfs/derived_perm.c35
-rw-r--r--fs/sdcardfs/file.c2
-rw-r--r--fs/sdcardfs/inode.c24
-rw-r--r--fs/sdcardfs/lookup.c18
-rw-r--r--fs/sdcardfs/packagelist.c40
-rw-r--r--fs/sdcardfs/sdcardfs.h17
6 files changed, 78 insertions, 58 deletions
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c
index d2bff5ecdad0..0bb442338a85 100644
--- a/fs/sdcardfs/derived_perm.c
+++ b/fs/sdcardfs/derived_perm.c
@@ -51,11 +51,16 @@ void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid,
}
/* While renaming, there is a point where we want the path from dentry, but the name from newdentry */
-void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, const char *name)
+void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, const struct qstr *name)
{
struct sdcardfs_inode_info *info = SDCARDFS_I(d_inode(dentry));
struct sdcardfs_inode_info *parent_info= SDCARDFS_I(d_inode(parent));
appid_t appid;
+ struct qstr q_Android = QSTR_LITERAL("Android");
+ struct qstr q_data = QSTR_LITERAL("data");
+ struct qstr q_obb = QSTR_LITERAL("obb");
+ struct qstr q_media = QSTR_LITERAL("media");
+ struct qstr q_cache = QSTR_LITERAL("cache");
/* By default, each inode inherits from its parent.
* the properties are maintained on its private fields
@@ -79,12 +84,12 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, co
case PERM_PRE_ROOT:
/* Legacy internal layout places users at top level */
info->perm = PERM_ROOT;
- info->userid = simple_strtoul(name, NULL, 10);
+ info->userid = simple_strtoul(name->name, NULL, 10);
set_top(info, &info->vfs_inode);
break;
case PERM_ROOT:
/* Assume masked off by default. */
- if (!strcasecmp(name, "Android")) {
+ if (qstr_case_eq(name, &q_Android)) {
/* App-specific directories inside; let anyone traverse */
info->perm = PERM_ANDROID;
info->under_android = true;
@@ -92,17 +97,17 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, co
}
break;
case PERM_ANDROID:
- if (!strcasecmp(name, "data")) {
+ if (qstr_case_eq(name, &q_data)) {
/* App-specific directories inside; let anyone traverse */
info->perm = PERM_ANDROID_DATA;
set_top(info, &info->vfs_inode);
- } else if (!strcasecmp(name, "obb")) {
+ } else if (qstr_case_eq(name, &q_obb)) {
/* App-specific directories inside; let anyone traverse */
info->perm = PERM_ANDROID_OBB;
info->under_obb = true;
set_top(info, &info->vfs_inode);
/* Single OBB directory is always shared */
- } else if (!strcasecmp(name, "media")) {
+ } else if (qstr_case_eq(name, &q_media)) {
/* App-specific directories inside; let anyone traverse */
info->perm = PERM_ANDROID_MEDIA;
set_top(info, &info->vfs_inode);
@@ -112,14 +117,14 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, co
case PERM_ANDROID_DATA:
case PERM_ANDROID_MEDIA:
info->perm = PERM_ANDROID_PACKAGE;
- appid = get_appid(name);
- if (appid != 0 && !is_excluded(name, parent_info->userid)) {
+ appid = get_appid(name->name);
+ if (appid != 0 && !is_excluded(name->name, parent_info->userid)) {
info->d_uid = multiuser_get_uid(parent_info->userid, appid);
}
set_top(info, &info->vfs_inode);
break;
case PERM_ANDROID_PACKAGE:
- if (!strcasecmp(name, "cache")) {
+ if (qstr_case_eq(name, &q_cache)) {
info->perm = PERM_ANDROID_PACKAGE_CACHE;
info->under_cache = true;
}
@@ -129,7 +134,7 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, co
void get_derived_permission(struct dentry *parent, struct dentry *dentry)
{
- get_derived_permission_new(parent, dentry, dentry->d_name.name);
+ get_derived_permission_new(parent, dentry, &dentry->d_name);
}
static appid_t get_type(const char *name) {
@@ -360,9 +365,10 @@ int need_graft_path(struct dentry *dentry)
struct dentry *parent = dget_parent(dentry);
struct sdcardfs_inode_info *parent_info= SDCARDFS_I(d_inode(parent));
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
+ struct qstr obb = QSTR_LITERAL("obb");
if(parent_info->perm == PERM_ANDROID &&
- !strcasecmp(dentry->d_name.name, "obb")) {
+ qstr_case_eq(&dentry->d_name, &obb)) {
/* /Android/obb is the base obbpath of DERIVED_UNIFIED */
if(!(sbi->options.multiuser == false
@@ -399,7 +405,7 @@ int is_obbpath_invalid(struct dentry *dent)
} else {
obbpath_s = d_path(&di->lower_path, path_buf, PATH_MAX);
if (d_unhashed(di->lower_path.dentry) ||
- strcasecmp(sbi->obbpath_s, obbpath_s)) {
+ !str_case_eq(sbi->obbpath_s, obbpath_s)) {
ret = 1;
}
kfree(path_buf);
@@ -419,15 +425,16 @@ int is_base_obbpath(struct dentry *dentry)
struct dentry *parent = dget_parent(dentry);
struct sdcardfs_inode_info *parent_info= SDCARDFS_I(d_inode(parent));
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
+ struct qstr q_obb = QSTR_LITERAL("obb");
spin_lock(&SDCARDFS_D(dentry)->lock);
if (sbi->options.multiuser) {
if(parent_info->perm == PERM_PRE_ROOT &&
- !strcasecmp(dentry->d_name.name, "obb")) {
+ qstr_case_eq(&dentry->d_name, &q_obb)) {
ret = 1;
}
} else if (parent_info->perm == PERM_ANDROID &&
- !strcasecmp(dentry->d_name.name, "obb")) {
+ qstr_case_eq(&dentry->d_name, &q_obb)) {
ret = 1;
}
spin_unlock(&SDCARDFS_D(dentry)->lock);
diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c
index 006c6ff57ad7..23f8cd7f8877 100644
--- a/fs/sdcardfs/file.c
+++ b/fs/sdcardfs/file.c
@@ -216,7 +216,7 @@ static int sdcardfs_open(struct inode *inode, struct file *file)
goto out_err;
}
- if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+ if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c
index cb0588691a0f..68e615045616 100644
--- a/fs/sdcardfs/inode.c
+++ b/fs/sdcardfs/inode.c
@@ -66,7 +66,7 @@ static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
struct fs_struct *saved_fs;
struct fs_struct *copied_fs;
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
@@ -168,7 +168,7 @@ static int sdcardfs_unlink(struct inode *dir, struct dentry *dentry)
struct path lower_path;
const struct cred *saved_cred = NULL;
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
@@ -275,8 +275,10 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
int touch_err = 0;
struct fs_struct *saved_fs;
struct fs_struct *copied_fs;
+ struct qstr q_obb = QSTR_LITERAL("obb");
+ struct qstr q_data = QSTR_LITERAL("data");
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
@@ -351,13 +353,13 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink);
fixup_lower_ownership(dentry, dentry->d_name.name);
unlock_dir(lower_parent_dentry);
- if ((!sbi->options.multiuser) && (!strcasecmp(dentry->d_name.name, "obb"))
+ if ((!sbi->options.multiuser) && (qstr_case_eq(&dentry->d_name, &q_obb))
&& (pi->perm == PERM_ANDROID) && (pi->userid == 0))
make_nomedia_in_obb = 1;
/* When creating /Android/data and /Android/obb, mark them as .nomedia */
if (make_nomedia_in_obb ||
- ((pi->perm == PERM_ANDROID) && (!strcasecmp(dentry->d_name.name, "data")))) {
+ ((pi->perm == PERM_ANDROID) && (qstr_case_eq(&dentry->d_name, &q_data)))) {
REVERT_CRED(saved_cred);
OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(d_inode(dentry)));
set_fs_pwd(current->fs, &lower_path);
@@ -388,7 +390,7 @@ static int sdcardfs_rmdir(struct inode *dir, struct dentry *dentry)
struct path lower_path;
const struct cred *saved_cred = NULL;
- if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+ if(!check_caller_access_to_name(dir, &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
@@ -476,8 +478,8 @@ static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct path lower_old_path, lower_new_path;
const struct cred *saved_cred = NULL;
- if(!check_caller_access_to_name(old_dir, old_dentry->d_name.name) ||
- !check_caller_access_to_name(new_dir, new_dentry->d_name.name)) {
+ if(!check_caller_access_to_name(old_dir, &old_dentry->d_name) ||
+ !check_caller_access_to_name(new_dir, &new_dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" new_dentry: %s, task:%s\n",
__func__, new_dentry->d_name.name, current->comm);
@@ -523,7 +525,7 @@ static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry,
sdcardfs_copy_and_fix_attrs(old_dir, d_inode(lower_old_dir_dentry));
fsstack_copy_inode_size(old_dir, d_inode(lower_old_dir_dentry));
}
- get_derived_permission_new(new_dentry->d_parent, old_dentry, new_dentry->d_name.name);
+ get_derived_permission_new(new_dentry->d_parent, old_dentry, &new_dentry->d_name);
fixup_tmp_permissions(d_inode(old_dentry));
fixup_lower_ownership(old_dentry, new_dentry->d_name.name);
drop_recursive(old_dentry); /* Can't fixup ownership recursively :( */
@@ -743,7 +745,7 @@ static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct
if (!err) {
/* check the Android group ID */
parent = dget_parent(dentry);
- if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+ if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
@@ -861,7 +863,7 @@ static int sdcardfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
int err;
parent = dget_parent(dentry);
- if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+ if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
__func__, dentry->d_name.name, current->comm);
diff --git a/fs/sdcardfs/lookup.c b/fs/sdcardfs/lookup.c
index 3c9454e5e1c6..9135866b7766 100644
--- a/fs/sdcardfs/lookup.c
+++ b/fs/sdcardfs/lookup.c
@@ -219,9 +219,8 @@ static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
struct vfsmount *lower_dir_mnt;
struct dentry *lower_dir_dentry = NULL;
struct dentry *lower_dentry;
- const char *name;
+ const struct qstr *name;
struct path lower_path;
- struct qstr this;
struct sdcardfs_sb_info *sbi;
sbi = SDCARDFS_SB(dentry->d_sb);
@@ -231,14 +230,14 @@ static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
if (IS_ROOT(dentry))
goto out;
- name = dentry->d_name.name;
+ name = &dentry->d_name;
/* now start the actual lookup procedure */
lower_dir_dentry = lower_parent_path->dentry;
lower_dir_mnt = lower_parent_path->mnt;
/* Use vfs_path_lookup to check if the dentry exists or not */
- err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name, 0,
+ err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name->name, 0,
&lower_path);
/* check for other cases */
if (err == -ENOENT) {
@@ -248,7 +247,7 @@ static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
spin_lock(&lower_dir_dentry->d_lock);
list_for_each_entry(child, &lower_dir_dentry->d_subdirs, d_child) {
if (child && d_inode(child)) {
- if (strcasecmp(child->d_name.name, name)==0) {
+ if (qstr_case_eq(&child->d_name, name)) {
match = dget(child);
break;
}
@@ -307,14 +306,11 @@ static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
goto out;
/* instatiate a new negative dentry */
- this.name = name;
- this.len = strlen(name);
- this.hash = full_name_hash(this.name, this.len);
- lower_dentry = d_lookup(lower_dir_dentry, &this);
+ lower_dentry = d_lookup(lower_dir_dentry, name);
if (lower_dentry)
goto setup_lower;
- lower_dentry = d_alloc(lower_dir_dentry, &this);
+ lower_dentry = d_alloc(lower_dir_dentry, name);
if (!lower_dentry) {
err = -ENOMEM;
goto out;
@@ -359,7 +355,7 @@ struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry,
parent = dget_parent(dentry);
- if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+ if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
ret = ERR_PTR(-EACCES);
printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
" dentry: %s, task:%s\n",
diff --git a/fs/sdcardfs/packagelist.c b/fs/sdcardfs/packagelist.c
index b02feef08d51..d96fcde041cc 100644
--- a/fs/sdcardfs/packagelist.c
+++ b/fs/sdcardfs/packagelist.c
@@ -65,7 +65,7 @@ static appid_t __get_appid(const struct qstr *key)
rcu_read_lock();
hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name)) {
+ if (qstr_case_eq(key, &hash_cur->key)) {
ret_id = atomic_read(&hash_cur->value);
rcu_read_unlock();
return ret_id;
@@ -90,7 +90,7 @@ static appid_t __get_ext_gid(const struct qstr *key)
rcu_read_lock();
hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name)) {
+ if (qstr_case_eq(key, &hash_cur->key)) {
ret_id = atomic_read(&hash_cur->value);
rcu_read_unlock();
return ret_id;
@@ -115,7 +115,7 @@ static appid_t __is_excluded(const struct qstr *app_name, userid_t user)
rcu_read_lock();
hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
if (atomic_read(&hash_cur->value) == user &&
- !strcasecmp(app_name->name, hash_cur->key.name)) {
+ qstr_case_eq(app_name, &hash_cur->key)) {
rcu_read_unlock();
return 1;
}
@@ -124,24 +124,26 @@ static appid_t __is_excluded(const struct qstr *app_name, userid_t user)
return 0;
}
-appid_t is_excluded(const char *app_name, userid_t user)
+appid_t is_excluded(const char *key, userid_t user)
{
struct qstr q;
- qstr_init(&q, app_name);
+ qstr_init(&q, key);
return __is_excluded(&q, user);
}
-
/* Kernel has already enforced everything we returned through
* derive_permissions_locked(), so this is used to lock down access
* even further, such as enforcing that apps hold sdcard_rw. */
-int check_caller_access_to_name(struct inode *parent_node, const char* name) {
+int check_caller_access_to_name(struct inode *parent_node, const struct qstr *name) {
+ struct qstr q_autorun = QSTR_LITERAL("autorun.inf");
+ struct qstr q__android_secure = QSTR_LITERAL(".android_secure");
+ struct qstr q_android_secure = QSTR_LITERAL("android_secure");
/* Always block security-sensitive files at root */
if (parent_node && SDCARDFS_I(parent_node)->perm == PERM_ROOT) {
- if (!strcasecmp(name, "autorun.inf")
- || !strcasecmp(name, ".android_secure")
- || !strcasecmp(name, "android_secure")) {
+ if (qstr_case_eq(name, &q_autorun)
+ || qstr_case_eq(name, &q__android_secure)
+ || qstr_case_eq(name, &q_android_secure)) {
return 0;
}
}
@@ -193,7 +195,7 @@ static int insert_packagelist_appid_entry_locked(const struct qstr *key, appid_t
unsigned int hash = key->hash;
hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name)) {
+ if (qstr_case_eq(key, &hash_cur->key)) {
atomic_set(&hash_cur->value, value);
return 0;
}
@@ -213,7 +215,7 @@ static int insert_ext_gid_entry_locked(const struct qstr *key, appid_t value)
/* An extension can only belong to one gid */
hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name))
+ if (qstr_case_eq(key, &hash_cur->key))
return -EINVAL;
}
new_entry = alloc_hashtable_entry(key, value);
@@ -232,7 +234,7 @@ static int insert_userid_exclude_entry_locked(const struct qstr *key, userid_t v
/* Only insert if not already present */
hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
if (atomic_read(&hash_cur->value) == value &&
- !strcasecmp(key->name, hash_cur->key.name))
+ qstr_case_eq(key, &hash_cur->key))
return 0;
}
new_entry = alloc_hashtable_entry(key, value);
@@ -336,13 +338,13 @@ static void remove_packagelist_entry_locked(const struct qstr *key)
HLIST_HEAD(free_list);
hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name)) {
+ if (qstr_case_eq(key, &hash_cur->key)) {
hash_del_rcu(&hash_cur->hlist);
hlist_add_head(&hash_cur->dlist, &free_list);
}
}
hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name)) {
+ if (qstr_case_eq(key, &hash_cur->key)) {
hash_del_rcu(&hash_cur->hlist);
hlist_add_head(&hash_cur->dlist, &free_list);
break;
@@ -368,7 +370,7 @@ static void remove_ext_gid_entry_locked(const struct qstr *key, gid_t group)
unsigned int hash = key->hash;
hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name) && atomic_read(&hash_cur->value) == group) {
+ if (qstr_case_eq(key, &hash_cur->key) && atomic_read(&hash_cur->value) == group) {
hash_del_rcu(&hash_cur->hlist);
synchronize_rcu();
free_hashtable_entry(hash_cur);
@@ -419,7 +421,7 @@ static void remove_userid_exclude_entry_locked(const struct qstr *key, userid_t
unsigned int hash = key->hash;
hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
- if (!strcasecmp(key->name, hash_cur->key.name) &&
+ if (qstr_case_eq(key, &hash_cur->key) &&
atomic_read(&hash_cur->value) == userid) {
hash_del_rcu(&hash_cur->hlist);
synchronize_rcu();
@@ -528,7 +530,7 @@ static ssize_t package_details_excluded_userids_show(struct config_item *item,
rcu_read_lock();
hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
- if (!strcasecmp(package_details->name.name, hash_cur->key.name))
+ if (qstr_case_eq(&package_details->name, &hash_cur->key))
count += scnprintf(page + count, PAGE_SIZE - count,
"%d ", atomic_read(&hash_cur->value));
}
@@ -757,7 +759,7 @@ static ssize_t packages_list_show(struct config_item *item, char *page)
hash_cur_app->key.name, atomic_read(&hash_cur_app->value));
hash = hash_cur_app->key.hash;
hash_for_each_possible_rcu(package_to_userid, hash_cur_user, hlist, hash) {
- if (!strcasecmp(hash_cur_app->key.name, hash_cur_user->key.name)) {
+ if (qstr_case_eq(&hash_cur_app->key, &hash_cur_user->key)) {
written += scnprintf(page + count + written - 1,
PAGE_SIZE - sizeof(errormsg) - count - written + 1,
" %d\n", atomic_read(&hash_cur_user->value)) - 1;
diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h
index 03da961e3b09..f3cced313108 100644
--- a/fs/sdcardfs/sdcardfs.h
+++ b/fs/sdcardfs/sdcardfs.h
@@ -459,7 +459,7 @@ extern struct list_head sdcardfs_super_list;
extern appid_t get_appid(const char *app_name);
extern appid_t get_ext_gid(const char *app_name);
extern appid_t is_excluded(const char *app_name, userid_t userid);
-extern int check_caller_access_to_name(struct inode *parent_node, const char* name);
+extern int check_caller_access_to_name(struct inode *parent_node, const struct qstr* name);
extern int open_flags_to_access_mode(int open_flags);
extern int packagelist_init(void);
extern void packagelist_exit(void);
@@ -477,7 +477,7 @@ struct limit_search {
extern void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid,
uid_t uid, bool under_android, struct inode *top);
extern void get_derived_permission(struct dentry *parent, struct dentry *dentry);
-extern void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, const char *name);
+extern void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, const struct qstr *name);
extern void drop_recursive(struct dentry *parent);
extern void fixup_top_recursive(struct dentry *parent);
extern void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit);
@@ -605,4 +605,17 @@ static inline void sdcardfs_copy_and_fix_attrs(struct inode *dest, const struct
dest->i_flags = src->i_flags;
set_nlink(dest, src->i_nlink);
}
+
+static inline bool str_case_eq(const char *s1, const char *s2)
+{
+ return !strcasecmp(s1, s2);
+}
+
+static inline bool qstr_case_eq(const struct qstr *q1, const struct qstr *q2)
+{
+ return q1->len == q2->len && str_case_eq(q1->name, q2->name);
+}
+
+#define QSTR_LITERAL(string) QSTR_INIT(string, sizeof(string)-1)
+
#endif /* not _SDCARDFS_H_ */