Skip to content

Commit

Permalink
Merge branch 'akpm' (patches from Andrew)
Browse files Browse the repository at this point in the history
Merge more updates from Andrew Morton:

 - more ocfs2 work

 - various leftovers

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  memory_hotplug: cond_resched in __remove_pages
  bfs: add sanity check at bfs_fill_super()
  kernel/sysctl.c: remove duplicated include
  kernel/kexec_file.c: remove some duplicated includes
  mm, thp: consolidate THP gfp handling into alloc_hugepage_direct_gfpmask
  ocfs2: fix clusters leak in ocfs2_defrag_extent()
  ocfs2: dlmglue: clean up timestamp handling
  ocfs2: don't put and assigning null to bh allocated outside
  ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry
  ocfs2: don't use iocb when EIOCBQUEUED returns
  ocfs2: without quota support, avoid calling quota recovery
  ocfs2: remove ocfs2_is_o2cb_active()
  mm: thp: relax __GFP_THISNODE for MADV_HUGEPAGE mappings
  include/linux/notifier.h: SRCU: fix ctags
  mm: handle no memcg case in memcg_kmem_charge() properly
  • Loading branch information
Linus Torvalds committed Nov 3, 2018
2 parents 5f21585 + dd33ad7 commit cddfa11
Show file tree
Hide file tree
Showing 19 changed files with 172 additions and 124 deletions.
9 changes: 6 additions & 3 deletions fs/bfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)

s->s_magic = BFS_MAGIC;

if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) {
if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end) ||
le32_to_cpu(bfs_sb->s_start) < BFS_BSIZE) {
printf("Superblock is corrupted\n");
goto out1;
}
Expand All @@ -359,9 +360,11 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
sizeof(struct bfs_inode)
+ BFS_ROOT_INO - 1;
imap_len = (info->si_lasti / 8) + 1;
info->si_imap = kzalloc(imap_len, GFP_KERNEL);
if (!info->si_imap)
info->si_imap = kzalloc(imap_len, GFP_KERNEL | __GFP_NOWARN);
if (!info->si_imap) {
printf("Cannot allocate %u bytes\n", imap_len);
goto out1;
}
for (i = 0; i < BFS_ROOT_INO; i++)
set_bit(i, info->si_imap);

Expand Down
77 changes: 59 additions & 18 deletions fs/ocfs2/buffer_head_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,25 +99,34 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
return ret;
}

/* Caller must provide a bhs[] with all NULL or non-NULL entries, so it
* will be easier to handle read failure.
*/
int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
unsigned int nr, struct buffer_head *bhs[])
{
int status = 0;
unsigned int i;
struct buffer_head *bh;
int new_bh = 0;

trace_ocfs2_read_blocks_sync((unsigned long long)block, nr);

if (!nr)
goto bail;

/* Don't put buffer head and re-assign it to NULL if it is allocated
* outside since the caller can't be aware of this alternation!
*/
new_bh = (bhs[0] == NULL);

for (i = 0 ; i < nr ; i++) {
if (bhs[i] == NULL) {
bhs[i] = sb_getblk(osb->sb, block++);
if (bhs[i] == NULL) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
break;
}
}
bh = bhs[i];
Expand Down Expand Up @@ -158,9 +167,26 @@ int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
submit_bh(REQ_OP_READ, 0, bh);
}

read_failure:
for (i = nr; i > 0; i--) {
bh = bhs[i - 1];

if (unlikely(status)) {
if (new_bh && bh) {
/* If middle bh fails, let previous bh
* finish its read and then put it to
* aovoid bh leak
*/
if (!buffer_jbd(bh))
wait_on_buffer(bh);
put_bh(bh);
bhs[i - 1] = NULL;
} else if (bh && buffer_uptodate(bh)) {
clear_buffer_uptodate(bh);
}
continue;
}

/* No need to wait on the buffer if it's managed by JBD. */
if (!buffer_jbd(bh))
wait_on_buffer(bh);
Expand All @@ -170,15 +196,17 @@ int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
* so we can safely record this and loop back
* to cleanup the other buffers. */
status = -EIO;
put_bh(bh);
bhs[i - 1] = NULL;
goto read_failure;
}
}

bail:
return status;
}

/* Caller must provide a bhs[] with all NULL or non-NULL entries, so it
* will be easier to handle read failure.
*/
int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
struct buffer_head *bhs[], int flags,
int (*validate)(struct super_block *sb,
Expand All @@ -188,6 +216,7 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
int i, ignore_cache = 0;
struct buffer_head *bh;
struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
int new_bh = 0;

trace_ocfs2_read_blocks_begin(ci, (unsigned long long)block, nr, flags);

Expand All @@ -213,6 +242,11 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
goto bail;
}

/* Don't put buffer head and re-assign it to NULL if it is allocated
* outside since the caller can't be aware of this alternation!
*/
new_bh = (bhs[0] == NULL);

