summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r--fs/gfs2/dir.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index a96fa07..2beb2f4 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -130,7 +130,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
if (ip->i_di.di_size < offset + size)
ip->i_di.di_size = offset + size;
- ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+ ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
@@ -228,7 +228,7 @@ out:
if (ip->i_di.di_size < offset + copied)
ip->i_di.di_size = offset + copied;
- ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+ ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(ip, dibh->b_data);
@@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
if (dip->i_di.di_entries != g.offset) {
fs_warn(sdp, "Number of entries corrupt in dir %llu, "
"ip->i_di.di_entries (%u) != g.offset (%u)\n",
- (unsigned long long)dip->i_num.no_addr,
+ (unsigned long long)dip->i_no_addr,
dip->i_di.di_entries,
g.offset);
error = -EIO;
@@ -1488,24 +1488,55 @@ out:
* Returns: errno
*/
-int gfs2_dir_search(struct inode *dir, const struct qstr *name,
- struct gfs2_inum_host *inum, unsigned int *type)
+struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
{
struct buffer_head *bh;
struct gfs2_dirent *dent;
+ struct inode *inode;
+
+ dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
+ if (dent) {
+ if (IS_ERR(dent))
+ return ERR_PTR(PTR_ERR(dent));
+ inode = gfs2_inode_lookup(dir->i_sb,
+ be16_to_cpu(dent->de_type),
+ be64_to_cpu(dent->de_inum.no_addr),
+ be64_to_cpu(dent->de_inum.no_formal_ino));
+ brelse(bh);
+ return inode;
+ }
+ return ERR_PTR(-ENOENT);
+}
+
+int gfs2_dir_check(struct inode *dir, const struct qstr *name,
+ const struct gfs2_inode *ip)
+{
+ struct buffer_head *bh;
+ struct gfs2_dirent *dent;
+ int ret = -ENOENT;
dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
if (dent) {
if (IS_ERR(dent))
return PTR_ERR(dent);
- if (inum)
- gfs2_inum_in(inum, (char *)&dent->de_inum);
- if (type)
- *type = be16_to_cpu(dent->de_type);
+ if (ip) {
+ if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
+ goto out;
+ if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
+ ip->i_no_formal_ino)
+ goto out;
+ if (unlikely(IF2DT(ip->i_inode.i_mode) !=
+ be16_to_cpu(dent->de_type))) {
+ gfs2_consist_inode(GFS2_I(dir));
+ ret = -EIO;
+ goto out;
+ }
+ }
+ ret = 0;
+out:
brelse(bh);
- return 0;
}
- return -ENOENT;
+ return ret;
}
static int dir_new_leaf(struct inode *inode, const struct qstr *name)
@@ -1565,7 +1596,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
*/
int gfs2_dir_add(struct inode *inode, const struct qstr *name,
- const struct gfs2_inum_host *inum, unsigned type)
+ const struct gfs2_inode *nip, unsigned type)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct buffer_head *bh;
@@ -1580,7 +1611,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
if (IS_ERR(dent))
return PTR_ERR(dent);
dent = gfs2_init_dirent(inode, dent, name, bh);
- gfs2_inum_out(inum, (char *)&dent->de_inum);
+ gfs2_inum_out(nip, dent);
dent->de_type = cpu_to_be16(type);
if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
leaf = (struct gfs2_leaf *)bh->b_data;
@@ -1592,7 +1623,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
break;
gfs2_trans_add_bh(ip->i_gl, bh, 1);
ip->i_di.di_entries++;
- ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+ ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
gfs2_dinode_out(ip, bh->b_data);
brelse(bh);
error = 0;
@@ -1678,7 +1709,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
gfs2_consist_inode(dip);
gfs2_trans_add_bh(dip->i_gl, bh, 1);
dip->i_di.di_entries--;
- dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
+ dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
gfs2_dinode_out(dip, bh->b_data);
brelse(bh);
mark_inode_dirty(&dip->i_inode);
@@ -1700,7 +1731,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
*/
int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
- struct gfs2_inum_host *inum, unsigned int new_type)
+ const struct gfs2_inode *nip, unsigned int new_type)
{
struct buffer_head *bh;
struct gfs2_dirent *dent;
@@ -1715,7 +1746,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
return PTR_ERR(dent);
gfs2_trans_add_bh(dip->i_gl, bh, 1);
- gfs2_inum_out(inum, (char *)&dent->de_inum);
+ gfs2_inum_out(nip, dent);
dent->de_type = cpu_to_be16(new_type);
if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
@@ -1726,7 +1757,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
gfs2_trans_add_bh(dip->i_gl, bh, 1);
}
- dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC;
+ dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
gfs2_dinode_out(dip, bh->b_data);
brelse(bh);
return 0;
@@ -1867,7 +1898,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
for (x = 0; x < rlist.rl_rgrps; x++) {
struct gfs2_rgrpd *rgd;
rgd = rlist.rl_ghs[x].gh_gl->gl_object;
- rg_blocks += rgd->rd_ri.ri_length;
+ rg_blocks += rgd->rd_length;
}
error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
OpenPOWER on IntegriCloud