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
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