mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
We've got nine patches this time:
- Abhi Das has two patches that fix a GFS2 splice issue (and an adjustment). - Ben Marzinski has a patch which allows the proper unmount of a GFS2 file system after hitting a withdraw error. - I have a patch to fix a problem where GFS2 would dereference an error value, plus three cosmetic / refactoring patches. - Daniel DeFreez has a patch to fix two glock reference count problems, where GFS2 was not properly "uninitializing" its glock holder on error paths. - Denys Vlasenko has a patch to change a function to not be inlined, thus reducing the memory footprint of the GFS2 module. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJXP2KLAAoJENeLYdPf93o7nScH/jlDCv+JzwBwAiFEVelgB657 lFY+Q3bPvmcTaHiOqXzco7U1EeyvAuZ+x9duaFBBEGC2/NydIbkAdCP1XjDOTAGZ aVVAP8qov4adFiXTfBdzMYjJ7DArOy/JRnlC8WK5OiD/3yxsXJZNlAHTgjjL/ZMq PkhjxX2Lc9ZHGF9YIFTyeoBlqf1qO6WbhkxvSNefgq3c702QPM+T9XND5T1duGDF ThEcXS2DRRoE+6wr3h+ruvS5kcfxXRLLausAgqNpj2FYQOFCQ6XXgGK8pyXA5V/t 3Vh8mHW0VmSjAfrRWslCRjd+APXoOf+7QHqOHUAA1dvQ6CGfC9qTETH9Wp32JCI= =8g+a -----END PGP SIGNATURE----- Merge tag 'gfs2-4.7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2 Pull GFS2 updates from Bob Peterson: "We've got nine patches this time: - Abhi Das has two patches that fix a GFS2 splice issue (and an adjustment). - Ben Marzinski has a patch which allows the proper unmount of a GFS2 file system after hitting a withdraw error. - I have a patch to fix a problem where GFS2 would dereference an error value, plus three cosmetic / refactoring patches. - Daniel DeFreez has a patch to fix two glock reference count problems, where GFS2 was not properly "uninitializing" its glock holder on error paths. - Denys Vlasenko has a patch to change a function to not be inlined, thus reducing the memory footprint of the GFS2 module" * tag 'gfs2-4.7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: GFS2: Refactor gfs2_remove_from_journal GFS2: Remove allocation parms from gfs2_rbm_find gfs2: use inode_lock/unlock instead of accessing i_mutex directly GFS2: Add calls to gfs2_holder_uninit in two error handlers GFS2: Don't dereference inode in gfs2_inode_lookup until it's valid GFS2: fs/gfs2/glock.c: Deinline do_error, save 1856 bytes gfs2: Use gfs2 wrapper to sync inode before calling generic_file_splice_read() GFS2: Get rid of dead code in inode_go_demote_ok GFS2: ignore unlock failures after withdraw
This commit is contained in:
commit
be1332c099
@ -977,7 +977,7 @@ static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh)
|
||||
if (!list_empty(&bd->bd_list) && !buffer_pinned(bh))
|
||||
list_del_init(&bd->bd_list);
|
||||
else
|
||||
gfs2_remove_from_journal(bh, current->journal_info, 0);
|
||||
gfs2_remove_from_journal(bh, REMOVE_JDATA);
|
||||
}
|
||||
bh->b_bdev = NULL;
|
||||
clear_buffer_mapped(bh);
|
||||
@ -1063,7 +1063,7 @@ static ssize_t gfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
||||
gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, &gh);
|
||||
rv = gfs2_glock_nq(&gh);
|
||||
if (rv)
|
||||
return rv;
|
||||
goto out_uninit;
|
||||
rv = gfs2_ok_for_dio(ip, offset);
|
||||
if (rv != 1)
|
||||
goto out; /* dio not valid, fall back to buffered i/o */
|
||||
@ -1102,6 +1102,7 @@ static ssize_t gfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
||||
gfs2_get_block_direct, NULL, NULL, 0);
|
||||
out:
|
||||
gfs2_glock_dq(&gh);
|
||||
out_uninit:
|
||||
gfs2_holder_uninit(&gh);
|
||||
return rv;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
|
||||
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
|
||||
error = gfs2_glock_nq(&gh);
|
||||
if (error)
|
||||
return error;
|
||||
goto out_uninit;
|
||||
|
||||
fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_diskflags);
|
||||
if (!S_ISDIR(inode->i_mode) && ip->i_diskflags & GFS2_DIF_JDATA)
|
||||
@ -169,6 +169,7 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
|
||||
error = -EFAULT;
|
||||
|
||||
gfs2_glock_dq(&gh);
|
||||
out_uninit:
|
||||
gfs2_holder_uninit(&gh);
|
||||
return error;
|
||||
}
|
||||
@ -953,6 +954,30 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t le
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t gfs2_file_splice_read(struct file *in, loff_t *ppos,
|
||||
struct pipe_inode_info *pipe, size_t len,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct inode *inode = in->f_mapping->host;
|
||||
struct gfs2_inode *ip = GFS2_I(inode);
|
||||
struct gfs2_holder gh;
|
||||
int ret;
|
||||
|
||||
inode_lock(inode);
|
||||
|
||||
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
|
||||
if (ret) {
|
||||
inode_unlock(inode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gfs2_glock_dq_uninit(&gh);
|
||||
inode_unlock(inode);
|
||||
|
||||
return generic_file_splice_read(in, ppos, pipe, len, flags);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t gfs2_file_splice_write(struct pipe_inode_info *pipe,
|
||||
struct file *out, loff_t *ppos,
|
||||
size_t len, unsigned int flags)
|
||||
@ -1115,7 +1140,7 @@ const struct file_operations gfs2_file_fops = {
|
||||
.fsync = gfs2_fsync,
|
||||
.lock = gfs2_lock,
|
||||
.flock = gfs2_flock,
|
||||
.splice_read = generic_file_splice_read,
|
||||
.splice_read = gfs2_file_splice_read,
|
||||
.splice_write = gfs2_file_splice_write,
|
||||
.setlease = simple_nosetlease,
|
||||
.fallocate = gfs2_fallocate,
|
||||
@ -1143,7 +1168,7 @@ const struct file_operations gfs2_file_fops_nolock = {
|
||||
.open = gfs2_open,
|
||||
.release = gfs2_release,
|
||||
.fsync = gfs2_fsync,
|
||||
.splice_read = generic_file_splice_read,
|
||||
.splice_read = gfs2_file_splice_read,
|
||||
.splice_write = gfs2_file_splice_write,
|
||||
.setlease = generic_setlease,
|
||||
.fallocate = gfs2_fallocate,
|
||||
|
@ -218,7 +218,7 @@ static void gfs2_holder_wake(struct gfs2_holder *gh)
|
||||
*
|
||||
*/
|
||||
|
||||
static inline void do_error(struct gfs2_glock *gl, const int ret)
|
||||
static void do_error(struct gfs2_glock *gl, const int ret)
|
||||
{
|
||||
struct gfs2_holder *gh, *tmp;
|
||||
|
||||
@ -475,7 +475,14 @@ __acquires(&gl->gl_lockref.lock)
|
||||
if (sdp->sd_lockstruct.ls_ops->lm_lock) {
|
||||
/* lock_dlm */
|
||||
ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags);
|
||||
if (ret) {
|
||||
if (ret == -EINVAL && gl->gl_target == LM_ST_UNLOCKED &&
|
||||
target == LM_ST_UNLOCKED &&
|
||||
test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags)) {
|
||||
finish_xmote(gl, target);
|
||||
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
|
||||
gfs2_glock_put(gl);
|
||||
}
|
||||
else if (ret) {
|
||||
pr_err("lm_lock ret %d\n", ret);
|
||||
GLOCK_BUG_ON(gl, 1);
|
||||
}
|
||||
|
@ -286,17 +286,10 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
|
||||
static int inode_go_demote_ok(const struct gfs2_glock *gl)
|
||||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||
struct gfs2_holder *gh;
|
||||
|
||||
if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object)
|
||||
return 0;
|
||||
|
||||
if (!list_empty(&gl->gl_holders)) {
|
||||
gh = list_entry(gl->gl_holders.next, struct gfs2_holder, gh_list);
|
||||
if (gh->gh_list.next != &gl->gl_holders)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -93,12 +93,12 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
||||
int error;
|
||||
|
||||
inode = iget_locked(sb, (unsigned long)no_addr);
|
||||
ip = GFS2_I(inode);
|
||||
ip->i_no_addr = no_addr;
|
||||
|
||||
if (!inode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ip = GFS2_I(inode);
|
||||
ip->i_no_addr = no_addr;
|
||||
|
||||
if (inode->i_state & I_NEW) {
|
||||
struct gfs2_sbd *sdp = GFS2_SB(inode);
|
||||
ip->i_no_formal_ino = no_formal_ino;
|
||||
|
@ -325,18 +325,19 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int meta)
|
||||
void gfs2_remove_from_journal(struct buffer_head *bh, int meta)
|
||||
{
|
||||
struct address_space *mapping = bh->b_page->mapping;
|
||||
struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping);
|
||||
struct gfs2_bufdata *bd = bh->b_private;
|
||||
struct gfs2_trans *tr = current->journal_info;
|
||||
int was_pinned = 0;
|
||||
|
||||
if (test_clear_buffer_pinned(bh)) {
|
||||
trace_gfs2_pin(bd, 0);
|
||||
atomic_dec(&sdp->sd_log_pinned);
|
||||
list_del_init(&bd->bd_list);
|
||||
if (meta)
|
||||
if (meta == REMOVE_META)
|
||||
tr->tr_num_buf_rm++;
|
||||
else
|
||||
tr->tr_num_databuf_rm++;
|
||||
@ -376,7 +377,7 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
|
||||
if (bh) {
|
||||
lock_buffer(bh);
|
||||
gfs2_log_lock(sdp);
|
||||
gfs2_remove_from_journal(bh, current->journal_info, 1);
|
||||
gfs2_remove_from_journal(bh, REMOVE_META);
|
||||
gfs2_log_unlock(sdp);
|
||||
unlock_buffer(bh);
|
||||
brelse(bh);
|
||||
|
@ -57,8 +57,12 @@ extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
|
||||
extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh);
|
||||
extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno,
|
||||
int create);
|
||||
extern void gfs2_remove_from_journal(struct buffer_head *bh,
|
||||
struct gfs2_trans *tr, int meta);
|
||||
enum {
|
||||
REMOVE_JDATA = 0,
|
||||
REMOVE_META = 1,
|
||||
};
|
||||
|
||||
extern void gfs2_remove_from_journal(struct buffer_head *bh, int meta);
|
||||
extern void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen);
|
||||
extern int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
|
||||
struct buffer_head **bhp);
|
||||
|
@ -73,8 +73,7 @@ static const char valid_change[16] = {
|
||||
};
|
||||
|
||||
static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
|
||||
const struct gfs2_inode *ip, bool nowrap,
|
||||
const struct gfs2_alloc_parms *ap);
|
||||
const struct gfs2_inode *ip, bool nowrap);
|
||||
|
||||
|
||||
/**
|
||||
@ -1511,7 +1510,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
|
||||
if (WARN_ON(gfs2_rbm_from_block(&rbm, goal)))
|
||||
return;
|
||||
|
||||
ret = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &extlen, ip, true, ap);
|
||||
ret = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &extlen, ip, true);
|
||||
if (ret == 0) {
|
||||
rs->rs_rbm = rbm;
|
||||
rs->rs_free = extlen;
|
||||
@ -1638,7 +1637,6 @@ static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm,
|
||||
* @ip: If set, check for reservations
|
||||
* @nowrap: Stop looking at the end of the rgrp, rather than wrapping
|
||||
* around until we've reached the starting point.
|
||||
* @ap: the allocation parameters
|
||||
*
|
||||
* Side effects:
|
||||
* - If looking for free blocks, we set GBF_FULL on each bitmap which
|
||||
@ -1650,8 +1648,7 @@ static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm,
|
||||
*/
|
||||
|
||||
static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
|
||||
const struct gfs2_inode *ip, bool nowrap,
|
||||
const struct gfs2_alloc_parms *ap)
|
||||
const struct gfs2_inode *ip, bool nowrap)
|
||||
{
|
||||
struct buffer_head *bh;
|
||||
int initial_bii;
|
||||
@ -1772,7 +1769,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
|
||||
while (1) {
|
||||
down_write(&sdp->sd_log_flush_lock);
|
||||
error = gfs2_rbm_find(&rbm, GFS2_BLKST_UNLINKED, NULL, NULL,
|
||||
true, NULL);
|
||||
true);
|
||||
up_write(&sdp->sd_log_flush_lock);
|
||||
if (error == -ENOSPC)
|
||||
break;
|
||||
@ -2329,12 +2326,11 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
|
||||
int error;
|
||||
|
||||
gfs2_set_alloc_start(&rbm, ip, dinode);
|
||||
error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, NULL, ip, false, NULL);
|
||||
error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, NULL, ip, false);
|
||||
|
||||
if (error == -ENOSPC) {
|
||||
gfs2_set_alloc_start(&rbm, ip, dinode);
|
||||
error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, NULL, NULL, false,
|
||||
NULL);
|
||||
error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, NULL, NULL, false);
|
||||
}
|
||||
|
||||
/* Since all blocks are reserved in advance, this shouldn't happen */
|
||||
|
@ -68,6 +68,7 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...)
|
||||
fs_err(sdp, "telling LM to unmount\n");
|
||||
lm->lm_unmount(sdp);
|
||||
}
|
||||
set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags);
|
||||
fs_err(sdp, "withdrawn\n");
|
||||
dump_stack();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user