Page MenuHomeFreeBSD

D23042.id66377.diff
No OneTemporary

D23042.id66377.diff

Index: lib/libc/sys/posix_fallocate.2
===================================================================
--- lib/libc/sys/posix_fallocate.2
+++ lib/libc/sys/posix_fallocate.2
@@ -28,7 +28,7 @@
.\" @(#)open.2 8.2 (Berkeley) 11/16/93
.\" $FreeBSD$
.\"
-.Dd November 4, 2017
+.Dd January 5, 2020
.Dt POSIX_FALLOCATE 2
.Os
.Sh NAME
@@ -115,7 +115,8 @@
.It Bq Er ENODEV
The
.Fa fd
-argument does not refer to a regular file.
+argument does not refer to a file that supports
+.Nm .
.It Bq Er ENOSPC
There is insufficient free space remaining on the file system storage
media.
Index: sys/kern/uipc_shm.c
===================================================================
--- sys/kern/uipc_shm.c
+++ sys/kern/uipc_shm.c
@@ -138,6 +138,7 @@
static fo_mmap_t shm_mmap;
static fo_get_seals_t shm_get_seals;
static fo_add_seals_t shm_add_seals;
+static fo_fallocate_t shm_fallocate;
/* File descriptor operations. */
struct fileops shm_ops = {
@@ -157,6 +158,7 @@
.fo_mmap = shm_mmap,
.fo_get_seals = shm_get_seals,
.fo_add_seals = shm_add_seals,
+ .fo_fallocate = shm_fallocate,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@@ -1437,6 +1439,25 @@
return (0);
}
+static int
+shm_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td)
+{
+ struct shmfd *shmfd;
+ size_t size;
+ int error;
+
+ /* This assumes that the caller already checked for overflow. */
+ error = 0;
+ shmfd = fp->f_data;
+ size = offset + len;
+ if (size > shmfd->shm_size)
+ error = shm_dotruncate(shmfd, size);
+ /* Translate to posix_fallocate(2) return value as needed. */
+ if (error == ENOMEM)
+ error = ENOSPC;
+ return (error);
+}
+
static int
sysctl_posix_shm_list(SYSCTL_HANDLER_ARGS)
{
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -4569,13 +4569,7 @@
kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len)
{
struct file *fp;
- struct mount *mp;
- struct vnode *vp;
- off_t olen, ooffset;
int error;
-#ifdef AUDIT
- int audited_vnode1 = 0;
-#endif
AUDIT_ARG_FD(fd);
if (offset < 0 || len <= 0)
@@ -4596,54 +4590,8 @@
error = EBADF;
goto out;
}
- if (fp->f_type != DTYPE_VNODE) {
- error = ENODEV;
- goto out;
- }
- vp = fp->f_vnode;
- if (vp->v_type != VREG) {
- error = ENODEV;
- goto out;
- }
- /* Allocating blocks may take a long time, so iterate. */
- for (;;) {
- olen = len;
- ooffset = offset;
-
- bwillwrite();
- mp = NULL;
- error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
- if (error != 0)
- break;
- error = vn_lock(vp, LK_EXCLUSIVE);
- if (error != 0) {
- vn_finished_write(mp);
- break;
- }
-#ifdef AUDIT
- if (!audited_vnode1) {
- AUDIT_ARG_VNODE1(vp);
- audited_vnode1 = 1;
- }
-#endif
-#ifdef MAC
- error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp);
- if (error == 0)
-#endif
- error = VOP_ALLOCATE(vp, &offset, &len);
- VOP_UNLOCK(vp);
- vn_finished_write(mp);
-
- if (olen + ooffset != offset + len) {
- panic("offset + len changed from %jx/%jx to %jx/%jx",
- ooffset, olen, offset, len);
- }
- if (error != 0 || len == 0)
- break;
- KASSERT(olen > len, ("Iteration did not make progress?"));
- maybe_yield();
- }
+ error = fo_fallocate(fp, offset, len, td);
out:
fdrop(fp, td);
return (error);
Index: sys/kern/vfs_vnops.c
===================================================================
--- sys/kern/vfs_vnops.c
+++ sys/kern/vfs_vnops.c
@@ -103,6 +103,7 @@
static fo_stat_t vn_statfile;
static fo_close_t vn_closefile;
static fo_mmap_t vn_mmap;
+static fo_fallocate_t vn_fallocate;
struct fileops vnops = {
.fo_read = vn_io_fault,
@@ -119,6 +120,7 @@
.fo_seek = vn_seek,
.fo_fill_kinfo = vn_fill_kinfo,
.fo_mmap = vn_mmap,
+ .fo_fallocate = vn_fallocate,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@@ -3150,3 +3152,60 @@
free(dat, M_TEMP);
return (error);
}
+
+static int
+vn_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td)
+{
+ struct mount *mp;
+ struct vnode *vp;
+ off_t olen, ooffset;
+ int error;
+#ifdef AUDIT
+ int audited_vnode1 = 0;
+#endif
+
+ vp = fp->f_vnode;
+ if (vp->v_type != VREG)
+ return (ENODEV);
+
+ /* Allocating blocks may take a long time, so iterate. */
+ for (;;) {
+ olen = len;
+ ooffset = offset;
+
+ bwillwrite();
+ mp = NULL;
+ error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
+ if (error != 0)
+ break;
+ error = vn_lock(vp, LK_EXCLUSIVE);
+ if (error != 0) {
+ vn_finished_write(mp);
+ break;
+ }
+#ifdef AUDIT
+ if (!audited_vnode1) {
+ AUDIT_ARG_VNODE1(vp);
+ audited_vnode1 = 1;
+ }
+#endif
+#ifdef MAC
+ error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp);
+ if (error == 0)
+#endif
+ error = VOP_ALLOCATE(vp, &offset, &len);
+ VOP_UNLOCK(vp);
+ vn_finished_write(mp);
+
+ if (olen + ooffset != offset + len) {
+ panic("offset + len changed from %jx/%jx to %jx/%jx",
+ ooffset, olen, offset, len);
+ }
+ if (error != 0 || len == 0)
+ break;
+ KASSERT(olen > len, ("Iteration did not make progress?"));
+ maybe_yield();
+ }
+
+ return (error);
+}
Index: sys/sys/file.h
===================================================================
--- sys/sys/file.h
+++ sys/sys/file.h
@@ -125,6 +125,8 @@
typedef int fo_aio_queue_t(struct file *fp, struct kaiocb *job);
typedef int fo_add_seals_t(struct file *fp, int flags);
typedef int fo_get_seals_t(struct file *fp, int *flags);
+typedef int fo_fallocate_t(struct file *fp, off_t offset, off_t len,
+ struct thread *td);
typedef int fo_flags_t;
struct fileops {
@@ -145,6 +147,7 @@
fo_aio_queue_t *fo_aio_queue;
fo_add_seals_t *fo_add_seals;
fo_get_seals_t *fo_get_seals;
+ fo_fallocate_t *fo_fallocate;
fo_flags_t fo_flags; /* DFLAG_* below */
};
@@ -446,6 +449,15 @@
return ((*fp->f_ops->fo_get_seals)(fp, seals));
}
+static __inline int
+fo_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td)
+{
+
+ if (fp->f_ops->fo_fallocate == NULL)
+ return (ENODEV);
+ return ((*fp->f_ops->fo_fallocate)(fp, offset, len, td));
+}
+
#endif /* _KERNEL */
#endif /* !SYS_FILE_H */

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 26, 3:33 AM (5 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32158815
Default Alt Text
D23042.id66377.diff (6 KB)

Event Timeline