Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
MRP-3408 osd-ldiskfs: pass uid/gid/xtime directly to ldiskfs
This patch changes ldiskfs API so that uid/gid/xtime can be
specified directly for a new inode.

With this change, __osd_object_create()->osd_attr_init()
can be almost a no-op for many cases.

Change-Id: I46060c50efe389f2835b61fd6b2f2084f0c808b0
Signed-off-by: Andrew Perepechko <andrew.perepecko@seagate.com>
Reviewed-on: http://es-gerrit.xyus.xyratex.com:8080/10374
Reviewed-by: Alexander Nikolaevich Boyko <alexander.boyko@seagate.com>
Reviewed-by: Alexander Zarochentsev <alexander.zarochentsev@seagate.com>
Tested-by: Jenkins
Tested-by: Elena V. Gryaznova <elena.gryaznova@seagate.com>
  • Loading branch information
Andrew Perepechko authored and Vitaly Fertman committed Oct 24, 2016
1 parent 17e1ed3 commit 7ab00b0
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 20 deletions.
160 changes: 160 additions & 0 deletions ldiskfs/kernel_patches/patches/rhel6.5/ext4-ialloc-uid-gid.patch
@@ -0,0 +1,160 @@
--- linux-stage.orig/fs/ext4/ialloc.c 2016-04-25 15:52:21.737760496 +0300
+++ linux-stage/fs/ext4/ialloc.c 2016-04-25 15:56:37.987901642 +0300
@@ -797,6 +797,9 @@ err_ret:
return retval;
}

+#define NEW_INODE_ATTRS (ATTR_UID | ATTR_GID | \
+ ATTR_ATIME | ATTR_CTIME | ATTR_MTIME)
+
/*
* There are two policies for allocating an inode. If the new inode is
* a directory, then a forward search is made for a block group with both
@@ -808,7 +808,8 @@ err_ret:
* group to find a free inode.
*/
struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
- const struct qstr *qstr, __u32 goal)
+ const struct qstr *qstr, __u32 goal,
+ struct iattr *attr)
{
struct super_block *sb;
struct buffer_head *inode_bitmap_bh = NULL;
@@ -827,6 +832,8 @@ struct inode *ext4_new_inode(handle_t
static int once = 1;
ldiskfs_group_t flex_group;

+ BUG_ON(attr && !((attr->ia_valid&NEW_INODE_ATTRS) == NEW_INODE_ATTRS));
+
/* Cannot create files in a deleted directory */
if (!dir || !dir->i_nlink)
return ERR_PTR(-EPERM);
@@ -994,22 +995,24 @@ got:
atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes);
}

- inode->i_uid = current_fsuid();
+ inode->i_uid = attr ? attr->ia_uid : current_fsuid();
if (test_opt(sb, GRPID))
inode->i_gid = dir->i_gid;
- else if (dir->i_mode & S_ISGID) {
+ else if (dir->i_mode & S_ISGID && attr == NULL) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
mode |= S_ISGID;
} else
- inode->i_gid = current_fsgid();
+ inode->i_gid = attr ? attr->ia_gid : current_fsgid();
inode->i_mode = mode;

inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
/* This is the optimal IO size (for stat), not the fs block size */
inode->i_blocks = 0;
- inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
- ext4_current_time(inode);
+ ei->i_crtime = ext4_current_time(inode);
+ inode->i_mtime = attr ? attr->ia_mtime : ei->i_crtime;
+ inode->i_atime = attr ? attr->ia_atime : ei->i_crtime;
+ inode->i_ctime = attr ? attr->ia_ctime : ei->i_crtime;

memset(ei->i_data, 0, sizeof(ei->i_data));
ei->i_dir_start_lookup = 0;
--- linux-stage.orig/fs/ext4/ext4.h 2016-04-25 16:06:13.271984889 +0300
+++ linux-stage/fs/ext4/ext4.h 2016-04-25 16:06:53.855716049 +0300
@@ -1869,7 +1869,8 @@ extern int ext4fs_dirhash(const char

/* ialloc.c */
extern struct inode *ext4_new_inode(handle_t *, struct inode *, int,
- const struct qstr *qstr, __u32 goal);
+ const struct qstr *qstr, __u32 goal,
+ struct iattr *attr);
extern void ext4_free_inode(handle_t *, struct inode *);
extern unsigned long ext4_find_reverse(struct super_block *);
extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
@@ -1970,7 +1971,8 @@ extern int ext4_orphan_del(handle_t *
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,
+ struct iattr *attr);
extern int ext4_add_entry(handle_t *handle, struct dentry *dentry,
struct inode *inode, struct htree_lock *lck);
extern int ext4_delete_entry(handle_t *handle, struct inode * dir,
--- linux-stage.orig/fs/ext4/migrate.c 2016-04-25 16:04:43.800580014 +0300
+++ linux-stage/fs/ext4/migrate.c 2016-04-25 16:04:50.808533269 +0300
@@ -491,7 +491,7 @@ int ext4_ext_migrate(struct inode *in
goal = (((inode->i_ino - 1) / ext4_INODES_PER_GROUP(inode->i_sb)) *
ext4_INODES_PER_GROUP(inode->i_sb)) + 1;
tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
- S_IFREG, 0, goal);
+ S_IFREG, 0, goal, NULL);
if (IS_ERR(tmp_inode)) {
retval = -ENOMEM;
ext4_journal_stop(handle);
--- linux-stage.orig/fs/ext4/xattr.c 2016-04-25 16:05:58.496082932 +0300
+++ linux-stage/fs/ext4/xattr.c 2016-04-25 16:06:06.360030741 +0300
@@ -725,7 +725,7 @@ ext4_xattr_inode_create(handle_t *han
* in the same group, or nearby one.
*/
ea_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
- S_IFREG|0600, NULL, inode->i_ino + 1);
+ S_IFREG|0600, NULL, inode->i_ino + 1, NULL);