ocfs2_metadata_cache_io_lock(ci);
for (i = 0 ; i < nr ; i++) {
if (bhs[i] == NULL) {
Expand All @@ -221,7 +255,8 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
ocfs2_metadata_cache_io_unlock(ci);
status = -ENOMEM;
mlog_errno(status);
goto bail;
/* Don't forget to put previous bh! */
break;
}
}
bh = bhs[i];
Expand Down Expand Up @@ -316,16 +351,27 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
}
}

status = 0;

read_failure:
for (i = (nr - 1); i >= 0; i--) {
bh = bhs[i];

if (!(flags & OCFS2_BH_READAHEAD)) {
if (status) {
/* Clear the rest of the buffers on error */
put_bh(bh);
bhs[i] = NULL;
if (unlikely(status)) {
/* Clear the buffers on error including those
* ever succeeded in reading
*/
if (new_bh && bh) {
/* If middle bh fails, let previous bh
* finish its read and then put it to
* aovoid bh leak
*/
if (!buffer_jbd(bh))
wait_on_buffer(bh);
put_bh(bh);
bhs[i] = NULL;
} else if (bh && buffer_uptodate(bh)) {
clear_buffer_uptodate(bh);
}
continue;
}
/* We know this can't have changed as we hold the
Expand All @@ -343,9 +389,7 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
* uptodate. */
status = -EIO;
clear_buffer_needs_validate(bh);
put_bh(bh);
bhs[i] = NULL;
continue;
goto read_failure;
}

if (buffer_needs_validate(bh)) {
Expand All @@ -355,11 +399,8 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
BUG_ON(buffer_jbd(bh));
clear_buffer_needs_validate(bh);
status = validate(sb, bh);
if (status) {
put_bh(bh);
bhs[i] = NULL;
continue;
}
if (status)
goto read_failure;
}
}

Expand Down
3 changes: 1 addition & 2 deletions fs/ocfs2/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1897,8 +1897,7 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
/* On error, skip the f_pos to the
next block. */
ctx->pos = (ctx->pos | (sb->s_blocksize - 1)) + 1;
brelse(bh);
continue;
break;
}
if (le64_to_cpu(de->inode)) {
unsigned char d_type = DT_UNKNOWN;
Expand Down
28 changes: 10 additions & 18 deletions fs/ocfs2/dlmglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -2123,10 +2123,10 @@ static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb,

/* LVB only has room for 64 bits of time here so we pack it for
* now. */
static u64 ocfs2_pack_timespec(struct timespec *spec)
static u64 ocfs2_pack_timespec(struct timespec64 *spec)
{
u64 res;
u64 sec = spec->tv_sec;
u64 sec = clamp_t(time64_t, spec->tv_sec, 0, 0x3ffffffffull);
u32 nsec = spec->tv_nsec;

res = (sec << OCFS2_SEC_SHIFT) | (nsec & OCFS2_NSEC_MASK);
Expand All @@ -2142,7 +2142,6 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb;
struct timespec ts;

lvb = ocfs2_dlm_lvb(&lockres->l_lksb);

Expand All @@ -2163,15 +2162,12 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
lvb->lvb_imode = cpu_to_be16(inode->i_mode);
lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
ts = timespec64_to_timespec(inode->i_atime);
lvb->lvb_iatime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts));
ts = timespec64_to_timespec(inode->i_ctime);
cpu_to_be64(ocfs2_pack_timespec(&inode->i_atime));
lvb->lvb_ictime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts));
ts = timespec64_to_timespec(inode->i_mtime);
cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
lvb->lvb_imtime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts));
cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
lvb->lvb_iattr = cpu_to_be32(oi->ip_attr);
lvb->lvb_idynfeatures = cpu_to_be16(oi->ip_dyn_features);
lvb->lvb_igeneration = cpu_to_be32(inode->i_generation);
Expand All @@ -2180,7 +2176,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
mlog_meta_lvb(0, lockres);
}

