Whamcloud - gitweb
Add a support for new flag (EXT2FS_LINK_EXPAND) for ext2fs_link()
authorTheodore Ts'o <tytso@mit.edu>
Sun, 25 May 2025 04:39:13 +0000 (00:39 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 25 May 2025 05:28:01 +0000 (01:28 -0400)
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 <tytso@mit.edu>
e2fsck/pass3.c
lib/ext2fs/ext2fs.h
lib/ext2fs/link.c
misc/create_inode.c
misc/create_inode_libarchive.c
misc/fuse2fs.c
misc/mk_hugefiles.c

index ba79416..56798b1 100644 (file)
@@ -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;
index 2661e10..fd2901b 100644 (file)
@@ -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
index 7ea00f8..0d9b183 100644 (file)
@@ -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;
 }
index 9204d87..bdd1f75 100644 (file)
@@ -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;
 }
 
index d787c5d..118bf4f 100644 (file)
@@ -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))
index 15a3730..d2793c0 100644 (file)
@@ -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;
index f2957d8..04bda20 100644 (file)
@@ -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;