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
0ac8d0f1
Commit
0ac8d0f1
authored
Oct 08, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://jfs.bkbits.net/linux-2.5
into home.osdl.org:/home/torvalds/v2.5/linux
parents
5e6c5631
1ec23637
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 @
0ac8d0f1
...
...
@@ -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 @
0ac8d0f1
...
...
@@ -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 @
0ac8d0f1
...
...
@@ -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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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 @
0ac8d0f1
/*
* 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