Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Oct 2011 17:35:54 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 200833 for review
Message-ID:  <201110271735.p9RHZs5c054711@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@200833?ac=10

Change 200833 by jhb@jhb_jhbbsd on 2011/10/27 17:35:46

	Move fadvise info out into a separate sub-structure that
	struct file points at.  Shove f_cdevpriv into a union and
	reuse its storage to point to fadvise info for non-cdev vnodes.
	This should leave the ABI of struct file unchanged now.

Affected files ...

.. //depot/projects/fadvise/sys/kern/kern_descrip.c#4 edit
.. //depot/projects/fadvise/sys/kern/vfs_syscalls.c#12 edit
.. //depot/projects/fadvise/sys/kern/vfs_vnops.c#4 edit
.. //depot/projects/fadvise/sys/sys/file.h#5 edit

Differences ...

==== //depot/projects/fadvise/sys/kern/kern_descrip.c#4 (text+ko) ====

@@ -1654,7 +1654,6 @@
 	fp->f_ops = &badfileops;
 	fp->f_data = NULL;
 	fp->f_vnode = NULL;
-	fp->f_advice = FADV_NORMAL;
 	*resultfp = fp;
 	return (0);
 }

==== //depot/projects/fadvise/sys/kern/vfs_syscalls.c#12 (text+ko) ====

@@ -86,6 +86,8 @@
 #include <vm/vm_page.h>
 #include <vm/uma.h>
 
+static MALLOC_DEFINE(M_FADVISE, "fadvise", "fadvise(2) information");
+
 SDT_PROVIDER_DEFINE(vfs);
 SDT_PROBE_DEFINE(vfs, , stat, mode, mode);
 SDT_PROBE_ARGTYPE(vfs, , stat, mode, 0, "char *");
