diff options
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 3a2a10d6d43d..509e2f0d97e7 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -60,6 +60,7 @@ #include <linux/crc32.h> #include <linux/vmalloc.h> #include <linux/bio.h> +#include <linux/log2.h> #include "gfs2.h" #include "incore.h" @@ -130,7 +131,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_inode.i_size < offset + size) i_size_write(&ip->i_inode, offset + size); - ip->i_inode.i_mtime = inode_set_ctime_current(&ip->i_inode); + inode_set_mtime_to_ts(&ip->i_inode, inode_set_ctime_current(&ip->i_inode)); gfs2_dinode_out(ip, dibh->b_data); brelse(dibh); @@ -227,7 +228,7 @@ out: if (ip->i_inode.i_size < offset + copied) i_size_write(&ip->i_inode, offset + copied); - ip->i_inode.i_mtime = inode_set_ctime_current(&ip->i_inode); + inode_set_mtime_to_ts(&ip->i_inode, inode_set_ctime_current(&ip->i_inode)); gfs2_trans_add_meta(ip->i_gl, dibh); gfs2_dinode_out(ip, dibh->b_data); @@ -562,15 +563,18 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, int ret = 0; ret = gfs2_dirent_offset(GFS2_SB(inode), buf); - if (ret < 0) - goto consist_inode; - + if (ret < 0) { + gfs2_consist_inode(GFS2_I(inode)); + return ERR_PTR(-EIO); + } offset = ret; prev = NULL; dent = buf + offset; size = be16_to_cpu(dent->de_rec_len); - if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1)) - goto consist_inode; + if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1)) { + gfs2_consist_inode(GFS2_I(inode)); + return ERR_PTR(-EIO); + } do { ret = scan(dent, name, opaque); if (ret) @@ -582,8 +586,10 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, dent = buf + offset; size = be16_to_cpu(dent->de_rec_len); if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, - len, 0)) - goto consist_inode; + len, 0)) { + gfs2_consist_inode(GFS2_I(inode)); + return ERR_PTR(-EIO); + } } while(1); switch(ret) { @@ -597,10 +603,6 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, BUG_ON(ret > 0); return ERR_PTR(ret); } - -consist_inode: - gfs2_consist_inode(GFS2_I(inode)); - return ERR_PTR(-EIO); } static int dirent_check_reclen(struct gfs2_inode *dip, @@ -609,14 +611,16 @@ static int dirent_check_reclen(struct gfs2_inode *dip, const void *ptr = d; u16 rec_len = be16_to_cpu(d->de_rec_len); - if (unlikely(rec_len < sizeof(struct gfs2_dirent))) - goto broken; + if (unlikely(rec_len < sizeof(struct gfs2_dirent))) { + gfs2_consist_inode(dip); + return -EIO; + } ptr += rec_len; if (ptr < end_p) return rec_len; if (ptr == end_p) return -ENOENT; -broken: + gfs2_consist_inode(dip); return -EIO; } @@ -909,7 +913,6 @@ static int dir_make_exhash(struct inode *inode) struct qstr args; struct buffer_head *bh, *dibh; struct gfs2_leaf *leaf; - int y; u32 x; __be64 *lp; u64 bn; @@ -976,9 +979,7 @@ static int dir_make_exhash(struct inode *inode) i_size_write(inode, sdp->sd_sb.sb_bsize / 2); gfs2_add_inode_blocks(&dip->i_inode, 1); dip->i_diskflags |= GFS2_DIF_EXHASH; - - for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; - dip->i_depth = y; + dip->i_depth = ilog2(sdp->sd_hash_ptrs); gfs2_dinode_out(dip, dibh->b_data); @@ -1825,7 +1826,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, da->bh = NULL; brelse(bh); ip->i_entries++; - ip->i_inode.i_mtime = tv; + inode_set_mtime_to_ts(&ip->i_inode, tv); if (S_ISDIR(nip->i_inode.i_mode)) inc_nlink(&ip->i_inode); mark_inode_dirty(inode); @@ -1911,7 +1912,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry) if (!dip->i_entries) gfs2_consist_inode(dip); dip->i_entries--; - dip->i_inode.i_mtime = tv; + inode_set_mtime_to_ts(&dip->i_inode, tv); if (d_is_dir(dentry)) drop_nlink(&dip->i_inode); mark_inode_dirty(&dip->i_inode); @@ -1952,7 +1953,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, dent->de_type = cpu_to_be16(new_type); brelse(bh); - dip->i_inode.i_mtime = inode_set_ctime_current(&dip->i_inode); + inode_set_mtime_to_ts(&dip->i_inode, inode_set_ctime_current(&dip->i_inode)); mark_inode_dirty_sync(&dip->i_inode); return 0; } |