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
1ec23637
Commit
1ec23637
authored
Oct 08, 2003
by
Dave Kleikamp
Browse files
Options
Browse Files
Download
Plain Diff
Merge jfs@jfs.bkbits.net:linux-2.5
into shaggy.austin.ibm.com:/home/shaggy/bk/jfs-2.5
parents
2ea73f8a
6349fc5a
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
466 additions
and
209 deletions
+466
-209
Documentation/filesystems/jfs.txt
Documentation/filesystems/jfs.txt
+4
-0
fs/jfs/file.c
fs/jfs/file.c
+5
-3
fs/jfs/inode.c
fs/jfs/inode.c
+7
-3
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.c
+105
-64
fs/jfs/jfs_dtree.c
fs/jfs/jfs_dtree.c
+9
-10
fs/jfs/jfs_extent.c
fs/jfs/jfs_extent.c
+6
-3
fs/jfs/jfs_filsys.h
fs/jfs/jfs_filsys.h
+6
-1
fs/jfs/jfs_imap.c
fs/jfs/jfs_imap.c
+142
-63
fs/jfs/jfs_metapage.c
fs/jfs/jfs_metapage.c
+16
-6
fs/jfs/jfs_superblock.h
fs/jfs/jfs_superblock.h
+2
-1
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.c
+4
-5
fs/jfs/jfs_xtree.c
fs/jfs/jfs_xtree.c
+65
-37
fs/jfs/namei.c
fs/jfs/namei.c
+14
-3
fs/jfs/resize.c
fs/jfs/resize.c
+2
-2
fs/jfs/super.c
fs/jfs/super.c
+68
-4
fs/jfs/xattr.c
fs/jfs/xattr.c
+11
-4
No files found.
Documentation/filesystems/jfs.txt
View file @
1ec23637
...
...
@@ -32,6 +32,10 @@ integrity Default. Commit metadata changes to the journal. Use this
option to remount a volume where the nointegrity option was
previously specified in order to restore normal behavior.
errors=continue Keep going on a filesystem error.
errors=remount-ro Default. Remount the filesystem read-only on an error.
errors=panic Panic and halt the machine if an error occurs.
JFS TODO list:
Plans for our near term development items
...
...
fs/jfs/file.c
View file @
1ec23637
...
...
@@ -34,10 +34,12 @@ int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
struct
inode
*
inode
=
dentry
->
d_inode
;
int
rc
=
0
;
if
(
!
(
inode
->
i_state
&
I_DIRTY
))
return
rc
;
if
(
datasync
&&
!
(
inode
->
i_state
&
I_DIRTY_DATASYNC
))
if
(
!
(
inode
->
i_state
&
I_DIRTY
)
||
(
datasync
&&
!
(
inode
->
i_state
&
I_DIRTY_DATASYNC
)))
{
/* Make sure committed changes hit the disk */
jfs_flush_journal
(
JFS_SBI
(
inode
->
i_sb
)
->
log
,
1
);
return
rc
;
}
rc
|=
jfs_commit_inode
(
inode
,
1
);
...
...
fs/jfs/inode.c
View file @
1ec23637
...
...
@@ -107,14 +107,18 @@ int jfs_commit_inode(struct inode *inode, int wait)
void
jfs_write_inode
(
struct
inode
*
inode
,
int
wait
)
{
if
(
test_cflag
(
COMMIT_Nolink
,
inode
))
return
;
/*
* If COMMIT_DIRTY is not set, the inode isn't really dirty.
* It has been committed since the last change, but was still
* on the dirty inode list
* on the dirty inode list
.
*/
if
(
test_cflag
(
COMMIT_Nolink
,
inode
)
||
!
test_cflag
(
COMMIT_Dirty
,
inode
))
if
(
!
test_cflag
(
COMMIT_Dirty
,
inode
))
{
/* Make sure committed changes hit the disk */
jfs_flush_journal
(
JFS_SBI
(
inode
->
i_sb
)
->
log
,
wait
);
return
;
}
if
(
jfs_commit_inode
(
inode
,
wait
))
{
jfs_err
(
"jfs_write_inode: jfs_commit_inode failed!"
);
...
...
fs/jfs/jfs_dmap.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -18,6 +18,7 @@
#include <linux/fs.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
#include "jfs_imap.h"
#include "jfs_lock.h"
...
...
@@ -134,7 +135,6 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
static
int
dbMaxBud
(
u8
*
cp
);
s64
dbMapFileSizeToMapSize
(
struct
inode
*
ipbmap
);
int
blkstol2
(
s64
nb
);
void
fsDirty
(
void
);
int
cntlz
(
u32
value
);
int
cnttz
(
u32
word
);
...
...
@@ -382,7 +382,15 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
IREAD_LOCK
(
ipbmap
);
/* block to be freed better be within the mapsize. */
assert
(
blkno
+
nblocks
<=
bmp
->
db_mapsize
);
if
(
blkno
+
nblocks
>
bmp
->
db_mapsize
)
{
IREAD_UNLOCK
(
ipbmap
);
printk
(
KERN_ERR
"blkno = %Lx, nblocks = %Lx
\n
"
,
(
unsigned
long
long
)
blkno
,
(
unsigned
long
long
)
nblocks
);
jfs_error
(
ip
->
i_sb
,
"dbFree: block to be freed is outside the map"
);
return
-
EIO
;
}
/*
* free the blocks a dmap at a time.
...
...
@@ -465,7 +473,14 @@ dbUpdatePMap(struct inode *ipbmap,
int
lsn
,
difft
,
diffp
;
/* the blocks better be within the mapsize. */
assert
(
blkno
+
nblocks
<=
bmp
->
db_mapsize
);
if
(
blkno
+
nblocks
>
bmp
->
db_mapsize
)
{
printk
(
KERN_ERR
"blkno = %Lx, nblocks = %Lx
\n
"
,
(
unsigned
long
long
)
blkno
,
(
unsigned
long
long
)
nblocks
);
jfs_error
(
ipbmap
->
i_sb
,
"dbUpdatePMap: blocks are outside the map"
);
return
-
EIO
;
}
/* compute delta of transaction lsn from log syncpt */
lsn
=
tblk
->
lsn
;
...
...
@@ -757,7 +772,10 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
mapSize
=
bmp
->
db_mapsize
;
/* the hint should be within the map */
assert
(
hint
<
mapSize
);
if
(
hint
>=
mapSize
)
{
jfs_error
(
ip
->
i_sb
,
"dbAlloc: the hint is outside the map"
);
return
-
EIO
;
}
/* if the number of blocks to be allocated is greater than the
* allocation group size, try to allocate anywhere.
...
...
@@ -1104,7 +1122,12 @@ int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
/* better be within the file system */
bmp
=
sbi
->
bmap
;
assert
(
lastblkno
>=
0
&&
lastblkno
<
bmp
->
db_mapsize
);
if
(
lastblkno
<
0
||
lastblkno
>=
bmp
->
db_mapsize
)
{
IREAD_UNLOCK
(
ipbmap
);
jfs_error
(
ip
->
i_sb
,
"dbExtend: the block is outside the filesystem"
);
return
-
EIO
;
}
/* we'll attempt to extend the current allocation in place by
* allocating the additional blocks as the blocks immediately
...
...
@@ -1145,11 +1168,10 @@ int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
DBALLOC
(
bmp
->
db_DBmap
,
bmp
->
db_mapsize
,
extblkno
,
addnblocks
);
write_metapage
(
mp
);
}
else
{
}
else
/* we were not successful */
release_metapage
(
mp
);
assert
(
rc
==
-
ENOSPC
||
rc
==
-
EIO
);
}
return
(
rc
);
}
...
...
@@ -1414,7 +1436,12 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
/* allocation request should not be for more than the
* allocation group size.
*/
assert
(
l2nb
<=
bmp
->
db_agl2size
);
if
(
l2nb
>
bmp
->
db_agl2size
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocAG: allocation request is larger than the "
"allocation group size"
);
return
-
EIO
;
}
/* determine the starting block number of the allocation
* group.
...
...
@@ -1441,13 +1468,13 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
if
(
bmp
->
db_agsize
==
BPERDMAP
||
bmp
->
db_agfree
[
agno
]
==
bmp
->
db_agsize
)
{
rc
=
dbAllocCtl
(
bmp
,
nblocks
,
l2nb
,
blkno
,
results
);
/* assert(!(rc == -ENOSPC && bmp->db_agfree[agno] == bmp->db_agsize)); */
if
((
rc
==
-
ENOSPC
)
&&
(
bmp
->
db_agfree
[
agno
]
==
bmp
->
db_agsize
))
{
jfs_err
(
"dbAllocAG: removed assert, but still need to "
"debug here
\n
blkno = 0x%Lx, nblocks = 0x%Lx"
,
(
unsigned
long
long
)
blkno
,
(
unsigned
long
long
)
nblocks
);
printk
(
KERN_ERR
"blkno = %Lx, blocks = %Lx
\n
"
,
(
unsigned
long
long
)
blkno
,
(
unsigned
long
long
)
nblocks
);
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocAG: dbAllocCtl failed in free AG"
);
}
return
(
rc
);
}
...
...
@@ -1496,7 +1523,11 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
break
;
}
}
assert
(
n
<
4
);
if
(
n
==
4
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocAG: failed descending stree"
);
return
-
EIO
;
}
}
/* determine the block number within the file system
...
...
@@ -1531,7 +1562,12 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
if
((
rc
=
dbFindCtl
(
bmp
,
l2nb
,
bmp
->
db_aglevel
-
1
,
&
blkno
)))
{
assert
(
rc
!=
-
ENOSPC
);
if
(
rc
==
-
ENOSPC
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocAG: control page "
"inconsistent"
);
return
-
EIO
;
}
return
(
rc
);
}
}
...
...
@@ -1539,7 +1575,11 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
/* allocate the blocks.
*/
rc
=
dbAllocCtl
(
bmp
,
nblocks
,
l2nb
,
blkno
,
results
);
assert
(
rc
!=
-
ENOSPC
);
if
(
rc
==
-
ENOSPC
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocAG: unable to allocate blocks"
);
rc
=
-
EIO
;
}
return
(
rc
);
}
...
...
@@ -1595,7 +1635,11 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
/* allocate the blocks.
*/
rc
=
dbAllocCtl
(
bmp
,
nblocks
,
l2nb
,
blkno
,
results
);
assert
(
rc
!=
-
ENOSPC
);
if
(
rc
==
-
ENOSPC
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocAny: unable to allocate blocks"
);
return
-
EIO
;
}
return
(
rc
);
}
...
...
@@ -1666,7 +1710,11 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
/* space found ?
*/
if
(
rc
)
{
assert
(
lev
==
level
);
if
(
lev
!=
level
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbFindCtl: dmap inconsistent"
);
return
-
EIO
;
}
return
-
ENOSPC
;
}
...
...
@@ -1785,7 +1833,13 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
/* the dmap better be all free.
*/
assert
(
dp
->
tree
.
stree
[
ROOT
]
==
L2BPERDMAP
);
if
(
dp
->
tree
.
stree
[
ROOT
]
!=
L2BPERDMAP
)
{
release_metapage
(
mp
);
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocCtl: the dmap is not all free"
);
rc
=
-
EIO
;
goto
backout
;
}
/* determine how many blocks to allocate from this dmap.
*/
...
...
@@ -1828,8 +1882,8 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
/* could not back out. mark the file system
* to indicate that we have leaked blocks.
*/
fsDirty
();
/* !!! */
jfs_err
(
"dbAllocCtl: I/O Error: Block Leakage."
);
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocCtl: I/O Error: Block Leakage."
);
continue
;
}
dp
=
(
struct
dmap
*
)
mp
->
data
;
...
...
@@ -1841,8 +1895,8 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
* to indicate that we have leaked blocks.
*/
release_metapage
(
mp
);
fsDirty
();
/* !!! */
jfs_err
(
"dbAllocCtl: Block Leakage."
);
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocCtl: Block Leakage."
);
continue
;
}
...
...
@@ -2137,7 +2191,12 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
* the allocated words.
*/
for
(;
nwords
>
0
;
nwords
-=
nw
)
{
assert
(
leaf
[
word
]
>=
BUDMIN
);
if
(
leaf
[
word
]
<
BUDMIN
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAllocBits: leaf page "
"corrupt"
);
break
;
}
/* determine what the leaf value should be
* updated to as the minimum of the l2 number
...
...
@@ -2489,7 +2548,11 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
* of the maximum free buddy system.
*/
assert
(
level
==
bmp
->
db_maxlevel
);
assert
(
bmp
->
db_maxfreebud
==
oldroot
);
if
(
bmp
->
db_maxfreebud
!=
oldroot
)
{
jfs_error
(
bmp
->
db_ipbmap
->
i_sb
,
"dbAdjCtl: the maximum free buddy is "
"not the old root"
);
}
bmp
->
db_maxfreebud
=
dcp
->
stree
[
ROOT
];
}
}
...
...
@@ -3039,24 +3102,6 @@ int blkstol2(s64 nb)
}
/*
* NAME: fsDirty()
*
* FUNCTION: xxx
*
* PARAMETERS:
* ipmnt - mount inode
*
* RETURN VALUES:
* none
*/
void
fsDirty
(
void
)
{
printk
(
"fsDirty(): bye-bye
\n
"
);
assert
(
0
);
}
/*
* NAME: dbAllocBottomUp()
*
...
...
@@ -3343,7 +3388,10 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
/* get L2 page */
p
=
BMAPBLKNO
+
nbperpage
;
/* L2 page */
l2mp
=
read_metapage
(
ipbmap
,
p
,
PSIZE
,
0
);
assert
(
l2mp
);
if
(
!
l2mp
)
{
jfs_error
(
ipbmap
->
i_sb
,
"dbExtendFS: L2 page could not be read"
);
return
-
EIO
;
}
l2dcp
=
(
struct
dmapctl
*
)
l2mp
->
data
;
/* compute start L1 */
...
...
@@ -3504,7 +3552,9 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
}
}
/* for each L1 in a L2 */
assert
(
0
);
jfs_error
(
ipbmap
->
i_sb
,
"dbExtendFS: function has not returned as expected"
);
return
-
EIO
;
/*
* finalize bmap control page
...
...
@@ -3568,7 +3618,10 @@ void dbFinalizeBmap(struct inode *ipbmap)
if
(
bmp
->
db_agfree
[
bmp
->
db_agpref
]
>=
avgfree
)
break
;
}
assert
(
bmp
->
db_agpref
<
bmp
->
db_numag
);
if
(
bmp
->
db_agpref
>=
bmp
->
db_numag
)
{
jfs_error
(
ipbmap
->
i_sb
,
"cannot find ag with average freespace"
);
}
}
/*
...
...
@@ -3589,10 +3642,6 @@ void dbFinalizeBmap(struct inode *ipbmap)
n
<<=
2
;
}
/*
printk("bmap: agpref:%d aglevel:%d agheigth:%d agwidth:%d\n",
bmp->db_agpref, bmp->db_aglevel, bmp->db_agheigth, bmp->db_agwidth);
*/
}
...
...
@@ -3616,9 +3665,6 @@ printk("bmap: agpref:%d aglevel:%d agheigth:%d agwidth:%d\n",
static
int
dbInitDmap
(
struct
dmap
*
dp
,
s64
Blkno
,
int
nblocks
)
{
int
blkno
,
w
,
b
,
r
,
nw
,
nb
,
i
;
/*
printk("sbh_dmap: in dbInitDmap blkno:%Ld nblocks:%ld\n", Blkno, nblocks);
*/
/* starting block number within the dmap */
blkno
=
Blkno
&
(
BPERDMAP
-
1
);
...
...
@@ -3678,10 +3724,6 @@ printk("sbh_dmap: in dbInitDmap blkno:%Ld nblocks:%ld\n", Blkno, nblocks);
* mark bits following the range to be freed (non-existing
* blocks) as allocated (ONES)
*/
/*
printk("sbh_dmap: in dbInitDmap, preparing to mark unbacked, blkno:%ld nblocks:%ld\n",
blkno, nblocks);
*/
if
(
blkno
==
BPERDMAP
)
goto
initTree
;
...
...
@@ -3691,9 +3733,6 @@ printk("sbh_dmap: in dbInitDmap, preparing to mark unbacked, blkno:%ld nblocks:
/* does nblocks fall on a 32-bit boundary ? */
b
=
blkno
&
(
DBWORD
-
1
);
/*
printk("sbh_dmap: in dbInitDmap, b:%ld w:%ld mask: %lx\n", b, w, (ONES>>b));
*/
if
(
b
)
{
/* mark a partial word allocated */
dp
->
wmap
[
w
]
=
dp
->
pmap
[
w
]
=
cpu_to_le32
(
ONES
>>
b
);
...
...
@@ -3990,7 +4029,7 @@ static void DBinitmap(s64 size, struct inode *ipbmap, u32 ** results)
dbmap
=
(
u32
*
)
xmalloc
(
npages
*
4096
,
L2PSIZE
,
kernel_heap
);
if
(
dbmap
==
NULL
)
assert
(
0
);
BUG
();
/* Not robust since this is only unused debug code */
for
(
n
=
0
,
d
=
dbmap
;
n
<
npages
;
n
++
,
d
+=
1024
)
bzero
(
d
,
4096
);
...
...
@@ -4004,7 +4043,9 @@ static void DBinitmap(s64 size, struct inode *ipbmap, u32 ** results)
db_l2nbperpage
);
mp
=
read_metapage
(
ipbmap
,
lblkno
,
PSIZE
,
0
);
if
(
mp
==
NULL
)
{
assert
(
0
);
jfs_error
(
ipbmap
->
i_sb
,
"DBinitmap: could not read disk map page"
);
continue
;
}
dp
=
(
struct
dmap
*
)
mp
->
data
;
...
...
fs/jfs/jfs_dtree.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -130,9 +130,8 @@ struct dtsplit {
if (((P)->header.nextindex > (((BN)==0)?DTROOTMAXSLOT:(P)->header.maxslot)) ||\
((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT)))\
{\
jfs_err("DT_GETPAGE: dtree page corrupt");\
BT_PUTPAGE(MP);\
updateSuper((IP)->i_sb, FM_DIRTY
);\
jfs_error((IP)->i_sb, "DT_GETPAGE: dtree page corrupt"
);\
MP = NULL;\
RC = -EIO;\
}\
...
...
@@ -768,8 +767,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
/* Something's corrupted, mark filesytem dirty so
* chkdsk will fix it.
*/
jfs_err
(
"stack overrun in dtSearch!"
);
updateSuper
(
sb
,
FM_DIRTY
);
jfs_error
(
sb
,
"stack overrun in dtSearch!"
);
rc
=
-
EIO
;
goto
out
;
}
...
...
@@ -3204,11 +3202,12 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
d_namleft
-=
len
;
/* Sanity Check */
if
(
d_namleft
==
0
)
{
jfs_err
(
"JFS:Dtree error: ino = "
"%ld, bn=%Ld, index = %d"
,
(
long
)
ip
->
i_ino
,(
long
long
)
bn
,
i
);
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
jfs_error
(
ip
->
i_sb
,
"JFS:Dtree error: ino = "
"%ld, bn=%Ld, index = %d"
,
(
long
)
ip
->
i_ino
,
(
long
long
)
bn
,
i
);
goto
skip_one
;
}
len
=
min
(
d_namleft
,
DTSLOTDATALEN
);
...
...
fs/jfs/jfs_extent.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -18,6 +18,7 @@
#include <linux/fs.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
#include "jfs_extent.h"
#include "jfs_debug.h"
...
...
@@ -403,8 +404,10 @@ int extHint(struct inode *ip, s64 offset, xad_t * xp)
*/
xp
->
flag
&=
XAD_NOTRECORDED
;
assert
(
xadl
.
nxad
==
1
);
assert
(
lengthXAD
(
xp
)
==
nbperpage
);
if
(
xadl
.
nxad
!=
1
||
lengthXAD
(
xp
)
!=
nbperpage
)
{
jfs_error
(
ip
->
i_sb
,
"extHint: corrupt xtree"
);
return
-
EIO
;
}
return
(
0
);
}
...
...
fs/jfs/jfs_filsys.h
View file @
1ec23637
/*
* Copyright (
c
) International Business Machines Corp., 2000-2003
* Copyright (
C
) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -32,6 +32,11 @@
/* mount time flag to disable journaling to disk */
#define JFS_NOINTEGRITY 0x00000010
/* mount time flags for error handling */
#define JFS_ERR_REMOUNT_RO 0x00000002
/* remount read-only */
#define JFS_ERR_CONTINUE 0x00000004
/* continue */
#define JFS_ERR_PANIC 0x00000008
/* panic */
/* platform option (conditional compilation) */
#define JFS_AIX 0x80000000
/* AIX support */
/* POSIX name/directory support */
...
...
fs/jfs/jfs_imap.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -410,8 +410,7 @@ int diRead(struct inode *ip)
dp
+=
rel_inode
;
if
(
ip
->
i_ino
!=
le32_to_cpu
(
dp
->
di_number
))
{
jfs_err
(
"diRead: i_ino != di_number"
);
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
jfs_error
(
ip
->
i_sb
,
"diRead: i_ino != di_number"
);
rc
=
-
EIO
;
}
else
if
(
le32_to_cpu
(
dp
->
di_nlink
)
==
0
)
rc
=
-
ESTALE
;
...
...
@@ -641,9 +640,12 @@ int diWrite(tid_t tid, struct inode *ip)
ino
=
ip
->
i_ino
&
(
INOSPERIAG
-
1
);
assert
(
lengthPXD
(
&
(
jfs_ip
->
ixpxd
))
==
JFS_IP
(
ipimap
)
->
i_imap
->
im_nbperiext
);
assert
(
addressPXD
(
&
(
jfs_ip
->
ixpxd
)));
if
(
!
addressPXD
(
&
(
jfs_ip
->
ixpxd
))
||
(
lengthPXD
(
&
(
jfs_ip
->
ixpxd
))
!=
JFS_IP
(
ipimap
)
->
i_imap
->
im_nbperiext
))
{
jfs_error
(
ip
->
i_sb
,
"diWrite: ixpxd invalid"
);
return
-
EIO
;
}
/*
* read the page of disk inode containing the specified inode:
...
...
@@ -918,12 +920,11 @@ int diFree(struct inode *ip)
/* make sure that the iag is contained within
* the map.
*/
//assert(iagno < imap->im_nextiag);
if
(
iagno
>=
imap
->
im_nextiag
)
{
jfs_err
(
"diFree: inum = %d, iagno = %d, nextiag = %d"
,
(
uint
)
inum
,
iagno
,
imap
->
im_nextiag
);
dump_mem
(
"imap"
,
imap
,
32
);
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
jfs_error
(
ip
->
i_sb
,
"diFree: inum = %d, iagno = %d, nextiag = %d"
,
(
uint
)
inum
,
iagno
,
imap
->
im_nextiag
);
return
-
EIO
;
}
...
...
@@ -957,22 +958,28 @@ int diFree(struct inode *ip)
bitno
=
ino
&
(
INOSPEREXT
-
1
);
mask
=
HIGHORDER
>>
bitno
;
assert
(
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
mask
);
#ifdef _STILL_TO_PORT
assert
((
le32_to_cpu
(
iagp
->
pmap
[
extno
])
&
mask
)
==
0
);
#endif
/* _STILL_TO_PORT */
assert
(
addressPXD
(
&
iagp
->
inoext
[
extno
]));
if
(
!
(
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
mask
))
{
jfs_error
(
ip
->
i_sb
,
"diFree: wmap shows inode already free"
);
}
if
(
!
addressPXD
(
&
iagp
->
inoext
[
extno
]))
{
release_metapage
(
mp
);
IREAD_UNLOCK
(
ipimap
);
AG_UNLOCK
(
imap
,
agno
);
jfs_error
(
ip
->
i_sb
,
"diFree: invalid inoext"
);
return
-
EIO
;
}
/* compute the bitmap for the extent reflecting the freed inode.
*/
bitmap
=
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
~
mask
;
if
(
imap
->
im_agctl
[
agno
].
numfree
>
imap
->
im_agctl
[
agno
].
numinos
)
{
jfs_err
(
"diFree: numfree > numinos"
);
release_metapage
(
mp
);
IREAD_UNLOCK
(
ipimap
);
AG_UNLOCK
(
imap
,
agno
);
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
jfs_error
(
ip
->
i_sb
,
"diFree: numfree > numinos"
);
return
-
EIO
;
}
/*
...
...
@@ -1136,7 +1143,6 @@ int diFree(struct inode *ip)
if
((
rc
=
diIAGRead
(
imap
,
inofreefwd
,
&
cmp
)))
goto
error_out
;
assert
(
cmp
!=
NULL
);
ciagp
=
(
struct
iag
*
)
cmp
->
data
;
}
assert
(
ciagp
!=
NULL
);
...
...
@@ -1151,7 +1157,6 @@ int diFree(struct inode *ip)
if
((
rc
=
diIAGRead
(
imap
,
inofreeback
,
&
dmp
)))
goto
error_out
;
assert
(
dmp
!=
NULL
);
diagp
=
(
struct
iag
*
)
dmp
->
data
;
}
assert
(
diagp
!=
NULL
);
...
...
@@ -1224,7 +1229,9 @@ int diFree(struct inode *ip)
* the permanent map should have been updated already
* for the inode being freed.
*/
assert
(
iagp
->
pmap
[
extno
]
==
0
);
if
(
iagp
->
pmap
[
extno
]
!=
0
)
{
jfs_error
(
ip
->
i_sb
,
"diFree: the pmap does not show inode free"
);
}
iagp
->
wmap
[
extno
]
=
0
;
DBG_DIFREE
(
imap
,
inum
);
PXDlength
(
&
iagp
->
inoext
[
extno
],
0
);
...
...
@@ -1304,7 +1311,7 @@ int diFree(struct inode *ip)
iplist
[
1
]
=
(
struct
inode
*
)
(
size_t
)
iagno
;
iplist
[
2
]
=
(
struct
inode
*
)
(
size_t
)
extno
;
rc
=
txCommit
(
tid
,
1
,
&
iplist
[
0
],
COMMIT_FORCE
);
// D233382
rc
=
txCommit
(
tid
,
1
,
&
iplist
[
0
],
COMMIT_FORCE
);
txEnd
(
tid
);
...
...
@@ -1434,6 +1441,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
iagno
=
INOTOIAG
(
inum
);
if
((
rc
=
diIAGRead
(
imap
,
iagno
,
&
mp
)))
{
IREAD_UNLOCK
(
ipimap
);
AG_UNLOCK
(
imap
,
agno
);
return
(
rc
);
}
iagp
=
(
struct
iag
*
)
mp
->
data
;
...
...
@@ -1536,10 +1544,16 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
*/
rem
=
diFindFree
(
inosmap
,
0
);
extno
=
(
sword
<<
L2EXTSPERSUM
)
+
rem
;
rem
=
diFindFree
(
le32_to_cpu
(
iagp
->
wmap
[
extno
]),
0
);
assert
(
rem
<
INOSPEREXT
);
rem
=
diFindFree
(
le32_to_cpu
(
iagp
->
wmap
[
extno
]),
0
);
if
(
rem
>=
INOSPEREXT
)
{
IREAD_UNLOCK
(
ipimap
);
AG_UNLOCK
(
imap
,
agno
);
jfs_error
(
ip
->
i_sb
,
"diAlloc: can't find free bit "
"in wmap"
);
return
EIO
;
}
/* determine the inode number within the
* iag and allocate the inode from the
...
...
@@ -1548,9 +1562,9 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
ino
=
(
extno
<<
L2INOSPEREXT
)
+
rem
;
rc
=
diAllocBit
(
imap
,
iagp
,
ino
);
IREAD_UNLOCK
(
ipimap
);
if
(
rc
)
{
if
(
rc
)
assert
(
rc
==
-
EIO
);
}
else
{
else
{
/* set the results of the allocation
* and write the iag.
*/
...
...
@@ -1678,8 +1692,7 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
numinos
=
imap
->
im_agctl
[
agno
].
numinos
;
if
(
numfree
>
numinos
)
{
jfs_err
(
"diAllocAG: numfree > numinos"
);
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
jfs_error
(
ip
->
i_sb
,
"diAllocAG: numfree > numinos"
);
return
-
EIO
;
}
...
...
@@ -1827,12 +1840,10 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
/* better be free inodes in this iag if it is on the
* list.
*/
//assert(iagp->nfreeinos);
if
(
!
iagp
->
nfreeinos
)
{
jfs_err
(
"diAllocIno: nfreeinos = 0, but iag on freelist"
);
jfs_err
(
" agno = %d, iagno = %d"
,
agno
,
iagno
);
dump_mem
(
"iag"
,
iagp
,
64
);
updateSuper
(
ip
->
i_sb
,
FM_DIRTY
);
IREAD_UNLOCK
(
imap
->
im_ipimap
);
jfs_error
(
ip
->
i_sb
,
"diAllocIno: nfreeinos = 0, but iag on freelist"
);
return
-
EIO
;
}
...
...
@@ -1840,7 +1851,12 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
* with free inodes.
*/
for
(
sword
=
0
;;
sword
++
)
{
assert
(
sword
<
SMAPSZ
);
if
(
sword
>=
SMAPSZ
)
{
IREAD_UNLOCK
(
imap
->
im_ipimap
);
jfs_error
(
ip
->
i_sb
,
"diAllocIno: free inode not found in summary map"
);
return
-
EIO
;
}
if
(
~
iagp
->
inosmap
[
sword
])
break
;
...
...
@@ -1850,13 +1866,21 @@ static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
* the extent number.
*/
rem
=
diFindFree
(
le32_to_cpu
(
iagp
->
inosmap
[
sword
]),
0
);
assert
(
rem
<
EXTSPERSUM
);
if
(
rem
>=
EXTSPERSUM
)
{
IREAD_UNLOCK
(
imap
->
im_ipimap
);
jfs_error
(
ip
->
i_sb
,
"diAllocIno: no free extent found"
);
return
-
EIO
;
}
extno
=
(
sword
<<
L2EXTSPERSUM
)
+
rem
;
/* find the first free inode in the extent.
*/
rem
=
diFindFree
(
le32_to_cpu
(
iagp
->
wmap
[
extno
]),
0
);
assert
(
rem
<
INOSPEREXT
);
if
(
rem
>=
INOSPEREXT
)
{
IREAD_UNLOCK
(
imap
->
im_ipimap
);
jfs_error
(
ip
->
i_sb
,
"diAllocIno: free inode not found"
);
return
-
EIO
;
}
/* compute the inode number within the iag.
*/
...
...
@@ -1939,7 +1963,9 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
*/
IREAD_LOCK
(
imap
->
im_ipimap
);
if
((
rc
=
diIAGRead
(
imap
,
iagno
,
&
mp
)))
{
assert
(
0
);
IREAD_UNLOCK
(
imap
->
im_ipimap
);
jfs_error
(
ip
->
i_sb
,
"diAllocExt: error reading iag"
);
return
rc
;
}
iagp
=
(
struct
iag
*
)
mp
->
data
;
}
...
...
@@ -1947,7 +1973,13 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
/* using the free extent summary map, find a free extent.
*/
for
(
sword
=
0
;;
sword
++
)
{
assert
(
sword
<
SMAPSZ
);
if
(
sword
>=
SMAPSZ
)
{
release_metapage
(
mp
);
IREAD_UNLOCK
(
imap
->
im_ipimap
);
jfs_error
(
ip
->
i_sb
,
"diAllocExt: free ext summary map not found"
);
return
-
EIO
;
}
if
(
~
iagp
->
extsmap
[
sword
])
break
;
}
...
...
@@ -1955,7 +1987,12 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
/* determine the extent number of the free extent.
*/
rem
=
diFindFree
(
le32_to_cpu
(
iagp
->
extsmap
[
sword
]),
0
);
assert
(
rem
<
EXTSPERSUM
);
if
(
rem
>=
EXTSPERSUM
)
{
release_metapage
(
mp
);
IREAD_UNLOCK
(
imap
->
im_ipimap
);
jfs_error
(
ip
->
i_sb
,
"diAllocExt: free extent not found"
);
return
-
EIO
;
}
extno
=
(
sword
<<
L2EXTSPERSUM
)
+
rem
;
/* initialize the new extent.
...
...
@@ -2066,9 +2103,18 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
/* the inode should be free and backed.
*/
assert
((
le32_to_cpu
(
iagp
->
pmap
[
extno
])
&
mask
)
==
0
);
assert
((
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
mask
)
==
0
);
assert
(
addressPXD
(
&
iagp
->
inoext
[
extno
])
!=
0
);
if
(((
le32_to_cpu
(
iagp
->
pmap
[
extno
])
&
mask
)
!=
0
)
||
((
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
mask
)
!=
0
)
||
(
addressPXD
(
&
iagp
->
inoext
[
extno
])
==
0
))
{
if
(
amp
)
release_metapage
(
amp
);
if
(
bmp
)
release_metapage
(
bmp
);
jfs_error
(
imap
->
im_ipimap
->
i_sb
,
"diAllocBit: iag inconsistent"
);
return
-
EIO
;
}
/* mark the inode as allocated in the working map.
*/
...
...
@@ -2172,7 +2218,10 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
/* better have free extents.
*/
assert
(
iagp
->
nfreeexts
);
if
(
!
iagp
->
nfreeexts
)
{
jfs_error
(
imap
->
im_ipimap
->
i_sb
,
"diNewExt: no free extents"
);
return
-
EIO
;
}
/* get the inode map inode.
*/
...
...
@@ -2240,7 +2289,12 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
goto
error_out
;
ciagp
=
(
struct
iag
*
)
cmp
->
data
;
}
assert
(
ciagp
!=
NULL
);
if
(
ciagp
==
NULL
)
{
jfs_error
(
imap
->
im_ipimap
->
i_sb
,
"diNewExt: ciagp == NULL"
);
rc
=
-
EIO
;
goto
error_out
;
}
}
}
...
...
@@ -2474,7 +2528,14 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
/* acquire inode map lock */
IWRITE_LOCK
(
ipimap
);
assert
(
ipimap
->
i_size
>>
L2PSIZE
==
imap
->
im_nextiag
+
1
);
if
(
ipimap
->
i_size
>>
L2PSIZE
!=
imap
->
im_nextiag
+
1
)
{
IWRITE_UNLOCK
(
ipimap
);
IAGFREE_UNLOCK
(
imap
);
jfs_error
(
imap
->
im_ipimap
->
i_sb
,
"diNewIAG: ipimap->i_size is wrong"
);
return
-
EIO
;
}
/* get the next avaliable iag number */
iagno
=
imap
->
im_nextiag
;
...
...
@@ -2507,7 +2568,6 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
/* assign a buffer for the page */
mp
=
get_metapage
(
ipimap
,
xaddr
,
PSIZE
,
1
);
//bp = bmAssign(ipimap, blkno, xaddr, PSIZE, bmREAD_PAGE);
if
(
!
mp
)
{
/* Free the blocks allocated for the iag since it was
* not successfully added to the inode map
...
...
@@ -2734,7 +2794,11 @@ diUpdatePMap(struct inode *ipimap,
/* get the iag number containing the inode */
iagno
=
INOTOIAG
(
inum
);
/* make sure that the iag is contained within the map */
assert
(
iagno
<
imap
->
im_nextiag
);
if
(
iagno
>=
imap
->
im_nextiag
)
{
jfs_error
(
ipimap
->
i_sb
,
"diUpdatePMap: the iag is outside the map"
);
return
-
EIO
;
}
/* read the iag */
IREAD_LOCK
(
ipimap
);
rc
=
diIAGRead
(
imap
,
iagno
,
&
mp
);
...
...
@@ -2759,14 +2823,14 @@ diUpdatePMap(struct inode *ipimap,
* of last reference release;
*/
if
(
!
(
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
mask
))
{
jfs_err
(
"diUpdatePMap: inode %ld not marked as "
"allocated in wmap!"
,
inum
);
updateSuper
(
ipimap
->
i_sb
,
FM_DIRTY
);
jfs_err
or
(
ipimap
->
i_sb
,
"diUpdatePMap: inode %ld not marked as "
"allocated in wmap!"
,
inum
);
}
if
(
!
(
le32_to_cpu
(
iagp
->
pmap
[
extno
])
&
mask
))
{
jfs_err
(
"diUpdatePMap: inode %ld not marked as "
"allocated in pmap!"
,
inum
);
updateSuper
(
ipimap
->
i_sb
,
FM_DIRTY
);
jfs_err
or
(
ipimap
->
i_sb
,
"diUpdatePMap: inode %ld not marked as "
"allocated in pmap!"
,
inum
);
}
/* update the bitmap for the extent of the freed inode */
iagp
->
pmap
[
extno
]
&=
cpu_to_le32
(
~
mask
);
...
...
@@ -2778,8 +2842,18 @@ diUpdatePMap(struct inode *ipimap,
/* The inode should be already allocated in the working map
* and should be free in persistent map;
*/
assert
(
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
mask
);
assert
((
le32_to_cpu
(
iagp
->
pmap
[
extno
])
&
mask
)
==
0
);
if
(
!
(
le32_to_cpu
(
iagp
->
wmap
[
extno
])
&
mask
))
{
jfs_error
(
ipimap
->
i_sb
,
"diUpdatePMap: the inode is not allocated in "
"the working map"
);
return
-
EIO
;
}
if
((
le32_to_cpu
(
iagp
->
pmap
[
extno
])
&
mask
)
!=
0
)
{
jfs_error
(
ipimap
->
i_sb
,
"diUpdatePMap: the inode is not free in the "
"persistent map"
);
return
-
EIO
;
}
/* update the bitmap for the extent of the allocated inode */
iagp
->
pmap
[
extno
]
|=
cpu_to_le32
(
mask
);
}
...
...
@@ -2817,7 +2891,6 @@ diUpdatePMap(struct inode *ipimap,
mp
->
clsn
=
tblk
->
clsn
;
LOGSYNC_UNLOCK
(
log
);
}
// bmLazyWrite(mp, log->flag & JFS_COMMIT);
write_metapage
(
mp
);
return
(
0
);
}
...
...
@@ -2872,7 +2945,12 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
continue
;
}
iagp
=
(
struct
iag
*
)
bp
->
data
;
assert
(
le32_to_cpu
(
iagp
->
iagnum
)
==
i
);
if
(
le32_to_cpu
(
iagp
->
iagnum
)
!=
i
)
{
release_metapage
(
bp
);
jfs_error
(
ipimap
->
i_sb
,
"diExtendFs: unexpected value of iagnum"
);
return
-
EIO
;
}
/* leave free iag in the free iag list */
if
(
iagp
->
nfreeexts
==
cpu_to_le32
(
EXTSPERIAG
))
{
...
...
@@ -2884,9 +2962,6 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
agstart
=
le64_to_cpu
(
iagp
->
agstart
);
/* iagp->agstart = agstart & ~(mp->db_agsize - 1); */
n
=
agstart
>>
mp
->
db_agl2size
;
/*
printf("diExtendFS: iag:%d agstart:%Ld agno:%d\n", i, agstart, n);
*/
/* compute backed inodes */
numinos
=
(
EXTSPERIAG
-
le32_to_cpu
(
iagp
->
nfreeexts
))
...
...
@@ -2947,8 +3022,12 @@ printf("diExtendFS: iag:%d agstart:%Ld agno:%d\n", i, agstart, n);
write_metapage
(
bp
);
}
ASSERT
(
xnuminos
==
atomic_read
(
&
imap
->
im_numinos
)
&&
xnumfree
==
atomic_read
(
&
imap
->
im_numfree
));
if
(
xnuminos
!=
atomic_read
(
&
imap
->
im_numinos
)
||
xnumfree
!=
atomic_read
(
&
imap
->
im_numfree
))
{
jfs_error
(
ipimap
->
i_sb
,
"diExtendFs: numinos or numfree incorrect"
);
return
-
EIO
;
}
return
rcx
;
}
...
...
fs/jfs/jfs_metapage.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Portions Copyright (
c
) Christoph Hellwig, 2001-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
* Portions Copyright (
C
) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -22,6 +22,7 @@
#include <linux/buffer_head.h>
#include <linux/mempool.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
#include "jfs_txnmgr.h"
...
...
@@ -233,14 +234,23 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
if
(
mp
)
{
page_found:
if
(
test_bit
(
META_discard
,
&
mp
->
flag
))
{
assert
(
new
);
/* It's okay to reuse a discarded
* if we expect it to be empty
*/
if
(
!
new
)
{
spin_unlock
(
&
meta_lock
);
jfs_error
(
inode
->
i_sb
,
"__get_metapage: using a "
"discarded metapage"
);
return
NULL
;
}
clear_bit
(
META_discard
,
&
mp
->
flag
);
}
mp
->
count
++
;
jfs_info
(
"__get_metapage: found 0x%p, in hash"
,
mp
);
assert
(
mp
->
logical_size
==
size
);
if
(
mp
->
logical_size
!=
size
)
{
spin_unlock
(
&
meta_lock
);
jfs_error
(
inode
->
i_sb
,
"__get_metapage: mp->logical_size != size"
);
return
NULL
;
}
lock_metapage
(
mp
);
spin_unlock
(
&
meta_lock
);
}
else
{
...
...
fs/jfs/jfs_superblock.h
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -108,5 +108,6 @@ struct jfs_superblock {
extern
int
readSuper
(
struct
super_block
*
,
struct
buffer_head
**
);
extern
int
updateSuper
(
struct
super_block
*
,
uint
);
extern
void
jfs_error
(
struct
super_block
*
,
const
char
*
,
...);
#endif
/*_H_JFS_SUPERBLOCK */
fs/jfs/jfs_txnmgr.c
View file @
1ec23637
/*
* Copyright (
c
) International Business Machines Corp., 2000-2003
* Portions Copyright (
c
) Christoph Hellwig, 2001-2002
* Copyright (
C
) International Business Machines Corp., 2000-2003
* Portions Copyright (
C
) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -1442,7 +1442,6 @@ int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
* page is not itself logged, to prevent pageout of the map
* page before the log;
*/
assert
(
tlck
->
type
&
tlckFREE
);
/* log LOG_NOREDOINOEXT of the freed inode extent for
* logredo() to start NoRedoPage filters, and to update
...
...
@@ -2655,7 +2654,7 @@ void txAbort(tid_t tid, int dirty)
* mark filesystem dirty
*/
if
(
dirty
)
updateSuper
(
tblk
->
sb
,
FM_DIRTY
);
jfs_error
(
tblk
->
sb
,
"txAbort"
);
return
;
}
...
...
@@ -2714,7 +2713,7 @@ static void txAbortCommit(struct commit * cd)
/*
* mark filesystem dirty
*/
updateSuper
(
cd
->
sb
,
FM_DIRTY
);
jfs_error
(
cd
->
sb
,
"txAbortCommit"
);
}
...
...
fs/jfs/jfs_xtree.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -60,21 +60,21 @@
#define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot)
/* get page buffer for specified block address */
/* ToDo: Replace this ugly macro with a function */
#define XT_GETPAGE(IP, BN, MP, SIZE, P, RC)\
{\
BT_GETPAGE(IP, BN, MP, xtpage_t, SIZE, P, RC, i_xtroot)\
if (!(RC))\
{\
if ((le16_to_cpu((P)->header.nextindex) < XTENTRYSTART) ||\
(le16_to_cpu((P)->header.nextindex) > le16_to_cpu((P)->header.maxentry)) ||\
(le16_to_cpu((P)->header.maxentry) > (((BN)==0)?XTROOTMAXSLOT:PSIZE>>L2XTSLOTSIZE)))\
{\
jfs_err(
"XT_GETPAGE: xtree page corrupt");\
BT_GETPAGE(IP, BN, MP, xtpage_t, SIZE, P, RC, i_xtroot)\
if (!(RC))\
{\
if ((le16_to_cpu((P)->header.nextindex) < XTENTRYSTART) ||\
(le16_to_cpu((P)->header.nextindex) > le16_to_cpu((P)->header.maxentry)) ||\
(le16_to_cpu((P)->header.maxentry) > (((BN)==0)?XTROOTMAXSLOT:PSIZE>>L2XTSLOTSIZE)))\
{\
jfs_error((IP)->i_sb,
"XT_GETPAGE: xtree page corrupt");\
BT_PUTPAGE(MP);\
updateSuper((IP)->i_sb, FM_DIRTY);\
MP = NULL;\
RC = -EIO;\
}\
RC = -EIO;\
}\
}\
}
...
...
@@ -1611,14 +1611,21 @@ int xtExtend(tid_t tid, /* transaction id */
/* there must exist extent to be extended */
if
((
rc
=
xtSearch
(
ip
,
xoff
-
1
,
&
cmp
,
&
btstack
,
XT_INSERT
)))
return
rc
;
assert
(
cmp
==
0
);
if
(
cmp
!=
0
)
{
jfs_error
(
ip
->
i_sb
,
"xtExtend: xtSearch did not find extent"
);
return
-
EIO
;
}
/* retrieve search result */
XT_GETSEARCH
(
ip
,
btstack
.
top
,
bn
,
mp
,
p
,
index
);
/* extension must be contiguous */
xad
=
&
p
->
xad
[
index
];
assert
((
offsetXAD
(
xad
)
+
lengthXAD
(
xad
))
==
xoff
);
if
((
offsetXAD
(
xad
)
+
lengthXAD
(
xad
))
!=
xoff
)
{
XT_PUTPAGE
(
mp
);
jfs_error
(
ip
->
i_sb
,
"xtExtend: extension is not contiguous"
);
return
-
EIO
;
}
/*
* acquire a transaction lock on the leaf page;
...
...
@@ -1771,14 +1778,22 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
/* there must exist extent to be tailgated */
if
((
rc
=
xtSearch
(
ip
,
xoff
,
&
cmp
,
&
btstack
,
XT_INSERT
)))
return
rc
;
assert
(
cmp
==
0
);
if
(
cmp
!=
0
)
{
jfs_error
(
ip
->
i_sb
,
"xtTailgate: couldn't find extent"
);
return
-
EIO
;
}
/* retrieve search result */
XT_GETSEARCH
(
ip
,
btstack
.
top
,
bn
,
mp
,
p
,
index
);
/* entry found must be last entry */
nextindex
=
le16_to_cpu
(
p
->
header
.
nextindex
);
assert
(
index
==
nextindex
-
1
);
if
(
index
!=
nextindex
-
1
)
{
XT_PUTPAGE
(
mp
);
jfs_error
(
ip
->
i_sb
,
"xtTailgate: the entry found is not the last entry"
);
return
-
EIO
;
}
BT_MARK_DIRTY
(
mp
,
ip
);
/*
...
...
@@ -1941,13 +1956,14 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
nxoff
=
offsetXAD
(
nxad
);
nxlen
=
lengthXAD
(
nxad
);
nxaddr
=
addressXAD
(
nxad
);
/*
printf("xtUpdate: nxflag:0x%x nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
nxad->flag, (ulong)nxoff, nxlen, (ulong)nxaddr);
*/
if
((
rc
=
xtSearch
(
ip
,
nxoff
,
&
cmp
,
&
btstack
,
XT_INSERT
)))
return
rc
;
assert
(
cmp
==
0
);
if
(
cmp
!=
0
)
{
jfs_error
(
ip
->
i_sb
,
"xtUpdate: Could not find extent"
);
return
-
EIO
;
}
/* retrieve search result */
XT_GETSEARCH
(
ip
,
btstack
.
top
,
bn
,
mp
,
p
,
index0
);
...
...
@@ -1966,14 +1982,15 @@ printf("xtUpdate: nxflag:0x%x nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
xoff
=
offsetXAD
(
xad
);
xlen
=
lengthXAD
(
xad
);
xaddr
=
addressXAD
(
xad
);
/*
printf("xtUpdate: xflag:0x%x xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
xflag, (ulong)xoff, xlen, (ulong)xaddr);
*/
/* nXAD must be completely contained within XAD */
assert
(
xoff
<=
nxoff
);
assert
(
nxoff
+
nxlen
<=
xoff
+
xlen
);
if
((
xoff
>
nxoff
)
||
(
nxoff
+
nxlen
>
xoff
+
xlen
))
{
XT_PUTPAGE
(
mp
);
jfs_error
(
ip
->
i_sb
,
"xtUpdate: nXAD in not completely contained within XAD"
);
return
-
EIO
;
}
index
=
index0
;
newindex
=
index
+
1
;
...
...
@@ -2118,7 +2135,11 @@ printf("xtUpdate: xflag:0x%x xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
}
else
if
(
xoff
==
nxoff
)
goto
out
;
assert
(
xoff
<
nxoff
);
if
(
xoff
>=
nxoff
)
{
XT_PUTPAGE
(
mp
);
jfs_error
(
ip
->
i_sb
,
"xtUpdate: xoff >= nxoff"
);
return
-
EIO
;
}
/* #endif _JFS_WIP_COALESCE */
/*
...
...
@@ -2135,9 +2156,6 @@ printf("xtUpdate: xflag:0x%x xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
/* insert nXAD:recorded */
if
(
nextindex
==
le16_to_cpu
(
p
->
header
.
maxentry
))
{
/*
printf("xtUpdate.updateRight.split p:0x%p\n", p);
*/
rootsplit
=
p
->
header
.
flag
&
BT_ROOT
;
/* xtSpliUp() unpins leaf pages */
...
...
@@ -2248,18 +2266,23 @@ printf("xtUpdate.updateRight.split p:0x%p\n", p);
/* recompute split pages */
if
(
nextindex
==
le16_to_cpu
(
p
->
header
.
maxentry
))
{
/*
printf("xtUpdate: updateRight+Left recompute split pages: p:0x%p\n", p);
*/
XT_PUTPAGE
(
mp
);
if
((
rc
=
xtSearch
(
ip
,
nxoff
,
&
cmp
,
&
btstack
,
XT_INSERT
)))
return
rc
;
assert
(
cmp
==
0
);
if
(
cmp
!=
0
)
{
jfs_error
(
ip
->
i_sb
,
"xtUpdate: xtSearch failed"
);
return
-
EIO
;
}
/* retrieve search result */
XT_GETSEARCH
(
ip
,
btstack
.
top
,
bn
,
mp
,
p
,
index0
);
assert
(
index0
==
index
);
if
(
index0
!=
index
)
{
XT_PUTPAGE
(
mp
);
jfs_error
(
ip
->
i_sb
,
"xtUpdate: unexpected value of index"
);
return
-
EIO
;
}
}
/*
...
...
@@ -2755,6 +2778,7 @@ xtDeleteUp(tid_t tid, struct inode *ip,
* txCommit() to commit all the allocation before call
* this routine.
*/
int
xtRelocate
(
tid_t
tid
,
struct
inode
*
ip
,
xad_t
*
oxad
,
/* old XAD */
s64
nxaddr
,
/* new xaddr */
int
xtype
)
...
...
@@ -3925,7 +3949,11 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
rc
=
xtSearch
(
ip
,
xoff
,
&
cmp
,
&
btstack
,
0
);
if
(
rc
)
return
rc
;
assert
(
cmp
==
0
);
if
(
cmp
!=
0
)
{
jfs_error
(
ip
->
i_sb
,
"xtTruncate_pmap: did not find extent"
);
return
-
EIO
;
}
XT_GETSEARCH
(
ip
,
btstack
.
top
,
bn
,
mp
,
p
,
index
);
}
else
{
/*
...
...
fs/jfs/namei.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Portions Copyright (
c
) Christoph Hellwig, 2001-2002
* Copyright (
C) International Business Machines Corp., 2000-2003
* Portions Copyright (
C
) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -19,6 +19,7 @@
#include <linux/fs.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_inode.h"
#include "jfs_dinode.h"
#include "jfs_dmap.h"
...
...
@@ -1138,7 +1139,17 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
new_ip
->
i_nlink
--
;
if
(
S_ISDIR
(
new_ip
->
i_mode
))
{
new_ip
->
i_nlink
--
;
assert
(
new_ip
->
i_nlink
==
0
);
if
(
new_ip
->
i_nlink
)
{
up
(
&
JFS_IP
(
new_dir
)
->
commit_sem
);
up
(
&
JFS_IP
(
old_ip
)
->
commit_sem
);
if
(
old_dir
!=
new_dir
)
up
(
&
JFS_IP
(
old_dir
)
->
commit_sem
);
if
(
!
S_ISDIR
(
old_ip
->
i_mode
)
&&
new_ip
)
IWRITE_UNLOCK
(
new_ip
);
jfs_error
(
new_ip
->
i_sb
,
"jfs_rename: new_ip->i_nlink != 0"
);
return
-
EIO
;
}
tblk
=
tid_to_tblock
(
tid
);
tblk
->
xflag
|=
COMMIT_DELETE
;
tblk
->
ip
=
new_ip
;
...
...
fs/jfs/resize.c
View file @
1ec23637
/*
* Copyright (
c
) International Business Machines Corp., 2000-2003
* Copyright (
C
) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -523,7 +523,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
goto
resume
;
error_out:
updateSuper
(
sb
,
FM_DIRTY
);
jfs_error
(
sb
,
"jfs_extendfs"
);
resume:
/*
...
...
fs/jfs/super.c
View file @
1ec23637
/*
* Copyright (
c
) International Business Machines Corp., 2000-2003
* Portions Copyright (
c
) Christoph Hellwig, 2001-2002
* Copyright (
C
) International Business Machines Corp., 2000-2003
* Portions Copyright (
C
) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -85,6 +85,42 @@ extern wait_queue_head_t jfs_IO_thread_wait;
extern
wait_queue_head_t
jfs_commit_thread_wait
;
extern
wait_queue_head_t
jfs_sync_thread_wait
;
static
void
jfs_handle_error
(
struct
super_block
*
sb
)
{
struct
jfs_sb_info
*
sbi
=
JFS_SBI
(
sb
);
if
(
sb
->
s_flags
&
MS_RDONLY
)
return
;
updateSuper
(
sb
,
FM_DIRTY
);
if
(
sbi
->
flag
&
JFS_ERR_PANIC
)
panic
(
"JFS (device %s): panic forced after error
\n
"
,
sb
->
s_id
);
else
if
(
sbi
->
flag
&
JFS_ERR_REMOUNT_RO
)
{
jfs_err
(
"ERROR: (device %s): remounting filesystem "
"as read-only
\n
"
,
sb
->
s_id
);
sb
->
s_flags
|=
MS_RDONLY
;
}
/* nothing is done for continue beyond marking the superblock dirty */
}
void
jfs_error
(
struct
super_block
*
sb
,
const
char
*
function
,
...)
{
static
char
error_buf
[
256
];
va_list
args
;
va_start
(
args
,
function
);
vsprintf
(
error_buf
,
function
,
args
);
va_end
(
args
);
printk
(
KERN_ERR
"ERROR: (device %s): %s
\n
"
,
sb
->
s_id
,
error_buf
);
jfs_handle_error
(
sb
);
}
static
struct
inode
*
jfs_alloc_inode
(
struct
super_block
*
sb
)
{
struct
jfs_inode_info
*
jfs_inode
;
...
...
@@ -167,7 +203,7 @@ static void jfs_put_super(struct super_block *sb)
enum
{
Opt_integrity
,
Opt_nointegrity
,
Opt_iocharset
,
Opt_resize
,
Opt_ignore
,
Opt_err
,
Opt_
errors
,
Opt_
ignore
,
Opt_err
,
};
static
match_table_t
tokens
=
{
...
...
@@ -175,6 +211,7 @@ static match_table_t tokens = {
{
Opt_nointegrity
,
"nointegrity"
},
{
Opt_iocharset
,
"iocharset=%s"
},
{
Opt_resize
,
"resize=%u"
},
{
Opt_errors
,
"errors=%s"
},
{
Opt_ignore
,
"noquota"
},
{
Opt_ignore
,
"quota"
},
{
Opt_ignore
,
"usrquota"
},
...
...
@@ -234,6 +271,31 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
*
newLVSize
=
simple_strtoull
(
resize
,
&
resize
,
0
);
break
;
}
case
Opt_errors
:
{
char
*
errors
=
args
[
0
].
from
;
if
(
!
errors
||
!*
errors
)
goto
cleanup
;
if
(
!
strcmp
(
errors
,
"continue"
))
{
*
flag
&=
~
JFS_ERR_REMOUNT_RO
;
*
flag
&=
~
JFS_ERR_PANIC
;
*
flag
|=
JFS_ERR_CONTINUE
;
}
else
if
(
!
strcmp
(
errors
,
"remount-ro"
))
{
*
flag
&=
~
JFS_ERR_CONTINUE
;
*
flag
&=
~
JFS_ERR_PANIC
;
*
flag
|=
JFS_ERR_REMOUNT_RO
;
}
else
if
(
!
strcmp
(
errors
,
"panic"
))
{
*
flag
&=
~
JFS_ERR_CONTINUE
;
*
flag
&=
~
JFS_ERR_REMOUNT_RO
;
*
flag
|=
JFS_ERR_PANIC
;
}
else
{
printk
(
KERN_ERR
"JFS: %s is an invalid error handler
\n
"
,
errors
);
goto
cleanup
;
}
break
;
}
default:
printk
(
"jfs: Unrecognized mount option
\"
%s
\"
"
" or missing value
\n
"
,
p
);
...
...
@@ -316,7 +378,9 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
memset
(
sbi
,
0
,
sizeof
(
struct
jfs_sb_info
));
sb
->
s_fs_info
=
sbi
;
flag
=
0
;
/* initialize the mount flag and determine the default error handler */
flag
=
JFS_ERR_REMOUNT_RO
;
if
(
!
parse_options
((
char
*
)
data
,
sb
,
&
newLVSize
,
&
flag
))
{
kfree
(
sbi
);
return
-
EINVAL
;
...
...
fs/jfs/xattr.c
View file @
1ec23637
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
c
) Christoph Hellwig, 2002
* Copyright (
C) International Business Machines Corp., 2000-2003
* Copyright (
C
) Christoph Hellwig, 2002
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/xattr.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
#include "jfs_debug.h"
#include "jfs_dinode.h"
...
...
@@ -381,7 +382,10 @@ static int ea_read(struct inode *ip, struct jfs_ea_list *ealist)
return
ea_read_inline
(
ip
,
ealist
);
nbytes
=
sizeDXD
(
&
ji
->
ea
);
assert
(
nbytes
);
if
(
!
nbytes
)
{
jfs_error
(
sb
,
"ea_read: nbytes is 0"
);
return
-
EIO
;
}
/*
* Figure out how many blocks were allocated when this EA list was
...
...
@@ -477,7 +481,10 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
}
current_blocks
=
0
;
}
else
{
assert
(
ji
->
ea
.
flag
&
DXD_EXTENT
);
if
(
!
(
ji
->
ea
.
flag
&
DXD_EXTENT
))
{
jfs_error
(
sb
,
"ea_get: invalid ea.flag)"
);
return
-
EIO
;
}
current_blocks
=
(
ea_size
+
sb
->
s_blocksize
-
1
)
>>
sb
->
s_blocksize_bits
;
}
...
...
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