Skip to content

Commit ad6ec09

Browse files
committed
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "7 patches. Subsystems affected by this patch series: lib, ocfs2, and mm (slub, migration, and memcg)" * emailed patches from Andrew Morton <[email protected]>: mm/memcg: fix NULL pointer dereference in memcg_slab_free_hook() slub: fix unreclaimable slab stat for bulk free mm/migrate: fix NR_ISOLATED corruption on 64-bit mm: memcontrol: fix blocking rstat function called from atomic cgroup1 thresholding code ocfs2: issue zeroout to EOF blocks ocfs2: fix zero out valid data lib/test_string.c: move string selftest in the Runtime Testing menu
2 parents 764a5bc + 121dffe commit ad6ec09

File tree

7 files changed

+81
-57
lines changed

7 files changed

+81
-57
lines changed

fs/ocfs2/file.c

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,45 @@ static void ocfs2_truncate_cluster_pages(struct inode *inode, u64 byte_start,
15291529
}
15301530
}
15311531

1532+
/*
1533+
* zero out partial blocks of one cluster.
1534+
*
1535+
* start: file offset where zero starts, will be made upper block aligned.
1536+
* len: it will be trimmed to the end of current cluster if "start + len"
1537+
* is bigger than it.
1538+
*/
1539+
static int ocfs2_zeroout_partial_cluster(struct inode *inode,
1540+
u64 start, u64 len)
1541+
{
1542+
int ret;
1543+
u64 start_block, end_block, nr_blocks;
1544+
u64 p_block, offset;
1545+
u32 cluster, p_cluster, nr_clusters;
1546+
struct super_block *sb = inode->i_sb;
1547+
u64 end = ocfs2_align_bytes_to_clusters(sb, start);
1548+
1549+
if (start + len < end)
1550+
end = start + len;
1551+
1552+
start_block = ocfs2_blocks_for_bytes(sb, start);
1553+
end_block = ocfs2_blocks_for_bytes(sb, end);
1554+
nr_blocks = end_block - start_block;
1555+
if (!nr_blocks)
1556+
return 0;
1557+
1558+
cluster = ocfs2_bytes_to_clusters(sb, start);
1559+
ret = ocfs2_get_clusters(inode, cluster, &p_cluster,
1560+
&nr_clusters, NULL);
1561+
if (ret)
1562+
return ret;
1563+
if (!p_cluster)
1564+
return 0;
1565+
1566+
offset = start_block - ocfs2_clusters_to_blocks(sb, cluster);
1567+
p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset;
1568+
return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS);
1569+
}
1570+
15321571
static int ocfs2_zero_partial_clusters(struct inode *inode,
15331572
u64 start, u64 len)
15341573
{
@@ -1538,6 +1577,7 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
15381577
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
15391578
unsigned int csize = osb->s_clustersize;
15401579
handle_t *handle;
1580+
loff_t isize = i_size_read(inode);
15411581

15421582
/*
15431583
* The "start" and "end" values are NOT necessarily part of
@@ -1558,6 +1598,26 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
15581598
if ((start & (csize - 1)) == 0 && (end & (csize - 1)) == 0)
15591599
goto out;
15601600

1601+
/* No page cache for EOF blocks, issue zero out to disk. */
1602+
if (end > isize) {
1603+
/*
1604+
* zeroout eof blocks in last cluster starting from
1605+
* "isize" even "start" > "isize" because it is
1606+
* complicated to zeroout just at "start" as "start"
1607+
* may be not aligned with block size, buffer write
1608+
* would be required to do that, but out of eof buffer
1609+
* write is not supported.
1610+
*/
1611+
ret = ocfs2_zeroout_partial_cluster(inode, isize,
1612+
end - isize);
1613+
if (ret) {
1614+
mlog_errno(ret);
1615+
goto out;
1616+
}
1617+
if (start >= isize)
1618+
goto out;
1619+
end = isize;
1620+
}
15611621
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
15621622
if (IS_ERR(handle)) {
15631623
ret = PTR_ERR(handle);
@@ -1855,45 +1915,6 @@ int ocfs2_remove_inode_range(struct inode *inode,
18551915
return ret;
18561916
}
18571917

1858-
/*
1859-
* zero out partial blocks of one cluster.
1860-
*
1861-
* start: file offset where zero starts, will be made upper block aligned.
1862-
* len: it will be trimmed to the end of current cluster if "start + len"
1863-
* is bigger than it.
1864-
*/
1865-
static int ocfs2_zeroout_partial_cluster(struct inode *inode,
1866-
u64 start, u64 len)
1867-
{
1868-
int ret;
1869-
u64 start_block, end_block, nr_blocks;
1870-
u64 p_block, offset;
1871-
u32 cluster, p_cluster, nr_clusters;
1872-
struct super_block *sb = inode->i_sb;
1873-
u64 end = ocfs2_align_bytes_to_clusters(sb, start);
1874-
1875-
if (start + len < end)
1876-
end = start + len;
1877-
1878-
start_block = ocfs2_blocks_for_bytes(sb, start);
1879-
end_block = ocfs2_blocks_for_bytes(sb, end);
1880-
nr_blocks = end_block - start_block;
1881-
if (!nr_blocks)
1882-
return 0;
1883-
1884-
cluster = ocfs2_bytes_to_clusters(sb, start);
1885-
ret = ocfs2_get_clusters(inode, cluster, &p_cluster,
1886-
&nr_clusters, NULL);
1887-
if (ret)
1888-
return ret;
1889-
if (!p_cluster)
1890-
return 0;
1891-
1892-
offset = start_block - ocfs2_clusters_to_blocks(sb, cluster);
1893-
p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset;
1894-
return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS);
1895-
}
1896-
18971918
/*
18981919
* Parts of this function taken from xfs_change_file_space()
18991920
*/
@@ -1935,15 +1956,14 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
19351956
goto out_inode_unlock;
19361957
}
19371958

