Currently, for object creation, initially uid/gid set as 0,
and then osd_quota_trasfer() is called to correct space accounting
for non-root users, function call is like:
|->osd_create
|->osd_create_type_f
|->osd_mkreg
|->ldiskfs_create_inode
|->ext4_new_inode() ->owner as NULL, create 0 as uid/gid
|->osd_attr_init
|->osd_quota_transfer ->which will change uid/gid again for above.
This is inefficient since osd_quota_transfer() is a more
heavy operations, we could just pass downer owner(uid,gid),
project quota will inherit from its' parents automatically
when creating inode.
Some distros ext4 still did not support passing @owner down,
that is (rhel6,sles11) we just added extra @owner arg in
ldiskfs_create_inode() to make build system happy, and we
could add similar support to older kernel if that is really needed.
Command:
$ salloc -N 32 --ntasks-per-node=24 mpirun -np 768 mdtest -n 2000
-F -u -d <mnt>
Without Patch:
Users Speed
root 175741.938 ops/sec
non-root 108631.673 ops/sec
Patched:
Users Speed
root 184775.286 ops/sec
non-root 185218.466 ops/sec
Patch improved ~80% for non-root users and we reached
same speed for both root and non-root users.
Change-Id: I57b0d2a6913268448c0ed90cfe76bd9f051b0b40
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Reviewed-on: https://review.whamcloud.com/34581
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Yang Sheng <ys@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 1d41eef..87b4ea3 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
-@@ -1778,6 +1778,13 @@ extern int ext4_orphan_add(handle_t *, s
+@@ -1825,6 +1825,14 @@ extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode * dir, int mode);
++ struct inode * dir, int mode,
++ uid_t *owner);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 * de_del,
+ struct buffer_head * bh);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 * de_del,
+ struct buffer_head * bh);
/* resize.c */
extern int ext4_group_add(struct super_block *sb,
/* resize.c */
extern int ext4_group_add(struct super_block *sb,
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 6433d87..0f3783b 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -24,6 +24,7 @@
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -24,6 +24,7 @@
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/jbd2.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/jbd2.h>
-@@ -1704,10 +1707,10 @@ cleanup:
+@@ -1691,10 +1692,10 @@ cleanup:
* ext4_delete_entry deletes a directory entry by merging it with the
* previous entry
*/
* ext4_delete_entry deletes a directory entry by merging it with the
* previous entry
*/
{
struct ext4_dir_entry_2 *de, *pde;
unsigned int blocksize = dir->i_sb->s_blocksize;
{
struct ext4_dir_entry_2 *de, *pde;
unsigned int blocksize = dir->i_sb->s_blocksize;
-@@ -1742,7 +1745,7 @@ static int ext4_delete_entry(handle_t *h
+@@ -1729,7 +1730,7 @@ static int ext4_delete_entry(handle_t *handle,
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
-@@ -1806,6 +1809,29 @@ static unsigned ext4_dentry_goal(struct
- return inum;
+@@ -1776,6 +1777,30 @@ static int ext4_add_nondir(handle_t *handle,
+ return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
-+struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode,
++ uid_t *owner)
+{
+ struct inode *inode;
+
+{
+ struct inode *inode;
+
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
-@@ -1882,44 +1908,32 @@ retry:
+@@ -1850,44 +1875,32 @@ retry:
+ struct ext4_dir_entry_2 * de;
unsigned int blocksize = dir->i_sb->s_blocksize;
- int err, retries = 0;
+ struct ext4_dir_entry_2 * de;
unsigned int blocksize = dir->i_sb->s_blocksize;
- int err, retries = 0;
- if (EXT4_DIR_LINK_MAX(dir))
- return -EMLINK;
- if (EXT4_DIR_LINK_MAX(dir))
- return -EMLINK;
-retry:
- handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
- EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-retry:
- handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
- EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
-@@ -1938,18 +1952,46 @@ retry:
+@@ -1906,18 +1919,46 @@ retry:
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
err = ext4_handle_dirty_metadata(handle, inode, dir_block);
if (err)
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
err = ext4_handle_dirty_metadata(handle, inode, dir_block);
if (err)
ext4_inc_count(handle, dir);
ext4_update_dx_flag(dir);
err = ext4_mark_inode_dirty(handle, dir);
ext4_inc_count(handle, dir);
ext4_update_dx_flag(dir);
err = ext4_mark_inode_dirty(handle, dir);
-@@ -1958,11 +2001,16 @@ out_clear_inode:
+@@ -1926,11 +1967,16 @@ out_clear_inode:
d_instantiate(dentry, inode);
unlock_new_inode(inode);
out_stop:
d_instantiate(dentry, inode);
unlock_new_inode(inode);
out_stop:
-Index: linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/ext4.h
-===================================================================
---- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/ext4.h
-+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/ext4.h
-@@ -2145,6 +2145,11 @@ extern int ext4_orphan_add(handle_t *, s
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index d4c79c12..8979e06b 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2222,6 +2222,12 @@ extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode *dir, int mode);
++ struct inode *dir, int mode,
++ uid_t *owner);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int search_dir(struct buffer_head *bh,
char *search_buf,
int buf_size,
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int search_dir(struct buffer_head *bh,
char *search_buf,
int buf_size,
-Index: linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/namei.c
-===================================================================
---- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/namei.c
-+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/namei.c
-@@ -2165,7 +2167,7 @@ int ext4_generic_delete_entry(handle_t *
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 1821d9a4..140163d3 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2176,7 +2176,7 @@ int ext4_generic_delete_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
-@@ -2206,7 +2208,7 @@ out:
+@@ -2216,7 +2216,7 @@ out:
ext4_std_error(dir->i_sb, err);
return err;
}
ext4_std_error(dir->i_sb, err);
return err;
}
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
-@@ -2253,6 +2255,28 @@ static int ext4_add_nondir(handle_t *han
+@@ -2263,6 +2263,29 @@ static int ext4_add_nondir(handle_t *handle,
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
-+struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode,
++ uid_t *owner)
+{
+ struct inode *inode;
+
+{
+ struct inode *inode;
+
-+ inode = ext4_new_inode(handle, dir, mode, NULL, 0, NULL);
++ inode = ext4_new_inode(handle, dir, mode, NULL, 0, owner);
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
-Index: linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/ext4.h
-===================================================================
---- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/ext4.h
-+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/ext4.h
-@@ -2145,6 +2145,11 @@ extern int ext4_orphan_add(handle_t *, s
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index fa0f45ae..8f89024e 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2239,6 +2239,12 @@ extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode *dir, int mode);
++ struct inode *dir, int mode,
++ uid_t *owner);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int search_dir(struct buffer_head *bh,
char *search_buf,
int buf_size,
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int search_dir(struct buffer_head *bh,
char *search_buf,
int buf_size,
-Index: linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/namei.c
-===================================================================
---- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/namei.c
-+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/namei.c
-@@ -2165,7 +2167,7 @@ int ext4_generic_delete_entry(handle_t *
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 8e265e61..77d0782c 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2176,7 +2176,7 @@ int ext4_generic_delete_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
-@@ -2206,7 +2208,7 @@ out:
+@@ -2216,7 +2216,7 @@ out:
ext4_std_error(dir->i_sb, err);
return err;
}
ext4_std_error(dir->i_sb, err);
return err;
}
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
-@@ -2253,6 +2255,28 @@ static int ext4_add_nondir(handle_t *han
+@@ -2263,6 +2263,29 @@ static int ext4_add_nondir(handle_t *handle,
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
-+struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode,
++ uid_t *owner)
+{
+ struct inode *inode;
+
+{
+ struct inode *inode;
+
-+ inode = ext4_new_inode(handle, dir, mode, NULL, 0, NULL);
++ inode = ext4_new_inode(handle, dir, mode, NULL, 0, owner);
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
----
- fs/ext4/ext4.h | 13 +++++
- fs/ext4/namei.c | 131 +++++++++++++++++++++++++++++++++++++-------------------
- 2 files changed, 101 insertions(+), 43 deletions(-)
-
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 986e058..344ed3a 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
-@@ -1895,6 +1895,13 @@ extern int ext4_orphan_add(handle_t *, s
+@@ -1879,6 +1879,14 @@ extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
extern int ext4_orphan_del(handle_t *, struct inode *);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode * dir, int mode);
++ struct inode * dir, int mode,
++ uid_t *owner);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 * de_del,
+ struct buffer_head * bh);
+extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 * de_del,
+ struct buffer_head * bh);
+extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir,
+ struct inode *inode);
/* resize.c */
extern int ext4_group_add(struct super_block *sb,
/* resize.c */
extern int ext4_group_add(struct super_block *sb,
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index cb049fe..2071f02 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -24,6 +24,7 @@
* Theodore Ts'o, 2002
*/
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -24,6 +24,7 @@
* Theodore Ts'o, 2002
*/
+#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/jbd2.h>
+#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/jbd2.h>
-@@ -1698,10 +1701,10 @@ cleanup:
+@@ -1688,10 +1689,10 @@ cleanup:
* ext4_delete_entry deletes a directory entry by merging it with the
* previous entry
*/
* ext4_delete_entry deletes a directory entry by merging it with the
* previous entry
*/
{
struct ext4_dir_entry_2 *de, *pde;
unsigned int blocksize = dir->i_sb->s_blocksize;
{
struct ext4_dir_entry_2 *de, *pde;
unsigned int blocksize = dir->i_sb->s_blocksize;
-@@ -1744,7 +1747,7 @@ static int ext4_delete_entry(handle_t *h
+@@ -1734,7 +1735,7 @@ static int ext4_delete_entry(handle_t *handle,
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
-@@ -1808,6 +1811,29 @@ static unsigned ext4_dentry_goal(struct
- return inum;
+@@ -1781,6 +1782,30 @@ static int ext4_add_nondir(handle_t *handle,
+ return err;
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
-+struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode,
++ uid_t *owner)
+{
+ struct inode *inode;
+
+{
+ struct inode *inode;
+
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
-@@ -1886,46 +1912,32 @@ retry:
+@@ -1857,46 +1882,32 @@ retry:
-static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+/* Initialize @inode as a subdirectory of @dir, and add the
+ * "." and ".." entries into the first directory block. */
-static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+/* Initialize @inode as a subdirectory of @dir, and add the
+ * "." and ".." entries into the first directory block. */
struct ext4_dir_entry_2 *de;
unsigned int blocksize = dir->i_sb->s_blocksize;
- int err, retries = 0;
struct ext4_dir_entry_2 *de;
unsigned int blocksize = dir->i_sb->s_blocksize;
- int err, retries = 0;
- if (EXT4_DIR_LINK_MAX(dir))
- return -EMLINK;
-
- dquot_initialize(dir);
- if (EXT4_DIR_LINK_MAX(dir))
- return -EMLINK;
-
- dquot_initialize(dir);
-retry:
- handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
- EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
- EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
if (IS_ERR(handle))
return PTR_ERR(handle);
-retry:
- handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
- EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
- EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb));
if (IS_ERR(handle))
return PTR_ERR(handle);
if (IS_DIRSYNC(dir))
ext4_handle_sync(handle);
if (IS_DIRSYNC(dir))
ext4_handle_sync(handle);
- inode = ext4_new_inode(handle, dir, S_IFDIR | mode,
- &dentry->d_name, 0);
- err = PTR_ERR(inode);
- inode = ext4_new_inode(handle, dir, S_IFDIR | mode,
- &dentry->d_name, 0);
- err = PTR_ERR(inode);
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
de = (struct ext4_dir_entry_2 *) dir_block->b_data;
de->inode = cpu_to_le32(inode->i_ino);
de->name_len = 1;
-@@ -1944,18 +1956,46 @@ retry:
+@@ -1915,18 +1926,46 @@ retry:
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
err = ext4_handle_dirty_metadata(handle, inode, dir_block);
if (err)
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
err = ext4_handle_dirty_metadata(handle, inode, dir_block);
if (err)
ext4_inc_count(handle, dir);
ext4_update_dx_flag(dir);
err = ext4_mark_inode_dirty(handle, dir);
ext4_inc_count(handle, dir);
ext4_update_dx_flag(dir);
err = ext4_mark_inode_dirty(handle, dir);
-@@ -1964,11 +2005,16 @@ out_clear_inode:
+@@ -1935,11 +1974,16 @@ out_clear_inode:
d_instantiate(dentry, inode);
unlock_new_inode(inode);
out_stop:
d_instantiate(dentry, inode);
unlock_new_inode(inode);
out_stop:
+ iput(inode);
+ goto out_stop;
}
+ iput(inode);
+ goto out_stop;
}
-Index: linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/ext4.h
-===================================================================
---- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/ext4.h
-+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/ext4.h
-@@ -2145,6 +2145,11 @@ extern int ext4_orphan_add(handle_t *, s
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index fcc2055..832da02 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2543,6 +2543,12 @@ extern int ext4_dirent_csum_verify(struct inode *inode,
struct ext4_dir_entry *dirent);
extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
+extern struct inode *ext4_create_inode(handle_t *handle,
struct ext4_dir_entry *dirent);
extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode *dir, int mode);
++ struct inode *dir, int mode,
++ uid_t *owner);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
- extern int search_dir(struct buffer_head *bh,
-Index: linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/namei.c
-===================================================================
---- linux-3.10.0-123.13.2.el7.x86_64.orig/fs/ext4/namei.c
-+++ linux-3.10.0-123.13.2.el7.x86_64/fs/ext4/namei.c
-@@ -2165,7 +2167,7 @@ int ext4_generic_delete_entry(handle_t *
+ extern int ext4_search_dir(struct buffer_head *bh,
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index cb35943..775925d 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2379,7 +2379,7 @@ int ext4_generic_delete_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
-@@ -2206,7 +2208,7 @@ out:
+@@ -2419,7 +2419,7 @@ out:
ext4_std_error(dir->i_sb, err);
return err;
}
ext4_std_error(dir->i_sb, err);
return err;
}
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
/*
* DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
* since this indicates that nlinks count was previously 1.
-@@ -2253,6 +2255,28 @@ static int ext4_add_nondir(handle_t *han
+@@ -2463,6 +2463,29 @@ static int ext4_add_nondir(handle_t *handle,
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
-+struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode,
++ uid_t *owner)
+{
+ struct inode *inode;
+
+{
+ struct inode *inode;
+
-+ inode = ext4_new_inode(handle, dir, mode, NULL, 0, NULL);
++ inode = ext4_new_inode(handle, dir, mode, NULL, 0, owner);
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
-Index: linux-4.15.0/fs/ext4/ext4.h
-===================================================================
---- linux-4.15.0.orig/fs/ext4/ext4.h
-+++ linux-4.15.0/fs/ext4/ext4.h
-@@ -2504,6 +2504,11 @@ extern int ext4_dirent_csum_verify(struc
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 91c73b231e58..e6c4550bbf0e 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2504,6 +2504,12 @@ extern int ext4_dirent_csum_verify(struct inode *inode,
struct ext4_dir_entry *dirent);
extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
+extern struct inode *ext4_create_inode(handle_t *handle,
struct ext4_dir_entry *dirent);
extern int ext4_orphan_add(handle_t *, struct inode *);
extern int ext4_orphan_del(handle_t *, struct inode *);
+extern struct inode *ext4_create_inode(handle_t *handle,
-+ struct inode *dir, int mode);
++ struct inode *dir, int mode,
++ uid_t *owner);
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
extern int ext4_search_dir(struct buffer_head *bh,
+extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
+ struct ext4_dir_entry_2 *de_del,
+ struct buffer_head *bh);
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
extern int ext4_search_dir(struct buffer_head *bh,
-Index: linux-4.15.0/fs/ext4/namei.c
-===================================================================
---- linux-4.15.0.orig/fs/ext4/namei.c
-+++ linux-4.15.0/fs/ext4/namei.c
-@@ -2360,7 +2360,7 @@ int ext4_generic_delete_entry(handle_t *
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 19e34b23ffe0..b9955ddb390a 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2360,7 +2360,7 @@ int ext4_generic_delete_entry(handle_t *handle,
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
struct inode *dir,
struct ext4_dir_entry_2 *de_del,
struct buffer_head *bh)
-@@ -2400,7 +2400,7 @@ out:
+@@ -2400,7 +2400,7 @@ static int ext4_delete_entry(handle_t *handle,
ext4_std_error(dir->i_sb, err);
return err;
}
ext4_std_error(dir->i_sb, err);
return err;
}
/*
* Set directory link count to 1 if nlinks > EXT4_LINK_MAX, or if nlinks == 2
* since this indicates that nlinks count was previously 1 to avoid overflowing
/*
* Set directory link count to 1 if nlinks > EXT4_LINK_MAX, or if nlinks == 2
* since this indicates that nlinks count was previously 1 to avoid overflowing
-@@ -2447,6 +2447,28 @@ static int ext4_add_nondir(handle_t *han
+@@ -2447,6 +2447,29 @@ static int ext4_add_nondir(handle_t *handle,
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
return err;
}
+ /* Return locked inode, then the caller can modify the inode's states/flags
+ * before others finding it. The caller should unlock the inode by itself. */
-+struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode)
++struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode,
++ uid_t *owner)
+{
+ struct inode *inode;
+
+{
+ struct inode *inode;
+
-+ inode = ext4_new_inode(handle, dir, mode, NULL, 0, NULL, 0);
++ inode = ext4_new_inode(handle, dir, mode, NULL, 0, owner, 0);
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
+ if (!IS_ERR(inode)) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
+#ifdef CONFIG_LDISKFS_FS_XATTR
static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
umode_t mode, struct dt_allocation_hint *hint,
static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
umode_t mode, struct dt_allocation_hint *hint,
+ struct thandle *th, struct lu_attr *attr)
{
int result;
struct osd_device *osd = osd_obj2dev(obj);
struct osd_thandle *oth;
struct dt_object *parent = NULL;
struct inode *inode;
{
int result;
struct osd_device *osd = osd_obj2dev(obj);
struct osd_thandle *oth;
struct dt_object *parent = NULL;
struct inode *inode;
+ uid_t owner[2] = {0, 0};
+
+ if (attr->la_valid & LA_UID)
+ owner[0] = attr->la_uid;
+ if (attr->la_valid & LA_GID)
+ owner[1] = attr->la_gid;
LINVRNT(osd_invariant(obj));
LASSERT(obj->oo_inode == NULL);
LINVRNT(osd_invariant(obj));
LASSERT(obj->oo_inode == NULL);
inode = ldiskfs_create_inode(oth->ot_handle,
parent ? osd_dt_obj(parent)->oo_inode :
osd_sb(osd)->s_root->d_inode,
inode = ldiskfs_create_inode(oth->ot_handle,
parent ? osd_dt_obj(parent)->oo_inode :
osd_sb(osd)->s_root->d_inode,
if (!IS_ERR(inode)) {
/* Do not update file c/mtime in ldiskfs. */
inode->i_flags |= S_NOCMTIME;
if (!IS_ERR(inode)) {
/* Do not update file c/mtime in ldiskfs. */
inode->i_flags |= S_NOCMTIME;
oth = container_of(th, struct osd_thandle, ot_super);
LASSERT(oth->ot_handle->h_transaction != NULL);
oth = container_of(th, struct osd_thandle, ot_super);
LASSERT(oth->ot_handle->h_transaction != NULL);
- result = osd_mkfile(info, obj, mode, hint, th);
+ result = osd_mkfile(info, obj, mode, hint, th, attr);
oth = container_of(th, struct osd_thandle, ot_super);
LASSERT(oth->ot_handle->h_transaction != NULL);
oth = container_of(th, struct osd_thandle, ot_super);
LASSERT(oth->ot_handle->h_transaction != NULL);
- result = osd_mkfile(info, obj, mode, hint, th);
+ result = osd_mkfile(info, obj, mode, hint, th, attr);
if (result == 0) {
LASSERT(obj->oo_inode != NULL);
if (feat->dif_flags & DT_IND_VARKEY)
if (result == 0) {
LASSERT(obj->oo_inode != NULL);
if (feat->dif_flags & DT_IND_VARKEY)
{
LASSERT(S_ISREG(attr->la_mode));
return osd_mkfile(info, obj, (attr->la_mode &
{
LASSERT(S_ISREG(attr->la_mode));
return osd_mkfile(info, obj, (attr->la_mode &
- (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th);
+ (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th,
+ attr);
}
static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
}
static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
{
LASSERT(S_ISLNK(attr->la_mode));
return osd_mkfile(info, obj, (attr->la_mode &
{
LASSERT(S_ISLNK(attr->la_mode));
return osd_mkfile(info, obj, (attr->la_mode &
- (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th);
+ (S_IFMT | S_IALLUGO | S_ISVTX)), hint, th,
+ attr);
}
static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
}
static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
LASSERT(S_ISCHR(mode) || S_ISBLK(mode) ||
S_ISFIFO(mode) || S_ISSOCK(mode));
LASSERT(S_ISCHR(mode) || S_ISBLK(mode) ||
S_ISFIFO(mode) || S_ISSOCK(mode));
- result = osd_mkfile(info, obj, mode, hint, th);
+ result = osd_mkfile(info, obj, mode, hint, th, attr);
if (result == 0) {
LASSERT(obj->oo_inode != NULL);
/*
if (result == 0) {
LASSERT(obj->oo_inode != NULL);
/*
oh = container_of(th, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle->h_transaction != NULL);
oh = container_of(th, struct osd_thandle, ot_super);
LASSERT(oh->ot_handle->h_transaction != NULL);
- local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type);
+ local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, type,
+ NULL);
if (IS_ERR(local)) {
CERROR("%s: create local error %d\n", osd_name(osd),
(int)PTR_ERR(local));
if (IS_ERR(local)) {
CERROR("%s: create local error %d\n", osd_name(osd),
(int)PTR_ERR(local));
if (IS_ERR(jh))
return PTR_ERR(jh);
if (IS_ERR(jh))
return PTR_ERR(jh);
- inode = ldiskfs_create_inode(jh, dir, (S_IFREG | S_IRUGO | S_IWUSR));
+ inode = ldiskfs_create_inode(jh, dir, (S_IFREG | S_IRUGO | S_IWUSR),
+ NULL);
if (IS_ERR(inode)) {
ldiskfs_journal_stop(jh);
return PTR_ERR(inode);
if (IS_ERR(inode)) {
ldiskfs_journal_stop(jh);
return PTR_ERR(inode);