aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2018-11-13 21:40:56 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2018-11-13 21:40:56 +0000
commit9fc5d538fc57f438ca860e07db191b946b4768c9 (patch)
tree0f73178df156f836c4d9dde3af92b526b95c4e72 /lib
parentf183fb162c1dbc58cc3f7e2c27891bd881db2bf2 (diff)
downloadsrc-9fc5d538fc57f438ca860e07db191b946b4768c9.tar.gz
src-9fc5d538fc57f438ca860e07db191b946b4768c9.zip
In preparation for adding inode check-hashes, clean up and
document the libufs interface for fetching and storing inodes. The undocumented getino / putino interface has been replaced with a new getinode / putinode interface. Convert the utilities that had been using the undocumented interface to use the new documented interface. No functional change (as for now the libufs library does not do inode check-hashes). Reviewed by: kib Tested by: Peter Holm Sponsored by: Netflix
Notes
Notes: svn path=/head/; revision=340411
Diffstat (limited to 'lib')
-rw-r--r--lib/libufs/Makefile5
-rw-r--r--lib/libufs/getinode.3131
-rw-r--r--lib/libufs/inode.c30
-rw-r--r--lib/libufs/libufs.h9
4 files changed, 153 insertions, 22 deletions
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile
index 16487bebc957..2685f7318ac1 100644
--- a/lib/libufs/Makefile
+++ b/lib/libufs/Makefile
@@ -3,12 +3,12 @@
PACKAGE=lib${LIB}
LIB= ufs
SHLIBDIR?= /lib
-SHLIB_MAJOR= 6
+SHLIB_MAJOR= 7
SRCS= block.c cgroup.c crc32.c inode.c sblock.c type.c ffs_subr.c ffs_tables.c
INCS= libufs.h
-MAN= bread.3 cgread.3 libufs.3 sbread.3 ufs_disk_close.3
+MAN= bread.3 cgread.3 getinode.3 libufs.3 sbread.3 ufs_disk_close.3
MLINKS+= bread.3 bwrite.3
MLINKS+= bread.3 berase.3
MLINKS+= cgread.3 cgread1.3
@@ -16,6 +16,7 @@ MLINKS+= cgread.3 cgget.3
MLINKS+= cgread.3 cgwrite.3
MLINKS+= cgread.3 cgwrite1.3
MLINKS+= cgread.3 cgput.3
+MLINKS+= getinode.3 putinode.3
MLINKS+= sbread.3 sbwrite.3
MLINKS+= sbread.3 sbget.3
MLINKS+= sbread.3 sbput.3
diff --git a/lib/libufs/getinode.3 b/lib/libufs/getinode.3
new file mode 100644
index 000000000000..6aa5388cbd6d
--- /dev/null
+++ b/lib/libufs/getinode.3
@@ -0,0 +1,131 @@
+.\" Author: Marshall Kirk McKusick <mckusick@freebsd.org>
+.\" Date: January 19, 2018
+.\" Description:
+.\" Manual page for libufs functions:
+.\" getinode(3)
+.\" putinode(3)
+.\"
+.\" This file is in the public domain.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 10, 2018
+.Dt GETINODE 3
+.Os
+.Sh NAME
+.Nm getinode , putinode
+.Nd fetch and store inodes on a UFS file system
+.Sh LIBRARY
+.Lb libufs
+.Sh SYNOPSIS
+.In ufs/ufs/dinode.h
+.In ufs/ffs/fs.h
+.In libufs.h
+.Ft int
+.Fn getinode "struct uufsd *disk" "union dinodep *dp" "ino_t inumber"
+.Ft int
+.Fn putinode "struct uufsd *disk"
+.Sh DESCRIPTION
+The
+.Fn getinode
+and
+.Fn putinode
+functions provide an inode fetch and store API for
+.Xr libufs 3
+consumers.
+They operate on a userland UFS disk structure.
+The
+.Fn getinode
+function fetches the specified inode from the filesystem.
+The
+.Fn putinode
+function stores the most recently fetched inode to the filesystem.
+.Pp
+The
+.Va dinodep
+union is defined as:
+.Bd -literal -offset indent
+union dinodep {
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+};
+.Ed
+.Pp
+Sample code to clear write permissions for inode number
+.Fa inumber
+stored on the filesystem described by
+.Fa diskp .
+.Bd -literal -offset indent
+#include <sys/stat.h>
+#include <err.h>
+
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+#include <libufs.h>
+
+void
+clearwrite(struct uufsd *diskp, ino_t inumber)
+{
+ union dinodep dp;
+
+ if (getinode(diskp, &dp, inumber) == -1)
+ err(1, "getinode: %s", diskp->d_error);
+ switch (diskp->d_ufs) {
+ case 1: /* UFS 1 filesystem */
+ dp.dp1->di_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+ break;
+ case 2: /* UFS 2 filesystem */
+ dp.dp2->di_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+ break;
+ default:
+ errx(1, "unknown filesystem type");
+ }
+ if (putinode(diskp) == -1)
+ err(1, "putinode: %s", diskp->d_error);
+}
+.Ed
+.Sh RETURN VALUES
+The
+.Fn getinode
+and
+.Fn putinode
+functions return 0 on success, or \-1 in case of any error.
+A string describing the error is stored in
+.Fa diskp->d_error .
+The global
+.Fa errno
+often provides additional information.
+.Sh ERRORS
+The function
+.Fn getinode
+may fail and set
+.Va errno
+for any of the errors specified for the library function
+.Xr pread 2 .
+It can also fail if the inode number is out of the range of inodes
+in the filesystem.
+.Pp
+The function
+.Fn putinode
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr ufs_disk_write 3
+or
+.Xr pwrite 2 .
+.Pp
+Additionally both functions may follow the
+.Xr libufs 3
+error methodologies in case of a device error.
+.Sh SEE ALSO
+.Xr pread 2 ,
+.Xr pwrite 2 ,
+.Xr libufs 3 ,
+.Xr ufs_disk_write 3
+.Sh HISTORY
+These functions first appeared as part of
+.Xr libufs 3
+in
+.Fx 13.0 .
+.Sh AUTHORS
+.An Marshall Kirk McKusick Aq Mt mckusick@freebsd.org
diff --git a/lib/libufs/inode.c b/lib/libufs/inode.c
index 83a6cf0e36c7..11e263f08ad5 100644
--- a/lib/libufs/inode.c
+++ b/lib/libufs/inode.c
@@ -49,18 +49,16 @@ __FBSDID("$FreeBSD$");
#include <libufs.h>
int
-getino(struct uufsd *disk, void **dino, ino_t inode, int *mode)
+getinode(struct uufsd *disk, union dinodep *dp, ino_t inum)
{
ino_t min, max;
caddr_t inoblock;
- struct ufs1_dinode *dp1;
- struct ufs2_dinode *dp2;
struct fs *fs;
ERROR(disk, NULL);
fs = &disk->d_fs;
- if (inode >= (ino_t)fs->fs_ipg * fs->fs_ncg) {
+ if (inum >= (ino_t)fs->fs_ipg * fs->fs_ncg) {
ERROR(disk, "inode number out of range");
return (-1);
}
@@ -76,26 +74,22 @@ getino(struct uufsd *disk, void **dino, ino_t inode, int *mode)
}
disk->d_inoblock = inoblock;
}
- if (inode >= min && inode < max)
+ if (inum >= min && inum < max)
goto gotit;
- bread(disk, fsbtodb(fs, ino_to_fsba(fs, inode)), inoblock,
+ bread(disk, fsbtodb(fs, ino_to_fsba(fs, inum)), inoblock,
fs->fs_bsize);
- disk->d_inomin = min = inode - (inode % INOPB(fs));
+ disk->d_inomin = min = inum - (inum % INOPB(fs));
disk->d_inomax = max = min + INOPB(fs);
gotit: switch (disk->d_ufs) {
case 1:
- dp1 = &((struct ufs1_dinode *)inoblock)[inode - min];
- if (mode != NULL)
- *mode = dp1->di_mode & IFMT;
- if (dino != NULL)
- *dino = dp1;
+ disk->d_dp.dp1 = &((struct ufs1_dinode *)inoblock)[inum - min];
+ if (dp != NULL)
+ *dp = disk->d_dp;
return (0);
case 2:
- dp2 = &((struct ufs2_dinode *)inoblock)[inode - min];
- if (mode != NULL)
- *mode = dp2->di_mode & IFMT;
- if (dino != NULL)
- *dino = dp2;
+ disk->d_dp.dp2 = &((struct ufs2_dinode *)inoblock)[inum - min];
+ if (dp != NULL)
+ *dp = disk->d_dp;
return (0);
default:
break;
@@ -105,7 +99,7 @@ gotit: switch (disk->d_ufs) {
}
int
-putino(struct uufsd *disk)
+putinode(struct uufsd *disk)
{
struct fs *fs;
diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index 4598a9999ce2..dbd378949877 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -35,6 +35,10 @@
/*
* libufs structures.
*/
+union dinodep {
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+};
/*
* userland ufs disk.
@@ -49,6 +53,7 @@ struct uufsd {
caddr_t d_inoblock; /* inode block */
uint32_t d_inomin; /* low inode (not ino_t for ABI compat) */
uint32_t d_inomax; /* high inode (not ino_t for ABI compat) */
+ union dinodep d_dp; /* pointer to currently active inode */
union {
struct fs d_fs; /* filesystem information */
char d_sb[MAXBSIZE];
@@ -135,8 +140,8 @@ int cgwrite1(struct uufsd *, int);
/*
* inode.c
*/
-int getino(struct uufsd *, void **, ino_t, int *);
-int putino(struct uufsd *);
+int getinode(struct uufsd *, union dinodep *, ino_t);
+int putinode(struct uufsd *);
/*
* sblock.c