aboutsummaryrefslogtreecommitdiff
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/Kconfig1
-rw-r--r--fs/gfs2/acl.c39
-rw-r--r--fs/gfs2/acl.h1
-rw-r--r--fs/gfs2/bmap.c179
-rw-r--r--fs/gfs2/daemon.c7
-rw-r--r--fs/gfs2/dir.c93
-rw-r--r--fs/gfs2/dir.h8
-rw-r--r--fs/gfs2/eaops.c2
-rw-r--r--fs/gfs2/eattr.c66
-rw-r--r--fs/gfs2/eattr.h6
-rw-r--r--fs/gfs2/glock.c36
-rw-r--r--fs/gfs2/glock.h3
-rw-r--r--fs/gfs2/glops.c138
-rw-r--r--fs/gfs2/incore.h43
-rw-r--r--fs/gfs2/inode.c406
-rw-r--r--fs/gfs2/inode.h20
-rw-r--r--fs/gfs2/log.c41
-rw-r--r--fs/gfs2/log.h2
-rw-r--r--fs/gfs2/lops.c40
-rw-r--r--fs/gfs2/lops.h2
-rw-r--r--fs/gfs2/main.c4
-rw-r--r--fs/gfs2/meta_io.c46
-rw-r--r--fs/gfs2/meta_io.h1
-rw-r--r--fs/gfs2/ondisk.c138
-rw-r--r--fs/gfs2/ops_address.c52
-rw-r--r--fs/gfs2/ops_dentry.c4
-rw-r--r--fs/gfs2/ops_export.c38
-rw-r--r--fs/gfs2/ops_export.h2
-rw-r--r--fs/gfs2/ops_file.c66
-rw-r--r--fs/gfs2/ops_file.h2
-rw-r--r--fs/gfs2/ops_fstype.c4
-rw-r--r--fs/gfs2/ops_inode.c134
-rw-r--r--fs/gfs2/ops_super.c11
-rw-r--r--fs/gfs2/ops_vm.c2
-rw-r--r--fs/gfs2/quota.c15
-rw-r--r--fs/gfs2/recovery.c29
-rw-r--r--fs/gfs2/recovery.h2
-rw-r--r--fs/gfs2/rgrp.c13
-rw-r--r--fs/gfs2/super.c50
-rw-r--r--fs/gfs2/super.h6
-rw-r--r--fs/gfs2/sys.c8
-rw-r--r--fs/gfs2/util.c6
-rw-r--r--fs/gfs2/util.h12
43 files changed, 769 insertions, 1009 deletions
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig
index 8c27de8b956..c0791cbacad 100644
--- a/fs/gfs2/Kconfig
+++ b/fs/gfs2/Kconfig
@@ -2,6 +2,7 @@ config GFS2_FS
tristate "GFS2 file system support"
depends on EXPERIMENTAL
select FS_POSIX_ACL
+ select CRC32
help
A cluster filesystem.
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 5f959b8ce40..6e80844367e 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -74,11 +74,11 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
{
if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
return -EOPNOTSUPP;
- if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER))
+ if (current->fsuid != ip->i_inode.i_uid && !capable(CAP_FOWNER))
return -EPERM;
- if (S_ISLNK(ip->i_di.di_mode))
+ if (S_ISLNK(ip->i_inode.i_mode))
return -EOPNOTSUPP;
- if (!access && !S_ISDIR(ip->i_di.di_mode))
+ if (!access && !S_ISDIR(ip->i_inode.i_mode))
return -EACCES;
return 0;
@@ -145,14 +145,14 @@ out:
}
/**
- * gfs2_check_acl_locked - Check an ACL to see if we're allowed to do something
+ * gfs2_check_acl - Check an ACL to see if we're allowed to do something
* @inode: the file we want to do something to
* @mask: what we want to do
*
* Returns: errno
*/
-int gfs2_check_acl_locked(struct inode *inode, int mask)
+int gfs2_check_acl(struct inode *inode, int mask)
{
struct posix_acl *acl = NULL;
int error;
@@ -170,21 +170,6 @@ int gfs2_check_acl_locked(struct inode *inode, int mask)
return -EAGAIN;
}
-int gfs2_check_acl(struct inode *inode, int mask)
-{
- struct gfs2_inode *ip = GFS2_I(inode);
- struct gfs2_holder i_gh;
- int error;
-
- error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
- if (!error) {
- error = gfs2_check_acl_locked(inode, mask);
- gfs2_glock_dq_uninit(&i_gh);
- }
-
- return error;
-}
-
static int munge_mode(struct gfs2_inode *ip, mode_t mode)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
@@ -198,10 +183,10 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode)
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
gfs2_assert_withdraw(sdp,
- (ip->i_di.di_mode & S_IFMT) == (mode & S_IFMT));
- ip->i_di.di_mode = mode;
+ (ip->i_inode.i_mode & S_IFMT) == (mode & S_IFMT));
+ ip->i_inode.i_mode = mode;
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);
}
@@ -215,12 +200,12 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct posix_acl *acl = NULL, *clone;
struct gfs2_ea_request er;
- mode_t mode = ip->i_di.di_mode;
+ mode_t mode = ip->i_inode.i_mode;
int error;
if (!sdp->sd_args.ar_posix_acl)
return 0;
- if (S_ISLNK(ip->i_di.di_mode))
+ if (S_ISLNK(ip->i_inode.i_mode))
return 0;
memset(&er, 0, sizeof(struct gfs2_ea_request));
@@ -232,7 +217,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
return error;
if (!acl) {
mode &= ~current->fs->umask;
- if (mode != ip->i_di.di_mode)
+ if (mode != ip->i_inode.i_mode)
error = munge_mode(ip, mode);
return error;
}
@@ -244,7 +229,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
posix_acl_release(acl);
acl = clone;
- if (S_ISDIR(ip->i_di.di_mode)) {
+ if (S_ISDIR(ip->i_inode.i_mode)) {
er.er_name = GFS2_POSIX_ACL_DEFAULT;
er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN;
error = gfs2_system_eaops.eo_set(ip, &er);
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h
index 05c294fe0d7..6751930bfb6 100644
--- a/fs/gfs2/acl.h
+++ b/fs/gfs2/acl.h
@@ -31,7 +31,6 @@ int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
struct gfs2_ea_request *er,
int *remove, mode_t *mode);
int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access);
-int gfs2_check_acl_locked(struct inode *inode, int mask);
int gfs2_check_acl(struct inode *inode, int mask);
int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip);
int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 06e9a8cb45e..8240c1ff94f 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -38,8 +38,8 @@ struct metapath {
};
typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh,
- struct buffer_head *bh, u64 *top,
- u64 *bottom, unsigned int height,
+ struct buffer_head *bh, __be64 *top,
+ __be64 *bottom, unsigned int height,
void *data);
struct strip_mine {
@@ -163,6 +163,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
if (ip->i_di.di_size) {
*(__be64 *)(di + 1) = cpu_to_be64(block);
ip->i_di.di_blocks++;
+ gfs2_set_inode_blocks(&ip->i_inode);
di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
}
@@ -230,7 +231,7 @@ static int build_height(struct inode *inode, unsigned height)
struct buffer_head *blocks[GFS2_MAX_META_HEIGHT];
struct gfs2_dinode *di;
int error;
- u64 *bp;
+ __be64 *bp;
u64 bn;
unsigned n;
@@ -255,7 +256,7 @@ static int build_height(struct inode *inode, unsigned height)
GFS2_FORMAT_IN);
gfs2_buffer_clear_tail(blocks[n],
sizeof(struct gfs2_meta_header));
- bp = (u64 *)(blocks[n]->b_data +
+ bp = (__be64 *)(blocks[n]->b_data +
sizeof(struct gfs2_meta_header));
*bp = cpu_to_be64(blocks[n+1]->b_blocknr);
brelse(blocks[n]);
@@ -272,6 +273,7 @@ static int build_height(struct inode *inode, unsigned height)
*(__be64 *)(di + 1) = cpu_to_be64(bn);
ip->i_di.di_height += new_height;
ip->i_di.di_blocks += new_height;
+ gfs2_set_inode_blocks(&ip->i_inode);
di->di_height = cpu_to_be16(ip->i_di.di_height);
di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
brelse(dibh);
@@ -360,15 +362,15 @@ static void find_metapath(struct gfs2_inode *ip, u64 block,
* metadata tree.
*/
-static inline u64 *metapointer(struct buffer_head *bh, int *boundary,
+static inline __be64 *metapointer(struct buffer_head *bh, int *boundary,
unsigned int height, const struct metapath *mp)
{
unsigned int head_size = (height > 0) ?
sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode);
- u64 *ptr;
+ __be64 *ptr;
*boundary = 0;
- ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height];
- if (ptr + 1 == (u64 *)(bh->b_data + bh->b_size))
+ ptr = ((__be64 *)(bh->b_data + head_size)) + mp->mp_list[height];
+ if (ptr + 1 == (__be64 *)(bh->b_data + bh->b_size))
*boundary = 1;
return ptr;
}
@@ -394,7 +396,7 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
int *new, u64 *block)
{
int boundary;
- u64 *ptr = metapointer(bh, &boundary, height, mp);
+ __be64 *ptr = metapointer(bh, &boundary, height, mp);
if (*ptr) {
*block = be64_to_cpu(*ptr);
@@ -415,17 +417,35 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
*ptr = cpu_to_be64(*block);
ip->i_di.di_blocks++;
+ gfs2_set_inode_blocks(&ip->i_inode);
*new = 1;
return 0;
}
+static inline void bmap_lock(struct inode *inode, int create)
+{
+ struct gfs2_inode *ip = GFS2_I(inode);
+ if (create)
+ down_write(&ip->i_rw_mutex);
+ else
+ down_read(&ip->i_rw_mutex);
+}
+
+static inline void bmap_unlock(struct inode *inode, int create)
+{
+ struct gfs2_inode *ip = GFS2_I(inode);
+ if (create)
+ up_write(&ip->i_rw_mutex);
+ else
+ up_read(&ip->i_rw_mutex);
+}
+
/**
- * gfs2_block_pointers - Map a block from an inode to a disk block
+ * gfs2_block_map - Map a block from an inode to a disk block
* @inode: The inode
* @lblock: The logical block number
- * @map_bh: The bh to be mapped
- * @mp: metapath to use
+ * @bh_map: The bh to be mapped
*
* Find the block number on the current device which corresponds to an
* inode's block. If the block had to be created, "new" will be set.
@@ -433,8 +453,8 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
* Returns: errno
*/
-static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create,
- struct buffer_head *bh_map, struct metapath *mp)
+int gfs2_block_map(struct inode *inode, u64 lblock, int create,
+ struct buffer_head *bh_map)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -448,57 +468,61 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create,
u64 dblock = 0;
int boundary;
unsigned int maxlen = bh_map->b_size >> inode->i_blkbits;
+ struct metapath mp;
+ u64 size;
BUG_ON(maxlen == 0);
if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip)))
return 0;
+ bmap_lock(inode, create);
+ clear_buffer_mapped(bh_map);
+ clear_buffer_new(bh_map);
+ clear_buffer_boundary(bh_map);
bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize;
-
- height = calc_tree_height(ip, (lblock + 1) * bsize);
- if (ip->i_di.di_height < height) {
- if (!create)
- return 0;
-
- error = build_height(inode, height);
- if (error)
- return error;
+ size = (lblock + 1) * bsize;
+
+ if (size > ip->i_di.di_size) {
+ height = calc_tree_height(ip, size);
+ if (ip->i_di.di_height < height) {
+ if (!create)
+ goto out_ok;
+
+ error = build_height(inode, height);
+ if (error)
+ goto out_fail;
+ }
}
- find_metapath(ip, lblock, mp);
+ find_metapath(ip, lblock, &mp);
end_of_metadata = ip->i_di.di_height - 1;
-
error = gfs2_meta_inode_buffer(ip, &bh);
if (error)
- return error;
+ goto out_fail;
for (x = 0; x < end_of_metadata; x++) {
- lookup_block(ip, bh, x, mp, create, &new, &dblock);
+ lookup_block(ip, bh, x, &mp, create, &new, &dblock);
brelse(bh);
if (!dblock)
- return 0;
+ goto out_ok;
error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh);
if (error)
- return error;
+ goto out_fail;
}
- boundary = lookup_block(ip, bh, end_of_metadata, mp, create, &new, &dblock);
- clear_buffer_mapped(bh_map);
- clear_buffer_new(bh_map);
- clear_buffer_boundary(bh_map);
-
+ boundary = lookup_block(ip, bh, end_of_metadata, &mp, create, &new, &dblock);
if (dblock) {
map_bh(bh_map, inode->i_sb, dblock);
if (boundary)
- set_buffer_boundary(bh);
+ set_buffer_boundary(bh_map);
if (new) {
struct buffer_head *dibh;
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
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);
}
set_buffer_new(bh_map);
@@ -507,8 +531,8 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create,
while(--maxlen && !buffer_boundary(bh_map)) {
u64 eblock;
- mp->mp_list[end_of_metadata]++;
- boundary = lookup_block(ip, bh, end_of_metadata, mp, 0, &new, &eblock);
+ mp.mp_list[end_of_metadata]++;
+ boundary = lookup_block(ip, bh, end_of_metadata, &mp, 0, &new, &eblock);
if (eblock != ++dblock)
break;
bh_map->b_size += (1 << inode->i_blkbits);
@@ -518,43 +542,15 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create,
}
out_brelse:
brelse(bh);
- return 0;
-}
-
-
-static inline void bmap_lock(struct inode *inode, int create)
-{
- struct gfs2_inode *ip = GFS2_I(inode);
- if (create)
- down_write(&ip->i_rw_mutex);
- else
- down_read(&ip->i_rw_mutex);
-}
-
-static inline void bmap_unlock(struct inode *inode, int create)
-{
- struct gfs2_inode *ip = GFS2_I(inode);
- if (create)
- up_write(&ip->i_rw_mutex);
- else
- up_read(&ip->i_rw_mutex);
-}
-
-int gfs2_block_map(struct inode *inode, u64 lblock, int create,
- struct buffer_head *bh)
-{
- struct metapath mp;
- int ret;
-
- bmap_lock(inode, create);
- ret = gfs2_block_pointers(inode, lblock, create, bh, &mp);
+out_ok:
+ error = 0;
+out_fail:
bmap_unlock(inode, create);
- return ret;
+ return error;
}
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
{
- struct metapath mp;
struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 };
int ret;
int create = *new;
@@ -564,9 +560,7 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi
BUG_ON(!new);
bh.b_size = 1 << (inode->i_blkbits + 5);
- bmap_lock(inode, create);
- ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp);
- bmap_unlock(inode, create);
+ ret = gfs2_block_map(inode, lblock, create, &bh);
*extlen = bh.b_size >> inode->i_blkbits;
*dblock = bh.b_blocknr;
if (buffer_new(&bh))
@@ -600,7 +594,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *bh = NULL;
- u64 *top, *bottom;
+ __be64 *top, *bottom;
u64 bn;
int error;
int mh_size = sizeof(struct gfs2_meta_header);
@@ -611,17 +605,17 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
return error;
dibh = bh;
- top = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0];
- bottom = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs;
+ top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0];
+ bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs;
} else {
error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh);
if (error)
return error;
- top = (u64 *)(bh->b_data + mh_size) +
+ top = (__be64 *)(bh->b_data + mh_size) +
(first ? mp->mp_list[height] : 0);
- bottom = (u64 *)(bh->b_data + mh_size) + sdp->sd_inptrs;
+ bottom = (__be64 *)(bh->b_data + mh_size) + sdp->sd_inptrs;
}
error = bc(ip, dibh, bh, top, bottom, height, data);
@@ -660,7 +654,7 @@ out:
*/
static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
- struct buffer_head *bh, u64 *top, u64 *bottom,
+ struct buffer_head *bh, __be64 *top, __be64 *bottom,
unsigned int height, void *data)
{
struct strip_mine *sm = data;
@@ -668,7 +662,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
struct gfs2_rgrp_list rlist;
u64 bn, bstart;
u32 blen;
- u64 *p;
+ __be64 *p;
unsigned int rg_blocks = 0;
int metadata;
unsigned int revokes = 0;
@@ -770,6 +764,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
if (!ip->i_di.di_blocks)
gfs2_consist_inode(ip);
ip->i_di.di_blocks--;
+ gfs2_set_inode_blocks(&ip->i_inode);
}
if (bstart) {
if (metadata)
@@ -778,9 +773,9 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
gfs2_free_data(ip, bstart, blen);
}
- 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_dinode_out(&ip->i_di, dibh->b_data);
+ gfs2_dinode_out(ip, dibh->b_data);
up_write(&ip->i_rw_mutex);
@@ -819,7 +814,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
if (error)
goto out;
- error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid);
+ error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid);
if (error)
goto out_gunlock_q;
@@ -853,14 +848,14 @@ static int do_grow(struct gfs2_inode *ip, u64 size)
}
ip->i_di.di_size = size;
- 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();
error = gfs2_meta_inode_buffer(ip, &dibh);
if (error)
goto out_end_trans;
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);
out_end_trans:
@@ -968,9 +963,9 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
if (gfs2_is_stuffed(ip)) {
ip->i_di.di_size = size;
- 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);
gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
error = 1;
@@ -980,10 +975,10 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
if (!error) {
ip->i_di.di_size = size;
- 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();
ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG;
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);
}
}
@@ -1053,11 +1048,11 @@ static int trunc_end(struct gfs2_inode *ip)
ip->i_num.no_addr;
gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
}
- 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();
ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG;
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);
out:
@@ -1109,7 +1104,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size)
{
int error;
- if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode)))
+ if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode)))
return -EINVAL;
if (size > ip->i_di.di_size)
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c
index cab1f68d468..683cb5bda87 100644
--- a/fs/gfs2/daemon.c
+++ b/fs/gfs2/daemon.c
@@ -112,6 +112,7 @@ int gfs2_logd(void *data)
struct gfs2_sbd *sdp = data;
struct gfs2_holder ji_gh;
unsigned long t;
+ int need_flush;
while (!kthread_should_stop()) {
/* Advance the log tail */
@@ -120,8 +121,10 @@ int gfs2_logd(void *data)
gfs2_tune_get(sdp, gt_log_flush_secs) * HZ;
gfs2_ail1_empty(sdp, DIO_ALL);
-
- if (time_after_eq(jiffies, t)) {
+ gfs2_log_lock(sdp);
+ need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks);
+ gfs2_log_unlock(sdp);
+ if (need_flush || time_after_eq(jiffies, t)) {
gfs2_log_flush(sdp, NULL);
sdp->sd_log_flush_time = jiffies;
}
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)
e