Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
48943bf8
Commit
48943bf8
authored
Dec 13, 2004
by
David Woodhouse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
JFFS2 locking fix: Don't hold references to obsolete nodes without lock.
Signed-off-by:
David Woodhouse
<
dwmw2@infradead.org
>
parent
50b8d1dc
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
25 additions
and
13 deletions
+25
-13
fs/jffs2/nodelist.c
fs/jffs2/nodelist.c
+25
-13
No files found.
fs/jffs2/nodelist.c
View file @
48943bf8
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
* For licensing information, see the file 'LICENCE' in this directory.
* For licensing information, see the file 'LICENCE' in this directory.
*
*
* $Id: nodelist.c,v 1.
89 2004/11/28 12:20:35 dedekind
Exp $
* $Id: nodelist.c,v 1.
90 2004/12/08 17:59:20 dwmw2
Exp $
*
*
*/
*/
...
@@ -92,6 +92,17 @@ static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
...
@@ -92,6 +92,17 @@ static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
}
}
}
}
/* Returns first valid node after 'ref'. May return 'ref' */
static
struct
jffs2_raw_node_ref
*
jffs2_first_valid_node
(
struct
jffs2_raw_node_ref
*
ref
)
{
while
(
ref
&&
ref
->
next_in_ino
)
{
if
(
!
ref_obsolete
(
ref
))
return
ref
;
D1
(
printk
(
KERN_DEBUG
"node at 0x%08x is obsoleted. Ignoring.
\n
"
,
ref_offset
(
ref
)));
ref
=
ref
->
next_in_ino
;
}
return
NULL
;
}
/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
with this ino, returning the former in order of version */
with this ino, returning the former in order of version */
...
@@ -101,7 +112,7 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
...
@@ -101,7 +112,7 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
uint32_t
*
highest_version
,
uint32_t
*
latest_mctime
,
uint32_t
*
highest_version
,
uint32_t
*
latest_mctime
,
uint32_t
*
mctime_ver
)
uint32_t
*
mctime_ver
)
{
{
struct
jffs2_raw_node_ref
*
ref
=
f
->
inocache
->
nodes
;
struct
jffs2_raw_node_ref
*
ref
,
*
valid_ref
;
struct
jffs2_tmp_dnode_info
*
tn
,
*
ret_tn
=
NULL
;
struct
jffs2_tmp_dnode_info
*
tn
,
*
ret_tn
=
NULL
;
struct
jffs2_full_dirent
*
fd
,
*
ret_fd
=
NULL
;
struct
jffs2_full_dirent
*
fd
,
*
ret_fd
=
NULL
;
union
jffs2_node_union
node
;
union
jffs2_node_union
node
;
...
@@ -111,22 +122,23 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
...
@@ -111,22 +122,23 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
*
mctime_ver
=
0
;
*
mctime_ver
=
0
;
D1
(
printk
(
KERN_DEBUG
"jffs2_get_inode_nodes(): ino #%u
\n
"
,
f
->
inocache
->
ino
));
D1
(
printk
(
KERN_DEBUG
"jffs2_get_inode_nodes(): ino #%u
\n
"
,
f
->
inocache
->
ino
));
if
(
!
f
->
inocache
->
nodes
)
{
printk
(
KERN_WARNING
"Eep. no nodes for ino #%u
\n
"
,
f
->
inocache
->
ino
);
}
spin_lock
(
&
c
->
erase_completion_lock
);
spin_lock
(
&
c
->
erase_completion_lock
);
for
(
ref
=
f
->
inocache
->
nodes
;
ref
&&
ref
->
next_in_ino
;
ref
=
ref
->
next_in_ino
)
{
valid_ref
=
jffs2_first_valid_node
(
f
->
inocache
->
nodes
);
/* Work out whether it's a data node or a dirent node */
if
(
ref_obsolete
(
ref
))
{
if
(
!
valid_ref
)
/* FIXME: On NAND flash we may need to read these */
printk
(
KERN_WARNING
"Eep. No valid nodes for ino #%u
\n
"
,
f
->
inocache
->
ino
);
D1
(
printk
(
KERN_DEBUG
"node at 0x%08x is obsoleted. Ignoring.
\n
"
,
ref_offset
(
ref
)));
continue
;
while
(
valid_ref
)
{
}
/* We can hold a pointer to a non-obsolete node without the spinlock,
/* We can hold a pointer to a non-obsolete node without the spinlock,
but _obsolete_ nodes may disappear at any time, if the block
but _obsolete_ nodes may disappear at any time, if the block
they're in gets erased */
they're in gets erased. So if we mark 'ref' obsolete while we're
not holding the lock, it can go away immediately. For that reason,
we find the next valid node first, before processing 'ref'.
*/
ref
=
valid_ref
;
valid_ref
=
jffs2_first_valid_node
(
ref
->
next_in_ino
);
spin_unlock
(
&
c
->
erase_completion_lock
);
spin_unlock
(
&
c
->
erase_completion_lock
);
cond_resched
();
cond_resched
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment