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
3aa8e204
Commit
3aa8e204
authored
Sep 26, 2002
by
Dave Kleikamp
Browse files
Options
Browse Files
Download
Plain Diff
Merge jfs@jfs.bkbits.net:linux-2.5
into kleikamp.austin.ibm.com:/home/shaggy/bk/jfs-2.5
parents
14fc589b
b275001f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
189 additions
and
50 deletions
+189
-50
fs/jfs/jfs_dtree.c
fs/jfs/jfs_dtree.c
+181
-40
fs/jfs/jfs_imap.c
fs/jfs/jfs_imap.c
+2
-9
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.c
+6
-1
No files found.
fs/jfs/jfs_dtree.c
View file @
3aa8e204
...
...
@@ -2830,6 +2830,86 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
return
;
}
/*
* add_missing_indices()
*
* function: Fix dtree page in which one or more entries has an invalid index.
* fsck.jfs should really fix this, but it currently does not.
* Called from jfs_readdir when bad index is detected.
*/
static
void
add_missing_indices
(
struct
inode
*
inode
,
s64
bn
)
{
struct
ldtentry
*
d
;
struct
dt_lock
*
dtlck
;
int
i
;
uint
index
;
struct
lv
*
lv
;
struct
metapage
*
mp
;
dtpage_t
*
p
;
int
rc
;
s8
*
stbl
;
tid_t
tid
;
struct
tlock
*
tlck
;
tid
=
txBegin
(
inode
->
i_sb
,
0
);
DT_GETPAGE
(
inode
,
bn
,
mp
,
PSIZE
,
p
,
rc
);
if
(
rc
)
{
printk
(
KERN_ERR
"DT_GETPAGE failed!
\n
"
);
goto
end
;
}
BT_MARK_DIRTY
(
mp
,
inode
);
ASSERT
(
p
->
header
.
flag
&
BT_LEAF
);
tlck
=
txLock
(
tid
,
inode
,
mp
,
tlckDTREE
|
tlckENTRY
);
dtlck
=
(
struct
dt_lock
*
)
&
tlck
->
lock
;
stbl
=
DT_GETSTBL
(
p
);
for
(
i
=
0
;
i
<
p
->
header
.
nextindex
;
i
++
)
{
d
=
(
struct
ldtentry
*
)
&
p
->
slot
[
stbl
[
i
]];
index
=
le32_to_cpu
(
d
->
index
);
if
((
index
<
2
)
||
(
index
>=
JFS_IP
(
inode
)
->
next_index
))
{
d
->
index
=
cpu_to_le32
(
add_index
(
tid
,
inode
,
bn
,
i
));
if
(
dtlck
->
index
>=
dtlck
->
maxcnt
)
dtlck
=
(
struct
dt_lock
*
)
txLinelock
(
dtlck
);
lv
=
dtlck
->
lv
;
lv
->
offset
=
stbl
[
i
];
lv
->
length
=
1
;
dtlck
->
index
++
;
}
}
DT_PUTPAGE
(
mp
);
(
void
)
txCommit
(
tid
,
1
,
&
inode
,
0
);
end:
txEnd
(
tid
);
}
/*
* Buffer to hold directory entry info while traversing a dtree page
* before being fed to the filldir function
*/
struct
jfs_dirent
{
loff_t
position
;
int
ino
;
u16
name_len
;
char
name
[
0
];
};
/*
* function to determine next variable-sized jfs_dirent in buffer
*/
inline
struct
jfs_dirent
*
next_jfs_dirent
(
struct
jfs_dirent
*
dirent
)
{
return
(
struct
jfs_dirent
*
)
((
char
*
)
dirent
+
((
sizeof
(
struct
jfs_dirent
)
+
dirent
->
name_len
+
1
+
sizeof
(
loff_t
)
-
1
)
&
~
(
sizeof
(
loff_t
)
-
1
)));
}
/*
* jfs_readdir()
*
...
...
@@ -2846,11 +2926,12 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct
inode
*
ip
=
filp
->
f_dentry
->
d_inode
;
struct
nls_table
*
codepage
=
JFS_SBI
(
ip
->
i_sb
)
->
nls_tab
;
int
rc
=
0
;
loff_t
dtpos
;
/* legacy OS/2 style position */
struct
dtoffset
{
s16
pn
;
s16
index
;
s32
unused
;
}
*
dtoffset
=
(
struct
dtoffset
*
)
&
filp
->
f_
pos
;
}
*
dtoffset
=
(
struct
dtoffset
*
)
&
dt
pos
;
s64
bn
;
struct
metapage
*
mp
;
dtpage_t
*
p
;
...
...
@@ -2860,12 +2941,17 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
int
i
,
next
;
struct
ldtentry
*
d
;
struct
dtslot
*
t
;
int
d_namleft
,
d_namlen
,
len
,
outlen
;
char
*
d_name
,
*
name_ptr
;
int
d_namleft
,
len
,
outlen
;
unsigned
long
dirent_buf
;
char
*
name_ptr
;
int
dtlhdrdatalen
;
u32
dir_index
;
int
do_index
=
0
;
uint
loop_count
=
0
;
struct
jfs_dirent
*
jfs_dirent
;
int
jfs_dirents
;
int
overflow
,
fix_page
,
page_fixed
=
0
;
static
int
unique_pos
=
2
;
/* If we can't fix broken index */
if
(
filp
->
f_pos
==
DIREND
)
return
0
;
...
...
@@ -2885,7 +2971,9 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if
(
dir_index
>
1
)
{
struct
dir_table_slot
dirtab_slot
;
if
(
dtEmpty
(
ip
))
{
if
(
dtEmpty
(
ip
)
||
(
dir_index
>=
JFS_IP
(
ip
)
->
next_index
))
{
/* Stale position. Directory has shrunk */
filp
->
f_pos
=
DIREND
;
return
0
;
}
...
...
@@ -2963,13 +3051,15 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
*/
dtlhdrdatalen
=
DTLHDRDATALEN_LEGACY
;
if
(
filp
->
f_pos
==
0
)
{
dtpos
=
filp
->
f_pos
;
if
(
dtpos
==
0
)
{
/* build "." entry */
if
(
filldir
(
dirent
,
"."
,
1
,
filp
->
f_pos
,
ip
->
i_ino
,
DT_DIR
))
return
0
;
dtoffset
->
index
=
1
;
filp
->
f_pos
=
dtpos
;
}
if
(
dtoffset
->
pn
==
0
)
{
...
...
@@ -2985,6 +3075,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
dtoffset
->
pn
=
1
;
dtoffset
->
index
=
0
;
filp
->
f_pos
=
dtpos
;
}
if
(
dtEmpty
(
ip
))
{
...
...
@@ -3009,32 +3100,72 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
}
d
_name
=
kmalloc
((
JFS_NAME_MAX
+
1
)
*
sizeof
(
wchar_t
),
GFP_NOFS
);
if
(
d
_name
==
NULL
)
{
d
irent_buf
=
__get_free_page
(
GFP_KERNEL
);
if
(
d
irent_buf
==
0
)
{
DT_PUTPAGE
(
mp
);
jERROR
(
1
,
(
"jfs_readdir:
kmalloc
failed!
\n
"
));
jERROR
(
1
,
(
"jfs_readdir:
__get_free_page
failed!
\n
"
));
filp
->
f_pos
=
DIREND
;
return
0
;
return
-
ENOMEM
;
}
while
(
1
)
{
jfs_dirent
=
(
struct
jfs_dirent
*
)
dirent_buf
;
jfs_dirents
=
0
;
overflow
=
fix_page
=
0
;
stbl
=
DT_GETSTBL
(
p
);
for
(
i
=
index
;
i
<
p
->
header
.
nextindex
;
i
++
)
{
d
=
(
struct
ldtentry
*
)
&
p
->
slot
[
stbl
[
i
]];
if
(((
long
)
jfs_dirent
+
d
->
namlen
+
1
)
>
(
dirent_buf
+
PSIZE
))
{
/* DBCS codepages could overrun dirent_buf */
index
=
i
;
overflow
=
1
;
break
;
}
d_namleft
=
d
->
namlen
;
name_ptr
=
d_name
;
name_ptr
=
jfs_dirent
->
name
;
jfs_dirent
->
ino
=
le32_to_cpu
(
d
->
inumber
);
if
(
do_index
)
{
filp
->
f_pos
=
le32_to_cpu
(
d
->
index
);
len
=
min
(
d_namleft
,
DTLHDRDATALEN
);
}
else
jfs_dirent
->
position
=
le32_to_cpu
(
d
->
index
);
/*
* d->index should always be valid, but it
* isn't. fsck.jfs doesn't create the
* directory index for the lost+found
* directory. Rather than let it go,
* we can try to fix it.
*/
if
((
jfs_dirent
->
position
<
2
)
||
(
jfs_dirent
->
position
>=
JFS_IP
(
ip
)
->
next_index
))
{
if
(
!
page_fixed
&&
!
isReadOnly
(
ip
))
{
fix_page
=
1
;
/*
* setting overflow and setting
* index to i will cause the
* same page to be processed
* again starting here
*/
overflow
=
1
;
index
=
i
;
break
;
}
jfs_dirent
->
position
=
unique_pos
++
;
}
}
else
{
jfs_dirent
->
position
=
dtpos
;
len
=
min
(
d_namleft
,
DTLHDRDATALEN_LEGACY
);
}
/* copy the name of head/only segment */
outlen
=
jfs_strfromUCS_le
(
name_ptr
,
d
->
name
,
len
,
codepage
);
d_nam
len
=
outlen
;
jfs_dirent
->
name_
len
=
outlen
;
/* copy name in the additional segment(s) */
next
=
d
->
next
;
...
...
@@ -3053,56 +3184,66 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
len
=
min
(
d_namleft
,
DTSLOTDATALEN
);
outlen
=
jfs_strfromUCS_le
(
name_ptr
,
t
->
name
,
len
,
codepage
);
d_namlen
+=
outlen
;
jfs_dirent
->
name_len
+=
outlen
;
next
=
t
->
next
;
}
if
(
filldir
(
dirent
,
d_name
,
d_namlen
,
filp
->
f_pos
,
le32_to_cpu
(
d
->
inumber
),
DT_UNKNOWN
))
goto
out
;
jfs_dirents
++
;
jfs_dirent
=
next_jfs_dirent
(
jfs_dirent
);
skip_one:
if
(
!
do_index
)
dtoffset
->
index
++
;
}
/*
* get next leaf page
*/
if
(
!
overflow
)
{
/* Point to next leaf page */
if
(
p
->
header
.
flag
&
BT_ROOT
)
bn
=
0
;
else
{
bn
=
le64_to_cpu
(
p
->
header
.
next
);
index
=
0
;
/* update offset (pn:index) for new page */
if
(
!
do_index
)
{
dtoffset
->
pn
++
;
dtoffset
->
index
=
0
;
}
}
page_fixed
=
0
;
}
if
(
p
->
header
.
flag
&
BT_ROOT
)
{
filp
->
f_pos
=
DIREND
;
break
;
/* unpin previous leaf page */
DT_PUTPAGE
(
mp
);
jfs_dirent
=
(
struct
jfs_dirent
*
)
dirent_buf
;
while
(
jfs_dirents
--
)
{
filp
->
f_pos
=
jfs_dirent
->
position
;
if
(
filldir
(
dirent
,
jfs_dirent
->
name
,
jfs_dirent
->
name_len
,
filp
->
f_pos
,
jfs_dirent
->
ino
,
DT_UNKNOWN
))
goto
out
;
jfs_dirent
=
next_jfs_dirent
(
jfs_dirent
);
}
bn
=
le64_to_cpu
(
p
->
header
.
next
);
if
(
bn
==
0
)
{
if
(
fix_page
)
{
add_missing_indices
(
ip
,
bn
);
page_fixed
=
1
;
}
if
(
!
overflow
&&
(
bn
==
0
))
{
filp
->
f_pos
=
DIREND
;
break
;
}
/* unpin previous leaf page */
DT_PUTPAGE
(
mp
);
/* get next leaf page */
DT_GETPAGE
(
ip
,
bn
,
mp
,
PSIZE
,
p
,
rc
);
if
(
rc
)
{
kfree
(
d_name
);
free_page
(
dirent_buf
);
return
-
rc
;
}
/* update offset (pn:index) for new page */
index
=
0
;
if
(
!
do_index
)
{
dtoffset
->
pn
++
;
dtoffset
->
index
=
0
;
}
}
out:
kfree
(
d_name
);
DT_PUTPAGE
(
mp
);
free_page
(
dirent_buf
);
return
rc
;
}
...
...
fs/jfs/jfs_imap.c
View file @
3aa8e204
...
...
@@ -365,11 +365,7 @@ int diRead(struct inode *ip)
if
((
lengthPXD
(
&
iagp
->
inoext
[
extno
])
!=
imap
->
im_nbperiext
)
||
(
addressPXD
(
&
iagp
->
inoext
[
extno
])
==
0
))
{
jERROR
(
1
,
(
"diRead: Bad inoext: 0x%lx, 0x%lx
\n
"
,
(
ulong
)
addressPXD
(
&
iagp
->
inoext
[
extno
]),
(
ulong
)
lengthPXD
(
&
iagp
->
inoext
[
extno
])));
release_metapage
(
mp
);
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
return
ESTALE
;
}
...
...
@@ -416,12 +412,9 @@ int diRead(struct inode *ip)
jERROR
(
1
,
(
"diRead: i_ino != di_number
\n
"
));
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
rc
=
EIO
;
}
else
if
(
le32_to_cpu
(
dp
->
di_nlink
)
==
0
)
{
jERROR
(
1
,
(
"diRead: di_nlink is zero. ino=%ld
\n
"
,
ip
->
i_ino
));
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
}
else
if
(
le32_to_cpu
(
dp
->
di_nlink
)
==
0
)
rc
=
ESTALE
;
}
else
else
/* copy the disk inode to the in-memory inode */
rc
=
copy_from_dinode
(
dp
,
ip
);
...
...
fs/jfs/jfs_logmgr.c
View file @
3aa8e204
...
...
@@ -1552,7 +1552,12 @@ static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate)
memcpy
(
logsuper
->
active
[
i
].
uuid
,
NULL_UUID
,
16
);
break
;
}
assert
(
i
<
MAX_ACTIVE
);
if
(
i
==
MAX_ACTIVE
)
{
jERROR
(
1
,(
"Somebody stomped on the journal!
\n
"
));
lbmFree
(
bpsuper
);
return
EIO
;
}
}
/*
...
...
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