Skip site navigation (1)Skip section navigation (2)
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>