Skip to content

Commit

Permalink
fs: sdcardfs: port form exynos8895 4.4 kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
ananjaser1211 committed Oct 27, 2023
1 parent 8116daf commit 7637a32
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 140 deletions.
2 changes: 1 addition & 1 deletion fs/sdcardfs/p/dentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
goto out;

/* If our top's inode is gone, we may be out of date */
inode = igrab(dentry->d_inode);
inode = igrab(d_inode(dentry));
if (inode) {
data = top_data_get(SDCARDFS_I(inode));
if (!data || data->abandoned) {
Expand Down
74 changes: 38 additions & 36 deletions fs/sdcardfs/p/derived_perm.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,21 @@ static void inherit_derived_state(struct inode *parent, struct inode *child)
ci->data->under_android = pi->data->under_android;
ci->data->under_cache = pi->data->under_cache;
ci->data->under_obb = pi->data->under_obb;
set_top(ci, pi->top_data);

ci->data->under_knox = pi->data->under_knox;
}

/* helper function for derived state */
void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid,
uid_t uid, bool under_android,
struct sdcardfs_inode_data *top)
uid_t uid)
{
struct sdcardfs_inode_info *info = SDCARDFS_I(inode);

info->data->perm = perm;
info->data->userid = userid;
info->data->d_uid = uid;
info->data->under_android = under_android;
info->data->under_android = false;
info->data->under_cache = false;
info->data->under_obb = false;
set_top(info, top);

info->data->under_knox = false;
}

Expand All @@ -61,14 +56,15 @@ void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid,
void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
const struct qstr *name)
{
struct sdcardfs_inode_info *info = SDCARDFS_I(dentry->d_inode);
struct sdcardfs_inode_data *parent_data =
SDCARDFS_I(parent->d_inode)->data;
struct sdcardfs_inode_info *info = SDCARDFS_I(d_inode(dentry));
struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent));
struct sdcardfs_inode_data *parent_data = parent_info->data;
appid_t appid;
unsigned long user_num;
int err;
struct qstr q_Android = QSTR_LITERAL("Android");
struct qstr q_data = QSTR_LITERAL("data");
struct qstr q_sandbox = QSTR_LITERAL("sandbox");
struct qstr q_obb = QSTR_LITERAL("obb");
struct qstr q_media = QSTR_LITERAL("media");
struct qstr q_cache = QSTR_LITERAL("cache");
Expand All @@ -84,16 +80,18 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
* of using the inode permissions.
*/

inherit_derived_state(parent->d_inode, dentry->d_inode);
inherit_derived_state(d_inode(parent), d_inode(dentry));

