Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
fde6699c
Commit
fde6699c
authored
Aug 04, 2002
by
Dave Kleikamp
Browse files
Options
Browse Files
Download
Plain Diff
Merge kleikamp.austin.ibm.com:/home/shaggy/bk/jfs-2.5
into kleikamp.austin.ibm.com:/home/shaggy/bk/resize-2.5
parents
30c4273f
1c706086
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
266 additions
and
360 deletions
+266
-360
fs/jfs/file.c
fs/jfs/file.c
+10
-2
fs/jfs/inode.c
fs/jfs/inode.c
+4
-10
fs/jfs/jfs_extent.c
fs/jfs/jfs_extent.c
+20
-19
fs/jfs/jfs_incore.h
fs/jfs/jfs_incore.h
+20
-9
fs/jfs/jfs_inode.c
fs/jfs/jfs_inode.c
+0
-37
fs/jfs/jfs_lock.h
fs/jfs/jfs_lock.h
+0
-56
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.c
+0
-2
fs/jfs/jfs_metapage.c
fs/jfs/jfs_metapage.c
+89
-99
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.c
+11
-13
fs/jfs/namei.c
fs/jfs/namei.c
+110
-112
fs/jfs/super.c
fs/jfs/super.c
+2
-1
No files found.
fs/jfs/file.c
View file @
fde6699c
...
...
@@ -38,9 +38,7 @@ int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
if
(
datasync
&&
!
(
inode
->
i_state
&
I_DIRTY_DATASYNC
))
return
rc
;
IWRITE_LOCK
(
inode
);
rc
|=
jfs_commit_inode
(
inode
,
1
);
IWRITE_UNLOCK
(
inode
);
return
rc
?
-
EIO
:
0
;
}
...
...
@@ -64,10 +62,19 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
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
;
}
...
...
@@ -76,6 +83,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
txCommit
(
tid
,
1
,
&
ip
,
0
);
txEnd
(
tid
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
}
while
(
newsize
>
length
);
/* Truncate isn't always atomic */
}
...
...
fs/jfs/inode.c
View file @
fde6699c
...
...
@@ -107,8 +107,10 @@ int jfs_commit_inode(struct inode *inode, int wait)
}
tid
=
txBegin
(
inode
->
i_sb
,
COMMIT_INODE
);
down
(
&
JFS_IP
(
inode
)
->
commit_sem
);
rc
=
txCommit
(
tid
,
1
,
&
inode
,
wait
?
COMMIT_SYNC
:
0
);
txEnd
(
tid
);
up
(
&
JFS_IP
(
inode
)
->
commit_sem
);
return
-
rc
;
}
...
...
@@ -123,25 +125,19 @@ void jfs_write_inode(struct inode *inode, int wait)
!
test_cflag
(
COMMIT_Dirty
,
inode
))
return
;
IWRITE_LOCK
(
inode
);
if
(
jfs_commit_inode
(
inode
,
wait
))
{
jERROR
(
1
,
(
"jfs_write_inode: jfs_commit_inode failed!
\n
"
));
}
IWRITE_UNLOCK
(
inode
);
}
void
jfs_delete_inode
(
struct
inode
*
inode
)
{
jFYI
(
1
,
(
"In jfs_delete_inode, inode = 0x%p
\n
"
,
inode
));
IWRITE_LOCK
(
inode
);
if
(
test_cflag
(
COMMIT_Freewmap
,
inode
))
freeZeroLink
(
inode
);
diFree
(
inode
);
IWRITE_UNLOCK
(
inode
);
clear_inode
(
inode
);
}
...
...
@@ -203,8 +199,7 @@ static int jfs_get_block(struct inode *ip, sector_t lblock,
if
((
no_size_check
||
((
lblock64
<<
ip
->
i_sb
->
s_blocksize_bits
)
<
ip
->
i_size
))
&&
(
xtLookup
(
ip
,
lblock64
,
1
,
&
xflag
,
&
xaddr
,
&
xlen
,
no_size_check
)
(
xtLookup
(
ip
,
lblock64
,
1
,
&
xflag
,
&
xaddr
,
&
xlen
,
no_size_check
)
==
0
)
&&
xlen
)
{
if
(
xflag
&
XAD_NOTRECORDED
)
{
if
(
!
create
)
...
...
@@ -241,8 +236,7 @@ static int jfs_get_block(struct inode *ip, sector_t lblock,
* Allocate a new block
*/
#ifdef _JFS_4K
if
((
rc
=
extHint
(
ip
,
lblock64
<<
ip
->
i_sb
->
s_blocksize_bits
,
&
xad
)))
if
((
rc
=
extHint
(
ip
,
lblock64
<<
ip
->
i_sb
->
s_blocksize_bits
,
&
xad
)))
goto
unlock
;
rc
=
extAlloc
(
ip
,
1
,
lblock64
,
&
xad
,
FALSE
);
if
(
rc
)
...
...
fs/jfs/jfs_extent.c
View file @
fde6699c
...
...
@@ -96,6 +96,9 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
/* This blocks if we are low on resources */
txBeginAnon
(
ip
->
i_sb
);
/* Avoid race with jfs_commit_inode() */
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
/* validate extent length */
if
(
xlen
>
MAXXLEN
)
xlen
=
MAXXLEN
;
...
...
@@ -138,8 +141,8 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
* is smaller than the number of blocks per page.
*/
nxlen
=
xlen
;
if
((
rc
=
extBalloc
(
ip
,
hint
?
hint
:
INOHINT
(
ip
),
&
nxlen
,
&
nxaddr
)))
{
if
((
rc
=
extBalloc
(
ip
,
hint
?
hint
:
INOHINT
(
ip
),
&
nxlen
,
&
nxaddr
)))
{
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
return
(
rc
);
}
...
...
@@ -160,6 +163,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
*/
if
(
rc
)
{
dbFree
(
ip
,
nxaddr
,
nxlen
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
return
(
rc
);
}
...
...
@@ -174,6 +178,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
mark_inode_dirty
(
ip
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
/*
* COMMIT_SyncList flags an anonymous tlock on page that is on
* sync list.
...
...
@@ -217,6 +222,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
/* This blocks if we are low on resources */
txBeginAnon
(
ip
->
i_sb
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
/* validate extent length */
if
(
nxlen
>
MAXXLEN
)
nxlen
=
MAXXLEN
;
...
...
@@ -235,7 +241,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
if
((
xp
->
flag
&
XAD_NOTRECORDED
)
&&
!
abnr
)
{
xp
->
flag
=
0
;
if
((
rc
=
xtUpdate
(
0
,
ip
,
xp
)))
return
(
rc
)
;
goto
exit
;
}
/* try to allocated the request number of blocks for the
...
...
@@ -247,7 +253,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
* space as to satisfy the extend page.
*/
if
((
rc
=
extBrealloc
(
ip
,
xaddr
,
xlen
,
&
nxlen
,
&
nxaddr
)))
return
(
rc
)
;
goto
exit
;
delta
=
nxlen
-
xlen
;
...
...
@@ -284,7 +290,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
/* extend the extent */
if
((
rc
=
xtExtend
(
0
,
ip
,
xoff
+
xlen
,
(
int
)
nextend
,
0
)))
{
dbFree
(
ip
,
xaddr
+
xlen
,
delta
);
return
(
rc
)
;
goto
exit
;
}
}
else
{
/*
...
...
@@ -294,7 +300,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
*/
if
((
rc
=
xtTailgate
(
0
,
ip
,
xoff
,
(
int
)
ntail
,
nxaddr
,
0
)))
{
dbFree
(
ip
,
nxaddr
,
nxlen
);
return
(
rc
)
;
goto
exit
;
}
}
...
...
@@ -325,8 +331,9 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
xp
->
flag
=
xflag
;
mark_inode_dirty
(
ip
);
return
(
0
);
exit:
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
return
(
rc
);
}
...
...
@@ -423,19 +430,13 @@ int extRecord(struct inode *ip, xad_t * xp)
txBeginAnon
(
ip
->
i_sb
);
/* update the extent */
if
((
rc
=
xtUpdate
(
0
,
ip
,
xp
)))
return
(
rc
);
#ifdef _STILL_TO_PORT
/* no longer abnr */
cp
->
cm_abnr
=
FALSE
;
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
/* mark the cbuf as modified */
cp
->
cm_modified
=
TRUE
;
#endif
/* _STILL_TO_PORT */
/* update the extent */
rc
=
xtUpdate
(
0
,
ip
,
xp
);
return
(
0
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
return
(
rc
);
}
...
...
fs/jfs/jfs_incore.h
View file @
fde6699c
...
...
@@ -19,6 +19,7 @@
#ifndef _H_JFS_INCORE
#define _H_JFS_INCORE
#include <linux/rwsem.h>
#include <linux/slab.h>
#include <asm/bitops.h>
#include "jfs_types.h"
...
...
@@ -30,14 +31,6 @@
*/
#define JFS_SUPER_MAGIC 0x3153464a
/* "JFS1" */
/*
* Due to header ordering problems this can't be in jfs_lock.h
*/
typedef
struct
jfs_rwlock
{
struct
rw_semaphore
rw_sem
;
atomic_t
in_use
;
/* for hacked implementation of trylock */
}
jfs_rwlock_t
;
/*
* JFS-private inode information
*/
...
...
@@ -62,7 +55,19 @@ struct jfs_inode_info {
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 */
jfs_rwlock_t
rdwrlock
;
/* read/write lock */
/*
* rdwrlock serializes xtree between reads & writes and synchronizes
* changes to special inodes. It's use would be redundant on
* directories since the i_sem taken in the VFS is sufficient.
*/
struct
rw_semaphore
rdwrlock
;
/*
* commit_sem serializes transaction processing on an inode.
* It must be taken after beginning a transaction (txBegin), since
* dirty inodes may be committed while a new transaction on the
* inode is blocked in txBegin or TxBeginAnon
*/
struct
semaphore
commit_sem
;
lid_t
xtlid
;
/* lid of xtree lock on directory */
union
{
struct
{
...
...
@@ -87,6 +92,12 @@ struct jfs_inode_info {
#define i_dtroot u.dir._dtroot
#define i_inline u.link._inline
#define IREAD_LOCK(ip) down_read(&JFS_IP(ip)->rdwrlock)
#define IREAD_UNLOCK(ip) up_read(&JFS_IP(ip)->rdwrlock)
#define IWRITE_LOCK(ip) down_write(&JFS_IP(ip)->rdwrlock)
#define IWRITE_UNLOCK(ip) up_write(&JFS_IP(ip)->rdwrlock)
/*
* cflag
*/
...
...
fs/jfs/jfs_inode.c
View file @
fde6699c
...
...
@@ -91,40 +91,3 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
return
inode
;
}
/*
* NAME: iwritelocklist()
*
* FUNCTION: Lock multiple inodes in sorted order to avoid deadlock
*
*/
void
iwritelocklist
(
int
n
,
...)
{
va_list
ilist
;
struct
inode
*
sort
[
4
];
struct
inode
*
ip
;
int
k
,
m
;
va_start
(
ilist
,
n
);
for
(
k
=
0
;
k
<
n
;
k
++
)
sort
[
k
]
=
va_arg
(
ilist
,
struct
inode
*
);
va_end
(
ilist
);
/* Bubble sort in descending order */
do
{
m
=
0
;
for
(
k
=
0
;
k
<
n
;
k
++
)
if
((
k
+
1
)
<
n
&&
sort
[
k
+
1
]
->
i_ino
>
sort
[
k
]
->
i_ino
)
{
ip
=
sort
[
k
];
sort
[
k
]
=
sort
[
k
+
1
];
sort
[
k
+
1
]
=
ip
;
m
++
;
}
}
while
(
m
);
/* Lock them */
for
(
k
=
0
;
k
<
n
;
k
++
)
{
IWRITE_LOCK
(
sort
[
k
]);
}
}
fs/jfs/jfs_lock.h
View file @
fde6699c
...
...
@@ -24,63 +24,7 @@
/*
* jfs_lock.h
*
* JFS lock definition for globally referenced locks
*/
/* readers/writer lock: thread-thread */
/*
* RW semaphores do not currently have a trylock function. Since the
* implementation varies by platform, I have implemented a platform-independent
* wrapper around the rw_semaphore routines. If this turns out to be the best
* way of avoiding our locking problems, I will push to get a trylock
* implemented in the kernel, but I'd rather find a way to avoid having to
* use it.
*/
#define RDWRLOCK_T jfs_rwlock_t
static
inline
void
RDWRLOCK_INIT
(
jfs_rwlock_t
*
Lock
)
{
init_rwsem
(
&
Lock
->
rw_sem
);
atomic_set
(
&
Lock
->
in_use
,
0
);
}
static
inline
void
READ_LOCK
(
jfs_rwlock_t
*
Lock
)
{
atomic_inc
(
&
Lock
->
in_use
);
down_read
(
&
Lock
->
rw_sem
);
}
static
inline
void
READ_UNLOCK
(
jfs_rwlock_t
*
Lock
)
{
up_read
(
&
Lock
->
rw_sem
);
atomic_dec
(
&
Lock
->
in_use
);
}
static
inline
void
WRITE_LOCK
(
jfs_rwlock_t
*
Lock
)
{
atomic_inc
(
&
Lock
->
in_use
);
down_write
(
&
Lock
->
rw_sem
);
}
static
inline
int
WRITE_TRYLOCK
(
jfs_rwlock_t
*
Lock
)
{
if
(
atomic_read
(
&
Lock
->
in_use
))
return
0
;
WRITE_LOCK
(
Lock
);
return
1
;
}
static
inline
void
WRITE_UNLOCK
(
jfs_rwlock_t
*
Lock
)
{
up_write
(
&
Lock
->
rw_sem
);
atomic_dec
(
&
Lock
->
in_use
);
}
#define IREAD_LOCK(ip) READ_LOCK(&JFS_IP(ip)->rdwrlock)
#define IREAD_UNLOCK(ip) READ_UNLOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_LOCK(ip) WRITE_LOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_TRYLOCK(ip) WRITE_TRYLOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_UNLOCK(ip) WRITE_UNLOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_LOCK_LIST iwritelocklist
extern
void
iwritelocklist
(
int
,
...);
/*
* Conditional sleep where condition is protected by spinlock
...
...
fs/jfs/jfs_logmgr.c
View file @
fde6699c
...
...
@@ -1524,8 +1524,6 @@ static int lmLogShutdown(log_t * log)
*
* RETURN: 0 - success
* errors returned by vms_iowait().
*
* serialization: IWRITE_LOCK(log inode) held on entry/exit
*/
static
int
lmLogFileSystem
(
log_t
*
log
,
char
*
uuid
,
int
activate
)
{
...
...
fs/jfs/jfs_metapage.c
View file @
fde6699c
...
...
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/buffer_head.h>
#include <linux/mempool.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
...
...
@@ -27,11 +28,6 @@
#include "jfs_debug.h"
extern
struct
task_struct
*
jfsCommitTask
;
static
unsigned
int
metapages
=
1024
;
/* ??? Need a better number */
static
unsigned
int
free_metapages
;
static
metapage_t
*
metapage_buf
;
static
unsigned
long
meta_order
;
static
metapage_t
*
meta_free_list
=
NULL
;
static
spinlock_t
meta_lock
=
SPIN_LOCK_UNLOCKED
;
static
wait_queue_head_t
meta_wait
;
...
...
@@ -93,12 +89,51 @@ static inline void lock_metapage(struct metapage *mp)
__lock_metapage
(
mp
);
}
int
__init
metapage_init
(
void
)
#define METAPOOL_MIN_PAGES 32
static
kmem_cache_t
*
metapage_cache
;
static
mempool_t
*
metapage_mempool
;
static
void
init_once
(
void
*
foo
,
kmem_cache_t
*
cachep
,
unsigned
long
flags
)
{
int
i
;
metapage_t
*
last
=
NULL
;
metapage_t
*
mp
;
metapage_t
*
mp
=
(
metapage_t
*
)
foo
;
if
((
flags
&
(
SLAB_CTOR_VERIFY
|
SLAB_CTOR_CONSTRUCTOR
))
==
SLAB_CTOR_CONSTRUCTOR
)
{
mp
->
lid
=
0
;
mp
->
lsn
=
0
;
mp
->
flag
=
0
;
mp
->
data
=
NULL
;
mp
->
clsn
=
0
;
mp
->
log
=
NULL
;
set_bit
(
META_free
,
&
mp
->
flag
);
init_waitqueue_head
(
&
mp
->
wait
);
}
}
static
inline
metapage_t
*
alloc_metapage
(
int
no_wait
)
{
return
mempool_alloc
(
metapage_mempool
,
no_wait
?
GFP_ATOMIC
:
GFP_NOFS
);
}
static
inline
void
free_metapage
(
metapage_t
*
mp
)
{
mp
->
flag
=
0
;
set_bit
(
META_free
,
&
mp
->
flag
);
mempool_free
(
mp
,
metapage_mempool
);
}
static
void
*
mp_mempool_alloc
(
int
gfp_mask
,
void
*
pool_data
)
{
return
kmem_cache_alloc
(
metapage_cache
,
gfp_mask
);
}
static
void
mp_mempool_free
(
void
*
element
,
void
*
pool_data
)
{
return
kmem_cache_free
(
metapage_cache
,
element
);
}
int
__init
metapage_init
(
void
)
{
/*
* Initialize wait queue
*/
...
...
@@ -107,30 +142,18 @@ int __init metapage_init(void)
/*
* Allocate the metapage structures
*/
for
(
meta_order
=
0
;
((
PAGE_SIZE
<<
meta_order
)
/
sizeof
(
metapage_t
))
<
metapages
;
meta_order
++
);
metapages
=
(
PAGE_SIZE
<<
meta_order
)
/
sizeof
(
metapage_t
);
jFYI
(
1
,
(
"metapage_init: metapage size = %Zd, metapages = %d
\n
"
,
sizeof
(
metapage_t
),
metapages
));
metapage_cache
=
kmem_cache_create
(
"jfs_mp"
,
sizeof
(
metapage_t
),
0
,
0
,
init_once
,
NULL
);
if
(
metapage_cache
==
NULL
)
return
-
ENOMEM
;
metapage_buf
=
(
metapage_t
*
)
__get_free_pages
(
GFP_KERNEL
,
meta_order
);
assert
(
metapage_buf
);
memset
(
metapage_buf
,
0
,
PAGE_SIZE
<<
meta_order
);
metapage_mempool
=
mempool_create
(
METAPOOL_MIN_PAGES
,
mp_mempool_alloc
,
mp_mempool_free
,
NULL
);
mp
=
metapage_buf
;
for
(
i
=
0
;
i
<
metapages
;
i
++
,
mp
++
)
{
mp
->
flag
=
0
;
set_bit
(
META_free
,
&
mp
->
flag
);
init_waitqueue_head
(
&
mp
->
wait
);
mp
->
hash_next
=
last
;
last
=
mp
;
if
(
metapage_mempool
==
NULL
)
{
kmem_cache_destroy
(
metapage_cache
);
return
-
ENOMEM
;
}
meta_free_list
=
last
;
free_metapages
=
metapages
;
/*
* Now the hash list
*/
...
...
@@ -147,64 +170,8 @@ int __init metapage_init(void)
void
metapage_exit
(
void
)
{
free_pages
((
unsigned
long
)
metapage_buf
,
meta_order
);
free_pages
((
unsigned
long
)
hash_table
,
hash_order
);
metapage_buf
=
0
;
/* This is a signal to the jfsIOwait thread */
}
/*
* Get metapage structure from freelist
*
* Caller holds meta_lock
*/
static
metapage_t
*
alloc_metapage
(
int
*
dropped_lock
)
{
metapage_t
*
new
;
*
dropped_lock
=
FALSE
;
/*
* Reserve two metapages for the lazy commit thread. Otherwise
* we may deadlock with holders of metapages waiting for tlocks
* that lazy thread should be freeing.
*/
if
((
free_metapages
<
3
)
&&
(
current
!=
jfsCommitTask
))
{
INCREMENT
(
mpStat
.
allocwait
);
*
dropped_lock
=
TRUE
;
__SLEEP_COND
(
meta_wait
,
(
free_metapages
>
2
),
spin_lock
(
&
meta_lock
),
spin_unlock
(
&
meta_lock
));
}
assert
(
meta_free_list
);
new
=
meta_free_list
;
meta_free_list
=
new
->
hash_next
;
free_metapages
--
;
return
new
;
}
/*
* Put metapage on freelist (holding meta_lock)
*/
static
inline
void
__free_metapage
(
metapage_t
*
mp
)
{
mp
->
flag
=
0
;
set_bit
(
META_free
,
&
mp
->
flag
);
mp
->
hash_next
=
meta_free_list
;
meta_free_list
=
mp
;
free_metapages
++
;
wake_up
(
&
meta_wait
);
}
/*
* Put metapage on freelist (not holding meta_lock)
*/
static
inline
void
free_metapage
(
metapage_t
*
mp
)
{
spin_lock
(
&
meta_lock
);
__free_metapage
(
mp
);
spin_unlock
(
&
meta_lock
);
mempool_destroy
(
metapage_mempool
);
kmem_cache_destroy
(
metapage_cache
);
}
/*
...
...
@@ -307,7 +274,6 @@ metapage_t *__get_metapage(struct inode *inode,
unsigned
long
lblock
,
unsigned
int
size
,
int
absolute
,
unsigned
long
new
)
{
int
dropped_lock
;
metapage_t
**
hash_ptr
;
int
l2BlocksPerPage
;
int
l2bsize
;
...
...
@@ -353,17 +319,43 @@ metapage_t *__get_metapage(struct inode *inode,
jERROR
(
1
,
(
"MetaData crosses page boundary!!
\n
"
));
return
NULL
;
}
/*
* Locks held on aggregate inode pages are usually
* not held long, and they are taken in critical code
* paths (committing dirty inodes, txCommit thread)
*
* Attempt to get metapage without blocking, tapping into
* reserves if necessary.
*/
mp
=
NULL
;
if
(
JFS_IP
(
inode
)
->
fileset
==
AGGREGATE_I
)
{
mp
=
mempool_alloc
(
metapage_mempool
,
GFP_ATOMIC
);
if
(
!
mp
)
{
/*
* mempool is supposed to protect us from
* failing here. We will try a blocking
* call, but a deadlock is possible here
*/
printk
(
KERN_WARNING
"__get_metapage: atomic call to mempool_alloc failed.
\n
"
);
printk
(
KERN_WARNING
"Will attempt blocking call
\n
"
);
}
}
if
(
!
mp
)
{
metapage_t
*
mp2
;
mp
=
alloc_metapage
(
&
dropped_lock
);
if
(
dropped_lock
)
{
/* alloc_metapage blocked, we need to search the hash
* again. (The goto is ugly, maybe we'll clean this
* up in the future.)
spin_unlock
(
&
meta_lock
);
mp
=
mempool_alloc
(
metapage_mempool
,
GFP_NOFS
);
spin_lock
(
&
meta_lock
);
/* we dropped the meta_lock, we need to search the
* hash again.
*/
metapage_t
*
mp2
;
mp2
=
search_hash
(
hash_ptr
,
mapping
,
lblock
);
if
(
mp2
)
{
__
free_metapage
(
mp
);
free_metapage
(
mp
);
mp
=
mp2
;
goto
page_found
;
}
...
...
@@ -416,7 +408,7 @@ metapage_t *__get_metapage(struct inode *inode,
remove_from_hash
(
mp
,
hash_ptr
);
if
(
!
absolute
)
list_del
(
&
mp
->
inode_list
);
__
free_metapage
(
mp
);
free_metapage
(
mp
);
spin_unlock
(
&
meta_lock
);
return
NULL
;
}
...
...
@@ -631,12 +623,10 @@ int jfs_mpstat_read(char *buffer, char **start, off_t offset, int length,
len
+=
sprintf
(
buffer
,
"JFS Metapage statistics
\n
"
"=======================
\n
"
"metapages in use = %d
\n
"
"page allocations = %d
\n
"
"page frees = %d
\n
"
"lock waits = %d
\n
"
"allocation waits = %d
\n
"
,
metapages
-
free_metapages
,
mpStat
.
pagealloc
,
mpStat
.
pagefree
,
mpStat
.
lockwait
,
...
...
fs/jfs/jfs_txnmgr.c
View file @
fde6699c
...
...
@@ -2898,6 +2898,8 @@ int jfs_sync(void)
{
struct
inode
*
ip
;
struct
jfs_inode_info
*
jfs_ip
;
int
rc
;
tid_t
tid
;
lock_kernel
();
...
...
@@ -2927,17 +2929,19 @@ int jfs_sync(void)
ip
=
&
jfs_ip
->
vfs_inode
;
/*
*
We must release the TXN_LOCK since our
*
IWRITE_TRYLOCK implementation may still block
*
down_trylock returns 0 on success. This is
*
inconsistent with spin_trylock.
*/
TXN_UNLOCK
();
if
(
IWRITE_TRYLOCK
(
ip
))
{
if
(
!
down_trylock
(
&
jfs_ip
->
commit_sem
))
{
/*
* inode will be removed from anonymous list
* when it is committed
*/
jfs_commit_inode
(
ip
,
0
);
IWRITE_UNLOCK
(
ip
);
TXN_UNLOCK
();
tid
=
txBegin
(
ip
->
i_sb
,
COMMIT_INODE
);
rc
=
txCommit
(
tid
,
1
,
&
ip
,
0
);
txEnd
(
tid
);
up
(
&
jfs_ip
->
commit_sem
);
/*
* Just to be safe. I don't know how
* long we can run without blocking
...
...
@@ -2945,17 +2949,11 @@ int jfs_sync(void)
cond_resched
();
TXN_LOCK
();
}
else
{
/* We can't get the
write lock
. It may
/* We can't get the
commit semaphore
. It may
* be held by a thread waiting for tlock's
* so let's not block here. Save it to
* put back on the anon_list.
*/
/*
* We released TXN_LOCK, let's make sure
* this inode is still there
*/
TXN_LOCK
();
if
(
TxAnchor
.
anon_list
.
next
!=
&
jfs_ip
->
anon_inode_list
)
continue
;
...
...
fs/jfs/namei.c
View file @
fde6699c
...
...
@@ -69,8 +69,6 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode)
jFYI
(
1
,
(
"jfs_create: dip:0x%p name:%s
\n
"
,
dip
,
dentry
->
d_name
.
name
));
IWRITE_LOCK
(
dip
);
/*
* search parent directory for entry/freespace
* (dtSearch() returns parent directory page pinned)
...
...
@@ -91,12 +89,12 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode)
tid
=
txBegin
(
dip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
dip
)
->
commit_sem
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
((
rc
=
dtSearch
(
dip
,
&
dname
,
&
ino
,
&
btstack
,
JFS_CREATE
)))
{
jERROR
(
1
,
(
"jfs_create: dtSearch returned %d
\n
"
,
rc
));
ip
->
i_nlink
=
0
;
iput
(
ip
);
txEnd
(
tid
);
goto
out2
;
goto
out3
;
}
tblk
=
tid_to_tblock
(
tid
);
...
...
@@ -118,16 +116,11 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode)
ino
=
ip
->
i_ino
;
if
((
rc
=
dtInsert
(
tid
,
dip
,
&
dname
,
&
ino
,
&
btstack
)))
{
jERROR
(
1
,
(
"jfs_create: dtInsert returned %d
\n
"
,
rc
));
/* discard new inode */
ip
->
i_nlink
=
0
;
iput
(
ip
);
if
(
rc
==
EIO
)
txAbort
(
tid
,
1
);
/* Marks Filesystem dirty */
else
txAbort
(
tid
,
0
);
/* Filesystem full */
txEnd
(
tid
);
goto
out2
;
goto
out3
;
}
ip
->
i_op
=
&
jfs_file_inode_operations
;
...
...
@@ -143,14 +136,21 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode)
mark_inode_dirty
(
dip
);
rc
=
txCommit
(
tid
,
2
,
&
iplist
[
0
],
0
);
out3:
txEnd
(
tid
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
out2:
free_UCSname
(
&
dname
);
out1:
IWRITE_UNLOCK
(
dip
);
jFYI
(
1
,
(
"jfs_create: rc:%d
\n
"
,
-
rc
));
return
-
rc
;
}
...
...
@@ -184,8 +184,6 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
jFYI
(
1
,
(
"jfs_mkdir: dip:0x%p name:%s
\n
"
,
dip
,
dentry
->
d_name
.
name
));
IWRITE_LOCK
(
dip
);
/* link count overflow on parent directory ? */
if
(
dip
->
i_nlink
==
JFS_LINK_MAX
)
{
rc
=
EMLINK
;
...
...
@@ -212,12 +210,12 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
tid
=
txBegin
(
dip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
dip
)
->
commit_sem
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
((
rc
=
dtSearch
(
dip
,
&
dname
,
&
ino
,
&
btstack
,
JFS_CREATE
)))
{
jERROR
(
1
,
(
"jfs_mkdir: dtSearch returned %d
\n
"
,
rc
));
ip
->
i_nlink
=
0
;
iput
(
ip
);
txEnd
(
tid
);
goto
out2
;
goto
out3
;
}
tblk
=
tid_to_tblock
(
tid
);
...
...
@@ -239,16 +237,12 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
ino
=
ip
->
i_ino
;
if
((
rc
=
dtInsert
(
tid
,
dip
,
&
dname
,
&
ino
,
&
btstack
)))
{
jERROR
(
1
,
(
"jfs_mkdir: dtInsert returned %d
\n
"
,
rc
));
/* discard new directory inode */
ip
->
i_nlink
=
0
;
iput
(
ip
);
if
(
rc
==
EIO
)
txAbort
(
tid
,
1
);
/* Marks Filesystem dirty */
else
txAbort
(
tid
,
0
);
/* Filesystem full */
txEnd
(
tid
);
goto
out2
;
goto
out3
;
}
ip
->
i_nlink
=
2
;
/* for '.' */
...
...
@@ -267,15 +261,21 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
mark_inode_dirty
(
dip
);
rc
=
txCommit
(
tid
,
2
,
&
iplist
[
0
],
0
);
out3:
txEnd
(
tid
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
out2:
free_UCSname
(
&
dname
);
out1:
IWRITE_UNLOCK
(
dip
);
jFYI
(
1
,
(
"jfs_mkdir: rc:%d
\n
"
,
-
rc
));
return
-
rc
;
}
...
...
@@ -311,24 +311,21 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry)
jFYI
(
1
,
(
"jfs_rmdir: dip:0x%p name:%s
\n
"
,
dip
,
dentry
->
d_name
.
name
));
IWRITE_LOCK_LIST
(
2
,
dip
,
ip
);
/* directory must be empty to be removed */
if
(
!
dtEmpty
(
ip
))
{
IWRITE_UNLOCK
(
ip
);
IWRITE_UNLOCK
(
dip
);
rc
=
ENOTEMPTY
;
goto
out
;
}
if
((
rc
=
get_UCSname
(
&
dname
,
dentry
,
JFS_SBI
(
dip
->
i_sb
)
->
nls_tab
)))
{
IWRITE_UNLOCK
(
ip
);
IWRITE_UNLOCK
(
dip
);
goto
out
;
}
tid
=
txBegin
(
dip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
dip
)
->
commit_sem
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
iplist
[
0
]
=
dip
;
iplist
[
1
]
=
ip
;
...
...
@@ -345,9 +342,8 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry)
if
(
rc
==
EIO
)
txAbort
(
tid
,
1
);
txEnd
(
tid
);
IWRITE_UNLOCK
(
ip
);
IWRITE_UNLOCK
(
dip
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
goto
out2
;
}
...
...
@@ -384,7 +380,8 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry)
txEnd
(
tid
);
IWRITE_UNLOCK
(
ip
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
/*
* Truncating the directory index table is not guaranteed. It
...
...
@@ -397,8 +394,6 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry)
clear_cflag
(
COMMIT_Stale
,
dip
);
}
IWRITE_UNLOCK
(
dip
);
out2:
free_UCSname
(
&
dname
);
...
...
@@ -444,10 +439,13 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
if
((
rc
=
get_UCSname
(
&
dname
,
dentry
,
JFS_SBI
(
dip
->
i_sb
)
->
nls_tab
)))
goto
out
;
IWRITE_LOCK
_LIST
(
2
,
ip
,
d
ip
);
IWRITE_LOCK
(
ip
);
tid
=
txBegin
(
dip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
dip
)
->
commit_sem
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
iplist
[
0
]
=
dip
;
iplist
[
1
]
=
ip
;
...
...
@@ -460,8 +458,9 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
if
(
rc
==
EIO
)
txAbort
(
tid
,
1
);
/* Marks FS Dirty */
txEnd
(
tid
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
IWRITE_UNLOCK
(
ip
);
IWRITE_UNLOCK
(
dip
);
goto
out1
;
}
...
...
@@ -483,8 +482,9 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
if
((
new_size
=
commitZeroLink
(
tid
,
ip
))
<
0
)
{
txAbort
(
tid
,
1
);
/* Marks FS Dirty */
txEnd
(
tid
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
IWRITE_UNLOCK
(
ip
);
IWRITE_UNLOCK
(
dip
);
rc
=
-
new_size
;
/* We return -rc */
goto
out1
;
}
...
...
@@ -511,8 +511,13 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
txEnd
(
tid
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
while
(
new_size
&&
(
rc
==
0
))
{
tid
=
txBegin
(
dip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
new_size
=
xtTruncate_pmap
(
tid
,
ip
,
new_size
);
if
(
new_size
<
0
)
{
txAbort
(
tid
,
1
);
/* Marks FS Dirty */
...
...
@@ -520,6 +525,7 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
}
else
rc
=
txCommit
(
tid
,
2
,
&
iplist
[
0
],
COMMIT_SYNC
);
txEnd
(
tid
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
}
if
(
ip
->
i_nlink
==
0
)
...
...
@@ -539,8 +545,6 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
clear_cflag
(
COMMIT_Stale
,
dip
);
}
IWRITE_UNLOCK
(
dip
);
out1:
free_UCSname
(
&
dname
);
out:
...
...
@@ -764,10 +768,11 @@ int jfs_link(struct dentry *old_dentry,
(
"jfs_link: %s %s
\n
"
,
old_dentry
->
d_name
.
name
,
dentry
->
d_name
.
name
));
IWRITE_LOCK_LIST
(
2
,
dir
,
ip
);
tid
=
txBegin
(
ip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
dir
)
->
commit_sem
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
(
ip
->
i_nlink
==
JFS_LINK_MAX
)
{
rc
=
EMLINK
;
goto
out
;
...
...
@@ -801,11 +806,11 @@ int jfs_link(struct dentry *old_dentry,
rc
=
txCommit
(
tid
,
2
,
&
iplist
[
0
],
0
);
out:
IWRITE_UNLOCK
(
dir
);
IWRITE_UNLOCK
(
ip
);
txEnd
(
tid
);
up
(
&
JFS_IP
(
dir
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
jFYI
(
1
,
(
"jfs_link: rc:%d
\n
"
,
rc
));
return
-
rc
;
}
...
...
@@ -849,12 +854,8 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
jFYI
(
1
,
(
"jfs_symlink: dip:0x%p name:%s
\n
"
,
dip
,
name
));
IWRITE_LOCK
(
dip
);
ssize
=
strlen
(
name
)
+
1
;
tid
=
txBegin
(
dip
->
i_sb
,
0
);
/*
* search parent directory for entry/freespace
* (dtSearch() returns parent directory page pinned)
...
...
@@ -863,23 +864,24 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
if
((
rc
=
get_UCSname
(
&
dname
,
dentry
,
JFS_SBI
(
dip
->
i_sb
)
->
nls_tab
)))
goto
out1
;
if
((
rc
=
dtSearch
(
dip
,
&
dname
,
&
ino
,
&
btstack
,
JFS_CREATE
)))
goto
out2
;
/*
* allocate on-disk/in-memory inode for symbolic link:
* (iAlloc() returns new, locked inode)
*/
ip
=
ialloc
(
dip
,
S_IFLNK
|
0777
);
if
(
ip
==
NULL
)
{
BT_PUTSEARCH
(
&
btstack
);
rc
=
ENOSPC
;
goto
out2
;
}
tid
=
txBegin
(
dip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
dip
)
->
commit_sem
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
((
rc
=
dtSearch
(
dip
,
&
dname
,
&
ino
,
&
btstack
,
JFS_CREATE
)))
goto
out3
;
tblk
=
tid_to_tblock
(
tid
);
tblk
->
xflag
|=
COMMIT_CREATE
;
tblk
->
ip
=
ip
;
...
...
@@ -895,9 +897,7 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
if
((
rc
=
dtInsert
(
tid
,
dip
,
&
dname
,
&
ino
,
&
btstack
)))
{
jERROR
(
1
,
(
"jfs_symlink: dtInsert returned %d
\n
"
,
rc
));
/* discard ne inode */
ip
->
i_nlink
=
0
;
iput
(
ip
);
goto
out2
;
goto
out3
;
}
...
...
@@ -955,10 +955,8 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
if
(
mp
==
NULL
)
{
dtDelete
(
tid
,
dip
,
&
dname
,
&
ino
,
JFS_REMOVE
);
ip
->
i_nlink
=
0
;
iput
(
ip
);
rc
=
EIO
;
goto
out
2
;
goto
out
3
;
}
memcpy
(
mp
->
data
,
name
,
copy_size
);
flush_metapage
(
mp
);
...
...
@@ -977,10 +975,8 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
ip
->
i_blocks
=
LBLK2PBLK
(
sb
,
xlen
);
}
else
{
dtDelete
(
tid
,
dip
,
&
dname
,
&
ino
,
JFS_REMOVE
);
ip
->
i_nlink
=
0
;
iput
(
ip
);
rc
=
ENOSPC
;
goto
out
2
;
goto
out
3
;
}
}
...
...
@@ -1008,14 +1004,19 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
}
else
rc
=
txCommit
(
tid
,
1
,
&
iplist
[
0
],
0
);
out2:
out3:
txEnd
(
tid
);
up
(
&
JFS_IP
(
dip
)
->
commit_sem
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
out2:
free_UCSname
(
&
dname
);
out1:
IWRITE_UNLOCK
(
dip
);
txEnd
(
tid
);
out1:
jFYI
(
1
,
(
"jfs_symlink: rc:%d
\n
"
,
-
rc
));
return
-
rc
;
}
...
...
@@ -1054,19 +1055,6 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
old_ip
=
old_dentry
->
d_inode
;
new_ip
=
new_dentry
->
d_inode
;
if
(
old_dir
==
new_dir
)
{
if
(
new_ip
)
IWRITE_LOCK_LIST
(
3
,
old_dir
,
old_ip
,
new_ip
);
else
IWRITE_LOCK_LIST
(
2
,
old_dir
,
old_ip
);
}
else
{
if
(
new_ip
)
IWRITE_LOCK_LIST
(
4
,
old_dir
,
new_dir
,
old_ip
,
new_ip
);
else
IWRITE_LOCK_LIST
(
3
,
old_dir
,
new_dir
,
old_ip
);
}
if
((
rc
=
get_UCSname
(
&
old_dname
,
old_dentry
,
JFS_SBI
(
old_dir
->
i_sb
)
->
nls_tab
)))
goto
out1
;
...
...
@@ -1112,14 +1100,21 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
rc
=
EMLINK
;
goto
out3
;
}
}
}
else
if
(
new_ip
)
IWRITE_LOCK
(
new_ip
);
/*
* The real work starts here
*/
tid
=
txBegin
(
new_dir
->
i_sb
,
0
);
down
(
&
JFS_IP
(
new_dir
)
->
commit_sem
);
down
(
&
JFS_IP
(
old_ip
)
->
commit_sem
);
if
(
old_dir
!=
new_dir
)
down
(
&
JFS_IP
(
old_dir
)
->
commit_sem
);
if
(
new_ip
)
{
down
(
&
JFS_IP
(
new_ip
)
->
commit_sem
);
/*
* Change existing directory entry to new inode number
*/
...
...
@@ -1247,14 +1242,24 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/*
* Don't unlock new_ip if COMMIT_HOLDLOCK is set
*/
if
(
new_ip
&&
test_cflag
(
COMMIT_Holdlock
,
new_ip
))
if
(
new_ip
&&
test_cflag
(
COMMIT_Holdlock
,
new_ip
))
{
up
(
&
JFS_IP
(
new_ip
)
->
commit_sem
);
new_ip
=
0
;
}
out4:
txEnd
(
tid
);
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
(
new_ip
)
up
(
&
JFS_IP
(
new_ip
)
->
commit_sem
);
while
(
new_size
&&
(
rc
==
0
))
{
tid
=
txBegin
(
new_ip
->
i_sb
,
0
);
down
(
&
JFS_IP
(
new_ip
)
->
commit_sem
);
new_size
=
xtTruncate_pmap
(
tid
,
new_ip
,
new_size
);
if
(
new_size
<
0
)
{
txAbort
(
tid
,
1
);
...
...
@@ -1262,6 +1267,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
}
else
rc
=
txCommit
(
tid
,
1
,
&
new_ip
,
COMMIT_SYNC
);
txEnd
(
tid
);
up
(
&
JFS_IP
(
new_ip
)
->
commit_sem
);
}
if
(
new_ip
&&
(
new_ip
->
i_nlink
==
0
))
set_cflag
(
COMMIT_Nolink
,
new_ip
);
...
...
@@ -1270,12 +1276,8 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
out2:
free_UCSname
(
&
old_dname
);
out1:
IWRITE_UNLOCK
(
old_ip
);
if
(
old_dir
!=
new_dir
)
IWRITE_UNLOCK
(
new_dir
);
if
(
new_ip
)
if
(
new_ip
&&
!
S_ISDIR
(
new_ip
->
i_mode
))
IWRITE_UNLOCK
(
new_ip
);
/*
* Truncating the directory index table is not guaranteed. It
* may need to be done iteratively
...
...
@@ -1287,8 +1289,6 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
clear_cflag
(
COMMIT_Stale
,
old_dir
);
}
IWRITE_UNLOCK
(
old_dir
);
jFYI
(
1
,
(
"jfs_rename: returning %d
\n
"
,
rc
));
return
-
rc
;
}
...
...
@@ -1315,8 +1315,6 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
if
((
rc
=
get_UCSname
(
&
dname
,
dentry
,
JFS_SBI
(
dir
->
i_sb
)
->
nls_tab
)))
goto
out
;
IWRITE_LOCK
(
dir
);
ip
=
ialloc
(
dir
,
mode
);
if
(
ip
==
NULL
)
{
rc
=
ENOSPC
;
...
...
@@ -1325,24 +1323,19 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
tid
=
txBegin
(
dir
->
i_sb
,
0
);
if
((
rc
=
dtSearch
(
dir
,
&
dname
,
&
ino
,
&
btstack
,
JFS_CREATE
)))
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
txEnd
(
tid
);
goto
out1
;
}
down
(
&
JFS_IP
(
dir
)
->
commit_sem
);
down
(
&
JFS_IP
(
ip
)
->
commit_sem
);
if
((
rc
=
dtSearch
(
dir
,
&
dname
,
&
ino
,
&
btstack
,
JFS_CREATE
)))
goto
out3
;
tblk
=
tid_to_tblock
(
tid
);
tblk
->
xflag
|=
COMMIT_CREATE
;
tblk
->
ip
=
ip
;
ino
=
ip
->
i_ino
;
if
((
rc
=
dtInsert
(
tid
,
dir
,
&
dname
,
&
ino
,
&
btstack
)))
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
txEnd
(
tid
);
goto
out1
;
}
if
((
rc
=
dtInsert
(
tid
,
dir
,
&
dname
,
&
ino
,
&
btstack
)))
goto
out3
;
init_special_inode
(
ip
,
ip
->
i_mode
,
rdev
);
...
...
@@ -1357,10 +1350,17 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
iplist
[
0
]
=
dir
;
iplist
[
1
]
=
ip
;
rc
=
txCommit
(
tid
,
2
,
iplist
,
0
);
out3:
txEnd
(
tid
);
up
(
&
JFS_IP
(
ip
)
->
commit_sem
);
up
(
&
JFS_IP
(
dir
)
->
commit_sem
);
if
(
rc
)
{
ip
->
i_nlink
=
0
;
iput
(
ip
);
}
out1:
IWRITE_UNLOCK
(
dir
);
free_UCSname
(
&
dname
);
out:
...
...
@@ -1389,9 +1389,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry)
if
((
rc
=
get_UCSname
(
&
key
,
dentry
,
JFS_SBI
(
dip
->
i_sb
)
->
nls_tab
)))
return
ERR_PTR
(
-
rc
);
IREAD_LOCK
(
dip
);
rc
=
dtSearch
(
dip
,
&
key
,
&
inum
,
&
btstack
,
JFS_LOOKUP
);
IREAD_UNLOCK
(
dip
);
free_UCSname
(
&
key
);
if
(
rc
==
ENOENT
)
{
d_add
(
dentry
,
NULL
);
...
...
fs/jfs/super.c
View file @
fde6699c
...
...
@@ -387,7 +387,8 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
SLAB_CTOR_CONSTRUCTOR
)
{
INIT_LIST_HEAD
(
&
jfs_ip
->
anon_inode_list
);
INIT_LIST_HEAD
(
&
jfs_ip
->
mp_list
);
RDWRLOCK_INIT
(
&
jfs_ip
->
rdwrlock
);
init_rwsem
(
&
jfs_ip
->
rdwrlock
);
init_MUTEX
(
&
jfs_ip
->
commit_sem
);
inode_init_once
(
&
jfs_ip
->
vfs_inode
);
}
}
...
...
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