summaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/Makefile2
-rw-r--r--fs/gfs2/acl.c10
-rw-r--r--fs/gfs2/bmap.c44
-rw-r--r--fs/gfs2/daemon.c27
-rw-r--r--fs/gfs2/daemon.h1
-rw-r--r--fs/gfs2/dir.c66
-rw-r--r--fs/gfs2/eaops.c14
-rw-r--r--fs/gfs2/eattr.c70
-rw-r--r--fs/gfs2/glock.c102
-rw-r--r--fs/gfs2/glock.h5
-rw-r--r--fs/gfs2/glops.c9
-rw-r--r--fs/gfs2/incore.h48
-rw-r--r--fs/gfs2/inode.c809
-rw-r--r--fs/gfs2/inode.h32
-rw-r--r--fs/gfs2/log.c3
-rw-r--r--fs/gfs2/lops.c30
-rw-r--r--fs/gfs2/main.c2
-rw-r--r--fs/gfs2/meta_io.c12
-rw-r--r--fs/gfs2/ondisk.c17
-rw-r--r--fs/gfs2/ops_address.c31
-rw-r--r--fs/gfs2/ops_dentry.c6
-rw-r--r--fs/gfs2/ops_export.c60
-rw-r--r--fs/gfs2/ops_file.c42
-rw-r--r--fs/gfs2/ops_fstype.c103
-rw-r--r--fs/gfs2/ops_inode.c168
-rw-r--r--fs/gfs2/ops_super.c112
-rw-r--r--fs/gfs2/ops_vm.c12
-rw-r--r--fs/gfs2/page.c64
-rw-r--r--fs/gfs2/quota.c28
-rw-r--r--fs/gfs2/recovery.c23
-rw-r--r--fs/gfs2/rgrp.c118
-rw-r--r--fs/gfs2/rgrp.h1
-rw-r--r--fs/gfs2/super.c45
-rw-r--r--fs/gfs2/sys.c2
-rw-r--r--fs/gfs2/trans.h1
-rw-r--r--fs/gfs2/unlinked.c459
-rw-r--r--fs/gfs2/unlinked.h25
-rw-r--r--fs/gfs2/util.c2
38 files changed, 738 insertions, 1867 deletions
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile
index 9974201..0b79776 100644
--- a/fs/gfs2/Makefile
+++ b/fs/gfs2/Makefile
@@ -3,7 +3,7 @@ gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \
glops.o inode.o lm.o log.o lops.o locking.o lvb.o main.o meta_io.o \
mount.o ondisk.o ops_address.o ops_dentry.o ops_export.o ops_file.o \
ops_fstype.o ops_inode.o ops_super.o ops_vm.o page.o quota.o \
- recovery.o rgrp.o super.o sys.o trans.o unlinked.o util.o
+ recovery.o rgrp.o super.o sys.o trans.o util.o
obj-$(CONFIG_GFS2_FS_LOCKING_NOLOCK) += locking/nolock/
obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += locking/dlm/
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 343dbe3..9ef4cf2 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -73,7 +73,7 @@ int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
{
- if (!ip->i_sbd->sd_args.ar_posix_acl)
+ if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
return -EOPNOTSUPP;
if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER))
return -EPERM;
@@ -160,7 +160,7 @@ int gfs2_check_acl_locked(struct inode *inode, int mask)
struct posix_acl *acl = NULL;
int error;
- error = acl_get(inode->u.generic_ip, ACL_ACCESS, &acl, NULL, NULL, NULL);
+ error = acl_get(GFS2_I(inode), ACL_ACCESS, &acl, NULL, NULL, NULL);
if (error)
return error;
@@ -175,7 +175,7 @@ int gfs2_check_acl_locked(struct inode *inode, int mask)
int gfs2_check_acl(struct inode *inode, int mask)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder i_gh;
int error;
@@ -192,7 +192,7 @@ int gfs2_check_acl(struct inode *inode, int mask)
static int munge_mode(struct gfs2_inode *ip, mode_t mode)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *dibh;
int error;
@@ -217,7 +217,7 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode)
int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ 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;
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 41abd3f..98fa07c 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -136,7 +136,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer,
static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
uint64_t *arr;
unsigned int max, height;
@@ -169,7 +169,7 @@ static unsigned int calc_tree_height(struct gfs2_inode *ip, uint64_t size)
static int build_height(struct inode *inode, unsigned height)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
unsigned new_height = height - ip->i_di.di_height;
struct buffer_head *dibh;
struct buffer_head *blocks[GFS2_MAX_META_HEIGHT];
@@ -283,7 +283,7 @@ static int build_height(struct inode *inode, unsigned height)
static void find_metapath(struct gfs2_inode *ip, uint64_t block,
struct metapath *mp)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
uint64_t b = block;
unsigned int i;
@@ -382,8 +382,8 @@ static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock,
int *boundary,
struct metapath *mp)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *bh;
int create = *new;
unsigned int bsize;
@@ -446,7 +446,7 @@ out:
static inline void bmap_lock(struct inode *inode, int create)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
if (create)
down_write(&ip->i_rw_mutex);
else
@@ -455,7 +455,7 @@ static inline void bmap_lock(struct inode *inode, int create)
static inline void bmap_unlock(struct inode *inode, int create)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
if (create)
up_write(&ip->i_rw_mutex);
else
@@ -481,8 +481,8 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *
int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct metapath mp;
struct buffer_head *bh;
int boundary;
@@ -541,7 +541,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
uint64_t block, int first, block_call_t bc,
void *data)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *bh = NULL;
uint64_t *top, *bottom;
uint64_t bn;
@@ -609,8 +609,8 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
struct buffer_head *bh, uint64_t *top, uint64_t *bottom,
unsigned int height, void *data)
{
- struct strip_mine *sm = (struct strip_mine *)data;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct strip_mine *sm = data;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrp_list rlist;
uint64_t bn, bstart;
uint32_t blen;
@@ -756,7 +756,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
static int do_grow(struct gfs2_inode *ip, uint64_t size)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al;
struct buffer_head *dibh;
unsigned int h;
@@ -795,7 +795,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
h = calc_tree_height(ip, size);
if (ip->i_di.di_height < h) {
down_write(&ip->i_rw_mutex);
- error = build_height(ip->i_vnode, h);
+ error = build_height(&ip->i_inode, h);
up_write(&ip->i_rw_mutex);
if (error)
goto out_end_trans;
@@ -830,7 +830,7 @@ static int do_grow(struct gfs2_inode *ip, uint64_t size)
static int trunc_start(struct gfs2_inode *ip, uint64_t size)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *dibh;
int journaled = gfs2_is_jdata(ip);
int error;
@@ -854,7 +854,7 @@ static int trunc_start(struct gfs2_inode *ip, uint64_t size)
} else {
if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1))
- error = gfs2_block_truncate_page(ip->i_vnode->i_mapping);
+ error = gfs2_block_truncate_page(ip->i_inode.i_mapping);
if (!error) {
ip->i_di.di_size = size;
@@ -883,7 +883,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, uint64_t size)
if (!size)
lblock = 0;
else
- lblock = (size - 1) >> ip->i_sbd->sd_sb.sb_bsize_shift;
+ lblock = (size - 1) >> GFS2_SB(&ip->i_inode)->sd_sb.sb_bsize_shift;
find_metapath(ip, lblock, &mp);
gfs2_alloc_get(ip);
@@ -911,7 +911,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, uint64_t size)
static int trunc_end(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *dibh;
int error;
@@ -990,7 +990,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size)
{
int error;
- if (gfs2_assert_warn(ip->i_sbd, S_ISREG(ip->i_di.di_mode)))
+ if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode)))
return -EINVAL;
if (size > ip->i_di.di_size)
@@ -1027,7 +1027,7 @@ int gfs2_file_dealloc(struct gfs2_inode *ip)
void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
unsigned int *data_blocks, unsigned int *ind_blocks)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
unsigned int tmp;
if (gfs2_is_dir(ip)) {
@@ -1057,7 +1057,7 @@ void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
unsigned int len, int *alloc_required)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
uint64_t lblock, lblock_stop, dblock;
uint32_t extlen;
int new = 0;
@@ -1088,7 +1088,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset,
}
for (; lblock < lblock_stop; lblock += extlen) {
- error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
+ error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
if (error)
return error;
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c
index 9e7b9f2..1453605 100644
--- a/fs/gfs2/daemon.c
+++ b/fs/gfs2/daemon.c
@@ -25,7 +25,6 @@
#include "quota.h"
#include "recovery.h"
#include "super.h"
-#include "unlinked.h"
#include "util.h"
/* This uses schedule_timeout() instead of msleep() because it's good for
@@ -195,29 +194,3 @@ int gfs2_quotad(void *data)
return 0;
}
-/**
- * gfs2_inoded - Deallocate unlinked inodes
- * @sdp: Pointer to GFS2 superblock
- *
- */
-
-int gfs2_inoded(void *data)
-{
- struct gfs2_sbd *sdp = data;
- unsigned long t;
- int error;
-
- while (!kthread_should_stop()) {
- error = gfs2_unlinked_dealloc(sdp);
- if (error &&
- error != -EROFS &&
- !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
- fs_err(sdp, "inoded: error = %d\n", error);
-
- t = gfs2_tune_get(sdp, gt_inoded_secs) * HZ;
- schedule_timeout_interruptible(t);
- }
-
- return 0;
-}
-
diff --git a/fs/gfs2/daemon.h b/fs/gfs2/daemon.h
index aa68e7a..aa93eb6 100644
--- a/fs/gfs2/daemon.h
+++ b/fs/gfs2/daemon.h
@@ -15,6 +15,5 @@ int gfs2_glockd(void *data);
int gfs2_recoverd(void *data);
int gfs2_logd(void *data);
int gfs2_quotad(void *data);
-int gfs2_inoded(void *data);
#endif /* __DAEMON_DOT_H__ */
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 6918a58..b035388 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -113,7 +113,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, uint64_t block,
error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh);
if (error)
return error;
- if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_JD)) {
+ if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
brelse(bh);
return -EIO;
}
@@ -158,7 +158,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
uint64_t offset, unsigned int size)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *dibh;
uint64_t lblock, dblock;
uint32_t extlen = 0;
@@ -197,7 +197,7 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
if (!extlen) {
new = 1;
- error = gfs2_extent_map(ip->i_vnode, lblock, &new,
+ error = gfs2_extent_map(&ip->i_inode, lblock, &new,
&dblock, &extlen);
if (error)
goto fail;
@@ -277,7 +277,7 @@ static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf,
static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
uint64_t offset, unsigned int size)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
uint64_t lblock, dblock;
uint32_t extlen = 0;
unsigned int o;
@@ -314,7 +314,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
if (!extlen) {
new = 0;
- error = gfs2_extent_map(ip->i_vnode, lblock, &new,
+ error = gfs2_extent_map(&ip->i_inode, lblock, &new,
&dblock, &extlen);
if (error)
goto fail;
@@ -534,7 +534,7 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode,
}
consist_inode:
- gfs2_consist_inode(inode->u.generic_ip);
+ gfs2_consist_inode(GFS2_I(inode));
return ERR_PTR(-EIO);
}
@@ -556,13 +556,13 @@ static int dirent_first(struct gfs2_inode *dip, struct buffer_head *bh,
struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
- if (gfs2_meta_check(dip->i_sbd, bh))
+ if (gfs2_meta_check(GFS2_SB(&dip->i_inode), bh))
return -EIO;
*dent = (struct gfs2_dirent *)(bh->b_data +
sizeof(struct gfs2_leaf));
return IS_LEAF;
} else {
- if (gfs2_metatype_check(dip->i_sbd, bh, GFS2_METATYPE_DI))
+ if (gfs2_metatype_check(GFS2_SB(&dip->i_inode), bh, GFS2_METATYPE_DI))
return -EIO;
*dent = (struct gfs2_dirent *)(bh->b_data +
sizeof(struct gfs2_dinode));
@@ -674,7 +674,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode,
const struct qstr *name,
struct buffer_head *bh)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_dirent *ndent;
unsigned offset = 0, totlen;
@@ -707,8 +707,10 @@ static int get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
int error;
error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp);
- if (!error && gfs2_metatype_check(dip->i_sbd, *bhp, GFS2_METATYPE_LF))
+ if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
+ /* printk(KERN_INFO "block num=%llu\n", leaf_no); */
error = -EIO;
+ }
return error;
}
@@ -759,7 +761,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
{
struct buffer_head *bh;
struct gfs2_dirent *dent;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
int error;
if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
@@ -771,7 +773,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
gfs2_consist_inode(ip);
return ERR_PTR(-EIO);
}
-
+
index = name->hash >> (32 - ip->i_di.di_depth);
error = get_first_leaf(ip, index, &bh);
if (error)
@@ -786,12 +788,14 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
brelse(bh);
if (!ln)
break;
+
error = get_leaf(ip, ln, &bh);
} while(!error);
return error ? ERR_PTR(error) : NULL;
}
+
error = gfs2_meta_inode_buffer(ip, &bh);
if (error)
return ERR_PTR(error);
@@ -807,7 +811,7 @@ got_dent:
static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
u64 bn = gfs2_alloc_meta(ip);
struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn);
struct gfs2_leaf *leaf;
@@ -815,6 +819,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
struct qstr name = { .name = "", .len = 0, .hash = 0 };
if (!bh)
return NULL;
+
gfs2_trans_add_bh(ip->i_gl, bh, 1);
gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF);
leaf = (struct gfs2_leaf *)bh->b_data;
@@ -838,8 +843,8 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
static int dir_make_exhash(struct inode *inode)
{
- struct gfs2_inode *dip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct gfs2_dirent *dent;
struct qstr args;
struct buffer_head *bh, *dibh;
@@ -874,7 +879,7 @@ static int dir_make_exhash(struct inode *inode)
args.len = bh->b_size - sizeof(struct gfs2_dinode) +
sizeof(struct gfs2_leaf);
args.name = bh->b_data;
- dent = gfs2_dirent_scan(dip->i_vnode, bh->b_data, bh->b_size,
+ dent = gfs2_dirent_scan(&dip->i_inode, bh->b_data, bh->b_size,
gfs2_dirent_last, &args, NULL);
if (!dent) {
brelse(bh);
@@ -933,7 +938,7 @@ static int dir_make_exhash(struct inode *inode)
static int dir_split_leaf(struct inode *inode, const struct qstr *name)
{
- struct gfs2_inode *dip = inode->u.generic_ip;
+ struct gfs2_inode *dip = GFS2_I(inode);
struct buffer_head *nbh, *obh, *dibh;
struct gfs2_leaf *nleaf, *oleaf;
struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
@@ -1044,7 +1049,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
oleaf->lf_depth = nleaf->lf_depth;
error = gfs2_meta_inode_buffer(dip, &dibh);
- if (!gfs2_assert_withdraw(dip->i_sbd, !error)) {
+ if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
dip->i_di.di_blocks++;
gfs2_dinode_out(&dip->i_di, dibh->b_data);
brelse(dibh);
@@ -1073,7 +1078,7 @@ fail_brelse:
static int dir_double_exhash(struct gfs2_inode *dip)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct buffer_head *dibh;
uint32_t hsize;
uint64_t *buf;
@@ -1268,7 +1273,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
gfs2_filldir_t filldir, int *copied,
unsigned *depth, u64 leaf_no)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct buffer_head *bh;
struct gfs2_leaf *lf;
unsigned entries = 0;
@@ -1348,8 +1353,8 @@ out:
static int dir_e_read(struct inode *inode, uint64_t *offset, void *opaque,
gfs2_filldir_t filldir)
{
- struct gfs2_inode *dip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
uint32_t hsize, len = 0;
uint32_t ht_offset, lp_offset, ht_offset_cur = -1;
uint32_t hash, index;
@@ -1407,7 +1412,7 @@ out:
int gfs2_dir_read(struct inode *inode, uint64_t *offset, void *opaque,
gfs2_filldir_t filldir)
{
- struct gfs2_inode *dip = inode->u.generic_ip;
+ struct gfs2_inode *dip = GFS2_I(inode);
struct dirent_gather g;
const struct gfs2_dirent **darr, *dent;
struct buffer_head *dibh;
@@ -1490,7 +1495,7 @@ int gfs2_dir_search(struct inode *dir, const struct qstr *name,
static int dir_new_leaf(struct inode *inode, const struct qstr *name)
{
struct buffer_head *bh, *obh;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_leaf *leaf, *oleaf;
int error;
u32 index;
@@ -1545,7 +1550,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)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct buffer_head *bh;
struct gfs2_dirent *dent;
struct gfs2_leaf *leaf;
@@ -1623,7 +1628,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
/* Returns _either_ the entry (if its first in block) or the
previous entry otherwise */
- dent = gfs2_dirent_search(dip->i_vnode, name, gfs2_dirent_prev, &bh);
+ dent = gfs2_dirent_search(&dip->i_inode, name, gfs2_dirent_prev, &bh);
if (!dent) {
gfs2_consist_inode(dip);
return -EIO;
@@ -1659,6 +1664,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
gfs2_dinode_out(&dip->i_di, bh->b_data);
brelse(bh);
+ mark_inode_dirty(&dip->i_inode);
return error;
}
@@ -1683,7 +1689,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
struct gfs2_dirent *dent;
int error;
- dent = gfs2_dirent_search(dip->i_vnode, filename, gfs2_dirent_find, &bh);
+ dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
if (!dent) {
gfs2_consist_inode(dip);
return -EIO;
@@ -1720,7 +1726,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct buffer_head *bh;
struct gfs2_leaf *leaf;
uint32_t hsize, len;
@@ -1800,7 +1806,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
uint64_t leaf_no, void *data)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct gfs2_leaf *tmp_leaf;
struct gfs2_rgrp_list rlist;
struct buffer_head *bh, *dibh;
@@ -1920,7 +1926,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct buffer_head *bh;
int error;
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c
index 1c5ac31..b7e6a37 100644
--- a/fs/gfs2/eaops.c
+++ b/fs/gfs2/eaops.c
@@ -58,7 +58,7 @@ unsigned int gfs2_ea_name2type(const char *name, char **truncated_name)
static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
int error = permission(inode, MAY_READ, NULL);
if (error)
return error;
@@ -68,7 +68,7 @@ static int user_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
if (S_ISREG(inode->i_mode) ||
(S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
@@ -83,7 +83,7 @@ static int user_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int user_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
if (S_ISREG(inode->i_mode) ||
(S_ISDIR(inode->i_mode) && !(inode->i_mode & S_ISVTX))) {
@@ -103,7 +103,7 @@ static int system_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (ip->i_sbd->sd_args.ar_posix_acl == 0 &&
+ if (GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl == 0 &&
(GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
return -EOPNOTSUPP;
@@ -172,7 +172,7 @@ static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
int error = permission(inode, MAY_READ, NULL);
if (error)
return error;
@@ -182,7 +182,7 @@ static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
int error = permission(inode, MAY_WRITE, NULL);
if (error)
return error;
@@ -192,7 +192,7 @@ static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
int error = permission(inode, MAY_WRITE, NULL);
if (error)
return error;
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
index 2e114c0..967369322 100644
--- a/fs/gfs2/eattr.c
+++ b/fs/gfs2/eattr.c
@@ -80,7 +80,7 @@ static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
struct gfs2_ea_header *ea, *prev = NULL;
int error = 0;
- if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_EA))
+ if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_EA))
return -EIO;
for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
@@ -128,13 +128,13 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
goto out;
}
- if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_IN)) {
+ if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_IN)) {
error = -EIO;
goto out;
}
eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs2_meta_header));
- end = eablk + ip->i_sbd->sd_inptrs;
+ end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs;
for (; eablk < end; eablk++) {
uint64_t bn;
@@ -232,7 +232,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
struct gfs2_ea_header *prev, void *private)
{
int *leave = private;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrpd *rgd;
struct gfs2_holder rg_gh;
struct buffer_head *dibh;
@@ -338,7 +338,7 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
if (error)
goto out_alloc;
- error = gfs2_rindex_hold(ip->i_sbd, &al->al_ri_gh);
+ error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
if (error)
goto out_quota;
@@ -459,7 +459,7 @@ int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
char *data)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head **bh;
unsigned int amount = GFS2_EA_DATA_LEN(ea);
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
@@ -604,7 +604,7 @@ int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_ea_header *ea;
uint64_t block;
@@ -641,7 +641,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
struct gfs2_ea_request *er)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
ea->ea_data_len = cpu_to_be32(er->er_data_len);
ea->ea_name_len = er->er_name_len;
@@ -723,7 +723,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
if (error)
goto out_gunlock_q;
- error = gfs2_trans_begin(ip->i_sbd,
+ error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
blks + al->al_rgd->rd_ri.ri_length +
RES_DINODE + RES_STATFS + RES_QUOTA, 0);
if (error)
@@ -736,7 +736,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
if (er->er_flags & GFS2_ERF_MODE) {
- gfs2_assert_withdraw(ip->i_sbd,
+ gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
(ip->i_di.di_mode & S_IFMT) ==
(er->er_mode & S_IFMT));
ip->i_di.di_mode = er->er_mode;
@@ -748,7 +748,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
}
out_end_trans:
- gfs2_trans_end(ip->i_sbd);
+ gfs2_trans_end(GFS2_SB(&ip->i_inode));
out_ipres:
gfs2_inplace_release(ip);
@@ -790,7 +790,7 @@ static int ea_init_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
static int ea_init(struct gfs2_inode *ip, struct gfs2_ea_request *er)
{
- unsigned int jbsize = ip->i_sbd->sd_jbsize;
+ unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
unsigned int blks = 1;
if (GFS2_EAREQ_SIZE_STUFFED(er) > jbsize)
@@ -830,7 +830,7 @@ static void ea_set_remove_stuffed(struct gfs2_inode *ip,
return;
} else if (GFS2_EA2NEXT(prev) != ea) {
prev = GFS2_EA2NEXT(prev);
- gfs2_assert_withdraw(ip->i_sbd, GFS2_EA2NEXT(prev) == ea);
+ gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), GFS2_EA2NEXT(prev) == ea);
}
len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
@@ -857,7 +857,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
struct buffer_head *dibh;
int error;
- error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + 2 * RES_EATTR, 0);
+ error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
if (error)
return error;
@@ -876,7 +876,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
goto out;
if (er->er_flags & GFS2_ERF_MODE) {
- gfs2_assert_withdraw(ip->i_sbd,
+ gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
(ip->i_di.di_mode & S_IFMT) == (er->er_mode & S_IFMT));
ip->i_di.di_mode = er->er_mode;
}
@@ -885,7 +885,7 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
gfs2_dinode_out(&ip->i_di, dibh->b_data);
brelse(dibh);
out:
- gfs2_trans_end(ip->i_sbd);
+ gfs2_trans_end(GFS2_SB(&ip->i_inode));
return error;
}
@@ -921,7 +921,7 @@ static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
int stuffed;
int error;
- stuffed = ea_calc_size(ip->i_sbd, es->es_er, &size);
+ stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er, &size);
if (ea->ea_type == GFS2_EATYPE_UNUSED) {
if (GFS2_EA_REC_LEN(ea) < size)
@@ -947,7 +947,7 @@ static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
es->es_bh = bh;
es->es_ea = ea;
blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
- ip->i_sbd->sd_jbsize);
+ GFS2_SB(&ip->i_inode)->sd_jbsize);
error = ea_alloc_skeleton(ip, es->es_er, blks,
ea_set_simple_alloc, es);
@@ -961,7 +961,7 @@ static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
void *private)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head *indbh, *newbh;
uint64_t *eablk;
int error;
@@ -1050,8 +1050,8 @@ static int ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
if (!(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT))
blks++;
- if (GFS2_EAREQ_SIZE_STUFFED(er) > ip->i_sbd->sd_jbsize)
- blks += DIV_ROUND_UP(er->er_data_len, ip->i_sbd->sd_jbsize);
+ if (GFS2_EAREQ_SIZE_STUFFED(er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
+ blks += DIV_ROUND_UP(er->er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
return ea_alloc_skeleton(ip, er, blks, ea_set_block, el);
}
@@ -1061,7 +1061,7 @@ static int ea_set_remove_unstuffed(struct gfs2_inode *ip,
{
if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
el->el_prev = GFS2_EA2NEXT(el->el_prev);
- gfs2_assert_withdraw(ip->i_sbd,
+ gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
GFS2_EA2NEXT(el->el_prev) == el->el_ea);
}
@@ -1119,7 +1119,7 @@ int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
er->er_data = NULL;
er->er_data_len = 0;
}
- error = ea_check_size(ip->i_sbd, er);
+ error = ea_check_size(GFS2_SB(&ip->i_inode), er);
if (error)
return error;
@@ -1127,7 +1127,7 @@ int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
if (error)
return error;
- if (IS_IMMUTABLE(ip->i_vnode))
+ if (IS_IMMUTABLE(&ip->i_inode))
error = -EPERM;
else
error = gfs2_ea_ops[er->er_type]->eo_set(ip, er);
@@ -1144,7 +1144,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
struct buffer_head *dibh;
int error;
- error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + RES_EATTR, 0);
+ error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
if (error)
return error;
@@ -1169,7 +1169,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
brelse(dibh);
}
- gfs2_trans_end(ip->i_sbd);
+ gfs2_trans_end(GFS2_SB(&ip->i_inode));
return error;
}
@@ -1219,7 +1219,7 @@ int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
if (error)
return error;
- if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
+ if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
error = -EPERM;
else
error = gfs2_ea_ops[er->er_type]->eo_remove(ip, er);
@@ -1232,7 +1232,7 @@ int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
struct gfs2_ea_header *ea, char *data)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head **bh;
unsigned int amount = GFS2_EA_DATA_LEN(ea);
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
@@ -1304,7 +1304,7 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
int error;
if (GFS2_EA_IS_STUFFED(el->el_ea)) {
- error = gfs2_trans_begin(ip->i_sbd, RES_DINODE + RES_EATTR, 0);
+ error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
if (error)
return error;
@@ -1320,22 +1320,22 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
- error = inode_setattr(ip->i_vnode, attr);
- gfs2_assert_warn(ip->i_sbd, !error);
+ error = inode_setattr(&ip->i_inode, attr);
+ gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
gfs2_inode_attr_out(ip);
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(&ip->i_di, dibh->b_data);
brelse(dibh);
}
- gfs2_trans_end(ip->i_sbd);
+ gfs2_trans_end(GFS2_SB(&ip->i_inode));
return error;
}
static int ea_dealloc_indirect(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrp_list rlist;
struct buffer_head *indbh, *dibh;
uint64_t *eablk, *end;
@@ -1456,7 +1456,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
static int ea_dealloc_block(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
struct gfs2_rgrpd *rgd;
struct buffer_head *dibh;
@@ -1518,7 +1518,7 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip)
if (error)
goto out_alloc;
- error = gfs2_rindex_hold(ip->i_sbd, &al->al_ri_gh);
+ error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
if (error)
goto out_quota;
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 0603a6d..35bac908 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -654,7 +654,7 @@ static void run_queue(struct gfs2_glock *gl)
* Gives caller exclusive access to manipulate a glock structure.
*/
-void gfs2_glmutex_lock(struct gfs2_glock *gl)
+static void gfs2_glmutex_lock(struct gfs2_glock *gl)
{
struct gfs2_holder gh;
@@ -704,7 +704,7 @@ static int gfs2_glmutex_trylock(struct gfs2_glock *gl)
*
*/
-void gfs2_glmutex_unlock(struct gfs2_glock *gl)
+static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
{
spin_lock(&gl->gl_spin);
clear_bit(GLF_LOCK, &gl->gl_flags);
@@ -726,7 +726,7 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state)
{
struct gfs2_holder *gh, *new_gh = NULL;
- restart:
+restart:
spin_lock(&gl->gl_spin);
list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
@@ -752,13 +752,27 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state)
goto restart;
}
- out:
+out:
spin_unlock(&gl->gl_spin);
if (new_gh)
gfs2_holder_put(new_gh);
}
+void gfs2_glock_inode_squish(struct inode *inode)
+{
+ struct gfs2_holder gh;
+ struct gfs2_glock *gl = GFS2_I(inode)->i_gl;
+ gfs2_holder_init(gl, LM_ST_UNLOCKED, 0, &gh);
+ set_bit(HIF_DEMOTE, &gh.gh_iflags);
+ spin_lock(&gl->gl_spin);
+ gfs2_assert(inode->i_sb->s_fs_info, list_empty(&gl->gl_holders));
+ list_add_tail(&gh.gh_list, &gl->gl_waiters2);
+ run_queue(gl);
+ spin_unlock(&gl->gl_spin);
+ gfs2_holder_uninit(&gh);
+}
+
/**
* state_change - record that the glock is now in a different state
* @gl: the glock
@@ -1383,8 +1397,7 @@ int gfs2_glock_be_greedy(struct gfs2_glock *gl, unsigned int time)
struct greedy *gr;
struct gfs2_holder *gh;
- if (!time ||
- gl->gl_sbd->sd_args.ar_localcaching ||
+ if (!time || gl->gl_sbd->sd_args.ar_localcaching ||
test_and_set_bit(GLF_GREEDY, &gl->gl_flags))
return 1;
@@ -1785,43 +1798,6 @@ void gfs2_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data)
}
/**
- * gfs2_try_toss_inode - try to remove a particular inode struct from cache
- * sdp: the filesystem
- * inum: the inode number
- *
- */
-
-void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum)
-{
- struct gfs2_glock *gl;
- struct gfs2_inode *ip;
- int error;
-
- error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops,
- NO_CREATE, &gl);
- if (error || !gl)
- return;
-
- if (!gfs2_glmutex_trylock(gl))
- goto out;
-
- ip = gl->gl_object;
- if (!ip)
- goto out_unlock;
-
- if (atomic_read(&ip->i_count))
- goto out_unlock;
-
- gfs2_inode_destroy(ip, 1);
-
- out_unlock:
- gfs2_glmutex_unlock(gl);
-
- out:
- gfs2_glock_put(gl);
-}
-
-/**
* gfs2_iopen_go_callback - Try to kick the inode/vnode associated with an
* iopen glock from memory
* @io_gl: the iopen glock
@@ -1831,34 +1807,10 @@ void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum)
void gfs2_iopen_go_callback(struct gfs2_glock *io_gl, unsigned int state)
{
- struct gfs2_glock *i_gl;
if (state != LM_ST_UNLOCKED)
return;
-
- spin_lock(&io_gl->gl_spin);
- i_gl = io_gl->gl_object;
- if (i_gl) {
- gfs2_glock_hold(i_gl);
- spin_unlock(&io_gl->gl_spin);
- } else {
- spin_unlock(&io_gl->gl_spin);
- return;
- }
-
- if (gfs2_glmutex_trylock(i_gl)) {
- struct gfs2_inode *ip = i_gl->gl_object;
- if (ip) {
- gfs2_try_toss_vnode(ip);
- gfs2_glmutex_unlock(i_gl);
- gfs2_glock_schedule_for_reclaim(i_gl);
- goto out;
- }
- gfs2_glmutex_unlock(i_gl);
- }
-
- out:
- gfs2_glock_put(i_gl);
+ /* FIXME: remove this? */
}
/**
@@ -1935,11 +1887,6 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp)
atomic_inc(&sdp->sd_reclaimed);
if (gfs2_glmutex_trylock(gl)) {
- if (gl->gl_ops == &gfs2_inode_glops) {
- struct gfs2_inode *ip = gl->gl_object;
- if (ip && !atomic_read(&ip->i_count))
- gfs2_inode_destroy(ip, 1);
- }
if (queue_empty(gl, &gl->gl_holders) &&
gl->gl_state != LM_ST_UNLOCKED &&
demote_ok(gl))
@@ -2018,7 +1965,7 @@ static void scan_glock(struct gfs2_glock *gl)
if (gfs2_glmutex_trylock(gl)) {
if (gl->gl_ops == &gfs2_inode_glops) {
struct gfs2_inode *ip = gl->gl_object;
- if (ip && !atomic_read(&ip->i_count))
+ if (ip)
goto out_schedule;
}
if (queue_empty(gl, &gl->gl_holders) &&
@@ -2078,11 +2025,6 @@ static void clear_glock(struct gfs2_glock *gl)
}
if (gfs2_glmutex_trylock(gl)) {
- if (gl->gl_ops == &gfs2_inode_glops) {
- struct gfs2_inode *ip = gl->gl_object;
- if (ip && !atomic_read(&ip->i_count))
- gfs2_inode_destroy(ip, 1);
- }
if (queue_empty(gl, &gl->gl_holders) &&
gl->gl_state != LM_ST_UNLOCKED)
handle_callback(gl, LM_ST_UNLOCKED);
@@ -2199,13 +2141,11 @@ static int dump_inode(struct gfs2_inode *ip)
(unsigned long long)ip->i_num.no_formal_ino,
(unsigned long long)ip->i_num.no_addr);
printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode));
- printk(KERN_INFO " i_count = %d\n", atomic_read(&ip->i_count));
printk(KERN_INFO " i_flags =");
for (x = 0; x < 32; x++)
if (test_bit(x, &ip->i_flags))
printk(" %u", x);
printk(" \n");
- printk(KERN_INFO " vnode = %s\n", (ip->i_vnode) ? "yes" : "no");
error = 0;
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 2e0a2ba..fdf58db 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -88,9 +88,6 @@ void gfs2_holder_uninit(struct gfs2_holder *gh);
void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags);
void gfs2_glock_drop_th(struct gfs2_glock *gl);
-void gfs2_glmutex_lock(struct gfs2_glock *gl);
-void gfs2_glmutex_unlock(struct gfs2_glock *gl);
-
int gfs2_glock_nq(struct gfs2_holder *gh);
int gfs2_glock_poll(struct gfs2_holder *gh);
int gfs2_glock_wait(struct gfs2_holder *gh);
@@ -110,6 +107,7 @@ void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs);
void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, uint64_t number,
struct gfs2_glock_operations *glops,
unsigned int state, int flags);
+void gfs2_glock_inode_squish(struct inode *inode);
/**
* gfs2_glock_nq_init - intialize a holder and enqueue it on a glock
@@ -143,7 +141,6 @@ void gfs2_lvb_unhold(struct gfs2_glock *gl);
void gfs2_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data);
-void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum);
void gfs2_iopen_go_callback(struct gfs2_glock *gl, unsigned int state);
void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index e262f22..013bf5f 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -129,6 +129,7 @@ static void inode_go_xmote_bh(struct gfs2_glock *gl)
static void inode_go_drop_th(struct gfs2_glock *gl)
{
+ printk(KERN_INFO "drop th %p\n", gl->gl_object);
gfs2_pte_inval(gl);
gfs2_glock_drop_th(gl);
}
@@ -147,6 +148,7 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags)
if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
if (meta && data) {
+ printk(KERN_INFO "sync all\n");
gfs2_page_sync(gl, flags | DIO_START);
gfs2_log_flush(gl->gl_sbd, gl);
gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT);
@@ -224,6 +226,7 @@ static int inode_go_lock(struct gfs2_holder *gh)
return 0;
if (ip->i_vn != gl->gl_vn) {
+ printk(KERN_INFO "refresh inode %p\n", &ip->i_inode);
error = gfs2_inode_refresh(ip);
if (error)
return error;
@@ -288,7 +291,7 @@ static void inode_greedy(struct gfs2_glock *gl)
spin_unlock(&ip->i_spin);
- gfs2_inode_put(ip);
+ iput(&ip->i_inode);
}
/**
@@ -361,14 +364,14 @@ static void trans_go_xmote_th(struct gfs2_glock *gl, unsigned int state,
static void trans_go_xmote_bh(struct gfs2_glock *gl)
{
struct gfs2_sbd *sdp = gl->gl_sbd;
- struct gfs2_inode *ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
struct gfs2_glock *j_gl = ip->i_gl;
struct gfs2_log_header head;
int error;
if (gl->gl_state != LM_ST_UNLOCKED &&
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
- gfs2_meta_cache_flush(sdp->sd_jdesc->jd_inode->u.generic_ip);
+ gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode));
j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA);
error = gfs2_find_jhead(sdp->sd_jdesc, &head);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 8caefec..9a67a59 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -33,7 +33,6 @@ struct gfs2_inode;
struct gfs2_file;
struct gfs2_revoke;
struct gfs2_revoke_replay;
-struct gfs2_unlinked;
struct gfs2_quota_data;
struct gfs2_log_buf;
struct gfs2_trans;
@@ -245,16 +244,12 @@ struct gfs2_inode {
struct inode i_inode;
struct gfs2_inum i_num;
- atomic_t i_count;
unsigned long i_flags; /* GIF_... */
uint64_t i_vn;
- struct gfs2_dinode i_di;
-
- struct gfs2_glock *i_gl;
- struct gfs2_sbd *i_sbd;
- struct inode *i_vnode;
+ struct gfs2_dinode i_di; /* To be replaced by ref to block */
+ struct gfs2_glock *i_gl; /* Move into i_gh? */
struct gfs2_holder i_iopen_gh;
struct gfs2_holder i_gh; /* for prepare/commit_write only */
struct gfs2_alloc i_alloc;
@@ -262,18 +257,27 @@ struct gfs2_inode {
spinlock_t i_spin;
struct rw_semaphore i_rw_mutex;
-
unsigned int i_greedy;
unsigned long i_last_pfault;
struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT];
};
+/*
+ * Since i_inode is the first element of struct gfs2_inode,
+ * this is effectively a cast.
+ */
static inline struct gfs2_inode *GFS2_I(struct inode *inode)
{
return container_of(inode, struct gfs2_inode, i_inode);
}
+/* To be removed? */
+static inline struct gfs2_sbd *GFS2_SB(struct inode *inode)
+{
+ return inode->i_sb->s_fs_info;
+}
+
enum {
GFF_DID_DIRECT_ALLOC = 0,
};
@@ -296,18 +300,6 @@ struct gfs2_revoke_replay {
};
enum {
- ULF_LOCKED = 0,
-};
-
-struct gfs2_unlinked {
- struct list_head ul_list;
- unsigned int ul_count;
- struct gfs2_unlinked_tag ul_ut;
- unsigned long ul_flags; /* ULF_... */
- unsigned int ul_slot;
-};
-
-enum {
QDF_USER = 0,
QDF_CHANGE = 1,
QDF_LOCKED = 2,
@@ -436,7 +428,6 @@ struct gfs2_tune {
unsigned int gt_recoverd_secs;
unsigned int gt_logd_secs;
unsigned int gt_quotad_secs;
- unsigned int gt_inoded_secs;
unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */
unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */
@@ -495,7 +486,6 @@ struct gfs2_sbd {
uint32_t sd_hash_bsize; /* sizeof(exhash block) */
uint32_t sd_hash_bsize_shift;
uint32_t sd_hash_ptrs; /* Number of pointers in a hash block */
- uint32_t sd_ut_per_block;
uint32_t sd_qc_per_block;
uint32_t sd_max_dirres; /* Max blocks needed to add a directory entry */
uint32_t sd_max_height; /* Max height of a file's metadata tree */
@@ -527,7 +517,6 @@ struct gfs2_sbd {
struct inode *sd_statfs_inode;
struct inode *sd_ir_inode;
struct inode *sd_sc_inode;
- struct inode *sd_ut_inode;
struct inode *sd_qc_inode;
struct inode *sd_rindex;
struct inode *sd_quota_inode;
@@ -569,7 +558,6 @@ struct gfs2_sbd {
struct gfs2_holder sd_ir_gh;
struct gfs2_holder sd_sc_gh;
- struct gfs2_holder sd_ut_gh;
struct gfs2_holder sd_qc_gh;
/* Daemon stuff */
@@ -578,21 +566,9 @@ struct gfs2_sbd {
struct task_struct *sd_recoverd_process;
struct task_struct *sd_logd_process;
struct task_struct *sd_quotad_process;
- struct task_struct *sd_inoded_process;
struct task_struct *sd_glockd_process[GFS2_GLOCKD_MAX];
unsigned int sd_glockd_num;
- /* Unlinked inode stuff */
-
- struct list_head sd_unlinked_list;
- atomic_t sd_unlinked_count;
- spinlock_t sd_unlinked_spin;
- struct mutex sd_unlinked_mutex;
-
- unsigned int sd_unlinked_slots;
- unsigned int sd_unlinked_chunks;
- unsigned char **sd_unlinked_bitmap;
-
/* Quota stuff */
struct list_head sd_quota_list;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index c2c7d2b..4e9c421 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -35,7 +35,6 @@
#include "quota.h"
#include "rgrp.h"
#include "trans.h"
-#include "unlinked.h"
#include "util.h"
/**
@@ -72,7 +71,7 @@ static void inode_attr_in(struct gfs2_inode *ip, struct inode *inode)
inode->i_ctime.tv_nsec = 0;
inode->i_blksize = PAGE_SIZE;
inode->i_blocks = ip->i_di.di_blocks <<
- (ip->i_sbd->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
+ (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT);
if (ip->i_di.di_flags & GFS2_DIF_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
@@ -93,13 +92,8 @@ static void inode_attr_in(struct gfs2_inode *ip, struct inode *inode)
void gfs2_inode_attr_in(struct gfs2_inode *ip)
{
- struct inode *inode;
-
- inode = gfs2_ip2v_lookup(ip);
- if (inode) {
- inode_attr_in(ip, inode);
- iput(inode);
- }
+ struct inode *inode = &ip->i_inode;
+ inode_attr_in(ip, inode);
}
/**
@@ -112,9 +106,9 @@ void gfs2_inode_attr_in(struct gfs2_inode *ip)
void gfs2_inode_attr_out(struct gfs2_inode *ip)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
- gfs2_assert_withdraw(ip->i_sbd,
+ gfs2_assert_withdraw(GFS2_SB(inode),
(ip->i_di.di_mode & S_IFMT) == (inode->i_mode & S_IFMT));
ip->i_di.di_mode = inode->i_mode;
ip->i_di.di_uid = inode->i_uid;
@@ -124,114 +118,100 @@ void gfs2_inode_attr_out(struct gfs2_inode *ip)
ip->i_di.di_ctime = inode->i_ctime.tv_sec;
}
-/**
- * gfs2_ip2v_lookup - Get the struct inode for a struct gfs2_inode
- * @ip: the struct gfs2_inode to get the struct inode for
- *
- * Returns: A VFS inode, or NULL if none
- */
+static int iget_test(struct inode *inode, void *opaque)
+{
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_inum *inum = opaque;
+
+ if (ip && ip->i_num.no_addr == inum->no_addr)
+ return 1;
-struct inode *gfs2_ip2v_lookup(struct gfs2_inode *ip)
+ return 0;
+}
+
+static int iget_set(struct inode *inode, void *opaque)
{
- struct inode *inode = NULL;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_inum *inum = opaque;
- gfs2_assert_warn(ip->i_sbd, test_bit(GIF_MIN_INIT, &ip->i_flags));
+ ip->i_num = *inum;
+ return 0;
+}
- spin_lock(&ip->i_spin);
- if (ip->i_vnode)
- inode = igrab(ip->i_vnode);
- spin_unlock(&ip->i_spin);
+struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum)
+{
+ return ilookup5(sb, (unsigned long)inum->no_formal_ino,
+ iget_test, inum);
+}
- return inode;
+static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
+{
+ return iget5_locked(sb, (unsigned long)inum->no_formal_ino,
+ iget_test, iget_set, inum);
}
/**
- * gfs2_ip2v - Get/Create a struct inode for a struct gfs2_inode
- * @ip: the struct gfs2_inode to get the struct inode for
+ * gfs2_inode_lookup - Lookup an inode
+ * @sb: The super block
+ * @inum: The inode number
+ * @type: The type of the inode
*
- * Returns: A VFS inode, or NULL if no mem
+ * Returns: A VFS inode, or an error
*/
-struct inode *gfs2_ip2v(struct gfs2_inode *ip)
+struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned int type)
{
- struct inode *inode, *tmp;
-
- inode = gfs2_ip2v_lookup(ip);
- if (inode)
- return inode;
-
- tmp = new_inode(ip->i_sbd->sd_vfs);
- if (!tmp)
- return NULL;
-
- inode_attr_in(ip, tmp);
-
- if (S_ISREG(ip->i_di.di_mode)) {
- tmp->i_op = &gfs2_file_iops;
- tmp->i_fop = &gfs2_file_fops;
- tmp->i_mapping->a_ops = &gfs2_file_aops;
- } else if (S_ISDIR(ip->i_di.di_mode)) {
- tmp->i_op = &gfs2_dir_iops;
- tmp->i_fop = &gfs2_dir_fops;
- } else if (S_ISLNK(ip->i_di.di_mode)) {
- tmp->i_op = &gfs2_symlink_iops;
- } else {
- tmp->i_op = &gfs2_dev_iops;
- init_special_inode(tmp, tmp->i_mode, tmp->i_rdev);
- }
-
- tmp->u.generic_ip = NULL;
-
- for (;;) {
- spin_lock(&ip->i_spin);
- if (!ip->i_vnode)
- break;
- inode = igrab(ip->i_vnode);
- spin_unlock(&ip->i_spin);
+ struct inode *inode = gfs2_iget(sb, inum);
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_glock *io_gl;
+ int error;
- if (inode) {
- iput(tmp);
- return inode;
+ if (inode->i_state & I_NEW) {
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
+ umode_t mode = DT2IF(type);
+ inode->u.generic_ip = ip;
+ inode->i_mode = mode;
+
+ if (S_ISREG(mode)) {
+ inode->i_op = &gfs2_file_iops;
+ inode->i_fop = &gfs2_file_fops;
+ inode->i_mapping->a_ops = &gfs2_file_aops;
+ } else if (S_ISDIR(mode)) {
+ inode->i_op = &gfs2_dir_iops;
+ inode->i_fop = &gfs2_dir_fops;
+ } else if (S_ISLNK(mode)) {
+ inode->i_op = &gfs2_symlink_iops;
+ } else {
+ inode->i_op = &gfs2_dev_iops;
}
- yield();
- }
- inode = tmp;
+ error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
+ if (unlikely(error))
+ goto fail;
+ ip->i_gl->gl_object = ip;
- gfs2_inode_hold(ip);
- ip->i_vnode = inode;
- inode->u.generic_ip = ip;
+ error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
+ if (unlikely(error))
+ goto fail_put;
- spin_unlock(&ip->i_spin);
+ ip->i_vn = ip->i_gl->gl_vn - 1;
+ error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
+ if (unlikely(error))
+ goto fail_iopen;
- insert_inode_hash(inode);
+ gfs2_glock_put(io_gl);
+ unlock_new_inode(inode);
+ }
return inode;
-}
-
-static int iget_test(struct inode *inode, void *opaque)
-{
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_inum *inum = (struct gfs2_inum *)opaque;
-
- if (ip && ip->i_num.no_addr == inum->no_addr)
- return 1;
-
- return 0;
-}
-
-struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
-{
- return ilookup5(sb, (unsigned long)inum->no_formal_ino,
- iget_test, inum);
-}
-
-void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type)
-{
- if (!test_and_set_bit(GIF_MIN_INIT, &ip->i_flags)) {
- ip->i_di.di_nlink = 1;
- ip->i_di.di_mode = DT2IF(type);
- }
+fail_iopen:
+ gfs2_glock_put(io_gl);
+fail_put:
+ ip->i_gl->gl_object = NULL;
+ gfs2_glock_put(ip->i_gl);
+fail:
+ iput(inode);
+ return ERR_PTR(error);
}
/**
@@ -250,7 +230,7 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
if (error)
return error;
- if (gfs2_metatype_check(ip->i_sbd, dibh, GFS2_METATYPE_DI)) {
+ if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) {
brelse(dibh);
return -EIO;
}
@@ -273,151 +253,9 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
return 0;
}
-/**
- * inode_create - create a struct gfs2_inode
- * @i_gl: The glock covering the inode
- * @inum: The inode number
- * @io_gl: the iopen glock to acquire/hold (using holder in new gfs2_inode)
- * @io_state: the state the iopen glock should be acquired in
- * @ipp: pointer to put the returned inode in
- *
- * Returns: errno
- */
-
-static int inode_create(struct gfs2_glock *i_gl, const struct gfs2_inum *inum,
- struct gfs2_glock *io_gl, unsigned int io_state,
- struct gfs2_inode **ipp, int need_lock)
+int gfs2_dinode_dealloc(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = i_gl->gl_sbd;
- struct gfs2_inode *ip;
- int error = 0;
-
- ip = kmem_cache_alloc(gfs2_inode_cachep, GFP_KERNEL);
- if (!ip)
- return -ENOMEM;
- memset(ip, 0, sizeof(struct gfs2_inode));
- ip->i_num = *inum;
- atomic_set(&ip->i_count, 1);
- ip->i_vn = i_gl->gl_vn - 1;
- ip->i_gl = i_gl;
- ip->i_sbd = sdp;
- spin_lock_init(&ip->i_spin);
- init_rwsem(&ip->i_rw_mutex);
- ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
-
- if (need_lock) {
- error = gfs2_glock_nq_init(io_gl,
- io_state, GL_LOCAL_EXCL | GL_EXACT,
- &ip->i_iopen_gh);
- if (error)
- goto fail;
-
- spin_lock(&io_gl->gl_spin);
- gfs2_glock_hold(i_gl);
- io_gl->gl_object = i_gl;
- spin_unlock(&io_gl->gl_spin);
- }
-
- gfs2_glock_hold(i_gl);
- i_gl->gl_object = ip;
- atomic_inc(&sdp->sd_inode_count);
- *ipp = ip;
- return 0;
-
-fail:
- gfs2_meta_cache_flush(ip);
- kmem_cache_free(gfs2_inode_cachep, ip);
- *ipp = NULL;
- return error;
-}
-
-/**
- * gfs2_inode_get - Create or get a reference on an inode
- * @i_gl: The glock covering the inode
- * @inum: The inode number
- * @create:
- * @ipp: pointer to put the returned inode in
- *
- * Returns: errno
- */
-
-int gfs2_inode_get(struct gfs2_glock *i_gl, const struct gfs2_inum *inum,
- int create, struct gfs2_inode **ipp)
-{
- struct gfs2_sbd *sdp = i_gl->gl_sbd;
- struct gfs2_glock *io_gl;
- int error = 0;
-
- gfs2_glmutex_lock(i_gl);
-
- *ipp = i_gl->gl_object;
- if (*ipp) {
- error = -ESTALE;
- if ((*ipp)->i_num.no_formal_ino != inum->no_formal_ino)
- goto out;
- atomic_inc(&(*ipp)->i_count);
- error = 0;
- goto out;
- }
-
- if (!create)
- goto out;
-
- error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops,
- CREATE, &io_gl);
- if (!error) {
- error = inode_create(i_gl, inum, io_gl, LM_ST_SHARED, ipp, 1);
- gfs2_glock_put(io_gl);
- }
-
- out:
- gfs2_glmutex_unlock(i_gl);
-
- return error;
-}
-
-void gfs2_inode_hold(struct gfs2_inode *ip)
-{
- gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
- atomic_inc(&ip->i_count);
-}
-
-void gfs2_inode_put(struct gfs2_inode *ip)
-{
- gfs2_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0);
- atomic_dec(&ip->i_count);
-}
-
-void gfs2_inode_destroy(struct gfs2_inode *ip, int unlock)
-{
- struct gfs2_sbd *sdp = ip->i_sbd;
- struct gfs2_glock *i_gl = ip->i_gl;
-
- gfs2_assert_warn(sdp, !atomic_read(&ip->i_count));
- if (unlock) {
- struct gfs2_glock *io_gl = ip->i_iopen_gh.gh_gl;
- gfs2_assert(sdp, io_gl->gl_object == i_gl);
-
- spin_lock(&io_gl->gl_spin);
- io_gl->gl_object = NULL;
- spin_unlock(&io_gl->gl_spin);
- gfs2_glock_put(i_gl);
-
- gfs2_glock_dq_uninit(&ip->i_iopen_gh);
- }
-
- gfs2_meta_cache_flush(ip);
- kmem_cache_free(gfs2_inode_cachep, ip);
-
- i_gl->gl_object = NULL;
- gfs2_glock_put(i_gl);
-
- atomic_dec(&sdp->sd_inode_count);
-}
-
-static int dinode_dealloc(struct gfs2_inode *ip, struct gfs2_unlinked *ul)
-{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al;
struct gfs2_rgrpd *rgd;
int error;
@@ -450,7 +288,7 @@ static int dinode_dealloc(struct gfs2_inode *ip, struct gfs2_unlinked *ul)
if (error)
goto out_rindex_relse;
- error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
+ error = gfs2_trans_begin(sdp, RES_RG_BIT +
RES_STATFS + RES_QUOTA, 1);
if (error)
goto out_rg_gunlock;
@@ -459,191 +297,20 @@ static int dinode_dealloc(struct gfs2_inode *ip, struct gfs2_unlinked *ul)
gfs2_free_di(rgd, ip);
- error = gfs2_unlinked_ondisk_rm(sdp, ul);
-
gfs2_trans_end(sdp);
clear_bit(GLF_STICKY, &ip->i_gl->gl_flags);
- out_rg_gunlock:
+out_rg_gunlock:
gfs2_glock_dq_uninit(&al->al_rgd_gh);
-
- out_rindex_relse:
+out_rindex_relse:
gfs2_glock_dq_uninit(&al->al_ri_gh);
-
- out_qs:
+out_qs:
gfs2_quota_unhold(ip);
-
- out:
- gfs2_alloc_put(ip);
-
- return error;
-}
-
-/**
- * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode)
- * @sdp: the filesystem
- * @inum: the inode number to deallocate
- * @io_gh: a holder for the iopen glock for this inode
- *
- * N.B. When we enter this we already hold the iopen glock and getting
- * the glock for the inode means that we are grabbing the locks in the
- * "wrong" order so we must only so a try lock operation and fail if we
- * don't get the lock. Thats ok, since if we fail it means someone else
- * is using the inode still and thus we shouldn't be deallocating it
- * anyway.
- *
- * Returns: errno
- */
-
-static int inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul,
- struct gfs2_holder *io_gh)
-{
- struct gfs2_inode *ip;
- struct gfs2_holder i_gh;
- int error;
-
- error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
- &gfs2_inode_glops, LM_ST_EXCLUSIVE,
- LM_FLAG_TRY_1CB|GL_DUMP, &i_gh);
- switch(error) {
- case 0:
- break;
- case GLR_TRYFAILED:
- return 1; /* or back off and relock in different order? */
- default:
- return error;
- }
-
- gfs2_assert_warn(sdp, !i_gh.gh_gl->gl_object);
- error = inode_create(i_gh.gh_gl, &ul->ul_ut.ut_inum, io_gh->gh_gl,
- LM_ST_EXCLUSIVE, &ip, 0);
-
- if (error)
- goto out;
-
- error = gfs2_inode_refresh(ip);
- if (error)
- goto out_iput;
-
- if (ip->i_di.di_nlink) {
- if (gfs2_consist_inode(ip))
- gfs2_dinode_print(&ip->i_di);
- error = -EIO;
- goto out_iput;
- }
-
- if (S_ISDIR(ip->i_di.di_mode) &&
- (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
- error = gfs2_dir_exhash_dealloc(ip);
- if (error)
- goto out_iput;
- }
-
- if (ip->i_di.di_eattr) {
- error = gfs2_ea_dealloc(ip);
- if (error)
- goto out_iput;
- }
-
- if (!gfs2_is_stuffed(ip)) {
- error = gfs2_file_dealloc(ip);
- if (error)
- goto out_iput;
- }
-
- error = dinode_dealloc(ip, ul);
- if (error)
- goto out_iput;
-
-out_iput:
- gfs2_glmutex_lock(i_gh.gh_gl);
- gfs2_inode_put(ip);
- gfs2_inode_destroy(ip, 0);
- gfs2_glmutex_unlock(i_gh.gh_gl);
-
out:
- gfs2_glock_dq_uninit(&i_gh);
-
- return error;
-}
-
-/**
- * try_inode_dealloc - Try to deallocate an inode and all its blocks
- * @sdp: the filesystem
- *
- * Returns: 0 on success, -errno on error, 1 on busy (inode open)
- */
-
-static int try_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- int error = 0;
- struct gfs2_holder iogh;
-
- gfs2_try_toss_inode(sdp, &ul->ul_ut.ut_inum);
- error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
- &gfs2_iopen_glops, LM_ST_EXCLUSIVE,
- LM_FLAG_TRY_1CB, &iogh);
- switch (error) {
- case 0:
- break;
- case GLR_TRYFAILED:
- return 1;
- default:
- return error;
- }
-
- error = inode_dealloc(sdp, ul, &iogh);
- gfs2_glock_dq_uninit(&iogh);
-
- return error;
-}
-
-static int inode_dealloc_uninit(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- struct gfs2_rgrpd *rgd;
- struct gfs2_holder ri_gh, rgd_gh;
- int error;
-
- error = gfs2_rindex_hold(sdp, &ri_gh);
- if (error)
- return error;
-
- rgd = gfs2_blk2rgrpd(sdp, ul->ul_ut.ut_inum.no_addr);
- if (!rgd) {
- gfs2_consist(sdp);
- error = -EIO;
- goto out;
- }
-
- error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh);
- if (error)
- goto out;
-
- error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED + RES_STATFS, 0);
- if (error)
- goto out_gunlock;
-
- gfs2_free_uninit_di(rgd, ul->ul_ut.ut_inum.no_addr);
- gfs2_unlinked_ondisk_rm(sdp, ul);
-
- gfs2_trans_end(sdp);
-
- out_gunlock:
- gfs2_glock_dq_uninit(&rgd_gh);
- out:
- gfs2_glock_dq_uninit(&ri_gh);
-
+ gfs2_alloc_put(ip);
return error;
}
-int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- if (ul->ul_ut.ut_flags & GFS2_UTF_UNINIT)
- return inode_dealloc_uninit(sdp, ul);
- else
- return try_inode_dealloc(sdp, ul);
-}
-
/**
* gfs2_change_nlink - Change nlink count on inode
* @ip: The GFS2 inode
@@ -654,6 +321,7 @@ int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
{
+ struct gfs2_sbd *sdp = ip->i_inode.i_sb->s_fs_info;
struct buffer_head *dibh;
uint32_t nlink;
int error;
@@ -678,8 +346,30 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(&ip->i_di, dibh->b_data);
brelse(dibh);
+ mark_inode_dirty(&ip->i_inode);
- return 0;
+ if (ip->i_di.di_nlink == 0) {
+ struct gfs2_rgrpd *rgd;
+ struct gfs2_holder ri_gh, rg_gh;
+
+ error = gfs2_rindex_hold(sdp, &ri_gh);
+ if (error)
+ goto out;
+ error = -EIO;
+ rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
+ if (!rgd)
+ goto out_norgrp;
+ error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
+ if (error)
+ goto out_norgrp;
+
+ gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */
+ gfs2_glock_dq_uninit(&rg_gh);
+out_norgrp:
+ gfs2_glock_dq_uninit(&ri_gh);
+ }
+out:
+ return error;
}
struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
@@ -703,18 +393,15 @@ struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
* Returns: errno
*/
-struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
- struct nameidata *nd)
+struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
+ int is_root, struct nameidata *nd)
{
struct super_block *sb = dir->i_sb;
- struct gfs2_inode *ipp;
- struct gfs2_inode *dip = dir->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(dir);
struct gfs2_holder d_gh;
struct gfs2_inum inum;
unsigned int type;
- struct gfs2_glock *gl;
int error = 0;
struct inode *inode = NULL;
@@ -742,34 +429,18 @@ struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
if (error)
goto out;
- error = gfs2_glock_get(sdp, inum.no_addr, &gfs2_inode_glops,
- CREATE, &gl);
- if (error)
- goto out;
-
- error = gfs2_inode_get(gl, &inum, CREATE, &ipp);
- if (!error)
- gfs2_inode_min_init(ipp, type);
-
- gfs2_glock_put(gl);
+ inode = gfs2_inode_lookup(sb, &inum, type);
out:
gfs2_glock_dq_uninit(&d_gh);
if (error == -ENOENT)
return NULL;
- if (error == 0) {
- inode = gfs2_ip2v(ipp);
- gfs2_inode_put(ipp);
- if (!inode)
- return ERR_PTR(-ENOMEM);
- return inode;
- }
- return ERR_PTR(error);
+ return inode;
}
static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
{
- struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
struct buffer_head *bh;
struct gfs2_inum_range ir;
int error;
@@ -810,8 +481,8 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino)
static int pick_formal_ino_2(struct gfs2_sbd *sdp, uint64_t *formal_ino)
{
- struct gfs2_inode *ip = sdp->sd_ir_inode->u.generic_ip;
- struct gfs2_inode *m_ip = sdp->sd_inum_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
+ struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode);
struct gfs2_holder gh;
struct buffer_head *bh;
struct gfs2_inum_range ir;
@@ -895,12 +566,12 @@ static int pick_formal_ino(struct gfs2_sbd *sdp, uint64_t *inum)
* Returns: errno
*/
-static int create_ok(struct gfs2_inode *dip, struct qstr *name,
+static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
unsigned int mode)
{
int error;
- error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
+ error = gfs2_repermission(&dip->i_inode, MAY_WRITE | MAY_EXEC, NULL);
if (error)
return error;
@@ -908,7 +579,7 @@ static int create_ok(struct gfs2_inode *dip, struct qstr *name,
if (!dip->i_di.di_nlink)
return -EPERM;
- error = gfs2_dir_search(dip->i_vnode, name, NULL, NULL);
+ error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL);
switch (error) {
case -ENOENT:
error = 0;
@@ -930,7 +601,7 @@ static int create_ok(struct gfs2_inode *dip, struct qstr *name,
static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
unsigned int *uid, unsigned int *gid)
{
- if (dip->i_sbd->sd_args.ar_suiddir &&
+ if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir &&
(dip->i_di.di_mode & S_ISUID) &&
dip->i_di.di_uid) {
if (S_ISDIR(*mode))
@@ -949,9 +620,9 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
*gid = current->fsgid;
}
-static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_unlinked *ul)
+static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum *inum)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
int error;
gfs2_alloc_get(dip);
@@ -961,15 +632,11 @@ static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_unlinked *ul)
if (error)
goto out;
- error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_UNLINKED +
- RES_STATFS, 0);
+ error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0);
if (error)
goto out_ipreserv;
- ul->ul_ut.ut_inum.no_addr = gfs2_alloc_di(dip);
-
- ul->ul_ut.ut_flags = GFS2_UTF_UNINIT;
- error = gfs2_unlinked_ondisk_add(sdp, ul);
+ inum->no_addr = gfs2_alloc_di(dip);
gfs2_trans_end(sdp);
@@ -997,7 +664,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
struct gfs2_inum *inum, unsigned int mode,
unsigned int uid, unsigned int gid)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct gfs2_dinode *di;
struct buffer_head *dibh;
@@ -1049,9 +716,9 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
}
static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
- unsigned int mode, struct gfs2_unlinked *ul)
+ unsigned int mode, struct gfs2_inum *inum)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
unsigned int uid, gid;
int error;
@@ -1066,28 +733,25 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
if (error)
goto out_quota;
- error = gfs2_trans_begin(sdp, RES_DINODE + RES_UNLINKED + RES_QUOTA, 0);
+ error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0);
if (error)
goto out_quota;
- ul->ul_ut.ut_flags = 0;
- error = gfs2_unlinked_ondisk_munge(sdp, ul);
- init_dinode(dip, gl, &ul->ul_ut.ut_inum, mode, uid, gid);
+ init_dinode(dip, gl, inum, mode, uid, gid);
gfs2_quota_change(dip, +1, uid, gid);
gfs2_trans_end(sdp);
- out_quota:
+out_quota:
gfs2_quota_unlock(dip);
-
- out:
+out:
gfs2_alloc_put(dip);
return error;
}
-static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
- struct gfs2_inode *ip, struct gfs2_unlinked *ul)
+static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
+ struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct gfs2_alloc *al;
int alloc_required;
struct buffer_head *dibh;
@@ -1099,7 +763,7 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
if (error)
goto fail;
- error = alloc_required = gfs2_diradd_alloc_required(dip->i_vnode, name);
+ error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name);
if (alloc_required < 0)
goto fail;
if (alloc_required) {
@@ -1116,20 +780,17 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
al->al_rgd->rd_ri.ri_length +
- 2 * RES_DINODE + RES_UNLINKED +
+ 2 * RES_DINODE +
RES_STATFS + RES_QUOTA, 0);
if (error)
goto fail_ipreserv;
} else {
- error = gfs2_trans_begin(sdp,
- RES_LEAF +
- 2 * RES_DINODE +
- RES_UNLINKED, 0);
+ error = gfs2_trans_begin(sdp, RES_LEAF + 2 * RES_DINODE, 0);
if (error)
goto fail_quota_locks;
}
- error = gfs2_dir_add(dip->i_vnode, name, &ip->i_num, IF2DT(ip->i_di.di_mode));
+ error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_di.di_mode));
if (error)
goto fail_end_trans;
@@ -1140,11 +801,6 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(&ip->i_di, dibh->b_data);
brelse(dibh);
-
- error = gfs2_unlinked_ondisk_rm(sdp, ul);
- if (error)
- goto fail_end_trans;
-
return 0;
fail_end_trans:
@@ -1178,23 +834,19 @@ fail:
* Returns: An inode
*/
-struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
+struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
unsigned int mode)
{
struct inode *inode;
struct gfs2_inode *dip = ghs->gh_gl->gl_object;
- struct gfs2_sbd *sdp = dip->i_sbd;
- struct gfs2_unlinked *ul;
- struct gfs2_inode *ip;
+ struct inode *dir = &dip->i_inode;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
+ struct gfs2_inum inum;
int error;
if (!name->len || name->len > GFS2_FNAMESIZE)
return ERR_PTR(-ENAMETOOLONG);
- error = gfs2_unlinked_get(sdp, &ul);
- if (error)
- return ERR_PTR(error);
-
gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
error = gfs2_glock_nq(ghs);
if (error)
@@ -1204,22 +856,21 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
if (error)
goto fail_gunlock;
- error = pick_formal_ino(sdp, &ul->ul_ut.ut_inum.no_formal_ino);
+ error = pick_formal_ino(sdp, &inum.no_formal_ino);
if (error)
goto fail_gunlock;
- error = alloc_dinode(dip, ul);
+ error = alloc_dinode(dip, &inum);
if (error)
goto fail_gunlock;
- if (ul->ul_ut.ut_inum.no_addr < dip->i_num.no_addr) {
+ if (inum.no_addr < dip->i_num.no_addr) {
gfs2_glock_dq(ghs);
- error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
+ error = gfs2_glock_nq_num(sdp, inum.no_addr,
&gfs2_inode_glops, LM_ST_EXCLUSIVE,
GL_SKIP, ghs + 1);
if (error) {
- gfs2_unlinked_put(sdp, ul);
return ERR_PTR(error);
}
@@ -1227,7 +878,6 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
error = gfs2_glock_nq(ghs);
if (error) {
gfs2_glock_dq_uninit(ghs + 1);
- gfs2_unlinked_put(sdp, ul);
return ERR_PTR(error);
}
@@ -1235,95 +885,48 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
if (error)
goto fail_gunlock2;
} else {
- error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
+ error = gfs2_glock_nq_num(sdp, inum.no_addr,
&gfs2_inode_glops, LM_ST_EXCLUSIVE,
GL_SKIP, ghs + 1);
if (error)
goto fail_gunlock;
}
- error = make_dinode(dip, ghs[1].gh_gl, mode, ul);
+ error = make_dinode(dip, ghs[1].gh_gl, mode, &inum);
if (error)
goto fail_gunlock2;
- error = gfs2_inode_get(ghs[1].gh_gl, &ul->ul_ut.ut_inum, CREATE, &ip);
- if (error)
+ inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode));
+ if (IS_ERR(inode))
goto fail_gunlock2;
- error = gfs2_inode_refresh(ip);
+ error = gfs2_inode_refresh(GFS2_I(inode));
if (error)
goto fail_iput;
- error = gfs2_acl_create(dip, ip);
+ error = gfs2_acl_create(dip, GFS2_I(inode));
if (error)
goto fail_iput;
- error = link_dinode(dip, name, ip, ul);
+ error = link_dinode(dip, name, GFS2_I(inode));
if (error)
goto fail_iput;
- gfs2_unlinked_put(sdp, ul);
-
- inode = gfs2_ip2v(ip);
- gfs2_inode_put(ip);
if (!inode)
return ERR_PTR(-ENOMEM);
return inode;
fail_iput:
- gfs2_inode_put(ip);
-
+ iput(inode);
fail_gunlock2:
gfs2_glock_dq_uninit(ghs + 1);
-
fail_gunlock:
gfs2_glock_dq(ghs);
-
fail:
- gfs2_unlinked_put(sdp, ul);
return ERR_PTR(error);
}
/**
- * gfs2_unlinki - Unlink a file
- * @dip: The inode of the directory
- * @name: The name of the file to be unlinked
- * @ip: The inode of the file to be removed
- *
- * Assumes Glocks on both dip and ip are held.
- *
- * Returns: errno
- */
-
-int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
- struct gfs2_inode *ip, struct gfs2_unlinked *ul)
-{
- struct gfs2_sbd *sdp = dip->i_sbd;
- int error;
-
- error = gfs2_dir_del(dip, name);
- if (error)
- return error;
-
- error = gfs2_change_nlink(ip, -1);
- if (error)
- return error;
-
- /* If this inode is being unlinked from the directory structure,
- we need to mark that in the log so that it isn't lost during
- a crash. */
-
- if (!ip->i_di.di_nlink) {
- ul->ul_ut.ut_inum = ip->i_num;
- error = gfs2_unlinked_ondisk_add(sdp, ul);
- if (!error)
- set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
- }
-
- return error;
-}
-
-/**
* gfs2_rmdiri - Remove a directory
* @dip: The parent directory of the directory to be removed
* @name: The name of the directory to be removed
@@ -1334,10 +937,9 @@ int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
* Returns: errno
*/
-int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
- struct gfs2_inode *ip, struct gfs2_unlinked *ul)
+int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
+ struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
struct qstr dotname;
int error;
@@ -1360,9 +962,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
if (error)
return error;
- dotname.len = 2;
- dotname.name = "..";
- dotname.hash = gfs2_disk_hash(dotname.name, dotname.len);
+ gfs2_str2qstr(&dotname, "..");
error = gfs2_dir_del(ip, &dotname);
if (error)
return error;
@@ -1371,15 +971,6 @@ int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
if (error)
return error;
- /* This inode is being unlinked from the directory structure and
- we need to mark that in the log so that it isn't lost during
- a crash. */
-
- ul->ul_ut.ut_inum = ip->i_num;
- error = gfs2_unlinked_ondisk_add(sdp, ul);
- if (!error)
- set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
-
return error;
}
@@ -1394,30 +985,29 @@ int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
* Returns: 0 if the parent/child relationship is correct, errno if it isn't
*/
-int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
+int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
struct gfs2_inode *ip)
{
struct gfs2_inum inum;
unsigned int type;
int error;
- if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode))
+ if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
return -EPERM;
if ((dip->i_di.di_mode & S_ISVTX) &&
dip->i_di.di_uid != current->fsuid &&
- ip->i_di.di_uid != current->fsuid &&
- !capable(CAP_FOWNER))
+ ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER))
return -EPERM;
- if (IS_APPEND(dip->i_vnode))
+ if (IS_APPEND(&dip->i_inode))
return -EPERM;
- error = gfs2_repermission(dip->i_vnode, MAY_WRITE | MAY_EXEC, NULL);
+ error = gfs2_repermission(&dip->i_inode, MAY_WRITE | MAY_EXEC, NULL);
if (error)
return error;
- error = gfs2_dir_search(dip->i_vnode, name, &inum, &type);
+ error = gfs2_dir_search(&dip->i_inode, name, &inum, &type);
if (error)
return error;
@@ -1445,7 +1035,7 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
{
- struct inode *dir = to->i_vnode;
+ struct inode *dir = &to->i_inode;
struct super_block *sb = dir->i_sb;
struct inode *tmp;
struct qstr dotdot;
@@ -1456,7 +1046,7 @@ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
igrab(dir);
for (;;) {
- if (dir == this->i_vnode) {
+ if (dir == &this->i_inode) {
error = -EINVAL;
break;
}
@@ -1528,12 +1118,10 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x);
*len = x;
- out_brelse:
+out_brelse:
brelse(dibh);
-
- out:
+out:
gfs2_glock_dq_uninit(&i_gh);
-
return error;
}
@@ -1622,12 +1210,10 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh)
return 0;
- fail_end_trans:
+fail_end_trans:
gfs2_trans_end(sdp);
-
- fail:
+fail:
gfs2_glock_dq(gh);
-
return error;
}
@@ -1722,49 +1308,6 @@ int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs)
return error;
}
-/**
- * gfs2_try_toss_vnode - See if we can toss a vnode from memory
- * @ip: the inode
- *
- * Returns: 1 if the vnode was tossed
- */
-
-void gfs2_try_toss_vnode(struct gfs2_inode *ip)
-{
- struct inode *inode;
-
- inode = gfs2_ip2v_lookup(ip);
- if (!inode)
- return;
-
- d_prune_aliases(inode);
-
- if (S_ISDIR(ip->i_di.di_mode)) {
- struct list_head *head = &inode->i_dentry;
- struct dentry *d = NULL;
-
- spin_lock(&dcache_lock);
- if (list_empty(head))
- spin_unlock(&dcache_lock);
- else {
- d = list_entry(head->next, struct dentry, d_alias);
- dget_locked(d);
- spin_unlock(&dcache_lock);
-
- if (have_submounts(d))
- dput(d);
- else {
- shrink_dcache_parent(d);
- dput(d);
- d_prune_aliases(inode);
- }
- }
- }
-
- inode->i_nlink = 0;
- iput(inode);
-}
-
static int
__gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
@@ -1774,8 +1317,8 @@ __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!error) {
- error = inode_setattr(ip->i_vnode, attr);
- gfs2_assert_warn(ip->i_sbd, !error);
+ error = inode_setattr(&ip->i_inode, attr);
+ gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
gfs2_inode_attr_out(ip);
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
@@ -1802,13 +1345,13 @@ int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
if (current->journal_info)
return __gfs2_setattr_simple(ip, attr);
- error = gfs2_trans_begin(ip->i_sbd, RES_DINODE, 0);
+ error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0);
if (error)
return error;
error = __gfs2_setattr_simple(ip, attr);
- gfs2_trans_end(ip->i_sbd);
+ gfs2_trans_end(GFS2_SB(&ip->i_inode));
return error;
}
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 5ef2131..30cfcc1 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -27,32 +27,20 @@ static inline int gfs2_is_dir(struct gfs2_inode *ip)
void gfs2_inode_attr_in(struct gfs2_inode *ip);
void gfs2_inode_attr_out(struct gfs2_inode *ip);
-struct inode *gfs2_ip2v_lookup(struct gfs2_inode *ip);
-struct inode *gfs2_ip2v(struct gfs2_inode *ip);
-struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum);
+struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned type);
+struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum);
-void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type);
int gfs2_inode_refresh(struct gfs2_inode *ip);
-int gfs2_inode_get(struct gfs2_glock *i_gl,
- const struct gfs2_inum *inum, int create,
- struct gfs2_inode **ipp);
-void gfs2_inode_hold(struct gfs2_inode *ip);
-void gfs2_inode_put(struct gfs2_inode *ip);
-void gfs2_inode_destroy(struct gfs2_inode *ip, int unlock);
-
-int gfs2_inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-
+int gfs2_dinode_dealloc(struct gfs2_inode *inode);
int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
-struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
- struct nameidata *nd);
-struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name,
+struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
+ int is_root, struct nameidata *nd);
+struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
unsigned int mode);
-int gfs2_unlinki(struct gfs2_inode *dip, struct qstr *name,
- struct gfs2_inode *ip, struct gfs2_unlinked *ul);
-int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name,
- struct gfs2_inode *ip, struct gfs2_unlinked *ul);
-int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
+int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
+ struct gfs2_inode *ip);
+int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
struct gfs2_inode *ip);
int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
@@ -60,8 +48,6 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
int gfs2_glock_nq_atime(struct gfs2_holder *gh);
int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs);
-void gfs2_try_toss_vnode(struct gfs2_inode *ip);
-
int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
int gfs2_repermission(struct inode *inode, int mask, struct nameidata *nd);
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 2a8b4b7..483d4fa 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -213,6 +213,9 @@ static uint64_t log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
int bdy;
error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy);
+ if (!(!error && dbn)) {
+ printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, dbn, lbn);
+ }
gfs2_assert_withdraw(sdp, !error && dbn);
return dbn;
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index e4c75a7..a76f1a7 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -184,8 +184,7 @@ static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
static void buf_lo_before_scan(struct gfs2_jdesc *jd,
struct gfs2_log_header *head, int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
if (pass != 0)
return;
@@ -198,8 +197,8 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
struct gfs2_log_descriptor *ld, __be64 *ptr,
int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
struct gfs2_glock *gl = ip->i_gl;
unsigned int blks = be32_to_cpu(ld->ld_data1);
struct buffer_head *bh_log, *bh_ip;
@@ -245,8 +244,8 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
if (error) {
gfs2_meta_sync(ip->i_gl,
@@ -332,8 +331,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
struct gfs2_log_header *head, int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
if (pass != 0)
return;
@@ -346,8 +344,7 @@ static int revoke_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
struct gfs2_log_descriptor *ld, __be64 *ptr,
int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
unsigned int blks = be32_to_cpu(ld->ld_length);
unsigned int revokes = be32_to_cpu(ld->ld_data1);
struct buffer_head *bh;
@@ -393,8 +390,7 @@ static int revoke_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
if (error) {
gfs2_revoke_clean(sdp);
@@ -465,7 +461,7 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
struct gfs2_trans *tr = current->journal_info;
struct address_space *mapping = bd->bd_bh->b_page->mapping;
- struct gfs2_inode *ip = mapping->host->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(mapping->host);
tr->tr_touched = 1;
if (!list_empty(&bd->bd_list_tr) &&
@@ -665,8 +661,8 @@ static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
struct gfs2_log_descriptor *ld,
__be64 *ptr, int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
struct gfs2_glock *gl = ip->i_gl;
unsigned int blks = be32_to_cpu(ld->ld_data1);
struct buffer_head *bh_log, *bh_ip;
@@ -716,8 +712,8 @@ static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
if (error) {
gfs2_meta_sync(ip->i_gl,
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index b24d0b4..c112943 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -29,8 +29,6 @@ static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&ip->i_inode);
- atomic_set(&ip->i_count, 0);
- ip->i_vnode = &ip->i_inode;
spin_lock_init(&ip->i_spin);
init_rwsem(&ip->i_rw_mutex);
memset(ip->i_cache, 0, sizeof(ip->i_cache));
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index c785172..2523d42 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -91,9 +91,6 @@ static void stuck_releasepage(struct buffer_head *bh)
fs_warn(sdp, "ip = %llu %llu\n",
(unsigned long long)ip->i_num.no_formal_ino,
(unsigned long long)ip->i_num.no_addr);
- fs_warn(sdp, "ip->i_count = %d, ip->i_vnode = %s\n",
- atomic_read(&ip->i_count),
- (ip->i_vnode) ? "!NULL" : "NULL");
for (x = 0; x < GFS2_MAX_META_HEIGHT; x++)
fs_warn(sdp, "ip->i_cache[%u] = %s\n",
@@ -567,7 +564,6 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
bd = kmem_cache_alloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL),
memset(bd, 0, sizeof(struct gfs2_bufdata));
-
bd->bd_bh = bh;
bd->bd_gl = gl;
@@ -664,7 +660,7 @@ void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
void gfs2_meta_wipe(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct inode *aspace = ip->i_gl->gl_aspace;
struct buffer_head *bh;
@@ -770,7 +766,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, uint64_t num,
if (new)
meta_prep_new(bh);
else {
- error = gfs2_meta_reread(ip->i_sbd, bh,
+ error = gfs2_meta_reread(GFS2_SB(&ip->i_inode), bh,
DIO_START | DIO_WAIT);
if (error) {
brelse(bh);
@@ -797,7 +793,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, uint64_t num,
}
if (new) {
- if (gfs2_assert_warn(ip->i_sbd, height)) {
+ if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), height)) {
brelse(bh);
return -EIO;
}
@@ -805,7 +801,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, uint64_t num,
gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
- } else if (gfs2_metatype_check(ip->i_sbd, bh,
+ } else if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh,
(height) ? GFS2_METATYPE_IN : GFS2_METATYPE_DI)) {
brelse(bh);
return -EIO;
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
index be5c86e..09154ad 100644
--- a/fs/gfs2/ondisk.c
+++ b/fs/gfs2/ondisk.c
@@ -293,23 +293,6 @@ void gfs2_statfs_change_out(struct gfs2_statfs_change *sc, char *buf)
str->sc_dinodes = cpu_to_be64(sc->sc_dinodes);
}
-void gfs2_unlinked_tag_in(struct gfs2_unlinked_tag *ut, char *buf)
-{
- struct gfs2_unlinked_tag *str = (struct gfs2_unlinked_tag *)buf;
-
- gfs2_inum_in(&ut->ut_inum, buf);
- ut->ut_flags = be32_to_cpu(str->ut_flags);
-}
-
-void gfs2_unlinked_tag_out(struct gfs2_unlinked_tag *ut, char *buf)
-{
- struct gfs2_unlinked_tag *str = (struct gfs2_unlinked_tag *)buf;
-
- gfs2_inum_out(&ut->ut_inum, buf);
- str->ut_flags = cpu_to_be32(ut->ut_flags);
- str->__pad = 0;
-}
-
void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf)
{
struct gfs2_quota_change *str = (struct gfs2_quota_change *)buf;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 16d3ebd..207363a 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -81,7 +81,6 @@ int gfs2_get_block(struct inode *inode, sector_t lblock,
static int get_block_noalloc(struct inode *inode, sector_t lblock,
struct buffer_head *bh_result, int create)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
int new = 0;
uint64_t dblock;
int error;
@@ -93,7 +92,7 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock,
if (dblock)
map_bh(bh_result, inode->i_sb, dblock);
- else if (gfs2_assert_withdraw(ip->i_sbd, !create))
+ else if (gfs2_assert_withdraw(GFS2_SB(inode), !create))
error = -EIO;
if (boundary)
set_buffer_boundary(bh_result);
@@ -114,8 +113,8 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock,
static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
{
struct inode *inode = page->mapping->host;
- struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
loff_t i_size = i_size_read(inode);
pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
unsigned offset;
@@ -216,8 +215,8 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
static int gfs2_readpage(struct file *file, struct page *page)
{
- struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
struct gfs2_holder gh;
int error;
@@ -271,8 +270,8 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages)
{
struct inode *inode = mapping->host;
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct gfs2_holder gh;
unsigned page_idx;
int ret;
@@ -345,8 +344,8 @@ out_unlock:
static int gfs2_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
- struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(page->mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
unsigned int data_blocks, ind_blocks, rblocks;
int alloc_required;
int error = 0;
@@ -440,8 +439,8 @@ static int gfs2_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
int error = -EOPNOTSUPP;
struct buffer_head *dibh;
struct gfs2_alloc *al = &ip->i_alloc;;
@@ -520,7 +519,7 @@ fail_nounlock:
static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
{
- struct gfs2_inode *ip = mapping->host->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(mapping->host);
struct gfs2_holder i_gh;
sector_t dblock = 0;
int error;
@@ -594,7 +593,7 @@ static ssize_t gfs2_direct_IO_write(struct kiocb *iocb, const struct iovec *iov,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder gh;
int rv;
@@ -641,8 +640,8 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
if (rw == WRITE)
return gfs2_direct_IO_write(iocb, iov, offset, nr_segs);
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index fef415e..fd55979 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -38,8 +38,8 @@
static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
{
struct dentry *parent = dget_parent(dentry);
- struct gfs2_sbd *sdp = parent->d_inode->i_sb->s_fs_info;
- struct gfs2_inode *dip = parent->d_inode->u.generic_ip;
+ struct gfs2_sbd *sdp = GFS2_SB(parent->d_inode);
+ struct gfs2_inode *dip = GFS2_I(parent->d_inode);
struct inode *inode = dentry->d_inode;
struct gfs2_holder d_gh;
struct gfs2_inode *ip;
@@ -71,7 +71,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
goto fail_gunlock;
}
- ip = inode->u.generic_ip;
+ ip = GFS2_I(inode);
if (!gfs2_inum_equal(&ip->i_num, &inum))
goto invalid_gunlock;
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index a376ead..eacc1c0 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -66,7 +66,7 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
{
struct inode *inode = dentry->d_inode;
struct super_block *sb = inode->i_sb;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
if (*len < 4 || (connectable && *len < 8))
return 255;
@@ -86,8 +86,8 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
spin_lock(&dentry->d_lock);
inode = dentry->d_parent->d_inode;
- ip = inode->u.generic_ip;
- gfs2_inode_hold(ip);
+ ip = GFS2_I(inode);
+ igrab(inode);
spin_unlock(&dentry->d_lock);
fh[4] = ip->i_num.no_formal_ino >> 32;
@@ -100,7 +100,7 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
fh[7] = cpu_to_be32(fh[7]);
*len = 8;
- gfs2_inode_put(ip);
+ iput(inode);
return *len;
}
@@ -142,8 +142,8 @@ static int gfs2_get_name(struct dentry *parent, char *name,
if (!S_ISDIR(dir->i_mode) || !inode)
return -EINVAL;
- dip = dir->u.generic_ip;
- ip = inode->u.generic_ip;
+ dip = GFS2_I(dir);
+ ip = GFS2_I(inode);
*name = 0;
gnfd.inum = ip->i_num;
@@ -189,39 +189,30 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
{
struct gfs2_sbd *sdp = sb->s_fs_info;
- struct gfs2_inum *inum = (struct gfs2_inum *)inum_p;
+ struct gfs2_inum *inum = inum_p;
struct gfs2_holder i_gh, ri_gh, rgd_gh;
struct gfs2_rgrpd *rgd;
- struct gfs2_inode *ip;
struct inode *inode;
struct dentry *dentry;
int error;
/* System files? */
- inode = gfs2_iget(sb, inum);
+ inode = gfs2_ilookup(sb, inum);
if (inode) {
- ip = inode->u.generic_ip;
- if (ip->i_num.no_formal_ino != inum->no_formal_ino) {
+ if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) {
iput(inode);
return ERR_PTR(-ESTALE);
}
goto out_inode;
}
- error = gfs2_glock_nq_num(sdp,
- inum->no_addr, &gfs2_inode_glops,
+ error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops,
LM_ST_SHARED, LM_FLAG_ANY | GL_LOCAL_EXCL,
&i_gh);
if (error)
return ERR_PTR(error);
- error = gfs2_inode_get(i_gh.gh_gl, inum, NO_CREATE, &ip);
- if (error)
- goto fail;
- if (ip)
- goto out_ip;
-
error = gfs2_rindex_hold(sdp, &ri_gh);
if (error)
goto fail;
@@ -242,32 +233,29 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
gfs2_glock_dq_uninit(&rgd_gh);
gfs2_glock_dq_uninit(&ri_gh);
- error = gfs2_inode_get(i_gh.gh_gl, inum, CREATE, &ip);
- if (error)
+ inode = gfs2_inode_lookup(sb, inum, DT_UNKNOWN);
+ if (!inode)
+ goto fail;
+ if (IS_ERR(inode)) {
+ error = PTR_ERR(inode);
goto fail;
+ }
- error = gfs2_inode_refresh(ip);
+ error = gfs2_inode_refresh(GFS2_I(inode));
if (error) {
- gfs2_inode_put(ip);
+ iput(inode);
goto fail;
}
- out_ip:
error = -EIO;
- if (ip->i_di.di_flags & GFS2_DIF_SYSTEM) {
- gfs2_inode_put(ip);
+ if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) {
+ iput(inode);
goto fail;
}
gfs2_glock_dq_uninit(&i_gh);
- inode = gfs2_ip2v(ip);
- gfs2_inode_put(ip);
-
- if (!inode)
- return ERR_PTR(-ENOMEM);
-
- out_inode:
+out_inode:
dentry = d_alloc_anon(inode);
if (!dentry) {
iput(inode);
@@ -276,13 +264,13 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_p)
return dentry;
- fail_rgd:
+fail_rgd:
gfs2_glock_dq_uninit(&rgd_gh);
- fail_rindex:
+fail_rindex:
gfs2_glock_dq_uninit(&ri_gh);
- fail:
+fail:
gfs2_glock_dq_uninit(&i_gh);
return ERR_PTR(error);
}
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 1e8f602..222f3be 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -105,7 +105,7 @@ static int gfs2_read_actor(read_descriptor_t *desc, struct page *page,
int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
char *buf, loff_t *pos, unsigned size)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
read_descriptor_t desc;
desc.written = 0;
desc.arg.buf = buf;
@@ -131,7 +131,7 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
{
- struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
struct gfs2_holder i_gh;
loff_t error;
@@ -178,7 +178,7 @@ static ssize_t __gfs2_file_aio_read(struct kiocb *iocb,
unsigned long nr_segs, loff_t *ppos)
{
struct file *filp = iocb->ki_filp;
- struct gfs2_inode *ip = filp->f_mapping->host->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(filp->f_mapping->host);
struct gfs2_holder gh;
ssize_t retval;
unsigned long seg;
@@ -361,13 +361,13 @@ static int filldir_reg_func(void *opaque, const char *name, unsigned int length,
static int readdir_reg(struct file *file, void *dirent, filldir_t filldir)
{
struct inode *dir = file->f_mapping->host;
- struct gfs2_inode *dip = dir->u.generic_ip;
+ struct gfs2_inode *dip = GFS2_I(dir);
struct filldir_reg fdr;
struct gfs2_holder d_gh;
uint64_t offset = file->f_pos;
int error;
- fdr.fdr_sbd = dip->i_sbd;
+ fdr.fdr_sbd = GFS2_SB(dir);
fdr.fdr_prefetch = 1;
fdr.fdr_filldir = filldir;
fdr.fdr_opaque = dirent;
@@ -451,8 +451,8 @@ static int filldir_bad_func(void *opaque, const char *name, unsigned int length,
static int readdir_bad(struct file *file, void *dirent, filldir_t filldir)
{
struct inode *dir = file->f_mapping->host;
- struct gfs2_inode *dip = dir->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(dir);
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
struct filldir_reg fdr;
unsigned int entries, size;
struct filldir_bad *fdb;
@@ -561,7 +561,7 @@ static const u32 gfs2_to_iflags[32] = {
static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
{
struct inode *inode = filp->f_dentry->d_inode;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder gh;
int error;
u32 iflags;
@@ -601,8 +601,8 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
{
struct inode *inode = filp->f_dentry->d_inode;
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *bh;
struct gfs2_holder gh;
int error;
@@ -693,7 +693,7 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
struct gfs2_holder i_gh;
int error;
@@ -728,7 +728,7 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
static int gfs2_open(struct inode *inode, struct file *file)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder i_gh;
struct gfs2_file *fp;
int error;
@@ -739,7 +739,7 @@ static int gfs2_open(struct inode *inode, struct file *file)
mutex_init(&fp->f_fl_mutex);
- gfs2_assert_warn(ip->i_sbd, !file->private_data);
+ gfs2_assert_warn(GFS2_SB(inode), !file->private_data);
file->private_data = fp;
if (S_ISREG(ip->i_di.di_mode)) {
@@ -808,7 +808,7 @@ static int gfs2_close(struct inode *inode, struct file *file)
static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
{
- struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
@@ -826,8 +826,8 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
{
- struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
struct lm_lockname name =
{ .ln_number = ip->i_num.no_addr,
.ln_type = LM_TYPE_PLOCK };
@@ -881,7 +881,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
{
struct gfs2_file *fp = file->private_data;
struct gfs2_holder *fl_gh = &fp->f_fl_gh;
- struct gfs2_inode *ip = file->f_dentry->d_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(file->f_dentry->d_inode);
struct gfs2_glock *gl;
unsigned int state;
int flags;
@@ -901,7 +901,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
&(struct file_lock){.fl_type = F_UNLCK});
gfs2_glock_dq_uninit(fl_gh);
} else {
- error = gfs2_glock_get(ip->i_sbd,
+ error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
ip->i_num.no_addr, &gfs2_flock_glops,
CREATE, &gl);
if (error)
@@ -918,7 +918,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
error = -EAGAIN;
} else {
error = flock_lock_file_wait(file, fl);
- gfs2_assert_warn(ip->i_sbd, !error);
+ gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
}
out:
@@ -950,8 +950,8 @@ static void do_unflock(struct file *file, struct file_lock *fl)
static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
{
- struct gfs2_inode *ip = file->f_mapping->host->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index a459820..b68eb6b 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -32,7 +32,6 @@
#include "recovery.h"
#include "rgrp.h"
#include "super.h"
-#include "unlinked.h"
#include "sys.h"
#include "util.h"
@@ -80,10 +79,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
spin_lock_init(&sdp->sd_jindex_spin);
mutex_init(&sdp->sd_jindex_mutex);
- INIT_LIST_HEAD(&sdp->sd_unlinked_list);
- spin_lock_init(&sdp->sd_unlinked_spin);
- mutex_init(&sdp->sd_unlinked_mutex);
-
INIT_LIST_HEAD(&sdp->sd_quota_list);
spin_lock_init(&sdp->sd_quota_spin);
mutex_init(&sdp->sd_quota_mutex);
@@ -248,19 +243,19 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
return 0;
- fail_trans:
+fail_trans:
gfs2_glock_put(sdp->sd_trans_gl);
- fail_rename:
+fail_rename:
gfs2_glock_put(sdp->sd_rename_gl);
- fail_live:
+fail_live:
gfs2_glock_dq_uninit(&sdp->sd_live_gh);
- fail_mount:
+fail_mount:
gfs2_glock_dq_uninit(mount_gh);
- fail:
+fail:
while (sdp->sd_glockd_num--)
kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);
@@ -269,28 +264,10 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,
return error;
}
-static struct inode *gfs2_lookup_root(struct gfs2_sbd *sdp,
- const struct gfs2_inum *inum)
+static struct inode *gfs2_lookup_root(struct super_block *sb,
+ struct gfs2_inum *inum)
{
- int error;
- struct gfs2_glock *gl;
- struct gfs2_inode *ip;
- struct inode *inode;
-
- error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops,
- CREATE, &gl);
- if (!error) {
- error = gfs2_inode_get(gl, inum, CREATE, &ip);
- if (!error) {
- gfs2_inode_min_init(ip, DT_DIR);
- inode = gfs2_ip2v(ip);
- gfs2_inode_put(ip);
- gfs2_glock_put(gl);
- return inode;
- }
- gfs2_glock_put(gl);
- }
- return ERR_PTR(error);
+ return gfs2_inode_lookup(sb, inum, DT_DIR);
}
static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
@@ -305,8 +282,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
return 0;
}
- error = gfs2_glock_nq_num(sdp,
- GFS2_SB_LOCK, &gfs2_meta_glops,
+ error = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,
LM_ST_SHARED, 0, &sb_gh);
if (error) {
fs_err(sdp, "can't acquire superblock glock: %d\n", error);
@@ -345,7 +321,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
inum = &sdp->sd_sb.sb_root_dir;
if (sb->s_type == &gfs2meta_fs_type)
inum = &sdp->sd_sb.sb_master_dir;
- inode = gfs2_lookup_root(sdp, inum);
+ inode = gfs2_lookup_root(sb, inum);
if (IS_ERR(inode)) {
error = PTR_ERR(inode);
fs_err(sdp, "can't read in root inode: %d\n", error);
@@ -382,7 +358,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
fs_err(sdp, "can't lookup journal index: %d\n", error);
return PTR_ERR(sdp->sd_jindex);
}
- ip = sdp->sd_jindex->u.generic_ip;
+ ip = GFS2_I(sdp->sd_jindex);
set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
/* Load in the journal index special file */
@@ -413,8 +389,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
}
sdp->sd_jdesc = gfs2_jdesc_find(sdp, sdp->sd_lockstruct.ls_jid);
- error = gfs2_glock_nq_num(sdp,
- sdp->sd_lockstruct.ls_jid,
+ error = gfs2_glock_nq_num(sdp, sdp->sd_lockstruct.ls_jid,
&gfs2_journal_glops,
LM_ST_EXCLUSIVE, LM_FLAG_NOEXP,
&sdp->sd_journal_gh);
@@ -423,9 +398,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
goto fail_jindex;
}
- ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
- error = gfs2_glock_nq_init(ip->i_gl,
- LM_ST_SHARED,
+ ip = GFS2_I(sdp->sd_jdesc->jd_inode);
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
LM_FLAG_NOEXP | GL_EXACT,
&sdp->sd_jinode_gh);
if (error) {
@@ -509,7 +483,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
if (undo)
goto fail_qinode;
- inode = gfs2_lookup_root(sdp, &sdp->sd_sb.sb_master_dir);
+ inode = gfs2_lookup_root(sdp->sd_vfs, &sdp->sd_sb.sb_master_dir);
if (IS_ERR(inode)) {
error = PTR_ERR(inode);
fs_err(sdp, "can't read in master directory: %d\n", error);
@@ -545,7 +519,7 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
fs_err(sdp, "can't get resource index inode: %d\n", error);
goto fail_statfs;
}
- ip = sdp->sd_rindex->u.generic_ip;
+ ip = GFS2_I(sdp->sd_rindex);
set_bit(GLF_STICKY, &ip->i_gl->gl_flags);
sdp->sd_rindex_vn = ip->i_gl->gl_vn - 1;
@@ -614,14 +588,6 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
goto fail_ir_i;
}
- sprintf(buf, "unlinked_tag%u", sdp->sd_jdesc->jd_jid);
- sdp->sd_ut_inode = gfs2_lookup_simple(pn, buf);
- if (IS_ERR(sdp->sd_ut_inode)) {
- error = PTR_ERR(sdp->sd_ut_inode);
- fs_err(sdp, "can't find local \"ut\" file: %d\n", error);
- goto fail_sc_i;
- }
-
sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid);
sdp->sd_qc_inode = gfs2_lookup_simple(pn, buf);
if (IS_ERR(sdp->sd_qc_inode)) {
@@ -633,7 +599,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
iput(pn);
pn = NULL;
- ip = sdp->sd_ir_inode->u.generic_ip;
+ ip = GFS2_I(sdp->sd_ir_inode);
error = gfs2_glock_nq_init(ip->i_gl,
LM_ST_EXCLUSIVE, 0,
&sdp->sd_ir_gh);
@@ -642,7 +608,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
goto fail_qc_i;
}
- ip = sdp->sd_sc_inode->u.generic_ip;
+ ip = GFS2_I(sdp->sd_sc_inode);
error = gfs2_glock_nq_init(ip->i_gl,
LM_ST_EXCLUSIVE, 0,
&sdp->sd_sc_gh);
@@ -651,16 +617,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
goto fail_ir_gh;
}
- ip = sdp->sd_ut_inode->u.generic_ip;
- error = gfs2_glock_nq_init(ip->i_gl,
- LM_ST_EXCLUSIVE, 0,
- &sdp->sd_ut_gh);
- if (error) {
- fs_err(sdp, "can't lock local \"ut\" file: %d\n", error);
- goto fail_sc_gh;
- }
-
- ip = sdp->sd_qc_inode->u.generic_ip;
+ ip = GFS2_I(sdp->sd_qc_inode);
error = gfs2_glock_nq_init(ip->i_gl,
LM_ST_EXCLUSIVE, 0,
&sdp->sd_qc_gh);
@@ -675,9 +632,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
fail_ut_gh:
- gfs2_glock_dq_uninit(&sdp->sd_ut_gh);
- fail_sc_gh:
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
fail_ir_gh:
@@ -687,9 +642,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
iput(sdp->sd_qc_inode);
fail_ut_i:
- iput(sdp->sd_ut_inode);
- fail_sc_i:
iput(sdp->sd_sc_inode);
fail_ir_i:
@@ -707,7 +660,7 @@ static int init_threads(struct gfs2_sbd *sdp, int undo)
int error = 0;
if (undo)
- goto fail_inoded;
+ goto fail_quotad;
sdp->sd_log_flush_time = jiffies;
sdp->sd_jindex_refresh_time = jiffies;
@@ -731,25 +684,13 @@ static int init_threads(struct gfs2_sbd *sdp, int undo)
}
sdp->sd_quotad_process = p;
- p = kthread_run(gfs2_inoded, sdp, "gfs2_inoded");
- error = IS_ERR(p);
- if (error) {
- fs_err(sdp, "can't start inoded thread: %d\n", error);
- goto fail_quotad;
- }
- sdp->sd_inoded_process = p;
-
return 0;
- fail_inoded:
- kthread_stop(sdp->sd_inoded_process);
- fail_quotad:
+fail_quotad:
kthread_stop(sdp->sd_quotad_process);
-
- fail:
+fail:
kthread_stop(sdp->sd_logd_process);
-
return error;
}
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 0c06f92..f678f6b 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -38,7 +38,6 @@
#include "quota.h"
#include "rgrp.h"
#include "trans.h"
-#include "unlinked.h"
#include "util.h"
/**
@@ -53,8 +52,8 @@
static int gfs2_create(struct inode *dir, struct dentry *dentry,
int mode, struct nameidata *nd)
{
- struct gfs2_inode *dip = dir->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(dir);
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
struct gfs2_holder ghs[2];
struct inode *inode;
int new = 1;
@@ -141,10 +140,10 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *dentry)
{
- struct gfs2_inode *dip = dir->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(dir);
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
struct inode *inode = old_dentry->d_inode;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder ghs[2];
int alloc_required;
int error;
@@ -231,30 +230,29 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
error = gfs2_change_nlink(ip, +1);
- out_end_trans:
+out_end_trans:
gfs2_trans_end(sdp);
- out_ipres:
+out_ipres:
if (alloc_required)
gfs2_inplace_release(dip);
- out_gunlock_q:
+out_gunlock_q:
if (alloc_required)
gfs2_quota_unlock(dip);
- out_alloc:
+out_alloc:
if (alloc_required)
gfs2_alloc_put(dip);
- out_gunlock:
+out_gunlock:
gfs2_glock_dq_m(2, ghs);
- out:
+out:
gfs2_holder_uninit(ghs);
gfs2_holder_uninit(ghs + 1);
if (!error) {
- atomic_inc(&inode->i_count);
d_instantiate(dentry, inode);
mark_inode_dirty(inode);
}
@@ -274,17 +272,12 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
{
- struct gfs2_inode *dip = dir->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
- struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
- struct gfs2_unlinked *ul;
+ struct gfs2_inode *dip = GFS2_I(dir);
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
+ struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
struct gfs2_holder ghs[2];
int error;
- error = gfs2_unlinked_get(sdp, &ul);
- if (error)
- return error;
-
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
@@ -296,24 +289,23 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
if (error)
goto out_gunlock;
- error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF +
- RES_UNLINKED, 0);
+ error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0);
if (error)
goto out_gunlock;
- error = gfs2_unlinki(dip, &dentry->d_name, ip, ul);
+ error = gfs2_dir_del(dip, &dentry->d_name);
+ if (error)
+ goto out_end_trans;
- gfs2_trans_end(sdp);
+ error = gfs2_change_nlink(ip, -1);
- out_gunlock:
+out_end_trans:
+ gfs2_trans_end(sdp);
+out_gunlock:
gfs2_glock_dq_m(2, ghs);
-
- out:
+out:
gfs2_holder_uninit(ghs);
gfs2_holder_uninit(ghs + 1);
-
- gfs2_unlinked_put(sdp, ul);
-
return error;
}
@@ -329,8 +321,8 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
const char *symname)
{
- struct gfs2_inode *dip = dir->u.generic_ip, *ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(dir), *ip;
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
struct gfs2_holder ghs[2];
struct inode *inode;
struct buffer_head *dibh;
@@ -388,8 +380,8 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
- struct gfs2_inode *dip = dir->u.generic_ip, *ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(dir), *ip;
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
struct gfs2_holder ghs[2];
struct inode *inode;
struct buffer_head *dibh;
@@ -466,17 +458,12 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
{
- struct gfs2_inode *dip = dir->u.generic_ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
- struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
- struct gfs2_unlinked *ul;
+ struct gfs2_inode *dip = GFS2_I(dir);
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
+ struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
struct gfs2_holder ghs[2];
int error;
- error = gfs2_unlinked_get(sdp, &ul);
- if (error)
- return error;
-
gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
@@ -499,12 +486,11 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
goto out_gunlock;
}
- error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF +
- RES_UNLINKED, 0);
+ error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF + RES_RG_BIT, 0);
if (error)
goto out_gunlock;
- error = gfs2_rmdiri(dip, &dentry->d_name, ip, ul);
+ error = gfs2_rmdiri(dip, &dentry->d_name, ip);
gfs2_trans_end(sdp);
@@ -515,8 +501,6 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
gfs2_holder_uninit(ghs);
gfs2_holder_uninit(ghs + 1);
- gfs2_unlinked_put(sdp, ul);
-
return error;
}
@@ -532,8 +516,8 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
dev_t dev)
{
- struct gfs2_inode *dip = dir->u.generic_ip, *ip;
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_inode *dip = GFS2_I(dir), *ip;
+ struct gfs2_sbd *sdp = GFS2_SB(dir);
struct gfs2_holder ghs[2];
struct inode *inode;
struct buffer_head *dibh;
@@ -600,12 +584,11 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
static int gfs2_rename(struct inode *odir, struct dentry *odentry,
struct inode *ndir, struct dentry *ndentry)
{
- struct gfs2_inode *odip = odir->u.generic_ip;
- struct gfs2_inode *ndip = ndir->u.generic_ip;
- struct gfs2_inode *ip = odentry->d_inode->u.generic_ip;
+ struct gfs2_inode *odip = GFS2_I(odir);
+ struct gfs2_inode *ndip = GFS2_I(ndir);
+ struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
struct gfs2_inode *nip = NULL;
- struct gfs2_sbd *sdp = odip->i_sbd;
- struct gfs2_unlinked *ul;
+ struct gfs2_sbd *sdp = GFS2_SB(odir);
struct gfs2_holder ghs[4], r_gh;
unsigned int num_gh;
int dir_rename = 0;
@@ -614,15 +597,11 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
int error;
if (ndentry->d_inode) {
- nip = ndentry->d_inode->u.generic_ip;
+ nip = GFS2_I(ndentry->d_inode);
if (ip == nip)
return 0;
}
- error = gfs2_unlinked_get(sdp, &ul);
- if (error)
- return error;
-
/* Make sure we aren't trying to move a dirctory into it's subdir */
if (S_ISDIR(ip->i_di.di_mode) && odip != ndip) {
@@ -743,14 +722,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
al->al_rgd->rd_ri.ri_length +
4 * RES_DINODE + 4 * RES_LEAF +
- RES_UNLINKED + RES_STATFS +
- RES_QUOTA, 0);
+ RES_STATFS + RES_QUOTA, 0);
if (error)
goto out_ipreserv;
} else {
error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
- 5 * RES_LEAF +
- RES_UNLINKED, 0);
+ 5 * RES_LEAF, 0);
if (error)
goto out_gunlock;
}
@@ -759,9 +736,13 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
if (nip) {
if (S_ISDIR(nip->i_di.di_mode))
- error = gfs2_rmdiri(ndip, &ndentry->d_name, nip, ul);
- else
- error = gfs2_unlinki(ndip, &ndentry->d_name, nip, ul);
+ error = gfs2_rmdiri(ndip, &ndentry->d_name, nip);
+ else {
+ error = gfs2_dir_del(ndip, &ndentry->d_name);
+ if (error)
+ goto out_end_trans;
+ error = gfs2_change_nlink(nip, -1);
+ }
if (error)
goto out_end_trans;
}
@@ -800,35 +781,26 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
if (error)
goto out_end_trans;
- out_end_trans:
+out_end_trans:
gfs2_trans_end(sdp);
-
- out_ipreserv:
+out_ipreserv:
if (alloc_required)
gfs2_inplace_release(ndip);
-
- out_gunlock_q:
+out_gunlock_q:
if (alloc_required)
gfs2_quota_unlock(ndip);
-
- out_alloc:
+out_alloc:
if (alloc_required)
gfs2_alloc_put(ndip);
-
- out_gunlock:
+out_gunlock:
gfs2_glock_dq_m(num_gh, ghs);
-
- out_uninit:
+out_uninit:
for (x = 0; x < num_gh; x++)
gfs2_holder_uninit(ghs + x);
-
- out_gunlock_r:
+out_gunlock_r:
if (dir_rename)
gfs2_glock_dq_uninit(&r_gh);
-
- out:
- gfs2_unlinked_put(sdp, ul);
-
+out:
return error;
}
@@ -844,7 +816,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
static int gfs2_readlink(struct dentry *dentry, char __user *user_buf,
int user_size)
{
- struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
char array[GFS2_FAST_NAME_SIZE], *buf = array;
unsigned int len = GFS2_FAST_NAME_SIZE;
int error;
@@ -880,7 +852,7 @@ static int gfs2_readlink(struct dentry *dentry, char __user *user_buf,
static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
{
- struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
char array[GFS2_FAST_NAME_SIZE], *buf = array;
unsigned int len = GFS2_FAST_NAME_SIZE;
int error;
@@ -906,7 +878,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder i_gh;
int error;
@@ -926,7 +898,7 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
static int setattr_size(struct inode *inode, struct iattr *attr)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
int error;
if (attr->ia_size != ip->i_di.di_size) {
@@ -944,8 +916,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr)
static int setattr_chown(struct inode *inode, struct iattr *attr)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *dibh;
uint32_t ouid, ogid, nuid, ngid;
int error;
@@ -1021,7 +993,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = dentry->d_inode;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder i_gh;
int error;
@@ -1068,7 +1040,7 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
- struct gfs2_inode *ip = inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder gh;
int error;
@@ -1084,7 +1056,7 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
static int gfs2_setxattr(struct dentry *dentry, const char *name,
const void *data, size_t size, int flags)
{
- struct gfs2_inode *ip = dentry->d_inode->u.generic_ip;
+ struct inode *inode = dentry->d_inode;
struct gfs2_ea_request er;
memset(&er, 0, sizeof(struct gfs2_ea_request));
@@ -1096,9 +1068,9 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name,
er.er_data_len = size;
er.er_flags = flags;
- gfs2_assert_warn(ip->i_sbd, !(er.er_flags & GFS2_ERF_MODE));
+ gfs2_assert_warn(GFS2_SB(inode), !(er.er_flags & GFS2_ERF_MODE));
- return gfs2_ea_set(ip, &er);
+ return gfs2_ea_set(GFS2_I(inode), &er);
}
static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
@@ -1114,7 +1086,7 @@ static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
er.er_name_len = strlen(er.er_name);
er.er_data_len = size;
- return gfs2_ea_get(dentry->d_inode->u.generic_ip, &er);
+ return gfs2_ea_get(GFS2_I(dentry->d_inode), &er);
}
static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
@@ -1125,7 +1097,7 @@ static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
er.er_data = (size) ? buffer : NULL;
er.er_data_len = size;
- return gfs2_ea_list(dentry->d_inode->u.generic_ip, &er);
+ return gfs2_ea_list(GFS2_I(dentry->d_inode), &er);
}
static int gfs2_removexattr(struct dentry *dentry, const char *name)
@@ -1138,7 +1110,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)
return -EOPNOTSUPP;
er.er_name_len = strlen(er.er_name);
- return gfs2_ea_remove(dentry->d_inode->u.generic_ip, &er);
+ return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er);
}
struct inode_operations gfs2_file_iops = {
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 1c17acc..317d497 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -19,6 +19,7 @@
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/gfs2_ondisk.h>
+#include <linux/crc32.h>
#include "gfs2.h"
#include "lm_interface.h"
@@ -36,6 +37,10 @@
#include "super.h"
#include "sys.h"
#include "util.h"
+#include "trans.h"
+#include "dir.h"
+#include "eattr.h"
+#include "bmap.h"
/**
* gfs2_write_inode - Make sure the inode is stable on the disk
@@ -47,12 +52,15 @@
static int gfs2_write_inode(struct inode *inode, int sync)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
-
- if (current->flags & PF_MEMALLOC)
- return 0;
- if (ip && sync)
- gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
+ struct gfs2_inode *ip = GFS2_I(inode);
+
+ /* Check this is a "normal" inode */
+ if (inode->u.generic_ip) {
+ if (current->flags & PF_MEMALLOC)
+ return 0;
+ if (sync)
+ gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
+ }
return 0;
}
@@ -78,7 +86,6 @@ static void gfs2_put_super(struct super_block *sb)
gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
mutex_unlock(&sdp->sd_freeze_lock);
- kthread_stop(sdp->sd_inoded_process);
kthread_stop(sdp->sd_quotad_process);
kthread_stop(sdp->sd_logd_process);
kthread_stop(sdp->sd_recoverd_process);
@@ -110,11 +117,9 @@ static void gfs2_put_super(struct super_block *sb)
gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
- gfs2_glock_dq_uninit(&sdp->sd_ut_gh);
gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
iput(sdp->sd_ir_inode);
iput(sdp->sd_sc_inode);
- iput(sdp->sd_ut_inode);
iput(sdp->sd_qc_inode);
}
@@ -274,16 +279,20 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
static void gfs2_clear_inode(struct inode *inode)
{
- struct gfs2_inode *ip = inode->u.generic_ip;
-
- if (ip) {
- spin_lock(&ip->i_spin);
- ip->i_vnode = NULL;
- inode->u.generic_ip = NULL;
- spin_unlock(&ip->i_spin);
-
+ /* This tells us its a "real" inode and not one which only
+ * serves to contain an address space (see rgrp.c, meta_io.c)
+ * which therefore doesn't have its own glocks.
+ */
+ if (inode->u.generic_ip) {
+ struct gfs2_inode *ip = GFS2_I(inode);
+ gfs2_glock_inode_squish(inode);
+ gfs2_assert(inode->i_sb->s_fs_info, ip->i_gl->gl_state == LM_ST_UNLOCKED);
+ ip->i_gl->gl_object = NULL;
gfs2_glock_schedule_for_reclaim(ip->i_gl);
- gfs2_inode_put(ip);
+ gfs2_glock_put(ip->i_gl);
+ ip->i_gl = NULL;
+ if (ip->i_iopen_gh.gh_gl)
+ gfs2_glock_dq_uninit(&ip->i_iopen_gh);
}
}
@@ -361,6 +370,70 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
return 0;
}
+/*
+ * We have to (at the moment) hold the inodes main lock to cover
+ * the gap between unlocking the shared lock on the iopen lock and
+ * taking the exclusive lock. I'd rather do a shared -> exclusive
+ * conversion on the iopen lock, but we can change that later. This
+ * is safe, just less efficient.
+ */
+static void gfs2_delete_inode(struct inode *inode)
+{
+ struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_holder gh;
+ int error;
+
+ if (!inode->u.generic_ip)
+ goto out;
+
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &gh);
+ if (unlikely(error)) {
+ gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+ goto out;
+ }
+
+ gfs2_glock_dq(&ip->i_iopen_gh);
+ gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
+ error = gfs2_glock_nq(&ip->i_iopen_gh);
+ if (error)
+ goto out_uninit;
+
+ if (S_ISDIR(ip->i_di.di_mode) &&
+ (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
+ error = gfs2_dir_exhash_dealloc(ip);
+ if (error)
+ goto out_unlock;
+ }
+
+ if (ip->i_di.di_eattr) {
+ error = gfs2_ea_dealloc(ip);
+ if (error)
+ goto out_unlock;
+ }
+
+ if (!gfs2_is_stuffed(ip)) {
+ error = gfs2_file_dealloc(ip);
+ if (error)
+ goto out_unlock;
+ }
+
+ error = gfs2_dinode_dealloc(ip);
+
+out_unlock:
+ gfs2_glock_dq(&ip->i_iopen_gh);
+out_uninit:
+ gfs2_holder_uninit(&ip->i_iopen_gh);
+ gfs2_glock_dq_uninit(&gh);
+ if (error)
+ fs_warn(sdp, "gfs2_delete_inode: %d\n", error);
+out:
+ truncate_inode_pages(&inode->i_data, 0);
+ clear_inode(inode);
+}
+
+
+
static struct inode *gfs2_alloc_inode(struct super_block *sb)
{
struct gfs2_sbd *sdp = sb->s_fs_info;
@@ -370,8 +443,6 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
if (ip) {
ip->i_flags = 0;
ip->i_gl = NULL;
- ip->i_sbd = sdp;
- ip->i_vnode = &ip->i_inode;
ip->i_greedy = gfs2_tune_get(sdp, gt_greedy_default);
ip->i_last_pfault = jiffies;
}
@@ -387,6 +458,7 @@ struct super_operations gfs2_super_ops = {
.alloc_inode = gfs2_alloc_inode,
.destroy_inode = gfs2_destroy_inode,
.write_inode = gfs2_write_inode,
+ .delete_inode = gfs2_delete_inode,
.put_super = gfs2_put_super,
.write_super = gfs2_write_super,
.write_super_lockfs = gfs2_write_super_lockfs,
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index 263c1fb..08709f1 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -38,15 +38,15 @@ static void pfault_be_greedy(struct gfs2_inode *ip)
ip->i_last_pfault = jiffies;
spin_unlock(&ip->i_spin);
- gfs2_inode_hold(ip);
+ igrab(&ip->i_inode);
if (gfs2_glock_be_greedy(ip->i_gl, time))
- gfs2_inode_put(ip);
+ iput(&ip->i_inode);
}
static struct page *gfs2_private_nopage(struct vm_area_struct *area,
unsigned long address, int *type)
{
- struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host);
struct gfs2_holder i_gh;
struct page *result;
int error;
@@ -69,7 +69,7 @@ static struct page *gfs2_private_nopage(struct vm_area_struct *area,
static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
unsigned long index = page->index;
uint64_t lblock = index << (PAGE_CACHE_SHIFT -
sdp->sd_sb.sb_bsize_shift);
@@ -114,7 +114,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
unsigned int extlen;
int new = 1;
- error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen);
+ error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
if (error)
goto out_trans;
@@ -142,7 +142,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page)
static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
unsigned long address, int *type)
{
- struct gfs2_inode *ip = area->vm_file->f_mapping->host->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(area->vm_file->f_mapping->host);
struct gfs2_holder i_gh;
struct page *result = NULL;
unsigned long index = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) +
diff --git a/fs/gfs2/page.c b/fs/gfs2/page.c
index cd93644..a8165a6 100644
--- a/fs/gfs2/page.c
+++ b/fs/gfs2/page.c
@@ -38,20 +38,17 @@ void gfs2_pte_inval(struct gfs2_glock *gl)
struct inode *inode;
ip = gl->gl_object;
+ inode = &ip->i_inode;
if (!ip || !S_ISREG(ip->i_di.di_mode))
return;
if (!test_bit(GIF_PAGED, &ip->i_flags))
return;
- inode = gfs2_ip2v_lookup(ip);
- if (inode) {
- unmap_shared_mapping_range(inode->i_mapping, 0, 0);
- iput(inode);
+ unmap_shared_mapping_range(inode->i_mapping, 0, 0);
- if (test_bit(GIF_SW_PAGED, &ip->i_flags))
- set_bit(GLF_DIRTY, &gl->gl_flags);
- }
+ if (test_bit(GIF_SW_PAGED, &ip->i_flags))
+ set_bit(GLF_DIRTY, &gl->gl_flags);
clear_bit(GIF_SW_PAGED, &ip->i_flags);
}
@@ -68,19 +65,12 @@ void gfs2_page_inval(struct gfs2_glock *gl)
struct inode *inode;
ip = gl->gl_object;
+ inode = &ip->i_inode;
if (!ip || !S_ISREG(ip->i_di.di_mode))
return;
- inode = gfs2_ip2v_lookup(ip);
- if (inode) {
- struct address_space *mapping = inode->i_mapping;
-
- truncate_inode_pages(mapping, 0);
- gfs2_assert_withdraw(ip->i_sbd, !mapping->nrpages);
-
- iput(inode);
- }
-
+ truncate_inode_pages(inode->i_mapping, 0);
+ gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages);
clear_bit(GIF_PAGED, &ip->i_flags);
}
@@ -97,32 +87,30 @@ void gfs2_page_sync(struct gfs2_glock *gl, int flags)
{
struct gfs2_inode *ip;
struct inode *inode;
+ struct address_space *mapping;
+ int error = 0;
ip = gl->gl_object;
+ inode = &ip->i_inode;
if (!ip || !S_ISREG(ip->i_di.di_mode))
return;
- inode = gfs2_ip2v_lookup(ip);
- if (inode) {
- struct address_space *mapping = inode->i_mapping;
- int error = 0;
+ mapping = inode->i_mapping;
- if (flags & DIO_START)
- filemap_fdatawrite(mapping);
- if (!error && (flags & DIO_WAIT))
- error = filemap_fdatawait(mapping);
+ if (flags & DIO_START)
+ filemap_fdatawrite(mapping);
+ if (!error && (flags & DIO_WAIT))
+ error = filemap_fdatawait(mapping);
- /* Put back any errors cleared by filemap_fdatawait()
- so they can be caught by someone who can pass them
- up to user space. */
+ /* Put back any errors cleared by filemap_fdatawait()
+ so they can be caught by someone who can pass them
+ up to user space. */
- if (error == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else if (error)
- set_bit(AS_EIO, &mapping->flags);
+ if (error == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ else if (error)
+ set_bit(AS_EIO, &mapping->flags);
- iput(inode);
- }
}
/**
@@ -138,8 +126,8 @@ void gfs2_page_sync(struct gfs2_glock *gl, int flags)
int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
uint64_t block, void *private)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
- struct inode *inode = ip->i_vnode;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+ struct inode *inode = &ip->i_inode;
struct page *page = (struct page *)private;
struct buffer_head *bh;
int release = 0;
@@ -193,8 +181,8 @@ int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
int gfs2_block_truncate_page(struct address_space *mapping)
{
struct inode *inode = mapping->host;
- struct gfs2_inode *ip = inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
loff_t from = inode->i_size;
unsigned long index = from >> PAGE_CACHE_SHIFT;
unsigned offset = from & (PAGE_CACHE_SIZE-1);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index f752b01..d3cd517 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -248,7 +248,7 @@ static void slot_put(struct gfs2_quota_data *qd)
static int bh_get(struct gfs2_quota_data *qd)
{
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
- struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
unsigned int block, offset;
uint64_t dblock;
int new = 0;
@@ -266,7 +266,7 @@ static int bh_get(struct gfs2_quota_data *qd)
block = qd->qd_slot / sdp->sd_qc_per_block;
offset = qd->qd_slot % sdp->sd_qc_per_block;;
- error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
+ error = gfs2_block_map(&ip->i_inode, block, &new, &dblock, &boundary);
if (error)
goto fail;
error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
@@ -444,7 +444,7 @@ static void qdsb_put(struct gfs2_quota_data *qd)
int gfs2_quota_hold(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
struct gfs2_quota_data **qd = al->al_qd;
int error;
@@ -493,7 +493,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
void gfs2_quota_unhold(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
unsigned int x;
@@ -531,7 +531,7 @@ static int sort_qd(const void *a, const void *b)
static void do_qc(struct gfs2_quota_data *qd, int64_t change)
{
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
- struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
struct gfs2_quota_change *qc = qd->qd_bh_qc;
int64_t x;
@@ -578,7 +578,7 @@ static void do_qc(struct gfs2_quota_data *qd, int64_t change)
static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
int64_t change, struct gfs2_quota_data *qd)
{
- struct inode *inode = ip->i_vnode;
+ struct inode *inode = &ip->i_inode;
struct address_space *mapping = inode->i_mapping;
unsigned long index = loc >> PAGE_CACHE_SHIFT;
unsigned offset = loc & (PAGE_CACHE_SHIFT - 1);
@@ -647,7 +647,7 @@ unlock:
static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
{
struct gfs2_sbd *sdp = (*qda)->qd_gl->gl_sbd;
- struct gfs2_inode *ip = sdp->sd_quota_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
unsigned int data_blocks, ind_blocks;
struct file_ra_state ra_state;
struct gfs2_holder *ghs, i_gh;
@@ -716,7 +716,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
goto out_gunlock;
}
- file_ra_state_init(&ra_state, ip->i_vnode->i_mapping);
+ file_ra_state_init(&ra_state, ip->i_inode.i_mapping);
for (x = 0; x < num_qd; x++) {
qd = qda[x];
offset = qd2offset(qd);
@@ -758,7 +758,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh,
struct gfs2_holder *q_gh)
{
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
- struct gfs2_inode *ip = sdp->sd_quota_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
struct gfs2_holder i_gh;
struct gfs2_quota q;
char buf[sizeof(struct gfs2_quota)];
@@ -829,7 +829,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh,
int gfs2_quota_lock(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
unsigned int x;
int error = 0;
@@ -958,7 +958,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
int gfs2_quota_check(struct gfs2_inode *ip, uint32_t uid, uint32_t gid)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
struct gfs2_quota_data *qd;
int64_t value;
@@ -1008,7 +1008,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, int64_t change,
unsigned int x;
unsigned int found = 0;
- if (gfs2_assert_warn(ip->i_sbd, change))
+ if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change))
return;
if (ip->i_di.di_flags & GFS2_DIF_SYSTEM)
return;
@@ -1126,7 +1126,7 @@ int gfs2_quota_read(struct gfs2_sbd *sdp, int user, uint32_t id,
int gfs2_quota_init(struct gfs2_sbd *sdp)
{
- struct gfs2_inode *ip = sdp->sd_qc_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
unsigned int x, slot = 0;
unsigned int found = 0;
@@ -1162,7 +1162,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
if (!extlen) {
int new = 0;
- error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
+ error = gfs2_extent_map(&ip->i_inode, x, &new, &dblock, &extlen);
if (error)
goto fail;
}
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index c504ac1..7aabc03 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -32,14 +32,14 @@
int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk,
struct buffer_head **bh)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
struct gfs2_glock *gl = ip->i_gl;
int new = 0;
uint64_t dblock;
uint32_t extlen;
int error;
- error = gfs2_extent_map(ip->i_vnode, blk, &new, &dblock, &extlen);
+ error = gfs2_extent_map(&ip->i_inode, blk, &new, &dblock, &extlen);
if (error)
return error;
if (!dblock) {
@@ -190,7 +190,7 @@ static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk,
*blk = 0;
if (*blk == orig_blk) {
- gfs2_consist_inode(jd->jd_inode->u.generic_ip);
+ gfs2_consist_inode(GFS2_I(jd->jd_inode));
return -EIO;
}
}
@@ -224,7 +224,7 @@ static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
continue;
if (lh.lh_sequence == head->lh_sequence) {
- gfs2_consist_inode(jd->jd_inode->u.generic_ip);
+ gfs2_consist_inode(GFS2_I(jd->jd_inode));
return -EIO;
}
if (lh.lh_sequence < head->lh_sequence)
@@ -300,8 +300,7 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
unsigned int end, int pass)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
struct buffer_head *bh;
struct gfs2_log_descriptor *ld;
int error = 0;
@@ -330,7 +329,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
continue;
}
if (error == 1) {
- gfs2_consist_inode(jd->jd_inode->u.generic_ip);
+ gfs2_consist_inode(GFS2_I(jd->jd_inode));
error = -EIO;
}
brelse(bh);
@@ -367,8 +366,8 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
unsigned int lblock;
int new = 0;
uint64_t dblock;
@@ -380,7 +379,7 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
lblock = head->lh_blkno;
gfs2_replay_incr_blk(sdp, &lblock);
- error = gfs2_block_map(ip->i_vnode, lblock, &new, &dblock, &boundary);
+ error = gfs2_block_map(&ip->i_inode, lblock, &new, &dblock, &boundary);
if (error)
return error;
if (!dblock) {
@@ -426,8 +425,8 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
int gfs2_recover_journal(struct gfs2_jdesc *jd)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
struct gfs2_log_header head;
struct gfs2_holder j_gh, ji_gh, t_gh;
unsigned long t;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 691e6f3..75df79e 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -34,17 +34,19 @@
/*
* These routines are used by the resource group routines (rgrp.c)
* to keep track of block allocation. Each block is represented by two
- * bits. One bit indicates whether or not the block is used. (1=used,
- * 0=free) The other bit indicates whether or not the block contains a
- * dinode or not. (1=dinode, 0=not-dinode) So, each byte represents
- * GFS2_NBBY (i.e. 4) blocks.
+ * bits. So, each byte represents GFS2_NBBY (i.e. 4) blocks.
+ *
+ * 0 = Free
+ * 1 = Used (not metadata)
+ * 2 = Unlinked (still in use) inode
+ * 3 = Used (metadata)
*/
static const char valid_change[16] = {
/* current */
- /* n */ 0, 1, 0, 1,
+ /* n */ 0, 1, 1, 1,
/* e */ 1, 0, 0, 0,
- /* w */ 0, 0, 0, 0,
+ /* w */ 0, 0, 0, 1,
1, 0, 0, 0
};
@@ -228,26 +230,27 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
tmp = rgd->rd_ri.ri_data -
rgd->rd_rg.rg_free -
rgd->rd_rg.rg_dinodes;
- if (count[1] != tmp) {
+ if (count[1] + count[2] != tmp) {
if (gfs2_consist_rgrpd(rgd))
fs_err(sdp, "used data mismatch: %u != %u\n",
count[1], tmp);
return;
}
- if (count[2]) {
+ if (count[3] != rgd->rd_rg.rg_dinodes) {
if (gfs2_consist_rgrpd(rgd))
- fs_err(sdp, "free metadata mismatch: %u != 0\n",
- count[2]);
+ fs_err(sdp, "used metadata mismatch: %u != %u\n",
+ count[3], rgd->rd_rg.rg_dinodes);
return;
}
- if (count[3] != rgd->rd_rg.rg_dinodes) {
+ if (count[2] > count[3]) {
if (gfs2_consist_rgrpd(rgd))
- fs_err(sdp, "used metadata mismatch: %u != %u\n",
- count[3], rgd->rd_rg.rg_dinodes);
+ fs_err(sdp, "unlinked inodes > inodes: %u\n",
+ count[2]);
return;
}
+
}
static inline int rgrp_contains_block(struct gfs2_rindex *ri, uint64_t block)
@@ -368,6 +371,9 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
uint32_t bytes_left, bytes;
int x;
+ if (!length)
+ return -EINVAL;
+
rgd->rd_bits = kcalloc(length, sizeof(struct gfs2_bitmap), GFP_KERNEL);
if (!rgd->rd_bits)
return -ENOMEM;
@@ -433,14 +439,16 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
static int gfs2_ri_update(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
- struct inode *inode = ip->i_vnode;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+ struct inode *inode = &ip->i_inode;
struct gfs2_rgrpd *rgd;
char buf[sizeof(struct gfs2_rindex)];
struct file_ra_state ra_state;
uint64_t junk = ip->i_di.di_size;
int error;
+ printk(KERN_INFO "gfs2_ri_update inode=%p\n", inode);
+
if (do_div(junk, sizeof(struct gfs2_rindex))) {
gfs2_consist_inode(ip);
return -EIO;
@@ -448,9 +456,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
clear_rgrpdi(sdp);
+ printk(KERN_INFO "rgrps cleared\n");
+
file_ra_state_init(&ra_state, inode->i_mapping);
for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
+ printk(KERN_INFO "reading rgrp %d\n", sdp->sd_rgrps);
error = gfs2_internal_read(ip, &ra_state, buf, &pos,
sizeof(struct gfs2_rindex));
if (!error)
@@ -474,13 +485,15 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list);
gfs2_rindex_in(&rgd->rd_ri, buf);
-
+ printk(KERN_INFO "compute bitstructs\n");
error = compute_bitstructs(rgd);
if (error)
goto fail;
+ printk(KERN_INFO "gfs2_glock_get\n");
error = gfs2_glock_get(sdp, rgd->rd_ri.ri_addr,
&gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
+ printk(KERN_INFO "gfs2_glock_got one\n");
if (error)
goto fail;
@@ -488,13 +501,14 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
}
+ printk(KERN_INFO "ok, finished\n");
sdp->sd_rindex_vn = ip->i_gl->gl_vn;
-
return 0;
- fail:
+fail:
+ printk(KERN_INFO "fail\n");
clear_rgrpdi(sdp);
-
+ printk(KERN_INFO "cleared rgrps\n");
return error;
}
@@ -518,7 +532,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh)
{
- struct gfs2_inode *ip = sdp->sd_rindex->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
struct gfs2_glock *gl = ip->i_gl;
int error;
@@ -583,8 +597,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
error = gfs2_meta_reread(sdp, bi->bi_bh, DIO_WAIT);
if (error)
goto fail;
- if (gfs2_metatype_check(sdp, bi->bi_bh,
- (y) ? GFS2_METATYPE_RB :
+ if (gfs2_metatype_check(sdp, bi->bi_bh, y ? GFS2_METATYPE_RB :
GFS2_METATYPE_RG)) {
error = -EIO;
goto fail;
@@ -605,7 +618,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
return 0;
- fail:
+fail:
while (x--) {
bi = rgd->rd_bits + x;
brelse(bi->bi_bh);
@@ -667,8 +680,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
if (!bi->bi_clone)
continue;
memcpy(bi->bi_clone + bi->bi_offset,
- bi->bi_bh->b_data + bi->bi_offset,
- bi->bi_len);
+ bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
}
spin_lock(&sdp->sd_rindex_spin);
@@ -757,13 +769,11 @@ static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp,
goto out;
}
- first:
+first:
rgd = list_entry(sdp->sd_rindex_recent_list.next, struct gfs2_rgrpd,
rd_recent);
-
- out:
+out:
spin_unlock(&sdp->sd_rindex_spin);
-
return rgd;
}
@@ -805,9 +815,8 @@ static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd,
if (!list_empty(head))
rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent);
- out:
+out:
spin_unlock(&sdp->sd_rindex_spin);
-
return rgd;
}
@@ -835,7 +844,7 @@ static void recent_rgrp_add(struct gfs2_rgrpd *new_rgd)
}
list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list);
- out:
+out:
spin_unlock(&sdp->sd_rindex_spin);
}
@@ -898,7 +907,7 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
static int get_local_rgrp(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrpd *rgd, *begin = NULL;
struct gfs2_alloc *al = &ip->i_alloc;
int flags = LM_FLAG_TRY;
@@ -965,7 +974,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
}
}
- out:
+out:
ip->i_last_rg_alloc = rgd->rd_ri.ri_addr;
if (begin) {
@@ -988,7 +997,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
int error;
@@ -1020,7 +1029,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
void gfs2_inplace_release(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
if (gfs2_assert_warn(sdp, al->al_alloced <= al->al_requested) == -1)
@@ -1061,8 +1070,7 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, uint64_t block)
gfs2_assert(rgd->rd_sbd, buf < length);
buf_block = rgrp_block - bi->bi_start * GFS2_NBBY;
- type = gfs2_testbit(rgd,
- bi->bi_bh->b_data + bi->bi_offset,
+ type = gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
bi->bi_len, buf_block);
return type;
@@ -1210,7 +1218,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, uint64_t bstart,
uint64_t gfs2_alloc_data(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
struct gfs2_rgrpd *rgd = al->al_rgd;
uint32_t goal, blk;
@@ -1254,7 +1262,7 @@ uint64_t gfs2_alloc_data(struct gfs2_inode *ip)
uint64_t gfs2_alloc_meta(struct gfs2_inode *ip)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_alloc *al = &ip->i_alloc;
struct gfs2_rgrpd *rgd = al->al_rgd;
uint32_t goal, blk;
@@ -1299,7 +1307,7 @@ uint64_t gfs2_alloc_meta(struct gfs2_inode *ip)
uint64_t gfs2_alloc_di(struct gfs2_inode *dip)
{
- struct gfs2_sbd *sdp = dip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct gfs2_alloc *al = &dip->i_alloc;
struct gfs2_rgrpd *rgd = al->al_rgd;
uint32_t blk;
@@ -1341,7 +1349,7 @@ uint64_t gfs2_alloc_di(struct gfs2_inode *dip)
void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrpd *rgd;
rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
@@ -1370,7 +1378,7 @@ void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrpd *rgd;
rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE);
@@ -1385,11 +1393,25 @@ void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen)
gfs2_trans_add_rg(rgd);
gfs2_statfs_change(sdp, 0, +blen, 0);
- gfs2_quota_change(ip, -(int64_t)blen,
- ip->i_di.di_uid, ip->i_di.di_gid);
+ gfs2_quota_change(ip, -(int64_t)blen, ip->i_di.di_uid, ip->i_di.di_gid);
gfs2_meta_wipe(ip, bstart, blen);
}
+void gfs2_unlink_di(struct inode *inode)
+{
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
+ struct gfs2_rgrpd *rgd;
+ u64 blkno = ip->i_num.no_addr;
+
+ rgd = rgblk_free(sdp, blkno, 1, GFS2_BLKST_UNLINKED);
+ if (!rgd)
+ return;
+ gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1);
+ gfs2_rgrp_out(&rgd->rd_rg, rgd->rd_bits[0].bi_bh->b_data);
+ gfs2_trans_add_rg(rgd);
+}
+
void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno)
{
struct gfs2_sbd *sdp = rgd->rd_sbd;
@@ -1412,12 +1434,6 @@ void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno)
gfs2_trans_add_rg(rgd);
}
-/**
- * gfs2_free_uninit_di - free a dinode block
- * @rgd: the resource group that contains the dinode
- * @ip: the inode
- *
- */
void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
{
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index d2db371..e86a532 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -45,6 +45,7 @@ void gfs2_free_data(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen);
void gfs2_free_meta(struct gfs2_inode *ip, uint64_t bstart, uint32_t blen);
void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, uint64_t blkno);
void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
+void gfs2_unlink_di(struct inode *inode);
struct gfs2_rgrp_list {
unsigned int rl_rgrps;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index a943a50..f2d2876 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -31,7 +31,6 @@
#include "rgrp.h"
#include "super.h"
#include "trans.h"
-#include "unlinked.h"
#include "util.h"
/**
@@ -55,7 +54,6 @@ void gfs2_tune_init(struct gfs2_tune *gt)
gt->gt_recoverd_secs = 60;
gt->gt_logd_secs = 1;
gt->gt_quotad_secs = 5;
- gt->gt_inoded_secs = 15;
gt->gt_quota_simul_sync = 64;
gt->gt_quota_warn_period = 10;
gt->gt_quota_scale_num = 1;
@@ -202,9 +200,6 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2;
sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t);
- sdp->sd_ut_per_block = (sdp->sd_sb.sb_bsize -
- sizeof(struct gfs2_meta_header)) /
- sizeof(struct gfs2_unlinked_tag);
sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -
sizeof(struct gfs2_meta_header)) /
sizeof(struct gfs2_quota_change);
@@ -277,7 +272,7 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent)
int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
{
- struct gfs2_inode *dip = sdp->sd_jindex->u.generic_ip;
+ struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex);
struct qstr name;
char buf[20];
struct gfs2_jdesc *jd;
@@ -296,8 +291,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
name.len = sprintf(buf, "journal%u", sdp->sd_journals);
name.hash = gfs2_disk_hash(name.name, name.len);
- error = gfs2_dir_search(sdp->sd_jindex,
- &name, NULL, NULL);
+ error = gfs2_dir_search(sdp->sd_jindex, &name, NULL, NULL);
if (error == -ENOENT) {
error = 0;
break;
@@ -423,22 +417,19 @@ struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp)
int gfs2_jdesc_check(struct gfs2_jdesc *jd)
{
- struct gfs2_inode *ip = jd->jd_inode->u.generic_ip;
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
int ar;
int error;
- if (ip->i_di.di_size < (8 << 20) ||
- ip->i_di.di_size > (1 << 30) ||
+ if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) ||
(ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) {
gfs2_consist_inode(ip);
return -EIO;
}
jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
- error = gfs2_write_alloc_required(ip,
- 0, ip->i_di.di_size,
- &ar);
+ error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar);
if (!error && ar) {
gfs2_consist_inode(ip);
error = -EIO;
@@ -456,7 +447,7 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
{
- struct gfs2_inode *ip = sdp->sd_jdesc->jd_inode->u.generic_ip;
+ struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
struct gfs2_glock *j_gl = ip->i_gl;
struct gfs2_holder t_gh;
struct gfs2_log_header head;
@@ -484,9 +475,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
sdp->sd_log_sequence = head.lh_sequence + 1;
gfs2_log_pointers_init(sdp, head.lh_blkno);
- error = gfs2_unlinked_init(sdp);
- if (error)
- goto fail;
error = gfs2_quota_init(sdp);
if (error)
goto fail_unlinked;
@@ -498,7 +486,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
return 0;
fail_unlinked:
- gfs2_unlinked_cleanup(sdp);
fail:
t_gh.gh_flags |= GL_NOCACHE;
@@ -519,7 +506,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
struct gfs2_holder t_gh;
int error;
- gfs2_unlinked_dealloc(sdp);
gfs2_quota_sync(sdp);
gfs2_statfs_sync(sdp);
@@ -537,7 +523,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
if (t_gh.gh_gl)
gfs2_glock_dq_uninit(&t_gh);
- gfs2_unlinked_cleanup(sdp);
gfs2_quota_cleanup(sdp);
return error;
@@ -545,9 +530,9 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
int gfs2_statfs_init(struct gfs2_sbd *sdp)
{
- struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip;
+ struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
- struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
+ struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
struct buffer_head *m_bh, *l_bh;
struct gfs2_holder gh;
@@ -594,7 +579,7 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
int64_t dinodes)
{
- struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
+ struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
struct buffer_head *l_bh;
int error;
@@ -620,8 +605,8 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free,
int gfs2_statfs_sync(struct gfs2_sbd *sdp)
{
- struct gfs2_inode *m_ip = sdp->sd_statfs_inode->u.generic_ip;
- struct gfs2_inode *l_ip = sdp->sd_sc_inode->u.generic_ip;
+ struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
+ struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master;
struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local;
struct gfs2_holder gh;
@@ -852,10 +837,8 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
error = -ENOMEM;
goto out;
}
- ip = jd->jd_inode->u.generic_ip;
- error = gfs2_glock_nq_init(ip->i_gl,
- LM_ST_SHARED, 0,
- &lfcc->gh);
+ ip = GFS2_I(jd->jd_inode);
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &lfcc->gh);
if (error) {
kfree(lfcc);
goto out;
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index d32a2c5..3c4cb45 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -453,7 +453,6 @@ TUNE_ATTR_DAEMON(scand_secs, scand_process);
TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process);
TUNE_ATTR_DAEMON(logd_secs, logd_process);
TUNE_ATTR_DAEMON(quotad_secs, quotad_process);
-TUNE_ATTR_DAEMON(inoded_secs, inoded_process);
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
static struct attribute *tune_attrs[] = {
@@ -485,7 +484,6 @@ static struct attribute *tune_attrs[] = {
&tune_attr_recoverd_secs.attr,
&tune_attr_logd_secs.attr,
&tune_attr_quotad_secs.attr,
- &tune_attr_inoded_secs.attr,
&tune_attr_quota_scale.attr,
&tune_attr_new_files_jdata.attr,
&tune_attr_new_files_directio.attr,
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
index 60ef163..fbef3f5 100644
--- a/fs/gfs2/trans.h
+++ b/fs/gfs2/trans.h
@@ -17,7 +17,6 @@
#define RES_LEAF 1
#define RES_RG_BIT 2
#define RES_EATTR 1
-#define RES_UNLINKED 1
#define RES_STATFS 1
#define RES_QUOTA 2
diff --git a/fs/gfs2/unlinked.c b/fs/gfs2/unlinked.c
deleted file mode 100644
index b92d730..0000000
--- a/fs/gfs2/unlinked.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
- */
-
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/buffer_head.h>
-#include <linux/kthread.h>
-#include <linux/gfs2_ondisk.h>
-
-#include "gfs2.h"
-#include "lm_interface.h"
-#include "incore.h"
-#include "bmap.h"
-#include "inode.h"
-#include "meta_io.h"
-#include "trans.h"
-#include "unlinked.h"
-#include "util.h"
-
-static int munge_ondisk(struct gfs2_sbd *sdp, unsigned int slot,
- struct gfs2_unlinked_tag *ut)
-{
- struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
- unsigned int block, offset;
- uint64_t dblock;
- int new = 0;
- struct buffer_head *bh;
- int error;
- int boundary;
-
- block = slot / sdp->sd_ut_per_block;
- offset = slot % sdp->sd_ut_per_block;
-
- error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
- if (error)
- return error;
- error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
- if (error)
- return error;
- if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
- error = -EIO;
- goto out;
- }
-
- mutex_lock(&sdp->sd_unlinked_mutex);
- gfs2_trans_add_bh(ip->i_gl, bh, 1);
- gfs2_unlinked_tag_out(ut, bh->b_data +
- sizeof(struct gfs2_meta_header) +
- offset * sizeof(struct gfs2_unlinked_tag));
- mutex_unlock(&sdp->sd_unlinked_mutex);
-
- out:
- brelse(bh);
-
- return error;
-}
-
-static void ul_hash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- spin_lock(&sdp->sd_unlinked_spin);
- list_add(&ul->ul_list, &sdp->sd_unlinked_list);
- gfs2_assert(sdp, ul->ul_count);
- ul->ul_count++;
- atomic_inc(&sdp->sd_unlinked_count);
- spin_unlock(&sdp->sd_unlinked_spin);
-}
-
-static void ul_unhash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- spin_lock(&sdp->sd_unlinked_spin);
- list_del_init(&ul->ul_list);
- gfs2_assert(sdp, ul->ul_count > 1);
- ul->ul_count--;
- gfs2_assert_warn(sdp, atomic_read(&sdp->sd_unlinked_count) > 0);
- atomic_dec(&sdp->sd_unlinked_count);
- spin_unlock(&sdp->sd_unlinked_spin);
-}
-
-static struct gfs2_unlinked *ul_fish(struct gfs2_sbd *sdp)
-{
- struct list_head *head;
- struct gfs2_unlinked *ul;
- int found = 0;
-
- if (sdp->sd_vfs->s_flags & MS_RDONLY)
- return NULL;
-
- spin_lock(&sdp->sd_unlinked_spin);
-
- head = &sdp->sd_unlinked_list;
-
- list_for_each_entry(ul, head, ul_list) {
- if (test_bit(ULF_LOCKED, &ul->ul_flags))
- continue;
-
- list_move_tail(&ul->ul_list, head);
- ul->ul_count++;
- set_bit(ULF_LOCKED, &ul->ul_flags);
- found = 1;
-
- break;
- }
-
- if (!found)
- ul = NULL;
-
- spin_unlock(&sdp->sd_unlinked_spin);
-
- return ul;
-}
-
-/**
- * enforce_limit - limit the number of inodes waiting to be deallocated
- * @sdp: the filesystem
- *
- * Returns: errno
- */
-
-static void enforce_limit(struct gfs2_sbd *sdp)
-{
- unsigned int tries = 0, min = 0;
- int error;
-
- if (atomic_read(&sdp->sd_unlinked_count) <
- gfs2_tune_get(sdp, gt_ilimit))
- return;
-
- tries = gfs2_tune_get(sdp, gt_ilimit_tries);
- min = gfs2_tune_get(sdp, gt_ilimit_min);
-
- while (tries--) {
- struct gfs2_unlinked *ul = ul_fish(sdp);
- if (!ul)
- break;
- error = gfs2_inode_dealloc(sdp, ul);
- gfs2_unlinked_put(sdp, ul);
-
- if (!error) {
- if (!--min)
- break;
- } else if (error != 1)
- break;
- }
-}
-
-static struct gfs2_unlinked *ul_alloc(struct gfs2_sbd *sdp)
-{
- struct gfs2_unlinked *ul;
-
- ul = kzalloc(sizeof(struct gfs2_unlinked), GFP_KERNEL);
- if (ul) {
- INIT_LIST_HEAD(&ul->ul_list);
- ul->ul_count = 1;
- set_bit(ULF_LOCKED, &ul->ul_flags);
- }
-
- return ul;
-}
-
-int gfs2_unlinked_get(struct gfs2_sbd *sdp, struct gfs2_unlinked **ul)
-{
- unsigned int c, o = 0, b;
- unsigned char byte = 0;
-
- enforce_limit(sdp);
-
- *ul = ul_alloc(sdp);
- if (!*ul)
- return -ENOMEM;
-
- spin_lock(&sdp->sd_unlinked_spin);
-
- for (c = 0; c < sdp->sd_unlinked_chunks; c++)
- for (o = 0; o < PAGE_SIZE; o++) {
- byte = sdp->sd_unlinked_bitmap[c][o];
- if (byte != 0xFF)
- goto found;
- }
-
- goto fail;
-
-found:
- for (b = 0; b < 8; b++)
- if (!(byte & (1 << b)))
- break;
- (*ul)->ul_slot = c * (8 * PAGE_SIZE) + o * 8 + b;
-
- if ((*ul)->ul_slot >= sdp->sd_unlinked_slots)
- goto fail;
-
- sdp->sd_unlinked_bitmap[c][o] |= 1 << b;
-
- spin_unlock(&sdp->sd_unlinked_spin);
-
- return 0;
-
-fail:
- spin_unlock(&sdp->sd_unlinked_spin);
- kfree(*ul);
- return -ENOSPC;
-}
-
-void gfs2_unlinked_put(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- gfs2_assert_warn(sdp, test_and_clear_bit(ULF_LOCKED, &ul->ul_flags));
-
- spin_lock(&sdp->sd_unlinked_spin);
- gfs2_assert(sdp, ul->ul_count);
- ul->ul_count--;
- if (!ul->ul_count) {
- gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, ul->ul_slot, 0);
- spin_unlock(&sdp->sd_unlinked_spin);
- kfree(ul);
- } else
- spin_unlock(&sdp->sd_unlinked_spin);
-}
-
-int gfs2_unlinked_ondisk_add(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- int error;
-
- gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
- gfs2_assert_warn(sdp, list_empty(&ul->ul_list));
-
- error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);
- if (!error)
- ul_hash(sdp, ul);
-
- return error;
-}
-
-int gfs2_unlinked_ondisk_munge(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- int error;
-
- gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
- gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));
-
- error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);
-
- return error;
-}
-
-int gfs2_unlinked_ondisk_rm(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
-{
- struct gfs2_unlinked_tag ut;
- int error;
-
- gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
- gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));
-
- memset(&ut, 0, sizeof(struct gfs2_unlinked_tag));
-
- error = munge_ondisk(sdp, ul->ul_slot, &ut);
- if (error)
- return error;
-
- ul_unhash(sdp, ul);
-
- return 0;
-}
-
-/**
- * gfs2_unlinked_dealloc - Go through the list of inodes to be deallocated
- * @sdp: the filesystem
- *
- * Returns: errno
- */
-
-int gfs2_unlinked_dealloc(struct gfs2_sbd *sdp)
-{
- unsigned int hits, strikes;
- int error;
-
- for (;;) {
- hits = 0;
- strikes = 0;
-
- for (;;) {
- struct gfs2_unlinked *ul = ul_fish(sdp);
- if (!ul)
- return 0;
- error = gfs2_inode_dealloc(sdp, ul);
- gfs2_unlinked_put(sdp, ul);
-
- if (!error) {
- hits++;
- if (strikes)
- strikes--;
- } else if (error == 1) {
- strikes++;
- if (strikes >=
- atomic_read(&sdp->sd_unlinked_count)) {
- error = 0;
- break;
- }
- } else
- return error;
- }
-
- if (!hits || kthread_should_stop())
- break;
-
- cond_resched();
- }
-
- return 0;
-}
-
-int gfs2_unlinked_init(struct gfs2_sbd *sdp)
-{
- struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
- unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
- unsigned int x, slot = 0;
- unsigned int found = 0;
- uint64_t dblock;
- uint32_t extlen = 0;
- int error;
-
- if (!ip->i_di.di_size ||
- ip->i_di.di_size > (64 << 20) ||
- ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1)) {
- gfs2_consist_inode(ip);
- return -EIO;
- }
- sdp->sd_unlinked_slots = blocks * sdp->sd_ut_per_block;
- sdp->sd_unlinked_chunks = DIV_ROUND_UP(sdp->sd_unlinked_slots,
- 8 * PAGE_SIZE);
-
- error = -ENOMEM;
-
- sdp->sd_unlinked_bitmap = kcalloc(sdp->sd_unlinked_chunks,
- sizeof(unsigned char *),
- GFP_KERNEL);
- if (!sdp->sd_unlinked_bitmap)
- return error;
-
- for (x = 0; x < sdp->sd_unlinked_chunks; x++) {
- sdp->sd_unlinked_bitmap[x] = kzalloc(PAGE_SIZE, GFP_KERNEL);
- if (!sdp->sd_unlinked_bitmap[x])
- goto fail;
- }
-
- for (x = 0; x < blocks; x++) {
- struct buffer_head *bh;
- unsigned int y;
-
- if (!extlen) {
- int new = 0;
- error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
- if (error)
- goto fail;
- }
- gfs2_meta_ra(ip->i_gl, dblock, extlen);
- error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT,
- &bh);
- if (error)
- goto fail;
- error = -EIO;
- if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
- brelse(bh);
- goto fail;
- }
-
- for (y = 0;
- y < sdp->sd_ut_per_block && slot < sdp->sd_unlinked_slots;
- y++, slot++) {
- struct gfs2_unlinked_tag ut;
- struct gfs2_unlinked *ul;
-
- gfs2_unlinked_tag_in(&ut, bh->b_data +
- sizeof(struct gfs2_meta_header) +
- y * sizeof(struct gfs2_unlinked_tag));
- if (!ut.ut_inum.no_addr)
- continue;
-
- error = -ENOMEM;
- ul = ul_alloc(sdp);
- if (!ul) {
- brelse(bh);
- goto fail;
- }
- ul->ul_ut = ut;
- ul->ul_slot = slot;
-
- spin_lock(&sdp->sd_unlinked_spin);
- gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, slot, 1);
- spin_unlock(&sdp->sd_unlinked_spin);
- ul_hash(sdp, ul);
-
- gfs2_unlinked_put(sdp, ul);
- found++;
- }
-
- brelse(bh);
- dblock++;
- extlen--;
- }
-
- if (found)
- fs_info(sdp, "found %u unlinked inodes\n", found);
-
- return 0;
-
-fail:
- gfs2_unlinked_cleanup(sdp);
- return error;
-}
-
-/**
- * gfs2_unlinked_cleanup - get rid of any extra struct gfs2_unlinked structures
- * @sdp: the filesystem
- *
- */
-
-void gfs2_unlinked_cleanup(struct gfs2_sbd *sdp)
-{
- struct list_head *head = &sdp->sd_unlinked_list;
- struct gfs2_unlinked *ul;
- unsigned int x;
-
- spin_lock(&sdp->sd_unlinked_spin);
- while (!list_empty(head)) {
- ul = list_entry(head->next, struct gfs2_unlinked, ul_list);
-
- if (ul->ul_count > 1) {
- list_move_tail(&ul->ul_list, head);
- spin_unlock(&sdp->sd_unlinked_spin);
- schedule();
- spin_lock(&sdp->sd_unlinked_spin);
- continue;
- }
-
- list_del_init(&ul->ul_list);
- atomic_dec(&sdp->sd_unlinked_count);
-
- gfs2_assert_warn(sdp, ul->ul_count == 1);
- gfs2_assert_warn(sdp, !test_bit(ULF_LOCKED, &ul->ul_flags));
- kfree(ul);
- }
- spin_unlock(&sdp->sd_unlinked_spin);
-
- gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_unlinked_count));
-
- if (sdp->sd_unlinked_bitmap) {
- for (x = 0; x < sdp->sd_unlinked_chunks; x++)
- kfree(sdp->sd_unlinked_bitmap[x]);
- kfree(sdp->sd_unlinked_bitmap);
- }
-}
-
diff --git a/fs/gfs2/unlinked.h b/fs/gfs2/unlinked.h
deleted file mode 100644
index 159cf5f..0000000
--- a/fs/gfs2/unlinked.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
- */
-
-#ifndef __UNLINKED_DOT_H__
-#define __UNLINKED_DOT_H__
-
-int gfs2_unlinked_get(struct gfs2_sbd *sdp, struct gfs2_unlinked **ul);
-void gfs2_unlinked_put(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-
-int gfs2_unlinked_ondisk_add(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-int gfs2_unlinked_ondisk_munge(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-int gfs2_unlinked_ondisk_rm(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul);
-
-int gfs2_unlinked_dealloc(struct gfs2_sbd *sdp);
-
-int gfs2_unlinked_init(struct gfs2_sbd *sdp);
-void gfs2_unlinked_cleanup(struct gfs2_sbd *sdp);
-
-#endif /* __UNLINKED_DOT_H__ */
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 88974e9..39e67b1 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -109,7 +109,7 @@ int gfs2_consist_i(struct gfs2_sbd *sdp, int cluster_wide, const char *function,
int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
const char *function, char *file, unsigned int line)
{
- struct gfs2_sbd *sdp = ip->i_sbd;
+ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
int rv;
rv = gfs2_lm_withdraw(sdp,
"GFS2: fsid=%s: fatal: filesystem consistency error\n"
OpenPOWER on IntegriCloud