Re: [PATCH v2 05/13] exfat: add file operations

From: Nikolay Borisov
Date: Wed Nov 20 2019 - 04:14:36 EST




On 19.11.19 Ð. 9:10 Ñ., Namjae Jeon wrote:
> This adds the implementation of file operations for exfat.
>
> Signed-off-by: Namjae Jeon <namjae.jeon@xxxxxxxxxxx>
> Signed-off-by: Sungjong Seo <sj1557.seo@xxxxxxxxxxx>
> ---
> fs/exfat/file.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 346 insertions(+)
> create mode 100644 fs/exfat/file.c
>
> diff --git a/fs/exfat/file.c b/fs/exfat/file.c
> new file mode 100644
> index 000000000000..5afd65a36eb5
> --- /dev/null
> +++ b/fs/exfat/file.c
> @@ -0,0 +1,346 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
> + */
> +
> +#include <linux/slab.h>
> +#include <linux/cred.h>
> +#include <linux/buffer_head.h>
> +
> +#include "exfat_raw.h"
> +#include "exfat_fs.h"
> +

<snip>

> +
> +static int exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode)
> +{
> + mode_t allow_utime = sbi->options.allow_utime;
> +
> + if (!uid_eq(current_fsuid(), inode->i_uid)) {
> + if (in_group_p(inode->i_gid))
> + allow_utime >>= 3;
> + if (allow_utime & MAY_WRITE)
> + return 1;
> + }
> +
> + /* use a default check */
> + return 0;

this function can be made to return bool.

> +}
> +

<snip>

> +/* resize the file length */
> +int __exfat_truncate(struct inode *inode, loff_t new_size)
> +{
> + unsigned int num_clusters_new, num_clusters_phys;
> + unsigned int last_clu = FREE_CLUSTER;
> + struct exfat_chain clu;
> + struct exfat_timestamp tm;
> + struct exfat_dentry *ep, *ep2;
> + struct super_block *sb = inode->i_sb;
> + struct exfat_sb_info *sbi = EXFAT_SB(sb);
> + struct exfat_inode_info *ei = EXFAT_I(inode);
> + struct exfat_entry_set_cache *es = NULL;
> + int evict = (ei->dir.dir == DIR_DELETED) ? 1 : 0;
> +
> + /* check if the given file ID is opened */
> + if (ei->type != TYPE_FILE && ei->type != TYPE_DIR)
> + return -EPERM;
> +
> + exfat_set_vol_flags(sb, VOL_DIRTY);
> +
> + num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi);
> + num_clusters_phys =
> + EXFAT_B_TO_CLU_ROUND_UP(EXFAT_I(inode)->i_size_ondisk, sbi);
> +
> + exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags);
> +
> + if (new_size > 0) {
> + /*
> + * Truncate FAT chain num_clusters after the first cluster
> + * num_clusters = min(new, phys);
> + */
> + unsigned int num_clusters =
> + min(num_clusters_new, num_clusters_phys);
> +
> + /*
> + * Follow FAT chain
> + * (defensive coding - works fine even with corrupted FAT table
> + */
> + if (clu.flags == 0x03) {

That 0x03 is magic constant, better define actual flags and check
clu.flag == (FLAG1|FLAG2)

> + clu.dir += num_clusters;
> + clu.size -= num_clusters;
> + } else {
> + while (num_clusters > 0) {
> + last_clu = clu.dir;
> + if (exfat_get_next_cluster(sb, &(clu.dir)))
> + return -EIO;
> +
> + num_clusters--;
> + clu.size--;
> + }
> + }
> + } else {
> + ei->flags = 0x03;

again, magic constant.
> + ei->start_clu = EOF_CLUSTER;
> + }
> +
> + i_size_write(inode, new_size);
> +
> + if (ei->type == TYPE_FILE)
> + ei->attr |= ATTR_ARCHIVE;

<snip>