git: bcbb927b97cb - stable/13 - Have fsdb(8) only mark a filesystem dirty when it is modified.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 05 Aug 2023 06:19:22 UTC
The branch stable/13 has been updated by mckusick:
URL: https://cgit.FreeBSD.org/src/commit/?id=bcbb927b97cb27cf6309c540ea7100fdbdccf048
commit bcbb927b97cb27cf6309c540ea7100fdbdccf048
Author: Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2023-07-26 02:27:59 +0000
Commit: Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2023-08-05 06:17:30 +0000
Have fsdb(8) only mark a filesystem dirty when it is modified.
Sponsored-by: The FreeBSD Foundation
(cherry picked from commit d51bdf327d9381807cbeffead1ed3cc466bdb87b)
---
sbin/fsdb/fsdb.c | 109 +++++++++++++++++++++++++++----------------------------
sbin/fsdb/fsdb.h | 3 +-
2 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/sbin/fsdb/fsdb.c b/sbin/fsdb/fsdb.c
index f907ea160a16..c80d4b65a830 100644
--- a/sbin/fsdb/fsdb.c
+++ b/sbin/fsdb/fsdb.c
@@ -63,6 +63,23 @@ static int find_blks64(uint64_t *buf, int size, uint64_t *blknum);
static int find_indirblks32(uint32_t blk, int ind_level, uint32_t *blknum);
static int find_indirblks64(uint64_t blk, int ind_level, uint64_t *blknum);
+/*
+ * Track modifications to the filesystem. Two types of changes are tracked.
+ * The first type of changes are those that are not critical to the integrity
+ * of the filesystem such as owner, group, time stamps, access mode, and
+ * generation number. The second type of changes are those that do affect
+ * the integrity of the filesystem including zeroing inodes, changing block
+ * pointers, directory entries, link counts, file lengths, file types and
+ * file flags.
+ *
+ * When quitting having made no changes or only changes to data that is not
+ * critical to filesystem integrity, the clean state of the filesystem is
+ * left unchanged. But if filesystem critical data are changed then fsdb
+ * will set the unclean flag which will require a full fsck to be run
+ * before the filesystem can be mounted.
+ */
+static int fsnoncritmodified; /* filesystem non-critical modifications */
+static int fscritmodified; /* filesystem integrity critical mods */
struct inode curip;
union dinode *curinode;
ino_t curinum, ocurrent;
@@ -119,9 +136,13 @@ main(int argc, char *argv[])
nflag? "Examining": "Editing", fsys, sblock.fs_fsmnt);
rval = cmdloop();
if (!nflag) {
- sblock.fs_clean = 0; /* mark it dirty */
- sbdirty();
- ckfini(0);
+ if (fscritmodified != 0) {
+ sblock.fs_clean = 0; /* mark it dirty */
+ sbdirty();
+ }
+ ckfini(fscritmodified ? 0 : sblock.fs_clean);
+ if (fscritmodified == 0)
+ exit(0);
printf("*** FILE SYSTEM MARKED DIRTY\n");
printf("*** BE SURE TO RUN FSCK TO CLEAN UP ANY DAMAGE\n");
printf("*** IF IT IS MOUNTED, RE-MOUNT WITH -u -o reload\n");
@@ -167,36 +188,35 @@ struct cmdtable cmds[] = {
{ "help", "Print out help", 1, 1, FL_RO, helpfn },
{ "?", "Print out help", 1, 1, FL_RO, helpfn },
{ "inode", "Set active inode to INUM", 2, 2, FL_RO, focus },
- { "clri", "Clear inode INUM", 2, 2, FL_WR, zapi },
+ { "clri", "Clear inode INUM", 2, 2, FL_CWR, zapi },
{ "lookup", "Set active inode by looking up NAME", 2, 2, FL_RO | FL_ST, focusname },
{ "cd", "Set active inode by looking up NAME", 2, 2, FL_RO | FL_ST, focusname },
{ "back", "Go to previous active inode", 1, 1, FL_RO, back },
{ "active", "Print active inode", 1, 1, FL_RO, active },
{ "print", "Print active inode", 1, 1, FL_RO, active },
{ "blocks", "Print block numbers of active inode", 1, 1, FL_RO, blocks },
- { "uplink", "Increment link count", 1, 1, FL_WR, uplink },
- { "downlink", "Decrement link count", 1, 1, FL_WR, downlink },
- { "linkcount", "Set link count to COUNT", 2, 2, FL_WR, linkcount },
+ { "uplink", "Increment link count", 1, 1, FL_CWR, uplink },
+ { "downlink", "Decrement link count", 1, 1, FL_CWR, downlink },
+ { "linkcount", "Set link count to COUNT", 2, 2, FL_CWR, linkcount },
{ "findblk", "Find inode owning disk block(s)", 2, 33, FL_RO, findblk},
{ "ls", "List current inode as directory", 1, 1, FL_RO, ls },
- { "rm", "Remove NAME from current inode directory", 2, 2, FL_WR | FL_ST, rm },
- { "del", "Remove NAME from current inode directory", 2, 2, FL_WR | FL_ST, rm },
- { "ln", "Hardlink INO into current inode directory as NAME", 3, 3, FL_WR | FL_ST, ln },
- { "chinum", "Change dir entry number INDEX to INUM", 3, 3, FL_WR, chinum },
+ { "rm", "Remove NAME from current inode directory", 2, 2, FL_CWR | FL_ST, rm },
+ { "del", "Remove NAME from current inode directory", 2, 2, FL_CWR | FL_ST, rm },
+ { "ln", "Hardlink INO into current inode directory as NAME", 3, 3, FL_CWR | FL_ST, ln },
+ { "chinum", "Change dir entry number INDEX to INUM", 3, 3, FL_CWR, chinum },
{ "chname", "Change dir entry number INDEX to NAME", 3, 3, FL_WR | FL_ST, chname },
- { "chtype", "Change type of current inode to TYPE", 2, 2, FL_WR, newtype },
+ { "chtype", "Change type of current inode to TYPE", 2, 2, FL_CWR, newtype },
{ "chmod", "Change mode of current inode to MODE", 2, 2, FL_WR, chmode },
- { "chlen", "Change length of current inode to LENGTH", 2, 2, FL_WR, chlen },
{ "chown", "Change owner of current inode to OWNER", 2, 2, FL_WR, chowner },
{ "chgrp", "Change group of current inode to GROUP", 2, 2, FL_WR, chgroup },
- { "chflags", "Change flags of current inode to FLAGS", 2, 2, FL_WR, chaflags },
+ { "chflags", "Change flags of current inode to FLAGS", 2, 2, FL_CWR, chaflags },
{ "chgen", "Change generation number of current inode to GEN", 2, 2, FL_WR, chgen },
- { "chsize", "Change size of current inode to SIZE", 2, 2, FL_WR, chsize },
+ { "chsize", "Change size of current inode to SIZE", 2, 2, FL_CWR, chsize },
{ "btime", "Change btime of current inode to BTIME", 2, 2, FL_WR, chbtime },
{ "mtime", "Change mtime of current inode to MTIME", 2, 2, FL_WR, chmtime },
{ "ctime", "Change ctime of current inode to CTIME", 2, 2, FL_WR, chctime },
{ "atime", "Change atime of current inode to ATIME", 2, 2, FL_WR, chatime },
- { "chdb", "Change db pointer N of current inode to BLKNO", 3, 3, FL_WR, chdb },
+ { "chdb", "Change db pointer N of current inode to BLKNO", 3, 3, FL_CWR, chdb },
{ "quit", "Exit", 1, 1, FL_RO, quit },
{ "q", "Exit", 1, 1, FL_RO, quit },
{ "exit", "Exit", 1, 1, FL_RO, quit },
@@ -280,7 +300,7 @@ cmdloop(void)
known = 0;
for (cmdp = cmds; cmdp->cmd; cmdp++) {
if (!strcmp(cmdp->cmd, cmd_argv[0])) {
- if ((cmdp->flags & FL_WR) == FL_WR && nflag)
+ if ((cmdp->flags & (FL_CWR | FL_WR)) != 0 && nflag)
warnx("`%s' requires write access", cmd_argv[0]),
rval = 1;
else if (cmd_argc >= cmdp->minargc &&
@@ -294,6 +314,12 @@ cmdloop(void)
} else
rval = argcount(cmdp, cmd_argc, cmd_argv);
known = 1;
+ if (rval == 0) {
+ if ((cmdp->flags & FL_WR) != 0)
+ fsnoncritmodified = 1;
+ if ((cmdp->flags & FL_CWR) != 0)
+ fscritmodified = 1;
+ }
break;
}
}
@@ -308,7 +334,7 @@ cmdloop(void)
return 0;
}
if (rval)
- warnx("rval was %d", rval);
+ warnx("command failed, return value was %d", rval);
}
el_end(elptr);
history_end(hist);
@@ -930,30 +956,8 @@ CMDFUNCSTART(newtype)
return 0;
}
-CMDFUNCSTART(chlen)
-{
- int rval = 1;
- long len;
- char *cp;
-
- if (!checkactive())
- return 1;
-
- len = strtol(argv[1], &cp, 0);
- if (cp == argv[1] || *cp != '\0' || len < 0) {
- warnx("bad length `%s'", argv[1]);
- return 1;
- }
-
- DIP_SET(curinode, di_size, len);
- inodirty(&curip);
- printactive(0);
- return rval;
-}
-
CMDFUNCSTART(chmode)
{
- int rval = 1;
long modebits;
char *cp;
@@ -970,12 +974,11 @@ CMDFUNCSTART(chmode)
DIP_SET(curinode, di_mode, DIP(curinode, di_mode) | modebits);
inodirty(&curip);
printactive(0);
- return rval;
+ return 0;
}
CMDFUNCSTART(chaflags)
{
- int rval = 1;
u_long flags;
char *cp;
@@ -995,12 +998,11 @@ CMDFUNCSTART(chaflags)
DIP_SET(curinode, di_flags, flags);
inodirty(&curip);
printactive(0);
- return rval;
+ return 0;
}
CMDFUNCSTART(chgen)
{
- int rval = 1;
long gen;
char *cp;
@@ -1013,19 +1015,19 @@ CMDFUNCSTART(chgen)
return 1;
}
- if (gen > INT_MAX || gen < INT_MIN) {
- warnx("gen set beyond 32-bit range of field (%lx)\n", gen);
+ if (gen > UINT_MAX) {
+ warnx("gen set beyond 32-bit range of field (0x%lx), max is 0x%x\n",
+ gen, UINT_MAX);
return(1);
}
DIP_SET(curinode, di_gen, gen);
inodirty(&curip);
printactive(0);
- return rval;
+ return 0;
}
CMDFUNCSTART(chsize)
{
- int rval = 1;
off_t size;
char *cp;
@@ -1045,7 +1047,7 @@ CMDFUNCSTART(chsize)
DIP_SET(curinode, di_size, size);
inodirty(&curip);
printactive(0);
- return rval;
+ return 0;
}
CMDFUNC(chdb)
@@ -1080,7 +1082,6 @@ CMDFUNC(chdb)
CMDFUNCSTART(linkcount)
{
- int rval = 1;
int lcnt;
char *cp;
@@ -1100,12 +1101,11 @@ CMDFUNCSTART(linkcount)
DIP_SET(curinode, di_nlink, lcnt);
inodirty(&curip);
printactive(0);
- return rval;
+ return 0;
}
CMDFUNCSTART(chowner)
{
- int rval = 1;
unsigned long uid;
char *cp;
struct passwd *pwd;
@@ -1127,12 +1127,11 @@ CMDFUNCSTART(chowner)
DIP_SET(curinode, di_uid, uid);
inodirty(&curip);
printactive(0);
- return rval;
+ return 0;
}
CMDFUNCSTART(chgroup)
{
- int rval = 1;
unsigned long gid;
char *cp;
struct group *grp;
@@ -1153,7 +1152,7 @@ CMDFUNCSTART(chgroup)
DIP_SET(curinode, di_gid, gid);
inodirty(&curip);
printactive(0);
- return rval;
+ return 0;
}
int
diff --git a/sbin/fsdb/fsdb.h b/sbin/fsdb/fsdb.h
index fee35886f675..d13caa3c0e93 100644
--- a/sbin/fsdb/fsdb.h
+++ b/sbin/fsdb/fsdb.h
@@ -49,7 +49,8 @@ struct cmdtable {
unsigned int flags;
#define FL_RO 0x0000 /* for symmetry */
#define FL_WR 0x0001 /* wants to write */
-#define FL_ST 0x0002 /* resplit final string if argc > maxargc */
+#define FL_CWR 0x0002 /* wants to write critical data */
+#define FL_ST 0x0003 /* resplit final string if argc > maxargc */
int (*handler)(int argc, char *argv[]);
};
extern struct inode curip;