/* Files don't get special labels */
if (!S_ISDIR(dentry->d_inode->i_mode))
if (!S_ISDIR(d_inode(dentry)->i_mode)) {
set_top(info, parent_info);
return;
}
/* Derive custom permissions based on parent and current node */
switch (parent_data->perm) {
case PERM_INHERIT:
case PERM_ANDROID_PACKAGE_CACHE:
/* Already inherited above */
set_top(info, parent_info);
break;
case PERM_PRE_ROOT:
/* Legacy internal layout places users at top level */
Expand All @@ -103,36 +101,37 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
info->data->userid = 0;
else
info->data->userid = user_num;
set_top(info, info->data);
break;
case PERM_ROOT:
/* Assume masked off by default. */
if (qstr_case_eq(name, &q_Android)) {
/* App-specific directories inside; let anyone traverse */
info->data->perm = PERM_ANDROID;
info->data->under_android = true;
set_top(info, info->data);
} else if (qstr_case_eq(name, &q_knox)) {
info->data->perm = PERM_KNOX_PRE_ROOT;
info->data->under_knox = true;
set_top(info, info->data);
} else {
set_top(info, parent_info);
}
break;
case PERM_ANDROID:
if (qstr_case_eq(name, &q_data)) {
/* App-specific directories inside; let anyone traverse */
info->data->perm = PERM_ANDROID_DATA;
set_top(info, info->data);
} else if (qstr_case_eq(name, &q_sandbox)) {
/* App-specific directories inside; let anyone traverse */
info->data->perm = PERM_ANDROID_DATA;
} else if (qstr_case_eq(name, &q_obb)) {
/* App-specific directories inside; let anyone traverse */
info->data->perm = PERM_ANDROID_OBB;
info->data->under_obb = true;
set_top(info, info->data);
/* Single OBB directory is always shared */
} else if (qstr_case_eq(name, &q_media)) {
/* App-specific directories inside; let anyone traverse */
info->data->perm = PERM_ANDROID_MEDIA;
set_top(info, info->data);
} else {
set_top(info, parent_info);
}
break;
case PERM_ANDROID_OBB:
Expand All @@ -143,13 +142,13 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
if (appid != 0 && !is_excluded(name->name, parent_data->userid))
info->data->d_uid =
multiuser_get_uid(parent_data->userid, appid);
set_top(info, info->data);
break;
case PERM_ANDROID_PACKAGE:
if (qstr_case_eq(name, &q_cache)) {
info->data->perm = PERM_ANDROID_PACKAGE_CACHE;
info->data->under_cache = true;
}
set_top(info, parent_info);
break;

/* KNOX */
Expand All @@ -160,20 +159,22 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
info->data->userid = 10; /* default container no. */
else
info->data->userid = user_num;
set_top(info, info->data);
break;
case PERM_KNOX_ROOT:
if (qstr_case_eq(name, &q_Android))
info->data->perm = PERM_KNOX_ANDROID;
set_top(info, parent_info);
break;
case PERM_KNOX_ANDROID:
if (qstr_case_eq(name, &q_data)) {
info->data->perm = PERM_KNOX_ANDROID_DATA;
set_top(info, parent_info);
} else if (qstr_case_eq(name, &q_shared)) {
info->data->perm = PERM_KNOX_ANDROID_SHARED;
info->data->d_uid =
multiuser_get_uid(parent_data->userid, 0);
set_top(info, info->data);
} else {
set_top(info, parent_info);
}
break;
case PERM_KNOX_ANDROID_DATA:
Expand All @@ -182,10 +183,10 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
if (appid != 0 && !is_excluded(name->name, parent_data->userid))
info->data->d_uid =
multiuser_get_uid(parent_data->userid, appid);
set_top(info, info->data);
break;
case PERM_KNOX_ANDROID_SHARED:
case PERM_KNOX_ANDROID_PACKAGE:
set_top(info, parent_info);
break;
}
}
Expand Down Expand Up @@ -226,7 +227,7 @@ void fixup_lower_ownership(struct dentry *dentry, const char *name)
if (!sbi->options.gid_derivation)
return;

info = SDCARDFS_I(dentry->d_inode);
info = SDCARDFS_I(d_inode(dentry));
info_d = info->data;
perm = info_d->perm;
if (info_d->under_obb) {
Expand Down Expand Up @@ -260,7 +261,7 @@ void fixup_lower_ownership(struct dentry *dentry, const char *name)
case PERM_ANDROID:
case PERM_ANDROID_DATA:
case PERM_ANDROID_MEDIA:
if (S_ISDIR(dentry->d_inode->i_mode))
if (S_ISDIR(d_inode(dentry)->i_mode))
gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW);
else
gid = multiuser_get_uid(info_d->userid, get_type(name));
Expand All @@ -286,8 +287,8 @@ void fixup_lower_ownership(struct dentry *dentry, const char *name)
}

