Content-Length: 653082 | pFad | https://github.com/DragonFlyBSD/DragonFlyBSD/commit/#start-of-content

683912CA sys/vfs/{ext2fs,ufs}: Add SEEK_HOLE / SEEK_DATA support · DragonFlyBSD/DragonFlyBSD@0c27d85 · GitHub
Skip to content

Commit 0c27d85

Browse files
committed
sys/vfs/{ext2fs,ufs}: Add SEEK_HOLE / SEEK_DATA support
Add VOP_BMAP based generic function vn_bmap_seekhole() for filesystems with .vop_bmap to support SEEK_HOLE / SEEK_DATA. FreeBSD has optimized version of FIOSEEKDATA for ext2 and ufs, but this commit only brings in generic version for both. taken-from: FreeBSD
1 parent 128dc99 commit 0c27d85

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-1
lines changed

sys/kern/vfs_vnops.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959

6060
#include <sys/mplock2.h>
6161

62+
#include <vm/vm_object.h>
63+
64+
#include <machine/limits.h>
65+
6266
static int vn_closefile (struct file *fp);
6367
static int vn_ioctl (struct file *fp, u_long com, caddr_t data,
6468
struct ucred *cred, struct sysmsg *msg);
@@ -1198,6 +1202,79 @@ vn_kqfilter(struct file *fp, struct knote *kn)
11981202
return (error);
11991203
}
12001204

1205+
int
1206+
vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
1207+
struct ucred *cred)
1208+
{
1209+
struct vattr vattr;
1210+
off_t size;
1211+
uint64_t bsize;
1212+
off_t noff, doff;
1213+
int error;
1214+
1215+
KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
1216+
("%s: Wrong command %lu", __func__, cmd));
1217+
KKASSERT(vn_islocked(vp) == LK_EXCLUSIVE);
1218+
1219+
if (vp->v_type != VREG) {
1220+
error = ENOTTY;
1221+
goto out;
1222+
}
1223+
error = VOP_GETATTR(vp, &vattr);
1224+
if (vattr.va_size <= OFF_MAX)
1225+
size = vattr.va_size;
1226+
else
1227+
error = EFBIG;
1228+
if (error != 0)
1229+
goto out;
1230+
noff = *off;
1231+
if (noff < 0 || noff >= size) {
1232+
error = ENXIO;
1233+
goto out;
1234+
}
1235+
1236+
vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC);
1237+
1238+
bsize = vp->v_mount->mnt_stat.f_iosize;
1239+
for (; noff < size; noff += bsize - noff % bsize) {
1240+
error = VOP_BMAP(vp, noff, &doff, NULL, NULL, BUF_CMD_READ);
1241+
if (error == EOPNOTSUPP) {
1242+
error = ENOTTY;
1243+
goto out;
1244+
}
1245+
if ((doff == NOOFFSET && cmd == FIOSEEKHOLE) ||
1246+
(doff != NOOFFSET && cmd == FIOSEEKDATA)) {
1247+
if (noff < *off)
1248+
noff = *off;
1249+
goto out;
1250+
}
1251+
}
1252+
if (noff > size)
1253+
noff = size;
1254+
/* noff == size. There is an implicit hole at the end of file. */
1255+
if (cmd == FIOSEEKDATA)
1256+
error = ENXIO;
1257+
out:
1258+
if (error == 0)
1259+
*off = noff;
1260+
return (error);
1261+
}
1262+
1263+
int
1264+
vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
1265+
{
1266+
int error;
1267+
1268+
KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
1269+
("%s: Wrong command %lu", __func__, cmd));
1270+
1271+
if (vn_lock(vp, LK_EXCLUSIVE) != 0)
1272+
return (EBADF);
1273+
error = vn_bmap_seekhole_locked(vp, cmd, off, cred);
1274+
vn_unlock(vp);
1275+
return (error);
1276+
}
1277+
12011278
int
12021279
vn_seek(struct file *fp, off_t offset, int whence, off_t *res)
12031280
{

sys/sys/vnode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,11 @@ void vn_syncer_thr_stop(struct mount *);
595595
void vn_syncer_one(struct mount *);
596596
long vn_syncer_count(struct mount *);
597597

598+
int vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
599+
struct ucred *cred);
600+
int vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off,
601+
struct ucred *cred);
602+
598603
u_quad_t init_va_filerev(void);
599604