if (!IS_ERR(ea_inode)) {
ea_inode->i_op = &ext4_file_inode_operations;
--- linux-stage.orig/fs/ext4/namei.c 2016-04-25 15:48:09.311726331 +0300
+++ linux-stage/fs/ext4/namei.c 2016-04-25 16:05:48.944146362 +0300
@@ -2373,12 +2373,12 @@ static unsigned ext4_dentry_goal(stru

/* 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, struct iattr *attr)
{
struct inode *inode;

- inode = ext4_new_inode(handle, dir, mode, 0,
- EXT4_SB(dir->i_sb)->s_inode_goal);
+ inode = ext4_new_inode(handle, dir, mode, 0,
+ EXT4_SB(dir->i_sb)->s_inode_goal, attr);
if (!IS_ERR(inode)) {
if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) {
#ifdef CONFIG_ext4_FS_XATTR
@@ -2420,7 +2420,7 @@ retry:
ext4_handle_sync(handle);

inode = ext4_new_inode(handle, dir, mode, &dentry->d_name,
- ext4_dentry_goal(dir->i_sb, dentry));
+ ext4_dentry_goal(dir->i_sb, dentry), NULL);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
inode->i_op = &ext4_file_inode_operations;
@@ -2455,7 +2455,7 @@ retry:
ext4_handle_sync(handle);

inode = ext4_new_inode(handle, dir, mode, &dentry->d_name,
- ext4_dentry_goal(dir->i_sb, dentry));
+ ext4_dentry_goal(dir->i_sb, dentry), NULL);
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, inode->i_mode, rdev);
@@ -2559,7 +2559,7 @@ retry:
ext4_handle_sync(handle);

inode = ext4_new_inode(handle, dir, S_IFDIR | mode, &dentry->d_name,
- ext4_dentry_goal(dir->i_sb, dentry));
+ ext4_dentry_goal(dir->i_sb, dentry), NULL);
err = PTR_ERR(inode);
if (IS_ERR(inode))
goto out_stop;
@@ -2959,7 +2959,8 @@ retry:
ext4_handle_sync(handle);

inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO,
- &dentry->d_name, ext4_dentry_goal(dir->i_sb, dentry));
+ &dentry->d_name, ext4_dentry_goal(dir->i_sb, dentry),
+ NULL);
err = PTR_ERR(inode);
if (IS_ERR(inode))
goto out_stop;
1 change: 1 addition & 0 deletions ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel6.5.series
Expand Up @@ -51,3 +51,4 @@ rhel6.3/ext4-speed-up-releasing-blocks-on-commit.patch
rhel6.3/ext4-notalloc_under_idatasem.patch
rhel6.5/export-write-super.patch
rhel6.5/ext4_s_max_ext_tree_depth.patch
rhel6.5/ext4-ialloc-uid-gid.patch
63 changes: 44 additions & 19 deletions lustre/osd-ldiskfs/osd_handler.c
Expand Up @@ -2031,7 +2031,7 @@ struct dentry *osd_child_dentry_get(const struct lu_env *env,

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 thandle *th, struct iattr *iattr)
{
int result;
struct osd_device *osd = osd_obj2dev(obj);
Expand All @@ -2055,11 +2055,11 @@ static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
if (hint && hint->dah_parent)
parent = hint->dah_parent;

inode = ldiskfs_create_inode(oth->ot_handle,
parent ? osd_dt_obj(parent)->oo_inode :
osd_sb(osd)->s_root->d_inode,
mode);
if (!IS_ERR(inode)) {
inode = ldiskfs_create_inode(oth->ot_handle,
parent ? osd_dt_obj(parent)->oo_inode :
osd_sb(osd)->s_root->d_inode,
mode, iattr);
if (!IS_ERR(inode)) {
/* Do not update file c/mtime in ldiskfs. */
inode->i_flags |= S_NOCMTIME;

Expand Down Expand Up @@ -2088,7 +2088,8 @@ static int osd_mkdir(struct osd_thread_info *info, struct osd_object *obj,
struct lu_attr *attr,
struct dt_allocation_hint *hint,
struct dt_object_format *dof,
struct thandle *th)
struct thandle *th,
struct iattr *iattr)
{
int result;
struct osd_thandle *oth;
Expand All @@ -2098,7 +2099,7 @@ static int osd_mkdir(struct osd_thread_info *info, struct osd_object *obj,

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, iattr);

return result;
}
Expand All @@ -2107,7 +2108,8 @@ static int osd_mk_index(struct osd_thread_info *info, struct osd_object *obj,
struct lu_attr *attr,
struct dt_allocation_hint *hint,
struct dt_object_format *dof,
struct thandle *th)
struct thandle *th,
struct iattr *iattr)
{
int result;
struct osd_thandle *oth;
Expand All @@ -2120,7 +2122,7 @@ static int osd_mk_index(struct osd_thread_info *info, struct osd_object *obj,
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, iattr);
if (result == 0) {
LASSERT(obj->oo_inode != NULL);
if (feat->dif_flags & DT_IND_VARKEY)
Expand All @@ -2144,29 +2146,34 @@ static int osd_mkreg(struct osd_thread_info *info, struct osd_object *obj,
struct lu_attr *attr,
struct dt_allocation_hint *hint,
struct dt_object_format *dof,
struct thandle *th)
struct thandle *th,
struct iattr *iattr)
{
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,
iattr);
}