@@ -4855,6 +4857,7 @@
 int
 sys_fadvise(struct thread *td, struct fadvise_args *uap)
 {
+	struct fadvise_info *fa, *new;
 	struct file *fp;
 	struct vnode *vp;
 	off_t end;
@@ -4864,12 +4867,15 @@
 	    uap->offset > OFF_MAX - uap->len)
 		return (EINVAL);
 	switch (uap->advice) {
-	case FADV_NORMAL:
 	case FADV_SEQUENTIAL:
 	case FADV_RANDOM:
+	case FADV_NOREUSE:
+		new = malloc(sizeof(*fa), M_FADVISE, M_WAITOK);
+		break;
+	case FADV_NORMAL:
 	case FADV_WILLNEED:
 	case FADV_DONTNEED:
-	case FADV_NOREUSE:
+		new = NULL;
 		break;
 	default:
 		return (EINVAL);
@@ -4909,18 +4915,21 @@
 		 * non-standard region for this request.
 		 */
 		mtx_pool_lock(mtxpool_sleep, fp);
-		if (fp->f_advice == uap->advice &&
-		    ((fp->f_advstart <= end && fp->f_advend >= uap->offset) ||
-		    (fp->f_advstart != 0 && fp->f_advstart == end + 1) ||
-		    (uap->offset != 0 && fp->f_advend + 1 == uap->offset))) {
-			if (uap->offset < fp->f_advstart)
-				fp->f_advstart = uap->offset;
-			if (end > fp->f_advend)
-				fp->f_advend = end;
+		fa = fp->f_advice;
+		if (fa != NULL && fa->fa_advice == uap->advice &&
+		    ((fa->fa_start <= end && fa->fa_end >= uap->offset) ||
+		    (fa->fa_start != 0 && fa->fa_start == end + 1) ||
+		    (uap->offset != 0 && fa->fa_end + 1 == uap->offset))) {
+			if (uap->offset < fa->fa_start)
+				fa->fa_start = uap->offset;
+			if (end > fa->fa_end)
+				fa->fa_end = end;
 		} else {
-			fp->f_advice = uap->advice;
-			fp->f_advstart = uap->offset;
-			fp->f_advend = end;
+			new->fa_advice = uap->advice;
+			new->fa_start = uap->offset;
+			new->fa_end = end;
+			fp->f_advice = new;
+			new = fa;
 		}
 		mtx_pool_unlock(mtxpool_sleep, fp);
 		break;
@@ -4931,18 +4940,20 @@
 		 * non-standard region.
 		 */
 		mtx_pool_lock(mtxpool_sleep, fp);
-		if (fp->f_advice != FADV_NORMAL) {
-			if (uap->offset <= fp->f_advstart &&
-			    end >= fp->f_advend)
-				fp->f_advice = FADV_NORMAL;
-			else if (uap->offset <= fp->f_advstart &&
-			    end >= fp->f_advstart)
-				fp->f_advstart = end + 1;
-			else if (uap->offset <= fp->f_advend &&
-			    end >= fp->f_advend)
-				fp->f_advend = uap->offset - 1;
-			else if (uap->offset >= fp->f_advstart &&
-			    end <= fp->f_advend)
+		fa = fp->f_advice;
+		if (fa != NULL) {
+			if (uap->offset <= fa->fa_start &&
+			    end >= fa->fa_end) {
+				new = fa;
+				fp->f_advice = NULL;
+			} else if (uap->offset <= fa->fa_start &&
+			    end >= fa->fa_start)
+				fa->fa_start = end + 1;
+			else if (uap->offset <= fa->fa_end &&
+			    end >= fa->fa_end)
+				fa->fa_end = uap->offset - 1;
+			else if (uap->offset >= fa->fa_start &&
+			    end <= fa->fa_end) {
 				/*
 				 * If the "normal" region is a middle
 				 * portion of the existing
@@ -4951,7 +4962,9 @@
 				 * one side or the other to
 				 * preserve.
 				 */
-				fp->f_advice = FADV_NORMAL;
+				new = fa;
+				fp->f_advice = NULL;
+			}
 		}
 		mtx_pool_unlock(mtxpool_sleep, fp);
 		break;
@@ -4961,6 +4974,8 @@
 		break;
 	}
 out:
-	fdrop(fp, td);
+	if (fp != NULL)
+		fdrop(fp, td);
+	free(new, M_FADVISE);
 	return (error);
 }

==== //depot/projects/fadvise/sys/kern/vfs_vnops.c#4 (text+ko) ====

@@ -535,7 +535,7 @@
 	 * According to McKusick the vn lock was protecting f_offset here.
 	 * It is now protected by the FOFFSET_LOCKED flag.
 	 */
-	if ((flags & FOF_OFFSET) == 0 || fp->f_advice != FADV_NORMAL) {
+	if ((flags & FOF_OFFSET) == 0 || fp->f_advice != NULL) {
 		mtxp = mtx_pool_find(mtxpool_sleep, fp);
 		mtx_lock(mtxp);
 		if ((flags & FOF_OFFSET) == 0) {
@@ -547,10 +547,10 @@
 			fp->f_vnread_flags |= FOFFSET_LOCKED;
 			uio->uio_offset = fp->f_offset;
 		}
-		if (fp->f_advice != FADV_NORMAL &&
-		    uio->uio_offset >= fp->f_advstart &&
-		    uio->uio_offset + uio->uio_resid <= fp->f_advend)
-			advice = fp->f_advice;
+		if (fp->f_advice != NULL &&
+		    uio->uio_offset >= fp->f_advice->fa_start &&
+		    uio->uio_offset + uio->uio_resid <= fp->f_advice->fa_end)
+			advice = fp->f_advice->fa_advice;
 		mtx_unlock(mtxp);
 	}
 	vn_lock(vp, LK_SHARED | LK_RETRY);
@@ -565,8 +565,8 @@
 		break;
 	case FADV_NOREUSE:
 		/*
-		 * Request the underlying FS to discard the pages
-		 * after the I/O is complete.
+		 * Request the underlying FS to discard the buffers
+		 * and pages after the I/O is complete.
 		 */
 		ioflag |= IO_DIRECT;
 		break;
@@ -641,13 +641,13 @@
 	if ((flags & FOF_OFFSET) == 0)
 		uio->uio_offset = fp->f_offset;
 	advice = FADV_NORMAL;
-	if (fp->f_advice != FADV_NORMAL) {
+	if (fp->f_advice != NULL) {
 		mtxp = mtx_pool_find(mtxpool_sleep, fp);
 		mtx_lock(mtxp);
-		if (fp->f_advice != FADV_NORMAL &&
-		    uio->uio_offset >= fp->f_advstart &&
-		    uio->uio_offset + uio->uio_resid <= fp->f_advend)
-			advice = fp->f_advice;
+		if (fp->f_advice != NULL &&
+		    uio->uio_offset >= fp->f_advice->fa_start &&
+		    uio->uio_offset + uio->uio_resid <= fp->f_advice->fa_end)
+			advice = fp->f_advice->fa_advice;
 		mtx_unlock(mtxp);
 	}
 	switch (advice) {
@@ -659,8 +659,8 @@
 		break;
 	case FADV_NOREUSE:
 		/*
-		 * Request the underlying FS to discard the pages
-		 * after the I/O is complete.
+		 * Request the underlying FS to discard the buffers
+		 * and pages after the I/O is complete.
 		 */
 		ioflag |= IO_DIRECT;
 		break;

==== //depot/projects/fadvise/sys/sys/file.h#5 (text+ko) ====

@@ -122,14 +122,19 @@
  * none	not locked
  */
 
+struct fadvise_info {
+	int		fa_advice;	/* (f) FADV_* type. */
+	off_t		fa_start;	/* (f) Region start. */
+	off_t		fa_end;		/* (f) Region end. */
+};
+
 struct file {
 	void		*f_data;	/* file descriptor specific data */
 	struct fileops	*f_ops;		/* File operations */
 	struct ucred	*f_cred;	/* associated credentials. */
 	struct vnode 	*f_vnode;	/* NULL or applicable vnode */
 	short		f_type;		/* descriptor type */
-	u_char		f_vnread_flags; /* (f) Sleep lock for f_offset */
-	u_char		f_advice;	/* (f) FADV_* type. */
+	short		f_vnread_flags; /* (f) Sleep lock for f_offset */
 	volatile u_int	f_flag;		/* see fcntl.h */
 	volatile u_int 	f_count;	/* reference count */
 	/*
@@ -137,9 +142,11 @@
 	 */
 	int		f_seqcount;	/* Count of sequential accesses. */
 	off_t		f_nextoff;	/* next expected read/write offset. */
-	struct cdev_privdata *f_cdevpriv; /* (d) Private data for the cdev. */
-	off_t		f_advstart;	/* (f) fadvice region start. */
-	off_t		f_advend;	/* (f) fadvice region end. */
+	union {
+		struct cdev_privdata *fvn_cdevpriv;
+					/* (d) Private data for the cdev. */
+		struct fadvise_info *fvn_advice;
+	} f_vnun;
 	/*
 	 *  DFLAG_SEEKABLE specific fields
 	 */
@@ -150,6 +157,9 @@
 	void		*f_label;	/* Place-holder for MAC label. */
 };
 
+#define	f_cdevpriv	f_vnun.fvn_cdevpriv
+#define	f_advice	f_vnun.fvn_advice
+
 #define	FOFFSET_LOCKED       0x1
 #define	FOFFSET_LOCK_WAITING 0x2		 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110271735.p9RHZs5c054711>