From 91f646fb971f4401216a2dff5c568bcbce79a923 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 13 Dec 2022 20:14:50 -0500 Subject: [PATCH] ext2_put_page(): accept any pointer within the page eliminates the need to keep the pointer to the first byte within the page if we are guaranteed to have pointers to some byte in the same page at hand. Don't backport without commit 88d7b12068b9 ("highmem: round down the address passed to kunmap_flush_on_unmap()"). Signed-off-by: Al Viro Reviewed-by: Fabio M. De Francesco Tested-by: Fabio M. De Francesco Signed-off-by: Jan Kara --- fs/ext2/dir.c | 38 +++++++++++++++++--------------------- fs/ext2/namei.c | 8 ++++---- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 75c8f80..31b2aab 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -299,7 +299,7 @@ ext2_readdir(struct file *file, struct dir_context *ctx) if (de->rec_len == 0) { ext2_error(sb, __func__, "zero-length directory entry"); - ext2_put_page(page, kaddr); + ext2_put_page(page, de); return -EIO; } if (de->inode) { @@ -311,7 +311,7 @@ ext2_readdir(struct file *file, struct dir_context *ctx) if (!dir_emit(ctx, de->name, de->name_len, le32_to_cpu(de->inode), d_type)) { - ext2_put_page(page, kaddr); + ext2_put_page(page, de); return 0; } } @@ -377,14 +377,14 @@ struct ext2_dir_entry_2 *ext2_find_entry (struct inode *dir, if (de->rec_len == 0) { ext2_error(dir->i_sb, __func__, "zero-length directory entry"); - ext2_put_page(page, page_addr); + ext2_put_page(page, de); goto out; } if (ext2_match(namelen, name, de)) goto found; de = ext2_next_entry(de); } - ext2_put_page(page, page_addr); + ext2_put_page(page, kaddr); if (++n >= npages) n = 0; @@ -443,7 +443,7 @@ int ext2_inode_by_name(struct inode *dir, const struct qstr *child, ino_t *ino) return PTR_ERR(de); *ino = le32_to_cpu(de->inode); - ext2_put_page(page, page_addr); + ext2_put_page(page, de); return 0; } @@ -499,7 +499,6 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) unsigned reclen = EXT2_DIR_REC_LEN(namelen); unsigned short rec_len, name_len; struct page *page = NULL; - void *page_addr = NULL; ext2_dirent * de; unsigned long npages = dir_pages(dir); unsigned long n; @@ -515,11 +514,10 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) char *kaddr; char *dir_end; - page_addr = ext2_get_page(dir, n, 0, &page); - if (IS_ERR(page_addr)) - return PTR_ERR(page_addr); + kaddr = ext2_get_page(dir, n, 0, &page); + if (IS_ERR(kaddr)) + return PTR_ERR(kaddr); lock_page(page); - kaddr = page_addr; dir_end = kaddr + ext2_last_byte(dir, n); de = (ext2_dirent *)kaddr; kaddr += PAGE_SIZE - reclen; @@ -550,7 +548,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) de = (ext2_dirent *) ((char *) de + rec_len); } unlock_page(page); - ext2_put_page(page, page_addr); + ext2_put_page(page, kaddr); } BUG(); return -EINVAL; @@ -577,7 +575,7 @@ got_it: err = ext2_handle_dirsync(dir); /* OFFSET_CACHE */ out_put: - ext2_put_page(page, page_addr); + ext2_put_page(page, de); return err; out_unlock: unlock_page(page); @@ -675,19 +673,17 @@ fail: */ int ext2_empty_dir (struct inode * inode) { - void *page_addr = NULL; - struct page *page = NULL; + struct page *page; + char *kaddr; unsigned long i, npages = dir_pages(inode); for (i = 0; i < npages; i++) { - char *kaddr; - ext2_dirent * de; - page_addr = ext2_get_page(inode, i, 0, &page); + ext2_dirent *de; - if (IS_ERR(page_addr)) + kaddr = ext2_get_page(inode, i, 0, &page); + if (IS_ERR(kaddr)) return 0; - kaddr = page_addr; de = (ext2_dirent *)kaddr; kaddr += ext2_last_byte(inode, i) - EXT2_DIR_REC_LEN(1); @@ -713,12 +709,12 @@ int ext2_empty_dir (struct inode * inode) } de = ext2_next_entry(de); } - ext2_put_page(page, page_addr); + ext2_put_page(page, kaddr); } return 1; not_empty: - ext2_put_page(page, page_addr); + ext2_put_page(page, kaddr); return 0; } diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index dafdd2d..50105d5 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -288,7 +288,7 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry) } err = ext2_delete_entry (de, page, page_addr); - ext2_put_page(page, page_addr); + ext2_put_page(page, de); if (err) goto out; @@ -370,7 +370,7 @@ static int ext2_rename (struct mnt_idmap * idmap, } err = ext2_set_link(new_dir, new_de, new_page, page_addr, old_inode, true); - ext2_put_page(new_page, page_addr); + ext2_put_page(new_page, new_de); if (err) goto out_dir; new_inode->i_ctime = current_time(new_inode); @@ -402,9 +402,9 @@ static int ext2_rename (struct mnt_idmap * idmap, } out_dir: if (dir_de) - ext2_put_page(dir_page, dir_page_addr); + ext2_put_page(dir_page, dir_de); out_old: - ext2_put_page(old_page, old_page_addr); + ext2_put_page(old_page, old_de); return err; } -- 2.7.4