ocfs2: retry on ENOSPC if sufficient space in truncate log
[cascardo/linux.git] / fs / ocfs2 / suballoc.c
index 2f19aee..ea47120 100644 (file)
@@ -1164,7 +1164,8 @@ static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
                                             int flags,
                                             struct ocfs2_alloc_context **ac)
 {
-       int status;
+       int status, ret = 0;
+       int retried = 0;
 
        *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
        if (!(*ac)) {
@@ -1189,7 +1190,24 @@ static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
        }
 
        if (status == -ENOSPC) {
+retry:
                status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
+               /* Retry if there is sufficient space cached in truncate log */
+               if (status == -ENOSPC && !retried) {
+                       retried = 1;
+                       ocfs2_inode_unlock((*ac)->ac_inode, 1);
+                       inode_unlock((*ac)->ac_inode);
+
+                       ret = ocfs2_try_to_free_truncate_log(osb, bits_wanted);
+                       if (ret == 1)
+                               goto retry;
+
+                       if (ret < 0)
+                               mlog_errno(ret);
+
+                       inode_lock((*ac)->ac_inode);
+                       ocfs2_inode_lock((*ac)->ac_inode, NULL, 1);
+               }
                if (status < 0) {
                        if (status != -ENOSPC)
                                mlog_errno(status);