get rid of S_BIAS
[safe/jmp/linux-2.6] / fs / ocfs2 / journal.c
index 4a3b9e6..47878cf 100644 (file)
@@ -48,6 +48,7 @@
 #include "slot_map.h"
 #include "super.h"
 #include "sysfile.h"
+#include "uptodate.h"
 #include "quota.h"
 
 #include "buffer_head_io.h"
@@ -401,9 +402,7 @@ int ocfs2_commit_trans(struct ocfs2_super *osb,
 }
 
 /*
- * 'nblocks' is what you want to add to the current
- * transaction. extend_trans will either extend the current handle by
- * nblocks, or commit it and start a new one with nblocks credits.
+ * 'nblocks' is what you want to add to the current transaction.
  *
  * This might call jbd2_journal_restart() which will commit dirty buffers
  * and then restart the transaction. Before calling
@@ -421,11 +420,15 @@ int ocfs2_commit_trans(struct ocfs2_super *osb,
  */
 int ocfs2_extend_trans(handle_t *handle, int nblocks)
 {
-       int status;
+       int status, old_nblocks;
 
        BUG_ON(!handle);
-       BUG_ON(!nblocks);
+       BUG_ON(nblocks < 0);
+
+       if (!nblocks)
+               return 0;
 
+       old_nblocks = handle->h_buffer_credits;
        mlog_entry_void();
 
        mlog(0, "Trying to extend transaction by %d blocks\n", nblocks);
@@ -444,7 +447,8 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks)
                mlog(0,
                     "jbd2_journal_extend failed, trying "
                     "jbd2_journal_restart\n");
-               status = jbd2_journal_restart(handle, nblocks);
+               status = jbd2_journal_restart(handle,
+                                             old_nblocks + nblocks);
                if (status < 0) {
                        mlog_errno(status);
                        goto bail;
@@ -554,6 +558,14 @@ static struct ocfs2_triggers eb_triggers = {
        .ot_offset      = offsetof(struct ocfs2_extent_block, h_check),
 };
 
+static struct ocfs2_triggers rb_triggers = {
+       .ot_triggers = {
+               .t_commit = ocfs2_commit_trigger,
+               .t_abort = ocfs2_abort_trigger,
+       },
+       .ot_offset      = offsetof(struct ocfs2_refcount_block, rf_check),
+};
+
 static struct ocfs2_triggers gd_triggers = {
        .ot_triggers = {
                .t_commit = ocfs2_commit_trigger,
@@ -601,14 +613,16 @@ static struct ocfs2_triggers dl_triggers = {
 };
 
 static int __ocfs2_journal_access(handle_t *handle,
-                                 struct inode *inode,
+                                 struct ocfs2_caching_info *ci,
                                  struct buffer_head *bh,
                                  struct ocfs2_triggers *triggers,
                                  int type)
 {
        int status;
+       struct ocfs2_super *osb =
+               OCFS2_SB(ocfs2_metadata_cache_get_super(ci));
 
-       BUG_ON(!inode);
+       BUG_ON(!ci || !ci->ci_ops);
        BUG_ON(!handle);
        BUG_ON(!bh);
 
@@ -627,15 +641,15 @@ static int __ocfs2_journal_access(handle_t *handle,
                BUG();
        }
 
-       /* Set the current transaction information on the inode so
+       /* Set the current transaction information on the ci so
         * that the locking code knows whether it can drop it's locks
-        * on this inode or not. We're protected from the commit
+        * on this ci or not. We're protected from the commit
         * thread updating the current transaction id until
         * ocfs2_commit_trans() because ocfs2_start_trans() took
         * j_trans_barrier for us. */
-       ocfs2_set_inode_lock_trans(OCFS2_SB(inode->i_sb)->journal, inode);
+       ocfs2_set_ci_lock_trans(osb->journal, ci);
 
-       mutex_lock(&OCFS2_I(inode)->ip_io_mutex);
+       ocfs2_metadata_cache_io_lock(ci);
        switch (type) {
        case OCFS2_JOURNAL_ACCESS_CREATE:
        case OCFS2_JOURNAL_ACCESS_WRITE:
@@ -648,11 +662,11 @@ static int __ocfs2_journal_access(handle_t *handle,
 
        default:
                status = -EINVAL;
-               mlog(ML_ERROR, "Uknown access type!\n");
+               mlog(ML_ERROR, "Unknown access type!\n");
        }
-       if (!status && ocfs2_meta_ecc(OCFS2_SB(inode->i_sb)) && triggers)
+       if (!status && ocfs2_meta_ecc(osb) && triggers)
                jbd2_journal_set_triggers(bh, &triggers->ot_triggers);
-       mutex_unlock(&OCFS2_I(inode)->ip_io_mutex);
+       ocfs2_metadata_cache_io_unlock(ci);
 
        if (status < 0)
                mlog(ML_ERROR, "Error %d getting %d access to buffer!\n",
@@ -662,70 +676,68 @@ static int __ocfs2_journal_access(handle_t *handle,
        return status;
 }
 
-int ocfs2_journal_access_di(handle_t *handle, struct inode *inode,
-                              struct buffer_head *bh, int type)
+int ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci,
+                           struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &di_triggers,
-                                     type);
+       return __ocfs2_journal_access(handle, ci, bh, &di_triggers, type);
 }
 
-int ocfs2_journal_access_eb(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci,
                            struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &eb_triggers,
-                                     type);
+       return __ocfs2_journal_access(handle, ci, bh, &eb_triggers, type);
 }
 
-int ocfs2_journal_access_gd(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci,
                            struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &gd_triggers,
+       return __ocfs2_journal_access(handle, ci, bh, &rb_triggers,
                                      type);
 }
 
-int ocfs2_journal_access_db(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci,
                            struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &db_triggers,
-                                     type);
+       return __ocfs2_journal_access(handle, ci, bh, &gd_triggers, type);
 }
 
-int ocfs2_journal_access_xb(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci,
                            struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &xb_triggers,
-                                     type);
+       return __ocfs2_journal_access(handle, ci, bh, &db_triggers, type);
 }
 
-int ocfs2_journal_access_dq(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci,
                            struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &dq_triggers,
-                                     type);
+       return __ocfs2_journal_access(handle, ci, bh, &xb_triggers, type);
 }
 
