Skip to content

Commit 9f26923

Browse files
committed
Merge tag 'ubifs-for-linus-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs
Pull UBI and UBIFS updates from Richard Weinberger: "UBI: - Fix error value for try_write_vid_and_data() - Minor cleanups UBIFS: - Fixes for various memory leaks - Minor cleanups" * tag 'ubifs-for-linus-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs: ubifs: Fix memleak when insert_old_idx() failed Revert "ubifs: dirty_cow_znode: Fix memleak in error handling path" ubifs: Fix memory leak in do_rename ubifs: Free memory for tmpfile name ubi: Fix return value overwrite issue in try_write_vid_and_data() ubifs: Remove return in compr_exit() ubi: Simplify bool conversion
2 parents fa31fc8 + b5fda08 commit 9f26923

5 files changed

Lines changed: 102 additions & 69 deletions

File tree

drivers/mtd/ubi/build.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,7 @@ static int __init ubi_init(void)
12661266
mutex_lock(&ubi_devices_mutex);
12671267
err = ubi_attach_mtd_dev(mtd, p->ubi_num,
12681268
p->vid_hdr_offs, p->max_beb_per1024,
1269-
p->enable_fm == 0 ? true : false);
1269+
p->enable_fm == 0);
12701270
mutex_unlock(&ubi_devices_mutex);
12711271
if (err < 0) {
12721272
pr_err("UBI error: cannot attach mtd%d\n",

drivers/mtd/ubi/eba.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum,
946946
int offset, int len)
947947
{
948948
struct ubi_device *ubi = vol->ubi;
949-
int pnum, opnum, err, vol_id = vol->vol_id;
949+
int pnum, opnum, err, err2, vol_id = vol->vol_id;
950950

951951
pnum = ubi_wl_get_peb(ubi);
952952
if (pnum < 0) {
@@ -981,10 +981,19 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum,
981981
out_put:
982982
up_read(&ubi->fm_eba_sem);
983983

984-
if (err && pnum >= 0)
985-
err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
986-
else if (!err && opnum >= 0)
987-
err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
984+
if (err && pnum >= 0) {
985+
err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
986+
if (err2) {
987+
ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
988+
pnum, err2);
989+
}
990+
} else if (!err && opnum >= 0) {
991+
err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
992+
if (err2) {
993+
ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
994+
opnum, err2);
995+
}
996+
}
988997

989998
return err;
990999
}

fs/ubifs/compress.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ static void compr_exit(struct ubifs_compressor *compr)
217217
{
218218
if (compr->capi_name)
219219
crypto_free_comp(compr->cc);
220-
return;
221220
}
222221

223222
/**

fs/ubifs/dir.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,6 @@ static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
358358
umode_t mode = S_IFCHR | WHITEOUT_MODE;
359359
struct inode *inode;
360360
struct ubifs_info *c = dir->i_sb->s_fs_info;
361-
struct fscrypt_name nm;
362361

363362
/*
364363
* Create an inode('nlink = 1') for whiteout without updating journal,
@@ -369,10 +368,6 @@ static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
369368
dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
370369
dentry, mode, dir->i_ino);
371370

372-
err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
373-
if (err)
374-
return ERR_PTR(err);
375-
376371
inode = ubifs_new_inode(c, dir, mode, false);
377372
if (IS_ERR(inode)) {
378373
err = PTR_ERR(inode);
@@ -395,7 +390,6 @@ static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
395390
make_bad_inode(inode);
396391
iput(inode);
397392
out_free:
398-
fscrypt_free_filename(&nm);
399393
ubifs_err(c, "cannot create whiteout file, error %d", err);
400394
return ERR_PTR(err);
401395
}
@@ -492,6 +486,7 @@ static int ubifs_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
492486
unlock_2_inodes(dir, inode);
493487

494488
ubifs_release_budget(c, &req);
489+
fscrypt_free_filename(&nm);
495490

496491
return finish_open_simple(file, 0);
497492

fs/ubifs/tnc.c

Lines changed: 86 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,33 @@ enum {
4444
NOT_ON_MEDIA = 3,
4545
};
4646

47+
static void do_insert_old_idx(struct ubifs_info *c,
48+
struct ubifs_old_idx *old_idx)
49+
{
50+
struct ubifs_old_idx *o;
51+
struct rb_node **p, *parent = NULL;
52+
53+
p = &c->old_idx.rb_node;
54+
while (*p) {
55+
parent = *p;
56+
o = rb_entry(parent, struct ubifs_old_idx, rb);
57+
if (old_idx->lnum < o->lnum)
58+
p = &(*p)->rb_left;
59+
else if (old_idx->lnum > o->lnum)
60+
p = &(*p)->rb_right;
61+
else if (old_idx->offs < o->offs)
62+
p = &(*p)->rb_left;
63+
else if (old_idx->offs > o->offs)
64+
p = &(*p)->rb_right;
65+
else {
66+
ubifs_err(c, "old idx added twice!");
67+
kfree(old_idx);
68+
}
69+
}
70+
rb_link_node(&old_idx->rb, parent, p);
71+
rb_insert_color(&old_idx->rb, &c->old_idx);
72+
}
73+
4774
/**
4875
* insert_old_idx - record an index node obsoleted since the last commit start.
4976
* @c: UBIFS file-system description object
@@ -69,35 +96,15 @@ enum {
6996
*/
7097
static int insert_old_idx(struct ubifs_info *c, int lnum, int offs)
7198
{
72-
struct ubifs_old_idx *old_idx, *o;
73-
struct rb_node **p, *parent = NULL;
99+
struct ubifs_old_idx *old_idx;
74100

75101
old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
76102
if (unlikely(!old_idx))
77103
return -ENOMEM;
78104
old_idx->lnum = lnum;
79105
old_idx->offs = offs;
106+
do_insert_old_idx(c, old_idx);
80107

81-
p = &c->old_idx.rb_node;
82-
while (*p) {
83-
parent = *p;
84-
o = rb_entry(parent, struct ubifs_old_idx, rb);
85-
if (lnum < o->lnum)
86-
p = &(*p)->rb_left;
87-
else if (lnum > o->lnum)
88-
p = &(*p)->rb_right;
89-
else if (offs < o->offs)
90-
p = &(*p)->rb_left;
91-
else if (offs > o->offs)
92-
p = &(*p)->rb_right;
93-
else {
94-
ubifs_err(c, "old idx added twice!");
95-
kfree(old_idx);
96-
return 0;
97-
}
98-
}
99-
rb_link_node(&old_idx->rb, parent, p);
100-
rb_insert_color(&old_idx->rb, &c->old_idx);
101108
return 0;
102109
}
103110