static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
struct lu_attr *attr,
struct dt_allocation_hint *hint,
struct dt_object_format *dof,
struct thandle *th)
struct thandle *th,
struct iattr *iattr)
{
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,
iattr);
}

static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
struct lu_attr *attr,
struct dt_allocation_hint *hint,
struct dt_object_format *dof,
struct thandle *th)
struct thandle *th,
struct iattr *iattr)
{
umode_t mode = attr->la_mode & (S_IFMT | S_IALLUGO | S_ISVTX);
int result;
Expand All @@ -2176,7 +2183,7 @@ 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));

result = osd_mkfile(info, obj, mode, hint, th);
result = osd_mkfile(info, obj, mode, hint, th, iattr);
if (result == 0) {
LASSERT(obj->oo_inode != NULL);
/*
Expand All @@ -2194,7 +2201,7 @@ typedef int (*osd_obj_type_f)(struct osd_thread_info *, struct osd_object *,
struct lu_attr *,
struct dt_allocation_hint *hint,
struct dt_object_format *dof,
struct thandle *);
struct thandle *, struct iattr *);

static osd_obj_type_f osd_create_type_f(enum dt_format_type type)
{
Expand Down Expand Up @@ -2274,6 +2281,8 @@ static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj,
attr->la_valid = valid;
}

#define sec_to_ts(seconds) ((struct timespec) { .tv_sec = seconds })

/**
* Helper function for osd_object_create()
*
Expand All @@ -2287,13 +2296,28 @@ static int __osd_object_create(struct osd_thread_info *info,
{
int result;
__u32 umask;
struct iattr iattr;

/* we drop umask so that permissions we pass are not affected */
umask = current->fs->umask;
current->fs->umask = 0;

/* Only this combination of attrs is allowed by ldiskfs */
iattr.ia_valid = ATTR_UID | ATTR_GID |
ATTR_ATIME | ATTR_CTIME | ATTR_MTIME;
iattr.ia_uid = attr->la_valid & LA_UID ?
attr->la_uid : current_fsuid();
iattr.ia_gid = attr->la_valid & LA_GID ?
attr->la_gid : current_fsgid();
iattr.ia_atime = attr->la_valid & LA_ATIME ?
sec_to_ts(attr->la_atime) : CURRENT_TIME_SEC;
iattr.ia_ctime = attr->la_valid & LA_CTIME ?
sec_to_ts(attr->la_ctime) : CURRENT_TIME_SEC;
iattr.ia_mtime = attr->la_valid & LA_MTIME ?
sec_to_ts(attr->la_mtime) : CURRENT_TIME_SEC;

result = osd_create_type_f(dof->dof_type)(info, obj, attr, hint, dof,
th);
th, &iattr);
if (result == 0) {
osd_attr_init(info, obj, attr, dof);
osd_object_init0(obj);
Expand Down Expand Up @@ -2685,7 +2709,8 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env,

/* FIXME: Insert index api needs to know the mode of
* the remote object. Just use S_IFDIR for now */
local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, S_IFDIR);
local = ldiskfs_create_inode(oh->ot_handle, pobj->oo_inode, S_IFDIR,
NULL);
if (IS_ERR(local)) {
CERROR("%s: create local error %d\n", osd_name(osd),
(int)PTR_ERR(local));
Expand Down
3 changes: 2 additions & 1 deletion lustre/osd-ldiskfs/osd_oi.c
Expand Up @@ -133,7 +133,8 @@ static int osd_oi_index_create_one(struct osd_thread_info *info,
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);
Expand Down

0 comments on commit 7ab00b0

Please sign in to comment.