Skip to content

Commit 440e6d7

Browse files
committed
Merge tag 'jfs-6.17' of github.com:kleikamp/linux-shaggy
Pull jfs updates from Dave Kleikamp: "Fixes and cleanups for JFS filesystem" * tag 'jfs-6.17' of github.com:kleikamp/linux-shaggy: jfs: fix metapage reference count leak in dbAllocCtl jfs: stop using write_cache_pages jfs: truncate good inode pages when hard link is 0 jfs: jfs_xtree: replace XT_GETPAGE macro with xt_getpage() jfs: Regular file corruption check jfs: upper bound check of tree index in dbAllocAG
2 parents ac46ff0 + 856db37 commit 440e6d7

File tree

5 files changed

+96
-69
lines changed

5 files changed

+96
-69
lines changed

fs/jfs/file.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ static int jfs_open(struct inode *inode, struct file *file)
4444
{
4545
int rc;
4646

47+
if (S_ISREG(inode->i_mode) && inode->i_size < 0)
48+
return -EIO;
49+
4750
if ((rc = dquot_file_open(inode, file)))
4851
return rc;
4952

fs/jfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ void jfs_evict_inode(struct inode *inode)
145145
if (!inode->i_nlink && !is_bad_inode(inode)) {
146146
dquot_initialize(inode);
147147

148+
truncate_inode_pages_final(&inode->i_data);
148149
if (JFS_IP(inode)->fileset == FILESYSTEM_I) {
149150
struct inode *ipimap = JFS_SBI(inode->i_sb)->ipimap;
150-
truncate_inode_pages_final(&inode->i_data);
151151

152152
if (test_cflag(COMMIT_Freewmap, inode))
153153
jfs_free_zero_link(inode);

fs/jfs/jfs_dmap.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,12 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
13891389
(1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth;
13901390
ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
13911391

1392+
if (ti < 0 || ti >= le32_to_cpu(dcp->nleafs)) {
1393+
jfs_error(bmp->db_ipbmap->i_sb, "Corrupt dmapctl page\n");
1394+
release_metapage(mp);
1395+
return -EIO;
1396+
}
1397+
13921398
/* dmap control page trees fan-out by 4 and a single allocation
13931399
* group may be described by 1 or 2 subtrees within the ag level
13941400
* dmap control page, depending upon the ag size. examine the ag's
@@ -1809,8 +1815,10 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
18091815
return -EIO;
18101816
dp = (struct dmap *) mp->data;
18111817

1812-
if (dp->tree.budmin < 0)
1818+
if (dp->tree.budmin < 0) {
1819+
release_metapage(mp);
18131820
return -EIO;
1821+
}
18141822

18151823
/* try to allocate the blocks.
18161824
*/

fs/jfs/jfs_metapage.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ static void metapage_write_end_io(struct bio *bio)
421421
}
422422

423423
static int metapage_write_folio(struct folio *folio,
424-
struct writeback_control *wbc, void *unused)
424+
struct writeback_control *wbc)
425425
{
426426
struct bio *bio = NULL;
427427
int block_offset; /* block offset of mp within page */
@@ -550,10 +550,12 @@ static int metapage_writepages(struct address_space *mapping,
550550
struct writeback_control *wbc)
551551
{
552552
struct blk_plug plug;
553+
struct folio *folio = NULL;
553554
int err;
554555

555556
blk_start_plug(&plug);
556-
err = write_cache_pages(mapping, wbc, metapage_write_folio, NULL);
557+
while ((folio = writeback_iter(mapping, wbc, folio, &err)))
558+
err = metapage_write_folio(folio, wbc);
557559
blk_finish_plug(&plug);
558560

559561
return err;
@@ -813,7 +815,7 @@ static int metapage_write_one(struct folio *folio)
813815

814816
if (folio_clear_dirty_for_io(folio)) {
815817
folio_get(folio);
816-
ret = metapage_write_folio(folio, &wbc, NULL);
818+
ret = metapage_write_folio(folio, &wbc);
817819
if (ret == 0)
818820
folio_wait_writeback(folio);
819821
folio_put(folio);

fs/jfs/jfs_xtree.c

Lines changed: 78 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,6 @@
4949

5050
#define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot)
5151

52-
/* get page buffer for specified block address */
53-
/* ToDo: Replace this ugly macro with a function */
54-
#define XT_GETPAGE(IP, BN, MP, SIZE, P, RC) \
55-
do { \
56-
BT_GETPAGE(IP, BN, MP, xtpage_t, SIZE, P, RC, i_xtroot); \
57-
if (!(RC)) { \
58-
if ((le16_to_cpu((P)->header.nextindex) < XTENTRYSTART) || \
59-
(le16_to_cpu((P)->header.nextindex) > \
60-
le16_to_cpu((P)->header.maxentry)) || \
61-
(le16_to_cpu((P)->header.maxentry) > \
62-
(((BN) == 0) ? XTROOTMAXSLOT : PSIZE >> L2XTSLOTSIZE))) { \
63-
jfs_error((IP)->i_sb, \
64-
"XT_GETPAGE: xtree page corrupt\n"); \
65-
BT_PUTPAGE(MP); \
66-
MP = NULL; \
67-
RC = -EIO; \
68-
} \
69-
} \
70-
} while (0)
71-
7252
/* for consistency */
7353
#define XT_PUTPAGE(MP) BT_PUTPAGE(MP)
7454

@@ -114,6 +94,42 @@ static int xtSplitPage(tid_t tid, struct inode *ip, struct xtsplit * split,
11494
static int xtSplitRoot(tid_t tid, struct inode *ip,
11595
struct xtsplit * split, struct metapage ** rmpp);
11696

97+
/*
98+
* xt_getpage()
99+
*
100+
* function: get the page buffer for a specified block address.
101+
*
102+
* parameters:
103+
* ip - pointer to the inode
104+
* bn - block number (s64) of the xtree page to be retrieved;
105+
* mp - pointer to a metapage pointer where the page buffer is returned;
106+
*
107+
* returns:
108+
* A pointer to the xtree page (xtpage_t) on success, -EIO on error.
109+
*/
110+
111+
static inline xtpage_t *xt_getpage(struct inode *ip, s64 bn, struct metapage **mp)
112+
{
113+
xtpage_t *p;
114+
int rc;
115+
116+
BT_GETPAGE(ip, bn, *mp, xtpage_t, PSIZE, p, rc, i_xtroot);
117+
118+
if (rc)
119+
return ERR_PTR(rc);
120+
if ((le16_to_cpu(p->header.nextindex) < XTENTRYSTART) ||
121+
(le16_to_cpu(p->header.nextindex) >
122+
le16_to_cpu(p->header.maxentry)) ||
123+
(le16_to_cpu(p->header.maxentry) >
124+
((bn == 0) ? XTROOTMAXSLOT : PSIZE >> L2XTSLOTSIZE))) {
125+
jfs_error(ip->i_sb, "xt_getpage: xtree page corrupt\n");
126+
BT_PUTPAGE(*mp);
127+
*mp = NULL;
128+
return ERR_PTR(-EIO);
129+
}
130+
return p;
131+
}
132+
117133
/*
118134
* xtLookup()
119135
*
@@ -216,7 +232,6 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
216232
int *cmpp, struct btstack * btstack, int flag)
217233
{
218234
struct jfs_inode_info *jfs_ip = JFS_IP(ip);
219-
int rc = 0;
220235
int cmp = 1; /* init for empty page */
221236
s64 bn; /* block number */
222237
struct metapage *mp; /* page buffer */
@@ -252,9 +267,9 @@ static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
252267
*/
253268
for (bn = 0;;) {
254269
/* get/pin the page to search */
255-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
256-
if (rc)
257-
return rc;
270+
p = xt_getpage(ip, bn, &mp);
271+
if (IS_ERR(p))
272+
return PTR_ERR(p);
258273

259274
/* try sequential access heuristics with the previous
260275
* access entry in target leaf page:
@@ -807,10 +822,10 @@ xtSplitUp(tid_t tid,
807822
* insert router entry in parent for new right child page <rp>
808823
*/
809824
/* get/pin the parent page <sp> */
810-
XT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc);
811-
if (rc) {
825+
sp = xt_getpage(ip, parent->bn, &smp);
826+
if (IS_ERR(sp)) {
812827
XT_PUTPAGE(rcmp);
813-
return rc;
828+
return PTR_ERR(sp);
814829
}
815830

816831
/*
@@ -1062,10 +1077,10 @@ xtSplitPage(tid_t tid, struct inode *ip,
10621077
* update previous pointer of old next/right page of <sp>
10631078
*/
10641079
if (nextbn != 0) {
1065-
XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
1066-
if (rc) {
1080+
p = xt_getpage(ip, nextbn, &mp);
1081+
if (IS_ERR(p)) {
10671082
XT_PUTPAGE(rmp);
1068-
goto clean_up;
1083+
return PTR_ERR(p);
10691084
}
10701085

10711086
BT_MARK_DIRTY(mp, ip);
@@ -1417,9 +1432,9 @@ int xtExtend(tid_t tid, /* transaction id */
14171432
return rc;
14181433

14191434
/* get back old page */
1420-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
1421-
if (rc)
1422-
return rc;
1435+
p = xt_getpage(ip, bn, &mp);
1436+
if (IS_ERR(p))
1437+
return PTR_ERR(p);
14231438
/*
14241439
* if leaf root has been split, original root has been
14251440
* copied to new child page, i.e., original entry now
@@ -1433,9 +1448,9 @@ int xtExtend(tid_t tid, /* transaction id */
14331448
XT_PUTPAGE(mp);
14341449

14351450
/* get new child page */
1436-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
1437-
if (rc)
1438-
return rc;
1451+
p = xt_getpage(ip, bn, &mp);
1452+
if (IS_ERR(p))
1453+
return PTR_ERR(p);
14391454

14401455
BT_MARK_DIRTY(mp, ip);
14411456
if (!test_cflag(COMMIT_Nolink, ip)) {
@@ -1711,9 +1726,9 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
17111726
return rc;
17121727

17131728
/* get back old page */
1714-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
1715-
if (rc)
1716-
return rc;
1729+
p = xt_getpage(ip, bn, &mp);
1730+
if (IS_ERR(p))
1731+
return PTR_ERR(p);
17171732
/*
17181733
* if leaf root has been split, original root has been
17191734
* copied to new child page, i.e., original entry now
@@ -1727,9 +1742,9 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
17271742
XT_PUTPAGE(mp);
17281743

17291744
/* get new child page */
1730-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
1731-
if (rc)
1732-
return rc;
1745+
p = xt_getpage(ip, bn, &mp);
1746+
if (IS_ERR(p))
1747+
return PTR_ERR(p);
17331748

17341749
BT_MARK_DIRTY(mp, ip);
17351750
if (!test_cflag(COMMIT_Nolink, ip)) {
@@ -1788,9 +1803,9 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
17881803
XT_PUTPAGE(mp);
17891804

17901805
/* get new right page */
1791-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
1792-
if (rc)
1793-
return rc;
1806+
p = xt_getpage(ip, bn, &mp);
1807+
if (IS_ERR(p))
1808+
return PTR_ERR(p);
17941809

17951810
BT_MARK_DIRTY(mp, ip);
17961811
if (!test_cflag(COMMIT_Nolink, ip)) {
@@ -1864,9 +1879,9 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p);
18641879
return rc;
18651880

18661881
/* get back old page */
1867-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
1868-
if (rc)
1869-
return rc;
1882+
p = xt_getpage(ip, bn, &mp);
1883+
if (IS_ERR(p))
1884+
return PTR_ERR(p);
18701885

18711886
/*
18721887
* if leaf root has been split, original root has been
@@ -1881,9 +1896,9 @@ printf("xtUpdate.updateLeft.split p:0x%p\n", p);
18811896
XT_PUTPAGE(mp);
18821897

18831898
/* get new child page */
1884-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
1885-
if (rc)
1886-
return rc;
1899+
p = xt_getpage(ip, bn, &mp);
1900+
if (IS_ERR(p))
1901+
return PTR_ERR(p);
18871902

18881903
BT_MARK_DIRTY(mp, ip);
18891904
if (!test_cflag(COMMIT_Nolink, ip)) {
@@ -2187,7 +2202,6 @@ void xtInitRoot(tid_t tid, struct inode *ip)
21872202
*/
21882203
s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
21892204
{
2190-
int rc = 0;
21912205
s64 teof;
21922206
struct metapage *mp;
21932207
xtpage_t *p;
@@ -2268,9 +2282,9 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
22682282
* first access of each page:
22692283
*/
22702284
getPage:
2271-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
2272-
if (rc)
2273-
return rc;
2285+
p = xt_getpage(ip, bn, &mp);
2286+
if (IS_ERR(p))
2287+
return PTR_ERR(p);
22742288

22752289
/* process entries backward from last index */
22762290
index = le16_to_cpu(p->header.nextindex) - 1;
@@ -2506,9 +2520,9 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
25062520

25072521
/* get back the parent page */
25082522
bn = parent->bn;
2509-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
2510-
if (rc)
2511-
return rc;
2523+
p = xt_getpage(ip, bn, &mp);
2524+
if (IS_ERR(p))
2525+
return PTR_ERR(p);
25122526

25132527
index = parent->index;
25142528

@@ -2791,9 +2805,9 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
27912805
* first access of each page:
27922806
*/
27932807
getPage:
2794-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
2795-
if (rc)
2796-
return rc;
2808+
p = xt_getpage(ip, bn, &mp);
2809+
if (IS_ERR(p))
2810+
return PTR_ERR(p);
27972811

27982812
/* process entries backward from last index */
27992813
index = le16_to_cpu(p->header.nextindex) - 1;
@@ -2836,9 +2850,9 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
28362850

28372851
/* get back the parent page */
28382852
bn = parent->bn;
2839-
XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
2840-
if (rc)
2841-
return rc;
2853+
p = xt_getpage(ip, bn, &mp);
2854+
if (IS_ERR(p))
2855+
return PTR_ERR(p);
28422856

28432857
index = parent->index;
28442858

0 commit comments

Comments
 (0)