aboutsummaryrefslogtreecommitdiff
path: root/fs/gfs2/ops_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r--fs/gfs2/ops_inode.c72
1 files changed, 35 insertions, 37 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 7633a8584b0..e8ab9d254b7 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -58,7 +58,6 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
struct gfs2_holder ghs[2];
struct inode *inode;
int new = 1;
- int error;
gfs2_holder_init(dip->i_gl, 0, 0, ghs);
@@ -78,14 +77,16 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
return PTR_ERR(inode);
}
- error = gfs2_lookupi(dir, &dentry->d_name, 0, &inode);
- if (!error) {
- new = 0;
- gfs2_holder_uninit(ghs);
- break;
- } else if (error != -ENOENT) {
- gfs2_holder_uninit(ghs);
- return error;
+ inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd);
+ if (inode) {
+ if (!IS_ERR(inode)) {
+ new = 0;
+ gfs2_holder_uninit(ghs);
+ break;
+ } else {
+ gfs2_holder_uninit(ghs);
+ return PTR_ERR(inode);
+ }
}
}
@@ -110,17 +111,13 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
- struct gfs2_inode *dip = dir->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
struct inode *inode = NULL;
- int error;
- if (!sdp->sd_args.ar_localcaching)
- dentry->d_op = &gfs2_dops;
+ dentry->d_op = &gfs2_dops;
- error = gfs2_lookupi(dir, &dentry->d_name, 0, &inode);
- if (error && error != -ENOENT)
- return ERR_PTR(error);
+ inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd);
+ if (inode && IS_ERR(inode))
+ return ERR_PTR(PTR_ERR(inode));
if (inode)
return d_splice_alias(inode, dentry);
@@ -166,7 +163,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
if (error)
goto out_gunlock;
- error = gfs2_dir_search(dip, &dentry->d_name, NULL, NULL);
+ error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL);
switch (error) {
case -ENOENT:
break;
@@ -192,10 +189,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
if (ip->i_di.di_nlink == (uint32_t)-1)
goto out_gunlock;
- error = gfs2_diradd_alloc_required(dip, &dentry->d_name,
- &alloc_required);
- if (error)
+ alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name);
+ if (error < 0)
goto out_gunlock;
+ error = 0;
if (alloc_required) {
struct gfs2_alloc *al = gfs2_alloc_get(dip);
@@ -228,7 +225,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
goto out_ipres;
}
- error = gfs2_dir_add(dip, &dentry->d_name, &ip->i_num,
+ error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num,
IF2DT(ip->i_di.di_mode));
if (error)
goto out_end_trans;
@@ -419,24 +416,24 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (!gfs2_assert_withdraw(sdp, !error)) {
struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
- struct gfs2_dirent *dent;
-
- gfs2_dirent_alloc(ip, dibh, 1, &dent);
+ struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1);
+ struct qstr str = { .name = ".", .len = 1 };
+ str.hash = gfs2_disk_hash(str.name, str.len);
+ gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+ gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent);
dent->de_inum = di->di_num; /* already GFS2 endian */
- dent->de_hash = gfs2_disk_hash(".", 1);
- dent->de_hash = cpu_to_be32(dent->de_hash);
dent->de_type = DT_DIR;
- memcpy((char *) (dent + 1), ".", 1);
di->di_entries = cpu_to_be32(1);
- gfs2_dirent_alloc(ip, dibh, 2, &dent);
+ str.name = "..";
+ str.len = 2;
+ str.hash = gfs2_disk_hash(str.name, str.len);
+ dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1));
+ gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent);
gfs2_inum_out(&dip->i_num, (char *) &dent->de_inum);
- dent->de_hash = gfs2_disk_hash("..", 2);
- dent->de_hash = cpu_to_be32(dent->de_hash);
dent->de_type = DT_DIR;
- memcpy((char *) (dent + 1), "..", 2);
gfs2_dinode_out(&ip->i_di, (char *)di);
@@ -687,7 +684,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
if (error)
goto out_gunlock;
- error = gfs2_dir_search(ndip, &ndentry->d_name, NULL, NULL);
+ error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL);
switch (error) {
case -ENOENT:
error = 0;
@@ -723,10 +720,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
goto out_gunlock;
}
- error = gfs2_diradd_alloc_required(ndip, &ndentry->d_name,
- &alloc_required);
- if (error)
+ alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name);
+ if (error < 0)
goto out_gunlock;
+ error = 0;
if (alloc_required) {
struct gfs2_alloc *al = gfs2_alloc_get(ndip);
@@ -777,6 +774,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
struct qstr name;
name.len = 2;
name.name = "..";
+ name.hash = gfs2_disk_hash(name.name, name.len);
error = gfs2_change_nlink(ndip, +1);
if (error)
@@ -803,7 +801,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
if (error)
goto out_end_trans;
- error = gfs2_dir_add(ndip, &ndentry->d_name, &ip->i_num,
+ error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num,
IF2DT(ip->i_di.di_mode));
if (error)
goto out_end_trans;