Commit bfd93a87 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gfs2-4.20.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2

Pull gfs2 updates from Bob Peterson:
 "We've got 18 patches for this merge window, none of which are very
  major:

   - clean up the gfs2 block allocator to prepare for future performance
     enhancements (Andreas Gruenbacher)

   - fix a use-after-free problem (Andy Price)

   - patches that fix gfs2's broken rgrplvb mount option (me)

   - cleanup patches and error message improvements (me)

   - enable getlabel support (Steve Whitehouse and Abhi Das)

   - flush the glock delete workqueue at exit (Tim Smith)"

* tag 'gfs2-4.20.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
  gfs2: Fix minor typo: couln't versus couldn't.
  gfs2: write revokes should traverse sd_ail1_list in reverse
  gfs2: Pass resource group to rgblk_free
  gfs2: Remove unnecessary gfs2_rlist_alloc parameter
  gfs2: Fix marking bitmaps non-full
  gfs2: Fix some minor typos
  gfs2: Rename bitmap.bi_{len => bytes}
  gfs2: Remove unused RGRP_RSRV_MINBYTES definition
  gfs2: Move rs_{sizehint, rgd_gh} fields into the inode
  gfs2: Clean up out-of-bounds check in gfs2_rbm_from_block
  gfs2: Always check the result of gfs2_rbm_from_block
  gfs2: getlabel support
  GFS2: Flush the GFS2 delete workqueue before stopping the kernel threads
  gfs2: Don't leave s_fs_info pointing to freed memory in init_sbd
  gfs2: Use fs_* functions instead of pr_* function where we can
  gfs2: slow the deluge of io error messages
  gfs2: Don't set GFS2_RDF_UPTODATE when the lvb is updated
  gfs2: improve debug information when lvb mismatches are found
