From: Miao Xie <miaoxie@huawei.com>
To: <linux-ext4@vger.kernel.org>
Cc: <miaoxie@huawei.com>, <tytso@mit.edu>, <lixi@ddn.com>,
<yi.zhang@huawei.com>, <adilger@dilger.ca>, <wshilong@ddn.com>,
<sihara@ddn.com>
Subject: [PATCH 4/4] ext4, project: expand inode extra size if possible
Date: Fri, 7 Jul 2017 01:09:53 +0800 [thread overview]
Message-ID: <1499360993-17130-4-git-send-email-miaoxie@huawei.com> (raw)
In-Reply-To: <1499360993-17130-1-git-send-email-miaoxie@huawei.com>
when upgrading from old format, try to set project id
to old file first time, it will return EOVERFLOW, but if
that file is dirtied(touch etc), changing project id will
be allowed, this might be confusing for users, we could
try to expand @i_extra_iszie here too.
Reported-by: Zhang Yi <yi.zhang@huawei.com>
Signed-off-by: Miao Xie <miaoxie@huawei.com>
Signed-off-by: Wang Shilong <wshilong@ddn.com>
---
fs/ext4/ext4_jbd2.h | 3 ++
fs/ext4/inode.c | 97 +++++++++++++++++++++++++++++++++++++++++------------
fs/ext4/ioctl.c | 9 +++--
3 files changed, 85 insertions(+), 24 deletions(-)
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index f976111..3149fdd 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -234,6 +234,9 @@ int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
+int ext4_expand_extra_isize(struct inode *inode,
+ unsigned int new_extra_isize,
+ struct ext4_iloc *iloc);
/*
* Wrapper functions with which ext4 calls into JBD.
*/
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 01a9340..41a353f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5628,6 +5628,42 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
return err;
}
+static int __ext4_expand_extra_isize(struct inode *inode,
+ unsigned int new_extra_isize,
+ struct ext4_iloc *iloc,
+ handle_t *handle, int *no_expand)
+{
+ struct ext4_inode *raw_inode;
+ struct ext4_xattr_ibody_header *header;
+ int error;
+
+ raw_inode = ext4_raw_inode(iloc);
+
+ header = IHDR(inode, raw_inode);
+
+ /* No extended attributes present */
+ if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
+ header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
+ memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
+ EXT4_I(inode)->i_extra_isize, 0,
+ new_extra_isize - EXT4_I(inode)->i_extra_isize);
+ EXT4_I(inode)->i_extra_isize = new_extra_isize;
+ return 0;
+ }
+
+ /* try to expand with EAs present */
+ error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
+ raw_inode, handle);
+ if (error) {
+ /*
+ * Inode size expansion failed; don't try again
+ */
+ *no_expand = 1;
+ }
+
+ return error;
+}
+
/*
* Expand an inode by new_extra_isize bytes.
* Returns 0 on success or negative error number on failure.
@@ -5637,8 +5673,6 @@ static int ext4_try_to_expand_extra_isize(struct inode *inode,
struct ext4_iloc iloc,
handle_t *handle)
{
- struct ext4_inode *raw_inode;
- struct ext4_xattr_ibody_header *header;
int no_expand;
int error;
@@ -5662,32 +5696,53 @@ static int ext4_try_to_expand_extra_isize(struct inode *inode,
if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
return -EBUSY;
- raw_inode = ext4_raw_inode(&iloc);
+ error = __ext4_expand_extra_isize(inode, new_extra_isize, &iloc,
+ handle, &no_expand);
+ ext4_write_unlock_xattr(inode, &no_expand);
- header = IHDR(inode, raw_inode);
+ return error;
+}
- /* No extended attributes present */
- if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
- header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
- memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
- EXT4_I(inode)->i_extra_isize, 0,
- new_extra_isize - EXT4_I(inode)->i_extra_isize);
- EXT4_I(inode)->i_extra_isize = new_extra_isize;
- ext4_write_unlock_xattr(inode, &no_expand);
- return 0;
+int ext4_expand_extra_isize(struct inode *inode,
+ unsigned int new_extra_isize,
+ struct ext4_iloc *iloc)
+{
+ handle_t *handle;
+ int no_expand;
+ int error, rc;
+
+ if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
+ brelse(iloc->bh);
+ return -EOVERFLOW;
}
- /* try to expand with EAs present */
- error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
- raw_inode, handle);
+ handle = ext4_journal_start(inode, EXT4_HT_INODE,
+ EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
+ if (IS_ERR(handle)) {
+ error = PTR_ERR(handle);
+ brelse(iloc->bh);
+ return error;
+ }
+
+ ext4_write_lock_xattr(inode, &no_expand);
+
+ BUFFER_TRACE(iloc.bh, "get_write_access");
+ error = ext4_journal_get_write_access(handle, iloc->bh);
if (error) {
- /*
- * Inode size expansion failed; don't try again
- */
- no_expand = 1;
+ brelse(iloc->bh);
+ goto out_stop;
}
- ext4_write_unlock_xattr(inode, &no_expand);
+ error = __ext4_expand_extra_isize(inode, new_extra_isize, iloc,
+ handle, &no_expand);
+
+ rc = ext4_mark_iloc_dirty(handle, inode, iloc);
+ if (!error)
+ error = rc;
+
+ ext4_write_unlock_xattr(inode, &no_expand);
+out_stop:
+ ext4_journal_stop(handle);
return error;
}
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 0c21e22..0120207 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -351,11 +351,14 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
raw_inode = ext4_raw_inode(&iloc);
if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
- err = -EOVERFLOW;
+ err = ext4_expand_extra_isize(inode,
+ EXT4_SB(sb)->s_want_extra_isize,
+ &iloc);
+ if (err)
+ goto out_unlock;
+ } else {
brelse(iloc.bh);
- goto out_unlock;
}
- brelse(iloc.bh);
dquot_initialize(inode);
--
2.5.0
next prev parent reply other threads:[~2017-07-06 8:41 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-06 17:09 [PATCH 1/4] ext4: fix forgetten xattr lock protection in ext4_expand_extra_isize Miao Xie
2017-07-06 17:09 ` [PATCH 2/4] ext4: restructure ext4_expand_extra_isize Miao Xie
2017-08-06 4:47 ` Theodore Ts'o
2017-07-06 17:09 ` [PATCH 3/4] ext4: cleanup ext4_expand_extra_isize_ea() Miao Xie
2017-08-06 4:56 ` Theodore Ts'o
2017-07-06 17:09 ` Miao Xie [this message]
2017-08-06 5:05 ` [PATCH 4/4] ext4, project: expand inode extra size if possible Theodore Ts'o
2017-07-13 12:55 ` [PATCH 1/4] ext4: fix forgetten xattr lock protection in ext4_expand_extra_isize Miao Xie
2017-07-13 13:04 ` Wang Shilong
2017-07-13 16:47 ` Theodore Ts'o
2017-08-06 4:28 ` Theodore Ts'o
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=1499360993-17130-4-git-send-email-miaoxie@huawei.com \
--to=miaoxie@huawei.com \
--cc=adilger@dilger.ca \
--cc=linux-ext4@vger.kernel.org \
--cc=lixi@ddn.com \
--cc=sihara@ddn.com \
--cc=tytso@mit.edu \
--cc=wshilong@ddn.com \
--cc=yi.zhang@huawei.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox