* http://sucs.org/~rohan/git/gfs2-3.0-nmw: (24 commits) GFS2: Move readahead of metadata during deallocation into its own function GFS2: Remove two unused variables GFS2: Misc fixes GFS2: rewrite fallocate code to write blocks directly GFS2: speed up delete/unlink performance for large files GFS2: Fix off-by-one in gfs2_blk2rgrpd GFS2: Clean up ->page_mkwrite GFS2: Correctly set goal block after allocation GFS2: Fix AIL flush issue during fsync GFS2: Use cached rgrp in gfs2_rlist_add() GFS2: Call do_strip() directly from recursive_scan() GFS2: Remove obsolete assert GFS2: Cache the most recently used resource group in the inode GFS2: Make resource groups "append only" during life of fs GFS2: Use rbtree for resource groups and clean up bitmap buffer ref count scheme GFS2: Fix lseek after SEEK_DATA, SEEK_HOLE have been added GFS2: Clean up gfs2_create GFS2: Use ->dirty_inode() GFS2: Fix bug trap and journaled data fsync GFS2: Fix inode allocation error path ...
This commit is contained in:
112
fs/gfs2/inode.c
112
fs/gfs2/inode.c
@@ -583,7 +583,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
|
||||
goto fail_quota_locks;
|
||||
|
||||
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
|
||||
al->al_rgd->rd_length +
|
||||
dip->i_rgd->rd_length +
|
||||
2 * RES_DINODE +
|
||||
RES_STATFS + RES_QUOTA, 0);
|
||||
if (error)
|
||||
@@ -613,8 +613,7 @@ fail_end_trans:
|
||||
gfs2_trans_end(sdp);
|
||||
|
||||
fail_ipreserv:
|
||||
if (dip->i_alloc->al_rgd)
|
||||
gfs2_inplace_release(dip);
|
||||
gfs2_inplace_release(dip);
|
||||
|
||||
fail_quota_locks:
|
||||
gfs2_quota_unlock(dip);
|
||||
@@ -661,7 +660,7 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
|
||||
|
||||
static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
||||
unsigned int mode, dev_t dev, const char *symname,
|
||||
unsigned int size)
|
||||
unsigned int size, int excl)
|
||||
{
|
||||
const struct qstr *name = &dentry->d_name;
|
||||
struct gfs2_holder ghs[2];
|
||||
@@ -681,6 +680,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
||||
goto fail;
|
||||
|
||||
error = create_ok(dip, name, mode);
|
||||
if ((error == -EEXIST) && S_ISREG(mode) && !excl) {
|
||||
inode = gfs2_lookupi(dir, &dentry->d_name, 0);
|
||||
gfs2_glock_dq_uninit(ghs);
|
||||
d_instantiate(dentry, inode);
|
||||
return IS_ERR(inode) ? PTR_ERR(inode) : 0;
|
||||
}
|
||||
if (error)
|
||||
goto fail_gunlock;
|
||||
|
||||
@@ -723,21 +728,22 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
||||
brelse(bh);
|
||||
|
||||
gfs2_trans_end(sdp);
|
||||
if (dip->i_alloc->al_rgd)
|
||||
gfs2_inplace_release(dip);
|
||||
gfs2_inplace_release(dip);
|
||||
gfs2_quota_unlock(dip);
|
||||
gfs2_alloc_put(dip);
|
||||
gfs2_glock_dq_uninit_m(2, ghs);
|
||||
mark_inode_dirty(inode);
|
||||
gfs2_glock_dq_uninit_m(2, ghs);
|
||||
d_instantiate(dentry, inode);
|
||||
return 0;
|
||||
|
||||
fail_gunlock2:
|
||||
gfs2_glock_dq_uninit(ghs + 1);
|
||||
if (inode && !IS_ERR(inode))
|
||||
iput(inode);
|
||||
fail_gunlock:
|
||||
gfs2_glock_dq_uninit(ghs);
|
||||
if (inode && !IS_ERR(inode)) {
|
||||
set_bit(GIF_ALLOC_FAILED, &GFS2_I(inode)->i_flags);
|
||||
iput(inode);
|
||||
}
|
||||
fail:
|
||||
if (bh)
|
||||
brelse(bh);
|
||||
@@ -756,24 +762,10 @@ fail:
|
||||
static int gfs2_create(struct inode *dir, struct dentry *dentry,
|
||||
int mode, struct nameidata *nd)
|
||||
{
|
||||
struct inode *inode;
|
||||
int ret;
|
||||
|
||||
for (;;) {
|
||||
ret = gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0);
|
||||
if (ret != -EEXIST || (nd && (nd->flags & LOOKUP_EXCL)))
|
||||
return ret;
|
||||
|
||||
inode = gfs2_lookupi(dir, &dentry->d_name, 0);
|
||||
if (inode) {
|
||||
if (!IS_ERR(inode))
|
||||
break;
|
||||
return PTR_ERR(inode);
|
||||
}
|
||||
}
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
return 0;
|
||||
int excl = 0;
|
||||
if (nd && (nd->flags & LOOKUP_EXCL))
|
||||
excl = 1;
|
||||
return gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0, excl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -900,7 +892,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
||||
goto out_gunlock_q;
|
||||
|
||||
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
|
||||
gfs2_rg_blocks(al) +
|
||||
gfs2_rg_blocks(dip) +
|
||||
2 * RES_DINODE + RES_STATFS +
|
||||
RES_QUOTA, 0);
|
||||
if (error)
|
||||
@@ -922,8 +914,9 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
||||
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
|
||||
inc_nlink(&ip->i_inode);
|
||||
ip->i_inode.i_ctime = CURRENT_TIME;
|
||||
gfs2_dinode_out(ip, dibh->b_data);
|
||||
mark_inode_dirty(&ip->i_inode);
|
||||
ihold(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
mark_inode_dirty(inode);
|
||||
|
||||
out_brelse:
|
||||
brelse(dibh);
|
||||
@@ -945,11 +938,6 @@ out_child:
|
||||
out_parent:
|
||||
gfs2_holder_uninit(ghs);
|
||||
gfs2_holder_uninit(ghs + 1);
|
||||
if (!error) {
|
||||
ihold(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
mark_inode_dirty(inode);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1022,8 +1010,6 @@ static int gfs2_unlink_inode(struct gfs2_inode *dip,
|
||||
clear_nlink(inode);
|
||||
else
|
||||
drop_nlink(inode);
|
||||
gfs2_trans_add_bh(ip->i_gl, bh, 1);
|
||||
gfs2_dinode_out(ip, bh->b_data);
|
||||
mark_inode_dirty(inode);
|
||||
if (inode->i_nlink == 0)
|
||||
gfs2_unlink_di(inode);
|
||||
@@ -1051,13 +1037,8 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
|
||||
struct buffer_head *bh;
|
||||
struct gfs2_holder ghs[3];
|
||||
struct gfs2_rgrpd *rgd;
|
||||
struct gfs2_holder ri_gh;
|
||||
int error;
|
||||
|
||||
error = gfs2_rindex_hold(sdp, &ri_gh);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
|
||||
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
|
||||
|
||||
@@ -1114,7 +1095,6 @@ out_child:
|
||||
gfs2_glock_dq(ghs);
|
||||
out_parent:
|
||||
gfs2_holder_uninit(ghs);
|
||||
gfs2_glock_dq_uninit(&ri_gh);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1137,7 +1117,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
|
||||
if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
return gfs2_create_inode(dir, dentry, S_IFLNK | S_IRWXUGO, 0, symname, size);
|
||||
return gfs2_create_inode(dir, dentry, S_IFLNK | S_IRWXUGO, 0, symname, size, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1151,7 +1131,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
|
||||
|
||||
static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
{
|
||||
return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0);
|
||||
return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1166,7 +1146,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
|
||||
dev_t dev)
|
||||
{
|
||||
return gfs2_create_inode(dir, dentry, mode, dev, NULL, 0);
|
||||
return gfs2_create_inode(dir, dentry, mode, dev, NULL, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1232,7 +1212,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||
struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
|
||||
struct gfs2_inode *nip = NULL;
|
||||
struct gfs2_sbd *sdp = GFS2_SB(odir);
|
||||
struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, }, ri_gh;
|
||||
struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, };
|
||||
struct gfs2_rgrpd *nrgd;
|
||||
unsigned int num_gh;
|
||||
int dir_rename = 0;
|
||||
@@ -1246,10 +1226,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = gfs2_rindex_hold(sdp, &ri_gh);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (odip != ndip) {
|
||||
error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE,
|
||||
0, &r_gh);
|
||||
@@ -1386,12 +1362,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||
|
||||
al->al_requested = sdp->sd_max_dirres;
|
||||
|
||||
error = gfs2_inplace_reserve_ri(ndip);
|
||||
error = gfs2_inplace_reserve(ndip);
|
||||
if (error)
|
||||
goto out_gunlock_q;
|
||||
|
||||
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
|
||||
gfs2_rg_blocks(al) +
|
||||
gfs2_rg_blocks(ndip) +
|
||||
4 * RES_DINODE + 4 * RES_LEAF +
|
||||
RES_STATFS + RES_QUOTA + 4, 0);
|
||||
if (error)
|
||||
@@ -1457,7 +1433,6 @@ out_gunlock_r:
|
||||
if (r_gh.gh_gl)
|
||||
gfs2_glock_dq_uninit(&r_gh);
|
||||
out:
|
||||
gfs2_glock_dq_uninit(&ri_gh);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1561,21 +1536,10 @@ int gfs2_permission(struct inode *inode, int mask)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
|
||||
static int __gfs2_setattr_simple(struct inode *inode, struct iattr *attr)
|
||||
{
|
||||
struct inode *inode = &ip->i_inode;
|
||||
struct buffer_head *dibh;
|
||||
int error;
|
||||
|
||||
error = gfs2_meta_inode_buffer(ip, &dibh);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
setattr_copy(inode, attr);
|
||||
mark_inode_dirty(inode);
|
||||
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
|
||||
gfs2_dinode_out(ip, dibh->b_data);
|
||||
brelse(dibh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1587,19 +1551,19 @@ static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
|
||||
* Returns: errno
|
||||
*/
|
||||
|
||||
int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
|
||||
int gfs2_setattr_simple(struct inode *inode, struct iattr *attr)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (current->journal_info)
|
||||
return __gfs2_setattr_simple(ip, attr);
|
||||
return __gfs2_setattr_simple(inode, attr);
|
||||
|
||||
error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0);
|
||||
error = gfs2_trans_begin(GFS2_SB(inode), RES_DINODE, 0);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = __gfs2_setattr_simple(ip, attr);
|
||||
gfs2_trans_end(GFS2_SB(&ip->i_inode));
|
||||
error = __gfs2_setattr_simple(inode, attr);
|
||||
gfs2_trans_end(GFS2_SB(inode));
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1637,7 +1601,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
|
||||
if (error)
|
||||
goto out_gunlock_q;
|
||||
|
||||
error = gfs2_setattr_simple(ip, attr);
|
||||
error = gfs2_setattr_simple(inode, attr);
|
||||
if (error)
|
||||
goto out_end_trans;
|
||||
|
||||
@@ -1693,12 +1657,12 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode))
|
||||
error = gfs2_acl_chmod(ip, attr);
|
||||
else
|
||||
error = gfs2_setattr_simple(ip, attr);
|
||||
error = gfs2_setattr_simple(inode, attr);
|
||||
|
||||
out:
|
||||
gfs2_glock_dq_uninit(&i_gh);
|
||||
if (!error)
|
||||
mark_inode_dirty(inode);
|
||||
gfs2_glock_dq_uninit(&i_gh);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user