@@ -199,23 +206,6 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c,
199206
__set_bit(DIRTY_ZNODE, &zn->flags);
200207
__clear_bit(COW_ZNODE, &zn->flags);
201208

202-
ubifs_assert(c, !ubifs_zn_obsolete(znode));
203-
__set_bit(OBSOLETE_ZNODE, &znode->flags);
204-
205-
if (znode->level != 0) {
206-
int i;
207-
const int n = zn->child_cnt;
208-
209-
/* The children now have new parent */
210-
for (i = 0; i < n; i++) {
211-
struct ubifs_zbranch *zbr = &zn->zbranch[i];
212-
213-
if (zbr->znode)
214-
zbr->znode->parent = zn;
215-
}
216-
}
217-
218-
atomic_long_inc(&c->dirty_zn_cnt);
219209
return zn;
220210
}
221211

@@ -233,6 +223,42 @@ static int add_idx_dirt(struct ubifs_info *c, int lnum, int dirt)
233223
return ubifs_add_dirt(c, lnum, dirt);
234224
}
235225

226+
/**
227+
* replace_znode - replace old znode with new znode.
228+
* @c: UBIFS file-system description object
229+
* @new_zn: new znode
230+
* @old_zn: old znode
231+
* @zbr: the branch of parent znode
232+
*
233+
* Replace old znode with new znode in TNC.
234+
*/
235+
static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn,
236+
struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr)
237+
{
238+
ubifs_assert(c, !ubifs_zn_obsolete(old_zn));
239+
__set_bit(OBSOLETE_ZNODE, &old_zn->flags);
240+
241+
if (old_zn->level != 0) {
242+
int i;
243+
const int n = new_zn->child_cnt;
244+
245+
/* The children now have new parent */
246+
for (i = 0; i < n; i++) {
247+
struct ubifs_zbranch *child = &new_zn->zbranch[i];
248+
249+
if (child->znode)
250+
child->znode->parent = new_zn;
251+
}
252+
}
253+
254+
zbr->znode = new_zn;
255+
zbr->lnum = 0;
256+
zbr->offs = 0;
257+
zbr->len = 0;
258+
259+
atomic_long_inc(&c->dirty_zn_cnt);
260+
}
261+
236262
/**
237263
* dirty_cow_znode - ensure a znode is not being committed.
238264
* @c: UBIFS file-system description object
@@ -265,28 +291,32 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,
265291
return zn;
266292

267293
if (zbr->len) {
268-
err = insert_old_idx(c, zbr->lnum, zbr->offs);
269-
if (unlikely(err))
270-
/*
271-
* Obsolete znodes will be freed by tnc_destroy_cnext()
272-
* or free_obsolete_znodes(), copied up znodes should
273-
* be added back to tnc and freed by
274-
* ubifs_destroy_tnc_subtree().
275-
*/
294+
struct ubifs_old_idx *old_idx;
295+
296+
old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
297+
if (unlikely(!old_idx)) {
298+
err = -ENOMEM;
276299
goto out;
300+
}
301+
old_idx->lnum = zbr->lnum;
302+
old_idx->offs = zbr->offs;
303+
277304
err = add_idx_dirt(c, zbr->lnum, zbr->len);
278-
} else
279-
err = 0;
305+
if (err) {
306+
kfree(old_idx);
307+
goto out;
308+
}
280309

281-
out:
282-
zbr->znode = zn;
283-
zbr->lnum = 0;
284-
zbr->offs = 0;
285-
zbr->len = 0;
310+
do_insert_old_idx(c, old_idx);
311+
}
312+
313+
replace_znode(c, zn, znode, zbr);
286314

287-
if (unlikely(err))
288-
return ERR_PTR(err);
289315
return zn;
316+
317+
out:
318+
kfree(zn);
319+
return ERR_PTR(err);
290320
}
291321

292322
/**

0 commit comments

Comments
 (0)