-int ocfs2_journal_access_dr(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci,
                            struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &dr_triggers,
-                                     type);
+       return __ocfs2_journal_access(handle, ci, bh, &dq_triggers, type);
 }
 
-int ocfs2_journal_access_dl(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci,
                            struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, &dl_triggers,
-                                     type);
+       return __ocfs2_journal_access(handle, ci, bh, &dr_triggers, type);
 }
 
-int ocfs2_journal_access(handle_t *handle, struct inode *inode,
+int ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci,
+                           struct buffer_head *bh, int type)
+{
+       return __ocfs2_journal_access(handle, ci, bh, &dl_triggers, type);
+}
+
+int ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci,
                         struct buffer_head *bh, int type)
 {
-       return __ocfs2_journal_access(handle, inode, bh, NULL, type);
+       return __ocfs2_journal_access(handle, ci, bh, NULL, type);
 }
 
-int ocfs2_journal_dirty(handle_t *handle,
-                       struct buffer_head *bh)
+void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh)
 {
        int status;
 
@@ -733,13 +745,9 @@ int ocfs2_journal_dirty(handle_t *handle,
                   (unsigned long long)bh->b_blocknr);
 
        status = jbd2_journal_dirty_metadata(handle, bh);
-       if (status < 0)
-               mlog(ML_ERROR, "Could not dirty metadata buffer. "
-                    "(bh->b_blocknr=%llu)\n",
-                    (unsigned long long)bh->b_blocknr);
+       BUG_ON(status);
 
-       mlog_exit(status);
-       return status;
+       mlog_exit_void();
 }
 
 #define OCFS2_DEFAULT_COMMIT_INTERVAL  (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE)
@@ -898,7 +906,7 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
                ocfs2_bump_recovery_generation(fe);
 
        ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
