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
Kirill Smelkov
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
Show 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