Applied, thanks! Milos Nikic, le mar. 06 oct. 2026 20:56:39 -0700, a ecrit: > Hello, > > Seems like this somehow didn't make it all the way to the mailing list so i am > reposting it hoping it will this time! > ... and re-attaching the patch explicitly. > > Its a cleanup, one liner that squashes a reproducible freeze under specific > conditions (disk full, and create node fails) > > Thanks, > Milos > > > On Mon, Oct 5, 2026 at 9:16 PM Milos Nikic <[1][email protected]> wrote: > > diskfs_alloc_node returns the new node locked and with a hard > reference. When diskfs_create_node then fails before entering the node > in the directory, for instance because diskfs_init_dir finds no free > block for a new directory, the error path cleared the mode and link > count and returned without releasing the node! The node stayed locked > for good, and its inode stayed allocated on disk until e2fsck freed it. > > The next diskfs_node_iterate then waits for that lock forever. Without > a journal this stops the periodic sync until reboot silently. > With a journal the periodic sync holds a handle while it waits, so the > commit > cannot drain and every new RPC blocks behind it. > Running mkdir on a full filesystem is enough to trigger it. > > Release the node with diskfs_nput. As it is unlinked, diskfs_drop_node > truncates it and frees its inode. Keep the file type in st_mode rather > than clearing it, since diskfs_drop_node passes the mode to > diskfs_free_node, and ext2fs uses it to undo the used directories count > that ext2_alloc_inode took for a directory. > --- > libdiskfs/node-create.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c > index 28d2c6e34..56d548f75 100644 > --- a/libdiskfs/node-create.c > +++ b/libdiskfs/node-create.c > @@ -137,11 +137,16 @@ diskfs_create_node (struct node *dir, > if (err) > { > change_err: > - np->dn_stat.st_mode = 0; > + /* Hand the inode back: dropping the last reference to an unlinked > + node truncates and frees it. Keep the file type so that > + diskfs_free_node undoes what diskfs_alloc_node accounted for it, > + such as the count of used directories. */ > + np->dn_stat.st_mode = mode & S_IFMT; > np->dn_stat.st_nlink = 0; > if (name) > diskfs_drop_dirstat (dir, ds); > *newnode = NULL; > + diskfs_nput (np); > return err; > } > > -- > 2.56.0 > > > > References: > > [1] mailto:[email protected]
> From 8184b0a8dc24cf60aef5ff45d469ba297f6a5c2d Mon Sep 17 00:00:00 2001 > From: Milos Nikic <[email protected]> > Date: Mon, 5 Oct 2026 20:51:51 -0700 > Subject: [PATCH] libdiskfs: Release the new node when diskfs_create_node fails > > diskfs_alloc_node returns the new node locked and with a hard > reference. When diskfs_create_node then fails before entering the node > in the directory, for instance because diskfs_init_dir finds no free > block for a new directory, the error path cleared the mode and link > count and returned without releasing the node! The node stayed locked > for good, and its inode stayed allocated on disk until e2fsck freed it. > > The next diskfs_node_iterate then waits for that lock forever. Without > a journal this stops the periodic sync until reboot silently. > With a journal the periodic sync holds a handle while it waits, so the commit > cannot drain and every new RPC blocks behind it. > Running mkdir on a full filesystem is enough to trigger it. > > Release the node with diskfs_nput. As it is unlinked, diskfs_drop_node > truncates it and frees its inode. Keep the file type in st_mode rather > than clearing it, since diskfs_drop_node passes the mode to > diskfs_free_node, and ext2fs uses it to undo the used directories count > that ext2_alloc_inode took for a directory. > --- > libdiskfs/node-create.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c > index 28d2c6e34..56d548f75 100644 > --- a/libdiskfs/node-create.c > +++ b/libdiskfs/node-create.c > @@ -137,11 +137,16 @@ diskfs_create_node (struct node *dir, > if (err) > { > change_err: > - np->dn_stat.st_mode = 0; > + /* Hand the inode back: dropping the last reference to an unlinked > + node truncates and frees it. Keep the file type so that > + diskfs_free_node undoes what diskfs_alloc_node accounted for it, > + such as the count of used directories. */ > + np->dn_stat.st_mode = mode & S_IFMT; > np->dn_stat.st_nlink = 0; > if (name) > diskfs_drop_dirstat (dir, ds); > *newnode = NULL; > + diskfs_nput (np); > return err; > } > > -- > 2.56.0 > -- Samuel <y> le y est un animal discret se logeant facilement dans un terminal *** c has changed the topic on channel #ens-mim to ne pas jeter de cacahuetes aux ys, svp -+- #ens-mim - n'oubliez pas le guide -+-