1938-
orig_isize = i_size_read(inode);
19391959
switch (sr->l_whence) {
19401960
case 0: /*SEEK_SET*/
19411961
break;
19421962
case 1: /*SEEK_CUR*/
19431963
sr->l_start += f_pos;
19441964
break;
19451965
case 2: /*SEEK_END*/
1946-
sr->l_start += orig_isize;
1966+
sr->l_start += i_size_read(inode);
19471967
break;
19481968
default:
19491969
ret = -EINVAL;
@@ -1998,6 +2018,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
19982018
ret = -EINVAL;
19992019
}
20002020

2021+
orig_isize = i_size_read(inode);
20012022
/* zeroout eof blocks in the cluster. */
20022023
if (!ret && change_size && orig_isize < size) {
20032024
ret = ocfs2_zeroout_partial_cluster(inode, orig_isize,

lib/Kconfig

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -683,9 +683,6 @@ config PARMAN
683683
config OBJAGG
684684
tristate "objagg" if COMPILE_TEST
685685

686-
config STRING_SELFTEST
687-
tristate "Test string functions"
688-
689686
endmenu
690687

691688
config GENERIC_IOREMAP

lib/Kconfig.debug

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,9 @@ config ASYNC_RAID6_TEST
21802180
config TEST_HEXDUMP
21812181
tristate "Test functions located in the hexdump module at runtime"
21822182

2183+
config STRING_SELFTEST
2184+
tristate "Test string functions at runtime"
2185+
21832186
config TEST_STRING_HELPERS
21842187
tristate "Test functions located in the string_helpers module at runtime"
21852188

mm/memcontrol.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3574,7 +3574,8 @@ static unsigned long mem_cgroup_usage(struct mem_cgroup *memcg, bool swap)
35743574
unsigned long val;
35753575

35763576
if (mem_cgroup_is_root(memcg)) {
3577-
cgroup_rstat_flush(memcg->css.cgroup);
3577+
/* mem_cgroup_threshold() calls here from irqsafe context */
3578+
cgroup_rstat_flush_irqsafe(memcg->css.cgroup);
35783579
val = memcg_page_state(memcg, NR_FILE_PAGES) +
35793580
memcg_page_state(memcg, NR_ANON_MAPPED);
35803581
if (swap)

mm/migrate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2068,7 +2068,7 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma,
20682068
LIST_HEAD(migratepages);
20692069
new_page_t *new;
20702070
bool compound;
2071-
unsigned int nr_pages = thp_nr_pages(page);
2071+
int nr_pages = thp_nr_pages(page);
20722072

20732073
/*
20742074
* PTE mapped THP or HugeTLB page can't reach here so the page could

mm/slab.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ static inline void memcg_slab_free_hook(struct kmem_cache *s_orig,
346346
continue;
347347

348348
page = virt_to_head_page(p[i]);
349-
objcgs = page_objcgs(page);
349+
objcgs = page_objcgs_check(page);
350350
if (!objcgs)
351351
continue;
352352

mm/slub.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3236,6 +3236,16 @@ struct detached_freelist {
32363236
struct kmem_cache *s;
32373237
};
32383238

3239+
static inline void free_nonslab_page(struct page *page)
3240+
{
3241+
unsigned int order = compound_order(page);
3242+
3243+
VM_BUG_ON_PAGE(!PageCompound(page), page);
3244+
kfree_hook(page_address(page));
3245+
mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B, -(PAGE_SIZE << order));
3246+
__free_pages(page, order);
3247+
}
3248+
32393249
/*
32403250
* This function progressively scans the array with free objects (with
32413251
* a limited look ahead) and extract objects belonging to the same
@@ -3272,9 +3282,7 @@ int build_detached_freelist(struct kmem_cache *s, size_t size,
32723282
if (!s) {
32733283
/* Handle kalloc'ed objects */
32743284
if (unlikely(!PageSlab(page))) {
3275-
BUG_ON(!PageCompound(page));
3276-
kfree_hook(object);
3277-
__free_pages(page, compound_order(page));
3285+
free_nonslab_page(page);
32783286
p[size] = NULL; /* mark object processed */
32793287
return size;
32803288
}
@@ -4250,13 +4258,7 @@ void kfree(const void *x)
42504258

42514259
page = virt_to_head_page(x);
42524260
if (unlikely(!PageSlab(page))) {
4253-
unsigned int order = compound_order(page);
4254-
4255-
BUG_ON(!PageCompound(page));
4256-
kfree_hook(object);
4257-
mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B,
4258-
-(PAGE_SIZE << order));
4259-
__free_pages(page, order);
4261+
free_nonslab_page(page);
42604262
return;
42614263
}
42624264
slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_);

0 commit comments

Comments
 (0)