600605
extern struct vop_ops default_vnode_vops;

sys/vfs/ext2fs/ext2_vnops.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,6 +1914,20 @@ ext2_read(struct vop_read_args *ap)
19141914
return (error);
19151915
}
19161916

1917+
static int
1918+
ext2_ioctl(struct vop_ioctl_args *ap)
1919+
{
1920+
1921+
switch (ap->a_command) {
1922+
case FIOSEEKDATA:
1923+
case FIOSEEKHOLE:
1924+
return (vn_bmap_seekhole(ap->a_vp, ap->a_command,
1925+
(off_t *)ap->a_data, ap->a_cred));
1926+
default:
1927+
return (ENOTTY);
1928+
}
1929+
}
1930+
19171931
/*
19181932
* Vnode op for writing.
19191933
*/
@@ -2116,6 +2130,7 @@ struct vop_ops ext2_vnodeops = {
21162130
.vop_putpages = vop_stdputpages,
21172131
.vop_getattr = ext2_getattr,
21182132
.vop_inactive = ext2_inactive,
2133+
.vop_ioctl = ext2_ioctl,
21192134
.vop_old_link = ext2_link,
21202135
.vop_old_lookup = ext2_lookup,
21212136
.vop_old_mkdir = ext2_mkdir,

sys/vfs/ufs/ufs_vnops.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <sys/uio.h>
4545
#include <sys/kernel.h>
4646
#include <sys/fcntl.h>
47+
#include <sys/filio.h>
4748
#include <sys/stat.h>
4849
#include <sys/buf.h>
4950
#include <sys/proc.h>
@@ -1888,6 +1889,27 @@ ufsfifo_close(struct vop_close_args *ap)
18881889
return (VOCALL(&fifo_vnode_vops, &ap->a_head));
18891890
}
18901891

1892+
/*
1893+
* Return POSIX pathconf information applicable to ufs filesystems.
1894+
*/
1895+
static int
1896+
ufs_pathconf(struct vop_pathconf_args *ap)
1897+
{
1898+
int error;
1899+
1900+
error = 0;
1901+
switch (ap->a_name) {
1902+
case _PC_MIN_HOLE_SIZE:
1903+
*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
1904+
break;
1905+
1906+
default:
1907+
error = vop_stdpathconf(ap);
1908+
break;
1909+
}
1910+
return (error);
1911+
}
1912+
18911913
/*
18921914
* Kqfilter wrapper for fifos.
18931915
*
@@ -2106,6 +2128,20 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
21062128
return (error);
21072129
}
21082130

2131+
static int
2132+
ufs_ioctl(struct vop_ioctl_args *ap)
2133+
{
2134+
2135+
switch (ap->a_command) {
2136+
case FIOSEEKDATA:
2137+
case FIOSEEKHOLE:
2138+
return (vn_bmap_seekhole(ap->a_vp, ap->a_command,
2139+
(off_t *)ap->a_data, ap->a_cred));
2140+
default:
2141+
return (ENOTTY);
2142+
}
2143+
}
2144+
21092145
static int
21102146
ufs_missingop(struct vop_generic_args *ap)
21112147
{
@@ -2229,11 +2265,12 @@ static struct vop_ops ufs_vnode_vops = {
22292265
.vop_old_create = ufs_create,
22302266
.vop_getattr = ufs_getattr,
22312267
.vop_inactive = ufs_inactive,
2268+
.vop_ioctl = ufs_ioctl,
22322269
.vop_old_link = ufs_link,
22332270
.vop_old_mkdir = ufs_mkdir,
22342271
.vop_old_mknod = ufs_mknod,
22352272
.vop_open = vop_stdopen,
2236-
.vop_pathconf = vop_stdpathconf,
2273+
.vop_pathconf = ufs_pathconf,
22372274
.vop_kqfilter = ufs_kqfilter,
22382275
.vop_print = ufs_print,
22392276
.vop_readdir = ufs_readdir,

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/DragonFlyBSD/DragonFlyBSD/commit/#start-of-content

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy