diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 5efd20e1e8daad9e087493fc7ad4f8b34bfbaf43..5d3ab404b36add905c457af0fa3e261ba7e5a514 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -89,6 +89,12 @@ Frequency  : only for Cray XT3
 Description: peer credits not enough on many OST per OSS systems.
 Details    : Use new lnet way to add credits as we need those for pings and ASTs
 
+Severity   : minor
+Bugzilla   : 12790
+Frequency  : only with liblustre
+Description: Liblustre is not releasing flock locks on file close.
+Details    : Release flock locks on file close.
+
 --------------------------------------------------------------------------------
 
 2007-07-30         Cluster File Systems, Inc. <info@clusterfs.com>
diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c
index c9ec160ea932e7e7beede7ade9c854e5e2cd01ce..4548aeb96f51f4b600bb6628d89beaabcf6fbf9d 100644
--- a/lustre/liblustre/file.c
+++ b/lustre/liblustre/file.c
@@ -402,9 +402,33 @@ int llu_file_release(struct inode *inode)
 int llu_iop_close(struct inode *inode)
 {
         int rc;
+        struct ldlm_res_id res_id =
+                { .name = {llu_i2stat(inode)->st_ino,
+                 (__u64)llu_i2info(inode)->lli_st_generation, LDLM_FLOCK} };
+        struct lustre_handle lockh = {0};
 
         liblustre_wait_event(0);
 
+        /* If we have posix locks on this file - clear all of those */
+        if (ldlm_lock_match(
+                      class_exp2obd(llu_i2mdcexp(inode))->obd_namespace,
+                      LDLM_FL_BLOCK_GRANTED|LDLM_FL_TEST_LOCK|LDLM_FL_CBPENDING,
+                      &res_id, LDLM_FLOCK, NULL, LCK_PR|LCK_PW, &lockh)) {
+                struct file_lock lock;
+                lock.fl_type = F_UNLCK;
+                lock.fl_flags = FL_POSIX;
+                lock.fl_start = 0;
+                lock.fl_end = OFFSET_MAX;
+                lock.fl_pid = getpid();
+                lock.fl_notify = NULL;
+                lock.fl_insert = NULL;
+                lock.fl_remove = NULL;
+                lock.fl_owner = NULL;
+                lock.fl_file = NULL;
+
+                llu_file_flock(inode, F_SETLK, &lock);
+        }
+
         rc = llu_file_release(inode);
         if (rc) {
                 CERROR("file close error %d\n", rc);
diff --git a/lustre/liblustre/llite_lib.h b/lustre/liblustre/llite_lib.h
index 3df6cad2ee41d7e7ce73bb5f3dbe56aa49046962..78c0bd45bfd9e8121417c7a7e4318eb4e591d5cc 100644
--- a/lustre/liblustre/llite_lib.h
+++ b/lustre/liblustre/llite_lib.h
@@ -189,6 +189,7 @@ int ll_it_open_error(int phase, struct lookup_intent *it);
 struct inode *llu_iget(struct filesys *fs, struct lustre_md *md);
 int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm);
 int llu_setattr_raw(struct inode *inode, struct iattr *attr);
+int llu_file_flock(struct inode *ino, int cmd, struct file_lock *file_lock);
 
 extern struct fssw_ops llu_fssw_ops;
 
diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c
index 93260a945525f6e95177ae2127924625290a9d8e..fa7ff8f5c0118f2ca0fe3d5c62be002f341c0952 100644
--- a/lustre/liblustre/super.c
+++ b/lustre/liblustre/super.c
@@ -1267,9 +1267,7 @@ static int llu_iop_rmdir_raw(struct pnode *pno)
 #define FCNTL_FLMASK_INVALID (O_NONBLOCK|O_ASYNC)
 
 /* refer to ll_file_flock() for details */
-static int llu_file_flock(struct inode *ino,
-                          int cmd,
-                          struct file_lock *file_lock)
+int llu_file_flock(struct inode *ino, int cmd, struct file_lock *file_lock)
 {
         struct llu_inode_info *lli = llu_i2info(ino);
         struct intnl_stat *st = llu_i2stat(ino);