diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libufs/Makefile | 2 | ||||
| -rw-r--r-- | lib/libufs/libufs.h | 4 | ||||
| -rw-r--r-- | lib/libufs/sblock.c | 54 | ||||
| -rw-r--r-- | lib/libufs/sbread.3 | 69 |
4 files changed, 108 insertions, 21 deletions
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile index a767546f457f..623d5ae541a0 100644 --- a/lib/libufs/Makefile +++ b/lib/libufs/Makefile @@ -20,6 +20,8 @@ MLINKS+= cgread.3 cgput.3 MLINKS+= getinode.3 putinode.3 MLINKS+= sbread.3 sbwrite.3 MLINKS+= sbread.3 sbget.3 +MLINKS+= sbread.3 sbsearch.3 +MLINKS+= sbread.3 sbfind.3 MLINKS+= sbread.3 sbput.3 MLINKS+= ufs_disk_close.3 ufs_disk_fillout.3 MLINKS+= ufs_disk_close.3 ufs_disk_fillout_blank.3 diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h index cb8774454b38..5dbf9c2a5c28 100644 --- a/lib/libufs/libufs.h +++ b/lib/libufs/libufs.h @@ -111,6 +111,8 @@ void ffs_clusteracct(struct fs *, struct cg *, ufs1_daddr_t, int); void ffs_fragacct(struct fs *, int, int32_t [], int); int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t); int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t); +int ffs_sbsearch(void *, struct fs **, int, char *, + int (*)(void *, off_t, void **, int)); void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t); int ffs_sbget(void *, struct fs **, off_t, int, char *, int (*)(void *, off_t, void **, int)); @@ -149,9 +151,11 @@ int putinode(struct uufsd *); * sblock.c */ int sbread(struct uufsd *); +int sbfind(struct uufsd *, int); int sbwrite(struct uufsd *, int); /* low level superblock read/write functions */ int sbget(int, struct fs **, off_t, int); +int sbsearch(int, struct fs **, int); int sbput(int, struct fs *, int); /* diff --git a/lib/libufs/sblock.c b/lib/libufs/sblock.c index 5708d50aa4f9..4dfa0e79a711 100644 --- a/lib/libufs/sblock.c +++ b/lib/libufs/sblock.c @@ -73,6 +73,30 @@ sbread(struct uufsd *disk) return (handle_disk_read(disk, fs, error)); } +/* + * Make an extensive search to find a superblock. If the superblock + * in the standard place cannot be used, try looking for one of the + * backup superblocks. + * + * The flags parameter is made up of the following or'ed together options: + * + * UFS_NOMSG indicates that superblock inconsistency error messages + * should not be printed. + * + * UFS_NOCSUM causes only the superblock itself to be returned, but does + * not read in any auxillary data structures like the cylinder group + * summary information. + */ +int +sbfind(struct uufsd *disk, int flags) +{ + struct fs *fs; + int error; + + error = sbsearch(disk->d_fd, &fs, flags); + return (handle_disk_read(disk, fs, error)); +} + static int handle_disk_read(struct uufsd *disk, struct fs *fs, int error) { @@ -174,8 +198,27 @@ static int use_pwrite(void *devfd, off_t loc, void *buf, int size); int sbget(int devfd, struct fs **fsp, off_t sblockloc, int flags) { + int error; + + error = ffs_sbget(&devfd, fsp, sblockloc, flags, "user", use_pread); + fflush(NULL); /* flush any messages */ + return (error); +} + +/* + * Make an extensive search of the devfd device to find a superblock. + * If the superblock in the standard place cannot be used, try looking + * for one of the backup superblocks. If found, memory is allocated and + * returned in fsp. + */ +int +sbsearch(int devfd, struct fs **fsp, int flags) +{ + int error; - return (ffs_sbget(&devfd, fsp, sblockloc, flags, "user", use_pread)); + error = ffs_sbsearch(&devfd, fsp, flags, "user", use_pread); + fflush(NULL); /* flush any messages */ + return (error); } /* @@ -209,11 +252,10 @@ sbput(int devfd, struct fs *fs, int numaltwrite) off_t savedactualloc; int i, error; - if ((error = ffs_sbput(&devfd, fs, fs->fs_sblockactualloc, - use_pwrite)) != 0) + error = ffs_sbput(&devfd, fs, fs->fs_sblockactualloc, use_pwrite); + fflush(NULL); /* flush any messages */ + if (error != 0 || numaltwrite == 0) return (error); - if (numaltwrite == 0) - return (0); savedactualloc = fs->fs_sblockactualloc; if (fs->fs_si != NULL) { savedcsp = fs->fs_csp; @@ -223,6 +265,7 @@ sbput(int devfd, struct fs *fs, int numaltwrite) fs->fs_sblockactualloc = dbtob(fsbtodb(fs, cgsblock(fs, i))); if ((error = ffs_sbput(&devfd, fs, fs->fs_sblockactualloc, use_pwrite)) != 0) { + fflush(NULL); /* flush any messages */ fs->fs_sblockactualloc = savedactualloc; fs->fs_csp = savedcsp; return (error); @@ -231,6 +274,7 @@ sbput(int devfd, struct fs *fs, int numaltwrite) fs->fs_sblockactualloc = savedactualloc; if (fs->fs_si != NULL) fs->fs_csp = savedcsp; + fflush(NULL); /* flush any messages */ return (0); } diff --git a/lib/libufs/sbread.3 b/lib/libufs/sbread.3 index f579fc7ffdf1..460699842036 100644 --- a/lib/libufs/sbread.3 +++ b/lib/libufs/sbread.3 @@ -3,19 +3,21 @@ .\" Description: .\" Manual page for libufs functions: .\" sbget(3) +.\" sbsearch(3) .\" sbput(3) .\" sbread(3) +.\" sbfind(3) .\" sbwrite(3) .\" .\" This file is in the public domain. .\" .\" $FreeBSD$ .\" -.Dd September 2, 2020 +.Dd August 8, 2022 .Dt SBREAD 3 .Os .Sh NAME -.Nm sbget , sbput , sbread , sbwrite +.Nm sbget , sbsearch , sbput , sbread , sbfind , sbwrite .Nd read and write superblocks of a UFS file system .Sh LIBRARY .Lb libufs @@ -29,16 +31,22 @@ .Ft int .Fn sbget "int devfd" "struct fs **fsp" "off_t sblockloc" "int flags" .Ft int +.Fn sbsearch "int devfd" "struct fs **fsp" "int flags" +.Ft int .Fn sbput "int devfd" "struct fs *fs" "int numaltwrite" .Ft int .Fn sbread "struct uufsd *disk" .Ft int +.Fn sbfind "struct uufsd *disk" "int flags" +.Ft int .Fn sbwrite "struct uufsd *disk" "int all" .Sh DESCRIPTION The -.Fn sbget +.Fn sbget , +.Fn sbsearch , +.Fn sbread , and -.Fn sbread +.Fn sbfind functions provide superblock reads for .Xr libufs 3 consumers. @@ -52,7 +60,9 @@ consumers. .Pp The .Fn sbget -function first allocates a buffer to hold the superblock. +and +.Fn sbsearch +functions first allocate a buffer to hold the superblock. Using the .Va devfd file descriptor that references the filesystem disk, @@ -65,26 +75,38 @@ The value may be specified for .Va sblockloc to request that the standard location for the superblock be read. +The +.Fn sbsearch +function uses the +.Va devfd +file descriptor that references the filesystem disk, +to search first for the superblock at the standard location. +If it is not found or is too damaged to use +.Fn sbsearch +will attempt to find one of the filesystem's alternate superblocks. Flags are specified by .Em or Ns 'ing the following values: .Pp -.Bl -tag -width UFS_NOHASHFAIL -.It Cm UFS_NOHASHFAIL -Will note if the check hash is wrong but will still return the superblock. +.Bl -tag -width UFS_NOCSUM +.It Cm UFS_NOCSUM +Causes only the superblock itself to be returned, but does not read in any +auxiliary data structures like the cylinder group summary information. .It Cm UFS_NOMSG Indicates that superblock inconsistency error messages should not be printed. -.It Cm UFS_NOCSUM -Causes only the superblock itself to be returned, but does not read in any auxiliary data structures like the cylinder group summary information. .El .Pp If successful, .Fn sbget -returns a pointer to the buffer containing the superblock in +and +.Fn sbsearch +functions return a pointer to the buffer containing the superblock in .Va fsp . The .Fn sbget -function is safe to use in threaded applications. +and +.Fn sbsearch +functions are safe to use in threaded applications. .Pp The .Fn sbput @@ -113,7 +135,19 @@ modified and the on-disk copy needs to be updated. .Pp The .Fn sbread -function reads the standard filesystem superblock into the +function reads the standard filesystem superblock. +The +.Fn sbfind +function tries to find a usable superblock. +It searchs first for the superblock at the standard location. +If it is not found or is too damaged to use +.Fn sbfind +will attempt to find one of the filesystem's alternate superblocks. +If successful +.Fn sbread +and +.Fn sbfind +return a superblock in the .Va d_sb , structure embedded in the given user-land UFS disk structure. .Pp @@ -131,16 +165,19 @@ value is non-zero. .Sh RETURN VALUES .Rv -std sbread sbwrite The -.Fn sbget +.Fn sbget , +.Fn sbsearch , and .Fn sbput functions return the value 0 if successful; otherwise they return one of the errors described below. .Sh ERRORS The errors returned by -.Fn sbget +.Fn sbget , +.Fn sbsearch , +.Fn sbread , and -.Fn sbread +.Fn sbfind , include any of the errors specified for the library function .Xr bread 3 . Additionally, they may follow the |
