return 0;
 }
 
+static ssize_t table_write2(struct file *file, const char __user *user_buf,
+                           size_t count, loff_t *ppos)
+{
+       struct seq_file *seq = file->private_data;
+       int n, len, lkb_nodeid, lkb_status, error;
+       char name[DLM_RESNAME_MAXLEN] = {};
+       struct dlm_ls *ls = seq->private;
+       unsigned int lkb_flags;
+       char buf[256] = {};
+       uint32_t lkb_id;
+
+       if (copy_from_user(buf, user_buf,
+                          min_t(size_t, sizeof(buf) - 1, count)))
+               return -EFAULT;
+
+       n = sscanf(buf, "%x %" __stringify(DLM_RESNAME_MAXLEN) "s %x %d %d",
+                  &lkb_id, name, &lkb_flags, &lkb_nodeid, &lkb_status);
+       if (n != 5)
+               return -EINVAL;
+
+       len = strnlen(name, DLM_RESNAME_MAXLEN);
+       error = dlm_debug_add_lkb(ls, lkb_id, name, len, lkb_flags,
+                                 lkb_nodeid, lkb_status);
+       if (error)
+               return error;
+
+       return count;
+}
+
 static int table_open3(struct inode *inode, struct file *file)
 {
        struct seq_file *seq;
        .owner   = THIS_MODULE,
        .open    = table_open2,
        .read    = seq_read,
+       .write   = table_write2,
        .llseek  = seq_lseek,
        .release = seq_release
 };
        snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_locks", ls->ls_name);
 
        ls->ls_debug_locks_dentry = debugfs_create_file(name,
-                                                       S_IFREG | S_IRUGO,
+                                                       0644,
                                                        dlm_root,
                                                        ls,
                                                        &format2_fops);
 
        return error;
 }
 
+/* debug functionality */
+int dlm_debug_add_lkb(struct dlm_ls *ls, uint32_t lkb_id, char *name, int len,
+                     int lkb_nodeid, unsigned int lkb_flags, int lkb_status)
+{
+       struct dlm_lksb *lksb;
+       struct dlm_lkb *lkb;
+       struct dlm_rsb *r;
+       int error;
+
+       /* we currently can't set a valid user lock */
+       if (lkb_flags & DLM_IFL_USER)
+               return -EOPNOTSUPP;
+
+       lksb = kzalloc(sizeof(*lksb), GFP_NOFS);
+       if (!lksb)
+               return -ENOMEM;
+
+       error = _create_lkb(ls, &lkb, lkb_id, lkb_id + 1);
+       if (error) {
+               kfree(lksb);
+               return error;
+       }
+
+       lkb->lkb_flags = lkb_flags;
+       lkb->lkb_nodeid = lkb_nodeid;
+       lkb->lkb_lksb = lksb;
+       /* user specific pointer, just don't have it NULL for kernel locks */
+       if (~lkb_flags & DLM_IFL_USER)
+               lkb->lkb_astparam = (void *)0xDEADBEEF;
+
+       error = find_rsb(ls, name, len, 0, R_REQUEST, &r);
+       if (error) {
+               kfree(lksb);
+               __put_lkb(ls, lkb);
+               return error;
+       }
+
+       lock_rsb(r);
+       attach_lkb(r, lkb);
+       add_lkb(r, lkb, lkb_status);
+       unlock_rsb(r);
+       put_rsb(r);
+
+       return 0;
+}
+
 
        int nodeid, int pid);
 int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid);
 void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc);
+int dlm_debug_add_lkb(struct dlm_ls *ls, uint32_t lkb_id, char *name, int len,
+                     int lkb_nodeid, unsigned int lkb_flags, int lkb_status);
 
 static inline int is_master(struct dlm_rsb *r)
 {