rapidio/rio_cm: avoid GFP_KERNEL in atomic context
[deliverable/linux.git] / fs / ocfs2 / suballoc.c
index 2f19aeec5482106de43b65bc6598c42fb4ed2e63..6ad3533940ba5e9fa32bfe83d3c1acc19b14513a 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,34 @@ 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) {
+                               iput((*ac)->ac_inode);
+                               (*ac)->ac_inode = NULL;
+                               goto retry;
+                       }
+
+                       if (ret < 0)
+                               mlog_errno(ret);
+
+                       inode_lock((*ac)->ac_inode);
+                       ret = ocfs2_inode_lock((*ac)->ac_inode, NULL, 1);
+                       if (ret < 0) {
+                               mlog_errno(ret);
+                               inode_unlock((*ac)->ac_inode);
+                               iput((*ac)->ac_inode);
+                               (*ac)->ac_inode = NULL;
+                               goto bail;
+                       }
+               }
                if (status < 0) {
                        if (status != -ENOSPC)
                                mlog_errno(status);
This page took 0.036979 seconds and 5 git commands to generate.