Signed-off-by: Alexander Holler <holler@xxxxxxxxxxxxx> --- fs/fat/fat.h | 1 + fs/fat/fatent.c | 20 ++++++++++++++++++++ fs/fat/inode.c | 13 +++++++++++++ 3 files changed, 34 insertions(+) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index e0c4ba3..b9febda 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -81,6 +81,7 @@ struct msdos_sb_info { unsigned int prev_free; /* previously allocated cluster number */ unsigned int free_clusters; /* -1 if undefined */ unsigned int free_clus_valid; /* is free_clusters valid? */ + atomic_t secure_delete; /* delete blocks securely? */ struct fat_mount_options options; struct nls_table *nls_disk; /* Codepage used on disk */ struct nls_table *nls_io; /* Charset used for input and display */ diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 260705c..b3b9c11 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -575,6 +575,10 @@ int fat_free_clusters(struct inode *inode, int cluster) goto error; } + // TODO: + // if (atomic_read(&sbi->secure_delete) && secure_trim_available) + // use secure trim + // else if (sbi->options.discard) { /* * Issue discard for the sectors we no longer @@ -591,6 +595,22 @@ int fat_free_clusters(struct inode *inode, int cluster) first_cl = cluster; } + } else if (atomic_read(&sbi->secure_delete)) { + /* + * Fill blocks with zero for the sectors we no + * longer care about, batching contiguous clusters + * into one request. + */ + if (cluster != fatent.entry + 1) { + int nr_clus = fatent.entry - first_cl + 1; + + sb_issue_zeroout(sb, + fat_clus_to_blknr(sbi, first_cl), + nr_clus * sbi->sec_per_clus, + GFP_NOFS); + + first_cl = cluster; + } } ops->ent_put(&fatent, FAT_ENT_FREE); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 756aead..9073690 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -816,6 +816,17 @@ int fat_sync_inode(struct inode *inode) EXPORT_SYMBOL_GPL(fat_sync_inode); +static void fat_set_secure_delete(struct super_block *sb, bool secure) +{ + struct msdos_sb_info *sbi = MSDOS_SB(sb); + // TODO: will overflow with a very large number of + // concurrent calls of unlinkat_s(). + if (secure) + atomic_inc(&sbi->secure_delete); + else + atomic_dec(&sbi->secure_delete); +} + static int fat_show_options(struct seq_file *m, struct dentry *root); static const struct super_operations fat_sops = { .alloc_inode = fat_alloc_inode, @@ -827,6 +838,7 @@ static const struct super_operations fat_sops = { .remount_fs = fat_remount, .show_options = fat_show_options, + .set_secure_delete = fat_set_secure_delete, }; static int fat_show_options(struct seq_file *m, struct dentry *root) @@ -1580,6 +1592,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sbi->root_cluster = 0; sbi->free_clusters = -1; /* Don't know yet */ sbi->free_clus_valid = 0; + atomic_set(&sbi->secure_delete, 0); sbi->prev_free = FAT_START_ENT; sb->s_maxbytes = 0xffffffff; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html