Skip to content

Commit

Permalink
Implement pageoutv2 feature
Browse files Browse the repository at this point in the history
Remodel the pageout to use V2 style calling so we control when the allocate
UPL, and model it after HFS vnop_pageout.
  • Loading branch information
lundman committed Sep 3, 2015
1 parent 776d41f commit c9c6da4
Show file tree
Hide file tree
Showing 9 changed files with 1,104 additions and 368 deletions.
14 changes: 14 additions & 0 deletions include/sys/hfs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ struct user64_ext_access_t {

#define HFSIOC_GETPATH _IOWR('h', 13, pathname_t)
#define HFS_GETPATH IOCBASECMD(HFSIOC_GETPATH)
#define HFS_GETPATH_VOLUME_RELATIVE 0x1

/* This define is deemed secret by Apple */
#define BUILDPATH_VOLUME_RELATIVE 0x8 /* Return path relative to the nearest mount point */

/* Enable/disable extent-based extended attributes */
#define HFSIOC_SET_XATTREXTENTS_STATE _IOW('h', 14, u_int32_t)
Expand Down Expand Up @@ -146,6 +150,16 @@ struct user64_ext_access_t {
#define HFSIOC_GET_DESIRED_DISK _IOR('h', 29, u_int32_t)
#define HFS_FSCTL_GET_DESIRED_DISK IOCBASECMD(HFSIOC_GET_DESIRED_DISK)

/* revisiond only uses this when something transforms in a way the kernel can't track
such as "foo.rtf" -> "foo.rtfd" */
#define HFSIOC_TRANSFER_DOCUMENT_ID _IOW('h', 32, u_int32_t)
#define HFS_TRANSFER_DOCUMENT_ID IOCBASECMD(HFSIOC_TRANSFER_DOCUMENT_ID)


/* fcntl.h */
#define F_MAKECOMPRESSED 80 /* Make the file compressed; truncate & toggle BSD bits */


// END of definitions

#endif
1 change: 1 addition & 0 deletions include/sys/zfs_vfsops.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct znode;
/* #define WITH_SEARCHFS */
/* #define WITH_READDIRATTR */
#define HAVE_NAMED_STREAMS 1
#define HAVE_PAGEOUT_V2 1
#endif


Expand Down
22 changes: 21 additions & 1 deletion include/sys/zfs_znode.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ extern "C" {
#define ZFS_OFFLINE 0x0000100000000000ull
#define ZFS_SPARSE 0x0000200000000000ull

#ifdef __APPLE__
/* Unsure how we officially register new flags bits, but
* I guess we will claim the whole nibble for OSX
* 0x00n0000000000000ull : n = 1 2 4 8
*/
#define ZFS_TRACKED 0x0010000000000000ull
#endif

#define ZFS_ATTR_SET(zp, attr, value, pflags, tx) \
{ \
if (value) \
Expand Down Expand Up @@ -237,6 +245,7 @@ typedef struct znode {
#ifdef __APPLE__
list_node_t z_link_reclaim_node; /* all reclaim znodes in fs link */
uint32_t z_vid; /* OSX vnode_vid */
uint32_t z_document_id;
/* Track vnop_lookup name for Finder - not for anything else */
char z_finder_hardlink_name[MAXPATHLEN];
boolean_t z_fastpath;
Expand Down Expand Up @@ -290,7 +299,11 @@ typedef struct znode {
*/
#define ZFS_ENTER(zfsvfs) \
{ \
rrm_enter_read(&(zfsvfs)->z_teardown_lock, FTAG); \
if (!POINTER_IS_VALID(zfsvfs)) { \
printf("ZFS: ZFS_ENTER on released %s:%d", \
__FILE__, __LINE__); \
return EIO; } \
rrm_enter_read(&(zfsvfs)->z_teardown_lock, FTAG); \
if ((zfsvfs)->z_unmounted) { \
ZFS_EXIT(zfsvfs); \
return (EIO); \
Expand Down Expand Up @@ -445,6 +458,13 @@ int zfs_attach_vnode(znode_t *zp);
uint32_t zfs_getbsdflags(znode_t *zp);
void zfs_setbsdflags(znode_t *zp, uint32_t bsdflags);
void zfs_time_stamper_locked(znode_t *zp, uint_t flag, dmu_tx_t *tx);
int zfs_setattr_set_documentid(znode_t *zp, boolean_t update_flags);
void zfs_setattr_generate_id(znode_t *zp, uint64_t val, char *name);

#define FNV1_32A_INIT ((uint32_t)0x811c9dc5)
uint32_t fnv_32a_str(const char *str, uint32_t hval);
uint32_t fnv_32a_buf(void *buf, size_t len, uint32_t hval);


#ifdef ZFS_DEBUG
typedef enum whereami {
Expand Down
2 changes: 2 additions & 0 deletions module/zfs/dmu_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,8 @@ dmu_tx_assign(dmu_tx_t *tx, txg_how_t txg_how)
txg_how == TXG_WAITED);
ASSERT(!dsl_pool_sync_context(tx->tx_pool));

VERIFY0(dsl_pool_sync_context(tx->tx_pool));

if (txg_how == TXG_WAITED)
tx->tx_waited = B_TRUE;

Expand Down
83 changes: 0 additions & 83 deletions module/zfs/zfs_osx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,93 +143,10 @@ zfs_vfs_sysctl(int *name, __unused u_int namelen, user_addr_t oldp, size_t *oldl
#endif /* __APPLE__ */





#include <sys/utsname.h>
#include <string.h>


/*
* fnv_32a_str - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a string
*
* input:
* str - string to hash
* hval - previous hash value or 0 if first call
*
* returns:
* 32 bit hash as a static hash type
*
* NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the
* hval arg on the first call to either fnv_32a_buf() or fnv_32a_str().
*/
#define FNV1_32A_INIT ((uint32_t)0x811c9dc5)
uint32_t
fnv_32a_str(const char *str, uint32_t hval)
{
unsigned char *s = (unsigned char *)str; /* unsigned string */

/*
* FNV-1a hash each octet in the buffer
*/
while (*s) {

/* xor the bottom with the current octet */
hval ^= (uint32_t)*s++;

/* multiply by the 32 bit FNV magic prime mod 2^32 */
#if defined(NO_FNV_GCC_OPTIMIZATION)
hval *= FNV_32_PRIME;
#else
hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
#endif
}

/* return our new hash value */
return hval;
}

/*
* fnv_32a_buf - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a buffer
*
* input:
*buf- start of buffer to hash
*len- length of buffer in octets
*hval- previous hash value or 0 if first call
*
* returns:
*32 bit hash as a static hash type
*
* NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the
* hval arg on the first call to either fnv_32a_buf() or fnv_32a_str().
*/
uint32_t
fnv_32a_buf(void *buf, size_t len, uint32_t hval)
{
unsigned char *bp = (unsigned char *)buf;/* start of buffer */
unsigned char *be = bp + len;/* beyond end of buffer */

/*
* FNV-1a hash each octet in the buffer
*/
while (bp < be) {

/* xor the bottom with the current octet */
hval ^= (uint32_t)*bp++;

/* multiply by the 32 bit FNV magic prime mod 2^32 */
#if defined(NO_FNV_GCC_OPTIMIZATION)
hval *= FNV_32_PRIME;
#else
hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
#endif
}

/* return our new hash value */
return hval;
}


} // Extern "C"


Expand Down
58 changes: 34 additions & 24 deletions module/zfs/zfs_vnops.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ update_pages(vnode_t *vp, int64_t nbytes, struct uio *uio,
dmu_tx_t *tx)
{
znode_t *zp = VTOZ(vp);
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
//zfsvfs_t *zfsvfs = zp->z_zfsvfs;
int len = nbytes;
int error = 0;
vm_offset_t vaddr = 0;
Expand All @@ -360,15 +360,22 @@ update_pages(vnode_t *vp, int64_t nbytes, struct uio *uio,
* Create a UPL for the current range and map its
* page list into the kernel virtual address space.
*/
if ( ubc_create_upl(vp, upl_start, upl_size, &upl, NULL,
UPL_FILE_IO | UPL_SET_LITE) == KERN_SUCCESS ) {
pl = ubc_upl_pageinfo(upl);
ubc_upl_map(upl, &vaddr);
}
error = ubc_create_upl(vp, upl_start, upl_size, &upl, &pl,
UPL_FILE_IO | UPL_SET_LITE);
if ((error != KERN_SUCCESS) || !upl) {
printf("ZFS: update_pages failed to ubc_create_upl: %d\n", error);
return;
}

if (ubc_upl_map(upl, &vaddr) != KERN_SUCCESS) {
printf("ZFS: update_pages failed to ubc_upl_map: %d\n", error);
(void) ubc_upl_abort(upl, UPL_ABORT_FREE_ON_EMPTY);
return;
}

for (upl_page = 0; len > 0; ++upl_page) {
uint64_t bytes = MIN(PAGESIZE - off, len);
uint64_t woff = uio_offset(uio);
//uint64_t woff = uio_offset(uio);
/*
* We don't want a new page to "appear" in the middle of
* the file update (because it may not get the write
Expand Down Expand Up @@ -417,14 +424,12 @@ update_pages(vnode_t *vp, int64_t nbytes, struct uio *uio,
/*
* Unmap the page list and free the UPL.
*/
if (pl) {
(void) ubc_upl_unmap(upl);
/*
* We want to abort here since due to dmu_write()
* we effectively didn't dirty any pages.
*/
(void) ubc_upl_abort(upl, UPL_ABORT_FREE_ON_EMPTY);
}
(void) ubc_upl_unmap(upl);
/*
* We want to abort here since due to dmu_write()
* we effectively didn't dirty any pages.
*/
(void) ubc_upl_abort(upl, UPL_ABORT_FREE_ON_EMPTY);

}
#endif
Expand Down Expand Up @@ -589,11 +594,18 @@ mappedread(vnode_t *vp, int nbytes, struct uio *uio)
* Create a UPL for the current range and map its
* page list into the kernel virtual address space.
*/
if ( ubc_create_upl(vp, upl_start, upl_size, &upl, NULL,
UPL_FILE_IO | UPL_SET_LITE) == KERN_SUCCESS ) {
pl = ubc_upl_pageinfo(upl);
ubc_upl_map(upl, &vaddr);
}
error = ubc_create_upl(vp, upl_start, upl_size, &upl, &pl,
UPL_FILE_IO | UPL_SET_LITE);
if ((error != KERN_SUCCESS) || !upl) {
printf("ZFS: mappedread failed to ubc_create_upl: %d\n", error);
return EIO;
}

if (ubc_upl_map(upl, &vaddr) != KERN_SUCCESS) {
printf("ZFS: mappedread failed to ubc_upl_map: %d\n", error);
(void) ubc_upl_abort(upl, UPL_ABORT_FREE_ON_EMPTY);
return ENOMEM;
}

for (upl_page = 0; len > 0; ++upl_page) {
uint64_t bytes = MIN(PAGE_SIZE - off, len);
Expand All @@ -620,10 +632,8 @@ mappedread(vnode_t *vp, int nbytes, struct uio *uio)
/*
* Unmap the page list and free the UPL.
*/
if (pl) {
(void) ubc_upl_unmap(upl);
(void) ubc_upl_abort(upl, UPL_ABORT_FREE_ON_EMPTY);
}
(void) ubc_upl_unmap(upl);
(void) ubc_upl_abort(upl, UPL_ABORT_FREE_ON_EMPTY);

return (error);
}
Expand Down
Loading

0 comments on commit c9c6da4

Please sign in to comment.