Commit 3f1266ec authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gfs2-for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2

Pull GFS2 updates from Andreas Gruenbacher:
 "Bob's extensive filesystem withdrawal and recovery testing:
   - don't write log headers after file system withdraw
   - clean up iopen glock mess in gfs2_create_inode
   - close timing window with GLF_INVALIDATE_IN_PROGRESS
   - abort gfs2_freeze if io error is seen
   - don't loop forever in gfs2_freeze if withdrawn
   - fix infinite loop in gfs2_ail1_flush on io error
   - introduce function gfs2_withdrawn
   - fix glock reference problem in gfs2_trans_remove_revoke

  Filesystems with a block size smaller than the page size:
   - fix end-of-file handling in gfs2_page_mkwrite
   - improve mmap write vs. punch_hole consistency

  Other:
   - remove active journal side effect from gfs2_write_log_header
   - multi-block allocations in gfs2_page_mkwrite

  Minor cleanups and coding style fixes:
   - remove duplicate call from gfs2_create_inode
   - make gfs2_log_shutdown static
   - make gfs2_fs_parameters static
   - some whitespace cleanups
   - removed unnecessary semicolon"

* tag 'gfs2-for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
  gfs2: Don't write log headers after file system withdraw
  gfs2: Remove duplicate call from gfs2_create_inode
  gfs2: clean up iopen glock mess in gfs2_create_inode
  gfs2: Close timing window with GLF_INVALIDATE_IN_PROGRESS
  gfs2: Abort gfs2_freeze if io error is seen
  gfs2: Don't loop forever in gfs2_freeze if withdrawn
  gfs2: fix infinite loop in gfs2_ail1_flush on io error
  gfs2: Introduce function gfs2_withdrawn
  gfs2: fix glock reference problem in gfs2_trans_remove_revoke
  gfs2: make gfs2_log_shutdown static
  gfs2: Remove active journal side effect from gfs2_write_log_header
  gfs2: Fix end-of-file handling in gfs2_page_mkwrite
  gfs2: Multi-block allocations in gfs2_page_mkwrite
  gfs2: Improve mmap write vs. punch_hole consistency
  gfs2: make gfs2_fs_parameters static
  gfs2: Some whitespace cleanups
  gfs2: removed unnecessary semicolon
parents a2315823 ade48088
...@@ -133,7 +133,7 @@ static int gfs2_write_full_page(struct page *page, get_block_t *get_block, ...@@ -133,7 +133,7 @@ static int gfs2_write_full_page(struct page *page, get_block_t *get_block,
* the page size, the remaining memory is zeroed when mapped, and * the page size, the remaining memory is zeroed when mapped, and
* writes to that region are not written out to the file." * writes to that region are not written out to the file."
*/ */
offset = i_size & (PAGE_SIZE-1); offset = i_size & (PAGE_SIZE - 1);
if (page->index == end_index && offset) if (page->index == end_index && offset)
zero_user_segment(page, offset, PAGE_SIZE); zero_user_segment(page, offset, PAGE_SIZE);
...@@ -497,7 +497,7 @@ static int __gfs2_readpage(void *file, struct page *page) ...@@ -497,7 +497,7 @@ static int __gfs2_readpage(void *file, struct page *page)
error = mpage_readpage(page, gfs2_block_map); error = mpage_readpage(page, gfs2_block_map);
} }
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) if (unlikely(gfs2_withdrawn(sdp)))
return -EIO; return -EIO;
return error; return error;
...@@ -614,7 +614,7 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping, ...@@ -614,7 +614,7 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping,
gfs2_glock_dq(&gh); gfs2_glock_dq(&gh);
out_uninit: out_uninit:
gfs2_holder_uninit(&gh); gfs2_holder_uninit(&gh);
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) if (unlikely(gfs2_withdrawn(sdp)))
ret = -EIO; ret = -EIO;
return ret; return ret;
} }
......
...@@ -2441,8 +2441,16 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length) ...@@ -2441,8 +2441,16 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_sbd *sdp = GFS2_SB(inode);
unsigned int blocksize = i_blocksize(inode);
loff_t start, end;
int error; int error;
start = round_down(offset, blocksize);
end = round_up(offset + length, blocksize) - 1;
error = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (error)
return error;
if (gfs2_is_jdata(ip)) if (gfs2_is_jdata(ip))
error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA, error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
GFS2_JTRUNC_REVOKES); GFS2_JTRUNC_REVOKES);
...@@ -2456,9 +2464,8 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length) ...@@ -2456,9 +2464,8 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
if (error) if (error)
goto out; goto out;
} else { } else {
unsigned int start_off, end_len, blocksize; unsigned int start_off, end_len;
blocksize = i_blocksize(inode);
start_off = offset & (blocksize - 1); start_off = offset & (blocksize - 1);
end_len = (offset + length) & (blocksize - 1); end_len = (offset + length) & (blocksize - 1);
if (start_off) { if (start_off) {
......
...@@ -407,27 +407,28 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) ...@@ -407,27 +407,28 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size)
/** /**
* gfs2_allocate_page_backing - Allocate blocks for a write fault * gfs2_allocate_page_backing - Allocate blocks for a write fault
* @page: The (locked) page to allocate backing for * @page: The (locked) page to allocate backing for
* @length: Size of the allocation
* *
* We try to allocate all the blocks required for the page in one go. This * We try to allocate all the blocks required for the page in one go. This
* might fail for various reasons, so we keep trying until all the blocks to * might fail for various reasons, so we keep trying until all the blocks to
* back this page are allocated. If some of the blocks are already allocated, * back this page are allocated. If some of the blocks are already allocated,
* that is ok too. * that is ok too.
*/ */
static int gfs2_allocate_page_backing(struct page *page) static int gfs2_allocate_page_backing(struct page *page, unsigned int length)
{ {
u64 pos = page_offset(page); u64 pos = page_offset(page);
u64 size = PAGE_SIZE;
do { do {
struct iomap iomap = { }; struct iomap iomap = { };
if (gfs2_iomap_get_alloc(page->mapping->host, pos, 1, &iomap)) if (gfs2_iomap_get_alloc(page->mapping->host, pos, length, &iomap))
return -EIO; return -EIO;
iomap.length = min(iomap.length, size); if (length < iomap.length)
size -= iomap.length; iomap.length = length;
length -= iomap.length;
pos += iomap.length; pos += iomap.length;
} while (size > 0); } while (length > 0);
return 0; return 0;
} }
...@@ -448,10 +449,10 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) ...@@ -448,10 +449,10 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_sbd *sdp = GFS2_SB(inode);
struct gfs2_alloc_parms ap = { .aflags = 0, }; struct gfs2_alloc_parms ap = { .aflags = 0, };
unsigned long last_index; u64 offset = page_offset(page);
u64 pos = page_offset(page);
unsigned int data_blocks, ind_blocks, rblocks; unsigned int data_blocks, ind_blocks, rblocks;
struct gfs2_holder gh; struct gfs2_holder gh;
unsigned int length;
loff_t size; loff_t size;
int ret; int ret;
...@@ -461,20 +462,39 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) ...@@ -461,20 +462,39 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
if (ret) if (ret)
goto out; goto out;
gfs2_size_hint(vmf->vma->vm_file, pos, PAGE_SIZE);
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
ret = gfs2_glock_nq(&gh); ret = gfs2_glock_nq(&gh);
if (ret) if (ret)
goto out_uninit; goto out_uninit;
/* Check page index against inode size */
size = i_size_read(inode);
if (offset >= size) {
ret = -EINVAL;
goto out_unlock;
}
/* Update file times before taking page lock */ /* Update file times before taking page lock */
file_update_time(vmf->vma->vm_file); file_update_time(vmf->vma->vm_file);
/* page is wholly or partially inside EOF */
if (offset > size - PAGE_SIZE)
length = offset_in_page(size);
else
length = PAGE_SIZE;
gfs2_size_hint(vmf->vma->vm_file, offset, length);
set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
set_bit(GIF_SW_PAGED, &ip->i_flags); set_bit(GIF_SW_PAGED, &ip->i_flags);
if (!gfs2_write_alloc_required(ip, pos, PAGE_SIZE)) { /*
* iomap_writepage / iomap_writepages currently don't support inline
* files, so always unstuff here.
*/
if (!gfs2_is_stuffed(ip) &&
!gfs2_write_alloc_required(ip, offset, length)) {
lock_page(page); lock_page(page);
if (!PageUptodate(page) || page->mapping != inode->i_mapping) { if (!PageUptodate(page) || page->mapping != inode->i_mapping) {
ret = -EAGAIN; ret = -EAGAIN;
...@@ -487,7 +507,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) ...@@ -487,7 +507,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
if (ret) if (ret)
goto out_unlock; goto out_unlock;
gfs2_write_calc_reserv(ip, PAGE_SIZE, &data_blocks, &ind_blocks); gfs2_write_calc_reserv(ip, length, &data_blocks, &ind_blocks);
ap.target = data_blocks + ind_blocks; ap.target = data_blocks + ind_blocks;
ret = gfs2_quota_lock_check(ip, &ap); ret = gfs2_quota_lock_check(ip, &ap);
if (ret) if (ret)
...@@ -508,13 +528,6 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) ...@@ -508,13 +528,6 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
goto out_trans_fail; goto out_trans_fail;
lock_page(page); lock_page(page);
ret = -EINVAL;
size = i_size_read(inode);
last_index = (size - 1) >> PAGE_SHIFT;
/* Check page index against inode size */
if (size == 0 || (page->index > last_index))
goto out_trans_end;
ret = -EAGAIN; ret = -EAGAIN;
/* If truncated, we must retry the operation, we may have raced /* If truncated, we must retry the operation, we may have raced
* with the glock demotion code. * with the glock demotion code.
...@@ -527,7 +540,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) ...@@ -527,7 +540,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
if (gfs2_is_stuffed(ip)) if (gfs2_is_stuffed(ip))
ret = gfs2_unstuff_dinode(ip, page); ret = gfs2_unstuff_dinode(ip, page);
if (ret == 0) if (ret == 0)
ret = gfs2_allocate_page_backing(page); ret = gfs2_allocate_page_backing(page, length);
out_trans_end: out_trans_end:
if (ret) if (ret)
...@@ -961,6 +974,7 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len, ...@@ -961,6 +974,7 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
brelse(dibh); brelse(dibh);
return error; return error;
} }
/** /**
* calc_max_reserv() - Reverse of write_calc_reserv. Given a number of * calc_max_reserv() - Reverse of write_calc_reserv. Given a number of
* blocks, determine how many bytes can be written. * blocks, determine how many bytes can be written.
...@@ -1208,7 +1222,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) ...@@ -1208,7 +1222,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
cmd = F_SETLK; cmd = F_SETLK;
fl->fl_type = F_UNLCK; fl->fl_type = F_UNLCK;
} }
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) { if (unlikely(gfs2_withdrawn(sdp))) {
if (fl->fl_type == F_UNLCK) if (fl->fl_type == F_UNLCK)
locks_lock_file_wait(file, fl); locks_lock_file_wait(file, fl);
return -EIO; return -EIO;
......
...@@ -549,7 +549,7 @@ __acquires(&gl->gl_lockref.lock) ...@@ -549,7 +549,7 @@ __acquires(&gl->gl_lockref.lock)
unsigned int lck_flags = (unsigned int)(gh ? gh->gh_flags : 0); unsigned int lck_flags = (unsigned int)(gh ? gh->gh_flags : 0);
int ret; int ret;
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) && if (unlikely(gfs2_withdrawn(sdp)) &&
target != LM_ST_UNLOCKED) target != LM_ST_UNLOCKED)
return; return;
lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
...@@ -558,7 +558,14 @@ __acquires(&gl->gl_lockref.lock) ...@@ -558,7 +558,14 @@ __acquires(&gl->gl_lockref.lock)
GLOCK_BUG_ON(gl, gl->gl_state == gl->gl_target); GLOCK_BUG_ON(gl, gl->gl_state == gl->gl_target);
if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) && if ((target == LM_ST_UNLOCKED || target == LM_ST_DEFERRED) &&
glops->go_inval) { glops->go_inval) {
set_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); /*
* If another process is already doing the invalidate, let that
* finish first. The glock state machine will get back to this
* holder again later.
*/
if (test_and_set_bit(GLF_INVALIDATE_IN_PROGRESS,
&gl->gl_flags))
return;
do_error(gl, 0); /* Fail queued try locks */ do_error(gl, 0); /* Fail queued try locks */
} }
gl->gl_req = target; gl->gl_req = target;
...@@ -586,8 +593,7 @@ __acquires(&gl->gl_lockref.lock) ...@@ -586,8 +593,7 @@ __acquires(&gl->gl_lockref.lock)
} }
else if (ret) { else if (ret) {
fs_err(sdp, "lm_lock ret %d\n", ret); fs_err(sdp, "lm_lock ret %d\n", ret);
GLOCK_BUG_ON(gl, !test_bit(SDF_WITHDRAWN, GLOCK_BUG_ON(gl, !gfs2_withdrawn(sdp));
&sdp->sd_flags));
} }
} else { /* lock_nolock */ } else { /* lock_nolock */
finish_xmote(gl, target); finish_xmote(gl, target);
...@@ -1191,7 +1197,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh) ...@@ -1191,7 +1197,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh)
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
int error = 0; int error = 0;
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) if (unlikely(gfs2_withdrawn(sdp)))
return -EIO; return -EIO;
if (test_bit(GLF_LRU, &gl->gl_flags)) if (test_bit(GLF_LRU, &gl->gl_flags))
......
...@@ -350,7 +350,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) ...@@ -350,7 +350,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major),
be32_to_cpu(str->di_minor)); be32_to_cpu(str->di_minor));
break; break;
}; }
i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid));
i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid)); i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid));
...@@ -540,7 +540,7 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) ...@@ -540,7 +540,7 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh)
gfs2_consist(sdp); gfs2_consist(sdp);
/* Initialize some head of the log stuff */ /* Initialize some head of the log stuff */
if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) { if (!gfs2_withdrawn(sdp)) {
sdp->sd_log_sequence = head.lh_sequence + 1; sdp->sd_log_sequence = head.lh_sequence + 1;
gfs2_log_pointers_init(sdp, head.lh_blkno); gfs2_log_pointers_init(sdp, head.lh_blkno);
} }
......
...@@ -656,7 +656,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -656,7 +656,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
inode->i_rdev = dev; inode->i_rdev = dev;
inode->i_size = size; inode->i_size = size;
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
gfs2_set_inode_blocks(inode, 1);
munge_mode_uid_gid(dip, inode); munge_mode_uid_gid(dip, inode);
check_and_update_goal(dip); check_and_update_goal(dip);
ip->i_goal = dip->i_goal; ip->i_goal = dip->i_goal;
...@@ -712,7 +711,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -712,7 +711,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
error = gfs2_trans_begin(sdp, blocks, 0); error = gfs2_trans_begin(sdp, blocks, 0);
if (error) if (error)
goto fail_gunlock2; goto fail_free_inode;
if (blocks > 1) { if (blocks > 1) {
ip->i_eattr = ip->i_no_addr + 1; ip->i_eattr = ip->i_no_addr + 1;
...@@ -723,7 +722,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -723,7 +722,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl); error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (error) if (error)
goto fail_gunlock2; goto fail_free_inode;
BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags)); BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags));
...@@ -732,7 +731,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -732,7 +731,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
goto fail_gunlock2; goto fail_gunlock2;
glock_set_object(ip->i_iopen_gh.gh_gl, ip); glock_set_object(ip->i_iopen_gh.gh_gl, ip);
gfs2_glock_put(io_gl);
gfs2_set_iop(inode); gfs2_set_iop(inode);
insert_inode_hash(inode); insert_inode_hash(inode);
...@@ -765,6 +763,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -765,6 +763,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
mark_inode_dirty(inode); mark_inode_dirty(inode);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
/* After instantiate, errors should result in evict which will destroy
* both inode and iopen glocks properly. */
if (file) { if (file) {
file->f_mode |= FMODE_CREATED; file->f_mode |= FMODE_CREATED;
error = finish_open(file, dentry, gfs2_open_common); error = finish_open(file, dentry, gfs2_open_common);
...@@ -772,15 +772,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -772,15 +772,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
gfs2_glock_dq_uninit(ghs); gfs2_glock_dq_uninit(ghs);
gfs2_glock_dq_uninit(ghs + 1); gfs2_glock_dq_uninit(ghs + 1);
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
gfs2_glock_put(io_gl);
return error; return error;
fail_gunlock3: fail_gunlock3:
glock_clear_object(io_gl, ip); glock_clear_object(io_gl, ip);
gfs2_glock_dq_uninit(&ip->i_iopen_gh); gfs2_glock_dq_uninit(&ip->i_iopen_gh);
gfs2_glock_put(io_gl);
fail_gunlock2: fail_gunlock2:
if (io_gl) clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); gfs2_glock_put(io_gl);
fail_free_inode: fail_free_inode:
if (ip->i_gl) { if (ip->i_gl) {
glock_clear_object(ip->i_gl, ip); glock_clear_object(ip->i_gl, ip);
...@@ -1475,7 +1475,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, ...@@ -1475,7 +1475,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
error = -EEXIST; error = -EEXIST;
default: default:
goto out_gunlock; goto out_gunlock;
}; }
if (odip != ndip) { if (odip != ndip) {
if (!ndip->i_inode.i_nlink) { if (!ndip->i_inode.i_nlink) {
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include "dir.h" #include "dir.h"
#include "trace_gfs2.h" #include "trace_gfs2.h"
static void gfs2_log_shutdown(struct gfs2_sbd *sdp);
/** /**
* gfs2_struct2blk - compute stuff * gfs2_struct2blk - compute stuff
* @sdp: the filesystem * @sdp: the filesystem
...@@ -159,7 +161,8 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) ...@@ -159,7 +161,8 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
list_for_each_entry_reverse(tr, head, tr_list) { list_for_each_entry_reverse(tr, head, tr_list) {
if (wbc->nr_to_write <= 0) if (wbc->nr_to_write <= 0)
break; break;
if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw)) if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw) &&
!gfs2_withdrawn(sdp))
goto restart; goto restart;
} }
spin_unlock(&sdp->sd_ail_lock); spin_unlock(&sdp->sd_ail_lock);
...@@ -609,6 +612,14 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) ...@@ -609,6 +612,14 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
list_add(&bd->bd_list, &sdp->sd_log_revokes); list_add(&bd->bd_list, &sdp->sd_log_revokes);
} }
void gfs2_glock_remove_revoke(struct gfs2_glock *gl)
{
if (atomic_dec_return(&gl->gl_revokes) == 0) {
clear_bit(GLF_LFLUSH, &gl->gl_flags);
gfs2_glock_queue_put(gl);
}
}
void gfs2_write_revokes(struct gfs2_sbd *sdp) void gfs2_write_revokes(struct gfs2_sbd *sdp)
{ {
struct gfs2_trans *tr; struct gfs2_trans *tr;
...@@ -682,12 +693,16 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, ...@@ -682,12 +693,16 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
{ {
struct gfs2_log_header *lh; struct gfs2_log_header *lh;
u32 hash, crc; u32 hash, crc;
struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); struct page *page;
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
struct timespec64 tv; struct timespec64 tv;
struct super_block *sb = sdp->sd_vfs; struct super_block *sb = sdp->sd_vfs;
u64 dblock; u64 dblock;
if (gfs2_withdrawn(sdp))
goto out;
page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
lh = page_address(page); lh = page_address(page);
clear_page(lh); clear_page(lh);
...@@ -707,7 +722,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, ...@@ -707,7 +722,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
lh->lh_nsec = cpu_to_be32(tv.tv_nsec); lh->lh_nsec = cpu_to_be32(tv.tv_nsec);
lh->lh_sec = cpu_to_be64(tv.tv_sec); lh->lh_sec = cpu_to_be64(tv.tv_sec);
if (!list_empty(&jd->extent_list)) if (!list_empty(&jd->extent_list))
dblock = gfs2_log_bmap(sdp); dblock = gfs2_log_bmap(jd, lblock);
else { else {
int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock); int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock);
if (gfs2_assert_withdraw(sdp, ret == 0)) if (gfs2_assert_withdraw(sdp, ret == 0))
...@@ -740,6 +755,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, ...@@ -740,6 +755,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock); gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE | op_flags); gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE | op_flags);
out:
log_flush_wait(sdp); log_flush_wait(sdp);
} }
...@@ -768,6 +784,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) ...@@ -768,6 +784,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail, gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail,
sdp->sd_log_flush_head, flags, op_flags); sdp->sd_log_flush_head, flags, op_flags);
gfs2_log_incr_head(sdp);
if (sdp->sd_log_tail != tail) if (sdp->sd_log_tail != tail)
log_pull_tail(sdp, tail); log_pull_tail(sdp, tail);
...@@ -948,7 +965,7 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) ...@@ -948,7 +965,7 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
* *
*/ */
void gfs2_log_shutdown(struct gfs2_sbd *sdp) static void gfs2_log_shutdown(struct gfs2_sbd *sdp)
{ {
gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved);
gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
......
...@@ -74,9 +74,9 @@ extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, ...@@ -74,9 +74,9 @@ extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc); extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc);
extern void gfs2_log_shutdown(struct gfs2_sbd *sdp);
extern int gfs2_logd(void *data); extern int gfs2_logd(void *data);
extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd); extern void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd);
extern void gfs2_glock_remove_revoke(struct gfs2_glock *gl);
extern void gfs2_write_revokes(struct gfs2_sbd *sdp); extern void gfs2_write_revokes(struct gfs2_sbd *sdp);
#endif /* __LOG_DOT_H__ */ #endif /* __LOG_DOT_H__ */
...@@ -129,7 +129,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, ...@@ -129,7 +129,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
atomic_dec(&sdp->sd_log_pinned); atomic_dec(&sdp->sd_log_pinned);
} }
static void gfs2_log_incr_head(struct gfs2_sbd *sdp) void gfs2_log_incr_head(struct gfs2_sbd *sdp)
{ {
BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) && BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) &&
(sdp->sd_log_flush_head != sdp->sd_log_head)); (sdp->sd_log_flush_head != sdp->sd_log_head));
...@@ -138,18 +138,13 @@ static void gfs2_log_incr_head(struct gfs2_sbd *sdp) ...@@ -138,18 +138,13 @@ static void gfs2_log_incr_head(struct gfs2_sbd *sdp)
sdp->sd_log_flush_head = 0; sdp->sd_log_flush_head = 0;
} }
u64 gfs2_log_bmap(struct gfs2_sbd *sdp) u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lblock)
{ {
unsigned int lbn = sdp->sd_log_flush_head;
struct gfs2_journal_extent *je; struct gfs2_journal_extent *je;
u64 block;
list_for_each_entry(je, &sdp->sd_jdesc->extent_list, list) { list_for_each_entry(je, &jd->extent_list, list) {
if ((lbn >= je->lblock) && (lbn < (je->lblock + je->blocks))) { if (lblock >= je->lblock && lblock < je->lblock + je->blocks)
block = je->dblock + lbn - je->lblock; return je->dblock + lblock - je->lblock;
gfs2_log_incr_head(sdp);
return block;
}
} }
return -1; return -1;
...@@ -351,8 +346,11 @@ void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, ...@@ -351,8 +346,11 @@ void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh)
{ {
gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh), u64 dblock;
gfs2_log_bmap(sdp));
dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head);
gfs2_log_incr_head(sdp);
gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh), dblock);
} }
/** /**
...@@ -369,8 +367,11 @@ static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) ...@@ -369,8 +367,11 @@ static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh)
void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page) void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page)
{ {
struct super_block *sb = sdp->sd_vfs; struct super_block *sb = sdp->sd_vfs;
gfs2_log_write(sdp, page, sb->s_blocksize, 0, u64 dblock;
gfs2_log_bmap(sdp));
dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head);
gfs2_log_incr_head(sdp);
gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
} }
/** /**
...@@ -882,10 +883,7 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) ...@@ -882,10 +883,7 @@ static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
bd = list_entry(head->next, struct gfs2_bufdata, bd_list); bd = list_entry(head->next, struct gfs2_bufdata, bd_list);
list_del_init(&bd->bd_list); list_del_init(&bd->bd_list);
gl = bd->bd_gl; gl = bd->bd_gl;
if (atomic_dec_return(&gl->gl_revokes) == 0) { gfs2_glock_remove_revoke(gl);
clear_bit(GLF_LFLUSH, &gl->gl_flags);
gfs2_glock_queue_put(gl);
}
kmem_cache_free(gfs2_bufdata_cachep, bd); kmem_cache_free(gfs2_bufdata_cachep, bd);
} }
} }
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
~(2 * sizeof(__be64) - 1)) ~(2 * sizeof(__be64) - 1))
extern const struct gfs2_log_operations *gfs2_log_ops[]; extern const struct gfs2_log_operations *gfs2_log_ops[];
extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp); extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
extern u64 gfs2_log_bmap(struct gfs2_jdesc *jd, unsigned int lbn);
extern void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, extern void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
unsigned size, unsigned offset, u64 blkno); unsigned size, unsigned offset, u64 blkno);
extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page); extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page);
......
...@@ -251,7 +251,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, ...@@ -251,7 +251,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
struct buffer_head *bh, *bhs[2]; struct buffer_head *bh, *bhs[2];
int num = 0; int num = 0;
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) { if (unlikely(gfs2_withdrawn(sdp))) {
*bhp = NULL; *bhp = NULL;
return -EIO; return -EIO;
} }
...@@ -309,7 +309,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, ...@@ -309,7 +309,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh) int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
{ {
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) if (unlikely(gfs2_withdrawn(sdp)))
return -EIO; return -EIO;
wait_on_buffer(bh); wait_on_buffer(bh);
...@@ -320,7 +320,7 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh) ...@@ -320,7 +320,7 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
gfs2_io_error_bh_wd(sdp, bh); gfs2_io_error_bh_wd(sdp, bh);
return -EIO; return -EIO;
} }
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) if (unlikely(gfs2_withdrawn(sdp)))
return -EIO; return -EIO;
return 0; return 0;
......
...@@ -1006,8 +1006,7 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent) ...@@ -1006,8 +1006,7 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
void gfs2_lm_unmount(struct gfs2_sbd *sdp) void gfs2_lm_unmount(struct gfs2_sbd *sdp)
{ {
const struct lm_lockops *lm = sdp->sd_lockstruct.ls_ops; const struct lm_lockops *lm = sdp->sd_lockstruct.ls_ops;
if (likely(!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) && if (likely(!gfs2_withdrawn(sdp)) && lm->lm_unmount)
lm->lm_unmount)
lm->lm_unmount(sdp); lm->lm_unmount(sdp);
} }
...@@ -1328,7 +1327,7 @@ static const struct fs_parameter_enum gfs2_param_enums[] = { ...@@ -1328,7 +1327,7 @@ static const struct fs_parameter_enum gfs2_param_enums[] = {
{} {}
}; };
const struct fs_parameter_description gfs2_fs_parameters = { static const struct fs_parameter_description gfs2_fs_parameters = {
.name = "gfs2", .name = "gfs2",
.specs = gfs2_param_specs, .specs = gfs2_param_specs,
.enums = gfs2_param_enums, .enums = gfs2_param_enums,
......
...@@ -1273,7 +1273,7 @@ int gfs2_quota_sync(struct super_block *sb, int type) ...@@ -1273,7 +1273,7 @@ int gfs2_quota_sync(struct super_block *sb, int type)
{ {
struct gfs2_sbd *sdp = sb->s_fs_info; struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_quota_data **qda; struct gfs2_quota_data **qda;
unsigned int max_qd = PAGE_SIZE/sizeof(struct gfs2_holder); unsigned int max_qd = PAGE_SIZE / sizeof(struct gfs2_holder);
unsigned int num_qd; unsigned int num_qd;
unsigned int x; unsigned int x;
int error = 0; int error = 0;
...@@ -1475,7 +1475,7 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error) ...@@ -1475,7 +1475,7 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error)
{ {
if (error == 0 || error == -EROFS) if (error == 0 || error == -EROFS)
return; return;
if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) { if (!gfs2_withdrawn(sdp)) {
fs_err(sdp, "gfs2_quotad: %s error %d\n", msg, error); fs_err(sdp, "gfs2_quotad: %s error %d\n", msg, error);
sdp->sd_log_error = error; sdp->sd_log_error = error;
wake_up(&sdp->sd_logd_waitq); wake_up(&sdp->sd_logd_waitq);
......
...@@ -263,11 +263,13 @@ static void clean_journal(struct gfs2_jdesc *jd, ...@@ -263,11 +263,13 @@ static void clean_journal(struct gfs2_jdesc *jd,
u32 lblock = head->lh_blkno; u32 lblock = head->lh_blkno;
gfs2_replay_incr_blk(jd, &lblock); gfs2_replay_incr_blk(jd, &lblock);
if (jd->jd_jid == sdp->sd_lockstruct.ls_jid)
sdp->sd_log_flush_head = lblock;
gfs2_write_log_header(sdp, jd, head->lh_sequence + 1, 0, lblock, gfs2_write_log_header(sdp, jd, head->lh_sequence + 1, 0, lblock,
GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_RECOVERY, GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_RECOVERY,
REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC); REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC);
if (jd->jd_jid == sdp->sd_lockstruct.ls_jid) {
sdp->sd_log_flush_head = lblock;
gfs2_log_incr_head(sdp);
}
} }
...@@ -326,7 +328,7 @@ void gfs2_recover_func(struct work_struct *work) ...@@ -326,7 +328,7 @@ void gfs2_recover_func(struct work_struct *work)
default: default:
goto fail; goto fail;
}; }
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
LM_FLAG_NOEXP | GL_NOCACHE, &ji_gh); LM_FLAG_NOEXP | GL_NOCACHE, &ji_gh);
......
...@@ -399,8 +399,7 @@ struct lfcc { ...@@ -399,8 +399,7 @@ struct lfcc {
* Returns: errno * Returns: errno
*/ */
static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp)
struct gfs2_holder *freeze_gh)
{ {
struct gfs2_inode *ip; struct gfs2_inode *ip;
struct gfs2_jdesc *jd; struct gfs2_jdesc *jd;
...@@ -425,7 +424,9 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, ...@@ -425,7 +424,9 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
} }
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE, error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE,
GL_NOCACHE, freeze_gh); GL_NOCACHE, &sdp->sd_freeze_gh);
if (error)
goto out;
list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
error = gfs2_jdesc_check(jd); error = gfs2_jdesc_check(jd);
...@@ -441,7 +442,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, ...@@ -441,7 +442,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
} }
if (error) if (error)
gfs2_glock_dq_uninit(freeze_gh); gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
out: out:
while (!list_empty(&list)) { while (!list_empty(&list)) {
...@@ -553,7 +554,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags) ...@@ -553,7 +554,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
if (!(flags & I_DIRTY_INODE)) if (!(flags & I_DIRTY_INODE))
return; return;
if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) if (unlikely(gfs2_withdrawn(sdp)))
return; return;
if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
...@@ -602,7 +603,7 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) ...@@ -602,7 +603,7 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE, error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE,
&freeze_gh); &freeze_gh);
if (error && !test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) if (error && !gfs2_withdrawn(sdp))
return error; return error;
flush_workqueue(gfs2_delete_workqueue); flush_workqueue(gfs2_delete_workqueue);
...@@ -761,21 +762,25 @@ static int gfs2_freeze(struct super_block *sb) ...@@ -761,21 +762,25 @@ static int gfs2_freeze(struct super_block *sb)
if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN)
goto out; goto out;
if (test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) {
error = -EINVAL;
goto out;
}
for (;;) { for (;;) {
error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh); if (gfs2_withdrawn(sdp)) {
error = -EINVAL;
goto out;
}
error = gfs2_lock_fs_check_clean(sdp);
if (!error) if (!error)
break; break;
if (error == -EBUSY) if (error == -EBUSY)
fs_err(sdp, "waiting for recovery before freeze\n"); fs_err(sdp, "waiting for recovery before freeze\n");
else else if (error == -EIO) {
fs_err(sdp, "Fatal IO error: cannot freeze gfs2 due "
"to recovery error.\n");
goto out;
} else {
fs_err(sdp, "error freezing FS: %d\n", error); fs_err(sdp, "error freezing FS: %d\n", error);
}
fs_err(sdp, "retrying...\n"); fs_err(sdp, "retrying...\n");
msleep(1000); msleep(1000);
} }
......
...@@ -118,7 +118,7 @@ static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len) ...@@ -118,7 +118,7 @@ static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf) static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf)
{ {
unsigned int b = test_bit(SDF_WITHDRAWN, &sdp->sd_flags); unsigned int b = gfs2_withdrawn(sdp);
return snprintf(buf, PAGE_SIZE, "%u\n", b); return snprintf(buf, PAGE_SIZE, "%u\n", b);
} }
......
...@@ -262,6 +262,8 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) ...@@ -262,6 +262,8 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len)
list_del_init(&bd->bd_list); list_del_init(&bd->bd_list);
gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke);
sdp->sd_log_num_revoke--; sdp->sd_log_num_revoke--;
if (bd->bd_gl)
gfs2_glock_remove_revoke(bd->bd_gl);
kmem_cache_free(gfs2_bufdata_cachep, bd); kmem_cache_free(gfs2_bufdata_cachep, bd);
tr->tr_num_revoke--; tr->tr_num_revoke--;
if (--n == 0) if (--n == 0)
......
...@@ -258,7 +258,7 @@ void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, ...@@ -258,7 +258,7 @@ 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)
{ {
if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) if (!gfs2_withdrawn(sdp))
fs_err(sdp, fs_err(sdp,
"fatal: I/O error\n" "fatal: I/O error\n"
" block = %llu\n" " block = %llu\n"
......
...@@ -164,6 +164,15 @@ static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, ...@@ -164,6 +164,15 @@ static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt,
return x; return x;
} }
/**
* gfs2_withdrawn - test whether the file system is withdrawing or withdrawn
* @sdp: the superblock
*/
static inline bool gfs2_withdrawn(struct gfs2_sbd *sdp)
{
return test_bit(SDF_WITHDRAWN, &sdp->sd_flags);
}
#define gfs2_tune_get(sdp, field) \ #define gfs2_tune_get(sdp, field) \
gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field) gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field)
......
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