summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Rosenberg <drosen@google.com>2018-07-06 16:24:27 -0700
committerDaniel Rosenberg <drosen@google.com>2018-11-06 03:22:22 +0000
commit1bdb20fcd45751bb7ec7b4399579ceb0d1fcc504 (patch)
tree4c58c36f4d6fd8f200cf3d0d28203bef61723210
parent3411c22ecc5a55b63e5b6314b02b0075830c32e3 (diff)
ANDROID: sdcardfs: Add option to drop unused dentries
This adds the nocache mount option, which will cause sdcardfs to always drop dentries that are not in use, preventing cached entries from holding on to lower dentries, which could cause strange behavior when bypassing the sdcardfs layer and directly changing the lower fs. Change-Id: I70268584a20b989ae8cfdd278a2e4fa1605217fb Signed-off-by: Daniel Rosenberg <drosen@google.com>
-rw-r--r--fs/sdcardfs/dentry.c7
-rw-r--r--fs/sdcardfs/main.c6
-rw-r--r--fs/sdcardfs/sdcardfs.h1
-rw-r--r--fs/sdcardfs/super.c2
4 files changed, 16 insertions, 0 deletions
diff --git a/fs/sdcardfs/dentry.c b/fs/sdcardfs/dentry.c
index 3795d2c26915..eb279de02ffb 100644
--- a/fs/sdcardfs/dentry.c
+++ b/fs/sdcardfs/dentry.c
@@ -123,6 +123,12 @@ out:
return err;
}
+/* 1 = delete, 0 = cache */
+static int sdcardfs_d_delete(const struct dentry *d)
+{
+ return SDCARDFS_SB(d->d_sb)->options.nocache ? 1 : 0;
+}
+
static void sdcardfs_d_release(struct dentry *dentry)
{
if (!dentry || !dentry->d_fsdata)
@@ -182,6 +188,7 @@ static void sdcardfs_canonical_path(const struct path *path,
const struct dentry_operations sdcardfs_ci_dops = {
.d_revalidate = sdcardfs_d_revalidate,
+ .d_delete = sdcardfs_d_delete,
.d_release = sdcardfs_d_release,
.d_hash = sdcardfs_hash_ci,
.d_compare = sdcardfs_cmp_ci,
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index 27ec726e7a46..ba52af8644cc 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -34,6 +34,7 @@ enum {
Opt_reserved_mb,
Opt_gid_derivation,
Opt_default_normal,
+ Opt_nocache,
Opt_err,
};
@@ -48,6 +49,7 @@ static const match_table_t sdcardfs_tokens = {
{Opt_gid_derivation, "derive_gid"},
{Opt_default_normal, "default_normal"},
{Opt_reserved_mb, "reserved_mb=%u"},
+ {Opt_nocache, "nocache"},
{Opt_err, NULL}
};
@@ -71,6 +73,7 @@ static int parse_options(struct super_block *sb, char *options, int silent,
/* by default, gid derivation is off */
opts->gid_derivation = false;
opts->default_normal = false;
+ opts->nocache = false;
*debug = 0;
@@ -128,6 +131,9 @@ static int parse_options(struct super_block *sb, char *options, int silent,
case Opt_default_normal:
opts->default_normal = true;
break;
+ case Opt_nocache:
+ opts->nocache = true;
+ break;
/* unknown option */
default:
if (!silent)
diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h
index 99227a07a8d6..57be4761d32b 100644
--- a/fs/sdcardfs/sdcardfs.h
+++ b/fs/sdcardfs/sdcardfs.h
@@ -198,6 +198,7 @@ struct sdcardfs_mount_options {
bool gid_derivation;
bool default_normal;
unsigned int reserved_mb;
+ bool nocache;
};
struct sdcardfs_vfsmount_options {
diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c
index cffcdb11cb8a..140696ed3ed3 100644
--- a/fs/sdcardfs/super.c
+++ b/fs/sdcardfs/super.c
@@ -311,6 +311,8 @@ static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m,
seq_puts(m, ",default_normal");
if (opts->reserved_mb != 0)
seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
+ if (opts->nocache)
+ seq_printf(m, ",nocache");
return 0;
};