aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/md
diff options
context:
space:
mode:
authorKa Ho Ng <khng@FreeBSD.org>2021-09-11 12:03:38 +0000
committerKa Ho Ng <khng@FreeBSD.org>2021-09-11 12:04:52 +0000
commit3703c18883341f3ff09c42d7f3b36ab80e4a071b (patch)
tree2463648a1f0b2dc6446e65cfcac0de59bcc33d66 /sys/dev/md
parent71a1ae7cebd3791d4d18ac9620a7a4ce8cf15819 (diff)
downloadsrc-3703c18883341f3ff09c42d7f3b36ab80e4a071b.tar.gz
src-3703c18883341f3ff09c42d7f3b36ab80e4a071b.zip
md: Add MD_MUSTDEALLOC support
This adds an option to detect if hole-punching is implemented by the underlying file system. If this flag is set, and if the underlying file system does not support hole-punching, md(4) fails BIO_DELETE requests with EOPNOTSUPP. Sponsored by: The FreeBSD Foundation Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D31883
Diffstat (limited to 'sys/dev/md')
-rw-r--r--sys/dev/md/md.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 08fb4b0c6574..92d93f0f0f1d 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -90,6 +90,7 @@
#include <sys/sf_buf.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
+#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/disk.h>
@@ -259,6 +260,7 @@ struct md_s {
struct g_provider *pp;
int (*start)(struct md_s *sc, struct bio *bp);
struct devstat *devstat;
+ bool candelete;
/* MD_MALLOC related fields */
struct indir *indir;
@@ -885,9 +887,12 @@ mdstart_vnode(struct md_s *sc, struct bio *bp)
case BIO_WRITE:
auio.uio_rw = UIO_WRITE;
break;
- case BIO_DELETE:
case BIO_FLUSH:
break;
+ case BIO_DELETE:
+ if (sc->candelete)
+ break;
+ /* FALLTHROUGH */
default:
return (EOPNOTSUPP);
}
@@ -1176,7 +1181,7 @@ md_handleattr(struct md_s *sc, struct bio *bp)
(g_handleattr_int(bp, "GEOM::fwsectors", sc->fwsectors) != 0 ||
g_handleattr_int(bp, "GEOM::fwheads", sc->fwheads) != 0))
return;
- if (g_handleattr_int(bp, "GEOM::candelete", 1) != 0)
+ if (g_handleattr_int(bp, "GEOM::candelete", sc->candelete) != 0)
return;
if (sc->ident[0] != '\0' &&
g_handleattr_str(bp, "GEOM::ident", sc->ident) != 0)
@@ -1405,6 +1410,7 @@ mdcreate_vnode(struct md_s *sc, struct md_req *mdr, struct thread *td)
struct nameidata nd;
char *fname;
int error, flags;
+ long v;
fname = mdr->md_file;
if (mdr->md_file_seg == UIO_USERSPACE) {
@@ -1434,6 +1440,13 @@ mdcreate_vnode(struct md_s *sc, struct md_req *mdr, struct thread *td)
error = VOP_GETATTR(nd.ni_vp, &vattr, td->td_ucred);
if (error != 0)
goto bad;
+ if ((mdr->md_options & MD_MUSTDEALLOC) != 0) {
+ error = VOP_PATHCONF(nd.ni_vp, _PC_DEALLOC_PRESENT, &v);
+ if (error != 0)
+ goto bad;
+ if (v == 0)
+ sc->candelete = false;
+ }
if (VOP_ISLOCKED(nd.ni_vp) != LK_EXCLUSIVE) {
vn_lock(nd.ni_vp, LK_UPGRADE | LK_RETRY);
if (VN_IS_DOOMED(nd.ni_vp)) {
@@ -1690,6 +1703,7 @@ kern_mdattach_locked(struct thread *td, struct md_req *mdr)
mdr->md_unit = sc->unit;
sc->mediasize = mdr->md_mediasize;
sc->sectorsize = sectsize;
+ sc->candelete = true;
error = EDOOFUS;
switch (sc->type) {
case MD_MALLOC: