+ /*
+ * To improve performance of cold-cache inode stats, we take
+ * the cluster lock here if possible.
+ *
+ * Generally, OCFS2 never trusts the contents of an inode
+ * unless it's holding a cluster lock, so taking it here isn't
+ * a correctness issue as much as it is a performance
+ * improvement.
+ *
+ * There are three times when taking the lock is not a good idea:
+ *
+ * 1) During startup, before we have initialized the DLM.
+ *
+ * 2) If we are reading certain system files which never get
+ * cluster locks (local alloc, truncate log).
+ *
+ * 3) If the process doing the iget() is responsible for
+ * orphan dir recovery. We're holding the orphan dir lock and
+ * can get into a deadlock with another process on another
+ * node in ->delete_inode().
+ *
+ * #1 and #2 can be simply solved by never taking the lock
+ * here for system files (which are the only type we read
+ * during mount). It's a heavier approach, but our main
+ * concern is user-accesible files anyway.
+ *
+ * #3 works itself out because we'll eventually take the
+ * cluster lock before trusting anything anyway.
+ */
+ can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
+ && !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK)
+ && !ocfs2_mount_local(osb);
+
+ /*
+ * To maintain backwards compatibility with older versions of
+ * ocfs2-tools, we still store the generation value for system
+ * files. The only ones that actually matter to userspace are
+ * the journals, but it's easier and inexpensive to just flag
+ * all system files similarly.
+ */
+ if (args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
+ generation = osb->fs_generation;
+
+ ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_meta_lockres,
+ OCFS2_LOCK_TYPE_META,
+ generation, inode);
+
+ if (can_lock) {
+ status = ocfs2_meta_lock(inode, NULL, 0);
+ if (status) {
+ make_bad_inode(inode);
+ mlog_errno(status);
+ return status;
+ }
+ }
+
+ status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0,
+ can_lock ? inode : NULL);