-       status = ocfs2_write_block(osb, bh, journal->j_inode);
+       status = ocfs2_write_block(osb, bh, INODE_CACHE(journal->j_inode));
        if (status < 0)
                mlog_errno(status);
 
@@ -1642,7 +1650,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
                                        ocfs2_get_recovery_generation(fe);
 
        ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
-       status = ocfs2_write_block(osb, bh, inode);
+       status = ocfs2_write_block(osb, bh, INODE_CACHE(inode));
        if (status < 0)
                mlog_errno(status);
 
@@ -1880,13 +1888,20 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
 
        os = &osb->osb_orphan_scan;
 
-       status = ocfs2_orphan_scan_lock(osb, &seqno, DLM_LOCK_EX);
+       if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
+               goto out;
+
+       status = ocfs2_orphan_scan_lock(osb, &seqno);
        if (status < 0) {
                if (status != -EAGAIN)
                        mlog_errno(status);
                goto out;
        }
 
+       /* Do no queue the tasks if the volume is being umounted */
+       if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
+               goto unlock;
+
        if (os->os_seqno != seqno) {
                os->os_seqno = seqno;
                goto unlock;
@@ -1903,7 +1918,7 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
        os->os_count++;
        os->os_scantime = CURRENT_TIME;
 unlock:
-       ocfs2_orphan_scan_unlock(osb, seqno, DLM_LOCK_EX);
+       ocfs2_orphan_scan_unlock(osb, seqno);
 out:
        return;
 }
@@ -1920,8 +1935,9 @@ void ocfs2_orphan_scan_work(struct work_struct *work)
 
        mutex_lock(&os->os_lock);
        ocfs2_queue_orphan_scan(osb);
-       schedule_delayed_work(&os->os_orphan_scan_work,
-                             ocfs2_orphan_scan_timeout());
+       if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE)
+               schedule_delayed_work(&os->os_orphan_scan_work,
+                                     ocfs2_orphan_scan_timeout());
        mutex_unlock(&os->os_lock);
 }
 
@@ -1930,26 +1946,39 @@ void ocfs2_orphan_scan_stop(struct ocfs2_super *osb)
        struct ocfs2_orphan_scan *os;
 
        os = &osb->osb_orphan_scan;
-       mutex_lock(&os->os_lock);
-       cancel_delayed_work(&os->os_orphan_scan_work);
-       mutex_unlock(&os->os_lock);
+       if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) {
+               atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
+               mutex_lock(&os->os_lock);
+               cancel_delayed_work(&os->os_orphan_scan_work);
+               mutex_unlock(&os->os_lock);
+       }
 }
 
-int ocfs2_orphan_scan_init(struct ocfs2_super *osb)
+void ocfs2_orphan_scan_init(struct ocfs2_super *osb)
 {
        struct ocfs2_orphan_scan *os;
 
        os = &osb->osb_orphan_scan;
        os->os_osb = osb;
        os->os_count = 0;
-       os->os_scantime = CURRENT_TIME;
+       os->os_seqno = 0;
        mutex_init(&os->os_lock);
+       INIT_DELAYED_WORK(&os->os_orphan_scan_work, ocfs2_orphan_scan_work);
+}
 
-       INIT_DELAYED_WORK(&os->os_orphan_scan_work,
-                         ocfs2_orphan_scan_work);
-       schedule_delayed_work(&os->os_orphan_scan_work,
-                             ocfs2_orphan_scan_timeout());
-       return 0;
+void ocfs2_orphan_scan_start(struct ocfs2_super *osb)
+{
+       struct ocfs2_orphan_scan *os;
+
+       os = &osb->osb_orphan_scan;
+       os->os_scantime = CURRENT_TIME;
+       if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb))
+               atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
+       else {
+               atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE);
+               schedule_delayed_work(&os->os_orphan_scan_work,
+                                     ocfs2_orphan_scan_timeout());
+       }
 }
 
 struct ocfs2_orphan_filldir_priv {
@@ -2003,7 +2032,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
                status = -ENOENT;
                mlog_errno(status);
                return status;
-       }       
+       }
 
        mutex_lock(&orphan_dir_inode->i_mutex);
        status = ocfs2_inode_lock(orphan_dir_inode, NULL, 0);