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.c93
1 files changed, 52 insertions, 41 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index e24af28b1a1..0fdcb7713cd 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -131,8 +131,8 @@ 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_di.di_mtime = ip->i_di.di_ctime = get_seconds();
- gfs2_dinode_out(&ip->i_di, dibh->b_data);
+ ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds();
+ gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
@@ -229,10 +229,10 @@ out:
if (ip->i_di.di_size < offset + copied)
ip->i_di.di_size = offset + copied;
- ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds();
+ ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds();
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
- gfs2_dinode_out(&ip->i_di, dibh->b_data);
+ gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
return copied;
@@ -340,10 +340,15 @@ fail:
return (copied) ? copied : error;
}
+static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent)
+{
+ return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0;
+}
+
static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent,
const struct qstr *name, int ret)
{
- if (dent->de_inum.no_addr != 0 &&
+ if (!gfs2_dirent_sentinel(dent) &&
be32_to_cpu(dent->de_hash) == name->hash &&
be16_to_cpu(dent->de_name_len) == name->len &&
memcmp(dent+1, name->name, name->len) == 0)
@@ -388,7 +393,7 @@ static int gfs2_dirent_find_space(const struct gfs2_dirent *dent,
unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
unsigned totlen = be16_to_cpu(dent->de_rec_len);
- if (!dent->de_inum.no_addr)
+ if (gfs2_dirent_sentinel(dent))
actual = GFS2_DIRENT_SIZE(0);
if (totlen - actual >= required)
return 1;
@@ -405,7 +410,7 @@ static int gfs2_dirent_gather(const struct gfs2_dirent *dent,
void *opaque)
{
struct dirent_gather *g = opaque;
- if (dent->de_inum.no_addr) {
+ if (!gfs2_dirent_sentinel(dent)) {
g->pdent[g->offset++] = dent;
}
return 0;
@@ -433,10 +438,10 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset,
if (unlikely(offset + size > len))
goto error;
msg = "zero inode number";
- if (unlikely(!first && !dent->de_inum.no_addr))
+ if (unlikely(!first && gfs2_dirent_sentinel(dent)))
goto error;
msg = "name length is greater than space in dirent";
- if (dent->de_inum.no_addr &&
+ if (!gfs2_dirent_sentinel(dent) &&
unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) >
size))
goto error;
@@ -598,7 +603,7 @@ static int dirent_next(struct gfs2_inode *dip, struct buffer_head *bh,
return ret;
/* Only the first dent could ever have de_inum.no_addr == 0 */
- if (!tmp->de_inum.no_addr) {
+ if (gfs2_dirent_sentinel(tmp)) {
gfs2_consist_inode(dip);
return -EIO;
}
@@ -621,7 +626,7 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh,
{
u16 cur_rec_len, prev_rec_len;
- if (!cur->de_inum.no_addr) {
+ if (gfs2_dirent_sentinel(cur)) {
gfs2_consist_inode(dip);
return;
}
@@ -633,7 +638,8 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh,
out the inode number and return. */
if (!prev) {
- cur->de_inum.no_addr = 0; /* No endianess worries */
+ cur->de_inum.no_addr = 0;
+ cur->de_inum.no_formal_ino = 0;
return;
}
@@ -664,7 +670,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode,
struct gfs2_dirent *ndent;
unsigned offset = 0, totlen;
- if (dent->de_inum.no_addr)
+ if (!gfs2_dirent_sentinel(dent))
offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
totlen = be16_to_cpu(dent->de_rec_len);
BUG_ON(offset + name->len > totlen);
@@ -713,12 +719,12 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
static int get_leaf_nr(struct gfs2_inode *dip, u32 index,
u64 *leaf_out)
{
- u64 leaf_no;
+ __be64 leaf_no;
int error;
error = gfs2_dir_read_data(dip, (char *)&leaf_no,
- index * sizeof(u64),
- sizeof(u64), 0);
+ index * sizeof(__be64),
+ sizeof(__be64), 0);
if (error != sizeof(u64))
return (error < 0) ? error : -EIO;
@@ -837,7 +843,8 @@ static int dir_make_exhash(struct inode *inode)
struct gfs2_leaf *leaf;
int y;
u32 x;
- u64 *lp, bn;
+ __be64 *lp;
+ u64 bn;
int error;
error = gfs2_meta_inode_buffer(dip, &dibh);
@@ -893,20 +900,20 @@ static int dir_make_exhash(struct inode *inode)
gfs2_trans_add_bh(dip->i_gl, dibh, 1);
gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
- lp = (u64 *)(dibh->b_data + sizeof(struct gfs2_dinode));
+ lp = (__be64 *)(dibh->b_data + sizeof(struct gfs2_dinode));
for (x = sdp->sd_hash_ptrs; x--; lp++)
*lp = cpu_to_be64(bn);
dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2;
dip->i_di.di_blocks++;
+ gfs2_set_inode_blocks(&dip->i_inode);
dip->i_di.di_flags |= GFS2_DIF_EXHASH;
- dip->i_di.di_payload_format = 0;
for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
dip->i_di.di_depth = y;
- gfs2_dinode_out(&dip->i_di, dibh->b_data);
+ gfs2_dinode_out(dip, dibh->b_data);
brelse(dibh);
@@ -929,7 +936,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
struct gfs2_leaf *nleaf, *oleaf;
struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new;
u32 start, len, half_len, divider;
- u64 bn, *lp, leaf_no;
+ u64 bn, leaf_no;
+ __be64 *lp;
u32 index;
int x, moved = 0;
int error;
@@ -974,7 +982,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
/* Change the pointers.
Don't bother distinguishing stuffed from non-stuffed.
This code is complicated enough already. */
- lp = kmalloc(half_len * sizeof(u64), GFP_NOFS | __GFP_NOFAIL);
+ lp = kmalloc(half_len * sizeof(__be64), GFP_NOFS | __GFP_NOFAIL);
/* Change the pointers */
for (x = 0; x < half_len; x++)
lp[x] = cpu_to_be64(bn);
@@ -1000,7 +1008,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
if (dirent_next(dip, obh, &next))
next = NULL;
- if (dent->de_inum.no_addr &&
+ if (!gfs2_dirent_sentinel(dent) &&
be32_to_cpu(dent->de_hash) < divider) {
struct qstr str;
str.name = (char*)(dent+1);
@@ -1037,7 +1045,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
error = gfs2_meta_inode_buffer(dip, &dibh);
if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
dip->i_di.di_blocks++;
- gfs2_dinode_out(&dip->i_di, dibh->b_data);
+ gfs2_set_inode_blocks(&dip->i_inode);
+ gfs2_dinode_out(dip, dibh->b_data);
brelse(dibh);
}
@@ -1117,7 +1126,7 @@ static int dir_double_exhash(struct gfs2_inode *dip)
error = gfs2_meta_inode_buffer(dip, &dibh);
if (!gfs2_assert_withdraw(sdp, !error)) {
dip->i_di.di_depth++;
- gfs2_dinode_out(&dip->i_di, dibh->b_data);
+ gfs2_dinode_out(dip, dibh->b_data);
brelse(dibh);
}
@@ -1194,7 +1203,7 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
int *copied)
{
const struct gfs2_dirent *dent, *dent_next;
- struct gfs2_inum inum;
+ struct gfs2_inum_host inum;
u64 off, off_next;
unsigned int x, y;
int run = 0;
@@ -1341,7 +1350,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
u32 hsize, len = 0;
u32 ht_offset, lp_offset, ht_offset_cur = -1;
u32 hash, index;
- u64 *lp;
+ __be64 *lp;
int copied = 0;
int error = 0;
unsigned depth = 0;
@@ -1365,7 +1374,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
if (ht_offset_cur != ht_offset) {
error = gfs2_dir_read_data(dip, (char *)lp,
- ht_offset * sizeof(u64),
+ ht_offset * sizeof(__be64),
sdp->sd_hash_bsize, 1);
if (error != sdp->sd_hash_bsize) {
if (error >= 0)
@@ -1456,7 +1465,7 @@ out:
*/
int gfs2_dir_search(struct inode *dir, const struct qstr *name,
- struct gfs2_inum *inum, unsigned int *type)
+ struct gfs2_inum_host *inum, unsigned int *type)
{
struct buffer_head *bh;
struct gfs2_dirent *dent;
@@ -1515,7 +1524,8 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
return error;
gfs2_trans_add_bh(ip->i_gl, bh, 1);
ip->i_di.di_blocks++;
- gfs2_dinode_out(&ip->i_di, bh->b_data);
+ gfs2_set_inode_blocks(&ip->i_inode);
+ gfs2_dinode_out(ip, bh->b_data);
brelse(bh);
return 0;
}
@@ -1531,7 +1541,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 *inum, unsigned type)
+ const struct gfs2_inum_host *inum, unsigned type)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct buffer_head *bh;
@@ -1558,8 +1568,8 @@ 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_di.di_mtime = ip->i_di.di_ctime = get_seconds();
- gfs2_dinode_out(&ip->i_di, bh->b_data);
+ ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds();
+ gfs2_dinode_out(ip, bh->b_data);
brelse(bh);
error = 0;
break;
@@ -1644,8 +1654,8 @@ 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_di.di_mtime = dip->i_di.di_ctime = get_seconds();
- gfs2_dinode_out(&dip->i_di, bh->b_data);
+ dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds();
+ gfs2_dinode_out(dip, bh->b_data);
brelse(bh);
mark_inode_dirty(&dip->i_inode);
@@ -1666,7 +1676,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 *inum, unsigned int new_type)
+ struct gfs2_inum_host *inum, unsigned int new_type)
{
struct buffer_head *bh;
struct gfs2_dirent *dent;
@@ -1692,8 +1702,8 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
gfs2_trans_add_bh(dip->i_gl, bh, 1);
}
- dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
- gfs2_dinode_out(&dip->i_di, bh->b_data);
+ dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds();
+ gfs2_dinode_out(dip, bh->b_data);
brelse(bh);
return 0;
}
@@ -1715,7 +1725,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
u32 hsize, len;
u32 ht_offset, lp_offset, ht_offset_cur = -1;
u32 index = 0;
- u64 *lp;
+ __be64 *lp;
u64 leaf_no;
int error = 0;
@@ -1735,7 +1745,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
if (ht_offset_cur != ht_offset) {
error = gfs2_dir_read_data(dip, (char *)lp,
- ht_offset * sizeof(u64),
+ ht_offset * sizeof(__be64),
sdp->sd_hash_bsize, 1);
if (error != sdp->sd_hash_bsize) {
if (error >= 0)
@@ -1859,6 +1869,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
if (!dip->i_di.di_blocks)
gfs2_consist_inode(dip);
dip->i_di.di_blocks--;
+ gfs2_set_inode_blocks(&dip->i_inode);
}
error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size);
@@ -1873,7 +1884,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
goto out_end_trans;
gfs2_trans_add_bh(dip->i_gl, dibh, 1);
- gfs2_dinode_out(&dip->i_di, dibh->b_data);
+ gfs2_dinode_out(dip, dibh->b_data);
brelse(dibh);
out_end_trans: