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
ebf488f2
Commit
ebf488f2
authored
Dec 09, 2002
by
Dave Kleikamp
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux.bkbits.net/linux-2.5
into hostme.bitkeeper.com:/ua/repos/j/jfs/linux-2.5
parents
5882eeaf
821d7f2d
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
290 additions
and
162 deletions
+290
-162
fs/jfs/file.c
fs/jfs/file.c
+1
-53
fs/jfs/inode.c
fs/jfs/inode.c
+56
-1
fs/jfs/jfs_debug.c
fs/jfs/jfs_debug.c
+2
-0
fs/jfs/jfs_dtree.c
fs/jfs/jfs_dtree.c
+51
-22
fs/jfs/jfs_imap.c
fs/jfs/jfs_imap.c
+1
-1
fs/jfs/jfs_incore.h
fs/jfs/jfs_incore.h
+0
-1
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.c
+69
-28
fs/jfs/jfs_metapage.c
fs/jfs/jfs_metapage.c
+2
-27
fs/jfs/jfs_metapage.h
fs/jfs/jfs_metapage.h
+2
-5
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.c
+97
-21
fs/jfs/jfs_xtree.c
fs/jfs/jfs_xtree.c
+7
-0
fs/jfs/namei.c
fs/jfs/namei.c
+2
-2
fs/jfs/super.c
fs/jfs/super.c
+0
-1
No files found.
fs/jfs/file.c
View file @
ebf488f2
...
...
@@ -27,6 +27,7 @@
extern
int
jfs_commit_inode
(
struct
inode
*
,
int
);
extern
void
jfs_truncate
(
struct
inode
*
);
int
jfs_fsync
(
struct
file
*
file
,
struct
dentry
*
dentry
,
int
datasync
)
{
...
...
@@ -43,59 +44,6 @@ int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
return
rc
?
-
EIO
:
0
;
}
/*
* Guts of jfs_truncate. Called with locks already held. Can be called
* with directory for truncating directory index table.
*/
void
jfs_truncate_nolock
(
struct
inode
*
ip
,
loff_t
length
)
{
loff_t
newsize
;
tid_t
tid
;
ASSERT
(
length
>=
0
);
if
(
test_cflag
(
COMMIT_Nolink
,
ip
))
{
xtTruncate
(
0
,
ip
,
length
,
COMMIT_WMAP
);
return
;
}
do
{
tid
=
txBegin
(
ip
->
i_sb
,
0
);
/*
* The commit_sem cannot be taken before txBegin.
* txBegin may block and there is a chance the inode
* could be marked dirty and need to be committed
* before txBegin unblocks
*/
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
newsize
=
xtTruncate
(
tid
,
ip
,
length
,
COMMIT_TRUNCATE
|
COMMIT_PWMAP
);
if
(
newsize
<
0
)
{
txEnd
(
tid
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
break
;
}
ip
->
i_mtime
=
ip
->
i_ctime
=
CURRENT_TIME
;
mark_inode_dirty
(
ip
);
txCommit
(
tid
,
1
,
&
ip
,
0
);
txEnd
(
tid
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
}
while
(
newsize
>
length
);
/* Truncate isn't always atomic */
}
static
void
jfs_truncate
(
struct
inode
*
ip
)
{
jFYI
(
1
,
(
"jfs_truncate: size = 0x%lx
\n
"
,
(
ulong
)
ip
->
i_size
));
IWRITE_LOCK
(
ip
);
jfs_truncate_nolock
(
ip
,
ip
->
i_size
);
IWRITE_UNLOCK
(
ip
);
}
static
int
jfs_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
rc
;
...
...
fs/jfs/inode.c
View file @
ebf488f2
...
...
@@ -59,7 +59,7 @@ struct inode *jfs_iget(struct super_block *sb, ino_t ino)
inode
->
i_mapping
->
a_ops
=
&
jfs_aops
;
inode
->
i_mapping
->
gfp_mask
=
GFP_NOFS
;
}
else
if
(
S_ISLNK
(
inode
->
i_mode
))
{
if
(
inode
->
i_size
>
IDATASIZE
)
{
if
(
inode
->
i_size
>
=
IDATASIZE
)
{
inode
->
i_op
=
&
page_symlink_inode_operations
;
inode
->
i_mapping
->
a_ops
=
&
jfs_aops
;
}
else
...
...
@@ -330,3 +330,58 @@ struct address_space_operations jfs_aops = {
.
bmap
=
jfs_bmap
,
.
direct_IO
=
jfs_direct_IO
,
};
/*
* Guts of jfs_truncate. Called with locks already held. Can be called
* with directory for truncating directory index table.
*/
void
jfs_truncate_nolock
(
struct
inode
*
ip
,
loff_t
length
)
{
loff_t
newsize
;
tid_t
tid
;
ASSERT
(
length
>=
0
);
if
(
test_cflag
(
COMMIT_Nolink
,
ip
))
{
xtTruncate
(
0
,
ip
,
length
,
COMMIT_WMAP
);
return
;
}
do
{
tid
=
txBegin
(
ip
->
i_sb
,
0
);
/*
* The commit_sem cannot be taken before txBegin.
* txBegin may block and there is a chance the inode
* could be marked dirty and need to be committed
* before txBegin unblocks
*/
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
newsize
=
xtTruncate
(
tid
,
ip
,
length
,
COMMIT_TRUNCATE
|
COMMIT_PWMAP
);
if
(
newsize
<
0
)
{
txEnd
(
tid
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
break
;
}
ip
->
i_mtime
=
ip
->
i_ctime
=
CURRENT_TIME
;
mark_inode_dirty
(
ip
);
txCommit
(
tid
,
1
,
&
ip
,
0
);
txEnd
(
tid
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
}
while
(
newsize
>
length
);
/* Truncate isn't always atomic */
}
void
jfs_truncate
(
struct
inode
*
ip
)
{
jFYI
(
1
,
(
"jfs_truncate: size = 0x%lx
\n
"
,
(
ulong
)
ip
->
i_size
));
block_truncate_page
(
ip
->
i_mapping
,
ip
->
i_size
,
jfs_get_block
);
IWRITE_LOCK
(
ip
);
jfs_truncate_nolock
(
ip
,
ip
->
i_size
);
IWRITE_UNLOCK
(
ip
);
}
fs/jfs/jfs_debug.c
View file @
ebf488f2
...
...
@@ -100,6 +100,7 @@ static int loglevel_write(struct file *file, const char *buffer,
#ifdef CONFIG_JFS_STATISTICS
extern
read_proc_t
jfs_lmstats_read
;
extern
read_proc_t
jfs_txstats_read
;
extern
read_proc_t
jfs_xtstat_read
;
extern
read_proc_t
jfs_mpstat_read
;
#endif
...
...
@@ -111,6 +112,7 @@ static struct {
}
Entries
[]
=
{
#ifdef CONFIG_JFS_STATISTICS
{
"lmstats"
,
jfs_lmstats_read
,
},
{
"txstats"
,
jfs_txstats_read
,
},
{
"xtstat"
,
jfs_xtstat_read
,
},
{
"mpstat"
,
jfs_mpstat_read
,
},
#endif
...
...
fs/jfs/jfs_dtree.c
View file @
ebf488f2
...
...
@@ -199,6 +199,28 @@ static void dtLinelockFreelist(dtpage_t * p, int m, struct dt_lock ** dtlock);
#define ciToUpper(c) UniStrupr((c)->name)
/*
* read_index_page()
*
* Reads a page of a directory's index table.
* Having metadata mapped into the directory inode's address space
* presents a multitude of problems. We avoid this by mapping to
* the absolute address space outside of the *_metapage routines
*/
static
struct
metapage
*
read_index_page
(
struct
inode
*
inode
,
s64
blkno
)
{
int
rc
;
s64
xaddr
;
int
xflag
;
s32
xlen
;
rc
=
xtLookup
(
inode
,
blkno
,
1
,
&
xflag
,
&
xaddr
,
&
xlen
,
1
);
if
(
rc
||
(
xlen
==
0
))
return
NULL
;
return
read_metapage
(
inode
,
xaddr
,
PSIZE
,
1
);
}
/*
* find_index()
*
...
...
@@ -208,7 +230,7 @@ static void dtLinelockFreelist(dtpage_t * p, int m, struct dt_lock ** dtlock);
* mp must be released by caller.
*/
static
struct
dir_table_slot
*
find_index
(
struct
inode
*
ip
,
u32
index
,
struct
metapage
**
mp
)
struct
metapage
**
mp
,
s64
*
lblock
)
{
struct
jfs_inode_info
*
jfs_ip
=
JFS_IP
(
ip
);
s64
blkno
;
...
...
@@ -243,12 +265,14 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index,
blkno
=
((
offset
+
1
)
>>
L2PSIZE
)
<<
JFS_SBI
(
ip
->
i_sb
)
->
l2nbperpage
;
if
(
*
mp
&&
(
(
*
mp
)
->
index
!=
blkno
))
{
if
(
*
mp
&&
(
*
lblock
!=
blkno
))
{
release_metapage
(
*
mp
);
*
mp
=
0
;
}
if
(
*
mp
==
0
)
*
mp
=
read_metapage
(
ip
,
blkno
,
PSIZE
,
0
);
if
(
*
mp
==
0
)
{
*
lblock
=
blkno
;
*
mp
=
read_index_page
(
ip
,
blkno
);
}
if
(
*
mp
==
0
)
{
jERROR
(
1
,
(
"free_index: error reading directory table
\n
"
));
...
...
@@ -368,7 +392,7 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
ip
->
i_size
=
PSIZE
;
ip
->
i_blocks
+=
LBLK2PBLK
(
sb
,
sbi
->
nbperpage
);
if
((
mp
=
get_metapage
(
ip
,
0
,
ip
->
i_blksize
,
0
))
==
0
)
{
if
((
mp
=
read_index_page
(
ip
,
0
))
==
0
)
{
jERROR
(
1
,
(
"add_index: get_metapage failed!
\n
"
));
xtTruncate
(
tid
,
ip
,
0
,
COMMIT_PWMAP
);
return
-
1
;
...
...
@@ -411,12 +435,12 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
ip
->
i_size
+=
PSIZE
;
ip
->
i_blocks
+=
LBLK2PBLK
(
sb
,
sbi
->
nbperpage
);
if
((
mp
=
get_metapage
(
ip
,
blkno
,
PSIZE
,
0
)))
if
((
mp
=
read_index_page
(
ip
,
blkno
)))
memset
(
mp
->
data
,
0
,
PSIZE
);
/* Just looks better */
else
xtTruncate
(
tid
,
ip
,
offset
,
COMMIT_PWMAP
);
}
else
mp
=
read_
metapage
(
ip
,
blkno
,
PSIZE
,
0
);
mp
=
read_
index_page
(
ip
,
blkno
);
if
(
mp
==
0
)
{
jERROR
(
1
,
(
"add_index: get/read_metapage failed!
\n
"
));
...
...
@@ -445,9 +469,10 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
static
void
free_index
(
tid_t
tid
,
struct
inode
*
ip
,
u32
index
,
u32
next
)
{
struct
dir_table_slot
*
dirtab_slot
;
s64
lblock
;
struct
metapage
*
mp
=
0
;
dirtab_slot
=
find_index
(
ip
,
index
,
&
mp
);
dirtab_slot
=
find_index
(
ip
,
index
,
&
mp
,
&
lblock
);
if
(
dirtab_slot
==
0
)
return
;
...
...
@@ -470,11 +495,11 @@ static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next)
* Changes an entry in the directory index table
*/
static
void
modify_index
(
tid_t
tid
,
struct
inode
*
ip
,
u32
index
,
s64
bn
,
int
slot
,
struct
metapage
**
mp
)
int
slot
,
struct
metapage
**
mp
,
u64
*
lblock
)
{
struct
dir_table_slot
*
dirtab_slot
;
dirtab_slot
=
find_index
(
ip
,
index
,
mp
);
dirtab_slot
=
find_index
(
ip
,
index
,
mp
,
lblock
);
if
(
dirtab_slot
==
0
)
return
;
...
...
@@ -497,10 +522,11 @@ static void modify_index(tid_t tid, struct inode *ip, u32 index, s64 bn,
static
int
read_index
(
struct
inode
*
ip
,
u32
index
,
struct
dir_table_slot
*
dirtab_slot
)
{
s64
lblock
;
struct
metapage
*
mp
=
0
;
struct
dir_table_slot
*
slot
;
slot
=
find_index
(
ip
,
index
,
&
mp
);
slot
=
find_index
(
ip
,
index
,
&
mp
,
&
lblock
);
if
(
slot
==
0
)
{
return
-
EIO
;
}
...
...
@@ -1491,12 +1517,14 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
* Update directory index table for entries now in right page
*/
if
((
rp
->
header
.
flag
&
BT_LEAF
)
&&
DO_INDEX
(
ip
))
{
s64
lblock
;
mp
=
0
;
stbl
=
DT_GETSTBL
(
rp
);
for
(
n
=
0
;
n
<
rp
->
header
.
nextindex
;
n
++
)
{
ldtentry
=
(
struct
ldtentry
*
)
&
rp
->
slot
[
stbl
[
n
]];
modify_index
(
tid
,
ip
,
le32_to_cpu
(
ldtentry
->
index
),
rbn
,
n
,
&
mp
);
rbn
,
n
,
&
mp
,
&
lblock
);
}
if
(
mp
)
release_metapage
(
mp
);
...
...
@@ -1616,6 +1644,8 @@ static int dtExtendPage(tid_t tid,
* Update directory index table to reflect new page address
*/
if
(
DO_INDEX
(
ip
))
{
s64
lblock
;
mp
=
0
;
stbl
=
DT_GETSTBL
(
sp
);
for
(
n
=
0
;
n
<
sp
->
header
.
nextindex
;
n
++
)
{
...
...
@@ -1623,7 +1653,7 @@ static int dtExtendPage(tid_t tid,
(
struct
ldtentry
*
)
&
sp
->
slot
[
stbl
[
n
]];
modify_index
(
tid
,
ip
,
le32_to_cpu
(
ldtentry
->
index
),
xaddr
,
n
,
&
mp
);
xaddr
,
n
,
&
mp
,
&
lblock
);
}
if
(
mp
)
release_metapage
(
mp
);
...
...
@@ -1911,6 +1941,7 @@ static int dtSplitRoot(tid_t tid,
* Update directory index table for entries now in right page
*/
if
((
rp
->
header
.
flag
&
BT_LEAF
)
&&
DO_INDEX
(
ip
))
{
s64
lblock
;
struct
metapage
*
mp
=
0
;
struct
ldtentry
*
ldtentry
;
...
...
@@ -1918,7 +1949,7 @@ static int dtSplitRoot(tid_t tid,
for
(
n
=
0
;
n
<
rp
->
header
.
nextindex
;
n
++
)
{
ldtentry
=
(
struct
ldtentry
*
)
&
rp
->
slot
[
stbl
[
n
]];
modify_index
(
tid
,
ip
,
le32_to_cpu
(
ldtentry
->
index
),
rbn
,
n
,
&
mp
);
rbn
,
n
,
&
mp
,
&
lblock
);
}
if
(
mp
)
release_metapage
(
mp
);
...
...
@@ -2120,6 +2151,8 @@ int dtDelete(tid_t tid,
* Update directory index table for entries moved in stbl
*/
if
(
DO_INDEX
(
ip
)
&&
index
<
p
->
header
.
nextindex
)
{
s64
lblock
;
imp
=
0
;
stbl
=
DT_GETSTBL
(
p
);
for
(
i
=
index
;
i
<
p
->
header
.
nextindex
;
i
++
)
{
...
...
@@ -2127,7 +2160,7 @@ int dtDelete(tid_t tid,
(
struct
ldtentry
*
)
&
p
->
slot
[
stbl
[
i
]];
modify_index
(
tid
,
ip
,
le32_to_cpu
(
ldtentry
->
index
),
bn
,
i
,
&
imp
);
bn
,
i
,
&
imp
,
&
lblock
);
}
if
(
imp
)
release_metapage
(
imp
);
...
...
@@ -2769,12 +2802,6 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
set_cflag
(
COMMIT_Stale
,
ip
);
tblk
->
xflag
=
xflag_save
;
/*
* Tells jfs_metapage code that the metadata pages
* for the index table are no longer useful, and
* remove them from page cache.
*/
invalidate_inode_metapages
(
ip
);
}
else
ip
->
i_size
=
1
;
...
...
@@ -3919,6 +3946,8 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
memmove
(
stbl
+
index
+
1
,
stbl
+
index
,
nextindex
-
index
);
if
((
p
->
header
.
flag
&
BT_LEAF
)
&&
data
->
leaf
.
ip
)
{
s64
lblock
;
/*
* Need to update slot number for entries that moved
* in the stbl
...
...
@@ -3928,7 +3957,7 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
lh
=
(
struct
ldtentry
*
)
&
(
p
->
slot
[
stbl
[
n
]]);
modify_index
(
data
->
leaf
.
tid
,
data
->
leaf
.
ip
,
le32_to_cpu
(
lh
->
index
),
bn
,
n
,
&
mp
);
&
mp
,
&
lblock
);
}
if
(
mp
)
release_metapage
(
mp
);
...
...
fs/jfs/jfs_imap.c
View file @
ebf488f2
...
...
@@ -1170,7 +1170,7 @@ int diFree(struct inode *ip)
* invalidate any page of the inode extent freed from buffer cache;
*/
freepxd
=
iagp
->
inoext
[
extno
];
invalidate_pxd_metapages
(
ip
->
i_sb
->
s_bdev
->
bd_inode
,
freepxd
);
invalidate_pxd_metapages
(
ip
,
freepxd
);
/*
* update iag list(s) (careful update step 2)
...
...
fs/jfs/jfs_incore.h
View file @
ebf488f2
...
...
@@ -54,7 +54,6 @@ struct jfs_inode_info {
lid_t
atlhead
;
/* anonymous tlock list head */
lid_t
atltail
;
/* anonymous tlock list tail */
struct
list_head
anon_inode_list
;
/* inodes having anonymous txns */
struct
list_head
mp_list
;
/* metapages in inode's address space */
/*
* rdwrlock serializes xtree between reads & writes and synchronizes
* changes to special inodes. It's use would be redundant on
...
...
fs/jfs/jfs_logmgr.c
View file @
ebf488f2
...
...
@@ -197,6 +197,8 @@ struct lmStat {
uint
commit
;
/* # of commit */
uint
pagedone
;
/* # of page written */
uint
submitted
;
/* # of pages submitted */
uint
full_page
;
/* # of full pages submitted */
uint
partial_page
;
/* # of partial pages submitted */
}
lmStat
;
#endif
...
...
@@ -597,21 +599,21 @@ static int lmNextPage(struct jfs_log * log)
/* mark tblk for end-of-page */
tblk
->
flag
|=
tblkGC_EOP
;
/* if page is not already on write queue,
* just enqueue (no lbmWRITE to prevent redrive)
* buffer to wqueue to ensure correct serial order
* of the pages since log pages will be added
* continuously (tblk bound with the page hasn't
* got around to init write of the page, either
* preempted or the page got filled by its COMMIT
* record);
* pages with COMMIT are paged out explicitly by
* tblk in lmGroupCommit();
*/
if
(
bp
->
l_wqnext
==
NULL
)
{
/* bp->l_ceor = bp->l_eor;
*/
/* lp->h.eor = lp->t.eor = bp->l_ceor; */
l
bmWrite
(
log
,
bp
,
0
,
0
);
if
(
log
->
cflag
&
logGC_PAGEOUT
)
{
/* if page is not already on write queue,
* just enqueue (no lbmWRITE to prevent redrive)
* buffer to wqueue to ensure correct serial order
* of the pages since log pages will be added
* continuously
*/
if
(
bp
->
l_wqnext
==
NULL
)
lbmWrite
(
log
,
bp
,
0
,
0
);
}
else
{
/*
* No current GC leader, initiate group commit
*/
log
->
cflag
|=
logGC_PAGEOUT
;
l
mGCwrite
(
log
,
0
);
}
}
/* page is not bound with outstanding tblk:
...
...
@@ -678,10 +680,17 @@ int lmGroupCommit(struct jfs_log * log, struct tblock * tblk)
LOGGC_UNLOCK
(
log
);
return
rc
;
}
jFYI
(
1
,
(
"lmGroup Commit: tblk = 0x%p, gcrtc = %d
\n
"
,
tblk
,
log
->
gcrtc
));
jFYI
(
1
,
(
"lmGroup Commit: tblk = 0x%p, gcrtc = %d
\n
"
,
tblk
,
log
->
gcrtc
));
if
(
tblk
->
xflag
&
COMMIT_LAZY
)
{
/*
* Lazy transactions can leave now
*/
tblk
->
flag
|=
tblkGC_LAZY
;
LOGGC_UNLOCK
(
log
);
return
0
;
}
/*
* group commit pageout in progress
*/
...
...
@@ -709,12 +718,6 @@ int lmGroupCommit(struct jfs_log * log, struct tblock * tblk)
/* upcount transaction waiting for completion
*/
log
->
gcrtc
++
;
if
(
tblk
->
xflag
&
COMMIT_LAZY
)
{
tblk
->
flag
|=
tblkGC_LAZY
;
LOGGC_UNLOCK
(
log
);
return
0
;
}
tblk
->
flag
|=
tblkGC_READY
;
__SLEEP_COND
(
tblk
->
gcwait
,
(
tblk
->
flag
&
tblkGC_COMMITTED
),
...
...
@@ -785,6 +788,7 @@ void lmGCwrite(struct jfs_log * log, int cant_write)
bp
->
l_ceor
));
lbmWrite
(
log
,
bp
,
lbmWRITE
|
lbmRELEASE
|
lbmGC
,
cant_write
);
INCREMENT
(
lmStat
.
full_page
);
}
/* page is not yet full */
else
{
...
...
@@ -794,6 +798,7 @@ void lmGCwrite(struct jfs_log * log, int cant_write)
(
"gc: tclsn:0x%x, bceor:0x%x
\n
"
,
tblk
->
clsn
,
bp
->
l_ceor
));
lbmWrite
(
log
,
bp
,
lbmWRITE
|
lbmGC
,
cant_write
);
INCREMENT
(
lmStat
.
partial_page
);
}
}
...
...
@@ -881,11 +886,15 @@ void lmPostGC(struct lbuf * bp)
/* are there any transactions who have entered lnGroupCommit()
* (whose COMMITs are after that of the last log page written.
* They are waiting for new group commit (above at (SLEEP 1)):
* They are waiting for new group commit (above at (SLEEP 1))
* or lazy transactions are on a full (queued) log page,
* select the latest ready transaction as new group leader and
* wake her up to lead her group.
*/
if
((
log
->
gcrtc
>
0
)
&&
log
->
cqueue
.
head
)
if
((
tblk
=
log
->
cqueue
.
head
)
&&
((
log
->
gcrtc
>
0
)
||
(
tblk
->
bp
->
l_wqnext
!=
NULL
)
||
test_bit
(
log_SYNCBARRIER
,
&
log
->
flag
)
||
test_bit
(
log_QUIESCE
,
&
log
->
flag
)))
/*
* Call lmGCwrite with new group leader
*/
...
...
@@ -1042,6 +1051,16 @@ int lmLogSync(struct jfs_log * log, int nosyncwait)
log
->
syncpt
));
}
/*
* We may have to initiate group commit
*/
LOGGC_LOCK
(
log
);
if
(
log
->
cqueue
.
head
&&
!
(
log
->
cflag
&
logGC_PAGEOUT
))
{
log
->
cflag
|=
logGC_PAGEOUT
;
lmGCwrite
(
log
,
0
);
}
LOGGC_UNLOCK
(
log
);
return
lsn
;
}
...
...
@@ -1407,6 +1426,22 @@ void lmLogWait(struct jfs_log *log)
jFYI
(
1
,
(
"lmLogWait: log:0x%p
\n
"
,
log
));
/*
* This ensures that we will keep writing to the journal as long
* as there are unwritten commit records
*/
set_bit
(
log_QUIESCE
,
&
log
->
flag
);
/*
* Initiate I/O on outstanding transactions
*/
LOGGC_LOCK
(
log
);
if
(
log
->
cqueue
.
head
&&
!
(
log
->
cflag
&
logGC_PAGEOUT
))
{
log
->
cflag
|=
logGC_PAGEOUT
;
lmGCwrite
(
log
,
0
);
}
LOGGC_UNLOCK
(
log
);
if
(
log
->
cqueue
.
head
||
!
list_empty
(
&
log
->
synclist
))
{
/*
* If there was very recent activity, we may need to wait
...
...
@@ -1423,6 +1458,8 @@ void lmLogWait(struct jfs_log *log)
}
assert
(
log
->
cqueue
.
head
==
NULL
);
assert
(
list_empty
(
&
log
->
synclist
));
clear_bit
(
log_QUIESCE
,
&
log
->
flag
);
/* Probably not needed */
}
/*
...
...
@@ -2312,10 +2349,14 @@ int jfs_lmstats_read(char *buffer, char **start, off_t offset, int length,
"================
\n
"
"commits = %d
\n
"
"writes submitted = %d
\n
"
"writes completed = %d
\n
"
,
"writes completed = %d
\n
"
"full pages submitted = %d
\n
"
"partial pages submitted = %d
\n
"
,
lmStat
.
commit
,
lmStat
.
submitted
,
lmStat
.
pagedone
);
lmStat
.
pagedone
,
lmStat
.
full_page
,
lmStat
.
partial_page
);
begin
=
offset
;
*
start
=
buffer
+
begin
;
...
...
fs/jfs/jfs_metapage.c
View file @
ebf488f2
...
...
@@ -317,8 +317,6 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
mp
->
page
=
0
;
mp
->
logical_size
=
size
;
add_to_hash
(
mp
,
hash_ptr
);
if
(
!
absolute
)
list_add
(
&
mp
->
inode_list
,
&
JFS_IP
(
inode
)
->
mp_list
);
spin_unlock
(
&
meta_lock
);
if
(
new
)
{
...
...
@@ -351,8 +349,6 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
freeit:
spin_lock
(
&
meta_lock
);
remove_from_hash
(
mp
,
hash_ptr
);
if
(
!
absolute
)
list_del
(
&
mp
->
inode_list
);
free_metapage
(
mp
);
spin_unlock
(
&
meta_lock
);
return
NULL
;
...
...
@@ -457,8 +453,6 @@ void release_metapage(struct metapage * mp)
spin_unlock
(
&
meta_lock
);
}
else
{
remove_from_hash
(
mp
,
meta_hash
(
mp
->
mapping
,
mp
->
index
));
if
(
!
test_bit
(
META_absolute
,
&
mp
->
flag
))
list_del
(
&
mp
->
inode_list
);
spin_unlock
(
&
meta_lock
);
if
(
mp
->
page
)
{
...
...
@@ -505,7 +499,8 @@ void __invalidate_metapages(struct inode *ip, s64 addr, int len)
struct
metapage
**
hash_ptr
;
unsigned
long
lblock
;
int
l2BlocksPerPage
=
PAGE_CACHE_SHIFT
-
ip
->
i_blkbits
;
struct
address_space
*
mapping
=
ip
->
i_mapping
;
/* All callers are interested in block device's mapping */
struct
address_space
*
mapping
=
ip
->
i_sb
->
s_bdev
->
bd_inode
->
i_mapping
;
struct
metapage
*
mp
;
struct
page
*
page
;
...
...
@@ -535,26 +530,6 @@ void __invalidate_metapages(struct inode *ip, s64 addr, int len)
}
}
void
invalidate_inode_metapages
(
struct
inode
*
inode
)
{
struct
list_head
*
ptr
;
struct
metapage
*
mp
;
spin_lock
(
&
meta_lock
);
list_for_each
(
ptr
,
&
JFS_IP
(
inode
)
->
mp_list
)
{
mp
=
list_entry
(
ptr
,
struct
metapage
,
inode_list
);
clear_bit
(
META_dirty
,
&
mp
->
flag
);
set_bit
(
META_discard
,
&
mp
->
flag
);
kunmap
(
mp
->
page
);
page_cache_release
(
mp
->
page
);
INCREMENT
(
mpStat
.
pagefree
);
mp
->
data
=
0
;
mp
->
page
=
0
;
}
spin_unlock
(
&
meta_lock
);
truncate_inode_pages
(
inode
->
i_mapping
,
0
);
}
#ifdef CONFIG_JFS_STATISTICS
int
jfs_mpstat_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
*
eof
,
void
*
data
)
...
...
fs/jfs/jfs_metapage.h
View file @
ebf488f2
...
...
@@ -38,7 +38,6 @@ struct metapage {
struct
metapage
*
hash_prev
;
struct
metapage
*
hash_next
;
/* Also used for free list */
struct
list_head
inode_list
;
/* per-inode metapage list */
/*
* mapping & index become redundant, but we need these here to
* add the metapage to the hash before we have the real page
...
...
@@ -109,9 +108,7 @@ extern void __invalidate_metapages(struct inode *, s64, int);
__invalidate_metapages((ip), addressPXD(&(pxd)), lengthPXD(&(pxd)))
#define invalidate_dxd_metapages(ip, dxd) \
__invalidate_metapages((ip), addressDXD(&(dxd)), lengthDXD(&(dxd)))
#define invalidate_xad_metapages(ip, xad) \
__invalidate_metapages((ip), addressXAD(&(xad)), lengthXAD(&(xad)))
/*
* This one uses mp_list to invalidate all pages for an inode
*/
extern
void
invalidate_inode_metapages
(
struct
inode
*
inode
);
#endif
/* _H_JFS_METAPAGE */
fs/jfs/jfs_txnmgr.c
View file @
ebf488f2
...
...
@@ -70,6 +70,7 @@ static struct {
wait_queue_head_t
freelockwait
;
/* eventlist of free tlock */
wait_queue_head_t
lowlockwait
;
/* eventlist of ample tlocks */
int
tlocksInUse
;
/* Number of tlocks in use */
int
TlocksLow
;
/* Indicates low number of available tlocks */
spinlock_t
LazyLock
;
/* synchronize sync_queue & unlock_queue */
/* struct tblock *sync_queue; * Transactions waiting for data sync */
struct
tblock
*
unlock_queue
;
/* Txns waiting to be released */
...
...
@@ -79,6 +80,20 @@ static struct {
that couldn't be sync'ed */
}
TxAnchor
;
#ifdef CONFIG_JFS_STATISTICS
struct
{
uint
txBegin
;
uint
txBegin_barrier
;
uint
txBegin_lockslow
;
uint
txBegin_freetid
;
uint
txBeginAnon
;
uint
txBeginAnon_barrier
;
uint
txBeginAnon_lockslow
;
uint
txLockAlloc
;
uint
txLockAlloc_freelock
;
}
TxStat
;
#endif
static
int
nTxBlock
=
512
;
/* number of transaction blocks */
struct
tblock
*
TxBlock
;
/* transaction block table */
...
...
@@ -86,7 +101,6 @@ static int nTxLock = 4096; /* number of transaction locks */
static
int
TxLockLWM
=
4096
*
.
4
;
/* Low water mark for number of txLocks used */
static
int
TxLockHWM
=
4096
*
.
8
;
/* High water mark for number of txLocks used */
struct
tlock
*
TxLock
;
/* transaction lock table */
static
int
TlocksLow
=
0
;
/* Indicates low number of available tlocks */
/*
...
...
@@ -143,7 +157,8 @@ struct {
/*
* external references
*/
extern
int
lmGroupCommit
(
struct
jfs_log
*
log
,
struct
tblock
*
tblk
);
extern
int
lmGroupCommit
(
struct
jfs_log
*
,
struct
tblock
*
);
extern
int
lmGCwrite
(
struct
jfs_log
*
,
int
);
extern
void
lmSync
(
struct
jfs_log
*
);
extern
int
jfs_commit_inode
(
struct
inode
*
,
int
);
extern
int
jfs_stop_threads
;
...
...
@@ -190,13 +205,18 @@ static lid_t txLockAlloc(void)
{
lid_t
lid
;
INCREMENT
(
TxStat
.
txLockAlloc
);
if
(
!
TxAnchor
.
freelock
)
{
INCREMENT
(
TxStat
.
txLockAlloc_freelock
);
}
while
(
!
(
lid
=
TxAnchor
.
freelock
))
TXN_SLEEP
(
&
TxAnchor
.
freelockwait
);
TxAnchor
.
freelock
=
TxLock
[
lid
].
next
;
HIGHWATERMARK
(
stattx
.
maxlid
,
lid
);
if
((
++
TxAnchor
.
tlocksInUse
>
TxLockHWM
)
&&
(
TlocksLow
==
0
))
{
if
((
++
TxAnchor
.
tlocksInUse
>
TxLockHWM
)
&&
(
T
xAnchor
.
T
locksLow
==
0
))
{
jEVENT
(
0
,(
"txLockAlloc TlocksLow
\n
"
));
TlocksLow
=
1
;
T
xAnchor
.
T
locksLow
=
1
;
wake_up
(
&
jfs_sync_thread_wait
);
}
...
...
@@ -208,9 +228,9 @@ static void txLockFree(lid_t lid)
TxLock
[
lid
].
next
=
TxAnchor
.
freelock
;
TxAnchor
.
freelock
=
lid
;
TxAnchor
.
tlocksInUse
--
;
if
(
TlocksLow
&&
(
TxAnchor
.
tlocksInUse
<
TxLockLWM
))
{
if
(
T
xAnchor
.
T
locksLow
&&
(
TxAnchor
.
tlocksInUse
<
TxLockLWM
))
{
jEVENT
(
0
,(
"txLockFree TlocksLow no more
\n
"
));
TlocksLow
=
0
;
T
xAnchor
.
T
locksLow
=
0
;
TXN_WAKEUP
(
&
TxAnchor
.
lowlockwait
);
}
TXN_WAKEUP
(
&
TxAnchor
.
freelockwait
);
...
...
@@ -322,6 +342,8 @@ tid_t txBegin(struct super_block *sb, int flag)
TXN_LOCK
();
INCREMENT
(
TxStat
.
txBegin
);
retry:
if
(
!
(
flag
&
COMMIT_FORCE
))
{
/*
...
...
@@ -329,6 +351,7 @@ tid_t txBegin(struct super_block *sb, int flag)
*/
if
(
test_bit
(
log_SYNCBARRIER
,
&
log
->
flag
)
||
test_bit
(
log_QUIESCE
,
&
log
->
flag
))
{
INCREMENT
(
TxStat
.
txBegin_barrier
);
TXN_SLEEP
(
&
log
->
syncwait
);
goto
retry
;
}
...
...
@@ -339,7 +362,8 @@ tid_t txBegin(struct super_block *sb, int flag)
* unless COMMIT_FORCE or COMMIT_INODE (which may ultimately
* free tlocks)
*/
if
(
TlocksLow
)
{
if
(
TxAnchor
.
TlocksLow
)
{
INCREMENT
(
TxStat
.
txBegin_lockslow
);
TXN_SLEEP
(
&
TxAnchor
.
lowlockwait
);
goto
retry
;
}
...
...
@@ -350,6 +374,7 @@ tid_t txBegin(struct super_block *sb, int flag)
*/
if
((
t
=
TxAnchor
.
freetid
)
==
0
)
{
jFYI
(
1
,
(
"txBegin: waiting for free tid
\n
"
));
INCREMENT
(
TxStat
.
txBegin_freetid
);
TXN_SLEEP
(
&
TxAnchor
.
freewait
);
goto
retry
;
}
...
...
@@ -359,6 +384,7 @@ tid_t txBegin(struct super_block *sb, int flag)
if
((
tblk
->
next
==
0
)
&&
(
current
!=
jfsCommitTask
))
{
/* Save one tblk for jfsCommit thread */
jFYI
(
1
,
(
"txBegin: waiting for free tid
\n
"
));
INCREMENT
(
TxStat
.
txBegin_freetid
);
TXN_SLEEP
(
&
TxAnchor
.
freewait
);
goto
retry
;
}
...
...
@@ -412,6 +438,7 @@ void txBeginAnon(struct super_block *sb)
log
=
JFS_SBI
(
sb
)
->
log
;
TXN_LOCK
();
INCREMENT
(
TxStat
.
txBeginAnon
);
retry:
/*
...
...
@@ -419,6 +446,7 @@ void txBeginAnon(struct super_block *sb)
*/
if
(
test_bit
(
log_SYNCBARRIER
,
&
log
->
flag
)
||
test_bit
(
log_QUIESCE
,
&
log
->
flag
))
{
INCREMENT
(
TxStat
.
txBeginAnon_barrier
);
TXN_SLEEP
(
&
log
->
syncwait
);
goto
retry
;
}
...
...
@@ -426,7 +454,8 @@ void txBeginAnon(struct super_block *sb)
/*
* Don't begin transaction if we're getting starved for tlocks
*/
if
(
TlocksLow
)
{
if
(
TxAnchor
.
TlocksLow
)
{
INCREMENT
(
TxStat
.
txBeginAnon_lockslow
);
TXN_SLEEP
(
&
TxAnchor
.
lowlockwait
);
goto
retry
;
}
...
...
@@ -1485,10 +1514,6 @@ int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
{
struct
metapage
*
mp
;
pxd_t
*
pxd
;
int
rc
;
s64
xaddr
;
int
xflag
;
s32
xlen
;
mp
=
tlck
->
mp
;
...
...
@@ -1513,13 +1538,7 @@ int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
return
0
;
}
rc
=
xtLookup
(
tlck
->
ip
,
mp
->
index
,
1
,
&
xflag
,
&
xaddr
,
&
xlen
,
1
);
if
(
rc
||
(
xlen
==
0
))
{
jERROR
(
1
,
(
"dataLog: can't find physical address
\n
"
));
return
0
;
}
PXDaddress
(
pxd
,
xaddr
);
PXDaddress
(
pxd
,
mp
->
index
);
PXDlength
(
pxd
,
mp
->
logical_size
>>
tblk
->
sb
->
s_blocksize_bits
);
lrd
->
backchain
=
cpu_to_le32
(
lmLog
(
log
,
tblk
,
lrd
,
tlck
));
...
...
@@ -2752,7 +2771,7 @@ void txLazyCommit(struct tblock * tblk)
tblk
->
flag
|=
tblkGC_COMMITTED
;
if
(
(
tblk
->
flag
&
tblkGC_READY
)
||
(
tblk
->
flag
&
tblkGC_LAZY
)
)
if
(
tblk
->
flag
&
tblkGC_READY
)
log
->
gcrtc
--
;
if
(
tblk
->
flag
&
tblkGC_READY
)
...
...
@@ -2958,6 +2977,16 @@ void txQuiesce(struct super_block *sb)
goto
restart
;
}
TXN_UNLOCK
();
/*
* We may need to kick off the group commit
*/
spin_lock_irq
(
&
log
->
gclock
);
// LOGGC_LOCK
if
(
log
->
cqueue
.
head
&&
!
(
log
->
cflag
&
logGC_PAGEOUT
))
{
log
->
cflag
|=
logGC_PAGEOUT
;
lmGCwrite
(
log
,
0
);
}
spin_unlock_irq
(
&
log
->
gclock
);
// LOGGC_UNLOCK
}
/*
...
...
@@ -3006,7 +3035,7 @@ int jfs_sync(void *arg)
* write each inode on the anonymous inode list
*/
TXN_LOCK
();
while
(
TlocksLow
&&
!
list_empty
(
&
TxAnchor
.
anon_list
))
{
while
(
T
xAnchor
.
T
locksLow
&&
!
list_empty
(
&
TxAnchor
.
anon_list
))
{
jfs_ip
=
list_entry
(
TxAnchor
.
anon_list
.
next
,
struct
jfs_inode_info
,
anon_inode_list
);
...
...
@@ -3097,6 +3126,7 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
"freelockwait = %s
\n
"
"lowlockwait = %s
\n
"
"tlocksInUse = %d
\n
"
"TlocksLow = %d
\n
"
"unlock_queue = 0x%p
\n
"
"unlock_tail = 0x%p
\n
"
,
TxAnchor
.
freetid
,
...
...
@@ -3105,6 +3135,7 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
freelockwait
,
lowlockwait
,
TxAnchor
.
tlocksInUse
,
TxAnchor
.
TlocksLow
,
TxAnchor
.
unlock_queue
,
TxAnchor
.
unlock_tail
);
...
...
@@ -3123,3 +3154,48 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
return
len
;
}
#endif
#if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_STATISTICS)
int
jfs_txstats_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
*
eof
,
void
*
data
)
{
int
len
=
0
;
off_t
begin
;
len
+=
sprintf
(
buffer
,
"JFS TxStats
\n
"
"===========
\n
"
"calls to txBegin = %d
\n
"
"txBegin blocked by sync barrier = %d
\n
"
"txBegin blocked by tlocks low = %d
\n
"
"txBegin blocked by no free tid = %d
\n
"
"calls to txBeginAnon = %d
\n
"
"txBeginAnon blocked by sync barrier = %d
\n
"
"txBeginAnon blocked by tlocks low = %d
\n
"
"calls to txLockAlloc = %d
\n
"
"tLockAlloc blocked by no free lock = %d
\n
"
,
TxStat
.
txBegin
,
TxStat
.
txBegin_barrier
,
TxStat
.
txBegin_lockslow
,
TxStat
.
txBegin_freetid
,
TxStat
.
txBeginAnon
,
TxStat
.
txBeginAnon_barrier
,
TxStat
.
txBeginAnon_lockslow
,
TxStat
.
txLockAlloc
,
TxStat
.
txLockAlloc_freelock
);
begin
=
offset
;
*
start
=
buffer
+
begin
;
len
-=
begin
;
if
(
len
>
length
)
len
=
length
;
else
*
eof
=
1
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
#endif
fs/jfs/jfs_xtree.c
View file @
ebf488f2
...
...
@@ -3517,6 +3517,13 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
xlen
=
lengthXAD
(
xad
);
xaddr
=
addressXAD
(
xad
);
/*
* The "data" for a directory is indexed by the block
* device's address space. This metadata must be invalidated
* here
*/
if
(
S_ISDIR
(
ip
->
i_mode
)
&&
(
teof
==
0
))
invalidate_xad_metapages
(
ip
,
*
xad
);
/*
* entry beyond eof: continue scan of current page
* xad
...
...
fs/jfs/namei.c
View file @
ebf488f2
...
...
@@ -602,7 +602,7 @@ s64 commitZeroLink(tid_t tid, struct inode *ip)
break
;
case
S_IFLNK
:
/* fast symbolic link */
if
(
ip
->
i_size
<
=
256
)
{
if
(
ip
->
i_size
<
IDATASIZE
)
{
ip
->
i_size
=
0
;
return
0
;
}
...
...
@@ -674,7 +674,7 @@ int freeZeroLink(struct inode *ip)
break
;
case
S_IFLNK
:
/* if its contained in inode nothing to do */
if
(
ip
->
i_size
<
=
256
)
if
(
ip
->
i_size
<
IDATASIZE
)
return
0
;
break
;
default:
...
...
fs/jfs/super.c
View file @
ebf488f2
...
...
@@ -412,7 +412,6 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
if
((
flags
&
(
SLAB_CTOR_VERIFY
|
SLAB_CTOR_CONSTRUCTOR
))
==
SLAB_CTOR_CONSTRUCTOR
)
{
INIT_LIST_HEAD
(
&
jfs_ip
->
anon_inode_list
);
INIT_LIST_HEAD
(
&
jfs_ip
->
mp_list
);
init_rwsem
(
&
jfs_ip
->
rdwrlock
);
init_MUTEX
(
&
jfs_ip
->
commit_sem
);
jfs_ip
->
atlhead
=
0
;
...
...
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