From 0a5dc78ba4dce69bdb320e51a79def9d2e0102d4 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sun, 25 May 2025 00:39:13 -0400 Subject: [PATCH] Add a support for new flag (EXT2FS_LINK_EXPAND) for ext2fs_link() Many calls to ext2fs_link() checks for EXT2_ET_DIR_NO_SPACE and if so, calls ext2fs_expand_dir() and then retries the ext2fs_link(). We can simplify a lot of code by adding support for a flag which does the retry into the ext2fs_link() function. Signed-off-by: Theodore Ts'o --- e2fsck/pass3.c | 11 ++-------- lib/ext2fs/ext2fs.h | 1 + lib/ext2fs/link.c | 11 ++++++++-- misc/create_inode.c | 35 ++++------------------------- misc/create_inode_libarchive.c | 7 ------ misc/fuse2fs.c | 50 +++++------------------------------------- misc/mk_hugefiles.c | 10 ++------- 7 files changed, 24 insertions(+), 101 deletions(-) diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index ba79416..56798b1 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -570,16 +570,9 @@ skip_new_block: /* * Finally, create the directory link */ - pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR); - if (pctx.errcode == EXT2_ET_DIR_NO_SPACE) { - pctx.errcode = ext2fs_expand_dir(fs, EXT2_ROOT_INO); - if (pctx.errcode) - goto link_error; - pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, - EXT2_FT_DIR); - } + pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, + EXT2_FT_DIR | EXT2FS_LINK_EXPAND); if (pctx.errcode) { -link_error: pctx.str = "ext2fs_link"; fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); return 0; diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 2661e10..fd2901b 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -807,6 +807,7 @@ struct ext2_xattr_handle; */ #define EXT2FS_LINK_FT_MASK 0x0007 #define EXT2FS_LINK_APPEND 0x0010 +#define EXT2FS_LINK_EXPAND 0x0020 /* * function prototypes diff --git a/lib/ext2fs/link.c b/lib/ext2fs/link.c index 7ea00f8..0d9b183 100644 --- a/lib/ext2fs/link.c +++ b/lib/ext2fs/link.c @@ -618,6 +618,7 @@ errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name, if (!(fs->flags & EXT2_FLAG_RW)) return EXT2_ET_RO_FILSYS; +retry: if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0) return retval; @@ -667,7 +668,13 @@ errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name, if (ls.err) return ls.err; - if (!ls.done) - return EXT2_ET_DIR_NO_SPACE; + if (!ls.done) { + if (!(flags & EXT2FS_LINK_EXPAND)) + return EXT2_ET_DIR_NO_SPACE; + retval = ext2fs_expand_dir(fs, dir); + if (retval) + return retval; + goto retry; + } return 0; } diff --git a/misc/create_inode.c b/misc/create_inode.c index 9204d87..bdd1f75 100644 --- a/misc/create_inode.c +++ b/misc/create_inode.c @@ -47,7 +47,7 @@ /* 64KiB is the minimum blksize to best minimize system call overhead. */ #define COPY_FILE_BUFLEN 65536 -int link_append_flag = 0; +int link_append_flag = EXT2FS_LINK_EXPAND; static int ext2_file_type(unsigned int mode) { @@ -90,17 +90,6 @@ errcode_t add_link(ext2_filsys fs, ext2_ino_t parent_ino, retval = ext2fs_link(fs, parent_ino, name, ino, ext2_file_type(inode.i_mode) | link_append_flag); - if (retval == EXT2_ET_DIR_NO_SPACE) { - retval = ext2fs_expand_dir(fs, parent_ino); - if (retval) { - com_err(__func__, retval, - _("while expanding directory")); - return retval; - } - retval = ext2fs_link(fs, parent_ino, name, ino, - (ext2_file_type(inode.i_mode) | - link_append_flag)); - } if (retval) { com_err(__func__, retval, _("while linking \"%s\""), name); return retval; @@ -304,16 +293,6 @@ errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name, printf("Allocated inode: %u\n", ino); #endif retval = ext2fs_link(fs, cwd, name, ino, filetype | link_append_flag); - if (retval == EXT2_ET_DIR_NO_SPACE) { - retval = ext2fs_expand_dir(fs, cwd); - if (retval) { - com_err(__func__, retval, - _("while expanding directory")); - return retval; - } - retval = ext2fs_link(fs, cwd, name, ino, - filetype | link_append_flag); - } if (retval) { com_err(name, retval, _("while creating inode \"%s\""), name); return retval; @@ -833,13 +812,6 @@ errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src, #endif retval = ext2fs_link(fs, parent_ino, dest, newfile, EXT2_FT_REG_FILE | link_append_flag); - if (retval == EXT2_ET_DIR_NO_SPACE) { - retval = ext2fs_expand_dir(fs, parent_ino); - if (retval) - goto out; - retval = ext2fs_link(fs, parent_ino, dest, newfile, - EXT2_FT_REG_FILE | link_append_flag); - } if (retval) goto out; if (ext2fs_test_inode_bitmap2(fs->inode_map, newfile)) @@ -1235,7 +1207,8 @@ errcode_t populate_fs3(ext2_filsys fs, ext2_ino_t parent_ino, file_info.path_max_len = 255; file_info.path = calloc(file_info.path_max_len, 1); - link_append_flag = (flags & POPULATE_FS_LINK_APPEND) ? + link_append_flag = EXT2FS_LINK_EXPAND; + link_append_flag |= (flags & POPULATE_FS_LINK_APPEND) ? EXT2FS_LINK_APPEND : 0; /* interpret input as tarball either if it's "-" (stdin) or if it's @@ -1276,7 +1249,7 @@ errcode_t populate_fs3(ext2_filsys fs, ext2_ino_t parent_ino, out: free(file_info.path); free(hdlinks.hdl); - link_append_flag = 0; + link_append_flag = EXT2FS_LINK_EXPAND; return retval; } diff --git a/misc/create_inode_libarchive.c b/misc/create_inode_libarchive.c index d787c5d..118bf4f 100644 --- a/misc/create_inode_libarchive.c +++ b/misc/create_inode_libarchive.c @@ -394,13 +394,6 @@ static errcode_t do_write_internal_tar(ext2_filsys fs, ext2_ino_t cwd, #endif retval = ext2fs_link(fs, cwd, dest, newfile, EXT2_FT_REG_FILE | link_append_flag); - if (retval == EXT2_ET_DIR_NO_SPACE) { - retval = ext2fs_expand_dir(fs, cwd); - if (retval) - goto out; - retval = ext2fs_link(fs, cwd, dest, newfile, - EXT2_FT_REG_FILE | link_append_flag); - } if (retval) goto out; if (ext2fs_test_inode_bitmap2(fs->inode_map, newfile)) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index 15a3730..d2793c0 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -1098,17 +1098,8 @@ static int op_mknod(const char *path, mode_t mode, dev_t dev) dbg_printf(ff, "%s: create ino=%d/name=%s in dir=%d\n", __func__, child, node_name, parent); - err = ext2fs_link(fs, parent, node_name, child, filetype); - if (err == EXT2_ET_DIR_NO_SPACE) { - err = ext2fs_expand_dir(fs, parent); - if (err) { - ret = translate_error(fs, parent, err); - goto out2; - } - - err = ext2fs_link(fs, parent, node_name, child, - filetype); - } + err = ext2fs_link(fs, parent, node_name, child, + filetype | EXT2FS_LINK_EXPAND); if (err) { ret = translate_error(fs, parent, err); goto out2; @@ -1879,17 +1870,7 @@ static int op_rename(const char *from, const char *to dbg_printf(ff, "%s: linking ino=%d/path=%s to dir=%d\n", __func__, from_ino, cp + 1, to_dir_ino); err = ext2fs_link(fs, to_dir_ino, cp + 1, from_ino, - ext2_file_type(inode.i_mode)); - if (err == EXT2_ET_DIR_NO_SPACE) { - err = ext2fs_expand_dir(fs, to_dir_ino); - if (err) { - ret = translate_error(fs, to_dir_ino, err); - goto out2; - } - - err = ext2fs_link(fs, to_dir_ino, cp + 1, from_ino, - ext2_file_type(inode.i_mode)); - } + ext2_file_type(inode.i_mode) | EXT2FS_LINK_EXPAND); if (err) { ret = translate_error(fs, to_dir_ino, err); goto out2; @@ -2046,17 +2027,7 @@ static int op_link(const char *src, const char *dest) dbg_printf(ff, "%s: linking ino=%d/name=%s to dir=%d\n", __func__, ino, node_name, parent); err = ext2fs_link(fs, parent, node_name, ino, - ext2_file_type(inode.i_mode)); - if (err == EXT2_ET_DIR_NO_SPACE) { - err = ext2fs_expand_dir(fs, parent); - if (err) { - ret = translate_error(fs, parent, err); - goto out2; - } - - err = ext2fs_link(fs, parent, node_name, ino, - ext2_file_type(inode.i_mode)); - } + ext2_file_type(inode.i_mode) | EXT2FS_LINK_EXPAND); if (err) { ret = translate_error(fs, parent, err); goto out2; @@ -3295,17 +3266,8 @@ static int op_create(const char *path, mode_t mode, struct fuse_file_info *fp) dbg_printf(ff, "%s: creating ino=%d/name=%s in dir=%d\n", __func__, child, node_name, parent); - err = ext2fs_link(fs, parent, node_name, child, filetype); - if (err == EXT2_ET_DIR_NO_SPACE) { - err = ext2fs_expand_dir(fs, parent); - if (err) { - ret = translate_error(fs, parent, err); - goto out2; - } - - err = ext2fs_link(fs, parent, node_name, child, - filetype); - } + err = ext2fs_link(fs, parent, node_name, child, + filetype | EXT2FS_LINK_EXPAND); if (err) { ret = translate_error(fs, parent, err); goto out2; diff --git a/misc/mk_hugefiles.c b/misc/mk_hugefiles.c index f2957d8..04bda20 100644 --- a/misc/mk_hugefiles.c +++ b/misc/mk_hugefiles.c @@ -270,14 +270,8 @@ static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num, sprintf(fn_numbuf, "%lu", idx); retry: - retval = ext2fs_link(fs, dir, fn_buf, *ino, EXT2_FT_REG_FILE); - if (retval == EXT2_ET_DIR_NO_SPACE) { - retval = ext2fs_expand_dir(fs, dir); - if (retval) - goto errout; - goto retry; - } - + retval = ext2fs_link(fs, dir, fn_buf, *ino, + EXT2_FT_REG_FILE | EXT2FS_LINK_EXPAND); if (retval) goto errout; -- 1.8.3.1