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
b4655acd
Commit
b4655acd
authored
Oct 11, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge home.transmeta.com:/home/torvalds/v2.5/coda
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
77a32d76
dbd82204
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
308 additions
and
550 deletions
+308
-550
fs/coda/cnode.c
fs/coda/cnode.c
+1
-0
fs/coda/coda_linux.c
fs/coda/coda_linux.c
+1
-15
fs/coda/dir.c
fs/coda/dir.c
+126
-85
fs/coda/file.c
fs/coda/file.c
+134
-123
fs/coda/inode.c
fs/coda/inode.c
+20
-25
fs/coda/pioctl.c
fs/coda/pioctl.c
+4
-5
fs/coda/symlink.c
fs/coda/symlink.c
+1
-1
fs/coda/sysctl.c
fs/coda/sysctl.c
+0
-209
fs/coda/upcall.c
fs/coda/upcall.c
+6
-36
include/linux/coda_fs_i.h
include/linux/coda_fs_i.h
+14
-2
include/linux/coda_linux.h
include/linux/coda_linux.h
+1
-2
include/linux/coda_proc.h
include/linux/coda_proc.h
+0
-27
include/linux/coda_psdev.h
include/linux/coda_psdev.h
+0
-20
No files found.
fs/coda/cnode.c
View file @
b4655acd
...
...
@@ -85,6 +85,7 @@ struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
cii
=
ITOC
(
inode
);
/* we still need to set i_ino for things like stat(2) */
inode
->
i_ino
=
hash
;
cii
->
c_mapcount
=
0
;
list_add
(
&
cii
->
c_cilist
,
&
sbi
->
sbi_cihead
);
unlock_new_inode
(
inode
);
}
...
...
fs/coda/coda_linux.c
View file @
b4655acd
...
...
@@ -29,21 +29,7 @@ int coda_fake_statfs;
char
*
coda_f2s
(
ViceFid
*
f
)
{
static
char
s
[
60
];
if
(
f
)
{
sprintf
(
s
,
"(%-#lx,%-#lx,%-#lx)"
,
f
->
Volume
,
f
->
Vnode
,
f
->
Unique
);
}
return
s
;
}
/* print another fid */
char
*
coda_f2s2
(
ViceFid
*
f
)
{
static
char
s
[
60
];
if
(
f
)
{
sprintf
(
s
,
"(%-#lx,%-#lx,%-#lx)"
,
f
->
Volume
,
f
->
Vnode
,
f
->
Unique
);
}
sprintf
(
s
,
"(%-#lx.%-#lx.%-#lx)"
,
f
->
Volume
,
f
->
Vnode
,
f
->
Unique
);
return
s
;
}
...
...
fs/coda/dir.c
View file @
b4655acd
...
...
@@ -49,40 +49,42 @@ static int coda_dentry_revalidate(struct dentry *de, int);
static
int
coda_dentry_delete
(
struct
dentry
*
);
/* support routines */
static
int
coda_venus_readdir
(
struct
file
*
filp
,
filldir_t
filldir
,
void
*
dirent
);
static
int
coda_venus_readdir
(
struct
file
*
filp
,
filldir_t
filldir
,
void
*
dirent
,
struct
dentry
*
dir
);
int
coda_fsync
(
struct
file
*
,
struct
dentry
*
dentry
,
int
datasync
);
int
coda_hasmknod
;
struct
dentry_operations
coda_dentry_operations
=
{
d_revalidate:
coda_dentry_revalidate
,
d_delete:
coda_dentry_delete
,
.
d_revalidate
=
coda_dentry_revalidate
,
.
d_delete
=
coda_dentry_delete
,
};
struct
inode_operations
coda_dir_inode_operations
=
{
create:
coda_create
,
lookup:
coda_lookup
,
link:
coda_link
,
unlink:
coda_unlink
,
symlink:
coda_symlink
,
mkdir:
coda_mkdir
,
rmdir:
coda_rmdir
,
mknod:
coda_mknod
,
rename:
coda_rename
,
permission:
coda_permission
,
getattr:
coda_getattr
,
setattr:
coda_setattr
,
.
create
=
coda_create
,
.
lookup
=
coda_lookup
,
.
link
=
coda_link
,
.
unlink
=
coda_unlink
,
.
symlink
=
coda_symlink
,
.
mkdir
=
coda_mkdir
,
.
rmdir
=
coda_rmdir
,
.
mknod
=
coda_mknod
,
.
rename
=
coda_rename
,
.
permission
=
coda_permission
,
.
getattr
=
coda_getattr
,
.
setattr
=
coda_setattr
,
};
struct
file_operations
coda_dir_operations
=
{
read:
generic_read_dir
,
readdir:
coda_readdir
,
open:
coda_open
,
flush:
coda_flush
,
release:
coda_release
,
fsync:
coda_fsync
,
.
llseek
=
generic_file_llseek
,
.
read
=
generic_read_dir
,
.
readdir
=
coda_readdir
,
.
open
=
coda_open
,
.
flush
=
coda_flush
,
.
release
=
coda_release
,
.
fsync
=
coda_fsync
,
};
...
...
@@ -475,70 +477,99 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
/* file operations for directories */
int
coda_readdir
(
struct
file
*
coda_file
,
void
*
dirent
,
filldir_t
filldir
)
int
coda_readdir
(
struct
file
*
coda_file
,
void
*
dirent
,
filldir_t
filldir
)
{
int
result
=
0
;
struct
dentry
*
coda_dentry
=
coda_file
->
f_dentry
;
struct
inode
*
coda_inode
=
coda_dentry
->
d_inode
;
struct
coda_inode_info
*
cii
=
ITOC
(
coda_inode
);
struct
file
*
host_file
=
cii
->
c_container
;
struct
coda_file_info
*
cfi
;
struct
file
*
host_file
;
struct
inode
*
host_inode
;
int
ret
;
BUG_ON
(
!
host_file
);
cfi
=
CODA_FTOC
(
coda_file
);
BUG_ON
(
!
cfi
||
cfi
->
cfi_magic
!=
CODA_MAGIC
);
host_file
=
cfi
->
cfi_container
;
coda_vfs_stat
.
readdir
++
;
/* Access to both host and coda f_pos fields is serialized on the
* coda_file->f_dentry->d_inode->i_sem which has already been taken by
* vfs_readdir. Userspace shouldn't 'play' with the container file as
* long as the file is held open. */
host_inode
=
host_file
->
f_dentry
->
d_inode
;
down
(
&
host_inode
->
i_sem
);
host_file
->
f_pos
=
coda_file
->
f_pos
;
if
(
!
host_file
->
f_op
->
readdir
)
if
(
!
host_file
->
f_op
->
readdir
)
{
/* Venus: we must read Venus dirents from the file */
result
=
coda_venus_readdir
(
host_file
,
filldir
,
dirent
);
else
/* potemkin case: we were handed a directory inode */
result
=
vfs_readdir
(
host_file
,
filldir
,
dirent
);
ret
=
coda_venus_readdir
(
host_file
,
filldir
,
dirent
,
coda_dentry
);
}
else
{
/* potemkin case: we were handed a directory inode. */
/* Yuk, we can't call vfs_readdir because we are already
* holding the inode semaphore. */
ret
=
-
ENOTDIR
;
if
(
!
host_file
->
f_op
||
!
host_file
->
f_op
->
readdir
)
goto
out
;
ret
=
-
ENOENT
;
if
(
!
IS_DEADDIR
(
host_inode
))
ret
=
host_file
->
f_op
->
readdir
(
host_file
,
filldir
,
dirent
);
}
out:
coda_file
->
f_pos
=
host_file
->
f_pos
;
return
result
;
up
(
&
host_inode
->
i_sem
);
return
ret
;
}
static
inline
unsigned
int
CDT2DT
(
unsigned
char
cdt
)
{
unsigned
int
dt
;
switch
(
cdt
)
{
case
CDT_UNKNOWN
:
dt
=
DT_UNKNOWN
;
break
;
case
CDT_FIFO
:
dt
=
DT_FIFO
;
break
;
case
CDT_CHR
:
dt
=
DT_CHR
;
break
;
case
CDT_DIR
:
dt
=
DT_DIR
;
break
;
case
CDT_BLK
:
dt
=
DT_BLK
;
break
;
case
CDT_REG
:
dt
=
DT_REG
;
break
;
case
CDT_LNK
:
dt
=
DT_LNK
;
break
;
case
CDT_SOCK
:
dt
=
DT_SOCK
;
break
;
case
CDT_WHT
:
dt
=
DT_WHT
;
break
;
default:
dt
=
DT_UNKNOWN
;
break
;
}
return
dt
;
unsigned
int
dt
;
switch
(
cdt
)
{
case
CDT_UNKNOWN
:
dt
=
DT_UNKNOWN
;
break
;
case
CDT_FIFO
:
dt
=
DT_FIFO
;
break
;
case
CDT_CHR
:
dt
=
DT_CHR
;
break
;
case
CDT_DIR
:
dt
=
DT_DIR
;
break
;
case
CDT_BLK
:
dt
=
DT_BLK
;
break
;
case
CDT_REG
:
dt
=
DT_REG
;
break
;
case
CDT_LNK
:
dt
=
DT_LNK
;
break
;
case
CDT_SOCK
:
dt
=
DT_SOCK
;
break
;
case
CDT_WHT
:
dt
=
DT_WHT
;
break
;
default:
dt
=
DT_UNKNOWN
;
break
;
}
return
dt
;
}
/* support routines */
static
int
coda_venus_readdir
(
struct
file
*
filp
,
filldir_t
filldir
,
void
*
getdent
)
void
*
dirent
,
struct
dentry
*
dir
)
{
int
result
=
0
;
/* # of entries returned */
struct
venus_dirent
*
vdir
;
unsigned
long
vdir_size
=
struct
venus_dirent
*
vdir
;
unsigned
long
vdir_size
=
(
unsigned
long
)(
&
((
struct
venus_dirent
*
)
0
)
->
d_name
);
int
ret
;
unsigned
int
type
;
struct
qstr
name
;
ino_t
ino
;
int
ret
,
i
;
vdir
=
(
struct
venus_dirent
*
)
kmalloc
(
sizeof
(
*
vdir
),
GFP_KERNEL
);
if
(
!
vdir
)
return
-
ENOMEM
;
while
(
1
)
{
/* we use this routine to read the file into our buffer */
ret
=
kernel_read
(
filp
,
filp
->
f_pos
,
(
char
*
)
vdir
,
i
=
filp
->
f_pos
;
switch
(
i
)
{
case
0
:
ret
=
filldir
(
dirent
,
"."
,
1
,
0
,
dir
->
d_inode
->
i_ino
,
DT_DIR
);
if
(
ret
<
0
)
break
;
result
++
;
filp
->
f_pos
++
;
/* fallthrough */
case
1
:
ret
=
filldir
(
dirent
,
".."
,
2
,
1
,
dir
->
d_parent
->
d_inode
->
i_ino
,
DT_DIR
);
if
(
ret
<
0
)
break
;
result
++
;
filp
->
f_pos
++
;
/* fallthrough */
default:
while
(
1
)
{
/* read entries from the directory file */
ret
=
kernel_read
(
filp
,
filp
->
f_pos
-
2
,
(
char
*
)
vdir
,
sizeof
(
*
vdir
));
if
(
ret
<
0
)
{
printk
(
"coda_venus_readdir: read dir failed %d
\n
"
,
ret
);
...
...
@@ -548,35 +579,51 @@ static int coda_venus_readdir(struct file *filp, filldir_t filldir,
/* catch truncated reads */
if
(
ret
<
vdir_size
||
ret
<
vdir_size
+
vdir
->
d_namlen
)
{
printk
(
"coda_venus_readdir: short read: %ld
\n
"
,
filp
->
f_dentry
->
d_inode
->
i_ino
);
ret
=
-
EBADF
;
break
;
printk
(
"coda_venus_readdir: short read: %ld
\n
"
,
filp
->
f_dentry
->
d_inode
->
i_ino
);
ret
=
-
EBADF
;
break
;
}
/* validate whether the directory file actually makes sense */
if
(
vdir
->
d_reclen
<
vdir_size
+
vdir
->
d_namlen
||
vdir
->
d_namlen
>
CODA_MAXNAMLEN
)
{
printk
(
"coda_venus_readdir: Invalid directory: %ld
\n
"
,
filp
->
f_dentry
->
d_inode
->
i_ino
);
ret
=
-
EBADF
;
break
;
printk
(
"coda_venus_readdir: Invalid dir: %ld
\n
"
,
filp
->
f_dentry
->
d_inode
->
i_ino
);
ret
=
-
EBADF
;
break
;
}
name
.
len
=
vdir
->
d_namlen
;
name
.
name
=
vdir
->
d_name
;
/* Make sure we skip '.' and '..', we already got those */
if
(
name
.
name
[
0
]
==
'.'
&&
(
name
.
len
==
1
||
(
vdir
->
d_name
[
1
]
==
'.'
&&
name
.
len
==
2
)))
vdir
->
d_fileno
=
name
.
len
=
0
;
/* skip null entries */
if
(
vdir
->
d_fileno
)
{
unsigned
int
d_type
=
CDT2DT
(
vdir
->
d_type
);
ret
=
filldir
(
getdent
,
vdir
->
d_name
,
vdir
->
d_namlen
,
filp
->
f_pos
,
vdir
->
d_fileno
,
d_type
);
/* failure means no space for filling in this round */
if
(
ret
<
0
)
break
;
result
++
;
if
(
vdir
->
d_fileno
&&
name
.
len
)
{
/* try to look up this entry in the dcache, that way
* userspace doesn't have to worry about breaking
* getcwd by having mismatched inode numbers for
* internal volume mountpoints. */
ino
=
find_inode_number
(
dir
,
&
name
);
if
(
!
ino
)
ino
=
vdir
->
d_fileno
;
type
=
CDT2DT
(
vdir
->
d_type
);
ret
=
filldir
(
dirent
,
name
.
name
,
name
.
len
,
filp
->
f_pos
,
ino
,
type
);
/* failure means no space for filling in this round */
if
(
ret
<
0
)
break
;
result
++
;
}
/* we'll always have progress because d_reclen is unsigned and
* we've already established it is non-zero. */
filp
->
f_pos
+=
vdir
->
d_reclen
;
}
}
kfree
(
vdir
);
return
result
?
result
:
ret
;
return
result
?
result
:
ret
;
}
/* called when a cache lookup succeeds */
...
...
@@ -660,7 +707,7 @@ int coda_revalidate_inode(struct dentry *dentry)
if
(
cii
->
c_flags
&
(
C_VATTR
|
C_PURGE
|
C_FLUSH
))
{
error
=
venus_getattr
(
inode
->
i_sb
,
&
(
cii
->
c_fid
),
&
attr
);
if
(
error
)
goto
return_bad
_inode
;
goto
return_bad
;
/* this inode may be lost if:
- it's ino changed
...
...
@@ -679,7 +726,7 @@ int coda_revalidate_inode(struct dentry *dentry)
/* the following can happen when a local fid is replaced
with a global one, here we lose and declare the inode bad */
if
(
inode
->
i_ino
!=
old_ino
)
goto
return_bad
_inode
;
goto
return_bad
;
coda_flag_inode_children
(
inode
,
C_FLUSH
);
cii
->
c_flags
&=
~
(
C_VATTR
|
C_PURGE
|
C_FLUSH
);
...
...
@@ -689,13 +736,7 @@ int coda_revalidate_inode(struct dentry *dentry)
unlock_kernel
();
return
0
;
return_bad_inode:
inode
->
i_mapping
=
&
inode
->
i_data
;
if
(
cii
->
c_container
)
{
fput
(
cii
->
c_container
);
cii
->
c_container
=
NULL
;
}
make_bad_inode
(
inode
);
return_bad:
unlock_kernel
();
return
-
EIO
;
}
...
...
fs/coda/file.c
View file @
b4655acd
...
...
@@ -29,143 +29,152 @@
int
use_coda_close
;
static
ssize_t
coda_file_read
(
struct
file
*
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
coda_file_read
(
struct
file
*
coda_
file
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
inode
*
inode
=
file
->
f_dentry
->
d_inode
;
struct
coda_inode_info
*
cii
=
ITOC
(
inode
);
struct
file
*
cfile
;
struct
coda_file_info
*
cfi
;
struct
file
*
host_file
;
cfile
=
cii
->
c_container
;
if
(
!
cfile
)
BUG
();
cfi
=
CODA_FTOC
(
coda_file
);
BUG_ON
(
!
cfi
||
cfi
->
cfi_magic
!=
CODA_MAGIC
);
host_file
=
cfi
->
cfi_container
;
if
(
!
cfile
->
f_op
||
!
c
file
->
f_op
->
read
)
if
(
!
host_file
->
f_op
||
!
host_
file
->
f_op
->
read
)
return
-
EINVAL
;
return
cfile
->
f_op
->
read
(
c
file
,
buf
,
count
,
ppos
);
return
host_file
->
f_op
->
read
(
host_
file
,
buf
,
count
,
ppos
);
}
static
ssize_t
coda_file_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
coda_file_write
(
struct
file
*
coda_file
,
const
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
inode
*
cinode
,
*
inode
=
file
->
f_dentry
->
d_inode
;
struct
coda_
inode_info
*
cii
=
ITOC
(
inode
)
;
struct
file
*
c
file
;
struct
inode
*
host_inode
,
*
coda_inode
=
coda_
file
->
f_dentry
->
d_inode
;
struct
coda_
file_info
*
cfi
;
struct
file
*
host_
file
;
ssize_t
ret
;
int
flags
;
cfile
=
cii
->
c_container
;
if
(
!
cfile
)
BUG
();
cfi
=
CODA_FTOC
(
coda_file
);
BUG_ON
(
!
cfi
||
cfi
->
cfi_magic
!=
CODA_MAGIC
);
host_file
=
cfi
->
cfi_container
;
if
(
!
cfile
->
f_op
||
!
c
file
->
f_op
->
write
)
if
(
!
host_file
->
f_op
||
!
host_
file
->
f_op
->
write
)
return
-
EINVAL
;
cinode
=
cfile
->
f_dentry
->
d_inode
;
down
(
&
inode
->
i_sem
);
flags
=
cfile
->
f_flags
;
cfile
->
f_flags
|=
file
->
f_flags
&
(
O_APPEND
|
O_SYNC
);
host_inode
=
host_file
->
f_dentry
->
d_inode
;
down
(
&
coda_inode
->
i_sem
);
ret
=
cfile
->
f_op
->
write
(
c
file
,
buf
,
count
,
ppos
);
ret
=
host_file
->
f_op
->
write
(
host_
file
,
buf
,
count
,
ppos
);
c
file
->
f_flags
=
flags
;
inode
->
i_size
=
cinode
->
i_size
;
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
up
(
&
inode
->
i_sem
);
c
oda_inode
->
i_size
=
host_inode
->
i_size
;
coda_inode
->
i_blocks
=
(
coda_inode
->
i_size
+
511
)
>>
9
;
coda_inode
->
i_mtime
=
coda_
inode
->
i_ctime
=
CURRENT_TIME
;
up
(
&
coda_
inode
->
i_sem
);
return
ret
;
}
static
int
coda_file_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
coda_file_mmap
(
struct
file
*
coda_
file
,
struct
vm_area_struct
*
vma
)
{
struct
inode
*
inode
=
file
->
f_dentry
->
d_inode
;
struct
coda_inode_info
*
cii
=
ITOC
(
inode
);
struct
file
*
cfile
;
cfile
=
cii
->
c_container
;
struct
coda_file_info
*
cfi
;
struct
coda_inode_info
*
cii
;
struct
file
*
host_file
;
struct
inode
*
coda_inode
,
*
host_inode
;
if
(
!
cfile
)
BUG
();
cfi
=
CODA_FTOC
(
coda_file
);
BUG_ON
(
!
cfi
||
cfi
->
cfi_magic
!=
CODA_MAGIC
);
host_file
=
cfi
->
cfi_container
;
if
(
!
cfile
->
f_op
||
!
c
file
->
f_op
->
mmap
)
if
(
!
host_file
->
f_op
||
!
host_
file
->
f_op
->
mmap
)
return
-
ENODEV
;
return
cfile
->
f_op
->
mmap
(
cfile
,
vma
);
coda_inode
=
coda_file
->
f_dentry
->
d_inode
;
host_inode
=
host_file
->
f_dentry
->
d_inode
;
if
(
coda_inode
->
i_mapping
==
&
coda_inode
->
i_data
)
coda_inode
->
i_mapping
=
host_inode
->
i_mapping
;
/* only allow additional mmaps as long as userspace isn't changing
* the container file on us! */
else
if
(
coda_inode
->
i_mapping
!=
host_inode
->
i_mapping
)
return
-
EBUSY
;
/* keep track of how often the coda_inode/host_file has been mmapped */
cii
=
ITOC
(
coda_inode
);
cii
->
c_mapcount
++
;
cfi
->
cfi_mapcount
++
;
return
host_file
->
f_op
->
mmap
(
host_file
,
vma
);
}
int
coda_open
(
struct
inode
*
i
,
struct
file
*
f
)
int
coda_open
(
struct
inode
*
coda_inode
,
struct
file
*
coda_file
)
{
struct
file
*
fh
=
NULL
;
int
error
=
0
;
unsigned
short
flags
=
f
->
f_flags
&
(
~
O_EXCL
);
struct
file
*
host_file
=
NULL
;
int
error
;
unsigned
short
flags
=
coda_file
->
f_flags
&
(
~
O_EXCL
);
unsigned
short
coda_flags
=
coda_flags_to_cflags
(
flags
);
struct
coda_cred
*
cred
;
struct
coda_inode_info
*
cii
;
struct
coda_file_info
*
cfi
;
lock_kernel
();
coda_vfs_stat
.
open
++
;
error
=
venus_open
(
i
->
i_sb
,
coda_i2f
(
i
),
coda_flags
,
&
fh
);
if
(
error
||
!
fh
)
{
cfi
=
kmalloc
(
sizeof
(
struct
coda_file_info
),
GFP_KERNEL
);
if
(
!
cfi
)
{
unlock_kernel
();
return
error
;
return
-
ENOMEM
;
}
/* coda_upcall returns filehandle of container file object */
cii
=
ITOC
(
i
);
if
(
cii
->
c_container
)
fput
(
cii
->
c_container
);
lock_kernel
();
cii
->
c_contcount
++
;
cii
->
c_container
=
fh
;
i
->
i_mapping
=
&
cii
->
c_container
->
f_dentry
->
d_inode
->
i_data
;
error
=
venus_open
(
coda_inode
->
i_sb
,
coda_i2f
(
coda_inode
),
coda_flags
,
&
host_file
);
if
(
error
||
!
host_file
)
{
kfree
(
cfi
);
unlock_kernel
();
return
error
;
}
cred
=
kmalloc
(
sizeof
(
struct
coda_cred
),
GFP_KERNEL
);
host_file
->
f_flags
|=
coda_file
->
f_flags
&
(
O_APPEND
|
O_SYNC
);
/* If the allocation failed, we'll just muddle on. This actually works
* fine for normal cases. (i.e. when open credentials are the same as
* close credentials) */
if
(
cred
)
{
coda_load_creds
(
cred
);
f
->
private_data
=
cred
;
}
cfi
->
cfi_magic
=
CODA_MAGIC
;
cfi
->
cfi_mapcount
=
0
;
cfi
->
cfi_container
=
host_file
;
coda_load_creds
(
&
cfi
->
cfi_cred
);
BUG_ON
(
coda_file
->
private_data
!=
NULL
)
;
coda_file
->
private_data
=
cfi
;
unlock_kernel
();
return
0
;
}
int
coda_flush
(
struct
file
*
file
)
int
coda_flush
(
struct
file
*
coda_file
)
{
unsigned
short
flags
=
(
file
->
f_flags
)
&
(
~
O_EXCL
);
unsigned
short
cflags
;
struct
coda_inode_info
*
cii
;
struct
file
*
cfile
;
struct
inode
*
cinode
,
*
inode
;
unsigned
short
flags
=
coda_file
->
f_flags
&
~
O_EXCL
;
unsigned
short
coda_flags
=
coda_flags_to_cflags
(
flags
);
struct
coda_file_info
*
cfi
;
struct
inode
*
coda_inode
;
int
err
=
0
,
fcnt
;
coda_vfs_stat
.
flush
++
;
/* last close semantics */
fcnt
=
file_count
(
coda_file
);
if
(
fcnt
>
1
)
return
0
;
/* No need to make an upcall when we have not made any modifications
* to the file */
if
((
file
->
f_flags
&
O_ACCMODE
)
==
O_RDONLY
)
if
((
coda_
file
->
f_flags
&
O_ACCMODE
)
==
O_RDONLY
)
return
0
;
if
(
use_coda_close
)
return
0
;
fcnt
=
file_count
(
file
);
if
(
fcnt
>
1
)
return
0
;
cfi
=
CODA_FTOC
(
coda_
file
);
BUG_ON
(
!
cfi
||
cfi
->
cfi_magic
!=
CODA_MAGIC
)
;
c
flags
=
coda_flags_to_cflags
(
flags
)
;
c
oda_inode
=
coda_file
->
f_dentry
->
d_inode
;
inode
=
file
->
f_dentry
->
d_inode
;
cii
=
ITOC
(
inode
);
cfile
=
cii
->
c_container
;
if
(
!
cfile
)
BUG
();
err
=
venus_store
(
coda_inode
->
i_sb
,
coda_i2f
(
coda_inode
),
coda_flags
,
&
cfi
->
cfi_cred
);
cinode
=
cfile
->
f_dentry
->
d_inode
;
err
=
venus_store
(
inode
->
i_sb
,
coda_i2f
(
inode
),
cflags
,
(
struct
coda_cred
*
)
file
->
private_data
);
if
(
err
==
-
EOPNOTSUPP
)
{
use_coda_close
=
1
;
err
=
0
;
...
...
@@ -174,79 +183,81 @@ int coda_flush(struct file *file)
return
err
;
}
int
coda_release
(
struct
inode
*
i
,
struct
file
*
f
)
int
coda_release
(
struct
inode
*
coda_inode
,
struct
file
*
coda_file
)
{
unsigned
short
flags
=
(
f
->
f_flags
)
&
(
~
O_EXCL
);
unsigned
short
cflags
=
coda_flags_to_cflags
(
flags
);
unsigned
short
flags
=
(
coda_file
->
f_flags
)
&
(
~
O_EXCL
);
unsigned
short
coda_flags
=
coda_flags_to_cflags
(
flags
);
struct
coda_file_info
*
cfi
;
struct
coda_inode_info
*
cii
;
struct
file
*
cfil
e
;
struct
inode
*
host_inod
e
;
int
err
=
0
;
lock_kernel
();
coda_vfs_stat
.
release
++
;
if
(
!
use_coda_close
)
{
err
=
venus_release
(
i
->
i_sb
,
coda_i2f
(
i
),
cflags
);
err
=
venus_release
(
coda_inode
->
i_sb
,
coda_i2f
(
coda_inode
),
coda_flags
);
if
(
err
==
-
EOPNOTSUPP
)
{
use_coda_close
=
1
;
err
=
0
;
}
}
cfi
=
CODA_FTOC
(
coda_file
);
BUG_ON
(
!
cfi
||
cfi
->
cfi_magic
!=
CODA_MAGIC
);
if
(
use_coda_close
)
err
=
venus_close
(
i
->
i_sb
,
coda_i2f
(
i
),
cflags
,
(
struct
coda_cred
*
)
f
->
private_data
);
err
=
venus_close
(
coda_inode
->
i_sb
,
coda_i2f
(
coda_inode
)
,
coda_flags
,
&
cfi
->
cfi_cred
);
cii
=
ITOC
(
i
);
cfile
=
cii
->
c_container
;
if
(
!
cfile
)
BUG
();
host_inode
=
cfi
->
cfi_container
->
f_dentry
->
d_inode
;
cii
=
ITOC
(
coda_inode
);
if
(
--
cii
->
c_contcount
)
{
unlock_kernel
();
return
err
;
/* did we mmap this file? */
if
(
coda_inode
->
i_mapping
==
&
host_inode
->
i_data
)
{
cii
->
c_mapcount
-=
cfi
->
cfi_mapcount
;
if
(
!
cii
->
c_mapcount
)
coda_inode
->
i_mapping
=
&
coda_inode
->
i_data
;
}
i
->
i_mapping
=
&
i
->
i_data
;
fput
(
cfile
);
cii
->
c_container
=
NULL
;
if
(
f
->
private_data
)
{
kfree
(
f
->
private_data
);
f
->
private_data
=
NULL
;
}
fput
(
cfi
->
cfi_container
);
kfree
(
coda_file
->
private_data
);
coda_file
->
private_data
=
NULL
;
unlock_kernel
();
return
err
;
}
int
coda_fsync
(
struct
file
*
file
,
struct
dentry
*
dentry
,
int
datasync
)
int
coda_fsync
(
struct
file
*
coda_file
,
struct
dentry
*
coda_
dentry
,
int
datasync
)
{
struct
file
*
c
file
;
struct
dentry
*
c
dentry
;
struct
inode
*
cinode
,
*
inode
=
dentry
->
d_inode
;
struct
coda_
inode_info
*
cii
=
ITOC
(
inode
)
;
struct
file
*
host_
file
;
struct
dentry
*
host_
dentry
;
struct
inode
*
host_inode
,
*
coda_inode
=
coda_
dentry
->
d_inode
;
struct
coda_
file_info
*
cfi
;
int
err
=
0
;
if
(
!
(
S_ISREG
(
inode
->
i_mode
)
||
S_ISDIR
(
inode
->
i_mode
)
||
S_ISLNK
(
inode
->
i_mode
)))
if
(
!
(
S_ISREG
(
coda_inode
->
i_mode
)
||
S_ISDIR
(
coda_
inode
->
i_mode
)
||
S_ISLNK
(
coda_
inode
->
i_mode
)))
return
-
EINVAL
;
cfile
=
cii
->
c_container
;
if
(
!
cfile
)
BUG
();
cfi
=
CODA_FTOC
(
coda_file
);
BUG_ON
(
!
cfi
||
cfi
->
cfi_magic
!=
CODA_MAGIC
);
host_file
=
cfi
->
cfi_container
;
coda_vfs_stat
.
fsync
++
;
if
(
cfile
->
f_op
&&
c
file
->
f_op
->
fsync
)
{
cdentry
=
c
file
->
f_dentry
;
cinode
=
c
dentry
->
d_inode
;
down
(
&
c
inode
->
i_sem
);
err
=
cfile
->
f_op
->
fsync
(
cfile
,
c
dentry
,
datasync
);
up
(
&
c
inode
->
i_sem
);
if
(
host_file
->
f_op
&&
host_
file
->
f_op
->
fsync
)
{
host_dentry
=
host_
file
->
f_dentry
;
host_inode
=
host_
dentry
->
d_inode
;
down
(
&
host_
inode
->
i_sem
);
err
=
host_file
->
f_op
->
fsync
(
host_file
,
host_
dentry
,
datasync
);
up
(
&
host_
inode
->
i_sem
);
}
if
(
!
err
&&
!
datasync
)
{
lock_kernel
();
err
=
venus_fsync
(
inode
->
i_sb
,
coda_i2f
(
inode
));
err
=
venus_fsync
(
coda_inode
->
i_sb
,
coda_i2f
(
coda_
inode
));
unlock_kernel
();
}
...
...
@@ -254,13 +265,13 @@ int coda_fsync(struct file *file, struct dentry *dentry, int datasync)
}
struct
file_operations
coda_file_operations
=
{
llseek:
generic_file_llseek
,
read:
coda_file_read
,
write:
coda_file_write
,
mmap:
coda_file_mmap
,
open:
coda_open
,
flush:
coda_flush
,
release:
coda_release
,
fsync:
coda_fsync
,
.
llseek
=
generic_file_llseek
,
.
read
=
coda_file_read
,
.
write
=
coda_file_write
,
.
mmap
=
coda_file_mmap
,
.
open
=
coda_open
,
.
flush
=
coda_flush
,
.
release
=
coda_release
,
.
fsync
=
coda_fsync
,
};
fs/coda/inode.c
View file @
b4655acd
...
...
@@ -8,7 +8,6 @@
* Copyright (C) Carnegie Mellon University
*/
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
...
...
@@ -47,8 +46,6 @@ static struct inode *coda_alloc_inode(struct super_block *sb)
memset
(
&
ei
->
c_fid
,
0
,
sizeof
(
struct
ViceFid
));
ei
->
c_flags
=
0
;
INIT_LIST_HEAD
(
&
ei
->
c_cilist
);
ei
->
c_container
=
NULL
;
ei
->
c_contcount
=
0
;
memset
(
&
ei
->
c_cached_cred
,
0
,
sizeof
(
struct
coda_cred
));
ei
->
c_cached_perm
=
0
;
return
&
ei
->
vfs_inode
;
...
...
@@ -88,11 +85,11 @@ void coda_destroy_inodecache(void)
/* exported operations */
struct
super_operations
coda_super_operations
=
{
alloc_inode:
coda_alloc_inode
,
destroy_inode:
coda_destroy_inode
,
clear_inode:
coda_clear_inode
,
put_super:
coda_put_super
,
statfs:
coda_statfs
,
.
alloc_inode
=
coda_alloc_inode
,
.
destroy_inode
=
coda_destroy_inode
,
.
clear_inode
=
coda_clear_inode
,
.
put_super
=
coda_put_super
,
.
statfs
=
coda_statfs
,
};
static
int
get_device_index
(
struct
coda_mount_data
*
data
)
...
...
@@ -230,10 +227,7 @@ static void coda_clear_inode(struct inode *inode)
{
struct
coda_inode_info
*
cii
=
ITOC
(
inode
);
if
(
cii
->
c_container
)
BUG
();
list_del_init
(
&
cii
->
c_cilist
);
inode
->
i_mapping
=
&
inode
->
i_data
;
list_del_init
(
&
cii
->
c_cilist
);
coda_cache_clear_inode
(
inode
);
}
...
...
@@ -248,16 +242,16 @@ int coda_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
int
coda_setattr
(
struct
dentry
*
de
,
struct
iattr
*
iattr
)
{
struct
inode
*
inode
=
de
->
d_inode
;
struct
coda_vattr
vattr
;
int
error
;
struct
coda_vattr
vattr
;
int
error
;
lock_kernel
();
memset
(
&
vattr
,
0
,
sizeof
(
vattr
));
memset
(
&
vattr
,
0
,
sizeof
(
vattr
));
inode
->
i_ctime
=
CURRENT_TIME
;
coda_iattr_to_vattr
(
iattr
,
&
vattr
);
vattr
.
va_type
=
C_VNON
;
/* cannot set type */
coda_iattr_to_vattr
(
iattr
,
&
vattr
);
vattr
.
va_type
=
C_VNON
;
/* cannot set type */
/* Venus is responsible for truncating the container-file!!! */
error
=
venus_setattr
(
inode
->
i_sb
,
coda_i2f
(
inode
),
&
vattr
);
...
...
@@ -273,9 +267,9 @@ int coda_setattr(struct dentry *de, struct iattr *iattr)
}
struct
inode_operations
coda_file_inode_operations
=
{
permission:
coda_permission
,
getattr:
coda_getattr
,
setattr:
coda_setattr
,
.
permission
=
coda_permission
,
.
getattr
=
coda_getattr
,
.
setattr
=
coda_setattr
,
};
static
int
coda_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
)
...
...
@@ -314,8 +308,9 @@ static struct super_block *coda_get_sb(struct file_system_type *fs_type,
}
struct
file_system_type
coda_fs_type
=
{
owner:
THIS_MODULE
,
name:
"coda"
,
get_sb:
coda_get_sb
,
kill_sb:
kill_anon_super
,
.
owner
=
THIS_MODULE
,
.
name
=
"coda"
,
.
get_sb
=
coda_get_sb
,
.
kill_sb
=
kill_anon_super
,
};
fs/coda/pioctl.c
View file @
b4655acd
...
...
@@ -14,7 +14,6 @@
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/string.h>
#define __NO_VERSION__
#include <linux/namei.h>
#include <linux/module.h>
#include <asm/uaccess.h>
...
...
@@ -32,13 +31,13 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
/* exported from this file */
struct
inode_operations
coda_ioctl_inode_operations
=
{
permission:
coda_ioctl_permission
,
setattr:
coda_setattr
,
.
permission
=
coda_ioctl_permission
,
.
setattr
=
coda_setattr
,
};
struct
file_operations
coda_ioctl_operations
=
{
owner:
THIS_MODULE
,
ioctl:
coda_pioctl
,
.
owner
=
THIS_MODULE
,
.
ioctl
=
coda_pioctl
,
};
/* the coda pioctl inode ops */
...
...
fs/coda/symlink.c
View file @
b4655acd
...
...
@@ -51,5 +51,5 @@ static int coda_symlink_filler(struct file *file, struct page *page)
}
struct
address_space_operations
coda_symlink_aops
=
{
readpage:
coda_symlink_filler
.
readpage
=
coda_symlink_filler
,
};
fs/coda/sysctl.c
View file @
b4655acd
...
...
@@ -22,7 +22,6 @@
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <linux/utsname.h>
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/coda.h>
...
...
@@ -39,7 +38,6 @@ static struct ctl_table_header *fs_table_header;
#define CODA_TIMEOUT 3
/* timeout on upcalls to become intrble */
#define CODA_HARD 5
/* mount type "hard" or "soft" */
#define CODA_VFS 6
/* vfs statistics */
#define CODA_UPCALL 7
/* upcall statistics */
#define CODA_CACHE_INV 9
/* cache invalidation statistics */
#define CODA_FAKE_STATFS 10
/* don't query venus for actual cache usage */
...
...
@@ -47,7 +45,6 @@ static ctl_table coda_table[] = {
{
CODA_TIMEOUT
,
"timeout"
,
&
coda_timeout
,
sizeof
(
int
),
0644
,
NULL
,
&
proc_dointvec
},
{
CODA_HARD
,
"hard"
,
&
coda_hard
,
sizeof
(
int
),
0644
,
NULL
,
&
proc_dointvec
},
{
CODA_VFS
,
"vfs_stats"
,
NULL
,
0
,
0644
,
NULL
,
&
do_reset_coda_vfs_stats
},
{
CODA_UPCALL
,
"upcall_stats"
,
NULL
,
0
,
0644
,
NULL
,
&
do_reset_coda_upcall_stats
},
{
CODA_CACHE_INV
,
"cache_inv_stats"
,
NULL
,
0
,
0644
,
NULL
,
&
do_reset_coda_cache_inv_stats
},
{
CODA_FAKE_STATFS
,
"fake_statfs"
,
&
coda_fake_statfs
,
sizeof
(
int
),
0600
,
NULL
,
&
proc_dointvec
},
{
0
}
...
...
@@ -60,152 +57,17 @@ static ctl_table fs_table[] = {
struct
coda_vfs_stats
coda_vfs_stat
;
struct
coda_cache_inv_stats
coda_cache_inv_stat
;
struct
coda_upcall_stats_entry
coda_upcall_stat
[
CODA_NCALLS
];
struct
coda_upcallstats
coda_callstats
;
int
coda_upcall_timestamping
=
0
;
/* keep this in sync with coda.h! */
char
*
coda_upcall_names
[]
=
{
"totals "
,
/* 0 */
"- "
,
/* 1 */
"root "
,
/* 2 */
"open_by_fd "
,
/* 3 */
"open "
,
/* 4 */
"close "
,
/* 5 */
"ioctl "
,
/* 6 */
"getattr "
,
/* 7 */
"setattr "
,
/* 8 */
"access "
,
/* 9 */
"lookup "
,
/* 10 */
"create "
,
/* 11 */
"remove "
,
/* 12 */
"link "
,
/* 13 */
"rename "
,
/* 14 */
"mkdir "
,
/* 15 */
"rmdir "
,
/* 16 */
"readdir "
,
/* 17 */
"symlink "
,
/* 18 */
"readlink "
,
/* 19 */
"fsync "
,
/* 20 */
"- "
,
/* 21 */
"vget "
,
/* 22 */
"signal "
,
/* 23 */
"replace "
,
/* 24 */
"flush "
,
/* 25 */
"purgeuser "
,
/* 26 */
"zapfile "
,
/* 27 */
"zapdir "
,
/* 28 */
"- "
,
/* 29 */
"purgefid "
,
/* 30 */
"open_by_path"
,
/* 31 */
"resolve "
,
/* 32 */
"reintegrate "
,
/* 33 */
"statfs "
,
/* 34 */
"store "
,
/* 35 */
"release "
/* 36 */
};
void
reset_coda_vfs_stats
(
void
)
{
memset
(
&
coda_vfs_stat
,
0
,
sizeof
(
coda_vfs_stat
)
);
}
void
reset_coda_upcall_stats
(
void
)
{
memset
(
&
coda_upcall_stat
,
0
,
sizeof
(
coda_upcall_stat
)
);
}
void
reset_coda_cache_inv_stats
(
void
)
{
memset
(
&
coda_cache_inv_stat
,
0
,
sizeof
(
coda_cache_inv_stat
)
);
}
void
do_time_stats
(
struct
coda_upcall_stats_entry
*
pentry
,
unsigned
long
runtime
)
{
unsigned
long
time
=
runtime
;
/* time in us */
if
(
pentry
->
count
==
0
)
{
pentry
->
time_sum
=
pentry
->
time_squared_sum
=
0
;
}
pentry
->
count
++
;
pentry
->
time_sum
+=
time
;
pentry
->
time_squared_sum
+=
time
*
time
;
}
void
coda_upcall_stats
(
int
opcode
,
long
unsigned
runtime
)
{
struct
coda_upcall_stats_entry
*
pentry
;
if
(
opcode
<
0
||
opcode
>
CODA_NCALLS
-
1
)
{
printk
(
"Nasty opcode %d passed to coda_upcall_stats
\n
"
,
opcode
);
return
;
}
pentry
=
&
coda_upcall_stat
[
opcode
];
do_time_stats
(
pentry
,
runtime
);
/* fill in the totals */
pentry
=
&
coda_upcall_stat
[
0
];
do_time_stats
(
pentry
,
runtime
);
}
unsigned
long
get_time_average
(
const
struct
coda_upcall_stats_entry
*
pentry
)
{
return
(
pentry
->
count
==
0
)
?
0
:
pentry
->
time_sum
/
pentry
->
count
;
}
static
inline
unsigned
long
absolute
(
unsigned
long
x
)
{
return
x
>=
0
?
x
:
-
x
;
}
static
unsigned
long
sqr_root
(
unsigned
long
x
)
{
unsigned
long
y
=
x
,
r
;
int
n_bit
=
0
;
if
(
x
==
0
)
return
0
;
if
(
x
<
0
)
x
=
-
x
;
while
(
y
)
{
y
>>=
1
;
n_bit
++
;
}
r
=
1
<<
(
n_bit
/
2
);
while
(
1
)
{
r
=
(
r
+
x
/
r
)
/
2
;
if
(
r
*
r
<=
x
&&
x
<
(
r
+
1
)
*
(
r
+
1
)
)
break
;
}
return
r
;
}
unsigned
long
get_time_std_deviation
(
const
struct
coda_upcall_stats_entry
*
pentry
)
{
unsigned
long
time_avg
;
if
(
pentry
->
count
<=
1
)
return
0
;
time_avg
=
get_time_average
(
pentry
);
return
sqr_root
(
(
pentry
->
time_squared_sum
/
pentry
->
count
)
-
time_avg
*
time_avg
);
}
int
do_reset_coda_vfs_stats
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
)
{
...
...
@@ -220,27 +82,6 @@ int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
return
0
;
}
int
do_reset_coda_upcall_stats
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
)
{
if
(
write
)
{
if
(
*
lenp
>
0
)
{
char
c
;
if
(
get_user
(
c
,
(
char
*
)
buffer
))
return
-
EFAULT
;
coda_upcall_timestamping
=
(
c
==
'1'
);
}
reset_coda_upcall_stats
();
filp
->
f_pos
+=
*
lenp
;
}
else
{
*
lenp
=
0
;
}
return
0
;
}
int
do_reset_coda_cache_inv_stats
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
)
...
...
@@ -317,52 +158,6 @@ int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
return
len
;
}
int
coda_upcall_stats_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
{
int
len
=
0
;
int
i
;
off_t
begin
;
off_t
pos
=
0
;
char
tmpbuf
[
80
];
int
tmplen
=
0
;
/* this works as long as we are below 1024 characters! */
if
(
offset
<
80
)
len
+=
sprintf
(
buffer
,
"%-79s
\n
"
,
"Coda upcall statistics"
);
if
(
offset
<
160
)
len
+=
sprintf
(
buffer
+
len
,
"%-79s
\n
"
,
"======================"
);
if
(
offset
<
240
)
len
+=
sprintf
(
buffer
+
len
,
"%-79s
\n
"
,
"upcall count avg time(us) std deviation(us)"
);
if
(
offset
<
320
)
len
+=
sprintf
(
buffer
+
len
,
"%-79s
\n
"
,
"------ ----- ------------ -----------------"
);
pos
=
320
;
for
(
i
=
0
;
i
<
CODA_NCALLS
;
i
++
)
{
tmplen
+=
sprintf
(
tmpbuf
,
"%s %9d %10ld %10ld"
,
coda_upcall_names
[
i
],
coda_upcall_stat
[
i
].
count
,
get_time_average
(
&
coda_upcall_stat
[
i
]),
coda_upcall_stat
[
i
].
time_squared_sum
);
pos
+=
80
;
if
(
pos
<
offset
)
continue
;
len
+=
sprintf
(
buffer
+
len
,
"%-79s
\n
"
,
tmpbuf
);
if
(
len
>=
length
)
break
;
}
begin
=
len
-
(
pos
-
offset
);
*
start
=
buffer
+
begin
;
len
-=
begin
;
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
}
int
coda_cache_inv_stats_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
{
...
...
@@ -421,9 +216,7 @@ struct proc_dir_entry* proc_fs_coda;
void
coda_sysctl_init
()
{
memset
(
&
coda_callstats
,
0
,
sizeof
(
coda_callstats
));
reset_coda_vfs_stats
();
reset_coda_upcall_stats
();
reset_coda_cache_inv_stats
();
#ifdef CONFIG_PROC_FS
...
...
@@ -431,7 +224,6 @@ void coda_sysctl_init()
if
(
proc_fs_coda
)
{
proc_fs_coda
->
owner
=
THIS_MODULE
;
coda_proc_create
(
"vfs_stats"
,
coda_vfs_stats_get_info
);
coda_proc_create
(
"upcall_stats"
,
coda_upcall_stats_get_info
);
coda_proc_create
(
"cache_inv_stats"
,
coda_cache_inv_stats_get_info
);
}
#endif
...
...
@@ -454,7 +246,6 @@ void coda_sysctl_clean()
#if CONFIG_PROC_FS
remove_proc_entry
(
"cache_inv_stats"
,
proc_fs_coda
);
remove_proc_entry
(
"upcall_stats"
,
proc_fs_coda
);
remove_proc_entry
(
"vfs_stats"
,
proc_fs_coda
);
remove_proc_entry
(
"coda"
,
proc_root_fs
);
#endif
...
...
fs/coda/upcall.c
View file @
b4655acd
...
...
@@ -171,10 +171,7 @@ int venus_store(struct super_block *sb, struct ViceFid *fid, int flags,
insize
=
SIZE
(
store
);
UPARG
(
CODA_STORE
);
if
(
cred
)
{
memcpy
(
&
(
inp
->
ih
.
cred
),
cred
,
sizeof
(
*
cred
));
}
else
printk
(
"CODA: store without valid file creds.
\n
"
);
memcpy
(
&
(
inp
->
ih
.
cred
),
cred
,
sizeof
(
*
cred
));
inp
->
coda_store
.
VFid
=
*
fid
;
inp
->
coda_store
.
flags
=
flags
;
...
...
@@ -213,10 +210,7 @@ int venus_close(struct super_block *sb, struct ViceFid *fid, int flags,
insize
=
SIZE
(
release
);
UPARG
(
CODA_CLOSE
);
if
(
cred
)
{
memcpy
(
&
(
inp
->
ih
.
cred
),
cred
,
sizeof
(
*
cred
));
}
else
printk
(
"CODA: close without valid file creds.
\n
"
);
memcpy
(
&
(
inp
->
ih
.
cred
),
cred
,
sizeof
(
*
cred
));
inp
->
coda_close
.
VFid
=
*
fid
;
inp
->
coda_close
.
flags
=
flags
;
...
...
@@ -620,17 +614,13 @@ int venus_statfs(struct super_block *sb, struct statfs *sfs)
*
*/
static
inline
unsigned
long
coda_waitfor_upcall
(
struct
upc_req
*
vmp
,
struct
venus_comm
*
vcommp
)
static
inline
void
coda_waitfor_upcall
(
struct
upc_req
*
vmp
,
struct
venus_comm
*
vcommp
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
struct
timeval
begin
=
{
0
,
0
},
end
=
{
0
,
0
};
vmp
->
uc_posttime
=
jiffies
;
if
(
coda_upcall_timestamping
)
do_gettimeofday
(
&
begin
);
add_wait_queue
(
&
vmp
->
uc_sleep
,
&
wait
);
for
(;;)
{
if
(
!
coda_hard
&&
vmp
->
uc_opcode
!=
CODA_CLOSE
)
...
...
@@ -661,17 +651,7 @@ static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp,
remove_wait_queue
(
&
vmp
->
uc_sleep
,
&
wait
);
set_current_state
(
TASK_RUNNING
);
if
(
coda_upcall_timestamping
&&
begin
.
tv_sec
!=
0
)
{
do_gettimeofday
(
&
end
);
if
(
end
.
tv_usec
<
begin
.
tv_usec
)
{
end
.
tv_usec
+=
1000000
;
end
.
tv_sec
--
;
}
end
.
tv_sec
-=
begin
.
tv_sec
;
end
.
tv_usec
-=
begin
.
tv_usec
;
}
return
((
end
.
tv_sec
*
1000000
)
+
end
.
tv_usec
);
return
;
}
...
...
@@ -689,7 +669,6 @@ static int coda_upcall(struct coda_sb_info *sbi,
int
inSize
,
int
*
outSize
,
union
inputArgs
*
buffer
)
{
unsigned
long
runtime
;
struct
venus_comm
*
vcommp
;
union
outputArgs
*
out
;
struct
upc_req
*
req
;
...
...
@@ -732,8 +711,7 @@ static int coda_upcall(struct coda_sb_info *sbi,
* ENODEV. */
/* Go to sleep. Wake up on signals only after the timeout. */
runtime
=
coda_waitfor_upcall
(
req
,
vcommp
);
coda_upcall_stats
(((
union
inputArgs
*
)
buffer
)
->
ih
.
opcode
,
runtime
);
coda_waitfor_upcall
(
req
,
vcommp
);
if
(
vcommp
->
vc_inuse
)
{
/* i.e. Venus is still alive */
/* Op went through, interrupt or not... */
...
...
@@ -794,8 +772,6 @@ static int coda_upcall(struct coda_sb_info *sbi,
exit:
upc_free
(
req
);
if
(
error
)
badclstats
();
return
error
;
}
...
...
@@ -842,7 +818,6 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
switch
(
opcode
)
{
case
CODA_FLUSH
:
{
clstats
(
CODA_FLUSH
);
coda_cache_clear_all
(
sb
,
NULL
);
shrink_dcache_sb
(
sb
);
coda_flag_inode
(
sb
->
s_root
->
d_inode
,
C_FLUSH
);
...
...
@@ -855,7 +830,6 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
printk
(
"PURGEUSER: null cred!
\n
"
);
return
0
;
}
clstats
(
CODA_PURGEUSER
);
coda_cache_clear_all
(
sb
,
cred
);
return
(
0
);
}
...
...
@@ -863,7 +837,6 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
case
CODA_ZAPDIR
:
{
struct
inode
*
inode
;
ViceFid
*
fid
=
&
out
->
coda_zapdir
.
CodaFid
;
clstats
(
CODA_ZAPDIR
);
inode
=
coda_fid_to_inode
(
fid
,
sb
);
if
(
inode
)
{
...
...
@@ -878,7 +851,6 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
case
CODA_ZAPFILE
:
{
struct
inode
*
inode
;
struct
ViceFid
*
fid
=
&
out
->
coda_zapfile
.
CodaFid
;
clstats
(
CODA_ZAPFILE
);
inode
=
coda_fid_to_inode
(
fid
,
sb
);
if
(
inode
)
{
coda_flag_inode
(
inode
,
C_VATTR
);
...
...
@@ -890,7 +862,6 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
case
CODA_PURGEFID
:
{
struct
inode
*
inode
;
ViceFid
*
fid
=
&
out
->
coda_purgefid
.
CodaFid
;
clstats
(
CODA_PURGEFID
);
inode
=
coda_fid_to_inode
(
fid
,
sb
);
if
(
inode
)
{
coda_flag_inode_children
(
inode
,
C_PURGE
);
...
...
@@ -908,7 +879,6 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
struct
inode
*
inode
;
ViceFid
*
oldfid
=
&
out
->
coda_replace
.
OldFid
;
ViceFid
*
newfid
=
&
out
->
coda_replace
.
NewFid
;
clstats
(
CODA_REPLACE
);
inode
=
coda_fid_to_inode
(
oldfid
,
sb
);
if
(
inode
)
{
coda_replace_fid
(
inode
,
oldfid
,
newfid
);
...
...
include/linux/coda_fs_i.h
View file @
b4655acd
...
...
@@ -20,13 +20,25 @@ struct coda_inode_info {
struct
ViceFid
c_fid
;
/* Coda identifier */
u_short
c_flags
;
/* flags (see below) */
struct
list_head
c_cilist
;
/* list of all coda inodes */
struct
file
*
c_container
;
/* container file for this cnode */
unsigned
int
c_contcount
;
/* refcount for container file */
unsigned
int
c_mapcount
;
/* nr of times this inode is mapped */
struct
coda_cred
c_cached_cred
;
/* credentials of cached perms */
unsigned
int
c_cached_perm
;
/* cached access permissions */
struct
inode
vfs_inode
;
};
/*
* coda fs file private data
*/
#define CODA_MAGIC 0xC0DAC0DA
struct
coda_file_info
{
int
cfi_magic
;
/* magic number */
struct
file
*
cfi_container
;
/* container file for this cnode */
unsigned
int
cfi_mapcount
;
/* nr of times this file is mapped */
struct
coda_cred
cfi_cred
;
/* credentials of opener */
};
#define CODA_FTOC(file) ((struct coda_file_info *)((file)->private_data))
/* flags */
#define C_VATTR 0x1
/* Validity of vattr in inode */
#define C_FLUSH 0x2
/* used after a flush */
...
...
include/linux/coda_linux.h
View file @
b4655acd
...
...
@@ -21,6 +21,7 @@
#include <linux/wait.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/coda_fs_i.h>
/* operations */
extern
struct
inode_operations
coda_dir_inode_operations
;
...
...
@@ -45,7 +46,6 @@ int coda_setattr(struct dentry *, struct iattr *);
int
coda_isnullfid
(
ViceFid
*
fid
);
/* global variables */
extern
int
coda_access_cache
;
extern
int
coda_fake_statfs
;
/* this file: heloers */
...
...
@@ -53,7 +53,6 @@ static __inline__ struct ViceFid *coda_i2f(struct inode *);
static
__inline__
char
*
coda_i2s
(
struct
inode
*
);
static
__inline__
void
coda_flag_inode
(
struct
inode
*
,
int
flag
);
char
*
coda_f2s
(
ViceFid
*
f
);
char
*
coda_f2s2
(
ViceFid
*
f
);
int
coda_isroot
(
struct
inode
*
i
);
int
coda_iscontrol
(
const
char
*
name
,
size_t
length
);
...
...
include/linux/coda_proc.h
View file @
b4655acd
...
...
@@ -14,7 +14,6 @@
void
coda_sysctl_init
(
void
);
void
coda_sysctl_clean
(
void
);
void
coda_upcall_stats
(
int
opcode
,
unsigned
long
jiffies
);
#include <linux/sysctl.h>
#include <linux/coda_fs_i.h>
...
...
@@ -23,13 +22,11 @@ void coda_upcall_stats(int opcode, unsigned long jiffies);
/* these four files are presented to show the result of the statistics:
*
* /proc/fs/coda/vfs_stats
* upcall_stats
* cache_inv_stats
*
* these four files are presented to reset the statistics to 0:
*
* /proc/sys/coda/vfs_stats
* upcall_stats
* cache_inv_stats
*/
...
...
@@ -61,13 +58,6 @@ struct coda_vfs_stats
int
readlink
;
};
struct
coda_upcall_stats_entry
{
int
count
;
unsigned
long
time_sum
;
unsigned
long
time_squared_sum
;
};
/* cache invalidation statistics */
struct
coda_cache_inv_stats
{
...
...
@@ -83,31 +73,16 @@ struct coda_cache_inv_stats
/* these global variables hold the actual statistics data */
extern
struct
coda_vfs_stats
coda_vfs_stat
;
extern
struct
coda_cache_inv_stats
coda_cache_inv_stat
;
extern
int
coda_upcall_timestamping
;
/* reset statistics to 0 */
void
reset_coda_vfs_stats
(
void
);
void
reset_coda_upcall_stats
(
void
);
void
reset_coda_cache_inv_stats
(
void
);
/* some utitlities to make it easier for you to do statistics for time */
void
do_time_stats
(
struct
coda_upcall_stats_entry
*
pentry
,
unsigned
long
jiffy
);
/*
double get_time_average( const struct coda_upcall_stats_entry * pentry );
double get_time_std_deviation( const struct coda_upcall_stats_entry * pentry );
*/
unsigned
long
get_time_average
(
const
struct
coda_upcall_stats_entry
*
pentry
);
unsigned
long
get_time_std_deviation
(
const
struct
coda_upcall_stats_entry
*
pentry
);
/* like coda_dointvec, these functions are to be registered in the ctl_table
* data structure for /proc/sys/... files
*/
int
do_reset_coda_vfs_stats
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
);
int
do_reset_coda_upcall_stats
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
);
int
do_reset_coda_cache_inv_stats
(
ctl_table
*
table
,
int
write
,
struct
file
*
filp
,
void
*
buffer
,
size_t
*
lenp
);
...
...
@@ -115,8 +90,6 @@ int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
/* these functions are called to form the content of /proc/fs/coda/... files */
int
coda_vfs_stats_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
);
int
coda_upcall_stats_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
);
int
coda_cache_inv_stats_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
);
...
...
include/linux/coda_psdev.h
View file @
b4655acd
...
...
@@ -98,27 +98,7 @@ struct upc_req {
/*
* Statistics
*/
struct
coda_upcallstats
{
int
ncalls
;
/* client requests */
int
nbadcalls
;
/* upcall failures */
int
reqs
[
CODA_NCALLS
];
/* count of each request */
}
;
extern
struct
coda_upcallstats
coda_callstats
;
extern
struct
venus_comm
coda_comms
[];
static
inline
void
clstats
(
int
opcode
)
{
coda_callstats
.
ncalls
++
;
if
(
(
0
<=
opcode
)
&&
(
opcode
<=
CODA_NCALLS
)
)
coda_callstats
.
reqs
[
opcode
]
++
;
else
printk
(
"clstats called with bad opcode %d
\n
"
,
opcode
);
}
static
inline
void
badclstats
(
void
)
{
coda_callstats
.
nbadcalls
++
;
}
#endif
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