Date: Sat, 20 Jul 2024 09:08:48 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 280383] Removing the last link to an open file prevents remounting read-only--suggest document and/or code change Message-ID: <bug-280383-227@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D280383 Bug ID: 280383 Summary: Removing the last link to an open file prevents remounting read-only--suggest document and/or code change Product: Base System Version: Unspecified Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: billblake2018@gmail.com Long ago, an issue was resolved in which removing the last link to an open = file followed by downgrading the file system to read-only could have unfortunate consequences, by forbidding a downgrade when any open file had no links. (https://svnweb.freebsd.org/base?view=3Drevision&revision=3D89384) This was reasonable because closing the file would require deallocating the file's i= node and disk blocks, which could no longer be done if the file system was downgraded. I got bit by this because, if this is documented at all, it is not document= ed in any obvious place. E.g., the mount(8) man page gives no clue that you c= an't do this; it only says, in the documentation for the -u option, that it will fail if any file is opened for write. mount(2) is similarly silent. A minimal improvement would be a document change to mount(8) so that the -u option indicates that one may not downgrade a file system if there are any = open files with no links. In addition, mount(2) should say that one can get EBU= SY from such an attempt. But I thought about this for awhile and realized that this is a problem wit= h a relatively simple solution. It basically needs a directory with a specific name in a specific place and a single flag bit in an on-disk inode and in t= he corresponding vnode. Let's call this directory .lastlink and put it in the root of a mounted file system. Then one can make the following changes: 1) When the last link to an open file is to be removed: Choose a file name, say, "#<inum>" (as with lost+found). If the .lastlink directory exists and .lastlink/#<inum> does not exist, link .lastlink/#<inum> to the open file a= nd flag the inode and its vnode before the (no longer) last link is removed. 2) When an open file with a flagged vnode is closed, unlink .lastlink/#<inu= m> if the file system is read/write. 3) Leave the current downgrade code alone, except possibly adding a comment. 4) When a file system is (re)mounted r/w, scan .lastlink, if it exists, for links to any flagged inodes and unlink those files if they are not open. 5) Make fsck know about .lastlink so that it can remove any flagged inodes. With these changes, if no directory .lastlink exists, the current behavior = is preserved. But if that directory exists and nobody creates problematic file names in it, open, unlinked files never exist and so can't prevent downgrad= ing the file system. If a downgrade does happen, the deletion that should have happened when the file was closed does actually happen, but only when the f= ile system is next mounted r/w. If something other than the above code creates= a #<number> file in .lastlink, the worst that'll happen is that the system reverts to prior behavior if an inode whose <inum> matches <number> has its last link removed while it is open. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-280383-227>