parents e1cbbf40 8e31582a
...@@ -1566,7 +1566,7 @@ static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh, ...@@ -1566,7 +1566,7 @@ static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh,
continue; continue;
} }
if (bstart) { if (bstart) {
__gfs2_free_blocks(ip, bstart, (u32)blen, meta); __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
(*btotal) += blen; (*btotal) += blen;
gfs2_add_inode_blocks(&ip->i_inode, -blen); gfs2_add_inode_blocks(&ip->i_inode, -blen);
} }
...@@ -1574,7 +1574,7 @@ static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh, ...@@ -1574,7 +1574,7 @@ static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh,
blen = 1; blen = 1;
} }
if (bstart) { if (bstart) {
__gfs2_free_blocks(ip, bstart, (u32)blen, meta); __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
(*btotal) += blen; (*btotal) += blen;
gfs2_add_inode_blocks(&ip->i_inode, -blen); gfs2_add_inode_blocks(&ip->i_inode, -blen);
} }
......
...@@ -506,7 +506,8 @@ static int gfs2_dirent_gather(const struct gfs2_dirent *dent, ...@@ -506,7 +506,8 @@ static int gfs2_dirent_gather(const struct gfs2_dirent *dent,
* For now the most important thing is to check that the various sizes * For now the most important thing is to check that the various sizes
* are correct. * are correct.
*/ */
static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset, static int gfs2_check_dirent(struct gfs2_sbd *sdp,
struct gfs2_dirent *dent, unsigned int offset,
unsigned int size, unsigned int len, int first) unsigned int size, unsigned int len, int first)
{ {
const char *msg = "gfs2_dirent too small"; const char *msg = "gfs2_dirent too small";
...@@ -528,12 +529,12 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset, ...@@ -528,12 +529,12 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset,
goto error; goto error;
return 0; return 0;
error: error:
pr_warn("%s: %s (%s)\n", fs_warn(sdp, "%s: %s (%s)\n",
__func__, msg, first ? "first in block" : "not first in block"); __func__, msg, first ? "first in block" : "not first in block");
return -EIO; return -EIO;
} }
static int gfs2_dirent_offset(const void *buf) static int gfs2_dirent_offset(struct gfs2_sbd *sdp, const void *buf)
{ {
const struct gfs2_meta_header *h = buf; const struct gfs2_meta_header *h = buf;
int offset; int offset;
...@@ -552,7 +553,8 @@ static int gfs2_dirent_offset(const void *buf) ...@@ -552,7 +553,8 @@ static int gfs2_dirent_offset(const void *buf)
} }
return offset; return offset;
wrong_type: wrong_type:
pr_warn("%s: wrong block type %u\n", __func__, be32_to_cpu(h->mh_type)); fs_warn(sdp, "%s: wrong block type %u\n", __func__,
be32_to_cpu(h->mh_type));
return -1; return -1;
} }
...@@ -566,7 +568,7 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, ...@@ -566,7 +568,7 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
unsigned size; unsigned size;
int ret = 0; int ret = 0;
ret = gfs2_dirent_offset(buf); ret = gfs2_dirent_offset(GFS2_SB(inode), buf);
if (ret < 0) if (ret < 0)
goto consist_inode; goto consist_inode;
...@@ -574,7 +576,7 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, ...@@ -574,7 +576,7 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
prev = NULL; prev = NULL;
dent = buf + offset; dent = buf + offset;
size = be16_to_cpu(dent->de_rec_len); size = be16_to_cpu(dent->de_rec_len);
if (gfs2_check_dirent(dent, offset, size, len, 1)) if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1))
goto consist_inode; goto consist_inode;
do { do {
ret = scan(dent, name, opaque); ret = scan(dent, name, opaque);
...@@ -586,7 +588,8 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf, ...@@ -586,7 +588,8 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
prev = dent; prev = dent;
dent = buf + offset; dent = buf + offset;
size = be16_to_cpu(dent->de_rec_len); size = be16_to_cpu(dent->de_rec_len);
if (gfs2_check_dirent(dent, offset, size, len, 0)) if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size,
len, 0))
goto consist_inode; goto consist_inode;
} while(1); } while(1);
...@@ -1043,7 +1046,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) ...@@ -1043,7 +1046,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
len = BIT(dip->i_depth - be16_to_cpu(oleaf->lf_depth)); len = BIT(dip->i_depth - be16_to_cpu(oleaf->lf_depth));
half_len = len >> 1; half_len = len >> 1;
if (!half_len) { if (!half_len) {
pr_warn("i_depth %u lf_depth %u index %u\n", fs_warn(GFS2_SB(inode), "i_depth %u lf_depth %u index %u\n",
dip->i_depth, be16_to_cpu(oleaf->lf_depth), index); dip->i_depth, be16_to_cpu(oleaf->lf_depth), index);
gfs2_consist_inode(dip); gfs2_consist_inode(dip);
error = -EIO; error = -EIO;
...@@ -1351,7 +1354,7 @@ static int gfs2_set_cookies(struct gfs2_sbd *sdp, struct buffer_head *bh, ...@@ -1351,7 +1354,7 @@ static int gfs2_set_cookies(struct gfs2_sbd *sdp, struct buffer_head *bh,
if (!sdp->sd_args.ar_loccookie) if (!sdp->sd_args.ar_loccookie)
continue; continue;
offset = (char *)(darr[i]) - offset = (char *)(darr[i]) -
(bh->b_data + gfs2_dirent_offset(bh->b_data)); (bh->b_data + gfs2_dirent_offset(sdp, bh->b_data));
offset /= GFS2_MIN_DIRENT_SIZE; offset /= GFS2_MIN_DIRENT_SIZE;
offset += leaf_nr * sdp->sd_max_dents_per_leaf; offset += leaf_nr * sdp->sd_max_dents_per_leaf;
if (offset >= GFS2_USE_HASH_FLAG || if (offset >= GFS2_USE_HASH_FLAG ||
...@@ -2018,7 +2021,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, ...@@ -2018,7 +2021,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
l_blocks++; l_blocks++;
} }
gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE); gfs2_rlist_alloc(&rlist);
for (x = 0; x < rlist.rl_rgrps; x++) { for (x = 0; x < rlist.rl_rgrps; x++) {
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(rlist.rl_ghs[x].gh_gl); struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(rlist.rl_ghs[x].gh_gl);
...@@ -2039,6 +2042,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, ...@@ -2039,6 +2042,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
bh = leaf_bh; bh = leaf_bh;
for (blk = leaf_no; blk; blk = nblk) { for (blk = leaf_no; blk; blk = nblk) {
struct gfs2_rgrpd *rgd;
if (blk != leaf_no) { if (blk != leaf_no) {
error = get_leaf(dip, blk, &bh); error = get_leaf(dip, blk, &bh);
if (error) if (error)
...@@ -2049,7 +2054,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, ...@@ -2049,7 +2054,8 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
if (blk != leaf_no) if (blk != leaf_no)
brelse(bh); brelse(bh);
gfs2_free_meta(dip, blk, 1); rgd = gfs2_blk2rgrpd(sdp, blk, true);
gfs2_free_meta(dip, rgd, blk, 1);
gfs2_add_inode_blocks(&dip->i_inode, -1); gfs2_add_inode_blocks(&dip->i_inode, -1);
} }
......
...@@ -314,6 +314,17 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) ...@@ -314,6 +314,17 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
return do_gfs2_set_flags(filp, gfsflags, mask); return do_gfs2_set_flags(filp, gfsflags, mask);
} }
static int gfs2_getlabel(struct file *filp, char __user *label)
{
struct inode *inode = file_inode(filp);
struct gfs2_sbd *sdp = GFS2_SB(inode);
if (copy_to_user(label, sdp->sd_sb.sb_locktable, GFS2_LOCKNAME_LEN))
return -EFAULT;
return 0;
}
static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{ {
switch(cmd) { switch(cmd) {
...@@ -323,7 +334,10 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -323,7 +334,10 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return gfs2_set_flags(filp, (u32 __user *)arg); return gfs2_set_flags(filp, (u32 __user *)arg);
case FITRIM: case FITRIM:
return gfs2_fitrim(filp, (void __user *)arg); return gfs2_fitrim(filp, (void __user *)arg);
case FS_IOC_GETFSLABEL:
return gfs2_getlabel(filp, (char __user *)arg);
} }
return -ENOTTY; return -ENOTTY;
} }
...@@ -347,8 +361,8 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) ...@@ -347,8 +361,8 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size)
size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift;
int hint = min_t(size_t, INT_MAX, blks); int hint = min_t(size_t, INT_MAX, blks);
if (hint > atomic_read(&ip->i_res.rs_sizehint)) if (hint > atomic_read(&ip->i_sizehint))
atomic_set(&ip->i_res.rs_sizehint, hint); atomic_set(&ip->i_sizehint, hint);
} }
/** /**
......
...@@ -494,7 +494,8 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret) ...@@ -494,7 +494,8 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
do_xmote(gl, gh, LM_ST_UNLOCKED); do_xmote(gl, gh, LM_ST_UNLOCKED);
break; break;
default: /* Everything else */ default: /* Everything else */
pr_err("wanted %u got %u\n", gl->gl_target, state); fs_err(gl->gl_name.ln_sbd, "wanted %u got %u\n",
gl->gl_target, state);
GLOCK_BUG_ON(gl, 1); GLOCK_BUG_ON(gl, 1);
} }
spin_unlock(&gl->gl_lockref.lock); spin_unlock(&gl->gl_lockref.lock);
...@@ -577,7 +578,7 @@ __acquires(&gl->gl_lockref.lock) ...@@ -577,7 +578,7 @@ __acquires(&gl->gl_lockref.lock)
gfs2_glock_queue_work(gl, 0); gfs2_glock_queue_work(gl, 0);
} }
else if (ret) { else if (ret) {
pr_err("lm_lock ret %d\n", ret); fs_err(sdp, "lm_lock ret %d\n", ret);
GLOCK_BUG_ON(gl, !test_bit(SDF_SHUTDOWN, GLOCK_BUG_ON(gl, !test_bit(SDF_SHUTDOWN,
&sdp->sd_flags)); &sdp->sd_flags));
} }
...@@ -1064,13 +1065,13 @@ __acquires(&gl->gl_lockref.lock) ...@@ -1064,13 +1065,13 @@ __acquires(&gl->gl_lockref.lock)
return; return;
trap_recursive: trap_recursive:
pr_err("original: %pSR\n", (void *)gh2->gh_ip); fs_err(sdp, "original: %pSR\n", (void *)gh2->gh_ip);
pr_err("pid: %d\n", pid_nr(gh2->gh_owner_pid)); fs_err(sdp, "pid: %d\n", pid_nr(gh2->gh_owner_pid));
pr_err("lock type: %d req lock state : %d\n", fs_err(sdp, "lock type: %d req lock state : %d\n",
gh2->gh_gl->gl_name.ln_type, gh2->gh_state); gh2->gh_gl->gl_name.ln_type, gh2->gh_state);
pr_err("new: %pSR\n", (void *)gh->gh_ip); fs_err(sdp, "new: %pSR\n", (void *)gh->gh_ip);
pr_err("pid: %d\n", pid_nr(gh->gh_owner_pid)); fs_err(sdp, "pid: %d\n", pid_nr(gh->gh_owner_pid));
pr_err("lock type: %d req lock state : %d\n", fs_err(sdp, "lock type: %d req lock state : %d\n",
gh->gh_gl->gl_name.ln_type, gh->gh_state); gh->gh_gl->gl_name.ln_type, gh->gh_state);
gfs2_dump_glock(NULL, gl); gfs2_dump_glock(NULL, gl);
BUG(); BUG();
......
...@@ -92,7 +92,7 @@ struct gfs2_bitmap { ...@@ -92,7 +92,7 @@ struct gfs2_bitmap {
unsigned long bi_flags; unsigned long bi_flags;
u32 bi_offset; u32 bi_offset;
u32 bi_start; u32 bi_start;
u32 bi_len; u32 bi_bytes;
u32 bi_blocks; u32 bi_blocks;
}; };
...@@ -309,10 +309,6 @@ struct gfs2_qadata { /* quota allocation data */ ...@@ -309,10 +309,6 @@ struct gfs2_qadata { /* quota allocation data */
*/ */
struct gfs2_blkreserv { struct gfs2_blkreserv {
/* components used during write (step 1): */
atomic_t rs_sizehint; /* hint of the write size */
struct gfs2_holder rs_rgd_gh; /* Filled in by get_local_rgrp */
struct rb_node rs_node; /* link to other block reservations */ struct rb_node rs_node; /* link to other block reservations */
struct gfs2_rbm rs_rbm; /* Start of reservation */ struct gfs2_rbm rs_rbm; /* Start of reservation */
u32 rs_free; /* how many blocks are still free */ u32 rs_free; /* how many blocks are still free */
...@@ -417,8 +413,10 @@ struct gfs2_inode { ...@@ -417,8 +413,10 @@ struct gfs2_inode {
struct gfs2_holder i_iopen_gh; struct gfs2_holder i_iopen_gh;
struct gfs2_holder i_gh; /* for prepare/commit_write only */ struct gfs2_holder i_gh; /* for prepare/commit_write only */
struct gfs2_qadata *i_qadata; /* quota allocation data */ struct gfs2_qadata *i_qadata; /* quota allocation data */
struct gfs2_holder i_rgd_gh;
struct gfs2_blkreserv i_res; /* rgrp multi-block reservation */ struct gfs2_blkreserv i_res; /* rgrp multi-block reservation */
u64 i_goal; /* goal block for allocations */ u64 i_goal; /* goal block for allocations */
atomic_t i_sizehint; /* hint of the write size */
struct rw_semaphore i_rw_mutex; struct rw_semaphore i_rw_mutex;
struct list_head i_ordered; struct list_head i_ordered;
struct list_head i_trunc_list; struct list_head i_trunc_list;
...@@ -623,6 +621,7 @@ enum { ...@@ -623,6 +621,7 @@ enum {
SDF_RORECOVERY = 7, /* read only recovery */ SDF_RORECOVERY = 7, /* read only recovery */
SDF_SKIP_DLM_UNLOCK = 8, SDF_SKIP_DLM_UNLOCK = 8,
SDF_FORCE_AIL_FLUSH = 9, SDF_FORCE_AIL_FLUSH = 9,
SDF_AIL1_IO_ERROR = 10,
}; };
enum gfs2_freeze_state { enum gfs2_freeze_state {
......
...@@ -177,14 +177,14 @@ static void gdlm_bast(void *arg, int mode) ...@@ -177,14 +177,14 @@ static void gdlm_bast(void *arg, int mode)
gfs2_glock_cb(gl, LM_ST_SHARED); gfs2_glock_cb(gl, LM_ST_SHARED);
break; break;
default: default:
pr_err("unknown bast mode %d\n", mode); fs_err(gl->gl_name.ln_sbd, "unknown bast mode %d\n", mode);
BUG(); BUG();
} }
} }
/* convert gfs lock-state to dlm lock-mode */ /* convert gfs lock-state to dlm lock-mode */
static int make_mode(const unsigned int lmstate) static int make_mode(struct gfs2_sbd *sdp, const unsigned int lmstate)
{ {
switch (lmstate) { switch (lmstate) {
case LM_ST_UNLOCKED: case LM_ST_UNLOCKED:
...@@ -196,7 +196,7 @@ static int make_mode(const unsigned int lmstate) ...@@ -196,7 +196,7 @@ static int make_mode(const unsigned int lmstate)
case LM_ST_SHARED: case LM_ST_SHARED:
return DLM_LOCK_PR; return DLM_LOCK_PR;
} }
pr_err("unknown LM state %d\n", lmstate); fs_err(sdp, "unknown LM state %d\n", lmstate);
BUG(); BUG();
return -1; return -1;
} }
...@@ -257,7 +257,7 @@ static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state, ...@@ -257,7 +257,7 @@ static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
u32 lkf; u32 lkf;
char strname[GDLM_STRNAME_BYTES] = ""; char strname[GDLM_STRNAME_BYTES] = "";
req = make_mode(req_state); req = make_mode(gl->gl_name.ln_sbd, req_state);
lkf = make_flags(gl, flags, req); lkf = make_flags(gl, flags, req);
gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT); gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT); gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
...@@ -309,7 +309,7 @@ static void gdlm_put_lock(struct gfs2_glock *gl) ...@@ -309,7 +309,7 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK, error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK,
NULL, gl); NULL, gl);
if (error) { if (error) {
pr_err("gdlm_unlock %x,%llx err=%d\n", fs_err(sdp, "gdlm_unlock %x,%llx err=%d\n",
gl->gl_name.ln_type, gl->gl_name.ln_type,
(unsigned long long)gl->gl_name.ln_number, error); (unsigned long long)gl->gl_name.ln_number, error);
return; return;
......
...@@ -108,7 +108,9 @@ __acquires(&sdp->sd_ail_lock) ...@@ -108,7 +108,9 @@ __acquires(&sdp->sd_ail_lock)
gfs2_assert(sdp, bd->bd_tr == tr); gfs2_assert(sdp, bd->bd_tr == tr);
if (!buffer_busy(bh)) { if (!buffer_busy(bh)) {
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh) &&
!test_and_set_bit(SDF_AIL1_IO_ERROR,
&sdp->sd_flags)) {
gfs2_io_error_bh(sdp, bh); gfs2_io_error_bh(sdp, bh);
*withdraw = true; *withdraw = true;
} }
...@@ -206,7 +208,8 @@ static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr, ...@@ -206,7 +208,8 @@ static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr,
gfs2_assert(sdp, bd->bd_tr == tr); gfs2_assert(sdp, bd->bd_tr == tr);
if (buffer_busy(bh)) if (buffer_busy(bh))
continue; continue;
if (!buffer_uptodate(bh)) { if (!buffer_uptodate(bh) &&
!test_and_set_bit(SDF_AIL1_IO_ERROR, &sdp->sd_flags)) {
gfs2_io_error_bh(sdp, bh); gfs2_io_error_bh(sdp, bh);
*withdraw = true; *withdraw = true;
} }
...@@ -618,7 +621,7 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp) ...@@ -618,7 +621,7 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp)
gfs2_ail1_empty(sdp); gfs2_ail1_empty(sdp);
spin_lock(&sdp->sd_ail_lock); spin_lock(&sdp->sd_ail_lock);
list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) {
list_for_each_entry(bd, &tr->tr_ail2_list, bd_ail_st_list) { list_for_each_entry(bd, &tr->tr_ail2_list, bd_ail_st_list) {
if (list_empty(&bd->bd_list)) { if (list_empty(&bd->bd_list)) {
have_revokes = 1; have_revokes = 1;
...@@ -642,7 +645,7 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp) ...@@ -642,7 +645,7 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp)
} }
gfs2_log_lock(sdp); gfs2_log_lock(sdp);
spin_lock(&sdp->sd_ail_lock); spin_lock(&sdp->sd_ail_lock);
list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) { list_for_each_entry_reverse(tr, &sdp->sd_ail1_list, tr_list) {
list_for_each_entry_safe(bd, tmp, &tr->tr_ail2_list, bd_ail_st_list) { list_for_each_entry_safe(bd, tmp, &tr->tr_ail2_list, bd_ail_st_list) {
if (max_revokes == 0) if (max_revokes == 0)
goto out_of_blocks; goto out_of_blocks;
......
...@@ -81,7 +81,7 @@ static void maybe_release_space(struct gfs2_bufdata *bd) ...@@ -81,7 +81,7 @@ static void maybe_release_space(struct gfs2_bufdata *bd)
if (sdp->sd_args.ar_discard) if (sdp->sd_args.ar_discard)
gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bd->bd_bh, bi, 1, NULL); gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bd->bd_bh, bi, 1, NULL);
memcpy(bi->bi_clone + bi->bi_offset, memcpy(bi->bi_clone + bi->bi_offset,
bd->bd_bh->b_data + bi->bi_offset, bi->bi_len); bd->bd_bh->b_data + bi->bi_offset, bi->bi_bytes);
clear_bit(GBF_FULL, &bi->bi_flags); clear_bit(GBF_FULL, &bi->bi_flags);
rgd->rd_free_clone = rgd->rd_free; rgd->rd_free_clone = rgd->rd_free;
rgd->rd_extfail_pt = rgd->rd_free; rgd->rd_extfail_pt = rgd->rd_free;
......
...@@ -39,9 +39,11 @@ static void gfs2_init_inode_once(void *foo) ...@@ -39,9 +39,11 @@ static void gfs2_init_inode_once(void *foo)
struct gfs2_inode *ip = foo; struct gfs2_inode *ip = foo;
inode_init_once(&ip->i_inode); inode_init_once(&ip->i_inode);
atomic_set(&ip->i_sizehint, 0);
init_rwsem(&ip->i_rw_mutex); init_rwsem(&ip->i_rw_mutex);
INIT_LIST_HEAD(&ip->i_trunc_list); INIT_LIST_HEAD(&ip->i_trunc_list);
ip->i_qadata = NULL; ip->i_qadata = NULL;
gfs2_holder_mark_uninitialized(&ip->i_rgd_gh);
memset(&ip->i_res, 0, sizeof(ip->i_res)); memset(&ip->i_res, 0, sizeof(ip->i_res));
RB_CLEAR_NODE(&ip->i_res.rs_node); RB_CLEAR_NODE(&ip->i_res.rs_node);
ip->i_hash_cache = NULL; ip->i_hash_cache = NULL;
......
...@@ -72,13 +72,13 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) ...@@ -72,13 +72,13 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
if (!sdp) if (!sdp)
return NULL; return NULL;
sb->s_fs_info = sdp;
sdp->sd_vfs = sb; sdp->sd_vfs = sb;
sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats); sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats);
if (!sdp->sd_lkstats) { if (!sdp->sd_lkstats) {
kfree(sdp); kfree(sdp);
return NULL; return NULL;
} }
sb->s_fs_info = sdp;
set_bit(SDF_NOJOURNALID, &sdp->sd_flags); set_bit(SDF_NOJOURNALID, &sdp->sd_flags);
gfs2_tune_init(&sdp->sd_tune); gfs2_tune_init(&sdp->sd_tune);
......
...@@ -1183,7 +1183,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type) ...@@ -1183,7 +1183,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
* *
* Returns: 0 on success. * Returns: 0 on success.
* min_req = ap->min_target ? ap->min_target : ap->target; * min_req = ap->min_target ? ap->min_target : ap->target;
* quota must allow atleast min_req blks for success and * quota must allow at least min_req blks for success and
* ap->allowed is set to the number of blocks allowed * ap->allowed is set to the number of blocks allowed
* *
* -EDQUOT otherwise, quota violation. ap->allowed is set to number * -EDQUOT otherwise, quota violation. ap->allowed is set to number
......
This diff is collapsed.
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
* By reserving 32 blocks at a time, we can optimize / shortcut how we search * By reserving 32 blocks at a time, we can optimize / shortcut how we search
* through the bitmaps by looking a word at a time. * through the bitmaps by looking a word at a time.
*/ */
#define RGRP_RSRV_MINBYTES 8 #define RGRP_RSRV_MINBLKS 32
#define RGRP_RSRV_MINBLKS ((u32)(RGRP_RSRV_MINBYTES * GFS2_NBBY))
#define RGRP_RSRV_ADDBLKS 64 #define RGRP_RSRV_ADDBLKS 64
struct gfs2_rgrpd; struct gfs2_rgrpd;
...@@ -52,8 +51,10 @@ extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, ...@@ -52,8 +51,10 @@ extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
extern int gfs2_rsqa_alloc(struct gfs2_inode *ip); extern int gfs2_rsqa_alloc(struct gfs2_inode *ip);
extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs);
extern void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount); extern void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount);
extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); extern void __gfs2_free_blocks(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd,
extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); u64 bstart, u32 blen, int meta);
extern void gfs2_free_meta(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd,
u64 bstart, u32 blen);
extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
extern void gfs2_unlink_di(struct inode *inode); extern void gfs2_unlink_di(struct inode *inode);
extern int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, extern int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr,
...@@ -68,7 +69,7 @@ struct gfs2_rgrp_list { ...@@ -68,7 +69,7 @@ struct gfs2_rgrp_list {
extern void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, extern void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist,
u64 block); u64 block);
extern void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state); extern void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist);
extern void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); extern void gfs2_rlist_free(struct gfs2_rgrp_list *rlist);
extern u64 gfs2_ri_total(struct gfs2_sbd *sdp); extern u64 gfs2_ri_total(struct gfs2_sbd *sdp);
extern void gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl); extern void gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl);
......
...@@ -854,10 +854,10 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) ...@@ -854,10 +854,10 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
return error; return error;
flush_workqueue(gfs2_delete_workqueue);
kthread_stop(sdp->sd_quotad_process); kthread_stop(sdp->sd_quotad_process);
kthread_stop(sdp->sd_logd_process); kthread_stop(sdp->sd_logd_process);
flush_workqueue(gfs2_delete_workqueue);
gfs2_quota_sync(sdp->sd_vfs, 0); gfs2_quota_sync(sdp->sd_vfs, 0);
gfs2_statfs_sync(sdp->sd_vfs, 0); gfs2_statfs_sync(sdp->sd_vfs, 0);
...@@ -971,7 +971,7 @@ void gfs2_freeze_func(struct work_struct *work) ...@@ -971,7 +971,7 @@ void gfs2_freeze_func(struct work_struct *work)
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0,
&freeze_gh); &freeze_gh);
if (error) { if (error) {
printk(KERN_INFO "GFS2: couln't get freeze lock : %d\n", error); printk(KERN_INFO "GFS2: couldn't get freeze lock : %d\n", error);
gfs2_assert_withdraw(sdp, 0); gfs2_assert_withdraw(sdp, 0);
} }
else { else {
......
...@@ -74,13 +74,13 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, ...@@ -74,13 +74,13 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
return error; return error;
} }
static void gfs2_print_trans(const struct gfs2_trans *tr) static void gfs2_print_trans(struct gfs2_sbd *sdp, const struct gfs2_trans *tr)
{ {
pr_warn("Transaction created at: %pSR\n", (void *)tr->tr_ip); fs_warn(sdp, "Transaction created at: %pSR\n", (void *)tr->tr_ip);
pr_warn("blocks=%u revokes=%u reserved=%u touched=%u\n", fs_warn(sdp, "blocks=%u revokes=%u reserved=%u touched=%u\n",
tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, tr->tr_blocks, tr->tr_revokes, tr->tr_reserved,
test_bit(TR_TOUCHED, &tr->tr_flags)); test_bit(TR_TOUCHED, &tr->tr_flags));
pr_warn("Buf %u/%u Databuf %u/%u Revoke %u/%u\n", fs_warn(sdp, "Buf %u/%u Databuf %u/%u Revoke %u/%u\n",
tr->tr_num_buf_new, tr->tr_num_buf_rm, tr->tr_num_buf_new, tr->tr_num_buf_rm,
tr->tr_num_databuf_new, tr->tr_num_databuf_rm, tr->tr_num_databuf_new, tr->tr_num_databuf_rm,
tr->tr_num_revoke, tr->tr_num_revoke_rm); tr->tr_num_revoke, tr->tr_num_revoke_rm);
...@@ -109,7 +109,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) ...@@ -109,7 +109,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
if (gfs2_assert_withdraw(sdp, (nbuf <= tr->tr_blocks) && if (gfs2_assert_withdraw(sdp, (nbuf <= tr->tr_blocks) &&
(tr->tr_num_revoke <= tr->tr_revokes))) (tr->tr_num_revoke <= tr->tr_revokes)))
gfs2_print_trans(tr); gfs2_print_trans(sdp, tr);
gfs2_log_commit(sdp, tr); gfs2_log_commit(sdp, tr);
if (alloced && !test_bit(TR_ATTACHED, &tr->tr_flags)) if (alloced && !test_bit(TR_ATTACHED, &tr->tr_flags))
...@@ -225,12 +225,13 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh) ...@@ -225,12 +225,13 @@ void gfs2_trans_add_meta(struct gfs2_glock *gl, struct buffer_head *bh)
set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) { if (unlikely(mh->mh_magic != cpu_to_be32(GFS2_MAGIC))) {
pr_err("Attempting to add uninitialised block to journal (inplace block=%lld)\n", fs_err(sdp, "Attempting to add uninitialised block to "
"journal (inplace block=%lld)\n",
(unsigned long long)bd->bd_bh->b_blocknr); (unsigned long long)bd->bd_bh->b_blocknr);
BUG(); BUG();
} }
if (unlikely(state == SFS_FROZEN)) { if (unlikely(state == SFS_FROZEN)) {
printk(KERN_INFO "GFS2:adding buf while frozen\n"); fs_info(sdp, "GFS2:adding buf while frozen\n");
gfs2_assert_withdraw(sdp, 0); gfs2_assert_withdraw(sdp, 0);
} }
gfs2_pin(sdp, bd->bd_bh); gfs2_pin(sdp, bd->bd_bh);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "gfs2.h" #include "gfs2.h"
#include "incore.h" #include "incore.h"
#include "glock.h" #include "glock.h"
#include "rgrp.h"
#include "util.h" #include "util.h"
struct kmem_cache *gfs2_glock_cachep __read_mostly; struct kmem_cache *gfs2_glock_cachep __read_mostly;
...@@ -181,6 +182,8 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide, ...@@ -181,6 +182,8 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide,
{ {
struct gfs2_sbd *sdp = rgd->rd_sbd; struct gfs2_sbd *sdp = rgd->rd_sbd;
int rv; int rv;
gfs2_rgrp_dump(NULL, rgd->rd_gl);
rv = gfs2_lm_withdraw(sdp, rv = gfs2_lm_withdraw(sdp,
"fatal: filesystem consistency error\n" "fatal: filesystem consistency error\n"
" RG = %llu\n" " RG = %llu\n"
...@@ -256,12 +259,13 @@ void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, ...@@ -256,12 +259,13 @@ void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
const char *function, char *file, unsigned int line, const char *function, char *file, unsigned int line,
bool withdraw) bool withdraw)
{ {
fs_err(sdp, if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
"fatal: I/O error\n" fs_err(sdp,
" block = %llu\n" "fatal: I/O error\n"
" function = %s, file = %s, line = %u\n", " block = %llu\n"
(unsigned long long)bh->b_blocknr, " function = %s, file = %s, line = %u\n",
function, file, line); (unsigned long long)bh->b_blocknr,
function, file, line);
if (withdraw) if (withdraw)
gfs2_lm_withdraw(sdp, NULL); gfs2_lm_withdraw(sdp, NULL);
} }
......
...@@ -86,7 +86,7 @@ static inline int gfs2_meta_check(struct gfs2_sbd *sdp, ...@@ -86,7 +86,7 @@ static inline int gfs2_meta_check(struct gfs2_sbd *sdp,
struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data;
u32 magic = be32_to_cpu(mh->mh_magic); u32 magic = be32_to_cpu(mh->mh_magic);
if (unlikely(magic != GFS2_MAGIC)) { if (unlikely(magic != GFS2_MAGIC)) {
pr_err("Magic number missing at %llu\n", fs_err(sdp, "Magic number missing at %llu\n",
(unsigned long long)bh->b_blocknr); (unsigned long long)bh->b_blocknr);
return -EIO; return -EIO;
} }
......
...@@ -283,7 +283,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, ...@@ -283,7 +283,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
blen++; blen++;
else { else {
if (bstart) if (bstart)
gfs2_free_meta(ip, bstart, blen); gfs2_free_meta(ip, rgd, bstart, blen);
bstart = bn; bstart = bn;
blen = 1; blen = 1;
} }
...@@ -292,7 +292,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, ...@@ -292,7 +292,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
gfs2_add_inode_blocks(&ip->i_inode, -1); gfs2_add_inode_blocks(&ip->i_inode, -1);
} }
if (bstart) if (bstart)
gfs2_free_meta(ip, bstart, blen); gfs2_free_meta(ip, rgd, bstart, blen);
if (prev && !leave) { if (prev && !leave) {
u32 len; u32 len;
...@@ -1250,6 +1250,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) ...@@ -1250,6 +1250,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
{ {
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_rgrp_list rlist; struct gfs2_rgrp_list rlist;
struct gfs2_rgrpd *rgd;
struct buffer_head *indbh, *dibh; struct buffer_head *indbh, *dibh;
__be64 *eablk, *end; __be64 *eablk, *end;
unsigned int rg_blocks = 0; unsigned int rg_blocks = 0;
...@@ -1299,11 +1300,10 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) ...@@ -1299,11 +1300,10 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
else else
goto out; goto out;
gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE); gfs2_rlist_alloc(&rlist);
for (x = 0; x < rlist.rl_rgrps; x++) { for (x = 0; x < rlist.rl_rgrps; x++) {
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(rlist.rl_ghs[x].gh_gl); rgd = gfs2_glock2rgrp(rlist.rl_ghs[x].gh_gl);
rg_blocks += rgd->rd_length; rg_blocks += rgd->rd_length;
} }
...@@ -1320,6 +1320,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) ...@@ -1320,6 +1320,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
bstart = 0; bstart = 0;
rgd = NULL;
blen = 0; blen = 0;
for (; eablk < end; eablk++) { for (; eablk < end; eablk++) {
...@@ -1333,8 +1334,9 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) ...@@ -1333,8 +1334,9 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
blen++; blen++;
else { else {
if (bstart) if (bstart)
gfs2_free_meta(ip, bstart, blen); gfs2_free_meta(ip, rgd, bstart, blen);
bstart = bn; bstart = bn;
rgd = gfs2_blk2rgrpd(sdp, bstart, true);
blen = 1; blen = 1;
} }
...@@ -1342,7 +1344,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) ...@@ -1342,7 +1344,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
gfs2_add_inode_blocks(&ip->i_inode, -1); gfs2_add_inode_blocks(&ip->i_inode, -1);
} }
if (bstart) if (bstart)
gfs2_free_meta(ip, bstart, blen); gfs2_free_meta(ip, rgd, bstart, blen);
ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT; ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT;
...@@ -1391,7 +1393,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip) ...@@ -1391,7 +1393,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
if (error) if (error)
goto out_gunlock; goto out_gunlock;
gfs2_free_meta(ip, ip->i_eattr, 1); gfs2_free_meta(ip, rgd, ip->i_eattr, 1);
ip->i_eattr = 0; ip->i_eattr = 0;
gfs2_add_inode_blocks(&ip->i_inode, -1); gfs2_add_inode_blocks(&ip->i_inode, -1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment