ocfs2: retry on ENOSPC if sufficient space in truncate log
[cascardo/linux.git] / fs / ocfs2 / alloc.c
index 460c0ce..7dabbc3 100644 (file)
@@ -6106,6 +6106,43 @@ void ocfs2_schedule_truncate_log_flush(struct ocfs2_super *osb,
        }
 }
 
+/*
+ * Try to flush truncate logs if we can free enough clusters from it.
+ * As for return value, "< 0" means error, "0" no space and "1" means
+ * we have freed enough spaces and let the caller try to allocate again.
+ */
+int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb,
+                                       unsigned int needed)
+{
+       tid_t target;
+       int ret = 0;
+       unsigned int truncated_clusters;
+
+       inode_lock(osb->osb_tl_inode);
+       truncated_clusters = osb->truncated_clusters;
+       inode_unlock(osb->osb_tl_inode);
+
+       /*
+        * Check whether we can succeed in allocating if we free
+        * the truncate log.
+        */
+       if (truncated_clusters < needed)
+               goto out;
+
+       ret = ocfs2_flush_truncate_log(osb);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       if (jbd2_journal_start_commit(osb->journal->j_journal, &target)) {
+               jbd2_log_wait_commit(osb->journal->j_journal, target);
+               ret = 1;
+       }
+out:
+       return ret;
+}
+
 static int ocfs2_get_truncate_log_info(struct ocfs2_super *osb,
                                       int slot_num,
                                       struct inode **tl_inode,