sdcardfs_get_lower_path(dentry, &path);
inode = path.dentry->d_inode;
if (path.dentry->d_inode->i_gid.val != gid || path.dentry->d_inode->i_uid.val != uid) {
inode = d_inode(path.dentry);
if (d_inode(path.dentry)->i_gid.val != gid || d_inode(path.dentry)->i_uid.val != uid) {
retry_deleg:
newattrs.ia_valid = ATTR_GID | ATTR_UID | ATTR_FORCE;
newattrs.ia_uid = make_kuid(current_user_ns(), uid);
Expand Down Expand Up @@ -342,19 +343,19 @@ static void __fixup_perms_recursive(struct dentry *dentry, struct limit_search *
*/
WARN(depth > 3, "%s: Max expected depth exceeded!\n", __func__);
spin_lock_nested(&dentry->d_lock, depth);
if (!dentry->d_inode) {
if (!d_inode(dentry)) {
spin_unlock(&dentry->d_lock);
return;
}
info = SDCARDFS_I(dentry->d_inode);
info = SDCARDFS_I(d_inode(dentry));

if (needs_fixup(info->data->perm)) {
list_for_each_entry(child, &dentry->d_subdirs, d_child) {
spin_lock_nested(&child->d_lock, depth + 1);
if (!(limit->flags & BY_NAME) || qstr_case_eq(&child->d_name, &limit->name)) {
if (child->d_inode) {
if (d_inode(child)) {
get_derived_permission(dentry, child);
fixup_tmp_permissions(child->d_inode);
fixup_tmp_permissions(d_inode(child));
spin_unlock(&child->d_lock);
break;
}
Expand All @@ -379,7 +380,7 @@ inline void update_derived_permission_lock(struct dentry *dentry)
{
struct dentry *parent;

if (!dentry || !dentry->d_inode) {
if (!dentry || !d_inode(dentry)) {
pr_err("sdcardfs: %s: invalid dentry\n", __func__);
return;
}
Expand All @@ -394,18 +395,19 @@ inline void update_derived_permission_lock(struct dentry *dentry)
dput(parent);
}
}
fixup_tmp_permissions(dentry->d_inode);
fixup_tmp_permissions(d_inode(dentry));
}

int need_graft_path(struct dentry *dentry)
{
int ret = 0;
struct dentry *parent = dget_parent(dentry);
struct sdcardfs_inode_info *parent_info = SDCARDFS_I(parent->d_inode);
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->data->perm == PERM_ANDROID &&
if (!sbi->options.unshared_obb &&
parent_info->data->perm == PERM_ANDROID &&
qstr_case_eq(&dentry->d_name, &obb)) {

/* /Android/obb is the base obbpath of DERIVED_UNIFIED */
Expand Down Expand Up @@ -465,7 +467,7 @@ int is_base_obbpath(struct dentry *dentry)
{
int ret = 0;
struct dentry *parent = dget_parent(dentry);
struct sdcardfs_inode_info *parent_info = SDCARDFS_I(parent->d_inode);
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");

Expand Down
28 changes: 17 additions & 11 deletions fs/sdcardfs/p/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static ssize_t sdcardfs_read(struct file *file, char __user *buf,
err = vfs_read(lower_file, buf, count, ppos);
/* update our inode atime upon a successful lower read */
if (err >= 0)
fsstack_copy_attr_atime(dentry->d_inode,
fsstack_copy_attr_atime(d_inode(dentry),
file_inode(lower_file));

return err;
Expand All @@ -62,6 +62,7 @@ static ssize_t sdcardfs_write(struct file *file, const char __user *buf,
int err;
struct file *lower_file;
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = d_inode(dentry);

/* check disk space */
if (!check_min_free_space(dentry, count, 0)) {
Expand All @@ -73,10 +74,12 @@ static ssize_t sdcardfs_write(struct file *file, const char __user *buf,
err = vfs_write(lower_file, buf, count, ppos);
/* update our inode times+sizes upon a successful lower write */
if (err >= 0) {
fsstack_copy_inode_size(dentry->d_inode,
file_inode(lower_file));
fsstack_copy_attr_times(dentry->d_inode,
file_inode(lower_file));
if (sizeof(loff_t) > sizeof(long))
inode_lock(inode);
fsstack_copy_inode_size(inode, file_inode(lower_file));
fsstack_copy_attr_times(inode, file_inode(lower_file));
if (sizeof(loff_t) > sizeof(long))
inode_unlock(inode);
}

return err;
Expand All @@ -94,7 +97,7 @@ static int sdcardfs_readdir(struct file *file, struct dir_context *ctx)
err = iterate_dir(lower_file, ctx);
file->f_pos = lower_file->f_pos;
if (err >= 0) /* copy the atime */
fsstack_copy_attr_atime(dentry->d_inode,
fsstack_copy_attr_atime(d_inode(dentry),
file_inode(lower_file));
return err;
}
Expand Down Expand Up @@ -240,7 +243,7 @@ static int sdcardfs_open(struct inode *inode, struct file *file)
goto out_err;
}

if (!check_caller_access_to_name(parent->d_inode, &dentry->d_name)) {
if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
err = -EACCES;
goto out_err;
}
Expand Down Expand Up @@ -403,6 +406,7 @@ ssize_t sdcardfs_write_iter(struct kiocb *iocb, struct iov_iter *iter)
{
int err;
struct file *file = iocb->ki_filp, *lower_file;
struct inode *inode = file->f_path.dentry->d_inode;

lower_file = sdcardfs_lower_file(file);
if (!lower_file->f_op->write_iter) {
Expand All @@ -417,10 +421,12 @@ ssize_t sdcardfs_write_iter(struct kiocb *iocb, struct iov_iter *iter)
fput(lower_file);
/* update upper inode times/sizes as needed */
if (err >= 0 || err == -EIOCBQUEUED) {
fsstack_copy_inode_size(file->f_path.dentry->d_inode,
file_inode(lower_file));
fsstack_copy_attr_times(file->f_path.dentry->d_inode,
file_inode(lower_file));
if (sizeof(loff_t) > sizeof(long))
inode_lock(inode);
fsstack_copy_inode_size(inode, file_inode(lower_file));
fsstack_copy_attr_times(inode, file_inode(lower_file));
if (sizeof(loff_t) > sizeof(long))
inode_unlock(inode);
}
out:
return err;
Expand Down
Loading

0 comments on commit 7637a32

Please sign in to comment.