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
6033f024
Commit
6033f024
authored
May 19, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
80be2217
9b406173
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
325 additions
and
177 deletions
+325
-177
Documentation/filesystems/Locking
Documentation/filesystems/Locking
+1
-1
Documentation/filesystems/porting
Documentation/filesystems/porting
+35
-0
fs/Makefile
fs/Makefile
+1
-1
fs/coda/cnode.c
fs/coda/cnode.c
+50
-50
fs/coda/inode.c
fs/coda/inode.c
+0
-14
fs/inode.c
fs/inode.c
+148
-38
fs/nfs/inode.c
fs/nfs/inode.c
+24
-20
fs/reiserfs/inode.c
fs/reiserfs/inode.c
+32
-30
fs/reiserfs/super.c
fs/reiserfs/super.c
+9
-5
include/linux/fs.h
include/linux/fs.h
+19
-11
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+0
-2
include/linux/reiserfs_fs.h
include/linux/reiserfs_fs.h
+5
-3
kernel/ksyms.c
kernel/ksyms.c
+1
-2
No files found.
Documentation/filesystems/Locking
View file @
6033f024
...
...
@@ -115,7 +115,7 @@ statfs: yes no no
remount_fs: yes yes maybe (see below)
umount_begin: yes no maybe (see below)
->read_inode() is not a method - it's a callback used in iget()
/iget4()
.
->read_inode() is not a method - it's a callback used in iget().
rules for mount_sem are not too nice - it is going to die and be replaced
by better scheme anyway.
...
...
Documentation/filesystems/porting
View file @
6033f024
...
...
@@ -152,3 +152,38 @@ settles down a bit.
s_export_op is now required for exporting a filesystem.
isofs, ext2, ext3, resierfs, fat
can be used as examples of very different filesystems.
---
[mandatory]
iget4() and the read_inode2 callback have been superseded by iget5_locked()
which has the following prototype,
struct inode *iget5_locked(struct super_block *sb, unsigned long ino,
int (*test)(struct inode *, void *),
int (*set)(struct inode *, void *),
void *data);
'test' is an additional function that can be used when the inode
number is not sufficient to identify the actual file object. 'set'
should be a non-blocking function that initializes those parts of a
newly created inode to allow the test function to succeed. 'data' is
passed as an opaque value to both test and set functions.
When the inode has been created by iget5_locked(), it will be returned with
the I_NEW flag set and will still be locked. read_inode has not been
called so the file system still has to finalize the initialization. Once
the inode is initialized it must be unlocked by calling unlock_new_inode().
The filesystem is responsible for setting (and possibly testing) i_ino
when appropriate. There is also a simpler iget_locked function that
just takes the superblock and inode number as arguments and does the
test and set for you.
e.g.
inode = iget_locked(sb, ino);
if (inode->i_state & I_NEW) {
read_inode_from_disk(inode);
unlock_new_inode(inode);
}
fs/Makefile
View file @
6033f024
...
...
@@ -7,7 +7,7 @@
O_TARGET
:=
fs.o
export-objs
:=
filesystems.o open.o dcache.o buffer.o bio.o
export-objs
:=
filesystems.o open.o dcache.o buffer.o bio.o
inode.o
mod-subdirs
:=
nls
obj-y
:=
open.o read_write.o devices.o file_table.o buffer.o
\
...
...
fs/coda/cnode.c
View file @
6033f024
...
...
@@ -25,11 +25,6 @@ inline int coda_isnullfid(ViceFid *fid)
return
1
;
}
static
int
coda_inocmp
(
struct
inode
*
inode
,
unsigned
long
ino
,
void
*
opaque
)
{
return
(
coda_fideq
((
ViceFid
*
)
opaque
,
&
(
ITOC
(
inode
)
->
c_fid
)));
}
static
struct
inode_operations
coda_symlink_inode_operations
=
{
readlink:
page_readlink
,
follow_link:
page_follow_link
,
...
...
@@ -55,26 +50,44 @@ static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
init_special_inode
(
inode
,
inode
->
i_mode
,
attr
->
va_rdev
);
}
static
int
coda_test_inode
(
struct
inode
*
inode
,
void
*
data
)
{
ViceFid
*
fid
=
(
ViceFid
*
)
data
;
return
coda_fideq
(
&
(
ITOC
(
inode
)
->
c_fid
),
fid
);
}
static
int
coda_set_inode
(
struct
inode
*
inode
,
void
*
data
)
{
ViceFid
*
fid
=
(
ViceFid
*
)
data
;
ITOC
(
inode
)
->
c_fid
=
*
fid
;
return
0
;
}
static
int
coda_fail_inode
(
struct
inode
*
inode
,
void
*
data
)
{
return
-
1
;
}
struct
inode
*
coda_iget
(
struct
super_block
*
sb
,
ViceFid
*
fid
,
struct
coda_vattr
*
attr
)
{
struct
inode
*
inode
;
struct
coda_inode_info
*
cii
;
ino_t
ino
=
coda_f2i
(
fid
);
struct
coda_sb_info
*
sbi
=
coda_sbp
(
sb
);
unsigned
long
hash
=
coda_f2i
(
fid
);
inode
=
iget
4
(
sb
,
ino
,
coda_inocmp
,
fid
);
inode
=
iget
5_locked
(
sb
,
hash
,
coda_test_inode
,
coda_set_inode
,
fid
);
if
(
!
inode
)
return
ERR_PTR
(
-
ENOMEM
);
/* check if the inode is already initialized */
if
(
inode
->
i_state
&
I_NEW
)
{
cii
=
ITOC
(
inode
);
if
(
coda_isnullfid
(
&
cii
->
c_fid
))
/* new, empty inode found... initializing */
cii
->
c_fid
=
*
fid
;
/* we shouldnt see inode collisions anymore */
if
(
!
coda_fideq
(
fid
,
&
cii
->
c_fid
))
BUG
();
/* we still need to set i_ino for things like stat(2) */
inode
->
i_ino
=
hash
;
list_add
(
&
cii
->
c_cilist
,
&
sbi
->
sbi_cihead
);
unlock_new_inode
(
inode
);
}
/* always replace the attributes, type might have changed */
coda_fill_inode
(
inode
,
attr
);
...
...
@@ -112,6 +125,7 @@ void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
struct
ViceFid
*
newfid
)
{
struct
coda_inode_info
*
cii
;
unsigned
long
hash
=
coda_f2i
(
newfid
);
cii
=
ITOC
(
inode
);
...
...
@@ -122,41 +136,28 @@ void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
/* XXX we probably need to hold some lock here! */
remove_inode_hash
(
inode
);
cii
->
c_fid
=
*
newfid
;
inode
->
i_ino
=
coda_f2i
(
newfid
)
;
insert_inode_hash
(
inode
);
inode
->
i_ino
=
hash
;
__insert_inode_hash
(
inode
,
hash
);
}
/* convert a fid to an inode. */
struct
inode
*
coda_fid_to_inode
(
ViceFid
*
fid
,
struct
super_block
*
sb
)
{
ino_t
nr
;
struct
inode
*
inode
;
struct
coda_inode_info
*
cii
;
unsigned
long
hash
=
coda_f2i
(
fid
)
;
if
(
!
sb
)
{
printk
(
"coda_fid_to_inode: no sb!
\n
"
);
return
NULL
;
}
nr
=
coda_f2i
(
fid
);
inode
=
iget4
(
sb
,
nr
,
coda_inocmp
,
fid
);
if
(
!
inode
)
{
printk
(
"coda_fid_to_inode: null from iget, sb %p, nr %ld.
\n
"
,
sb
,
(
long
)
nr
);
inode
=
iget5_locked
(
sb
,
hash
,
coda_test_inode
,
coda_fail_inode
,
fid
);
if
(
!
inode
)
return
NULL
;
}
cii
=
ITOC
(
inode
);
/* The inode could already be purged due to memory pressure */
if
(
coda_isnullfid
(
&
cii
->
c_fid
))
{
inode
->
i_nlink
=
0
;
iput
(
inode
);
return
NULL
;
}
/* we shouldn't see inode collisions anymore */
if
(
!
coda_fideq
(
fid
,
&
cii
->
c_fid
)
)
BUG
();
/* we should never see newly created inodes because we intentionally
* fail in the initialization callback */
BUG_ON
(
inode
->
i_state
&
I_NEW
);
return
inode
;
}
...
...
@@ -164,16 +165,15 @@ struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
/* the CONTROL inode is made without asking attributes from Venus */
int
coda_cnode_makectl
(
struct
inode
**
inode
,
struct
super_block
*
sb
)
{
int
error
=
0
;
int
error
=
-
ENOMEM
;
*
inode
=
iget
(
sb
,
CTL_INO
);
if
(
*
inode
)
{
*
inode
=
new_inode
(
sb
);
if
(
*
inode
)
{
(
*
inode
)
->
i_ino
=
CTL_INO
;
(
*
inode
)
->
i_op
=
&
coda_ioctl_inode_operations
;
(
*
inode
)
->
i_fop
=
&
coda_ioctl_operations
;
(
*
inode
)
->
i_mode
=
0444
;
error
=
0
;
}
else
{
error
=
-
ENOMEM
;
}
return
error
;
...
...
fs/coda/inode.c
View file @
6033f024
...
...
@@ -33,7 +33,6 @@
#include <linux/coda_cache.h>
/* VFS super_block ops */
static
void
coda_read_inode
(
struct
inode
*
);
static
void
coda_clear_inode
(
struct
inode
*
);
static
void
coda_put_super
(
struct
super_block
*
);
static
int
coda_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
);
...
...
@@ -92,7 +91,6 @@ struct super_operations coda_super_operations =
{
alloc_inode:
coda_alloc_inode
,
destroy_inode:
coda_destroy_inode
,
read_inode:
coda_read_inode
,
clear_inode:
coda_clear_inode
,
put_super:
coda_put_super
,
statfs:
coda_statfs
,
...
...
@@ -229,18 +227,6 @@ static void coda_put_super(struct super_block *sb)
kfree
(
sbi
);
}
/* all filling in of inodes postponed until lookup */
static
void
coda_read_inode
(
struct
inode
*
inode
)
{
struct
coda_sb_info
*
sbi
=
coda_sbp
(
inode
->
i_sb
);
struct
coda_inode_info
*
cii
;
if
(
!
sbi
)
BUG
();
cii
=
ITOC
(
inode
);
list_add
(
&
cii
->
c_cilist
,
&
sbi
->
sbi_cihead
);
}
static
void
coda_clear_inode
(
struct
inode
*
inode
)
{
struct
coda_inode_info
*
cii
=
ITOC
(
inode
);
...
...
fs/inode.c
View file @
6033f024
...
...
@@ -12,6 +12,7 @@
#include <linux/quotaops.h>
#include <linux/slab.h>
#include <linux/writeback.h>
#include <linux/module.h>
#include <linux/backing-dev.h>
/*
...
...
@@ -443,7 +444,32 @@ int shrink_icache_memory(int priority, int gfp_mask)
* by hand after calling find_inode now! This simplifies iunique and won't
* add any additional branch in the common code.
*/
static
struct
inode
*
find_inode
(
struct
super_block
*
sb
,
unsigned
long
ino
,
struct
list_head
*
head
,
find_inode_t
find_actor
,
void
*
opaque
)
static
struct
inode
*
find_inode
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
list_head
*
tmp
;
struct
inode
*
inode
;
tmp
=
head
;
for
(;;)
{
tmp
=
tmp
->
next
;
inode
=
NULL
;
if
(
tmp
==
head
)
break
;
inode
=
list_entry
(
tmp
,
struct
inode
,
i_hash
);
if
(
inode
->
i_sb
!=
sb
)
continue
;
if
(
!
test
(
inode
,
data
))
continue
;
break
;
}
return
inode
;
}
/*
* find_inode_fast is the fast path version of find_inode, see the comment at
* iget_locked for details.
*/
static
struct
inode
*
find_inode_fast
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
unsigned
long
ino
)
{
struct
list_head
*
tmp
;
struct
inode
*
inode
;
...
...
@@ -459,8 +485,6 @@ static struct inode * find_inode(struct super_block * sb, unsigned long ino, str
continue
;
if
(
inode
->
i_sb
!=
sb
)
continue
;
if
(
find_actor
&&
!
find_actor
(
inode
,
ino
,
opaque
))
continue
;
break
;
}
return
inode
;
...
...
@@ -492,13 +516,28 @@ struct inode *new_inode(struct super_block *sb)
return
inode
;
}
void
unlock_new_inode
(
struct
inode
*
inode
)
{
/*
* This is special! We do not need the spinlock
* when clearing I_LOCK, because we're guaranteed
* that nobody else tries to do anything about the
* state of the inode when it is locked, as we
* just created it (so there can be no old holders
* that haven't tested I_LOCK).
*/
inode
->
i_state
&=
~
(
I_LOCK
|
I_NEW
);
wake_up
(
&
inode
->
i_wait
);
}
/*
* This is called without the inode lock held.. Be careful.
*
* We no longer cache the sb_flags in i_flags - see fs.h
* -- rmk@arm.uk.linux.org
*/
static
struct
inode
*
get_new_inode
(
struct
super_block
*
sb
,
unsigned
long
ino
,
struct
list_head
*
head
,
find_inode_t
find_actor
,
void
*
opaque
)
static
struct
inode
*
get_new_inode
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
int
(
*
set
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
inode
*
inode
;
...
...
@@ -508,37 +547,68 @@ static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, s
spin_lock
(
&
inode_lock
);
/* We released the lock, so.. */
old
=
find_inode
(
sb
,
ino
,
head
,
find_actor
,
opaque
);
old
=
find_inode
(
sb
,
head
,
test
,
data
);
if
(
!
old
)
{
if
(
set
(
inode
,
data
))
goto
set_failed
;
inodes_stat
.
nr_inodes
++
;
list_add
(
&
inode
->
i_list
,
&
inode_in_use
);
list_add
(
&
inode
->
i_hash
,
head
);
inode
->
i_ino
=
ino
;
inode
->
i_state
=
I_LOCK
;
inode
->
i_state
=
I_LOCK
|
I_NEW
;
spin_unlock
(
&
inode_lock
);
/* reiserfs specific hack right here. We don't
** want this to last, and are looking for VFS changes
** that will allow us to get rid of it.
** -- mason@suse.com
/* Return the locked inode with I_NEW set, the
* caller is responsible for filling in the contents
*/
if
(
sb
->
s_op
->
read_inode2
)
{
sb
->
s_op
->
read_inode2
(
inode
,
opaque
)
;
}
else
{
sb
->
s_op
->
read_inode
(
inode
);
return
inode
;
}
/*
* This is special! We do not need the spinlock
* when clearing I_LOCK, because we're guaranteed
* that nobody else tries to do anything about the
* state of the inode when it is locked, as we
* just created it (so there can be no old holders
* that haven't tested I_LOCK).
* Uhhuh, somebody else created the same inode under
* us. Use the old inode instead of the one we just
* allocated.
*/
inode
->
i_state
&=
~
I_LOCK
;
wake_up
(
&
inode
->
i_wait
);
__iget
(
old
);
spin_unlock
(
&
inode_lock
);
destroy_inode
(
inode
);
inode
=
old
;
wait_on_inode
(
inode
);
}
return
inode
;
set_failed:
spin_unlock
(
&
inode_lock
);
destroy_inode
(
inode
);
return
NULL
;
}
/*
* get_new_inode_fast is the fast path version of get_new_inode, see the
* comment at iget_locked for details.
*/
static
struct
inode
*
get_new_inode_fast
(
struct
super_block
*
sb
,
struct
list_head
*
head
,
unsigned
long
ino
)
{
struct
inode
*
inode
;
inode
=
alloc_inode
(
sb
);
if
(
inode
)
{
struct
inode
*
old
;
spin_lock
(
&
inode_lock
);
/* We released the lock, so.. */
old
=
find_inode_fast
(
sb
,
head
,
ino
);
if
(
!
old
)
{
inode
->
i_ino
=
ino
;
inodes_stat
.
nr_inodes
++
;
list_add
(
&
inode
->
i_list
,
&
inode_in_use
);
list_add
(
&
inode
->
i_hash
,
head
);
inode
->
i_state
=
I_LOCK
|
I_NEW
;
spin_unlock
(
&
inode_lock
);
/* Return the locked inode with I_NEW set, the
* caller is responsible for filling in the contents
*/
return
inode
;
}
...
...
@@ -556,9 +626,9 @@ static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, s
return
inode
;
}
static
inline
unsigned
long
hash
(
struct
super_block
*
sb
,
unsigned
long
i_ino
)
static
inline
unsigned
long
hash
(
struct
super_block
*
sb
,
unsigned
long
hashval
)
{
unsigned
long
tmp
=
i_ino
+
((
unsigned
long
)
sb
/
L1_CACHE_BYTES
);
unsigned
long
tmp
=
hashval
+
((
unsigned
long
)
sb
/
L1_CACHE_BYTES
);
tmp
=
tmp
+
(
tmp
>>
I_HASHBITS
);
return
tmp
&
I_HASHMASK
;
}
...
...
@@ -590,7 +660,8 @@ ino_t iunique(struct super_block *sb, ino_t max_reserved)
retry:
if
(
counter
>
max_reserved
)
{
head
=
inode_hashtable
+
hash
(
sb
,
counter
);
inode
=
find_inode
(
sb
,
res
=
counter
++
,
head
,
NULL
,
NULL
);
res
=
counter
++
;
inode
=
find_inode_fast
(
sb
,
head
,
res
);
if
(
!
inode
)
{
spin_unlock
(
&
inode_lock
);
return
res
;
...
...
@@ -618,14 +689,18 @@ struct inode *igrab(struct inode *inode)
return
inode
;
}
struct
inode
*
iget4
(
struct
super_block
*
sb
,
unsigned
long
ino
,
find_inode_t
find_actor
,
void
*
opaque
)
/*
* This is iget without the read_inode portion of get_new_inode
* the filesystem gets back a new locked and hashed inode and gets
* to fill it in before unlocking it via unlock_new_inode().
*/
struct
inode
*
iget5_locked
(
struct
super_block
*
sb
,
unsigned
long
hashval
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
int
(
*
set
)(
struct
inode
*
,
void
*
),
void
*
data
)
{
struct
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
ino
);
struct
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
hashval
);
struct
inode
*
inode
;
spin_lock
(
&
inode_lock
);
inode
=
find_inode
(
sb
,
ino
,
head
,
find_actor
,
opaque
);
inode
=
find_inode
(
sb
,
head
,
test
,
data
);
if
(
inode
)
{
__iget
(
inode
);
spin_unlock
(
&
inode_lock
);
...
...
@@ -638,22 +713,57 @@ struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find
* get_new_inode() will do the right thing, re-trying the search
* in case it had to block at any point.
*/
return
get_new_inode
(
sb
,
ino
,
head
,
find_actor
,
opaque
);
return
get_new_inode
(
sb
,
head
,
test
,
set
,
data
);
}
/*
* Because most filesystems are based on 32-bit unique inode numbers some
* functions are duplicated to keep iget_locked as a fast path. We can avoid
* unnecessary pointer dereferences and function calls for this specific
* case. The duplicated functions (find_inode_fast and get_new_inode_fast)
* have the same pre- and post-conditions as their original counterparts.
*/
struct
inode
*
iget_locked
(
struct
super_block
*
sb
,
unsigned
long
ino
)
{
struct
list_head
*
head
=
inode_hashtable
+
hash
(
sb
,
ino
);
struct
inode
*
inode
;
spin_lock
(
&
inode_lock
);
inode
=
find_inode_fast
(
sb
,
head
,
ino
);
if
(
inode
)
{
__iget
(
inode
);
spin_unlock
(
&
inode_lock
);
wait_on_inode
(
inode
);
return
inode
;
}
spin_unlock
(
&
inode_lock
);
/*
* get_new_inode_fast() will do the right thing, re-trying the search
* in case it had to block at any point.
*/
return
get_new_inode_fast
(
sb
,
head
,
ino
);
}
EXPORT_SYMBOL
(
iget5_locked
);
EXPORT_SYMBOL
(
iget_locked
);
EXPORT_SYMBOL
(
unlock_new_inode
);
/**
* insert_inode_hash - hash an inode
*
__
insert_inode_hash - hash an inode
* @inode: unhashed inode
* @hashval: unsigned long value used to locate this object in the
* inode_hashtable.
*
* Add an inode to the inode hash for this superblock. If the inode
* has no superblock it is added to a separate anonymous chain.
*/
void
insert_inode_hash
(
struct
inode
*
inode
)
void
__insert_inode_hash
(
struct
inode
*
inode
,
unsigned
long
hashval
)
{
struct
list_head
*
head
=
&
anon_hash_chain
;
if
(
inode
->
i_sb
)
head
=
inode_hashtable
+
hash
(
inode
->
i_sb
,
inode
->
i_ino
);
head
=
inode_hashtable
+
hash
(
inode
->
i_sb
,
hashval
);
spin_lock
(
&
inode_lock
);
list_add
(
&
inode
->
i_hash
,
head
);
spin_unlock
(
&
inode_lock
);
...
...
fs/nfs/inode.c
View file @
6033f024
...
...
@@ -47,7 +47,6 @@ static void nfs_invalidate_inode(struct inode *);
static
struct
inode
*
nfs_alloc_inode
(
struct
super_block
*
sb
);
static
void
nfs_destroy_inode
(
struct
inode
*
);
static
void
nfs_read_inode
(
struct
inode
*
);
static
void
nfs_write_inode
(
struct
inode
*
,
int
);
static
void
nfs_delete_inode
(
struct
inode
*
);
static
void
nfs_put_super
(
struct
super_block
*
);
...
...
@@ -59,7 +58,6 @@ static int nfs_show_options(struct seq_file *, struct vfsmount *);
static
struct
super_operations
nfs_sops
=
{
alloc_inode:
nfs_alloc_inode
,
destroy_inode:
nfs_destroy_inode
,
read_inode:
nfs_read_inode
,
write_inode:
nfs_write_inode
,
delete_inode:
nfs_delete_inode
,
put_super:
nfs_put_super
,
...
...
@@ -98,15 +96,6 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
return
nfs_fileid_to_ino_t
(
fattr
->
fileid
);
}
/*
* The "read_inode" function doesn't actually do anything:
* the real data is filled in later in nfs_fhget.
*/
static
void
nfs_read_inode
(
struct
inode
*
inode
)
{
}
static
void
nfs_write_inode
(
struct
inode
*
inode
,
int
sync
)
{
...
...
@@ -592,7 +581,7 @@ struct nfs_find_desc {
* i_ino.
*/
static
int
nfs_find_actor
(
struct
inode
*
inode
,
unsigned
long
ino
,
void
*
opaque
)
nfs_find_actor
(
struct
inode
*
inode
,
void
*
opaque
)
{
struct
nfs_find_desc
*
desc
=
(
struct
nfs_find_desc
*
)
opaque
;
struct
nfs_fh
*
fh
=
desc
->
fh
;
...
...
@@ -610,6 +599,18 @@ nfs_find_actor(struct inode *inode, unsigned long ino, void *opaque)
return
1
;
}
static
int
nfs_init_locked
(
struct
inode
*
inode
,
void
*
opaque
)
{
struct
nfs_find_desc
*
desc
=
(
struct
nfs_find_desc
*
)
opaque
;
struct
nfs_fh
*
fh
=
desc
->
fh
;
struct
nfs_fattr
*
fattr
=
desc
->
fattr
;
NFS_FILEID
(
inode
)
=
fattr
->
fileid
;
memcpy
(
NFS_FH
(
inode
),
fh
,
sizeof
(
struct
nfs_fh
));
return
0
;
}
/*
* This is our own version of iget that looks up inodes by file handle
* instead of inode number. We use this technique instead of using
...
...
@@ -640,7 +641,7 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
fattr:
fattr
};
struct
inode
*
inode
=
NULL
;
unsigned
long
ino
;
unsigned
long
hash
;
if
((
fattr
->
valid
&
NFS_ATTR_FATTR
)
==
0
)
goto
out_no_inode
;
...
...
@@ -650,20 +651,21 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
goto
out_no_inode
;
}
ino
=
nfs_fattr_to_ino_t
(
fattr
);
hash
=
nfs_fattr_to_ino_t
(
fattr
);
if
(
!
(
inode
=
iget
4
(
sb
,
ino
,
nfs_find_actor
,
&
desc
)))
if
(
!
(
inode
=
iget
5_locked
(
sb
,
hash
,
nfs_find_actor
,
nfs_init_locked
,
&
desc
)))
goto
out_no_inode
;
if
(
NFS_NEW
(
inode
)
)
{
if
(
inode
->
i_state
&
I_NEW
)
{
__u64
new_size
,
new_mtime
;
loff_t
new_isize
;
time_t
new_atime
;
/* We set i_ino for the few things that still rely on it,
* such as stat(2) */
inode
->
i_ino
=
hash
;
/* We can't support UPDATE_ATIME(), since the server will reset it */
NFS_FLAGS
(
inode
)
&=
~
NFS_INO_NEW
;
NFS_FILEID
(
inode
)
=
fattr
->
fileid
;
memcpy
(
NFS_FH
(
inode
),
fh
,
sizeof
(
struct
nfs_fh
));
inode
->
i_flags
|=
S_NOATIME
;
inode
->
i_mode
=
fattr
->
mode
;
/* Why so? Because we want revalidate for devices/FIFOs, and
...
...
@@ -711,6 +713,8 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
NFS_ATTRTIMEO
(
inode
)
=
NFS_MINATTRTIMEO
(
inode
);
NFS_ATTRTIMEO_UPDATE
(
inode
)
=
jiffies
;
memset
(
NFS_COOKIEVERF
(
inode
),
0
,
sizeof
(
NFS_COOKIEVERF
(
inode
)));
unlock_new_inode
(
inode
);
}
else
nfs_refresh_inode
(
inode
,
fattr
);
dprintk
(
"NFS: __nfs_fhget(%s/%Ld ct=%d)
\n
"
,
...
...
@@ -1231,7 +1235,7 @@ static struct inode *nfs_alloc_inode(struct super_block *sb)
nfsi
=
(
struct
nfs_inode
*
)
kmem_cache_alloc
(
nfs_inode_cachep
,
SLAB_KERNEL
);
if
(
!
nfsi
)
return
NULL
;
nfsi
->
flags
=
NFS_INO_NEW
;
nfsi
->
flags
=
0
;
nfsi
->
mm_cred
=
NULL
;
return
&
nfsi
->
vfs_inode
;
}
...
...
fs/reiserfs/inode.c
View file @
6033f024
...
...
@@ -33,7 +33,7 @@ void reiserfs_delete_inode (struct inode * inode)
lock_kernel
()
;
/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
if
(
INODE_PKEY
(
inode
)
->
k_objectid
!=
0
)
{
/* also handles bad_inode case */
if
(
!
(
inode
->
i_state
&
I_NEW
)
&&
INODE_PKEY
(
inode
)
->
k_objectid
!=
0
)
{
/* also handles bad_inode case */
down
(
&
inode
->
i_sem
);
journal_begin
(
&
th
,
inode
->
i_sb
,
jbegin_count
)
;
...
...
@@ -886,7 +886,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
// item version directly
//
// called by read_inode
// called by read_
locked_
inode
static
void
init_inode
(
struct
inode
*
inode
,
struct
path
*
path
)
{
struct
buffer_head
*
bh
;
...
...
@@ -1117,7 +1117,7 @@ void reiserfs_update_sd (struct reiserfs_transaction_handle *th,
return
;
}
/* reiserfs_read_
inode2
is called to read the inode off disk, and it
/* reiserfs_read_
locked_inode
is called to read the inode off disk, and it
** does a make_bad_inode when things go wrong. But, we need to make sure
** and clear the key in the private portion of the inode, otherwise a
** corresponding iput might try to delete whatever object the inode last
...
...
@@ -1128,32 +1128,29 @@ static void reiserfs_make_bad_inode(struct inode *inode) {
make_bad_inode
(
inode
);
}
void
reiserfs_read_inode
(
struct
inode
*
inode
)
{
reiserfs_make_bad_inode
(
inode
)
;
}
//
// initially this function was derived from minix or ext2's analog and
// evolved as the prototype did
//
int
reiserfs_init_locked_inode
(
struct
inode
*
inode
,
void
*
p
)
{
struct
reiserfs_iget_args
*
args
=
(
struct
reiserfs_iget_args
*
)
p
;
inode
->
i_ino
=
args
->
objectid
;
INODE_PKEY
(
inode
)
->
k_dir_id
=
cpu_to_le32
(
args
->
dirid
);
return
0
;
}
/* looks for stat data in the tree, and fills up the fields of in-core
inode stat data fields */
void
reiserfs_read_
inode2
(
struct
inode
*
inode
,
void
*
p
)
void
reiserfs_read_
locked_inode
(
struct
inode
*
inode
,
struct
reiserfs_iget_args
*
args
)
{
INITIALIZE_PATH
(
path_to_sd
);
struct
cpu_key
key
;
struct
reiserfs_iget4_args
*
args
=
(
struct
reiserfs_iget4_args
*
)
p
;
unsigned
long
dirino
;
int
retval
;
if
(
!
p
)
{
reiserfs_make_bad_inode
(
inode
)
;
return
;
}
dirino
=
args
->
objectid
;
dirino
=
args
->
dirid
;
/* set version 1, version 2 could be used too, because stat data
key is the same in both versions */
...
...
@@ -1166,7 +1163,7 @@ void reiserfs_read_inode2 (struct inode * inode, void *p)
/* look for the object's stat data */
retval
=
search_item
(
inode
->
i_sb
,
&
key
,
&
path_to_sd
);
if
(
retval
==
IO_ERROR
)
{
reiserfs_warning
(
"vs-13070: reiserfs_read_
inode2
: "
reiserfs_warning
(
"vs-13070: reiserfs_read_
locked_inode
: "
"i/o failure occurred trying to find stat data of %K
\n
"
,
&
key
);
reiserfs_make_bad_inode
(
inode
)
;
...
...
@@ -1198,7 +1195,7 @@ void reiserfs_read_inode2 (struct inode * inode, void *p)
during mount (fs/reiserfs/super.c:finish_unfinished()). */
if
(
(
inode
->
i_nlink
==
0
)
&&
!
REISERFS_SB
(
inode
->
i_sb
)
->
s_is_unlinked_ok
)
{
reiserfs_warning
(
"vs-13075: reiserfs_read_
inode2
: "
reiserfs_warning
(
"vs-13075: reiserfs_read_
locked_inode
: "
"dead inode read from disk %K. "
"This is likely to be race with knfsd. Ignore
\n
"
,
&
key
);
...
...
@@ -1210,39 +1207,44 @@ void reiserfs_read_inode2 (struct inode * inode, void *p)
}
/**
* reiserfs_find_actor() - "find actor" reiserfs supplies to iget
4
().
* reiserfs_find_actor() - "find actor" reiserfs supplies to iget
5_locked
().
*
* @inode: inode from hash table to check
* @inode_no: inode number we are looking for
* @opaque: "cookie" passed to iget4(). This is &reiserfs_iget4_args.
* @opaque: "cookie" passed to iget5_locked(). This is &reiserfs_iget_args.
*
* This function is called by iget
4
() to distinguish reiserfs inodes
* This function is called by iget
5_locked
() to distinguish reiserfs inodes
* having the same inode numbers. Such inodes can only exist due to some
* error condition. One of them should be bad. Inodes with identical
* inode numbers (objectids) are distinguished by parent directory ids.
*
*/
static
int
reiserfs_find_actor
(
struct
inode
*
inode
,
unsigned
long
inode_no
,
void
*
opaque
)
int
reiserfs_find_actor
(
struct
inode
*
inode
,
void
*
opaque
)
{
struct
reiserfs_iget
4
_args
*
args
;
struct
reiserfs_iget_args
*
args
;
args
=
opaque
;
/* args is already in CPU order */
return
le32_to_cpu
(
INODE_PKEY
(
inode
)
->
k_dir_id
)
==
args
->
objectid
;
return
(
inode
->
i_ino
==
args
->
objectid
)
&&
(
le32_to_cpu
(
INODE_PKEY
(
inode
)
->
k_dir_id
)
==
args
->
dirid
);
}
struct
inode
*
reiserfs_iget
(
struct
super_block
*
s
,
const
struct
cpu_key
*
key
)
{
struct
inode
*
inode
;
struct
reiserfs_iget
4
_args
args
;
struct
reiserfs_iget_args
args
;
args
.
objectid
=
key
->
on_disk_key
.
k_dir_id
;
inode
=
iget4
(
s
,
key
->
on_disk_key
.
k_objectid
,
reiserfs_find_actor
,
(
void
*
)(
&
args
));
args
.
objectid
=
key
->
on_disk_key
.
k_objectid
;
args
.
dirid
=
key
->
on_disk_key
.
k_dir_id
;
inode
=
iget5_locked
(
s
,
key
->
on_disk_key
.
k_objectid
,
reiserfs_find_actor
,
reiserfs_init_locked_inode
,
(
void
*
)(
&
args
));
if
(
!
inode
)
return
ERR_PTR
(
-
ENOMEM
)
;
if
(
inode
->
i_state
&
I_NEW
)
{
reiserfs_read_locked_inode
(
inode
,
&
args
);
unlock_new_inode
(
inode
);
}
if
(
comp_short_keys
(
INODE_PKEY
(
inode
),
key
)
||
is_bad_inode
(
inode
))
{
/* either due to i/o error or a stale NFS handle */
iput
(
inode
);
...
...
fs/reiserfs/super.c
View file @
6033f024
...
...
@@ -484,8 +484,6 @@ struct super_operations reiserfs_sops =
{
alloc_inode:
reiserfs_alloc_inode
,
destroy_inode:
reiserfs_destroy_inode
,
read_inode:
reiserfs_read_inode
,
read_inode2:
reiserfs_read_inode2
,
write_inode:
reiserfs_write_inode
,
dirty_inode:
reiserfs_dirty_inode
,
delete_inode:
reiserfs_delete_inode
,
...
...
@@ -1007,7 +1005,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
int
old_format
=
0
;
unsigned
long
blocks
;
int
jinit_done
=
0
;
struct
reiserfs_iget
4
_args
args
;
struct
reiserfs_iget_args
args
;
struct
reiserfs_super_block
*
rs
;
char
*
jdev_name
;
struct
reiserfs_sb_info
*
sbi
;
...
...
@@ -1069,13 +1067,19 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
printk
(
"clm-7000: Detected readonly device, marking FS readonly
\n
"
)
;
s
->
s_flags
|=
MS_RDONLY
;
}
args
.
objectid
=
REISERFS_ROOT_PARENT_OBJECTID
;
root_inode
=
iget4
(
s
,
REISERFS_ROOT_OBJECTID
,
0
,
(
void
*
)(
&
args
));
args
.
objectid
=
REISERFS_ROOT_OBJECTID
;
args
.
dirid
=
REISERFS_ROOT_PARENT_OBJECTID
;
root_inode
=
iget5_locked
(
s
,
REISERFS_ROOT_OBJECTID
,
reiserfs_find_actor
,
reiserfs_init_locked_inode
,
(
void
*
)(
&
args
));
if
(
!
root_inode
)
{
printk
(
"reiserfs_fill_super: get root inode failed
\n
"
);
goto
error
;
}
if
(
root_inode
->
i_state
&
I_NEW
)
{
reiserfs_read_locked_inode
(
root_inode
,
&
args
);
unlock_new_inode
(
root_inode
);
}
s
->
s_root
=
d_alloc_root
(
root_inode
);
if
(
!
s
->
s_root
)
{
iput
(
root_inode
);
...
...
include/linux/fs.h
View file @
6033f024
...
...
@@ -771,13 +771,6 @@ struct super_operations {
void
(
*
read_inode
)
(
struct
inode
*
);
/* reiserfs kludge. reiserfs needs 64 bits of information to
** find an inode. We are using the read_inode2 call to get
** that information. We don't like this, and are waiting on some
** VFS changes for the real solution.
** iget4 calls read_inode2, iff it is defined
*/
void
(
*
read_inode2
)
(
struct
inode
*
,
void
*
)
;
void
(
*
dirty_inode
)
(
struct
inode
*
);
void
(
*
write_inode
)
(
struct
inode
*
,
int
);
void
(
*
put_inode
)
(
struct
inode
*
);
...
...
@@ -801,6 +794,7 @@ struct super_operations {
#define I_LOCK 8
#define I_FREEING 16
#define I_CLEAR 32
#define I_NEW 64
#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
...
...
@@ -1208,19 +1202,33 @@ extern void force_delete(struct inode *);
extern
struct
inode
*
igrab
(
struct
inode
*
);
extern
ino_t
iunique
(
struct
super_block
*
,
ino_t
);
typedef
int
(
*
find_inode_t
)(
struct
inode
*
,
unsigned
long
,
void
*
);
extern
struct
inode
*
iget4
(
struct
super_block
*
,
unsigned
long
,
find_inode_t
,
void
*
);
extern
struct
inode
*
iget5_locked
(
struct
super_block
*
,
unsigned
long
,
int
(
*
test
)(
struct
inode
*
,
void
*
),
int
(
*
set
)(
struct
inode
*
,
void
*
),
void
*
);
extern
struct
inode
*
iget_locked
(
struct
super_block
*
,
unsigned
long
);
extern
void
unlock_new_inode
(
struct
inode
*
);
static
inline
struct
inode
*
iget
(
struct
super_block
*
sb
,
unsigned
long
ino
)
{
return
iget4
(
sb
,
ino
,
NULL
,
NULL
);
struct
inode
*
inode
=
iget_locked
(
sb
,
ino
);
if
(
inode
&&
(
inode
->
i_state
&
I_NEW
))
{
sb
->
s_op
->
read_inode
(
inode
);
unlock_new_inode
(
inode
);
}
return
inode
;
}
extern
void
__iget
(
struct
inode
*
inode
);
extern
void
clear_inode
(
struct
inode
*
);
extern
struct
inode
*
new_inode
(
struct
super_block
*
);
extern
void
remove_suid
(
struct
dentry
*
);
extern
void
insert_inode_hash
(
struct
inode
*
);
extern
void
__insert_inode_hash
(
struct
inode
*
,
unsigned
long
hashval
);
extern
void
remove_inode_hash
(
struct
inode
*
);
static
inline
void
insert_inode_hash
(
struct
inode
*
inode
)
{
__insert_inode_hash
(
inode
,
inode
->
i_ino
);
}
extern
struct
file
*
get_empty_filp
(
void
);
extern
void
file_move
(
struct
file
*
f
,
struct
list_head
*
list
);
extern
void
ll_rw_block
(
int
,
int
,
struct
buffer_head
*
bh
[]);
...
...
include/linux/nfs_fs.h
View file @
6033f024
...
...
@@ -170,7 +170,6 @@ struct nfs_inode {
#define NFS_INO_REVALIDATING 0x0004
/* revalidating attrs */
#define NFS_IS_SNAPSHOT 0x0010
/* a snapshot file */
#define NFS_INO_FLUSH 0x0020
/* inode is due for flushing */
#define NFS_INO_NEW 0x0040
/* hadn't been filled yet */
static
inline
struct
nfs_inode
*
NFS_I
(
struct
inode
*
inode
)
{
...
...
@@ -208,7 +207,6 @@ do { \
#define NFS_FLAGS(inode) (NFS_I(inode)->flags)
#define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING)
#define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE)
#define NFS_NEW(inode) (NFS_FLAGS(inode) & NFS_INO_NEW)
#define NFS_FILEID(inode) (NFS_I(inode)->fileid)
...
...
include/linux/reiserfs_fs.h
View file @
6033f024
...
...
@@ -1564,8 +1564,9 @@ extern struct item_operations * item_ops [TYPE_ANY + 1];
#define B_I_POS_UNFM_POINTER(bh,ih,pos) le32_to_cpu(*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)))
#define PUT_B_I_POS_UNFM_POINTER(bh,ih,pos, val) do {*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)) = cpu_to_le32(val); } while (0)
struct
reiserfs_iget
4
_args
{
struct
reiserfs_iget_args
{
__u32
objectid
;
__u32
dirid
;
}
;
/***************************************************************************/
...
...
@@ -1818,8 +1819,9 @@ void padd_item (char * item, int total_length, int length);
/* inode.c */
void
reiserfs_read_inode
(
struct
inode
*
inode
)
;
void
reiserfs_read_inode2
(
struct
inode
*
inode
,
void
*
p
)
;
void
reiserfs_read_locked_inode
(
struct
inode
*
inode
,
struct
reiserfs_iget_args
*
args
)
;
int
reiserfs_find_actor
(
struct
inode
*
inode
,
void
*
p
)
;
int
reiserfs_init_locked_inode
(
struct
inode
*
inode
,
void
*
p
)
;
void
reiserfs_delete_inode
(
struct
inode
*
inode
);
void
reiserfs_write_inode
(
struct
inode
*
inode
,
int
)
;
struct
dentry
*
reiserfs_get_dentry
(
struct
super_block
*
,
void
*
)
;
...
...
kernel/ksyms.c
View file @
6033f024
...
...
@@ -137,7 +137,6 @@ EXPORT_SYMBOL(fput);
EXPORT_SYMBOL
(
fget
);
EXPORT_SYMBOL
(
igrab
);
EXPORT_SYMBOL
(
iunique
);
EXPORT_SYMBOL
(
iget4
);
EXPORT_SYMBOL
(
iput
);
EXPORT_SYMBOL
(
inode_init_once
);
EXPORT_SYMBOL
(
force_delete
);
...
...
@@ -540,7 +539,7 @@ EXPORT_SYMBOL(clear_inode);
EXPORT_SYMBOL
(
init_special_inode
);
EXPORT_SYMBOL
(
__get_hash_table
);
EXPORT_SYMBOL
(
new_inode
);
EXPORT_SYMBOL
(
insert_inode_hash
);
EXPORT_SYMBOL
(
__
insert_inode_hash
);
EXPORT_SYMBOL
(
remove_inode_hash
);
EXPORT_SYMBOL
(
buffer_insert_list
);
EXPORT_SYMBOL
(
make_bad_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