From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF994C7619A for ; Wed, 5 Apr 2023 11:42:50 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 800CB6B0072; Wed, 5 Apr 2023 07:42:50 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 78A1C900003; Wed, 5 Apr 2023 07:42:50 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6033D900002; Wed, 5 Apr 2023 07:42:50 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 4A41E6B0072 for ; Wed, 5 Apr 2023 07:42:50 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 27A65160FD4 for ; Wed, 5 Apr 2023 11:42:50 +0000 (UTC) X-FDA: 80647150500.05.A09DC59 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by imf18.hostedemail.com (Postfix) with ESMTP id 1C9A91C0005 for ; Wed, 5 Apr 2023 11:42:46 +0000 (UTC) Authentication-Results: imf18.hostedemail.com; dkim=pass header.d=suse.cz header.s=susede2_rsa header.b=KMPaH074; dkim=pass header.d=suse.cz header.s=susede2_ed25519 header.b=7fDrp4t4; dmarc=none; spf=pass (imf18.hostedemail.com: domain of jack@suse.cz designates 195.135.220.29 as permitted sender) smtp.mailfrom=jack@suse.cz ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1680694967; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Kx3+Og+BqjworQfE0Cgco0zEE9jQhWPtk2eUyIEG25I=; b=tAn4deJHqUGCHQNl8qwm3ZmnYBBdRyUUWMm06uAiZQOM9ZOAPxGGcrZZpM8jPAbyBmzu/c ROZL/tcZ7voDHl0PkcWuZdhV7epYm4WcfPWeNmiqEAZx/IkJoglALRff9jCYo6ug6Y4axQ +TfI9s5Ig3Oedpggtt3eDTJ9NrUMsy0= ARC-Authentication-Results: i=1; imf18.hostedemail.com; dkim=pass header.d=suse.cz header.s=susede2_rsa header.b=KMPaH074; dkim=pass header.d=suse.cz header.s=susede2_ed25519 header.b=7fDrp4t4; dmarc=none; spf=pass (imf18.hostedemail.com: domain of jack@suse.cz designates 195.135.220.29 as permitted sender) smtp.mailfrom=jack@suse.cz ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1680694967; a=rsa-sha256; cv=none; b=NGUD/DAG8Q354NuaV2yUzIX2s+Stic8xmwzlHQt7YS9vTmU6vcBQGEfr3E8UGUZQYrdw+E uvI+zmrO+yrkVJF8ypdagmm27SnKquI77kp1prOEeTzn2LXI2eMgzsUwj4PG887yf5Bo9i lTF6hPqXJcoKTn5sminwIywpnIoQssY= Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id AABDA1FD84; Wed, 5 Apr 2023 11:42:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1680694965; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Kx3+Og+BqjworQfE0Cgco0zEE9jQhWPtk2eUyIEG25I=; b=KMPaH074dFHBKxXJiv5UDB4WPI/iSbAXVIlo3jCMGkJyCwBgVQW1aHSTSd20gfMb69/U4P z5F15mP1kBixdvS8PMy5xJFt9DLmUAwm5vglvMZdp/2eztQVaAyiynfsBku5I18kAAXSWI oxLv3+fIEsP4zYxclOcU7WNq6RfhoRo= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1680694965; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Kx3+Og+BqjworQfE0Cgco0zEE9jQhWPtk2eUyIEG25I=; b=7fDrp4t4F3np8uaMTCjV+A2SiNccZbq+gl2f76FtZUckb2G8vvSZO/MzTEihHqZadTI/Ng AjidqYstPf6CxACg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 9A73C13A31; Wed, 5 Apr 2023 11:42:45 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ZpqpJbVeLWTrLAAAMHmgww (envelope-from ); Wed, 05 Apr 2023 11:42:45 +0000 Received: by quack3.suse.cz (Postfix, from userid 1000) id 0FE9FA0729; Wed, 5 Apr 2023 13:42:45 +0200 (CEST) Date: Wed, 5 Apr 2023 13:42:45 +0200 From: Jan Kara To: cem@kernel.org Cc: hughd@google.com, jack@suse.cz, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, djwong@kernel.org Subject: Re: [PATCH 5/6] shmem: quota support Message-ID: <20230405114245.nnzorjm5nlr4l4g6@quack3> References: <20230403084759.884681-1-cem@kernel.org> <20230403084759.884681-6-cem@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20230403084759.884681-6-cem@kernel.org> X-Rspamd-Queue-Id: 1C9A91C0005 X-Rspamd-Server: rspam09 X-Rspam-User: X-Stat-Signature: bnmfi8oeojkap6cr41my8ufkdtr5ur6w X-HE-Tag: 1680694966-791965 X-HE-Meta: U2FsdGVkX18jWeiEHCmGXdj2fQF9xiQVfxquCvzKmscwrkN8LkPUEmomqIeEA8sscvSmh/+O/UMXpXDyhn14vZtT5UXfp0zN3a12Q5ff4899ScWyJ+d+3kvgq0PHYQUhToyapTtFfKeAPNTo1Mw4t7wjj2fjruKKMq/dcYsc9VNLk3Hs4Rh3lbv+U6xNuJ0V/UM7Xm0jWXfkiElJy8GJpD+TNjRvb5TVhakkwlgAt83NZMYPo5TBQEm5nMhrIJOMRHcSbxyKy0W+a4VMTSN+XE8Mt54GK0H1mWSWRs/DucBwy4JxKVQDX4suNOI24DHa1nJcF9e7aDJJHeyAvhY6UZe40bpt0OvvvzHhRmC53baOvLx88mllYxXg/GZ7iSs39qdoAzltyNKwEDbhMo3GW484kQkJNjnqDZFVYtnJkmXUJ7X5h6Lr7b4SlQw0FyCTIVYUfJ2lRFYSOv1cemkptz0nn1f9cNGsWKpZ4cMrvqLrMLfwncDYcZZyvABYKAfHQy26oXNJxlNIXejzodUmEYYU64MIhIC+kRhkP/e44Dq0Zqk1woCjFWgOZOXzaWPKMoyJhfRucONika+T0GkiOoEmDcspiR2g2F+2lNMeSJUETD1WJ/SbLu2GAINTdODoU2L5J3kfPJIKMqMn7A3TC1jtGEikdHFTpCF+O7JfreqKg3mXk96ayp9oQmLV1eGu+EpcMxYv97YqxhZhMvCYbApJ2m81MrqDYDyH5haEkEWJ006s2+GsZEfLVyAmNB7NWrtlI1TnZC5+w6xwbEeQcXl+beqPn3pg1HCSbF2RqcnhcyHyAq5tgH6uLmNXFvQbH2TaANfcR/Bl659efzv07h0k+6ThyXKfowfUf4Y9av7FUBBVttb7fRnRllrTtPxxlt71L85iuR+Kuh8K0pj7QeHgiiE+bYbI79fxKaWaHEciNBvvlEGzR1si++4s+0bY1JHY2M3h2O2TBTVKzUw fnfQYbOP b4j4RfGT67Qkbh2frxz/7+PyM8yrnd6o6sDvxNSekHF0o1IYfJ+Nh1hbj7Fww83/bhlLsn5pl5eXg+oh/JmiGyLjVACQWXNy8cq3RYzzYAcyIrwh4bvPV49k4RSMFloJvc4AKboD4dactS1UcLCcb22rA1xsSIz8NLo6M314RBJm/qKVrmAyXyDbR59MyQv0F7Tr7xR9xnD3r25Jx1Chp5jrYap7yX398EK6GfKhfGLw9z7pFVLB2h44BHfJIpEeS4vVgg/m0nsWZan5vqyD1Xg3CUNTVo/bIr1UNAcuxbU4mOXLEAUlAB5r7GKCxKvWe+SwlR/HzKoZ8HmqMvvC8ggcTCC8J1TvYlqOk X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Mon 03-04-23 10:47:58, cem@kernel.org wrote: > From: Lukas Czerner > > Now the basic infra-structure is in place, enable quota support for tmpfs. > > Signed-off-by: Lukas Czerner > Signed-off-by: Carlos Maiolino Some comments below... > diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h > index cf38381bdb4c1..3e7e18726feb5 100644 > --- a/include/linux/shmem_fs.h > +++ b/include/linux/shmem_fs.h > @@ -26,6 +26,9 @@ struct shmem_inode_info { > atomic_t stop_eviction; /* hold when working on inode */ > struct timespec64 i_crtime; /* file creation time */ > unsigned int fsflags; /* flags for FS_IOC_[SG]ETFLAGS */ > +#ifdef CONFIG_TMPFS_QUOTA > + struct dquot *i_dquot[MAXQUOTAS]; > +#endif > struct inode vfs_inode; > }; > > @@ -171,4 +174,10 @@ extern int shmem_mfill_atomic_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd, > #define SHMEM_QUOTA_MAX_SPC_LIMIT 0x7fffffffffffffffLL /* 2^63-1 */ > #define SHMEM_QUOTA_MAX_INO_LIMIT 0x7fffffffffffffffLL > > +#ifdef CONFIG_TMPFS_QUOTA > +#define SHMEM_MAXQUOTAS 2 You have this definition already in mm/shmem_quota.c. > +extern const struct dquot_operations shmem_quota_operations; > +extern struct quota_format_type shmem_quota_format; > +#endif /* CONFIG_TMPFS_QUOTA */ > + > #endif > diff --git a/mm/shmem.c b/mm/shmem.c > index 88e13930fc013..d7529c883eaf5 100644 > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -79,6 +79,7 @@ static struct vfsmount *shm_mnt; > #include > #include > #include > +#include > > #include > > @@ -116,10 +117,12 @@ struct shmem_options { > bool full_inums; > int huge; > int seen; > + unsigned short quota_types; > #define SHMEM_SEEN_BLOCKS 1 > #define SHMEM_SEEN_INODES 2 > #define SHMEM_SEEN_HUGE 4 > #define SHMEM_SEEN_INUMS 8 > +#define SHMEM_SEEN_QUOTA 16 > }; > > #ifdef CONFIG_TMPFS > @@ -211,8 +214,11 @@ static inline int shmem_inode_acct_block(struct inode *inode, long pages) > if (percpu_counter_compare(&sbinfo->used_blocks, > sbinfo->max_blocks - pages) > 0) > goto unacct; > + if ((err = dquot_alloc_block_nodirty(inode, pages)) != 0) > + goto unacct; We generally try to avoid assignments in conditions so I'd do: err = dquot_alloc_block_nodirty(inode, pages); if (err) goto unacct; > percpu_counter_add(&sbinfo->used_blocks, pages); > - } > + } else if ((err = dquot_alloc_block_nodirty(inode, pages)) != 0) > + goto unacct; > The same here... > @@ -1133,6 +1179,15 @@ static int shmem_setattr(struct mnt_idmap *idmap, > } > } > > + /* Transfer quota accounting */ > + if (i_uid_needs_update(idmap, attr, inode) || > + i_gid_needs_update(idmap, attr,inode)) { > + error = dquot_transfer(idmap, inode, attr); > + > + if (error) > + return error; > + } > + I think you also need to add: if (is_quota_modification(idmap, inode, attr)) { error = dquot_initialize(inode); if (error) return error; } to shmem_setattr(). > setattr_copy(idmap, inode, attr); > if (attr->ia_valid & ATTR_MODE) > error = posix_acl_chmod(idmap, dentry, inode->i_mode); > @@ -1178,7 +1233,9 @@ static void shmem_evict_inode(struct inode *inode) > simple_xattrs_free(&info->xattrs); > WARN_ON(inode->i_blocks); > shmem_free_inode(inode->i_sb); > + dquot_free_inode(inode); > clear_inode(inode); > + dquot_drop(inode); > } > > static int shmem_find_swap_entries(struct address_space *mapping, > @@ -1975,7 +2032,6 @@ static int shmem_get_folio_gfp(struct inode *inode, pgoff_t index, > > spin_lock_irq(&info->lock); > info->alloced += folio_nr_pages(folio); > - inode->i_blocks += (blkcnt_t)BLOCKS_PER_PAGE << folio_order(folio); > shmem_recalc_inode(inode); > spin_unlock_irq(&info->lock); > alloced = true; > @@ -2346,9 +2402,10 @@ static void shmem_set_inode_flags(struct inode *inode, unsigned int fsflags) > #define shmem_initxattrs NULL > #endif > > -static struct inode *shmem_get_inode(struct mnt_idmap *idmap, struct super_block *sb, > - struct inode *dir, umode_t mode, dev_t dev, > - unsigned long flags) > +static struct inode *shmem_get_inode_noquota(struct mnt_idmap *idmap, > + struct super_block *sb, > + struct inode *dir, umode_t mode, > + dev_t dev, unsigned long flags) > { > struct inode *inode; > struct shmem_inode_info *info; > @@ -2422,6 +2479,37 @@ static struct inode *shmem_get_inode(struct mnt_idmap *idmap, struct super_block > return inode; > } > > +static struct inode *shmem_get_inode(struct mnt_idmap *idmap, > + struct super_block *sb, struct inode *dir, > + umode_t mode, dev_t dev, unsigned long flags) > +{ > + int err; > + struct inode *inode; > + > + inode = shmem_get_inode_noquota(idmap, sb, dir, mode, dev, flags); > + if (IS_ERR(inode)) > + return inode; > + > + err = dquot_initialize(inode); > + if (err) > + goto errout; > + > + err = dquot_alloc_inode(inode); > + if (err) { > + dquot_drop(inode); > + goto errout; > + } > + return inode; > + > +errout: > + inode->i_flags |= S_NOQUOTA; > + iput(inode); > + shmem_free_inode(sb); I think shmem_free_inode() is superfluous here. iput() above should already unaccount the inode... > + if (err) How could err be possibly unset here? > + return ERR_PTR(err); > + return NULL; > +} > + > @@ -3582,6 +3679,18 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) > ctx->full_inums = true; > ctx->seen |= SHMEM_SEEN_INUMS; > break; > + case Opt_quota: > + ctx->seen |= SHMEM_SEEN_QUOTA; > + ctx->quota_types |= (QTYPE_MASK_USR | QTYPE_MASK_GRP); > + break; > + case Opt_usrquota: > + ctx->seen |= SHMEM_SEEN_QUOTA; > + ctx->quota_types |= QTYPE_MASK_USR; > + break; > + case Opt_grpquota: > + ctx->seen |= SHMEM_SEEN_QUOTA; > + ctx->quota_types |= QTYPE_MASK_GRP; > + break; > } > return 0; > > @@ -3681,6 +3790,12 @@ static int shmem_reconfigure(struct fs_context *fc) > goto out; > } > > + if (ctx->seen & SHMEM_SEEN_QUOTA && > + !sb_any_quota_loaded(fc->root->d_sb)) { > + err = "Cannot enable quota on remount"; > + goto out; > + } > + > if (ctx->seen & SHMEM_SEEN_HUGE) > sbinfo->huge = ctx->huge; > if (ctx->seen & SHMEM_SEEN_INUMS) > @@ -3763,6 +3878,9 @@ static void shmem_put_super(struct super_block *sb) > { > struct shmem_sb_info *sbinfo = SHMEM_SB(sb); > > +#ifdef CONFIG_TMPFS_QUOTA > + shmem_disable_quotas(sb); > +#endif > free_percpu(sbinfo->ino_batch); > percpu_counter_destroy(&sbinfo->used_blocks); > mpol_put(sbinfo->mpol); > @@ -3841,6 +3959,17 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) > #endif > uuid_gen(&sb->s_uuid); > > +#ifdef CONFIG_TMPFS_QUOTA > + if (ctx->seen & SHMEM_SEEN_QUOTA) { > + sb->dq_op = &shmem_quota_operations; > + sb->s_qcop = &dquot_quotactl_sysfile_ops; > + sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; s_quota_types should rather be copied from ctx, shouldn't it? Or why is s_quota_types inconsistent with ctx->quota_types? Honza -- Jan Kara SUSE Labs, CR