Skip to content

Commit

Permalink
kernfs: clean up struct kernfs_iattrs
Browse files Browse the repository at this point in the history
Right now, kernfs_iattrs embeds the whole struct iattr, even though it
doesn't really use half of its fields... This both leads to wasting
space and makes the code look awkward. Let's just list the few fields
we need directly in struct kernfs_iattrs.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
[PM: merged a number of chunks manually due to fuzz]
Signed-off-by: Paul Moore <paul@paul-moore.com>
  • Loading branch information
WOnder93 authored and pcmoore committed Mar 21, 2019
1 parent ccd19d4 commit 0589521
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 36 deletions.
10 changes: 4 additions & 6 deletions fs/kernfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,9 +795,8 @@ int kernfs_add_one(struct kernfs_node *kn)
/* Update timestamps on the parent */
ps_iattr = parent->iattr;
if (ps_iattr) {
struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
ktime_get_real_ts64(&ps_iattrs->ia_ctime);
ps_iattrs->ia_mtime = ps_iattrs->ia_ctime;
ktime_get_real_ts64(&ps_iattr->ia_ctime);
ps_iattr->ia_mtime = ps_iattr->ia_ctime;
}

mutex_unlock(&kernfs_mutex);
Expand Down Expand Up @@ -1329,9 +1328,8 @@ static void __kernfs_remove(struct kernfs_node *kn)

/* update timestamps on the parent */
if (ps_iattr) {
ktime_get_real_ts64(&ps_iattr->ia_iattr.ia_ctime);
ps_iattr->ia_iattr.ia_mtime =
ps_iattr->ia_iattr.ia_ctime;
ktime_get_real_ts64(&ps_iattr->ia_ctime);
ps_iattr->ia_mtime = ps_iattr->ia_ctime;
}

kernfs_put(pos);
Expand Down
47 changes: 20 additions & 27 deletions fs/kernfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
{
static DEFINE_MUTEX(iattr_mutex);
struct kernfs_iattrs *ret;
struct iattr *iattrs;

mutex_lock(&iattr_mutex);

Expand All @@ -45,16 +44,14 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
kn->iattr = kmem_cache_zalloc(kernfs_iattrs_cache, GFP_KERNEL);
if (!kn->iattr)
goto out_unlock;
iattrs = &kn->iattr->ia_iattr;

/* assign default attributes */
iattrs->ia_mode = kn->mode;
iattrs->ia_uid = GLOBAL_ROOT_UID;
iattrs->ia_gid = GLOBAL_ROOT_GID;
kn->iattr->ia_uid = GLOBAL_ROOT_UID;
kn->iattr->ia_gid = GLOBAL_ROOT_GID;

ktime_get_real_ts64(&iattrs->ia_atime);
iattrs->ia_mtime = iattrs->ia_atime;
iattrs->ia_ctime = iattrs->ia_atime;
ktime_get_real_ts64(&kn->iattr->ia_atime);
kn->iattr->ia_mtime = kn->iattr->ia_atime;
kn->iattr->ia_ctime = kn->iattr->ia_atime;

simple_xattrs_init(&kn->iattr->xattrs);
out_unlock:
Expand All @@ -66,29 +63,24 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
{
struct kernfs_iattrs *attrs;
struct iattr *iattrs;
unsigned int ia_valid = iattr->ia_valid;

attrs = kernfs_iattrs(kn);
if (!attrs)
return -ENOMEM;

iattrs = &attrs->ia_iattr;

if (ia_valid & ATTR_UID)
iattrs->ia_uid = iattr->ia_uid;
attrs->ia_uid = iattr->ia_uid;
if (ia_valid & ATTR_GID)
iattrs->ia_gid = iattr->ia_gid;
attrs->ia_gid = iattr->ia_gid;
if (ia_valid & ATTR_ATIME)
iattrs->ia_atime = iattr->ia_atime;
attrs->ia_atime = iattr->ia_atime;
if (ia_valid & ATTR_MTIME)
iattrs->ia_mtime = iattr->ia_mtime;
attrs->ia_mtime = iattr->ia_mtime;
if (ia_valid & ATTR_CTIME)
iattrs->ia_ctime = iattr->ia_ctime;
if (ia_valid & ATTR_MODE) {
umode_t mode = iattr->ia_mode;
iattrs->ia_mode = kn->mode = mode;
}
attrs->ia_ctime = iattr->ia_ctime;
if (ia_valid & ATTR_MODE)
kn->mode = iattr->ia_mode;
return 0;
}

Expand Down Expand Up @@ -171,14 +163,15 @@ static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
inode->i_ctime = current_time(inode);
}

static inline void set_inode_attr(struct inode *inode, struct iattr *iattr)
static inline void set_inode_attr(struct inode *inode,
struct kernfs_iattrs *attrs)
{
struct super_block *sb = inode->i_sb;
inode->i_uid = iattr->ia_uid;
inode->i_gid = iattr->ia_gid;
inode->i_atime = timespec64_trunc(iattr->ia_atime, sb->s_time_gran);
inode->i_mtime = timespec64_trunc(iattr->ia_mtime, sb->s_time_gran);
inode->i_ctime = timespec64_trunc(iattr->ia_ctime, sb->s_time_gran);
inode->i_uid = attrs->ia_uid;
inode->i_gid = attrs->ia_gid;
inode->i_atime = timespec64_trunc(attrs->ia_atime, sb->s_time_gran);
inode->i_mtime = timespec64_trunc(attrs->ia_mtime, sb->s_time_gran);
inode->i_ctime = timespec64_trunc(attrs->ia_ctime, sb->s_time_gran);
}

static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
Expand All @@ -191,7 +184,7 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
* kernfs_node has non-default attributes get them from
* persistent copy in kernfs_node.
*/
set_inode_attr(inode, &attrs->ia_iattr);
set_inode_attr(inode, attrs);
security_inode_notifysecctx(inode, attrs->ia_secdata,
attrs->ia_secdata_len);
}
Expand Down
6 changes: 5 additions & 1 deletion fs/kernfs/kernfs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
#include <linux/fs_context.h>

struct kernfs_iattrs {
struct iattr ia_iattr;
kuid_t ia_uid;
kgid_t ia_gid;
struct timespec64 ia_atime;
struct timespec64 ia_mtime;
struct timespec64 ia_ctime;
void *ia_secdata;
u32 ia_secdata_len;

Expand Down
4 changes: 2 additions & 2 deletions fs/kernfs/symlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
kgid_t gid = GLOBAL_ROOT_GID;

if (target->iattr) {
uid = target->iattr->ia_iattr.ia_uid;
gid = target->iattr->ia_iattr.ia_gid;
uid = target->iattr->ia_uid;
gid = target->iattr->ia_gid;
}

kn = kernfs_new_node(parent, name, S_IFLNK|S_IRWXUGO, uid, gid,
Expand Down

0 comments on commit 0589521

Please sign in to comment.