Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Linux kernel compatability enhancements (through 3.19)
[palacios.git] / linux_module / iface-keyed-stream.c
index 75978ab..1f75aa0 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/file.h>
 #include <linux/uaccess.h>
 #include <linux/namei.h>
-#include <linux/vmalloc.h>
 #include <linux/poll.h>
 #include <linux/anon_inodes.h>
 
@@ -168,7 +167,7 @@ static struct mem_stream *create_mem_stream_internal(uint64_t size)
     }
 
 
-    m->data = vmalloc(size);
+    m->data = palacios_valloc(size);
     
     if (!m->data) { 
        palacios_free(m);
@@ -193,7 +192,7 @@ static void destroy_mem_stream(struct mem_stream *m)
 {
     if (m) {
        if (m->data) {
-           vfree(m->data);
+           palacios_vfree(m->data);
        }
        m->data=0;
        palacios_free(m);
@@ -202,7 +201,7 @@ static void destroy_mem_stream(struct mem_stream *m)
     
 static int expand_mem_stream(struct mem_stream *m, uint32_t new_size)
 {
-    void *data = vmalloc(new_size);
+    void *data = palacios_valloc(new_size);
     uint32_t nc;
 
     if (!data) { 
@@ -213,7 +212,7 @@ static int expand_mem_stream(struct mem_stream *m, uint32_t new_size)
 
     memcpy(data,m->data,nc);
 
-    vfree(m->data);
+    palacios_vfree(m->data);
 
     m->data=data;
     m->size=new_size;
@@ -311,7 +310,7 @@ static v3_keyed_stream_t open_stream_mem(char *url,
                    return 0;
                }
 
-               strcpy(mykey,url+4);
+               strcpy(mykey,url+4); // will fit
                
                mks = (struct mem_keyed_stream *) palacios_alloc(sizeof(struct mem_keyed_stream));
 
@@ -383,7 +382,7 @@ static v3_keyed_stream_key_t open_key_mem(v3_keyed_stream_t stream,
            return 0;
        }
 
-       strcpy(mykey,key);
+       strcpy(mykey,key); // will fit
 
        m = create_mem_stream();
        
@@ -432,7 +431,7 @@ static void preallocate_hint_key_mem(v3_keyed_stream_t stream,
            return;
        }
        
-       strcpy(mykey,key);
+       strcpy(mykey,key); // will fit
        
        m = create_mem_stream_internal(size);
        
@@ -658,12 +657,157 @@ struct file_stream {
     struct file *f;   // the opened file
 };
 
+/* lookup directory, see if it is writeable, and if so, create it if asked*/
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,41)
+
+static int lookup_check_mkdir(const char *path, int need_write, int create, unsigned short perms)
+{
+  struct nameidata nd;
+
+  if (path_lookup(path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) { 
+    
+    // directory does does not exist.  
+    
+    if (!create) { 
+      // we are not being asked to create it
+      ERROR("attempt to open %s, which does not exist\n",path);
+      return -1;
+    } else {
+      // We are being asked to create it
+
+      struct dentry *de;
+      int err;
+      
+      // Find its parent
+      if (path_lookup(path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) { 
+       ERROR("attempt to create %s failed because its parent cannot be looked up\n",path);
+       return -1;
+      }
+      
+      // Can we write to the parent?
+      
+      if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
+       ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",path);
+       return -1;
+      }
+
+      // OK, we can, so let's create it
+      
+      de = lookup_create(&nd,1);
+      
+      if (!de || IS_ERR(de)) { 
+       ERROR("cannot allocate dentry\n");
+       return -1;
+      }
+
+      err = vfs_mkdir(nd.path.dentry->d_inode, de, perms);
+      
+      // lookup_create locks this for us!
+      
+      mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
+
+      if (err) {
+       ERROR("attempt to create %s failed because mkdir failed\n",path);
+       return -1;
+      }
+
+      // successfully created it. 
+      return 0;
+
+    }
+
+  } else {
+    
+    // it exists, can we read (and write, if needed) to it?
+    
+    if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_READ | need_write ? MAY_WRITE : 0 )) {
+      ERROR("attempt to open %s, which has the wrong permissions\n",path);
+      return -1;
+    }
+    
+    return 0;
+  }
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,41)
+static int lookup_check_mkdir(const char *path, int need_write, int create, unsigned short perms)
+{
+  struct path p; 
+
+  if (kern_path(path, LOOKUP_DIRECTORY|LOOKUP_FOLLOW, &p)) { 
+    
+    // directory does does not exist.  
+    
+    if (!create) { 
+      // we are not being asked to create it
+      ERROR("attempt to open %s, which does not exist\n",path);
+      return -1;
+    } else {
+      // We are being asked to create it
+
+      struct dentry *de;
+      int err;
+      
+      // Find its parent
+      if (kern_path(path,LOOKUP_PARENT|LOOKUP_FOLLOW,&p)) { 
+       ERROR("attempt to create %s failed because its parent cannot be looked up\n",path);
+       return -1;
+      }
+      
+      // Can we write to the parent?
+      
+      if (inode_permission(p.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
+       ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",path);
+       return -1;
+      }
+
+      // OK, we can, so let's create it
+      
+      de = kern_path_create(AT_FDCWD,path,&p,1);
+      
+      if (!de || IS_ERR(de)) { 
+       ERROR("cannot allocate dentry\n");
+       return -1;
+      }
+
+      err = vfs_mkdir(p.dentry->d_inode, de, perms);
+      
+      // lookup_create locks this for us!
+      
+      mutex_unlock(&(p.dentry->d_inode->i_mutex));
+
+      if (err) {
+       ERROR("attempt to create %s failed because mkdir failed\n",path);
+       return -1;
+      }
+
+      // successfully created it. 
+      return 0;
+
+    }
+    
+  } else {
+    
+    // it exists, can we read (and write, if needed) to it?
+    
+    if (inode_permission(p.dentry->d_inode, MAY_EXEC | MAY_READ | need_write ? MAY_WRITE : 0 )) {
+      ERROR("attempt to open %s, which has the wrong permissions\n",path);
+      return -1;
+    }
+    
+    return 0;
+  }
+}
+
+#endif
+
 
 static v3_keyed_stream_t open_stream_file(char *url,
                                          v3_keyed_stream_open_t ot)
 {
     struct file_keyed_stream *fks;
-    struct nameidata nd;
 
     if (strncasecmp(url,"file:",5)) { 
        WARNING("illegitimate attempt to open file stream \"%s\"\n",url);
@@ -685,80 +829,18 @@ static v3_keyed_stream_t open_stream_file(char *url,
        return 0;
     }
     
-    strcpy(fks->path,url+5);
+    strcpy(fks->path,url+5); // will fit
     
     fks->stype=STREAM_FILE;
 
     fks->ot= ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
 
-    // Does the directory exist, and can we read/write it?
-   
-    if (path_lookup(fks->path,LOOKUP_DIRECTORY|LOOKUP_FOLLOW,&nd)) { 
-
-       // directory does does not exist.  
-
-       if (ot==V3_KS_RD_ONLY || ot==V3_KS_WR_ONLY) { 
-
-           // we are not being asked to create it
-           ERROR("attempt to open %s, which does not exist\n",fks->path);
-           goto fail_out;
-
-       } else {
-
-           // We are being asked to create it
-
-           struct dentry *de;
-           int err;
-
-           // Find its parent
-           if (path_lookup(fks->path,LOOKUP_PARENT|LOOKUP_FOLLOW,&nd)) { 
-               ERROR("attempt to create %s failed because its parent cannot be looked up\n",fks->path);
-               goto fail_out;
-           }
-
-           // Can we write to the parent?
-
-           if (inode_permission(nd.path.dentry->d_inode, MAY_WRITE | MAY_EXEC)) { 
-               ERROR("attempt to open %s, which has the wrong permissions for directory creation\n",fks->path);
-               goto fail_out;
-           }
-
-           // OK, we can, so let's create it
-
-           de = lookup_create(&nd,1);
-
-           if (IS_ERR(de)) { 
-               ERROR("cannot allocate dentry\n");
-               goto fail_out;
-           }
-
-           err = vfs_mkdir(nd.path.dentry->d_inode, de, 0700);
-
-           // lookup_create locks this for us!
-
-           mutex_unlock(&(nd.path.dentry->d_inode->i_mutex));
-
-           if (err) {
-               ERROR("attempt to create %s failed because mkdir failed\n",fks->path);
-               goto fail_out;
-           }
-
-           // now the directory should exist and have reasonable permissions
-           return (v3_keyed_stream_t) fks;
-       }
-    } 
-
-    
-    // we must be in V3_KS_RD_ONLY or V3_KS_WR_ONLY, 
-    // and the directory exists, so we must check the permissions
-
-    if (inode_permission(nd.path.dentry->d_inode, MAY_EXEC | (ot==V3_KS_RD_ONLY ? MAY_READ : MAY_WRITE))) {
-       ERROR("attempt to open %s, which has the wrong permissions\n",fks->path);
-       goto fail_out;
-    } else {
-       return (v3_keyed_stream_t) fks;
+    if (lookup_check_mkdir(fks->path,ot!=V3_KS_RD_ONLY,ot==V3_KS_WR_ONLY_CREATE,0700)) { 
+      ERROR("cannot find or create directory for stream\n");
+      goto fail_out;
     }
 
+    return fks;
 
  fail_out:
     palacios_free(fks->path);
@@ -797,11 +879,12 @@ static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream,
        ERROR("cannot allocate file keyed stream for key %s\n",key);
        return 0;
     }
+    // this sequence will fit and terminate with a zero
     strcpy(path,fks->path);
     strcat(path,"/");
     strcat(path,key);
     
-    fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream *));
+    fs = (struct file_stream *) palacios_alloc(sizeof(struct file_stream));
     
     if (!fs) { 
        ERROR("cannot allocate file keyed stream for key %s\n",key);
@@ -811,9 +894,9 @@ static v3_keyed_stream_key_t open_key_file(v3_keyed_stream_t stream,
 
     fs->stype=STREAM_FILE;
 
-    fs->f = filp_open(path,O_RDWR|O_CREAT,0600);
-    
-    if (IS_ERR(fs->f)) {
+    fs->f = filp_open(path,O_RDWR|O_CREAT|O_LARGEFILE,0600);
+
+    if (!fs->f || IS_ERR(fs->f)) {
        ERROR("cannot open relevent file \"%s\" for stream \"file:%s\" and key \"%s\"\n",path,fks->path,key);
        palacios_free(fs);
        palacios_free(path);
@@ -1449,7 +1532,7 @@ static v3_keyed_stream_key_t open_key_textfile(v3_keyed_stream_t stream,
     }
 
 
-    if (token_scan(ms,tempkey,keylen+3," \t\r\n",4)) { 
+    if (token_scan(ms,tempkey,keylen+3,"\t\r\n",3)) { 
       ERROR("Cannot scan for token (key search)\n");
       close_key_file(mks,ms);
       mks->stype=STREAM_TEXTFILE;
@@ -1709,7 +1792,7 @@ static int do_request_to_response(struct user_keyed_stream *s, unsigned long *fl
     s->waiting = 1;
 
     // release the stream
-    spin_unlock_irqrestore(&(s->lock), *flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
 
     // wake up anyone waiting on it
     wake_up_interruptible(&(s->user_wait_queue));
@@ -1718,7 +1801,7 @@ static int do_request_to_response(struct user_keyed_stream *s, unsigned long *fl
     while (wait_event_interruptible(s->host_wait_queue, (s->waiting == 0)) != 0) {}
 
     // reacquire the lock for our called
-    spin_lock_irqsave(&(s->lock), *flags);
+    palacios_spinlock_lock_irqsave(&(s->lock), *flags);
 
     return 0;
 }
@@ -1739,7 +1822,7 @@ static int do_response_to_request(struct user_keyed_stream *s, unsigned long *fl
     s->waiting = 0;
 
     // release the stream
-    spin_unlock_irqrestore(&(s->lock), *flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock), *flags);
 
     // wake up anyone waiting on it
     wake_up_interruptible(&(s->host_wait_queue));
@@ -1758,16 +1841,16 @@ static unsigned int keyed_stream_poll_user(struct file *filp, poll_table *wait)
         return POLLERR;
     }
     
-    spin_lock_irqsave(&(s->lock), flags);
+    palacios_spinlock_lock_irqsave(&(s->lock), flags);
+
+    poll_wait(filp, &(s->user_wait_queue), wait);
 
     if (s->waiting) {
-       spin_unlock_irqrestore(&(s->lock), flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
        return POLLIN | POLLRDNORM;
     }
-
-    poll_wait(filp, &(s->user_wait_queue), wait);
     
-    spin_unlock_irqrestore(&(s->lock), flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
 
     return 0;
 }
@@ -1786,22 +1869,22 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi
            
            // inform request size
            
-           spin_lock_irqsave(&(s->lock), flags);
+           palacios_spinlock_lock_irqsave(&(s->lock), flags);
            
            if (!(s->waiting)) {
-               spin_unlock_irqrestore(&(s->lock), flags);
+               palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
                return 0;
            }
 
            size =  sizeof(struct palacios_user_keyed_stream_op) + s->op->buf_len;
            
            if (copy_to_user((void * __user) argp, &size, sizeof(uint64_t))) {
-               spin_unlock_irqrestore(&(s->lock), flags);
+               palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
                ERROR("palacios user key size request failed to copy data\n");
                return -EFAULT;
            }
            
-           spin_unlock_irqrestore(&(s->lock), flags);
+           palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
            
            return 1;
            
@@ -1811,10 +1894,10 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi
                
            // pull the request
            
-           spin_lock_irqsave(&(s->lock), flags);
+           palacios_spinlock_lock_irqsave(&(s->lock), flags);
 
            if (!(s->waiting)) {
-               spin_unlock_irqrestore(&(s->lock), flags);
+               palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
                ERROR("palacios user key pull request when not waiting\n");
                return 0;
            }
@@ -1823,12 +1906,12 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi
 
 
            if (copy_to_user((void __user *) argp, s->op, size)) {
-               spin_unlock_irqrestore(&(s->lock), flags);
+               palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
                ERROR("palacios user key pull request failed to copy data\n");
                return -EFAULT;
            }
 
-           spin_unlock_irqrestore(&(s->lock), flags);
+           palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
            
            return 1;
            
@@ -1839,28 +1922,29 @@ static long keyed_stream_ioctl_user(struct file * filp, unsigned int ioctl, unsi
 
         // push the response
 
-        spin_lock_irqsave(&(s->lock), flags);
+        palacios_spinlock_lock_irqsave(&(s->lock), flags);
 
         if (!(s->waiting)) {
-            spin_unlock_irqrestore(&(s->lock), flags);
+            palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
            ERROR("palacios user key push response when not waiting\n");
             return 0;
         }
        
         if (copy_from_user(&size, (void __user *) argp, sizeof(uint64_t))) {
            ERROR("palacios user key push response failed to copy size\n");
-            spin_unlock_irqrestore(&(s->lock), flags);
+            palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
             return -EFAULT;
         }
 
+       // overflow possible here for very large request
        if (resize_op(&(s->op),size-sizeof(struct palacios_user_keyed_stream_op))) {
            ERROR("unable to resize op in user key push response\n");
-            spin_unlock_irqrestore(&(s->lock), flags);
+            palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
            return -EFAULT;
        }
 
         if (copy_from_user(s->op, (void __user *) argp, size)) {
-            spin_unlock_irqrestore(&(s->lock), flags);
+            palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
             return -EFAULT;
         }
 
@@ -1887,13 +1971,13 @@ static int keyed_stream_release_user(struct inode *inode, struct file *filp)
     struct user_keyed_stream *s = filp->private_data;
     unsigned long f1,f2;
 
-    spin_lock_irqsave(&(user_streams->lock),f1);
-    spin_lock_irqsave(&(s->lock), f2);
+    palacios_spinlock_lock_irqsave(&(user_streams->lock),f1);
+    palacios_spinlock_lock_irqsave(&(s->lock), f2);
 
     list_del(&(s->node));
 
-    spin_unlock_irqrestore(&(s->lock), f2);
-    spin_unlock_irqrestore(&(user_streams->lock), f1);
+    palacios_spinlock_unlock_irqrestore(&(s->lock), f2);
+    palacios_spinlock_unlock_irqrestore(&(user_streams->lock), f1);
     
     palacios_free(s->url);
     palacios_free(s);
@@ -1934,6 +2018,7 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned
        return -1;
     }
 
+    // overflow possible here, but only if this is a huge guest request (>4GB)
     url = palacios_alloc(len);
     
     if (!url) { 
@@ -1949,7 +2034,7 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned
        
     
     // Check for duplicate handler
-    spin_lock_irqsave(&(user_streams->lock), flags);
+    palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
     list_for_each_entry(s, &(user_streams->streams), node) {
         if (!strncasecmp(url, s->url, len)) {
             ERROR("user keyed stream connection with url \"%s\" already exists\n", url);
@@ -1957,7 +2042,7 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned
             return -1;
         }
     }
-    spin_unlock_irqrestore(&(user_streams->lock), flags);
+    palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
     
     // Create connection
     s = palacios_alloc(sizeof(struct user_keyed_stream));
@@ -1988,9 +2073,9 @@ int keyed_stream_connect_user(struct v3_guest *guest, unsigned int cmd, unsigned
     init_waitqueue_head(&(s->host_wait_queue));
     
     // Insert connection into list
-    spin_lock_irqsave(&(user_streams->lock), flags);
+    palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
     list_add(&(s->node), &(user_streams->streams));
-    spin_unlock_irqrestore(&(user_streams->lock), flags);
+    palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
     
     return fd;
 }
@@ -2005,15 +2090,15 @@ static struct user_keyed_stream *keyed_stream_user_find(char *url)
        return NULL;
     }
     
-    spin_lock_irqsave(&(user_streams->lock), flags);
+    palacios_spinlock_lock_irqsave(&(user_streams->lock), flags);
     list_for_each_entry(s, &(user_streams->streams), node) {
         if (!strcasecmp(url, s->url)) {
-            spin_unlock_irqrestore(&(user_streams->lock), flags);
+            palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
             return s;
         }
     }
     
-    spin_unlock_irqrestore(&(user_streams->lock), flags);
+    palacios_spinlock_unlock_irqrestore(&(user_streams->lock), flags);
     
     return NULL;
 }
@@ -2031,17 +2116,17 @@ static v3_keyed_stream_t open_stream_user(char *url, v3_keyed_stream_open_t ot)
         return NULL;
     }
 
-    spin_lock_irqsave(&(s->lock), flags);
+    palacios_spinlock_lock_irqsave(&(s->lock), flags);
 
     if (s->waiting) {
-        spin_unlock_irqrestore(&(s->lock), flags);
+        palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
        ERROR("cannot open user stream %s as it is already in waiting state\n",url);
         return NULL;
     }
     
     s->otype = ot==V3_KS_WR_ONLY_CREATE ? V3_KS_WR_ONLY : ot;
     
-    spin_unlock_irqrestore(&(s->lock), flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock), flags);
     
     return s;
     
@@ -2072,22 +2157,22 @@ static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
     uint64_t   len = strlen(key)+1;
     void *user_key;
 
-    spin_lock_irqsave(&(s->lock), flags);
+    palacios_spinlock_lock_irqsave(&(s->lock), flags);
 
 
     if (resize_op(&(s->op),len)) {
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("cannot resize op in opening key %s on user keyed stream %s\n",key,s->url);
        return NULL;
     }
 
     s->op->type = PALACIOS_KSTREAM_OPEN_KEY;
     s->op->buf_len = len;
-    strncpy(s->op->buf,key,len);
+    strncpy(s->op->buf,key,len); // will terminate buffer
 
     // enter with it locked
     if (do_request_to_response(s,&flags)) { 
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("request/response handling failed\n");
        return NULL;
     }
@@ -2095,7 +2180,7 @@ static v3_keyed_stream_key_t open_key_user(v3_keyed_stream_t stream, char *key)
 
     user_key=s->op->user_key;
 
-    spin_unlock_irqrestore(&(s->lock),flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
 
     return user_key;
 }
@@ -2106,10 +2191,10 @@ static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
     uint64_t   len = 0;
     unsigned long flags;
     
-    spin_lock_irqsave(&(s->lock), flags);
+    palacios_spinlock_lock_irqsave(&(s->lock), flags);
 
     if (resize_op(&(s->op),len)) {
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("cannot resize op in closing key 0x%p on user keyed stream %s\n",key,s->url);
        return;
     }
@@ -2120,13 +2205,13 @@ static void close_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t key)
 
     // enter with it locked
     if (do_request_to_response(s,&flags)) { 
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("request/response handling failed\n");
        return;
     }
     // return with it locked
 
-    spin_unlock_irqrestore(&(s->lock),flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
 
     return;
 }
@@ -2144,16 +2229,16 @@ static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke
     sint64_t   xfer;
     unsigned long flags;
 
-    spin_lock_irqsave(&(s->lock), flags);
+    palacios_spinlock_lock_irqsave(&(s->lock), flags);
 
     if (s->otype != V3_KS_RD_ONLY) { 
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("attempt to read key from stream that is not in read state on %s\n",s->url);
     }  
 
 
     if (resize_op(&(s->op),len)) {
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
        return -1;
     }
@@ -2168,7 +2253,7 @@ static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke
 
     // enter with it locked
     if (do_request_to_response(s,&flags)) { 
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("request/response handling failed\n");
        return -1;
     }
@@ -2182,7 +2267,7 @@ static sint64_t read_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke
 
     xfer=s->op->xfer;
 
-    spin_unlock_irqrestore(&(s->lock),flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
 
     return xfer;
 }
@@ -2200,15 +2285,15 @@ static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t k
     unsigned long flags;
 
 
-    spin_lock_irqsave(&(s->lock), flags);
+    palacios_spinlock_lock_irqsave(&(s->lock), flags);
 
     if (s->otype != V3_KS_WR_ONLY) { 
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("attempt to write key on stream that is not in write state on %s\n",s->url);
     }  
 
     if (resize_op(&(s->op),len)) {
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("cannot resize op in reading key 0x%p on user keyed stream %s\n",key,s->url);
        return -1;
     }
@@ -2224,7 +2309,7 @@ static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t k
 
     // enter with it locked
     if (do_request_to_response(s,&flags)) { 
-       spin_unlock_irqrestore(&(s->lock),flags);
+       palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
        ERROR("request/response handling failed\n");
        return -1;
     }
@@ -2234,7 +2319,7 @@ static sint64_t write_key_user(v3_keyed_stream_t stream, v3_keyed_stream_key_t k
 
     xfer=s->op->xfer;
 
-    spin_unlock_irqrestore(&(s->lock),flags);
+    palacios_spinlock_unlock_irqrestore(&(s->lock),flags);
 
     return xfer;
 }
@@ -2350,8 +2435,12 @@ static int send_msg(struct net_stream *ns,  char * buf, int len)
        msg.msg_namelen = 0;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),WRITE,&iov,1,0);
+#endif
 
        iov.iov_base = (char *)&(buf[len-left]);
        iov.iov_len = (size_t)left;
@@ -2404,8 +2493,12 @@ static int recv_msg(struct net_stream *ns, char * buf, int len)
        msg.msg_namelen = 0;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
+#else
+       iov_iter_init(&(msg.msg_iter),READ,&iov,1,0);
+#endif
        
        iov.iov_base = (void *)&(buf[len-left]);
        iov.iov_len = (size_t)left;
@@ -2780,7 +2873,7 @@ static sint64_t write_key_net(v3_keyed_stream_t stream, v3_keyed_stream_key_t ke
            ERROR("Could not send tag length in write_key_net\n");
            return -1;
        } 
-       if (send_msg(nks->ns,tag,taglen)!=len) { 
+       if (send_msg(nks->ns,tag,taglen)!=taglen) { 
            ERROR("Could not send tag in write_key_net\n");
            return -1;
        }
@@ -3145,7 +3238,7 @@ static int init_keyed_streams( void )
 
     INIT_LIST_HEAD(&(user_streams->streams));
     
-    spin_lock_init(&(user_streams->lock));
+    palacios_spinlock_init(&(user_streams->lock));
 
     V3_Init_Keyed_Streams(&hooks);
 
@@ -3157,6 +3250,8 @@ static int deinit_keyed_streams( void )
 {
     palacios_free_htable(mem_streams,1,1);
 
+    palacios_spinlock_deinit(&(user_streams->lock));
+
     palacios_free(user_streams);
 
     WARNING("Deinit of Palacios Keyed Streams likely leaked memory\n");
@@ -3176,6 +3271,7 @@ static int guest_init_keyed_streams(struct v3_guest * guest, void ** vm_data )
 
 static int guest_deinit_keyed_streams(struct v3_guest * guest, void * vm_data)
 {
+    remove_guest_ctrl(guest, V3_VM_KSTREAM_USER_CONNECT);
 
     return 0;
 }