All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans Reiser <reiser@namesys.com>
To: Linus Torvalds <torvalds@transmeta.com>, linux-kernel@vger.kernel.org
Subject: [BK]: reiser4: journal_info sharing 2 of 2
Date: Wed, 16 Oct 2002 19:40:26 +0400	[thread overview]
Message-ID: <3DAD886A.7020308@namesys.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: [PATCH]: [reiser4/2] ->journal_info sharing --]
[-- Type: message/rfc822, Size: 7296 bytes --]

From: Nikita Danilov <Nikita@Namesys.COM>
To: Hans Reiser <Reiser@Namesys.COM>
Subject: [PATCH]: [reiser4/2] ->journal_info sharing
Date: Wed, 16 Oct 2002 18:54:04 +0400
Message-ID: <15789.32140.730305.111433@laputa.namesys.com>

Hello, Linus,

this patch changes declaration of ->journal_info in struct task_struct
and updates the only user (ext3) correspondingly.

->journal_info is supposed to hold some file system data per-thread
per-file-system-invocation. Problem is that it is possible (through VM
call backs or page faults, for example) for invocations of file system
drivers to nest. This patch changes ->journal_info from void * to a
pointer to the struct fs_activation. struct fs_activation contains only
one field ->owner: it can be used by file system to tell whether it can
continue within given "parent" context: generally journalling file
system cannot be called from within different journalling file system,
because of deadlocks.

struct fs_activation will be usually embedded into some file system
specific object (like transaction handle for ext3, or reiser4_context
for, well, reiser4) and it is file system responsibility to save
original value of ->journal_info on entry and restore it on exit.

Also, ->journal_info is renamed to less specific ->fs_context.

Thanks to Stephen Tweedie for useful comments.
Please, apply.

Hans, on behalf of reiser4 team.
diff -X dontdiff -rup bk-linux-2.5/fs/jbd/transaction.c linux-2.5-reiser4/fs/jbd/transaction.c
--- bk-linux-2.5/fs/jbd/transaction.c	Tue Oct 15 13:23:34 2002
+++ linux-2.5-reiser4/fs/jbd/transaction.c	Mon Oct 14 19:46:24 2002
@@ -101,6 +101,7 @@ static int start_this_handle(journal_t *
 
 	jbd_debug(3, "New handle %p going live.\n", handle);
 
+	handle->h_journal = journal;
 repeat:
 
 	lock_journal(journal);
@@ -223,6 +224,23 @@ static handle_t *new_handle(int nblocks)
 }
 
 /*
+ * push @handle into ->fs_context stack
+ */
+static void push_handle(handle_t *handle)
+{
+	handle->h_parent = current->fs_context;
+	current->fs_context = (struct fs_activation *) handle;
+}
+
+/*
+ * pop top of ->fs_context stack
+ */
+static void pop_handle(handle_t *handle)
+{
+	current->fs_context = (struct fs_activation *) handle->h_parent;
+}
+
+/*
  * Obtain a new handle.  
  *
  * We make sure that the transaction can guarantee at least nblocks of
@@ -243,7 +261,7 @@ handle_t *journal_start(journal_t *journ
 	if (!journal)
 		return ERR_PTR(-EROFS);
 
-	if (handle) {
+	if (handle && handle->h_journal == journal) {
 		J_ASSERT(handle->h_transaction->t_journal == journal);
 		handle->h_ref++;
 		return handle;
@@ -253,12 +271,12 @@ handle_t *journal_start(journal_t *journ
 	if (!handle)
 		return ERR_PTR(-ENOMEM);
 
-	current->journal_info = handle;
+	push_handle(handle);
 
 	err = start_this_handle(journal, handle);
 	if (err < 0) {
+		pop_handle(handle);
 		kfree(handle);
-		current->journal_info = NULL;
 		return ERR_PTR(err);
 	}
 
@@ -336,7 +354,7 @@ handle_t *journal_try_start(journal_t *j
 	if (!journal)
 		return ERR_PTR(-EROFS);
 
-	if (handle) {
+	if (handle && handle->h_journal == journal) {
 		jbd_debug(4, "h_ref %d -> %d\n",
 				handle->h_ref,
 				handle->h_ref + 1);
@@ -356,12 +374,12 @@ handle_t *journal_try_start(journal_t *j
 	if (!handle)
 		return ERR_PTR(-ENOMEM);
 
-	current->journal_info = handle;
+	push_handle(handle);
 
 	err = try_start_this_handle(journal, handle);
 	if (err < 0) {
+		pop_handle(handle);
 		kfree(handle);
-		current->journal_info = NULL;
 		return ERR_PTR(err);
 	}
 
@@ -1441,7 +1459,7 @@ int journal_stop(handle_t *handle)
 		} while (old_handle_count != transaction->t_handle_count);
 	}
 
-	current->journal_info = NULL;
+	pop_handle(handle);
 	transaction->t_outstanding_credits -= handle->h_buffer_credits;
 	transaction->t_updates--;
 	if (!transaction->t_updates) {
diff -X dontdiff -rup bk-linux-2.5/include/linux/init_task.h linux-2.5-reiser4/include/linux/init_task.h
--- bk-linux-2.5/include/linux/init_task.h	Mon Sep 30 10:23:33 2002
+++ linux-2.5-reiser4/include/linux/init_task.h	Mon Oct 14 18:41:55 2002
@@ -95,7 +95,7 @@
 	.blocked	= {{0}},					\
 	.alloc_lock	= SPIN_LOCK_UNLOCKED,				\
 	.switch_lock	= SPIN_LOCK_UNLOCKED,				\
-	.journal_info	= NULL,						\
+	.fs_context	= NULL,				\
 }
 
 
diff -X dontdiff -rup bk-linux-2.5/include/linux/jbd.h linux-2.5-reiser4/include/linux/jbd.h
--- bk-linux-2.5/include/linux/jbd.h	Sun Oct 13 03:01:04 2002
+++ linux-2.5-reiser4/include/linux/jbd.h	Mon Oct 14 19:01:18 2002
@@ -274,6 +274,14 @@ struct jbd_revoke_table_s;
 
 struct handle_s 
 {
+	/* Which journal this handle belongs to.  This has to be first
+	 * field, because current->fs_context points here. */
+	journal_t             * h_journal;
+
+	/* Previous file system context. NULL if we are top-most
+	 * call. */
+	struct fs_activation  * h_parent;
+
 	/* Which compound transaction is this update a part of? */
 	transaction_t	      * h_transaction;
 
