summaryrefslogtreecommitdiff
path: root/sys/lib/libsa/ufs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/lib/libsa/ufs.c')
-rw-r--r--sys/lib/libsa/ufs.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/sys/lib/libsa/ufs.c b/sys/lib/libsa/ufs.c
index e768beaef24..9ba26a49048 100644
--- a/sys/lib/libsa/ufs.c
+++ b/sys/lib/libsa/ufs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs.c,v 1.26 2016/11/25 17:00:33 reyk Exp $ */
+/* $OpenBSD: ufs.c,v 1.27 2019/08/03 15:22:17 deraadt Exp $ */
/* $NetBSD: ufs.c,v 1.16 1996/09/30 16:01:22 ws Exp $ */
/*-
@@ -81,6 +81,7 @@ struct file {
off_t f_seekp; /* seek pointer */
struct fs *f_fs; /* pointer to super-block */
struct ufs1_dinode f_di; /* copy of on-disk inode */
+ ufsino_t f_ino; /* our inode number */
int f_nindir[NIADDR];
/* number of blocks mapped by
indirect block at level i */
@@ -95,6 +96,7 @@ struct file {
};
static int read_inode(ufsino_t, struct open_file *);
+static int chmod_inode(ufsino_t, struct open_file *, mode_t);
static int block_map(struct open_file *, daddr32_t, daddr32_t *);
static int buf_read_file(struct open_file *, char **, size_t *);
static int search_directory(char *, struct open_file *, ufsino_t *);
@@ -154,6 +156,50 @@ out:
}
/*
+ * Read a new inode into a file structure.
+ */
+static int
+chmod_inode(ufsino_t inumber, struct open_file *f, mode_t mode)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ struct fs *fs = fp->f_fs;
+ char *buf;
+ size_t rsize;
+ int rc;
+
+ /*
+ * Read inode and save it.
+ */
+ buf = alloc(fs->fs_bsize);
+ twiddle();
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fsbtodb(fs, (daddr32_t)ino_to_fsba(fs, inumber)), fs->fs_bsize,
+ buf, &rsize);
+ if (rc)
+ goto out;
+ if (rsize != (size_t)fs->fs_bsize) {
+ rc = EIO;
+ goto out;
+ }
+
+ {
+ struct ufs1_dinode *dp;
+
+ dp = &((struct ufs1_dinode *)buf)[ino_to_fsbo(fs, inumber)];
+ dp->di_mode = mode;
+ }
+
+ twiddle();
+ rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
+ fsbtodb(fs, (daddr32_t)ino_to_fsba(fs, inumber)), fs->fs_bsize,
+ buf, NULL);
+
+out:
+ free(buf, fs->fs_bsize);
+ return (rc);
+}
+
+/*
* Given an offset in a file, find the disk block number that
* contains that block.
*/
@@ -522,6 +568,7 @@ ufs_open(char *path, struct open_file *f)
/*
* Found terminal component.
*/
+ fp->f_ino = inumber;
rc = 0;
out:
if (buf)
@@ -639,6 +686,14 @@ ufs_stat(struct open_file *f, struct stat *sb)
return (0);
}
+int
+ufs_fchmod(struct open_file *f, mode_t mode)
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ return chmod_inode(fp->f_ino, f, mode);
+}
+
#ifndef NO_READDIR
int
ufs_readdir(struct open_file *f, char *name)