All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
To: Kari Argillander <kari.argillander@gmail.com>
Cc: "linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
	"viro@zeniv.linux.org.uk" <viro@zeniv.linux.org.uk>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"pali@kernel.org" <pali@kernel.org>,
	"dsterba@suse.cz" <dsterba@suse.cz>,
	"aaptel@suse.com" <aaptel@suse.com>,
	"willy@infradead.org" <willy@infradead.org>,
	"rdunlap@infradead.org" <rdunlap@infradead.org>,
	"joe@perches.com" <joe@perches.com>,
	"mark@harmstone.com" <mark@harmstone.com>,
	"nborisov@suse.com" <nborisov@suse.com>,
	"linux-ntfs-dev@lists.sourceforge.net" 
	<linux-ntfs-dev@lists.sourceforge.net>,
	"anton@tuxera.com" <anton@tuxera.com>,
	"dan.carpenter@oracle.com" <dan.carpenter@oracle.com>,
	"hch@lst.de" <hch@lst.de>,
	"ebiggers@kernel.org" <ebiggers@kernel.org>,
	"andy.lavr@gmail.com" <andy.lavr@gmail.com>
Subject: RE: [PATCH v17 02/10] fs/ntfs3: Add initialization of super block
Date: Mon, 18 Jan 2021 09:35:05 +0000	[thread overview]
Message-ID: <750a0cef33f34c0989cacfb0bcd4ac5e@paragon-software.com> (raw)
In-Reply-To: <20210103195017.fim2msuzj3kup6rq@kari-VirtualBox>

From: Kari Argillander <kari.argillander@gmail.com>
Sent: Sunday, January 3, 2021 10:50 PM
> To: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
> Cc: linux-fsdevel@vger.kernel.org; viro@zeniv.linux.org.uk; linux-kernel@vger.kernel.org; pali@kernel.org; dsterba@suse.cz;
> aaptel@suse.com; willy@infradead.org; rdunlap@infradead.org; joe@perches.com; mark@harmstone.com; nborisov@suse.com;
> linux-ntfs-dev@lists.sourceforge.net; anton@tuxera.com; dan.carpenter@oracle.com; hch@lst.de; ebiggers@kernel.org;
> andy.lavr@gmail.com
> Subject: Re: [PATCH v17 02/10] fs/ntfs3: Add initialization of super block
> 
> On Thu, Dec 31, 2020 at 06:23:53PM +0300, Konstantin Komarov wrote:
> 
> > diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
> 
> > +int ntfs_loadlog_and_replay(struct ntfs_inode *ni, struct ntfs_sb_info *sbi)
> > +{
> > +	int err = 0;
> > +	struct super_block *sb = sbi->sb;
> > +	struct inode *inode = &ni->vfs_inode;
> > +	struct MFT_REF ref;
> > +
> > +	/* Check for 4GB */
> > +	if (inode->i_size >= 0x100000000ull) {
> > +		ntfs_err(sb, "$LogFile is too big");
> > +		err = -EINVAL;
> > +		goto out;
> > +	}
> > +
> > +	sbi->flags |= NTFS_FLAGS_LOG_REPLAYING;
> > +
> > +	ref.low = cpu_to_le32(MFT_REC_MFT);
> > +	ref.high = 0;
> > +	ref.seq = cpu_to_le16(1);
> > +
> > +	inode = ntfs_iget5(sb, &ref, NULL);
> > +
> > +	if (IS_ERR(inode))
> > +		inode = NULL;
> > +
> > +	if (!inode) {
> > +		/* Try to use mft copy */
> > +		u64 t64 = sbi->mft.lbo;
> > +
> > +		sbi->mft.lbo = sbi->mft.lbo2;
> > +		inode = ntfs_iget5(sb, &ref, NULL);
> > +		sbi->mft.lbo = t64;
> > +		if (IS_ERR(inode))
> > +			inode = NULL;
> > +	}
> > +
> > +	if (!inode) {
> > +		err = -EINVAL;
> > +		ntfs_err(sb, "Failed to load $MFT.");
> > +		goto out;
> > +	}
> > +
> > +	sbi->mft.ni = ntfs_i(inode);
> > +
> > +	err = ni_load_all_mi(sbi->mft.ni);
> > +	if (!err)
> > +		err = log_replay(ni);
> 
> We only get error from log_replay if
> 
> > +
> > +	iput(inode);
> > +	sbi->mft.ni = NULL;
> > +
> > +	sync_blockdev(sb->s_bdev);
> > +	invalidate_bdev(sb->s_bdev);
> > +
> > +	/* reinit MFT */
> > +	if (sbi->flags & NTFS_FLAGS_NEED_REPLAY) {
> > +		err = 0;
> > +		goto out;
> > +	}
> > +
> > +	if (sb_rdonly(sb))
> > +		goto out;
> 
> we get here. Is this a intentional? Probably but I'm just checking.
> 

Hi Kari! Thanks for your attention on our patches.
This may be indeed quite entangled, here are the cases needed to be
covered:
1) !err && !(sbi->flags & NTFS_FLAGS_NEED_REPLAY) - ok
2) err && !(sbi->flags & NTFS_FLAGS_NEED_REPLAY) - no memory,
  io error, etc on prepare to replay stage