@@ -637,7 +645,7 @@ static inline void unlock_journal(journa
 
 static inline handle_t *journal_current_handle(void)
 {
-	return current->journal_info;
+	return (handle_t*) current->fs_context;
 }
 
 /* The journaling code user interface:
diff -X dontdiff -rup bk-linux-2.5/include/linux/mm.h linux-2.5-reiser4/include/linux/mm.h
--- bk-linux-2.5/include/linux/sched.h	Fri Oct  4 03:00:47 2002
+++ linux-2.5-reiser4/include/linux/sched.h	Mon Oct 14 18:39:18 2002
@@ -278,6 +278,24 @@ extern struct user_struct root_user;
 typedef struct prio_array prio_array_t;
 struct backing_dev_info;
 
+/*
+ * Some file systems need context associated with current thread during
+ * one system call (transaction handle, for example). This context in
+ * attached to current->fs_context.
+ *
+ * As it is possible for file system calls to nest (through quota of VM
+ * call backs), every file system using current->fs_context should store
+ * original ->fs_context value of entrance and restore in on exit.
+ */
+struct fs_activation {
+	/*
+	 * cookie allowing to distinguish file system instances
+	 * (mounts). Usually this is pointer to the super block, but not
+	 * necessary. This is used to tell reentrance.
+	 */
+	void *owner;
+};
+
 struct task_struct {
 	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
 	struct thread_info *thread_info;
@@ -397,8 +415,8 @@ struct task_struct {
 /* context-switch lock */
 	spinlock_t switch_lock;
 
-/* journalling filesystem info */
-	void *journal_info;
+/* info about current file system activation */
+	struct fs_activation *fs_context;
 	struct dentry *proc_dentry;
 	struct backing_dev_info *backing_dev_info;
 };




                 reply	other threads:[~2002-10-16 15:34 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3DAD886A.7020308@namesys.com \
    --to=reiser@namesys.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.