PERFORCE change 200833 for review
John Baldwin
jhb at FreeBSD.org
Thu Oct 27 17:35:55 UTC 2011
http://p4web.freebsd.org/@@200833?ac=10
Change 200833 by jhb at 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
More information about the p4-projects
mailing list