Skip to content

Commit 2d1a9d5

Browse files
Christoph HellwigAl Viro
authored andcommitted
minix: fix error handling in minix_set_link
If minix_prepare_chunk fails, updating c/mtime and marking the dir inode dirty is wrong, as the inode hasn't been modified. Also propagate the error to the caller. Note that this moves the dir_put_page call later, but that matches other uses of this helper in the directory code. Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent b61d15d commit 2d1a9d5

File tree

3 files changed

+20
-15
lines changed

3 files changed

+20
-15
lines changed

fs/minix/dir.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,8 @@ int minix_empty_dir(struct inode * inode)
410410
}
411411

412412
/* Releases the page */
413-
void minix_set_link(struct minix_dir_entry *de, struct page *page,
414-
struct inode *inode)
413+
int minix_set_link(struct minix_dir_entry *de, struct page *page,
414+
struct inode *inode)
415415
{
416416
struct inode *dir = page->mapping->host;
417417
struct minix_sb_info *sbi = minix_sb(dir->i_sb);
@@ -420,19 +420,21 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page,
420420
int err;
421421

422422
lock_page(page);
423-
424423
err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
425-
if (err == 0) {
426-
if (sbi->s_version == MINIX_V3)
427-
((minix3_dirent *) de)->inode = inode->i_ino;
428-
else
429-
de->inode = inode->i_ino;
430-
err = dir_commit_chunk(page, pos, sbi->s_dirsize);
431-
} else {
424+
if (err) {
432425
unlock_page(page);
426+
return err;
433427
}
428+
if (sbi->s_version == MINIX_V3)
429+
((minix3_dirent *)de)->inode = inode->i_ino;
430+
else
431+
de->inode = inode->i_ino;
432+
err = dir_commit_chunk(page, pos, sbi->s_dirsize);
433+
if (err)
434+
return err;
434435
dir->i_mtime = dir->i_ctime = current_time(dir);
435436
mark_inode_dirty(dir);
437+
return 0;
436438
}
437439

438440
struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)

fs/minix/minix.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ extern int minix_add_link(struct dentry*, struct inode*);
6969
extern int minix_delete_entry(struct minix_dir_entry*, struct page*);
7070
extern int minix_make_empty(struct inode*, struct inode*);
7171
extern int minix_empty_dir(struct inode*);
72-
extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*);
72+
int minix_set_link(struct minix_dir_entry *de, struct page *page,
73+
struct inode *inode);
7374
extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**);
7475
extern ino_t minix_inode_by_name(struct dentry*);
7576

fs/minix/namei.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,11 @@ static int minix_rename(struct user_namespace *mnt_userns,
213213
new_de = minix_find_entry(new_dentry, &new_page);
214214
if (!new_de)
215215
goto out_dir;
216-
err = 0;
217-
minix_set_link(new_de, new_page, old_inode);
216+
err = minix_set_link(new_de, new_page, old_inode);
218217
kunmap(new_page);
219218
put_page(new_page);
219+
if (err)
220+
goto out_dir;
220221
new_inode->i_ctime = current_time(new_inode);
221222
if (dir_de)
222223
drop_nlink(new_inode);
@@ -233,8 +234,9 @@ static int minix_rename(struct user_namespace *mnt_userns,
233234
mark_inode_dirty(old_inode);
234235

235236
if (dir_de) {
236-
minix_set_link(dir_de, dir_page, new_dir);
237-
inode_dec_link_count(old_dir);
237+
err = minix_set_link(dir_de, dir_page, new_dir);
238+
if (!err)
239+
inode_dec_link_count(old_dir);
238240
}
239241
out_dir:
240242
if (dir_de) {

0 commit comments

Comments
 (0)