3) !err && (sbi->flags & NTFS_FLAGS_NEED_REPLAY) -
  journal is not empty, storage is readonly or unsupported log version
4) err && (sbi->flags & NTFS_FLAGS_NEED_REPLAY) - no memory, io error,
  etc while replaying
Distinction is that, cases 2/3 lead to mount error every time, while
case 4 permits read-only mount.

> > diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
> 
> > +int ntfs_create_inode(struct inode *dir, struct dentry *dentry,
> > +		      const struct cpu_str *uni, umode_t mode, dev_t dev,
> > +		      const char *symname, u32 size, int excl,
> > +		      struct ntfs_fnd *fnd, struct inode **new_inode)
> > +{
> 
> > +#ifdef CONFIG_NTFS3_FS_POSIX_ACL
> 
> In Kconfig this is NTFS3_POSIX_ACL. This repeat every file.
> 

This is OK. You may refer to similar parts of ext4/btrfs sources as a
reference:
fs/ext4/Kconfig or fs/btrfs/Kconfig

> > +int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry)
> > +{
> > +	int err;
> > +	struct super_block *sb = dir->i_sb;
> > +	struct ntfs_sb_info *sbi = sb->s_fs_info;
> > +	struct inode *inode = d_inode(dentry);
> > +	struct ntfs_inode *ni = ntfs_i(inode);
> > +	const struct qstr *name = &dentry->d_name;
> > +	struct ntfs_inode *dir_ni = ntfs_i(dir);
> > +	struct ntfs_index *indx = &dir_ni->dir;
> > +	struct cpu_str *uni = NULL;
> > +	struct ATTR_FILE_NAME *fname;
> > +	u8 name_type;
> > +	struct ATTR_LIST_ENTRY *le;
> > +	struct MFT_REF ref;
> > +	bool is_dir = S_ISDIR(inode->i_mode);
> > +	struct INDEX_ROOT *dir_root;
> > +
> > +	dir_root = indx_get_root(indx, dir_ni, NULL, NULL);
> > +	if (!dir_root)
> > +		return -EINVAL;
> > +
> > +	ni_lock(ni);
> > +
> > +	if (is_dir && !dir_is_empty(inode)) {
> > +		err = -ENOTEMPTY;
> > +		goto out1;
> > +	}
> > +
> > +	if (ntfs_is_meta_file(sbi, inode->i_ino)) {
> > +		err = -EINVAL;
> > +		goto out1;
> > +	}
> > +
> > +	/* allocate PATH_MAX bytes */
> > +	uni = __getname();
> > +	if (!uni) {
> > +		err = -ENOMEM;
> > +		goto out1;
> > +	}
> > +
> > +	/* Convert input string to unicode */
> > +	err = ntfs_nls_to_utf16(sbi, name->name, name->len, uni, NTFS_NAME_LEN,
> > +				UTF16_HOST_ENDIAN);
> > +	if (err < 0)
> > +		goto out4;
> > +
> > +	le = NULL;
> 
> Little bit random place for this. Do we even need to NULL le.
> 

Thanks. Inititialization is moved to to the place where ni_fname_name
is being called.
> > +
> > +	/*mark rw ntfs as dirty. it will be cleared at umount*/
> > +	ntfs_set_state(sbi, NTFS_DIRTY_DIRTY);
> > +
> > +	/* find name in record */
> > +#ifdef NTFS3_64BIT_CLUSTER
> > +	ref.low = cpu_to_le32(dir->i_ino & 0xffffffff);
> > +	ref.high = cpu_to_le16(dir->i_ino >> 32);
> > +#else
> > +	ref.low = cpu_to_le32(dir->i_ino & 0xffffffff);
> > +	ref.high = 0;
> > +#endif
> > +	ref.seq = dir_ni->mi.mrec->seq;
> > +
> > +	fname = ni_fname_name(ni, uni, &ref, &le);
> 
> > diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
> 
> > +#ifdef CONFIG_PRINTK
> > +/*
> > + * Trace warnings/notices/errors
> > + * Thanks Joe Perches <joe@perches.com> for implementation
> > + */
> > +void ntfs_printk(const struct super_block *sb, const char *fmt, ...)
> > +{
> > +	struct va_format vaf;
> > +	va_list args;
> > +	int level;
> > +	struct ntfs_sb_info *sbi = sb->s_fs_info;
> > +
> > +	/*should we use different ratelimits for warnings/notices/errors? */
> > +	if (!___ratelimit(&sbi->msg_ratelimit, "ntfs3"))
> > +		return;
> > +
> > +	va_start(args, fmt);
> > +
> > +	level = printk_get_level(fmt);
> > +	vaf.fmt = printk_skip_level(fmt);
> > +	vaf.va = &args;
> > +	printk("%c%cntfs3: %s: %pV\n", KERN_SOH_ASCII, level, sb->s_id, &vaf);
> > +
> > +	va_end(args);
> > +}
> > +
> > +static char s_name_buf[512];
> > +static atomic_t s_name_buf_cnt = ATOMIC_INIT(1); // 1 means 'free s_name_buf'
> > +
> > +/* print warnings/notices/errors about inode using name or inode number */
> > +void ntfs_inode_printk(struct inode *inode, const char *fmt, ...)
> > +{
> > +	struct super_block *sb = inode->i_sb;
> > +	struct ntfs_sb_info *sbi = sb->s_fs_info;
> > +	char *name;
> > +	va_list args;
> > +	struct va_format vaf;
> > +	int level;
> > +
> > +	if (!___ratelimit(&sbi->msg_ratelimit, "ntfs3"))
> > +		return;
> > +
> > +	if (atomic_dec_and_test(&s_name_buf_cnt)) {
> > +		/* use static allocated buffer */
> > +		name = s_name_buf;
> > +	} else {
> > +		name = kmalloc(sizeof(s_name_buf), GFP_NOFS);
> > +	}
> > +
> > +	if (name) {
> > +		struct dentry *dentry = d_find_alias(inode);
> > +		const u32 name_len = ARRAY_SIZE(s_name_buf) - 1;
> > +
> > +		if (dentry) {
> > +			spin_lock(&dentry->d_lock);
> > +			snprintf(name, name_len, "%s", dentry->d_name.name);
> > +			spin_unlock(&dentry->d_lock);
> > +			dput(dentry);
> > +			name[name_len] = 0; /* to be sure*/
> > +		} else {
> > +			name[0] = 0;
> > +		}
> > +	}
> > +
> > +	va_start(args, fmt);
> > +
> > +	level = printk_get_level(fmt);
> > +	vaf.fmt = printk_skip_level(fmt);
> > +	vaf.va = &args;
> > +
> > +	printk("%c%cntfs3: %s: ino=%lx, \"%s\" %pV\n", KERN_SOH_ASCII, level,
> > +	       sb->s_id, inode->i_ino, name ? name : "", &vaf);
> > +
> > +	va_end(args);
> > +
> > +	atomic_inc(&s_name_buf_cnt);
> > +	if (name != s_name_buf)
> > +		kfree(name);
> > +}
> > +#endif
> 
> Should these be in debug.c or something? Atleast I do not see point why
> they are in super.c.
> 
Overall, the problem file name may be omitted, but it seems to be useful for
debug purposes. This code is placed into super.c because ntfs_printk is described there.

> > +static int __init init_ntfs_fs(void)
> > +{
> > +	int err;
> > +
> > +#ifdef NTFS3_INDEX_BINARY_SEARCH
> > +	pr_notice("ntfs3: +index binary search\n");
> > +#endif
> > +
> > +#ifdef NTFS3_CHECK_FREE_CLST
> > +	pr_notice("ntfs3: +check free clusters\n");
> > +#endif
> > +
> > +#if NTFS_LINK_MAX < 0xffff
> > +	pr_notice("ntfs3: max link count %u\n", NTFS_LINK_MAX);
> > +#endif
> > +
> > +#ifdef NTFS3_64BIT_CLUSTER
> > +	pr_notice("ntfs3: 64 bits per cluster\n");
> > +#else
> > +	pr_notice("ntfs3: 32 bits per cluster\n");
> > +#endif
> > +#ifdef CONFIG_NTFS3_LZX_XPRESS
> > +	pr_notice("ntfs3: read-only lzx/xpress compression included\n");
> > +#endif
> > +
> > +	ntfs_inode_cachep = kmem_cache_create(
> > +		"ntfs_inode_cache", sizeof(struct ntfs_inode), 0,
> > +		(SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD | SLAB_ACCOUNT),
> > +		init_once);
> > +	if (!ntfs_inode_cachep) {
> > +		err = -ENOMEM;
> > +		goto failed;
> > +	}
> > +
> > +	err = register_filesystem(&ntfs_fs_type);
> > +	if (!err)
> > +		return 0;
> 
> Do we need kmem_cache_destroy() here if err?
> 
Thanks, this will be fixed in v18.
> > +
> > +failed:
> > +	return err;
> > +}

  reply	other threads:[~2021-01-18 11:15 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-31 15:23 [PATCH v17 00/10] NTFS read-write driver GPL implementation by Paragon Software Konstantin Komarov
2020-12-31 15:23 ` [PATCH v17 01/10] fs/ntfs3: Add headers and misc files Konstantin Komarov
2021-01-03 23:17   ` Kari Argillander
2021-01-19 10:43     ` Dan Carpenter
2021-01-19 20:34       ` Kari Argillander
2020-12-31 15:23 ` [PATCH v17 02/10] fs/ntfs3: Add initialization of super block Konstantin Komarov
2021-01-03 19:50   ` Kari Argillander
2021-01-18  9:35     ` Konstantin Komarov [this message]
2021-01-18 14:09       ` Kari Argillander
2021-01-19  4:03   ` Kari Argillander
2021-01-20  7:20     ` Kari Argillander
2020-12-31 15:23 ` [PATCH v17 03/10] fs/ntfs3: Add bitmap Konstantin Komarov
2020-12-31 15:23 ` [PATCH v17 04/10] fs/ntfs3: Add file operations and implementation Konstantin Komarov
2021-01-03 21:57   ` Kari Argillander
2021-01-03 22:04     ` Matthew Wilcox
2021-01-18 10:00     ` Konstantin Komarov
2021-01-18 14:24       ` Kari Argillander
2021-01-04  2:18   ` Matthew Wilcox
2020-12-31 15:23 ` [PATCH v17 05/10] fs/ntfs3: Add attrib operations Konstantin Komarov
2021-01-04  0:25   ` Kari Argillander
2021-01-18 12:01     ` Konstantin Komarov
2020-12-31 15:23 ` [PATCH v17 06/10] fs/ntfs3: Add compression Konstantin Komarov
2020-12-31 15:23 ` [PATCH v17 07/10] fs/ntfs3: Add NTFS journal Konstantin Komarov
2021-01-03 22:47   ` Kari Argillander
2020-12-31 15:23 ` [PATCH v17 08/10] fs/ntfs3: Add Kconfig, Makefile and doc Konstantin Komarov
2021-01-03 22:07   ` Kari Argillander
2021-01-18 11:43     ` Konstantin Komarov
2021-01-18 13:42       ` Mark Harmstone
2020-12-31 15:24 ` [PATCH v17 09/10] fs/ntfs3: Add NTFS3 in fs/Kconfig and fs/Makefile Konstantin Komarov
2020-12-31 15:24 ` [PATCH v17 10/10] fs/ntfs3: Add MAINTAINERS Konstantin Komarov
2021-01-03 20:01   ` Kari Argillander

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=750a0cef33f34c0989cacfb0bcd4ac5e@paragon-software.com \
    --to=almaz.alexandrovich@paragon-software.com \
    --cc=aaptel@suse.com \
    --cc=andy.lavr@gmail.com \
    --cc=anton@tuxera.com \
    --cc=dan.carpenter@oracle.com \
    --cc=dsterba@suse.cz \
    --cc=ebiggers@kernel.org \
    --cc=hch@lst.de \
    --cc=joe@perches.com \
    --cc=kari.argillander@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-ntfs-dev@lists.sourceforge.net \
    --cc=mark@harmstone.com \
    --cc=nborisov@suse.com \
    --cc=pali@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.