summaryrefslogtreecommitdiff
path: root/fs/gfs2/inode.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-02-26 23:09:35 +0400
committerSteven Whitehouse <swhiteho@redhat.com>2013-04-08 11:40:17 +0400
commit28fb30275570e9397e551d6f8e3bfd78862ea79e (patch)
tree21ac75d577a0a8220531106b4048f77c6bab217d /fs/gfs2/inode.c
parentfd4b4e042c6aac980ccac0e829aa1378d2c17bd5 (diff)
downloadlinux-28fb30275570e9397e551d6f8e3bfd78862ea79e.tar.xz
GFS2: Remove gfs2_refresh_inode from inode creation path
The original method for creating inodes used in GFS2 was to fill out a buffer, with all the information, and then to read that buffer into the in-core inode, using gfs2_refresh_inode() The problem with this approach is that all the inode's fields need to be calculated ahead of time, and were stored in various variables making the code rather complicated. The new approach is simply to allocate the in-core inode earlier and fill in as many fields as possible ahead of time. These can then be used to initilise the on disk representation. The code has been working towards the point where it is possible to remove gfs2_refresh_inode() because all the fields are correctly initialised ahead of time. We've now reached that milestone, and have reversed the order of setting up the in core and on disk inodes. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r--fs/gfs2/inode.c79
1 files changed, 35 insertions, 44 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index df51557fc986..cb53b4ffc0d3 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -448,7 +448,6 @@ static void gfs2_init_dir(struct buffer_head *dibh,
static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
const char *symname, struct buffer_head **bhp)
{
- struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct gfs2_dinode *di;
struct buffer_head *dibh;
@@ -465,7 +464,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
di->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode));
di->di_nlink = 0;
di->di_size = cpu_to_be64(ip->i_inode.i_size);
- di->di_blocks = cpu_to_be64(1);
+ di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
di->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec);
di->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec);
@@ -473,33 +472,23 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
di->di_minor = cpu_to_be32(MINOR(ip->i_inode.i_rdev));
di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_no_addr);
di->di_generation = cpu_to_be64(ip->i_generation);
- di->di_flags = 0;
+ di->di_flags = cpu_to_be32(ip->i_diskflags);
di->__pad1 = 0;
di->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) ? GFS2_FORMAT_DE : 0);
- di->di_height = 0;
+ di->di_height = cpu_to_be16(ip->i_height);
di->__pad2 = 0;
di->__pad3 = 0;
- di->di_depth = 0;
- di->di_entries = 0;
+ di->di_depth = cpu_to_be16(ip->i_depth);
+ di->di_entries = cpu_to_be32(ip->i_entries);
memset(&di->__pad4, 0, sizeof(di->__pad4));
- di->di_eattr = 0;
+ di->di_eattr = cpu_to_be64(ip->i_eattr);
di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
di->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec);
di->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec);
memset(&di->di_reserved, 0, sizeof(di->di_reserved));
switch(ip->i_inode.i_mode & S_IFMT) {
- case S_IFREG:
- if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) ||
- gfs2_tune_get(sdp, gt_new_files_jdata))
- di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
- break;
case S_IFDIR:
- di->di_flags |= cpu_to_be32(dip->i_diskflags &
- GFS2_DIF_INHERIT_JDATA);
- di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
- di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode));
- di->di_entries = cpu_to_be32(2);
gfs2_init_dir(dibh, dip);
break;
case S_IFLNK:
@@ -516,15 +505,10 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
struct gfs2_inode *ip, int arq)
{
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
- struct buffer_head *dibh;
int error;
- error = gfs2_quota_lock(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
- if (error)
- return error;
-
if (arq) {
- error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid);
+ error = gfs2_quota_lock_check(dip);
if (error)
goto fail_quota_locks;
@@ -548,14 +532,8 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
if (error)
goto fail_end_trans;
- error = gfs2_meta_inode_buffer(ip, &dibh);
- if (error)
- goto fail_end_trans;
set_nlink(&ip->i_inode, S_ISDIR(ip->i_inode.i_mode) ? 2 : 1);
- gfs2_trans_add_meta(ip->i_gl, dibh);
- gfs2_dinode_out(ip, dibh->b_data);
- brelse(dibh);
- return 0;
+ mark_inode_dirty(&ip->i_inode);
fail_end_trans:
gfs2_trans_end(sdp);
@@ -655,13 +633,33 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (error)
goto fail_free_inode;
- set_bit(GIF_INVALID, &ip->i_flags);
inode->i_mode = mode;
inode->i_rdev = dev;
inode->i_size = size;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ gfs2_set_inode_blocks(inode, 1);
munge_mode_uid_gid(dip, inode);
ip->i_goal = dip->i_goal;
+ ip->i_diskflags = 0;
+ ip->i_eattr = 0;
+ ip->i_height = 0;
+ ip->i_depth = 0;
+ ip->i_entries = 0;
+
+ switch(mode & S_IFMT) {
+ case S_IFREG:
+ if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) ||
+ gfs2_tune_get(sdp, gt_new_files_jdata))
+ ip->i_diskflags |= GFS2_DIF_JDATA;
+ gfs2_set_aops(inode);
+ break;
+ case S_IFDIR:
+ ip->i_diskflags |= (dip->i_diskflags & GFS2_DIF_INHERIT_JDATA);
+ ip->i_diskflags |= GFS2_DIF_JDATA;
+ ip->i_entries = 2;
+ break;
+ }
+ gfs2_set_inode_flags(inode);
if ((GFS2_I(sdp->sd_root_dir->d_inode) == dip) ||
(dip->i_diskflags & GFS2_DIF_TOPDIR))
@@ -700,10 +698,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
gfs2_set_iop(inode);
insert_inode_hash(inode);
- error = gfs2_inode_refresh(ip);
- if (error)
- goto fail_gunlock3;
-
error = gfs2_acl_create(dip, inode);
if (error)
goto fail_gunlock3;
@@ -716,14 +710,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (error)
goto fail_gunlock3;
- if (bh)
- brelse(bh);
-
- gfs2_trans_end(sdp);
- gfs2_inplace_release(dip);
- gfs2_quota_unlock(dip);
- mark_inode_dirty(inode);
- gfs2_glock_dq_uninit_m(2, ghs);
+ brelse(bh);
+ gfs2_glock_dq_uninit(ghs);
+ gfs2_glock_dq_uninit(ghs + 1);
d_instantiate(dentry, inode);
return 0;
@@ -1126,7 +1115,9 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
- return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0, 0);
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
+ unsigned dsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode);
+ return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, dsize, 0);
}
/**