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
30a7ddb1
Commit
30a7ddb1
authored
May 20, 2004
by
Dave Kleikamp
Browse files
Options
Browse Files
Download
Plain Diff
Merge jfs@jfs.bkbits.net:linux-2.5
into austin.ibm.com:/shaggy/bk/jfs-2.5
parents
3cab1c95
21776fa3
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
210 additions
and
149 deletions
+210
-149
fs/jfs/jfs_incore.h
fs/jfs/jfs_incore.h
+8
-0
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.c
+32
-30
fs/jfs/jfs_logmgr.h
fs/jfs/jfs_logmgr.h
+1
-4
fs/jfs/jfs_mount.c
fs/jfs/jfs_mount.c
+5
-0
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.c
+94
-70
fs/jfs/jfs_txnmgr.h
fs/jfs/jfs_txnmgr.h
+10
-10
fs/jfs/jfs_types.h
fs/jfs/jfs_types.h
+6
-3
fs/jfs/jfs_umount.c
fs/jfs/jfs_umount.c
+7
-1
fs/jfs/namei.c
fs/jfs/namei.c
+11
-9
fs/jfs/super.c
fs/jfs/super.c
+34
-13
fs/jfs/xattr.c
fs/jfs/xattr.c
+2
-9
No files found.
fs/jfs/jfs_incore.h
View file @
30a7ddb1
...
...
@@ -152,6 +152,11 @@ struct jfs_sb_info {
pxd_t
ait2
;
/* pxd describing AIT copy */
char
uuid
[
16
];
/* 128-bit uuid for volume */
char
loguuid
[
16
];
/* 128-bit uuid for log */
/*
* commit_state is used for synchronization of the jfs_commit
* threads. It is protected by LAZY_LOCK().
*/
int
commit_state
;
/* commit state */
/* Formerly in ipimap */
uint
gengen
;
/* inode generation generator*/
uint
inostamp
;
/* shows inode belongs to fileset*/
...
...
@@ -164,6 +169,9 @@ struct jfs_sb_info {
uint
p_state
;
/* state prior to going no integrity */
};
/* jfs_sb_info commit_state */
#define IN_LAZYCOMMIT 1
static
inline
struct
jfs_inode_info
*
JFS_IP
(
struct
inode
*
inode
)
{
return
list_entry
(
inode
,
struct
jfs_inode_info
,
vfs_inode
);
...
...
fs/jfs/jfs_logmgr.c
View file @
30a7ddb1
...
...
@@ -171,6 +171,7 @@ DECLARE_MUTEX(jfs_log_sem);
extern
void
txLazyUnlock
(
struct
tblock
*
tblk
);
extern
int
jfs_stop_threads
;
extern
struct
completion
jfsIOwait
;
extern
int
jfs_tlocks_low
;
/*
* forward references
...
...
@@ -524,12 +525,7 @@ lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
tblk
->
eor
=
log
->
eor
;
/* enqueue transaction to commit queue */
tblk
->
cqnext
=
NULL
;
if
(
log
->
cqueue
.
head
)
{
log
->
cqueue
.
tail
->
cqnext
=
tblk
;
log
->
cqueue
.
tail
=
tblk
;
}
else
log
->
cqueue
.
head
=
log
->
cqueue
.
tail
=
tblk
;
list_add_tail
(
&
tblk
->
cqueue
,
&
log
->
cqueue
);
LOGGC_UNLOCK
(
log
);
}
...
...
@@ -587,7 +583,10 @@ static int lmNextPage(struct jfs_log * log)
* write or queue the full page at the tail of write queue
*/
/* get the tail tblk on commit queue */
tblk
=
log
->
cqueue
.
tail
;
if
(
list_empty
(
&
log
->
cqueue
))
tblk
=
NULL
;
else
tblk
=
list_entry
(
log
->
cqueue
.
prev
,
struct
tblock
,
cqueue
);
/* every tblk who has COMMIT record on the current page,
* and has not been committed, must be on commit queue
...
...
@@ -688,8 +687,9 @@ int lmGroupCommit(struct jfs_log * log, struct tblock * tblk)
if
(
tblk
->
xflag
&
COMMIT_LAZY
)
tblk
->
flag
|=
tblkGC_LAZY
;
if
((
!
(
log
->
cflag
&
logGC_PAGEOUT
))
&&
log
->
cqueue
.
head
&&
(
!
(
tblk
->
xflag
&
COMMIT_LAZY
)
||
test_bit
(
log_FLUSH
,
&
log
->
flag
)))
{
if
((
!
(
log
->
cflag
&
logGC_PAGEOUT
))
&&
(
!
list_empty
(
&
log
->
cqueue
))
&&
(
!
(
tblk
->
xflag
&
COMMIT_LAZY
)
||
test_bit
(
log_FLUSH
,
&
log
->
flag
)
||
jfs_tlocks_low
))
{
/*
* No pageout in progress
*
...
...
@@ -753,7 +753,7 @@ static void lmGCwrite(struct jfs_log * log, int cant_write)
struct
logpage
*
lp
;
int
gcpn
;
/* group commit page number */
struct
tblock
*
tblk
;
struct
tblock
*
xtblk
;
struct
tblock
*
xtblk
=
NULL
;
/*
* build the commit group of a log page
...
...
@@ -762,15 +762,16 @@ static void lmGCwrite(struct jfs_log * log, int cant_write)
* transactions with COMMIT records on the same log page.
*/
/* get the head tblk on the commit queue */
tblk
=
xtblk
=
log
->
cqueue
.
head
;
gcpn
=
tblk
->
pn
;
gcpn
=
list_entry
(
log
->
cqueue
.
next
,
struct
tblock
,
cqueue
)
->
pn
;
list_for_each_entry
(
tblk
,
&
log
->
cqueue
,
cqueue
)
{
if
(
tblk
->
pn
!=
gcpn
)
break
;
while
(
tblk
&&
tblk
->
pn
==
gcpn
)
{
xtblk
=
tblk
;
/* state transition: (QUEUE, READY) -> COMMIT */
tblk
->
flag
|=
tblkGC_COMMIT
;
tblk
=
tblk
->
cqnext
;
}
tblk
=
xtblk
;
/* last tblk of the page */
...
...
@@ -816,7 +817,7 @@ static void lmPostGC(struct lbuf * bp)
unsigned
long
flags
;
struct
jfs_log
*
log
=
bp
->
l_log
;
struct
logpage
*
lp
;
struct
tblock
*
tblk
;
struct
tblock
*
tblk
,
*
temp
;
//LOGGC_LOCK(log);
spin_lock_irqsave
(
&
log
->
gclock
,
flags
);
...
...
@@ -826,7 +827,9 @@ static void lmPostGC(struct lbuf * bp)
* remove/wakeup transactions from commit queue who were
* group committed with the current log page
*/
while
((
tblk
=
log
->
cqueue
.
head
)
&&
(
tblk
->
flag
&
tblkGC_COMMIT
))
{
list_for_each_entry_safe
(
tblk
,
temp
,
&
log
->
cqueue
,
cqueue
)
{
if
(
!
(
tblk
->
flag
&
tblkGC_COMMIT
))
break
;
/* if transaction was marked GC_COMMIT then
* it has been shipped in the current pageout
* and made it to disk - it is committed.
...
...
@@ -836,11 +839,8 @@ static void lmPostGC(struct lbuf * bp)
tblk
->
flag
|=
tblkGC_ERROR
;
/* remove it from the commit queue */
log
->
cqueue
.
head
=
tblk
->
cqnext
;
if
(
log
->
cqueue
.
head
==
NULL
)
log
->
cqueue
.
tail
=
NULL
;
list_del
(
&
tblk
->
cqueue
);
tblk
->
flag
&=
~
tblkGC_QUEUE
;
tblk
->
cqnext
=
0
;
if
(
tblk
==
log
->
flush_tblk
)
{
/* we can stop flushing the log now */
...
...
@@ -893,9 +893,9 @@ static void lmPostGC(struct lbuf * bp)
* select the latest ready transaction as new group leader and
* wake her up to lead her group.
*/
if
((
tblk
=
log
->
cqueue
.
head
)
&&
if
((
!
list_empty
(
&
log
->
cqueue
)
)
&&
((
log
->
gcrtc
>
0
)
||
(
tblk
->
bp
->
l_wqnext
!=
NULL
)
||
test_bit
(
log_FLUSH
,
&
log
->
flag
)))
test_bit
(
log_FLUSH
,
&
log
->
flag
)
||
jfs_tlocks_low
))
/*
* Call lmGCwrite with new group leader
*/
...
...
@@ -1288,7 +1288,7 @@ int lmLogInit(struct jfs_log * log)
init_waitqueue_head
(
&
log
->
syncwait
);
log
->
cqueue
.
head
=
log
->
cqueue
.
tail
=
NULL
;
INIT_LIST_HEAD
(
&
log
->
cqueue
)
;
log
->
flush_tblk
=
NULL
;
log
->
count
=
0
;
...
...
@@ -1486,6 +1486,7 @@ int lmLogClose(struct super_block *sb)
* in-line log in host file system
*/
rc
=
lmLogShutdown
(
log
);
kfree
(
log
);
goto
out
;
}
...
...
@@ -1515,6 +1516,8 @@ int lmLogClose(struct super_block *sb)
bd_release
(
bdev
);
blkdev_put
(
bdev
);
kfree
(
log
);
out:
up
(
&
jfs_log_sem
);
jfs_info
(
"lmLogClose: exit(%d)"
,
rc
);
...
...
@@ -1535,7 +1538,7 @@ int lmLogClose(struct super_block *sb)
void
jfs_flush_journal
(
struct
jfs_log
*
log
,
int
wait
)
{
int
i
;
struct
tblock
*
target
;
struct
tblock
*
target
=
NULL
;
/* jfs_write_inode may call us during read-only mount */
if
(
!
log
)
...
...
@@ -1545,13 +1548,12 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
LOGGC_LOCK
(
log
);
target
=
log
->
cqueue
.
head
;
if
(
target
)
{
if
(
!
list_empty
(
&
log
->
cqueue
))
{
/*
* This ensures that we will keep writing to the journal as long
* as there are unwritten commit records
*/
target
=
list_entry
(
log
->
cqueue
.
prev
,
struct
tblock
,
cqueue
);
if
(
test_bit
(
log_FLUSH
,
&
log
->
flag
))
{
/*
...
...
@@ -1602,16 +1604,16 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
* If there was recent activity, we may need to wait
* for the lazycommit thread to catch up
*/
if
(
log
->
cqueue
.
head
||
!
list_empty
(
&
log
->
synclist
))
{
if
(
(
!
list_empty
(
&
log
->
cqueue
))
||
!
list_empty
(
&
log
->
synclist
))
{
for
(
i
=
0
;
i
<
800
;
i
++
)
{
/* Too much? */
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
HZ
/
4
);
if
(
(
log
->
cqueue
.
head
==
NULL
)
&&
if
(
list_empty
(
&
log
->
cqueue
)
&&
list_empty
(
&
log
->
synclist
))
break
;
}
}
assert
(
l
og
->
cqueue
.
head
==
NULL
);
assert
(
l
ist_empty
(
&
log
->
cqueue
)
);
assert
(
list_empty
(
&
log
->
synclist
));
clear_bit
(
log_FLUSH
,
&
log
->
flag
);
}
...
...
fs/jfs/jfs_logmgr.h
View file @
30a7ddb1
...
...
@@ -398,10 +398,7 @@ struct jfs_log {
/* commit */
uint
cflag
;
/* 4: */
struct
{
/* 8: FIFO commit queue header */
struct
tblock
*
head
;
struct
tblock
*
tail
;
}
cqueue
;
struct
list_head
cqueue
;
/* FIFO commit queue */
struct
tblock
*
flush_tblk
;
/* tblk we're waiting on for flush */
int
gcrtc
;
/* 4: GC_READY transaction count */
struct
tblock
*
gclrt
;
/* 4: latest GC_READY transaction */
...
...
fs/jfs/jfs_mount.c
View file @
30a7ddb1
...
...
@@ -288,6 +288,11 @@ int jfs_mount_rw(struct super_block *sb, int remount)
*/
logMOUNT
(
sb
);
/*
* Set page cache allocation policy
*/
mapping_set_gfp_mask
(
sb
->
s_bdev
->
bd_inode
->
i_mapping
,
GFP_NOFS
);
return
rc
;
}
...
...
fs/jfs/jfs_txnmgr.c
View file @
30a7ddb1
...
...
@@ -48,6 +48,8 @@
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
...
...
@@ -61,25 +63,22 @@
* transaction management structures
*/
static
struct
{
/* tblock */
int
freetid
;
/* index of a free tid structure */
wait_queue_head_t
freewait
;
/* eventlist of free tblock */
/* tlock */
int
freelock
;
/* index first free lock word */
wait_queue_head_t
freewait
;
/* eventlist of free tblock */
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 */
struct
tblock
*
unlock_tail
;
/* Tail of unlock_queue */
struct
list_head
unlock_queue
;
/* Txns waiting to be released */
struct
list_head
anon_list
;
/* inodes having anonymous txns */
struct
list_head
anon_list2
;
/* inodes having anonymous txns
that couldn't be sync'ed */
}
TxAnchor
;
int
jfs_tlocks_low
;
/* Indicates low number of available tlocks */
#ifdef CONFIG_JFS_STATISTICS
struct
{
uint
txBegin
;
...
...
@@ -95,11 +94,19 @@ struct {
#endif
static
int
nTxBlock
=
512
;
/* number of transaction blocks */
struct
tblock
*
TxBlock
;
/* transaction block table */
module_param
(
nTxBlock
,
int
,
0
);
MODULE_PARM_DESC
(
nTxBlock
,
"Number of transaction blocks (default:512, max:65536)"
);
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 */
module_param
(
nTxLock
,
int
,
0
);
MODULE_PARM_DESC
(
nTxLock
,
"Number of transaction locks (default:4096, max:65536)"
);
struct
tblock
*
TxBlock
;
/* transaction block table */
static
int
TxLockLWM
;
/* Low water mark for number of txLocks used */
static
int
TxLockHWM
;
/* High water mark for number of txLocks used */
static
int
TxLockVHWM
;
/* Very High water mark */
struct
tlock
*
TxLock
;
/* transaction lock table */
...
...
@@ -162,7 +169,6 @@ extern void lmSync(struct jfs_log *);
extern
int
jfs_commit_inode
(
struct
inode
*
,
int
);
extern
int
jfs_stop_threads
;
struct
task_struct
*
jfsCommitTask
;
extern
struct
completion
jfsIOwait
;
/*
...
...
@@ -210,9 +216,9 @@ static lid_t txLockAlloc(void)
TXN_SLEEP
(
&
TxAnchor
.
freelockwait
);
TxAnchor
.
freelock
=
TxLock
[
lid
].
next
;
HIGHWATERMARK
(
stattx
.
maxlid
,
lid
);
if
((
++
TxAnchor
.
tlocksInUse
>
TxLockHWM
)
&&
(
TxAnchor
.
TlocksL
ow
==
0
))
{
jfs_info
(
"txLockAlloc
TlocksL
ow"
);
TxAnchor
.
TlocksL
ow
=
1
;
if
((
++
TxAnchor
.
tlocksInUse
>
TxLockHWM
)
&&
(
jfs_tlocks_l
ow
==
0
))
{
jfs_info
(
"txLockAlloc
tlocks l
ow"
);
jfs_tlocks_l
ow
=
1
;
wake_up
(
&
jfs_sync_thread_wait
);
}
...
...
@@ -224,9 +230,9 @@ static void txLockFree(lid_t lid)
TxLock
[
lid
].
next
=
TxAnchor
.
freelock
;
TxAnchor
.
freelock
=
lid
;
TxAnchor
.
tlocksInUse
--
;
if
(
TxAnchor
.
TlocksL
ow
&&
(
TxAnchor
.
tlocksInUse
<
TxLockLWM
))
{
jfs_info
(
"txLockFree
TlocksL
ow no more"
);
TxAnchor
.
TlocksL
ow
=
0
;
if
(
jfs_tlocks_l
ow
&&
(
TxAnchor
.
tlocksInUse
<
TxLockLWM
))
{
jfs_info
(
"txLockFree
jfs_tlocks_l
ow no more"
);
jfs_tlocks_l
ow
=
0
;
TXN_WAKEUP
(
&
TxAnchor
.
lowlockwait
);
}
TXN_WAKEUP
(
&
TxAnchor
.
freelockwait
);
...
...
@@ -245,12 +251,25 @@ int txInit(void)
{
int
k
,
size
;
/* Verify tunable parameters */
if
(
nTxBlock
<
16
)
nTxBlock
=
16
;
/* No one should set it this low */
if
(
nTxBlock
>
65536
)
nTxBlock
=
65536
;
if
(
nTxLock
<
256
)
nTxLock
=
256
;
/* No one should set it this low */
if
(
nTxLock
>
65536
)
nTxLock
=
65536
;
/*
* initialize transaction block (tblock) table
*
* transaction id (tid) = tblock index
* tid = 0 is reserved.
*/
TxLockLWM
=
(
nTxLock
*
4
)
/
10
;
TxLockHWM
=
(
nTxLock
*
8
)
/
10
;
TxLockVHWM
=
(
nTxLock
*
9
)
/
10
;
size
=
sizeof
(
struct
tblock
)
*
nTxBlock
;
TxBlock
=
(
struct
tblock
*
)
vmalloc
(
size
);
if
(
TxBlock
==
NULL
)
...
...
@@ -295,6 +314,9 @@ int txInit(void)
INIT_LIST_HEAD
(
&
TxAnchor
.
anon_list
);
INIT_LIST_HEAD
(
&
TxAnchor
.
anon_list2
);
LAZY_LOCK_INIT
();
INIT_LIST_HEAD
(
&
TxAnchor
.
unlock_queue
);
stattx
.
maxlid
=
1
;
/* statistics */
return
0
;
...
...
@@ -358,7 +380,7 @@ tid_t txBegin(struct super_block *sb, int flag)
* unless COMMIT_FORCE or COMMIT_INODE (which may ultimately
* free tlocks)
*/
if
(
TxAnchor
.
TlocksLow
)
{
if
(
TxAnchor
.
tlocksInUse
>
TxLockVHWM
)
{
INCREMENT
(
TxStat
.
txBegin_lockslow
);
TXN_SLEEP
(
&
TxAnchor
.
lowlockwait
);
goto
retry
;
...
...
@@ -450,7 +472,7 @@ void txBeginAnon(struct super_block *sb)
/*
* Don't begin transaction if we're getting starved for tlocks
*/
if
(
TxAnchor
.
TlocksLow
)
{
if
(
TxAnchor
.
tlocksInUse
>
TxLockVHWM
)
{
INCREMENT
(
TxStat
.
txBeginAnon_lockslow
);
TXN_SLEEP
(
&
TxAnchor
.
lowlockwait
);
goto
retry
;
...
...
@@ -2559,6 +2581,7 @@ void txFreelock(struct inode *ip)
if
(
!
jfs_ip
->
atlhead
)
return
;
TXN_LOCK
();
xtlck
=
(
struct
tlock
*
)
&
jfs_ip
->
atlhead
;
while
((
lid
=
xtlck
->
next
))
{
...
...
@@ -2579,10 +2602,9 @@ void txFreelock(struct inode *ip)
/*
* If inode was on anon_list, remove it
*/
TXN_LOCK
();
list_del_init
(
&
jfs_ip
->
anon_inode_list
);
TXN_UNLOCK
();
}
TXN_UNLOCK
();
}
...
...
@@ -2707,50 +2729,54 @@ int jfs_lazycommit(void *arg)
int
WorkDone
;
struct
tblock
*
tblk
;
unsigned
long
flags
;
struct
jfs_sb_info
*
sbi
;
daemonize
(
"jfsCommit"
);
jfsCommitTask
=
current
;
LAZY_LOCK_INIT
();
TxAnchor
.
unlock_queue
=
TxAnchor
.
unlock_tail
=
0
;
complete
(
&
jfsIOwait
);
do
{
LAZY_LOCK
(
flags
);
restart:
while
(
!
list_empty
(
&
TxAnchor
.
unlock_queue
))
{
WorkDone
=
0
;
while
((
tblk
=
TxAnchor
.
unlock_queue
))
{
list_for_each_entry
(
tblk
,
&
TxAnchor
.
unlock_queue
,
cqueue
)
{
sbi
=
JFS_SBI
(
tblk
->
sb
);
/*
* We can't get ahead of user thread. Spinning is
* simpler than blocking/waking. We shouldn't spin
* very long, since user thread shouldn't be blocking
* between lmGroupCommit & txEnd.
* For each volume, the transactions must be
* handled in order. If another commit thread
* is handling a tblk for this superblock,
* skip it
*/
if
(
sbi
->
commit_state
&
IN_LAZYCOMMIT
)
continue
;
sbi
->
commit_state
|=
IN_LAZYCOMMIT
;
WorkDone
=
1
;
/*
* Remove first
transaction from queue
* Remove
transaction from queue
*/
TxAnchor
.
unlock_queue
=
tblk
->
cqnext
;
tblk
->
cqnext
=
0
;
if
(
TxAnchor
.
unlock_tail
==
tblk
)
TxAnchor
.
unlock_tail
=
0
;
list_del
(
&
tblk
->
cqueue
);
LAZY_UNLOCK
(
flags
);
txLazyCommit
(
tblk
);
LAZY_LOCK
(
flags
);
sbi
->
commit_state
&=
~
IN_LAZYCOMMIT
;
/*
* We can be running indefinitely if other processors
* are adding transactions to this list
* Don't continue in the for loop. (We can't
* anyway, it's unsafe!) We want to go back to
* the beginning of the list.
*/
cond_resched
();
LAZY_LOCK
(
flags
);
break
;
}
if
(
WorkDone
)
goto
restart
;
/* If there was nothing to do, don't continue */
if
(
!
WorkDone
)
break
;
}
if
(
current
->
flags
&
PF_FREEZE
)
{
LAZY_UNLOCK
(
flags
);
...
...
@@ -2767,7 +2793,7 @@ int jfs_lazycommit(void *arg)
}
}
while
(
!
jfs_stop_threads
);
if
(
TxAnchor
.
unlock_queue
)
if
(
!
list_empty
(
&
TxAnchor
.
unlock_queue
)
)
jfs_err
(
"jfs_lazycommit being killed w/pending transactions!"
);
else
jfs_info
(
"jfs_lazycommit being killed
\n
"
);
...
...
@@ -2780,14 +2806,14 @@ void txLazyUnlock(struct tblock * tblk)
LAZY_LOCK
(
flags
);
if
(
TxAnchor
.
unlock_tail
)
TxAnchor
.
unlock_tail
->
cqnext
=
tblk
;
else
TxAnchor
.
unlock_queue
=
tblk
;
TxAnchor
.
unlock_tail
=
tblk
;
tblk
->
cqnext
=
0
;
LAZY_UNLOCK
(
flags
);
list_add_tail
(
&
tblk
->
cqueue
,
&
TxAnchor
.
unlock_queue
);
/*
* Don't wake up a commit thread if there is already one servicing
* this superblock.
*/
if
(
!
(
JFS_SBI
(
tblk
->
sb
)
->
commit_state
&
IN_LAZYCOMMIT
))
wake_up
(
&
jfs_commit_thread_wait
);
LAZY_UNLOCK
(
flags
);
}
static
void
LogSyncRelease
(
struct
metapage
*
mp
)
...
...
@@ -2821,7 +2847,7 @@ static void LogSyncRelease(struct metapage * mp)
* completion
*
* This does almost the same thing as jfs_sync below. We don't
* worry about deadlocking when
TlocksL
ow is set, since we would
* worry about deadlocking when
jfs_tlocks_l
ow is set, since we would
* expect jfs_sync to get us out of that jam.
*/
void
txQuiesce
(
struct
super_block
*
sb
)
...
...
@@ -2912,7 +2938,7 @@ int jfs_sync(void *arg)
* write each inode on the anonymous inode list
*/
TXN_LOCK
();
while
(
TxAnchor
.
TlocksL
ow
&&
!
list_empty
(
&
TxAnchor
.
anon_list
))
{
while
(
jfs_tlocks_l
ow
&&
!
list_empty
(
&
TxAnchor
.
anon_list
))
{
jfs_ip
=
list_entry
(
TxAnchor
.
anon_list
.
next
,
struct
jfs_inode_info
,
anon_inode_list
);
...
...
@@ -3008,18 +3034,16 @@ 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
"
,
"jfs_tlocks_low = %d
\n
"
"unlock_queue is %sempty
\n
"
,
TxAnchor
.
freetid
,
freewait
,
TxAnchor
.
freelock
,
freelockwait
,
lowlockwait
,
TxAnchor
.
tlocksInUse
,
TxAnchor
.
TlocksLow
,
TxAnchor
.
unlock_queue
,
TxAnchor
.
unlock_tail
);
jfs_tlocks_low
,
list_empty
(
&
TxAnchor
.
unlock_queue
)
?
""
:
"not "
);
begin
=
offset
;
*
start
=
buffer
+
begin
;
...
...
fs/jfs/jfs_txnmgr.h
View file @
30a7ddb1
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2004
*
* 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
...
...
@@ -53,7 +53,7 @@ struct tblock {
u32
logtid
;
/* log transaction id */
/* commit management */
struct
tblock
*
cqnext
;
/* commit queue link
*/
struct
list_head
cqueue
;
/* commit queue list
*/
s32
clsn
;
/* commit lsn */
struct
lbuf
*
bp
;
s32
pn
;
/* commit record log page number */
...
...
@@ -93,16 +93,16 @@ extern struct tblock *TxBlock; /* transaction block table */
* transaction lock
*/
struct
tlock
{
lid_t
next
;
/* index next lockword on tid locklist
lid_t
next
;
/*
2:
index next lockword on tid locklist
* next lockword on freelist
*/
tid_t
tid
;
/* transaction id holding lock */
tid_t
tid
;
/*
2:
transaction id holding lock */
u16
flag
;
/* 2: lock control */
u16
type
;
/* 2: log type */
struct
metapage
*
mp
;
/* 4: object page buffer locked */
struct
inode
*
ip
;
/* 4: object */
struct
metapage
*
mp
;
/* 4
/8
: object page buffer locked */
struct
inode
*
ip
;
/* 4
/8
: object */
/* (16) */
s16
lock
[
24
];
/* 48: overlay area */
...
...
@@ -167,7 +167,7 @@ struct lv {
#define TLOCKLONG 28
struct
linelock
{
u16
next
;
/* 2: next linelock */
lid_t
next
;
/* 2: next linelock */
s8
maxcnt
;
/* 1: */
s8
index
;
/* 1: */
...
...
@@ -183,7 +183,7 @@ struct linelock {
#define dt_lock linelock
struct
xtlock
{
u16
next
;
/* 2: */
lid_t
next
;
/* 2: */
s8
maxcnt
;
/* 1: */
s8
index
;
/* 1: */
...
...
@@ -214,7 +214,7 @@ struct xtlock {
* free maplock (i.e., number of maplock) in the tlock;
*/
struct
maplock
{
u16
next
;
/* 2: */
lid_t
next
;
/* 2: */
u8
maxcnt
;
/* 2: */
u8
index
;
/* 2: next free maplock index */
...
...
@@ -242,7 +242,7 @@ struct maplock {
#define pxd_lock maplock
struct
xdlistlock
{
u16
next
;
/* 2: */
lid_t
next
;
/* 2: */
u8
maxcnt
;
/* 2: */
u8
index
;
/* 2: */
...
...
fs/jfs/jfs_types.h
View file @
30a7ddb1
/*
* Copyright (
c) International Business Machines Corp., 2000-2002
* Copyright (
C) International Business Machines Corp., 2000-2004
*
* 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
...
...
@@ -34,9 +34,12 @@
/*
* transaction and lock id's
*
* Don't change these without carefully considering the impact on the
* size and alignment of all of the linelock variants
*/
typedef
u
int
tid_t
;
typedef
u
int
lid_t
;
typedef
u
16
tid_t
;
typedef
u
16
lid_t
;
/*
* Almost identical to Linux's timespec, but not quite
...
...
fs/jfs/jfs_umount.c
View file @
30a7ddb1
...
...
@@ -121,7 +121,10 @@ int jfs_umount(struct super_block *sb)
* list (to signify skip logredo()).
*/
if
(
log
)
{
/* log = NULL if read-only mount */
rc
=
updateSuper
(
sb
,
FM_CLEAN
);
updateSuper
(
sb
,
FM_CLEAN
);
/* Restore default gfp_mask for bdev */
mapping_set_gfp_mask
(
bdev_mapping
,
GFP_USER
);
/*
* close log:
...
...
@@ -168,5 +171,8 @@ int jfs_umount_rw(struct super_block *sb)
updateSuper
(
sb
,
FM_CLEAN
);
/* Restore default gfp_mask for bdev */
mapping_set_gfp_mask
(
bdev_mapping
,
GFP_USER
);
return
lmLogClose
(
sb
);
}
fs/jfs/namei.c
View file @
30a7ddb1
...
...
@@ -135,7 +135,6 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
insert_inode_hash
(
ip
);
mark_inode_dirty
(
ip
);
d_instantiate
(
dentry
,
ip
);
dip
->
i_ctime
=
dip
->
i_mtime
=
CURRENT_TIME
;
...
...
@@ -150,7 +149,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
}
else
d_instantiate
(
dentry
,
ip
);
out2:
free_UCSname
(
&
dname
);
...
...
@@ -265,7 +265,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
insert_inode_hash
(
ip
);
mark_inode_dirty
(
ip
);
d_instantiate
(
dentry
,
ip
);
/* update parent directory inode */
dip
->
i_nlink
++
;
/* for '..' from child directory */
...
...
@@ -281,7 +280,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
}
else
d_instantiate
(
dentry
,
ip
);
out2:
free_UCSname
(
&
dname
);
...
...
@@ -806,12 +806,14 @@ static int jfs_link(struct dentry *old_dentry,
ip
->
i_ctime
=
CURRENT_TIME
;
mark_inode_dirty
(
dir
);
atomic_inc
(
&
ip
->
i_count
);
d_instantiate
(
dentry
,
ip
);
iplist
[
0
]
=
ip
;
iplist
[
1
]
=
dir
;
rc
=
txCommit
(
tid
,
2
,
&
iplist
[
0
],
0
);
if
(
!
rc
)
d_instantiate
(
dentry
,
ip
);
free_dname:
free_UCSname
(
&
dname
);
...
...
@@ -999,7 +1001,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
insert_inode_hash
(
ip
);
mark_inode_dirty
(
ip
);
d_instantiate
(
dentry
,
ip
);
/*
* commit update of parent directory and link object
...
...
@@ -1028,7 +1029,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
}
else
d_instantiate
(
dentry
,
ip
);
out2:
free_UCSname
(
&
dname
);
...
...
@@ -1368,7 +1370,6 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
insert_inode_hash
(
ip
);
mark_inode_dirty
(
ip
);
d_instantiate
(
dentry
,
ip
);
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
...
...
@@ -1385,7 +1386,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
}
else
d_instantiate
(
dentry
,
ip
);
out1:
free_UCSname
(
&
dname
);
...
...
fs/jfs/super.c
View file @
30a7ddb1
...
...
@@ -23,6 +23,7 @@
#include <linux/parser.h>
#include <linux/completion.h>
#include <linux/vfs.h>
#include <linux/moduleparam.h>
#include <asm/uaccess.h>
#include "jfs_incore.h"
...
...
@@ -44,15 +45,20 @@ static struct super_operations jfs_super_operations;
static
struct
export_operations
jfs_export_operations
;
static
struct
file_system_type
jfs_fs_type
;
#define MAX_COMMIT_THREADS 64
static
int
commit_threads
=
0
;
module_param
(
commit_threads
,
int
,
0
);
MODULE_PARM_DESC
(
commit_threads
,
"Number of commit threads"
);
int
jfs_stop_threads
;
static
pid_t
jfsIOthread
;
static
pid_t
jfsCommitThread
;
static
pid_t
jfsCommitThread
[
MAX_COMMIT_THREADS
]
;
static
pid_t
jfsSyncThread
;
DECLARE_COMPLETION
(
jfsIOwait
);
#ifdef CONFIG_JFS_DEBUG
int
jfsloglevel
=
JFS_LOGLEVEL_WARN
;
MODULE_PARM
(
jfsloglevel
,
"i"
);
module_param
(
jfsloglevel
,
int
,
644
);
MODULE_PARM_DESC
(
jfsloglevel
,
"Specify JFS loglevel (0, 1 or 2)"
);
#endif
...
...
@@ -564,6 +570,7 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
static
int
__init
init_jfs_fs
(
void
)
{
int
i
;
int
rc
;
jfs_inode_cachep
=
...
...
@@ -600,12 +607,23 @@ static int __init init_jfs_fs(void)
}
wait_for_completion
(
&
jfsIOwait
);
/* Wait until thread starts */
jfsCommitThread
=
kernel_thread
(
jfs_lazycommit
,
0
,
CLONE_KERNEL
);
if
(
jfsCommitThread
<
0
)
{
jfs_err
(
"init_jfs_fs: fork failed w/rc = %d"
,
jfsCommitThread
);
goto
kill_iotask
;
if
(
commit_threads
<
1
)
commit_threads
=
num_online_cpus
();
else
if
(
commit_threads
>
MAX_COMMIT_THREADS
)
commit_threads
=
MAX_COMMIT_THREADS
;
for
(
i
=
0
;
i
<
commit_threads
;
i
++
)
{
jfsCommitThread
[
i
]
=
kernel_thread
(
jfs_lazycommit
,
0
,
CLONE_KERNEL
);
if
(
jfsCommitThread
[
i
]
<
0
)
{
jfs_err
(
"init_jfs_fs: fork failed w/rc = %d"
,
jfsCommitThread
[
i
]);
commit_threads
=
i
;
goto
kill_committask
;
}
/* Wait until thread starts */
wait_for_completion
(
&
jfsIOwait
);
}
wait_for_completion
(
&
jfsIOwait
);
/* Wait until thread starts */
jfsSyncThread
=
kernel_thread
(
jfs_sync
,
0
,
CLONE_KERNEL
);
if
(
jfsSyncThread
<
0
)
{
...
...
@@ -622,10 +640,10 @@ static int __init init_jfs_fs(void)
kill_committask:
jfs_stop_threads
=
1
;
wake_up
(
&
jfs_commit_thread_wait
);
wait_for_completion
(
&
jfsIOwait
);
/* Wait for thread exit */
kill_iotask:
jfs_stop_threads
=
1
;
wake_up
_all
(
&
jfs_commit_thread_wait
);
for
(
i
=
0
;
i
<
commit_threads
;
i
++
)
wait_for_completion
(
&
jfsIOwait
);
wake_up
(
&
jfs_IO_thread_wait
);
wait_for_completion
(
&
jfsIOwait
);
/* Wait for thread exit */
end_txmngr:
...
...
@@ -639,6 +657,8 @@ static int __init init_jfs_fs(void)
static
void
__exit
exit_jfs_fs
(
void
)
{
int
i
;
jfs_info
(
"exit_jfs_fs called"
);
jfs_stop_threads
=
1
;
...
...
@@ -646,8 +666,9 @@ static void __exit exit_jfs_fs(void)
metapage_exit
();
wake_up
(
&
jfs_IO_thread_wait
);
wait_for_completion
(
&
jfsIOwait
);
/* Wait until IO thread exits */
wake_up
(
&
jfs_commit_thread_wait
);
wait_for_completion
(
&
jfsIOwait
);
/* Wait until Commit thread exits */
wake_up_all
(
&
jfs_commit_thread_wait
);
for
(
i
=
0
;
i
<
commit_threads
;
i
++
)
wait_for_completion
(
&
jfsIOwait
);
wake_up
(
&
jfs_sync_thread_wait
);
wait_for_completion
(
&
jfsIOwait
);
/* Wait until Sync thread exits */
#ifdef PROC_FS_JFS
...
...
fs/jfs/xattr.c
View file @
30a7ddb1
...
...
@@ -550,7 +550,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
}
ea_buf
->
flag
=
EA_EXTENT
;
ea_buf
->
mp
=
read_metapage
(
inode
,
addressDXD
(
&
ji
->
ea
),
lengthDXD
(
&
ji
->
ea
),
1
);
lengthDXD
(
&
ji
->
ea
)
<<
sb
->
s_blocksize_bits
,
1
);
if
(
ea_buf
->
mp
==
NULL
)
return
-
EIO
;
ea_buf
->
xattr
=
ea_buf
->
mp
->
data
;
...
...
@@ -737,11 +738,7 @@ static int can_set_xattr(struct inode *inode, const char *name,
(
!
S_ISDIR
(
inode
->
i_mode
)
||
inode
->
i_mode
&
S_ISVTX
))
return
-
EPERM
;
#ifdef CONFIG_JFS_POSIX_ACL
return
jfs_permission
(
inode
,
MAY_WRITE
,
NULL
);
#else
return
permission
(
inode
,
MAY_WRITE
,
NULL
);
#endif
}
int
__jfs_setxattr
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
value
,
...
...
@@ -900,13 +897,9 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
static
int
can_get_xattr
(
struct
inode
*
inode
,
const
char
*
name
)
{
#ifdef CONFIG_JFS_POSIX_ACL
if
(
strncmp
(
name
,
XATTR_SYSTEM_PREFIX
,
XATTR_SYSTEM_PREFIX_LEN
)
==
0
)
return
0
;
return
jfs_permission
(
inode
,
MAY_READ
,
NULL
);
#else
return
permission
(
inode
,
MAY_READ
,
NULL
);
#endif
}
ssize_t
__jfs_getxattr
(
struct
inode
*
inode
,
const
char
*
name
,
void
*
data
,
...
...
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