static void ocfs2_unpack_timespec(struct timespec *spec,
static void ocfs2_unpack_timespec(struct timespec64 *spec,
u64 packed_time)
{
spec->tv_sec = packed_time >> OCFS2_SEC_SHIFT;
Expand All @@ -2189,7 +2185,6 @@ static void ocfs2_unpack_timespec(struct timespec *spec,

static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
{
struct timespec ts;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb;
Expand Down Expand Up @@ -2217,15 +2212,12 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
inode->i_mode = be16_to_cpu(lvb->lvb_imode);
set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
ocfs2_unpack_timespec(&ts,
ocfs2_unpack_timespec(&inode->i_atime,
be64_to_cpu(lvb->lvb_iatime_packed));
inode->i_atime = timespec_to_timespec64(ts);
ocfs2_unpack_timespec(&ts,
ocfs2_unpack_timespec(&inode->i_mtime,
be64_to_cpu(lvb->lvb_imtime_packed));
inode->i_mtime = timespec_to_timespec64(ts);
ocfs2_unpack_timespec(&ts,
ocfs2_unpack_timespec(&inode->i_ctime,
be64_to_cpu(lvb->lvb_ictime_packed));
inode->i_ctime = timespec_to_timespec64(ts);
spin_unlock(&oi->ip_lock);
}

Expand Down Expand Up @@ -3603,7 +3595,7 @@ static int ocfs2_downconvert_lock(struct ocfs2_super *osb,
* we can recover correctly from node failure. Otherwise, we may get
* invalid LVB in LKB, but without DLM_SBF_VALNOTVALID being set.
*/
if (!ocfs2_is_o2cb_active() &&
if (ocfs2_userspace_stack(osb) &&
lockres->l_ops->flags & LOCK_TYPE_USES_LVB)
lvb = 1;

Expand Down
4 changes: 2 additions & 2 deletions fs/ocfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2343,7 +2343,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,

written = __generic_file_write_iter(iocb, from);
/* buffered aio wouldn't have proper lock coverage today */
BUG_ON(written == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT));
BUG_ON(written == -EIOCBQUEUED && !direct_io);

/*
* deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
Expand Down Expand Up @@ -2463,7 +2463,7 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,
trace_generic_file_read_iter_ret(ret);

/* buffered aio wouldn't have proper lock coverage today */
BUG_ON(ret == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT));
BUG_ON(ret == -EIOCBQUEUED && !direct_io);

/* see ocfs2_file_write_iter */
if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) {
Expand Down
51 changes: 34 additions & 17 deletions fs/ocfs2/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1378,15 +1378,23 @@ static int __ocfs2_recovery_thread(void *arg)
int rm_quota_used = 0, i;
struct ocfs2_quota_recovery *qrec;

/* Whether the quota supported. */
int quota_enabled = OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb,
OCFS2_FEATURE_RO_COMPAT_USRQUOTA)
|| OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb,
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA);

status = ocfs2_wait_on_mount(osb);
if (status < 0) {
goto bail;
}

rm_quota = kcalloc(osb->max_slots, sizeof(int), GFP_NOFS);
if (!rm_quota) {
status = -ENOMEM;
goto bail;
if (quota_enabled) {
rm_quota = kcalloc(osb->max_slots, sizeof(int), GFP_NOFS);
if (!rm_quota) {
status = -ENOMEM;
goto bail;
}
}
restart:
status = ocfs2_super_lock(osb, 1);
Expand Down Expand Up @@ -1422,9 +1430,14 @@ static int __ocfs2_recovery_thread(void *arg)
* then quota usage would be out of sync until some node takes
* the slot. So we remember which nodes need quota recovery
* and when everything else is done, we recover quotas. */
for (i = 0; i < rm_quota_used && rm_quota[i] != slot_num; i++);
if (i == rm_quota_used)
rm_quota[rm_quota_used++] = slot_num;
if (quota_enabled) {
for (i = 0; i < rm_quota_used
&& rm_quota[i] != slot_num; i++)
;

if (i == rm_quota_used)
rm_quota[rm_quota_used++] = slot_num;
}

status = ocfs2_recover_node(osb, node_num, slot_num);
skip_recovery:
Expand Down Expand Up @@ -1452,16 +1465,19 @@ static int __ocfs2_recovery_thread(void *arg)
/* Now it is right time to recover quotas... We have to do this under
* superblock lock so that no one can start using the slot (and crash)
* before we recover it */
for (i = 0; i < rm_quota_used; i++) {
qrec = ocfs2_begin_quota_recovery(osb, rm_quota[i]);
if (IS_ERR(qrec)) {
status = PTR_ERR(qrec);
mlog_errno(status);
continue;
if (quota_enabled) {
for (i = 0; i < rm_quota_used; i++) {
qrec = ocfs2_begin_quota_recovery(osb, rm_quota[i]);
if (IS_ERR(qrec)) {
status = PTR_ERR(qrec);
mlog_errno(status);
continue;
}
ocfs2_queue_recovery_completion(osb->journal,
rm_quota[i],
NULL, NULL, qrec,
ORPHAN_NEED_TRUNCATE);
}
ocfs2_queue_recovery_completion(osb->journal, rm_quota[i],
NULL, NULL, qrec,
ORPHAN_NEED_TRUNCATE);
}

ocfs2_super_unlock(osb, 1);
Expand All @@ -1483,7 +1499,8 @@ static int __ocfs2_recovery_thread(void *arg)

mutex_unlock(&osb->recovery_lock);

kfree(rm_quota);
if (quota_enabled)
kfree(rm_quota);

/* no one is callint kthread_stop() for us so the kthread() api
* requires that we call do_exit(). And it isn't exported, but
Expand Down
Loading

0 comments on commit cddfa11

Please sign in to comment.