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
c83fb0bd
Commit
c83fb0bd
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.1.45pre8
parent
1b081ced
Changes
62
Hide whitespace changes
Inline
Side-by-side
Showing
62 changed files
with
649 additions
and
620 deletions
+649
-620
Documentation/binfmt_misc.txt
Documentation/binfmt_misc.txt
+43
-26
fs/autofs/dir.c
fs/autofs/dir.c
+3
-2
fs/autofs/inode.c
fs/autofs/inode.c
+11
-4
fs/autofs/root.c
fs/autofs/root.c
+87
-46
fs/binfmt_misc.c
fs/binfmt_misc.c
+22
-7
fs/ext2/ialloc.c
fs/ext2/ialloc.c
+2
-4
fs/ext2/inode.c
fs/ext2/inode.c
+11
-1
fs/ext2/namei.c
fs/ext2/namei.c
+30
-41
fs/ext2/super.c
fs/ext2/super.c
+2
-1
fs/fat/cache.c
fs/fat/cache.c
+1
-1
fs/fat/file.c
fs/fat/file.c
+5
-3
fs/fat/inode.c
fs/fat/inode.c
+8
-5
fs/fat/misc.c
fs/fat/misc.c
+3
-5
fs/fat/mmap.c
fs/fat/mmap.c
+3
-3
fs/fifo.c
fs/fifo.c
+0
-1
fs/inode.c
fs/inode.c
+30
-67
fs/isofs/dir.c
fs/isofs/dir.c
+1
-17
fs/isofs/inode.c
fs/isofs/inode.c
+2
-3
fs/isofs/namei.c
fs/isofs/namei.c
+17
-61
fs/minix/bitmap.c
fs/minix/bitmap.c
+1
-1
fs/minix/file.c
fs/minix/file.c
+1
-1
fs/minix/inode.c
fs/minix/inode.c
+4
-10
fs/minix/namei.c
fs/minix/namei.c
+24
-24
fs/minix/symlink.c
fs/minix/symlink.c
+17
-1
fs/minix/truncate.c
fs/minix/truncate.c
+7
-7
fs/msdos/namei.c
fs/msdos/namei.c
+15
-12
fs/namei.c
fs/namei.c
+17
-29
fs/nfs/dir.c
fs/nfs/dir.c
+16
-18
fs/nfs/file.c
fs/nfs/file.c
+1
-1
fs/nfs/inode.c
fs/nfs/inode.c
+13
-4
fs/nfs/read.c
fs/nfs/read.c
+0
-2
fs/nfs/write.c
fs/nfs/write.c
+1
-4
fs/open.c
fs/open.c
+1
-0
fs/pipe.c
fs/pipe.c
+50
-6
fs/proc/Makefile
fs/proc/Makefile
+1
-1
fs/proc/arbitrary.c
fs/proc/arbitrary.c
+0
-57
fs/proc/fd.c
fs/proc/fd.c
+18
-6
fs/proc/inode.c
fs/proc/inode.c
+10
-3
fs/proc/root.c
fs/proc/root.c
+40
-35
fs/stat.c
fs/stat.c
+0
-4
fs/sysv/dir.c
fs/sysv/dir.c
+1
-0
fs/sysv/file.c
fs/sysv/file.c
+4
-3
fs/sysv/ialloc.c
fs/sysv/ialloc.c
+2
-2
fs/sysv/inode.c
fs/sysv/inode.c
+7
-8
fs/sysv/namei.c
fs/sysv/namei.c
+38
-37
fs/sysv/symlink.c
fs/sysv/symlink.c
+17
-1
fs/sysv/truncate.c
fs/sysv/truncate.c
+7
-5
fs/vfat/namei.c
fs/vfat/namei.c
+10
-8
include/linux/dcache.h
include/linux/dcache.h
+1
-1
include/linux/ext2_fs.h
include/linux/ext2_fs.h
+2
-1
include/linux/fs.h
include/linux/fs.h
+5
-4
include/linux/iso_fs.h
include/linux/iso_fs.h
+1
-2
include/linux/iso_fs_i.h
include/linux/iso_fs_i.h
+0
-1
include/linux/minix_fs.h
include/linux/minix_fs.h
+1
-1
include/linux/msdos_fs.h
include/linux/msdos_fs.h
+1
-1
include/linux/nfsd/nfsfh.h
include/linux/nfsd/nfsfh.h
+13
-13
include/linux/pipe_fs_i.h
include/linux/pipe_fs_i.h
+1
-2
include/linux/proc_fs.h
include/linux/proc_fs.h
+1
-1
include/linux/sysv_fs.h
include/linux/sysv_fs.h
+3
-3
kernel/ksyms.c
kernel/ksyms.c
+1
-0
net/socket.c
net/socket.c
+13
-0
net/unix/af_unix.c
net/unix/af_unix.c
+2
-2
No files found.
Documentation/binfmt_misc.txt
View file @
c83fb0bd
Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
=====================================================================
Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
=====================================================================
This Kernel feature allows to invoke almost (for restrictions see below) every
program by simply typing it
'
s name in the shell.
program by simply typing its name in the shell.
This includes for example compiled Java(TM), Python or Emacs programs.
To achieve this you must tell binfmt_misc which interpreter has to be invoked
with
w
hich binary. Binfmt_misc recognises the binary-type by matching some bytes at the
beginning of the file with a magic byte sequence (masking out specified bits) you
have supplied. Binfmt_misc can also recognise a filename extension (aka .com) and
optionally strip it off.
To achieve this you must tell binfmt_misc which interpreter has to be invoked
w
ith which binary. Binfmt_misc recognises the binary-type by matching some bytes
at the beginning of the file with a magic byte sequence (masking out specified
bits) you have supplied. Binfmt_misc can also recognise a filename extension
(aka .com) and
optionally strip it off.
To actually register a new binary type, you have to set up a string looking like
:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon
your
needs) and echo it to /proc/sys/fs/binfmt_misc/register.
:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon
your
needs) and echo it to /proc/sys/fs/binfmt_misc/register.
Here is what the fields mean:
- 'name' is an identifier string. A new /proc file will be created with this
this
name below /proc/sys/fs/binfmt_misc
name below /proc/sys/fs/binfmt_misc
- 'type' is the type of recognition. Give 'M' for magic and 'E' for extension.
Give the corresponding lowercase letter to let binfmt_misc strip of the
Give the corresponding lowercase letter to let binfmt_misc strip of
f
the
filename extension.
- 'offset' is the offset of the magic/mask in the file counted in bytes. This
- 'offset' is the offset of the magic/mask in the file
,
counted in bytes. This
defaults to 0 if you omit it (i.e. you write ':name:type::magic...')
- 'magic' is the byte sequence binfmt_misc is matching for. The magic string
may contain hex-encoded characters like \x0a or \xA4. In a shell environment
...
...
@@ -28,26 +28,23 @@ Here is what the fields mean:
If you chose filename extension matching, this is the extension to be
recognised (the \x0a specials are not allowed). Extension matching is case
sensitive!
- 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some
bits
from matching by supplying a string like magic and as long as magic. The
mask is anded with the byte sequence of the file.
- 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some
bits from matching by supplying a string like magic and as long as magic.
The
mask is anded with the byte sequence of the file.
- 'interpreter' is the program that should be invoked with the binary as first
argument (specify the full path)
There are some restrictions:
- the whole register string may not exceed 255 characters
- the magic must resist in the first 128 bytes of the file, i.e.
offset+size(magic)
has to be less than 128
- the magic must resist in the first 128 bytes of the file, i.e.
offset+size(magic)
has to be less than 128
- the interpreter string may not exceed 127 characters
You may want to add the binary formats in one of your /etc/rc scripts during boot-up.
Read the manual of your init program to figure out how to do this right.
You may want to add the binary formats in one of your /etc/rc scripts during
boot-up. Read the manual of your init program to figure out how to do this
right.
A few examples (assumed you are in /proc/sys/fs/binfmt_misc):
- enable Java(TM)-support (like binfmt_java):
echo ":Java:M::\xca\xfe\xba\xbe::/usr/local/bin/java:" > register
echo :Applet:M::\<\!--applet::/usr/local/bin/appletviewer: > register
- enable support for em86 (like binfmt_em86, for Alpha AXP only):
echo ":i386:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
echo ":i486:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
...
...
@@ -57,8 +54,9 @@ A few examples (assumed you are in /proc/sys/fs/binfmt_misc):
- enable support for DOS/Windows executables (using mzloader and dosemu/wine):
echo ":DOSWin:M::MZ::/usr/sbin/mzloader:" > register
echo ":DOS:E::com::/usr/sbin/mzloader:" > register
echo ":DOS2:E::exe::/usr/sbin/mzloader:" > register
echo ":DOScom:E::com::/usr/sbin/mzloader:" > register
echo ":DOSexe:E::exe::/usr/sbin/mzloader:" > register
You can enable/disable binfmt_misc or one binary type by echoing 0 (to disable)
or 1 (to enable) to /proc/sys/fs/binfmt_misc/status or /proc/.../the_name.
...
...
@@ -68,6 +66,25 @@ You can remove one entry or all entries by echoing -1 to /proc/.../the_name
or /proc/sys/fs/binfmt_misc/status.
Emulating binfmt_java:
======================
To emulate binfmt_java the following register-strings are necessary
(the first two for byte-compiled Java binaries, the third for applets
contained in a html-file). Register exactly in this order!
":Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/java:"
":JavaC:e::class::/usr/local/java/bin/java:"
":Applet:E::html::/usr/local/java/bin/appletviewer:"
To add a Java-executable to your path you can either make a symbolic
link to the .class file elsewhere in your path (cut the .class-extension
in the destination name for convenience) or add the directory of your
.class files to your PATH environment. In both cases, ensure that the
.class files are in your CLASSPATH environment!
This is sort of ugly - Javas filename handling is just broken.
HINTS:
======
...
...
fs/autofs/dir.c
View file @
c83fb0bd
...
...
@@ -37,9 +37,10 @@ static int autofs_dir_readdir(struct inode *inode, struct file *filp,
/*
* No entries except for "." and "..", both of which are handled by the VFS layer
*/
static
int
autofs_dir_lookup
(
struct
inode
*
dir
,
struct
qstr
*
str
,
struct
inode
**
result
)
static
int
autofs_dir_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
return
-
ENOENT
;
/* No other entries */
d_add
(
dentry
,
NULL
);
return
0
;
}
static
struct
file_operations
autofs_dir_operations
=
{
...
...
fs/autofs/inode.c
View file @
c83fb0bd
...
...
@@ -19,10 +19,16 @@
#define __NO_VERSION__
#include <linux/module.h>
/*
* Dummy functions - do we ever actually want to do
* something here?
*/
static
void
autofs_put_inode
(
struct
inode
*
inode
)
{
if
(
inode
->
i_nlink
)
return
;
}
static
void
autofs_delete_inode
(
struct
inode
*
inode
)
{
inode
->
i_size
=
0
;
}
...
...
@@ -59,11 +65,12 @@ static void autofs_write_inode(struct inode *inode);
static
struct
super_operations
autofs_sops
=
{
autofs_read_inode
,
NULL
,
autofs_write_inode
,
autofs_put_inode
,
autofs_delete_inode
,
NULL
,
/* notify_change */
autofs_put_super
,
NULL
,
NULL
,
/* write_super */
autofs_statfs
,
NULL
};
...
...
fs/autofs/root.c
View file @
c83fb0bd
...
...
@@ -16,7 +16,7 @@
#include "autofs_i.h"
static
int
autofs_root_readdir
(
struct
inode
*
,
struct
file
*
,
void
*
,
filldir_t
);
static
int
autofs_root_lookup
(
struct
inode
*
,
struct
qstr
*
,
struct
inode
*
*
);
static
int
autofs_root_lookup
(
struct
inode
*
,
struct
dentry
*
);
static
int
autofs_root_symlink
(
struct
inode
*
,
struct
dentry
*
,
const
char
*
);
static
int
autofs_root_unlink
(
struct
inode
*
,
struct
dentry
*
);
static
int
autofs_root_rmdir
(
struct
inode
*
,
struct
dentry
*
);
...
...
@@ -93,64 +93,105 @@ static int autofs_root_readdir(struct inode *inode, struct file *filp,
return
0
;
}
static
int
autofs_root_lookup
(
struct
inode
*
dir
,
struct
qstr
*
str
,
struct
inode
**
result
)
static
int
try_to_fill_dentry
(
struct
dentry
*
dentry
,
struct
super_block
*
sb
,
struct
autofs_sb_info
*
sbi
)
{
struct
autofs_sb_info
*
sbi
;
struct
inode
*
inode
;
struct
autofs_dir_ent
*
ent
;
while
(
!
(
ent
=
autofs_hash_lookup
(
&
sbi
->
dirhash
,
&
dentry
->
d_name
)))
{
int
status
=
autofs_wait
(
sbi
,
&
dentry
->
d_name
);
/* Turn this into a real negative dentry? */
if
(
status
==
-
ENOENT
)
{
dentry
->
d_flags
=
0
;
return
0
;
}
if
(
status
)
return
status
;
}
if
(
!
dentry
->
d_inode
)
{
inode
=
iget
(
sb
,
ent
->
ino
);
if
(
!
inode
)
return
-
EACCES
;
dentry
->
d_inode
=
inode
;
}
if
(
S_ISDIR
(
dentry
->
d_inode
->
i_mode
))
{
while
(
dentry
==
dentry
->
d_mounts
)
schedule
();
}
dentry
->
d_flags
=
0
;
return
0
;
}
/*
* Revalidate is called on every cache lookup. Some of those
* cache lookups may actually happen while the dentry is not
* yet completely filled in, and revalidate has to delay such
* lookups..
*/
static
struct
dentry
*
autofs_revalidate
(
struct
dentry
*
dentry
)
{
struct
autofs_sb_info
*
sbi
;
struct
inode
*
dir
=
dentry
->
d_parent
->
d_inode
;
sbi
=
(
struct
autofs_sb_info
*
)
dir
->
i_sb
->
u
.
generic_sbp
;
/* Incomplete dentry? */
if
(
dentry
->
d_flags
)
{
if
(
autofs_oz_mode
(
sbi
))
return
dentry
;
try_to_fill_dentry
(
dentry
,
dir
->
i_sb
,
sbi
);
return
dentry
;
}
/* Negative dentry.. Should we time these out? */
if
(
!
dentry
->
d_inode
)
return
dentry
;
/* We should update the usage stuff here.. */
return
dentry
;
}
static
int
autofs_root_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
struct
autofs_sb_info
*
sbi
;
struct
inode
*
res
;
int
status
,
oz_mode
;
int
oz_mode
;
DPRINTK
((
"autofs_root_lookup: name = "
));
autofs_say
(
str
->
name
,
str
->
len
);
autofs_say
(
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
);
*
result
=
NULL
;
if
(
!
dir
)
return
-
ENOENT
;
if
(
!
S_ISDIR
(
dir
->
i_mode
))
return
-
ENOTDIR
;
*
result
=
res
=
NULL
;
res
=
NULL
;
sbi
=
(
struct
autofs_sb_info
*
)
dir
->
i_sb
->
u
.
generic_sbp
;
oz_mode
=
autofs_oz_mode
(
sbi
);
DPRINTK
((
"autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d
\n
"
,
current
->
pid
,
current
->
pgrp
,
sbi
->
catatonic
,
oz_mode
));
do
{
while
(
!
(
ent
=
autofs_hash_lookup
(
&
sbi
->
dirhash
,
str
))
)
{
DPRINTK
((
"lookup failed, pid = %u, pgrp = %u
\n
"
,
current
->
pid
,
current
->
pgrp
));
if
(
oz_mode
)
return
-
ENOENT
;
up
(
&
dir
->
i_sem
);
status
=
autofs_wait
(
sbi
,
str
);
down
(
&
dir
->
i_sem
);
DPRINTK
((
"autofs_wait returned %d
\n
"
,
status
));
if
(
status
)
return
status
;
}
DPRINTK
((
"lookup successful, inode = %08x
\n
"
,
(
unsigned
int
)
ent
->
ino
));
if
(
!
(
res
=
iget
(
dir
->
i_sb
,
ent
->
ino
)))
{
printk
(
"autofs: iget returned null!
\n
"
);
return
-
EACCES
;
}
if
(
!
oz_mode
&&
S_ISDIR
(
res
->
i_mode
)
&&
i_dentry
(
res
)
->
d_covers
==
i_dentry
(
res
))
{
/* Not a mount point yet, call 1-800-DAEMON */
DPRINTK
((
"autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u
\n
"
,
res
->
i_ino
,
current
->
pid
,
current
->
pgrp
));
iput
(
res
);
res
=
NULL
;
up
(
&
dir
->
i_sem
);
status
=
autofs_wait
(
sbi
,
str
);
down
(
&
dir
->
i_sem
);
if
(
status
)
return
status
;
}
}
while
(
!
res
);
autofs_update_usage
(
&
sbi
->
dirhash
,
ent
);
*
result
=
res
;
/*
* Mark the dentry incomplete, but add it. This is needed so
* that the VFS layer knows about the dentry, and we can count
* on catching any lookups through the revalidate.
*
* Let all the hard work be done by the revalidate function that
* needs to be able to do this anyway..
*
* We need to do this before we release the directory semaphore.
*/
dentry
->
d_revalidate
=
autofs_revalidate
;
dentry
->
d_flags
=
1
;
d_add
(
dentry
,
NULL
);
up
(
&
dir
->
i_sem
);
autofs_revalidate
(
dentry
);
down
(
&
dir
->
i_sem
);
return
0
;
}
...
...
@@ -164,7 +205,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
struct
autofs_symlink
*
sl
;
DPRINTK
((
"autofs_root_symlink: %s <- "
,
symname
));
autofs_say
(
name
,
len
);
autofs_say
(
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
);
if
(
!
autofs_oz_mode
(
sbi
)
)
return
-
EPERM
;
...
...
fs/binfmt_misc.c
View file @
c83fb0bd
...
...
@@ -50,7 +50,7 @@ struct binfmt_entry {
#define ENTRY_ENABLED 1
/* the old binfmt_entry.enabled */
#define ENTRY_MAGIC 8
/* not filename detection */
#define ENTRY_STRIP_EXT 32
/* strip of last filename extension */
#define ENTRY_STRIP_EXT 32
/* strip of
f
last filename extension */
static
int
load_misc_binary
(
struct
linux_binprm
*
bprm
,
struct
pt_regs
*
regs
);
static
void
entry_proc_cleanup
(
struct
binfmt_entry
*
e
);
...
...
@@ -162,6 +162,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
char
*
iname_addr
=
iname
,
*
p
;
int
retval
,
fmt_flags
=
0
;
MOD_INC_USE_COUNT
;
if
(
!
enabled
)
{
retval
=
-
ENOEXEC
;
goto
_ret
;
...
...
@@ -208,6 +209,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if
(
retval
>=
0
)
retval
=
search_binary_handler
(
bprm
,
regs
);
_ret:
MOD_DEC_USE_COUNT
;
return
retval
;
}
...
...
@@ -266,13 +268,18 @@ static int proc_write_register(struct file *file, const char *buffer,
struct
binfmt_entry
*
e
;
int
memsize
,
cnt
=
count
-
1
,
err
=
0
;
MOD_INC_USE_COUNT
;
/* some sanity checks */
if
((
count
<
11
)
||
(
count
>
256
))
return
-
EINVAL
;
if
((
count
<
11
)
||
(
count
>
256
))
{
err
=
-
EINVAL
;
goto
_err
;
}
memsize
=
sizeof
(
struct
binfmt_entry
)
+
count
;
if
(
!
(
e
=
(
struct
binfmt_entry
*
)
kmalloc
(
memsize
,
GFP_USER
)))
return
-
ENOMEM
;
if
(
!
(
e
=
(
struct
binfmt_entry
*
)
kmalloc
(
memsize
,
GFP_USER
)))
{
err
=
-
ENOMEM
;
goto
_err
;
}
sp
=
buffer
+
1
;
del
=
buffer
[
0
];
...
...
@@ -309,7 +316,8 @@ static int proc_write_register(struct file *file, const char *buffer,
!
(
e
->
proc_name
)
||
!
(
e
->
interpreter
)
||
entry_proc_setup
(
e
))
{
kfree
(
e
);
return
-
EINVAL
;
err
=
-
EINVAL
;
goto
_err
;
}
write_lock
(
&
entries_lock
);
...
...
@@ -317,7 +325,10 @@ static int proc_write_register(struct file *file, const char *buffer,
entries
=
e
;
write_unlock
(
&
entries_lock
);
return
count
;
err
=
count
;
_err:
MOD_DEC_USE_COUNT
;
return
err
;
}
/*
...
...
@@ -332,6 +343,7 @@ static int proc_read_status(char *page, char **start, off_t off,
char
*
dp
;
int
elen
,
i
;
MOD_INC_USE_COUNT
;
#ifndef VERBOSE_STATUS
if
(
data
)
{
read_lock
(
&
entries_lock
);
...
...
@@ -391,6 +403,7 @@ static int proc_read_status(char *page, char **start, off_t off,
*
eof
=
(
elen
<=
count
)
?
1
:
0
;
*
start
=
page
+
off
;
MOD_DEC_USE_COUNT
;
return
elen
;
}
...
...
@@ -404,6 +417,7 @@ static int proc_write_status(struct file *file, const char *buffer,
struct
binfmt_entry
*
e
;
int
res
=
count
;
MOD_INC_USE_COUNT
;
if
(((
buffer
[
0
]
==
'1'
)
||
(
buffer
[
0
]
==
'0'
))
&&
((
count
==
1
)
||
((
count
==
2
)
&&
(
buffer
[
1
]
==
'\n'
))))
{
if
(
data
)
{
...
...
@@ -423,6 +437,7 @@ static int proc_write_status(struct file *file, const char *buffer,
}
else
{
res
=
-
EINVAL
;
}
MOD_DEC_USE_COUNT
;
return
res
;
}
...
...
fs/ext2/ialloc.c
View file @
c83fb0bd
...
...
@@ -171,9 +171,8 @@ void ext2_free_inode (struct inode * inode)
printk
(
"ext2_free_inode: inode has no device
\n
"
);
return
;
}
if
(
atomic_read
(
&
inode
->
i_count
)
>
1
)
{
printk
(
"ext2_free_inode: inode has count=%d
\n
"
,
atomic_read
(
&
inode
->
i_count
));
if
(
inode
->
i_count
>
1
)
{
printk
(
"ext2_free_inode: inode has count=%d
\n
"
,
inode
->
i_count
);
return
;
}
if
(
inode
->
i_nlink
)
{
...
...
@@ -403,7 +402,6 @@ struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err)
sb
->
s_dirt
=
1
;
inode
->
i_mode
=
mode
;
inode
->
i_sb
=
sb
;
atomic_set
(
&
inode
->
i_count
,
1
);
inode
->
i_nlink
=
1
;
inode
->
i_dev
=
sb
->
s_dev
;
inode
->
i_uid
=
current
->
fsuid
;
...
...
fs/ext2/inode.c
View file @
c83fb0bd
...
...
@@ -31,10 +31,20 @@
static
int
ext2_update_inode
(
struct
inode
*
inode
,
int
do_sync
);
/*
* Called at each iput()
*/
void
ext2_put_inode
(
struct
inode
*
inode
)
{
ext2_discard_prealloc
(
inode
);
if
(
inode
->
i_nlink
||
inode
->
i_ino
==
EXT2_ACL_IDX_INO
||
}
/*
* Called at the last iput() if i_nlink is zero.
*/
void
ext2_delete_inode
(
struct
inode
*
inode
)
{
if
(
inode
->
i_ino
==
EXT2_ACL_IDX_INO
||
inode
->
i_ino
==
EXT2_ACL_DATA_INO
)
return
;
inode
->
u
.
ext2_i
.
i_dtime
=
CURRENT_TIME
;
...
...
fs/ext2/namei.c
View file @
c83fb0bd
...
...
@@ -155,31 +155,26 @@ static struct buffer_head * ext2_find_entry (struct inode * dir,
return
NULL
;
}
int
ext2_lookup
(
struct
inode
*
dir
,
struct
qstr
*
name
,
struct
inode
**
result
)
int
ext2_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
unsigned
long
ino
;
struct
inode
*
inode
;
struct
ext2_dir_entry
*
de
;
struct
buffer_head
*
bh
;
*
result
=
NULL
;
if
(
!
dir
)
return
-
ENOENT
;
if
(
!
S_ISDIR
(
dir
->
i_mode
))
return
-
ENOTDIR
;
if
(
name
->
len
>
EXT2_NAME_LEN
)
if
(
dentry
->
d_name
.
len
>
EXT2_NAME_LEN
)
return
-
ENAMETOOLONG
;
ino
=
dir
->
i_version
;
if
(
!
(
bh
=
ext2_find_entry
(
dir
,
name
->
name
,
name
->
len
,
&
de
)))
return
-
ENOENT
;
ino
=
le32_to_cpu
(
de
->
inode
);
brelse
(
bh
);
if
(
!
(
*
result
=
iget
(
dir
->
i_sb
,
ino
)))
return
-
EACCES
;
bh
=
ext2_find_entry
(
dir
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
&
de
);
inode
=
NULL
;
if
(
bh
)
{
unsigned
long
ino
=
le32_to_cpu
(
de
->
inode
);
brelse
(
bh
);
inode
=
iget
(
dir
->
i_sb
,
ino
);
if
(
!
inode
)
return
-
EACCES
;
}
d_add
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -613,7 +608,7 @@ int ext2_rmdir (struct inode * dir, struct dentry *dentry)
else
if
(
le32_to_cpu
(
de
->
inode
)
!=
inode
->
i_ino
)
retval
=
-
ENOENT
;
else
{
if
(
atomic_read
(
&
inode
->
i_count
)
>
1
)
{
if
(
inode
->
i_count
>
1
)
{
/*
* Are we deleting the last instance of a busy directory?
* Better clean up if so.
...
...
@@ -809,32 +804,30 @@ int ext2_link (struct inode * inode, struct inode * dir, struct dentry *dentry)
inode
->
i_nlink
++
;
inode
->
i_ctime
=
CURRENT_TIME
;
mark_inode_dirty
(
inode
);
atomic_inc
(
&
inode
->
i_count
)
;
inode
->
i_count
++
;
d_instantiate
(
dentry
,
inode
);
return
0
;
}
static
int
subdir
(
struct
inode
*
new_inode
,
struct
inode
*
old_inode
)
/*
* Trivially implemented using the dcache structure
*/
static
int
subdir
(
struct
dentry
*
new_dentry
,
struct
dentry
*
old_dentry
)
{
int
ino
;
int
result
;
atomic_inc
(
&
new_inode
->
i_count
);
result
=
0
;
for
(;;)
{
if
(
new_inode
==
old_inode
)
{
result
=
1
;
break
;
if
(
new_dentry
!=
old_dentry
)
{
struct
dentry
*
parent
=
new_dentry
->
d_parent
;
if
(
parent
==
new_dentry
)
break
;
new_dentry
=
parent
;
continue
;
}
if
(
new_inode
->
i_dev
!=
old_inode
->
i_dev
)
break
;
ino
=
new_inode
->
i_ino
;
if
(
ext2_lookup
(
new_inode
,
&
(
struct
qstr
)
{
".."
,
2
,
0
},
&
new_inode
))
break
;
if
(
new_inode
->
i_ino
==
ino
)
break
;
result
=
1
;
break
;
}
iput
(
new_inode
);
return
result
;
}
...
...
@@ -842,10 +835,6 @@ static int subdir (struct inode * new_inode, struct inode * old_inode)
((struct ext2_dir_entry *) ((char *) buffer + \
le16_to_cpu(((struct ext2_dir_entry *) buffer)->rec_len)))->inode
#define PARENT_NAME(buffer) \
((struct ext2_dir_entry *) ((char *) buffer + \
le16_to_cpu(((struct ext2_dir_entry *) buffer)->rec_len)))->name
/*
* rename uses retrying to avoid race-conditions: at least they should be
* minimal.
...
...
@@ -906,13 +895,13 @@ static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
if
(
!
S_ISDIR
(
old_inode
->
i_mode
))
goto
end_rename
;
retval
=
-
EINVAL
;
if
(
subdir
(
new_dir
,
old_inode
))
if
(
subdir
(
new_dentry
,
old_dentry
))
goto
end_rename
;
retval
=
-
ENOTEMPTY
;
if
(
!
empty_dir
(
new_inode
))
goto
end_rename
;
retval
=
-
EBUSY
;
if
(
atomic_read
(
&
new_inode
->
i_count
)
>
1
)
if
(
new_inode
->
i_count
>
1
)
goto
end_rename
;
}
retval
=
-
EPERM
;
...
...
@@ -925,7 +914,7 @@ static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
if
(
new_inode
&&
!
S_ISDIR
(
new_inode
->
i_mode
))
goto
end_rename
;
retval
=
-
EINVAL
;
if
(
subdir
(
new_dir
,
old_inode
))
if
(
subdir
(
new_dentry
,
old_dentry
))
goto
end_rename
;
dir_bh
=
ext2_bread
(
old_inode
,
0
,
0
,
&
retval
);
if
(
!
dir_bh
)
...
...
fs/ext2/super.c
View file @
c83fb0bd
...
...
@@ -133,9 +133,10 @@ void ext2_put_super (struct super_block * sb)
static
struct
super_operations
ext2_sops
=
{
ext2_read_inode
,
NULL
,
ext2_write_inode
,
ext2_put_inode
,
ext2_delete_inode
,
NULL
,
ext2_put_super
,
ext2_write_super
,
ext2_statfs
,
...
...
fs/fat/cache.c
View file @
c83fb0bd
...
...
@@ -280,7 +280,7 @@ int fat_free(struct inode *inode,int skip)
12
?
EOF_FAT12
:
EOF_FAT16
);
else
{
MSDOS_I
(
inode
)
->
i_start
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
lock_fat
(
inode
->
i_sb
);
while
(
nr
!=
-
1
)
{
...
...
fs/fat/file.c
View file @
c83fb0bd
...
...
@@ -52,6 +52,7 @@ struct inode_operations fat_file_inode_operations = {
NULL
,
/* mknod */
NULL
,
/* rename */
NULL
,
/* readlink */
NULL
,
/* follow_link */
generic_readpage
,
/* readpage */
NULL
,
/* writepage */
fat_bmap
,
/* bmap */
...
...
@@ -99,6 +100,7 @@ struct inode_operations fat_file_inode_operations_1024 = {
NULL
,
/* mknod */
NULL
,
/* rename */
NULL
,
/* readlink */
NULL
,
/* follow_link */
NULL
,
/* readpage */
NULL
,
/* writepage */
NULL
,
/* bmap */
...
...
@@ -355,7 +357,7 @@ long fat_file_write(
filp
->
f_pos
+=
written
;
if
(
filp
->
f_pos
>
inode
->
i_size
)
{
inode
->
i_size
=
filp
->
f_pos
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
fat_set_uptodate
(
sb
,
bh
,
1
);
fat_mark_buffer_dirty
(
sb
,
bh
,
0
);
...
...
@@ -365,7 +367,7 @@ long fat_file_write(
return
error
;
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
MSDOS_I
(
inode
)
->
i_attrs
|=
ATTR_ARCH
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
return
buf
-
start
;
}
...
...
@@ -379,5 +381,5 @@ void fat_truncate(struct inode *inode)
cluster
=
SECTOR_SIZE
*
MSDOS_SB
(
inode
->
i_sb
)
->
cluster_size
;
(
void
)
fat_free
(
inode
,(
inode
->
i_size
+
(
cluster
-
1
))
/
cluster
);
MSDOS_I
(
inode
)
->
i_attrs
|=
ATTR_ARCH
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
fs/fat/inode.c
View file @
c83fb0bd
...
...
@@ -196,6 +196,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
int
debug
,
error
,
fat
;
int
blksize
=
512
;
struct
fat_mount_options
opts
;
struct
inode
*
root_inode
;
MOD_INC_USE_COUNT
;
if
(
hardsect_size
[
MAJOR
(
sb
->
s_dev
)]
!=
NULL
){
...
...
@@ -329,7 +330,10 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
MSDOS_SB
(
sb
)
->
fat_lock
=
0
;
MSDOS_SB
(
sb
)
->
prev_free
=
0
;
memcpy
(
&
(
MSDOS_SB
(
sb
)
->
options
),
&
opts
,
sizeof
(
struct
fat_mount_options
));
if
(
!
(
sb
->
s_mounted
=
iget
(
sb
,
MSDOS_ROOT_INO
)))
{
root_inode
=
iget
(
sb
,
MSDOS_ROOT_INO
);
sb
->
s_root
=
d_alloc_root
(
root_inode
,
NULL
);
if
(
!
sb
->
s_root
)
{
sb
->
s_dev
=
0
;
printk
(
"get root inode failed
\n
"
);
MOD_DEC_USE_COUNT
;
...
...
@@ -339,7 +343,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
}
void
fat_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
bufsiz
)
int
fat_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
bufsiz
)
{
int
free
,
nr
;
struct
statfs
tmp
;
...
...
@@ -362,7 +366,7 @@ void fat_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
tmp
.
f_files
=
0
;
tmp
.
f_ffree
=
0
;
tmp
.
f_namelen
=
12
;
copy_to_user
(
buf
,
&
tmp
,
bufsiz
)
;
return
copy_to_user
(
buf
,
&
tmp
,
bufsiz
)
?
-
EFAULT
:
0
;
}
...
...
@@ -514,10 +518,9 @@ void fat_write_inode(struct inode *inode)
linked
->
i_blocks
=
inode
->
i_blocks
;
linked
->
i_atime
=
inode
->
i_atime
;
MSDOS_I
(
linked
)
->
i_attrs
=
MSDOS_I
(
inode
)
->
i_attrs
;
linked
->
i_dirt
=
1
;
mark_inode_dirty
(
linked
)
;
}
inode
->
i_dirt
=
0
;
if
(
inode
->
i_ino
==
MSDOS_ROOT_INO
||
!
inode
->
i_nlink
)
return
;
if
(
!
(
bh
=
fat_bread
(
sb
,
inode
->
i_ino
>>
MSDOS_DPB_BITS
)))
{
printk
(
"dev = %s, ino = %ld
\n
"
,
...
...
fs/fat/misc.c
View file @
c83fb0bd
...
...
@@ -40,9 +40,7 @@ void fat_fs_panic(struct super_block *s,const char *msg)
not_ro
=
!
(
s
->
s_flags
&
MS_RDONLY
);
if
(
not_ro
)
s
->
s_flags
|=
MS_RDONLY
;
printk
(
"Filesystem panic (dev %s, "
,
kdevname
(
s
->
s_dev
));
printk
(
"mounted on %s:%ld)
\n
%s
\n
"
,
/* note: kdevname returns & static char[] */
kdevname
(
s
->
s_covered
->
i_dev
),
s
->
s_covered
->
i_ino
,
msg
);
printk
(
"Filesystem panic (dev %s)."
,
kdevname
(
s
->
s_dev
));
if
(
not_ro
)
printk
(
" File system has been set read-only
\n
"
);
}
...
...
@@ -180,7 +178,7 @@ printk("last = %d\n",last);
if
(
last
)
fat_access
(
sb
,
last
,
nr
);
else
{
MSDOS_I
(
inode
)
->
i_start
=
nr
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
#ifdef DEBUG
if
(
last
)
printk
(
"next set to %d
\n
"
,
fat_access
(
sb
,
last
,
-
1
));
...
...
@@ -217,7 +215,7 @@ if (last) printk("next set to %d\n",fat_access(sb,last,-1));
#ifdef DEBUG
printk
(
"size is %d now (%x)
\n
"
,
inode
->
i_size
,
inode
);
#endif
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
return
0
;
}
...
...
fs/fat/mmap.c
View file @
c83fb0bd
...
...
@@ -29,7 +29,7 @@ static unsigned long fat_file_mmap_nopage(
unsigned
long
address
,
int
error_code
)
{
struct
inode
*
inode
=
area
->
vm_inode
;
struct
inode
*
inode
=
area
->
vm_
dentry
->
d_
inode
;
unsigned
long
page
;
unsigned
int
clear
;
int
pos
;
...
...
@@ -101,10 +101,10 @@ int fat_mmap(struct inode * inode, struct file * file, struct vm_area_struct * v
return
-
EACCES
;
if
(
!
IS_RDONLY
(
inode
))
{
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
vma
->
vm_
inode
=
inode
;
vma
->
vm_
dentry
=
dget
(
file
->
f_dentry
)
;
atomic_inc
(
&
inode
->
i_count
);
vma
->
vm_ops
=
&
fat_file_mmap
;
return
0
;
...
...
fs/fifo.c
View file @
c83fb0bd
...
...
@@ -153,7 +153,6 @@ struct inode_operations fifo_inode_operations = {
void
init_fifo
(
struct
inode
*
inode
)
{
inode
->
i_op
=
&
fifo_inode_operations
;
inode
->
i_pipe
=
1
;
PIPE_LOCK
(
*
inode
)
=
0
;
PIPE_BASE
(
*
inode
)
=
NULL
;
PIPE_START
(
*
inode
)
=
PIPE_LEN
(
*
inode
)
=
0
;
...
...
fs/inode.c
View file @
c83fb0bd
...
...
@@ -104,6 +104,7 @@ static inline void init_once(struct inode * inode)
memset
(
inode
,
0
,
sizeof
(
*
inode
));
init_waitqueue
(
&
inode
->
i_wait
);
INIT_LIST_HEAD
(
&
inode
->
i_dentry
);
INIT_LIST_HEAD
(
&
inode
->
i_hash
);
sema_init
(
&
inode
->
i_sem
,
1
);
}
...
...
@@ -192,18 +193,13 @@ void clear_inode(struct inode *inode)
if
(
IS_WRITABLE
(
inode
)
&&
inode
->
i_sb
&&
inode
->
i_sb
->
dq_op
)
inode
->
i_sb
->
dq_op
->
drop
(
inode
);
spin_lock
(
&
inode_lock
);
inode
->
i_state
=
0
;
list_del
(
&
inode
->
i_hash
);
list_del
(
&
inode
->
i_list
);
list_add
(
&
inode
->
i_list
,
&
inode_unused
);
spin_unlock
(
&
inode_lock
);
}
#define CAN_UNUSE(inode) \
((
atomic_read(&(inode)->i_count)
== 0) && \
((
(inode)->i_count
== 0) && \
((inode)->i_nrpages == 0) && \
(!
test_bit(I_LOCK, &(inode)->i_state)
))
(!
(inode)->i_state
))
static
void
invalidate_list
(
struct
list_head
*
head
,
kdev_t
dev
)
{
...
...
@@ -223,6 +219,7 @@ static void invalidate_list(struct list_head *head, kdev_t dev)
if
(
!
CAN_UNUSE
(
inode
))
continue
;
list_del
(
&
inode
->
i_hash
);
INIT_LIST_HEAD
(
&
inode
->
i_hash
);
list_del
(
&
inode
->
i_list
);
list_add
(
&
inode
->
i_list
,
&
inode_unused
);
}
...
...
@@ -257,6 +254,7 @@ static void try_to_free_inodes(void)
inode
=
list_entry
(
tmp
,
struct
inode
,
i_list
);
if
(
CAN_UNUSE
(
inode
))
{
list_del
(
&
inode
->
i_hash
);
INIT_LIST_HEAD
(
&
inode
->
i_hash
);
head
=
&
inode_unused
;
}
list_add
(
tmp
,
head
);
...
...
@@ -280,7 +278,7 @@ static struct inode * find_inode(struct super_block * sb, unsigned long ino, str
continue
;
if
(
inode
->
i_ino
!=
ino
)
continue
;
atomic_inc
(
&
inode
->
i_count
)
;
inode
->
i_count
++
;
break
;
}
return
inode
;
...
...
@@ -296,10 +294,9 @@ static struct inode * find_inode(struct super_block * sb, unsigned long ino, str
void
clean_inode
(
struct
inode
*
inode
)
{
memset
(
&
inode
->
u
,
0
,
sizeof
(
inode
->
u
));
inode
->
i_pipe
=
0
;
inode
->
i_sock
=
0
;
inode
->
i_op
=
NULL
;
inode
->
i_nlink
=
1
;
inode
->
i_nlink
=
0
;
inode
->
i_writecount
=
0
;
memset
(
&
inode
->
i_dquot
,
0
,
sizeof
(
inode
->
i_dquot
));
sema_init
(
&
inode
->
i_sem
,
1
);
...
...
@@ -322,15 +319,15 @@ struct inode * get_empty_inode(void)
struct
list_head
*
tmp
;
spin_lock
(
&
inode_lock
);
try_to_free_inodes
();
tmp
=
inode_unused
.
next
;
if
(
tmp
!=
&
inode_unused
)
{
list_del
(
tmp
);
inode
=
list_entry
(
tmp
,
struct
inode
,
i_list
);
add_new_inode:
INIT_LIST_HEAD
(
&
inode
->
i_hash
);
inode
->
i_sb
=
NULL
;
inode
->
i_ino
=
++
last_ino
;
atomic_set
(
&
inode
->
i_count
,
1
)
;
inode
->
i_count
=
1
;
list_add
(
&
inode
->
i_list
,
&
inode_in_use
);
inode
->
i_state
=
0
;
spin_unlock
(
&
inode_lock
);
...
...
@@ -350,44 +347,6 @@ struct inode * get_empty_inode(void)
return
inode
;
}
struct
inode
*
get_pipe_inode
(
void
)
{
extern
struct
inode_operations
pipe_inode_operations
;
struct
inode
*
inode
=
get_empty_inode
();
if
(
inode
)
{
unsigned
long
page
=
__get_free_page
(
GFP_USER
);
if
(
!
page
)
{
iput
(
inode
);
inode
=
NULL
;
}
else
{
PIPE_BASE
(
*
inode
)
=
(
char
*
)
page
;
inode
->
i_op
=
&
pipe_inode_operations
;
atomic_set
(
&
inode
->
i_count
,
1
);
PIPE_WAIT
(
*
inode
)
=
NULL
;
PIPE_START
(
*
inode
)
=
PIPE_LEN
(
*
inode
)
=
0
;
PIPE_RD_OPENERS
(
*
inode
)
=
PIPE_WR_OPENERS
(
*
inode
)
=
0
;
PIPE_READERS
(
*
inode
)
=
PIPE_WRITERS
(
*
inode
)
=
1
;
PIPE_LOCK
(
*
inode
)
=
0
;
/*
* Mark the inode dirty from the very beginning,
* that way it will never be moved to the dirty
* list because "make_inode_dirty()" will think
* that it already _is_ on the dirty list.
*/
inode
->
i_state
=
1
<<
I_DIRTY
;
inode
->
i_pipe
=
1
;
inode
->
i_mode
|=
S_IFIFO
|
S_IRUSR
|
S_IWUSR
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_gid
=
current
->
fsgid
;
inode
->
i_atime
=
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_blksize
=
PAGE_SIZE
;
}
}
return
inode
;
}
/*
* This is called with the inode lock held.. Be careful.
*/
...
...
@@ -406,7 +365,7 @@ static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, s
inode
->
i_dev
=
sb
->
s_dev
;
inode
->
i_ino
=
ino
;
inode
->
i_flags
=
sb
->
s_flags
;
atomic_set
(
&
inode
->
i_count
,
1
)
;
inode
->
i_count
=
1
;
inode
->
i_state
=
1
<<
I_LOCK
;
spin_unlock
(
&
inode_lock
);
clean_inode
(
inode
);
...
...
@@ -466,27 +425,31 @@ void insert_inode_hash(struct inode *inode)
void
iput
(
struct
inode
*
inode
)
{
if
(
inode
)
{
if
(
inode
->
i_pipe
)
wake_up_interruptible
(
&
PIPE_WAIT
(
*
inode
));
struct
super_operations
*
op
=
NULL
;
/*
* Last user dropping the inode?
*/
if
(
atomic_read
(
&
inode
->
i_count
)
==
1
)
{
void
(
*
put
)(
struct
inode
*
);
if
(
inode
->
i_sb
&&
inode
->
i_sb
->
s_op
)
op
=
inode
->
i_sb
->
s_op
;
if
(
op
&&
op
->
put_inode
)
op
->
put_inode
(
inode
);
if
(
inode
->
i_pipe
)
{
free_page
((
unsigned
long
)
PIPE_BASE
(
*
inode
));
PIPE_BASE
(
*
inode
)
=
NULL
;
spin_lock
(
&
inode_lock
);
if
(
!--
inode
->
i_count
)
{
if
(
!
inode
->
i_nlink
)
{
list_del
(
&
inode
->
i_hash
);
INIT_LIST_HEAD
(
&
inode
->
i_hash
);
if
(
op
&&
op
->
delete_inode
)
{
void
(
*
delete
)(
struct
inode
*
)
=
op
->
delete_inode
;
spin_unlock
(
&
inode_lock
);
delete
(
inode
);
spin_lock
(
&
inode_lock
);
}
}
if
(
inode
->
i_sb
&&
inode
->
i_sb
->
s_op
)
{
put
=
inode
->
i_sb
->
s_op
->
put_inode
;
if
(
put
)
put
(
inode
);
if
(
list_empty
(
&
inode
->
i_hash
))
{
list_del
(
&
inode
->
i_list
);
list_add
(
&
inode
->
i_list
,
&
inode_unused
);
}
}
atomic_dec
(
&
inode
->
i_count
);
spin_unlock
(
&
inode_lock
);
}
}
...
...
fs/isofs/dir.c
View file @
c83fb0bd
...
...
@@ -62,20 +62,6 @@ struct inode_operations isofs_dir_inode_operations =
NULL
/* permission */
};
static
int
parent_inode_number
(
struct
inode
*
inode
,
struct
iso_directory_record
*
de
)
{
int
inode_number
=
inode
->
i_ino
;
if
((
inode
->
i_sb
->
u
.
isofs_sb
.
s_firstdatazone
)
!=
inode
->
i_ino
)
inode_number
=
inode
->
u
.
isofs_i
.
i_backlink
;
if
(
inode_number
!=
-
1
)
return
inode_number
;
/* This should never happen, but who knows. Try to be forgiving */
return
isofs_lookup_grandparent
(
inode
,
find_rock_ridge_relocation
(
de
,
inode
));
}
static
int
isofs_name_translate
(
char
*
old
,
int
len
,
char
*
new
)
{
int
i
,
c
;
...
...
@@ -197,9 +183,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
/* Handle the case of the '..' directory */
if
(
de
->
name_len
[
0
]
==
1
&&
de
->
name
[
0
]
==
1
)
{
inode_number
=
parent_inode_number
(
inode
,
de
);
if
(
inode_number
==
-
1
)
break
;
inode_number
=
filp
->
f_dentry
->
d_parent
->
d_inode
->
i_ino
;
if
(
filldir
(
dirent
,
".."
,
2
,
filp
->
f_pos
,
inode_number
)
<
0
)
break
;
filp
->
f_pos
+=
de_len
;
...
...
fs/isofs/inode.c
View file @
c83fb0bd
...
...
@@ -54,9 +54,10 @@ void isofs_put_super(struct super_block *sb)
static
struct
super_operations
isofs_sops
=
{
isofs_read_inode
,
NULL
,
/* notify_change */
NULL
,
/* write_inode */
NULL
,
/* put_inode */
NULL
,
/* delete_inode */
NULL
,
/* notify_change */
isofs_put_super
,
NULL
,
/* write_super */
isofs_statfs
,
...
...
@@ -663,7 +664,6 @@ void isofs_read_inode(struct inode * inode)
isonum_711
(
raw_inode
->
ext_attr_length
))
<<
inode
->
i_sb
->
u
.
isofs_sb
.
s_log_zone_size
;
inode
->
u
.
isofs_i
.
i_backlink
=
0xffffffff
;
/* Will be used for previous directory */
switch
(
inode
->
i_sb
->
u
.
isofs_sb
.
s_conversion
){
case
'a'
:
inode
->
u
.
isofs_i
.
i_file_format
=
ISOFS_FILE_UNKNOWN
;
/* File type */
...
...
@@ -735,7 +735,6 @@ void isofs_read_inode(struct inode * inode)
/* With a data error we return this information */
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
0
;
inode
->
u
.
isofs_i
.
i_first_extent
=
0
;
inode
->
u
.
isofs_i
.
i_backlink
=
0xffffffff
;
inode
->
i_size
=
0
;
inode
->
i_nlink
=
1
;
inode
->
i_uid
=
inode
->
i_gid
=
0
;
...
...
fs/isofs/namei.c
View file @
c83fb0bd
...
...
@@ -59,14 +59,13 @@ static int isofs_match(int len,const char * name, const char * compare, int dlen
* entry - you'll have to do that yourself if you want to.
*/
static
struct
buffer_head
*
isofs_find_entry
(
struct
inode
*
dir
,
const
char
*
name
,
int
namelen
,
unsigned
long
*
ino
,
unsigned
long
*
ino_back
)
const
char
*
name
,
int
namelen
,
unsigned
long
*
ino
)
{
unsigned
long
bufsize
=
ISOFS_BUFFER_SIZE
(
dir
);
unsigned
char
bufbits
=
ISOFS_BUFFER_BITS
(
dir
);
unsigned
int
block
,
i
,
f_pos
,
offset
,
inode_number
;
struct
buffer_head
*
bh
;
unsigned
int
old_offset
;
unsigned
int
backlink
;
int
dlen
,
rrflag
,
match
;
char
*
dpnt
;
struct
iso_directory_record
*
de
;
...
...
@@ -86,7 +85,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
while
(
f_pos
<
dir
->
i_size
)
{
de
=
(
struct
iso_directory_record
*
)
(
bh
->
b_data
+
offset
);
backlink
=
dir
->
i_ino
;
inode_number
=
(
block
<<
bufbits
)
+
(
offset
&
(
bufsize
-
1
));
/* If byte is zero, this is the end of file, or time to move to
...
...
@@ -120,28 +118,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
return
0
;
}
/* Handle the '.' case */
if
(
de
->
name
[
0
]
==
0
&&
de
->
name_len
[
0
]
==
1
)
{
inode_number
=
dir
->
i_ino
;
backlink
=
0
;
}
/* Handle the '..' case */
if
(
de
->
name
[
0
]
==
1
&&
de
->
name_len
[
0
]
==
1
)
{
#if 0
printk("Doing .. (%d %d)",
dir->i_sb->s_firstdatazone,
dir->i_ino);
#endif
if
((
dir
->
i_sb
->
u
.
isofs_sb
.
s_firstdatazone
)
!=
dir
->
i_ino
)
inode_number
=
dir
->
u
.
isofs_i
.
i_backlink
;
else
inode_number
=
dir
->
i_ino
;
backlink
=
0
;
}
dlen
=
de
->
name_len
[
0
];
dpnt
=
de
->
name
;
/* Now convert the filename in the buffer to lower case */
...
...
@@ -183,16 +159,8 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
inode_number
=
isofs_lookup_grandparent
(
dir
,
find_rock_ridge_relocation
(
de
,
dir
));
if
(
inode_number
==
-
1
){
/* Should never happen */
printk
(
"Backlink not properly set %x %lx.
\n
"
,
isonum_733
(
de
->
extent
),
dir
->
i_ino
);
goto
out
;
}
}
*
ino
=
inode_number
;
*
ino_back
=
backlink
;
return
bh
;
}
}
...
...
@@ -201,16 +169,15 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
return
NULL
;
}
int
isofs_lookup
(
struct
inode
*
dir
,
struct
qstr
*
name
,
struct
inode
**
result
)
int
isofs_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
unsigned
long
ino
,
ino_back
;
unsigned
long
ino
;
struct
buffer_head
*
bh
;
char
*
lcname
;
struct
inode
*
inode
;
#ifdef DEBUG
printk
(
"lookup: %x %d
\n
"
,
dir
->
i_ino
,
name
->
len
);
printk
(
"lookup: %x %d
\n
"
,
dir
->
i_ino
,
dentry
->
d_name
.
len
);
#endif
if
(
!
dir
)
return
-
ENOENT
;
...
...
@@ -222,39 +189,28 @@ int isofs_lookup(struct inode * dir, struct qstr *name,
* then first convert this name to lower case.
*/
if
(
dir
->
i_sb
->
u
.
isofs_sb
.
s_name_check
==
'r'
&&
(
lcname
=
kmalloc
(
name
->
len
,
GFP_KERNEL
))
!=
NULL
)
{
(
lcname
=
kmalloc
(
dentry
->
d_name
.
len
,
GFP_KERNEL
))
!=
NULL
)
{
int
i
;
char
c
;
for
(
i
=
0
;
i
<
name
->
len
;
i
++
)
{
c
=
name
->
name
[
i
];
for
(
i
=
0
;
i
<
dentry
->
d_name
.
len
;
i
++
)
{
c
=
dentry
->
d_name
.
name
[
i
];
if
(
c
>=
'A'
&&
c
<=
'Z'
)
c
|=
0x20
;
lcname
[
i
]
=
c
;
}
bh
=
isofs_find_entry
(
dir
,
lcname
,
name
->
len
,
&
ino
,
&
ino_back
);
bh
=
isofs_find_entry
(
dir
,
lcname
,
dentry
->
d_name
.
len
,
&
ino
);
kfree
(
lcname
);
}
else
bh
=
isofs_find_entry
(
dir
,
name
->
name
,
name
->
len
,
&
ino
,
&
ino_back
);
bh
=
isofs_find_entry
(
dir
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
&
ino
);
i
f
(
!
bh
)
return
-
ENOENT
;
brelse
(
bh
);
i
node
=
NULL
;
if
(
bh
)
{
brelse
(
bh
);
inode
=
iget
(
dir
->
i_sb
,
ino
);
if
(
!
inode
)
return
-
EACCES
;
/* We need this backlink for the ".." entry unless the name that we
* are looking up traversed a mount point (in which case the inode
* may not even be on an iso9660 filesystem, and writing to
* u.isofs_i would only cause memory corruption).
*/
if
(
ino_back
&&
!
inode
->
i_pipe
&&
inode
->
i_sb
==
dir
->
i_sb
)
inode
->
u
.
isofs_i
.
i_backlink
=
ino_back
;
*
result
=
inode
;
inode
=
iget
(
dir
->
i_sb
,
ino
);
if
(
!
inode
)
return
-
EACCES
;
}
d_add
(
dentry
,
inode
);
return
0
;
}
fs/minix/bitmap.c
View file @
c83fb0bd
...
...
@@ -256,7 +256,7 @@ struct inode * minix_new_inode(const struct inode * dir)
inode
->
i_dev
=
sb
->
s_dev
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_gid
=
(
dir
->
i_mode
&
S_ISGID
)
?
dir
->
i_gid
:
current
->
fsgid
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
inode
->
i_ino
=
j
;
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_op
=
NULL
;
...
...
fs/minix/file.c
View file @
c83fb0bd
...
...
@@ -121,6 +121,6 @@ static long minix_file_write(struct inode * inode, struct file * filp,
inode
->
i_size
=
pos
;
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
filp
->
f_pos
=
pos
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
return
written
;
}
fs/minix/inode.c
View file @
c83fb0bd
...
...
@@ -307,7 +307,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
return
s
;
}
void
minix_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
bufsiz
)
int
minix_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
bufsiz
)
{
struct
statfs
tmp
;
...
...
@@ -319,7 +319,7 @@ void minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
tmp
.
f_files
=
sb
->
u
.
minix_sb
.
s_ninodes
;
tmp
.
f_ffree
=
minix_count_free_inodes
(
sb
);
tmp
.
f_namelen
=
sb
->
u
.
minix_sb
.
s_namelen
;
copy_to_user
(
buf
,
&
tmp
,
bufsiz
)
;
return
copy_to_user
(
buf
,
&
tmp
,
bufsiz
)
?
-
EFAULT
:
0
;
}
/*
...
...
@@ -472,7 +472,7 @@ static struct buffer_head * V1_inode_getblk(struct inode * inode, int nr,
}
*
p
=
tmp
;
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
return
result
;
}
...
...
@@ -585,7 +585,7 @@ static struct buffer_head * V2_inode_getblk(struct inode * inode, int nr,
}
*
p
=
tmp
;
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
return
result
;
}
...
...
@@ -833,14 +833,12 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
printk
(
"Bad inode number on dev %s"
": %d is out of range
\n
"
,
kdevname
(
inode
->
i_dev
),
ino
);
inode
->
i_dirt
=
0
;
return
0
;
}
block
=
2
+
inode
->
i_sb
->
u
.
minix_sb
.
s_imap_blocks
+
inode
->
i_sb
->
u
.
minix_sb
.
s_zmap_blocks
+
(
ino
-
1
)
/
MINIX_INODES_PER_BLOCK
;
if
(
!
(
bh
=
bread
(
inode
->
i_dev
,
block
,
BLOCK_SIZE
)))
{
printk
(
"unable to read i-node block
\n
"
);
inode
->
i_dirt
=
0
;
return
0
;
}
raw_inode
=
((
struct
minix_inode
*
)
bh
->
b_data
)
+
...
...
@@ -855,7 +853,6 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
raw_inode
->
i_zone
[
0
]
=
kdev_t_to_nr
(
inode
->
i_rdev
);
else
for
(
block
=
0
;
block
<
9
;
block
++
)
raw_inode
->
i_zone
[
block
]
=
inode
->
u
.
minix_i
.
u
.
i1_data
[
block
];
inode
->
i_dirt
=
0
;
mark_buffer_dirty
(
bh
,
1
);
return
bh
;
}
...
...
@@ -874,14 +871,12 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
printk
(
"Bad inode number on dev %s"
": %d is out of range
\n
"
,
kdevname
(
inode
->
i_dev
),
ino
);
inode
->
i_dirt
=
0
;
return
0
;
}
block
=
2
+
inode
->
i_sb
->
u
.
minix_sb
.
s_imap_blocks
+
inode
->
i_sb
->
u
.
minix_sb
.
s_zmap_blocks
+
(
ino
-
1
)
/
MINIX2_INODES_PER_BLOCK
;
if
(
!
(
bh
=
bread
(
inode
->
i_dev
,
block
,
BLOCK_SIZE
)))
{
printk
(
"unable to read i-node block
\n
"
);
inode
->
i_dirt
=
0
;
return
0
;
}
raw_inode
=
((
struct
minix2_inode
*
)
bh
->
b_data
)
+
...
...
@@ -898,7 +893,6 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
raw_inode
->
i_zone
[
0
]
=
kdev_t_to_nr
(
inode
->
i_rdev
);
else
for
(
block
=
0
;
block
<
10
;
block
++
)
raw_inode
->
i_zone
[
block
]
=
inode
->
u
.
minix_i
.
u
.
i2_data
[
block
];
inode
->
i_dirt
=
0
;
mark_buffer_dirty
(
bh
,
1
);
return
bh
;
}
...
...
fs/minix/namei.c
View file @
c83fb0bd
...
...
@@ -173,7 +173,7 @@ static int minix_add_entry(struct inode * dir,
if
(
block
*
bh
->
b_size
+
offset
>
dir
->
i_size
)
{
de
->
inode
=
0
;
dir
->
i_size
=
block
*
bh
->
b_size
+
offset
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
}
if
(
de
->
inode
)
{
if
(
namecompare
(
namelen
,
info
->
s_namelen
,
name
,
de
->
name
))
{
...
...
@@ -182,7 +182,7 @@ static int minix_add_entry(struct inode * dir,
}
}
else
{
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
for
(
i
=
0
;
i
<
info
->
s_namelen
;
i
++
)
de
->
name
[
i
]
=
(
i
<
namelen
)
?
name
[
i
]
:
0
;
dir
->
i_version
=
++
event
;
...
...
@@ -215,12 +215,12 @@ int minix_create(struct inode * dir, struct dentry *dentry, int mode)
return
-
ENOSPC
;
inode
->
i_op
=
&
minix_file_inode_operations
;
inode
->
i_mode
=
mode
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
error
=
minix_add_entry
(
dir
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
&
bh
,
&
de
);
if
(
error
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
return
error
;
}
...
...
@@ -269,11 +269,11 @@ int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
init_fifo
(
inode
);
if
(
S_ISBLK
(
mode
)
||
S_ISCHR
(
mode
))
inode
->
i_rdev
=
to_kdev_t
(
rdev
);
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
error
=
minix_add_entry
(
dir
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
&
bh
,
&
de
);
if
(
error
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
return
error
;
}
...
...
@@ -311,7 +311,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
dir_block
=
minix_bread
(
inode
,
0
,
1
);
if
(
!
dir_block
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
return
-
ENOSPC
;
}
...
...
@@ -327,7 +327,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
inode
->
i_mode
=
S_IFDIR
|
(
mode
&
0777
&
~
current
->
fs
->
umask
);
if
(
dir
->
i_mode
&
S_ISGID
)
inode
->
i_mode
|=
S_ISGID
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
error
=
minix_add_entry
(
dir
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
&
bh
,
&
de
);
if
(
error
)
{
...
...
@@ -338,7 +338,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
de
->
inode
=
inode
->
i_ino
;
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_nlink
++
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
brelse
(
bh
);
d_instantiate
(
dentry
,
inode
);
return
0
;
...
...
@@ -449,10 +449,10 @@ int minix_rmdir(struct inode * dir, struct dentry *dentry)
dir
->
i_version
=
++
event
;
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
inode
->
i_ctime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_nlink
--
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
d_delete
(
dentry
);
retval
=
0
;
end_rmdir:
...
...
@@ -503,10 +503,10 @@ int minix_unlink(struct inode * dir, struct dentry *dentry)
dir
->
i_version
=
++
event
;
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
inode
->
i_nlink
--
;
inode
->
i_ctime
=
dir
->
i_ctime
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
d_delete
(
dentry
);
/* This also frees the inode */
retval
=
0
;
end_unlink:
...
...
@@ -531,7 +531,7 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
name_block
=
minix_bread
(
inode
,
0
,
1
);
if
(
!
name_block
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
return
-
ENOSPC
;
}
...
...
@@ -542,12 +542,12 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
mark_buffer_dirty
(
name_block
,
1
);
brelse
(
name_block
);
inode
->
i_size
=
i
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
bh
=
minix_find_entry
(
dir
,
dentry
->
d_name
.
name
,
dentry
->
d_name
.
len
,
&
de
);
if
(
bh
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
brelse
(
bh
);
return
-
EEXIST
;
...
...
@@ -556,7 +556,7 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
dentry
->
d_name
.
len
,
&
bh
,
&
de
);
if
(
i
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
return
i
;
}
...
...
@@ -597,7 +597,7 @@ int minix_link(struct inode * inode, struct inode * dir,
brelse
(
bh
);
inode
->
i_nlink
++
;
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -740,15 +740,15 @@ static int do_minix_rename(struct inode * old_dir, struct dentry *old_dentry,
old_de
->
inode
=
0
;
new_de
->
inode
=
old_inode
->
i_ino
;
old_dir
->
i_ctime
=
old_dir
->
i_mtime
=
CURRENT_TIME
;
old_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
old_dir
)
;
old_dir
->
i_version
=
++
event
;
new_dir
->
i_ctime
=
new_dir
->
i_mtime
=
CURRENT_TIME
;
new_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
new_dir
)
;
new_dir
->
i_version
=
++
event
;
if
(
new_inode
)
{
new_inode
->
i_nlink
--
;
new_inode
->
i_ctime
=
CURRENT_TIME
;
new_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
new_inode
)
;
}
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
...
...
@@ -756,13 +756,13 @@ static int do_minix_rename(struct inode * old_dir, struct dentry *old_dentry,
PARENT_INO
(
dir_bh
->
b_data
)
=
new_dir
->
i_ino
;
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
old_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
old_dir
)
;
if
(
new_inode
)
{
new_inode
->
i_nlink
--
;
new_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
new_inode
)
;
}
else
{
new_dir
->
i_nlink
++
;
new_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
new_dir
)
;
}
}
/* Update the dcache */
...
...
fs/minix/symlink.c
View file @
c83fb0bd
...
...
@@ -15,6 +15,7 @@
#include <asm/uaccess.h>
static
int
minix_readlink
(
struct
inode
*
,
char
*
,
int
);
static
struct
dentry
*
minix_follow_link
(
struct
inode
*
,
struct
dentry
*
);
/*
* symlinks can't do much...
...
...
@@ -31,6 +32,7 @@ struct inode_operations minix_symlink_inode_operations = {
NULL
,
/* mknod */
NULL
,
/* rename */
minix_readlink
,
/* readlink */
minix_follow_link
,
/* follow_link */
NULL
,
/* readpage */
NULL
,
/* writepage */
NULL
,
/* bmap */
...
...
@@ -38,6 +40,21 @@ struct inode_operations minix_symlink_inode_operations = {
NULL
/* permission */
};
static
struct
dentry
*
minix_follow_link
(
struct
inode
*
inode
,
struct
dentry
*
base
)
{
struct
buffer_head
*
bh
;
bh
=
minix_bread
(
inode
,
0
,
0
);
if
(
!
bh
)
{
dput
(
base
);
return
ERR_PTR
(
-
EIO
);
}
UPDATE_ATIME
(
inode
);
base
=
lookup_dentry
(
bh
->
b_data
,
base
,
1
);
brelse
(
bh
);
return
base
;
}
static
int
minix_readlink
(
struct
inode
*
inode
,
char
*
buffer
,
int
buflen
)
{
struct
buffer_head
*
bh
;
...
...
@@ -47,7 +64,6 @@ static int minix_readlink(struct inode * inode, char * buffer, int buflen)
if
(
buflen
>
1023
)
buflen
=
1023
;
bh
=
minix_bread
(
inode
,
0
,
0
);
iput
(
inode
);
if
(
!
bh
)
return
0
;
i
=
0
;
...
...
fs/minix/truncate.c
View file @
c83fb0bd
...
...
@@ -58,7 +58,7 @@ static int V1_trunc_direct(struct inode * inode)
continue
;
}
*
p
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
if
(
bh
)
{
mark_buffer_clean
(
bh
);
brelse
(
bh
);
...
...
@@ -167,7 +167,7 @@ static int V1_trunc_dindirect(struct inode * inode, int offset, unsigned short *
else
{
tmp
=
*
p
;
*
p
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
minix_free_block
(
inode
->
i_sb
,
tmp
);
}
brelse
(
dind_bh
);
...
...
@@ -191,7 +191,7 @@ void V1_minix_truncate(struct inode * inode)
schedule
();
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
/*
...
...
@@ -220,7 +220,7 @@ static int V2_trunc_direct(struct inode * inode)
continue
;
}
*
p
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
if
(
bh
)
{
mark_buffer_clean
(
bh
);
brelse
(
bh
);
...
...
@@ -329,7 +329,7 @@ static int V2_trunc_dindirect(struct inode * inode, int offset, unsigned long *p
else
{
tmp
=
*
p
;
*
p
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
minix_free_block
(
inode
->
i_sb
,
tmp
);
}
brelse
(
dind_bh
);
...
...
@@ -374,7 +374,7 @@ static int V2_trunc_tindirect(struct inode * inode, int offset, unsigned long *
else
{
tmp
=
*
p
;
*
p
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
minix_free_block
(
inode
->
i_sb
,
tmp
);
}
brelse
(
tind_bh
);
...
...
@@ -402,7 +402,7 @@ static void V2_minix_truncate(struct inode * inode)
schedule
();
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
/*
...
...
fs/msdos/namei.c
View file @
c83fb0bd
...
...
@@ -280,7 +280,7 @@ static int msdos_create_entry(struct inode *dir, const char *name,int len,
* XXX all times should be set by caller upon successful completion.
*/
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
memcpy
(
de
->
name
,
name
,
MSDOS_NAME
);
memset
(
de
->
unused
,
0
,
sizeof
(
de
->
unused
));
de
->
attr
=
is_dir
?
ATTR_DIR
:
ATTR_ARCH
;
...
...
@@ -295,7 +295,7 @@ static int msdos_create_entry(struct inode *dir, const char *name,int len,
if
(
!*
result
)
return
-
EIO
;
(
*
result
)
->
i_mtime
=
(
*
result
)
->
i_atime
=
(
*
result
)
->
i_ctime
=
CURRENT_TIME
;
(
*
result
)
->
i_dirt
=
1
;
mark_inode_dirty
(
*
result
)
;
return
0
;
}
...
...
@@ -415,7 +415,8 @@ int msdos_rmdir(struct inode *dir,const char *name,int len)
inode
->
i_nlink
=
0
;
inode
->
i_ctime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_nlink
--
;
inode
->
i_dirt
=
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
);
mark_inode_dirty
(
dir
);
de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
bh
,
1
);
res
=
0
;
...
...
@@ -465,7 +466,7 @@ int msdos_mkdir(struct inode *dir,const char *name,int len,int mode)
dot
->
i_size
=
inode
->
i_size
;
/* doesn't grow in the 2nd create_entry */
MSDOS_I
(
dot
)
->
i_start
=
MSDOS_I
(
inode
)
->
i_start
;
dot
->
i_nlink
=
inode
->
i_nlink
;
dot
->
i_dirt
=
1
;
mark_inode_dirty
(
dot
)
;
iput
(
dot
);
if
((
res
=
msdos_create_entry
(
inode
,
MSDOS_DOTDOT
,
2
,
1
,
0
,
&
dot
))
<
0
)
goto
mkdir_error
;
...
...
@@ -473,7 +474,7 @@ int msdos_mkdir(struct inode *dir,const char *name,int len,int mode)
dot
->
i_size
=
dir
->
i_size
;
MSDOS_I
(
dot
)
->
i_start
=
MSDOS_I
(
dir
)
->
i_start
;
dot
->
i_nlink
=
dir
->
i_nlink
;
dot
->
i_dirt
=
1
;
mark_inode_dirty
(
dot
)
;
MSDOS_I
(
inode
)
->
i_busy
=
0
;
iput
(
dot
);
iput
(
inode
);
...
...
@@ -519,7 +520,8 @@ static int msdos_unlinkx(
inode
->
i_nlink
=
0
;
inode
->
i_ctime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
MSDOS_I
(
inode
)
->
i_busy
=
1
;
inode
->
i_dirt
=
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
);
mark_inode_dirty
(
dir
);
de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
bh
,
1
);
unlink_done:
...
...
@@ -580,11 +582,11 @@ static int rename_same_dir(struct inode *old_dir,char *old_name,int old_len,
}
if
(
S_ISDIR
(
new_inode
->
i_mode
))
{
new_dir
->
i_nlink
--
;
new_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
new_dir
)
;
}
new_inode
->
i_nlink
=
0
;
MSDOS_I
(
new_inode
)
->
i_busy
=
1
;
new_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
new_inode
)
;
new_de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
new_bh
,
1
);
iput
(
new_inode
);
...
...
@@ -675,7 +677,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,int old_len,
}
new_inode
->
i_nlink
=
0
;
MSDOS_I
(
new_inode
)
->
i_busy
=
1
;
new_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
new_inode
)
;
new_de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
new_bh
,
1
);
}
...
...
@@ -696,14 +698,14 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,int old_len,
}
if
(
exists
&&
S_ISDIR
(
new_inode
->
i_mode
))
{
new_dir
->
i_nlink
--
;
new_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
new_dir
)
;
}
msdos_read_inode
(
free_inode
);
MSDOS_I
(
old_inode
)
->
i_busy
=
1
;
MSDOS_I
(
old_inode
)
->
i_linked
=
free_inode
;
MSDOS_I
(
free_inode
)
->
i_oldlink
=
old_inode
;
fat_cache_inval_inode
(
old_inode
);
old_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
old_inode
)
;
old_de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
old_bh
,
1
);
fat_mark_buffer_dirty
(
sb
,
free_bh
,
1
);
...
...
@@ -726,7 +728,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,int old_len,
}
dotdot_de
->
start
=
MSDOS_I
(
dotdot_inode
)
->
i_start
=
MSDOS_I
(
new_dir
)
->
i_start
;
dotdot_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
dotdot_inode
)
;
fat_mark_buffer_dirty
(
sb
,
dotdot_bh
,
1
);
old_dir
->
i_nlink
--
;
new_dir
->
i_nlink
++
;
...
...
@@ -793,6 +795,7 @@ struct inode_operations msdos_dir_inode_operations = {
NULL
,
/* mknod */
msdos_rename
,
/* rename */
NULL
,
/* readlink */
NULL
,
/* follow_link */
NULL
,
/* readpage */
NULL
,
/* writepage */
fat_bmap
,
/* bmap */
...
...
fs/namei.c
View file @
c83fb0bd
...
...
@@ -237,38 +237,23 @@ void put_write_access(struct inode * inode)
*/
static
struct
dentry
*
real_lookup
(
struct
dentry
*
parent
,
struct
qstr
*
name
)
{
struct
dentry
*
result
;
struct
inode
*
dir
=
parent
->
d_inode
;
struct
dentry
*
result
;
struct
inode
*
inode
;
int
error
=
-
ENOTDIR
;
down
(
&
dir
->
i_sem
);
error
=
-
ENOTDIR
;
if
(
dir
->
i_op
&&
dir
->
i_op
->
lookup
)
error
=
dir
->
i_op
->
lookup
(
dir
,
name
,
&
inode
);
result
=
ERR_PTR
(
error
);
if
(
!
error
||
error
==
-
ENOENT
)
{
struct
dentry
*
new
;
if
(
error
)
inode
=
NULL
;
new
=
d_alloc
(
parent
,
name
);
/*
* Ok, now we can't sleep any more. Double-check that
* nobody else added this in the meantime..
*/
result
=
ERR_PTR
(
-
ENOTDIR
);
if
(
dir
->
i_op
&&
dir
->
i_op
->
lookup
)
{
down
(
&
dir
->
i_sem
);
result
=
d_lookup
(
parent
,
name
);
if
(
result
)
{
d_free
(
new
);
iput
(
inode
);
}
else
{
d_add
(
new
,
inode
);
result
=
new
;
if
(
!
result
)
{
int
error
;
result
=
d_alloc
(
parent
,
name
);
error
=
dir
->
i_op
->
lookup
(
dir
,
result
);
if
(
error
)
{
d_free
(
result
);
result
=
ERR_PTR
(
error
);
}
}
up
(
&
dir
->
i_sem
);
}
up
(
&
dir
->
i_sem
);
return
result
;
...
...
@@ -280,8 +265,11 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
struct
dentry
*
dentry
=
d_lookup
(
parent
,
name
);
if
(
dentry
)
{
if
(
dentry
->
d_revalidate
)
if
(
dentry
->
d_revalidate
)
{
/* spin_unlock(&dentry_lock); */
dentry
=
dentry
->
d_revalidate
(
dentry
);
/* spin_lock(&dentry_lock); */
}
/*
* The parent d_count _should_ be at least 2: one for the
...
...
fs/nfs/dir.c
View file @
c83fb0bd
...
...
@@ -42,7 +42,7 @@ struct nfs_dirent {
static
int
nfs_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
);
static
long
nfs_dir_read
(
struct
inode
*
,
struct
file
*
,
char
*
,
unsigned
long
);
static
int
nfs_readdir
(
struct
inode
*
,
struct
file
*
,
void
*
,
filldir_t
);
static
int
nfs_lookup
(
struct
inode
*
,
struct
qstr
*
,
struct
inode
*
*
);
static
int
nfs_lookup
(
struct
inode
*
,
struct
dentry
*
);
static
int
nfs_create
(
struct
inode
*
,
struct
dentry
*
,
int
);
static
int
nfs_mkdir
(
struct
inode
*
,
struct
dentry
*
,
int
);
static
int
nfs_rmdir
(
struct
inode
*
,
struct
dentry
*
);
...
...
@@ -328,19 +328,17 @@ nfs_free_dircache(void)
}
static
int
nfs_lookup
(
struct
inode
*
dir
,
struct
qstr
*
__name
,
struct
inode
**
result
)
static
int
nfs_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
struct
inode
*
inode
;
struct
nfs_fh
fhandle
;
struct
nfs_fattr
fattr
;
int
len
=
__name
->
len
;
char
name
[
len
>
NFS_MAXNAMLEN
?
1
:
len
+
1
];
int
len
=
dentry
->
d_name
.
len
;
int
error
;
dfprintk
(
VFS
,
"NFS: lookup(%x/%ld, %.*s)
\n
"
,
dir
->
i_dev
,
dir
->
i_ino
,
len
,
__name
->
name
);
dir
->
i_dev
,
dir
->
i_ino
,
len
,
dentry
->
d_name
.
name
);
*
result
=
NULL
;
if
(
!
dir
||
!
S_ISDIR
(
dir
->
i_mode
))
{
printk
(
"nfs_lookup: inode is NULL or not a directory
\n
"
);
return
-
ENOENT
;
...
...
@@ -349,17 +347,18 @@ static int nfs_lookup(struct inode *dir, struct qstr * __name,
if
(
len
>
NFS_MAXNAMLEN
)
return
-
ENAMETOOLONG
;
memcpy
(
name
,
__name
->
name
,
len
);
name
[
len
]
=
'\0'
;
error
=
nfs_proc_lookup
(
NFS_SERVER
(
dir
),
NFS_FH
(
dir
),
dentry
->
d_name
.
name
,
&
fhandle
,
&
fattr
);
error
=
nfs_proc_lookup
(
NFS_SERVER
(
dir
),
NFS_FH
(
dir
),
name
,
&
fhandle
,
&
fattr
);
if
(
error
)
inode
=
NULL
;
if
(
!
error
)
{
error
=
-
ENOENT
;
inode
=
nfs_fhget
(
dir
->
i_sb
,
&
fhandle
,
&
fattr
);
if
(
!
inode
)
return
-
EACCES
;
}
else
if
(
error
!=
-
ENOENT
)
return
error
;
if
(
!
(
*
result
=
nfs_fhget
(
dir
->
i_sb
,
&
fhandle
,
&
fattr
)))
return
-
EACCES
;
d_add
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -587,7 +586,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr
if
(
error
)
return
error
;
atomic_inc
(
&
inode
->
i_count
)
;
inode
->
i_count
++
;
d_instantiate
(
dentry
,
inode
);
return
0
;
}
...
...
@@ -647,8 +646,7 @@ void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
int
was_empty
;
dfprintk
(
VFS
,
"NFS: refresh_inode(%x/%ld ct=%d)
\n
"
,
inode
->
i_dev
,
inode
->
i_ino
,
atomic_read
(
&
inode
->
i_count
));
inode
->
i_dev
,
inode
->
i_ino
,
inode
->
i_count
);
if
(
!
inode
||
!
fattr
)
{
printk
(
"nfs_refresh_inode: inode or fattr is NULL
\n
"
);
...
...
fs/nfs/file.c
View file @
c83fb0bd
...
...
@@ -143,7 +143,7 @@ nfs_file_write(struct inode *inode, struct file *file,
int
result
;
dfprintk
(
VFS
,
"nfs: write(%x/%ld (%d), %lu@%lu)
\n
"
,
inode
->
i_dev
,
inode
->
i_ino
,
atomic_read
(
&
inode
->
i_count
)
,
inode
->
i_dev
,
inode
->
i_ino
,
inode
->
i_count
,
count
,
(
unsigned
long
)
file
->
f_pos
);
if
(
!
inode
)
{
...
...
fs/nfs/inode.c
View file @
c83fb0bd
...
...
@@ -36,15 +36,17 @@
static
int
nfs_notify_change
(
struct
inode
*
,
struct
iattr
*
);
static
void
nfs_put_inode
(
struct
inode
*
);
static
void
nfs_delete_inode
(
struct
inode
*
);
static
void
nfs_put_super
(
struct
super_block
*
);
static
void
nfs_read_inode
(
struct
inode
*
);
static
int
nfs_statfs
(
struct
super_block
*
,
struct
statfs
*
,
int
bufsiz
);
static
struct
super_operations
nfs_sops
=
{
nfs_read_inode
,
/* read inode */
nfs_notify_change
,
/* notify change */
NULL
,
/* write inode */
nfs_put_inode
,
/* put inode */
nfs_delete_inode
,
/* delete inode */
nfs_notify_change
,
/* notify change */
nfs_put_super
,
/* put superblock */
NULL
,
/* write superblock */
nfs_statfs
,
/* stat filesystem */
...
...
@@ -73,9 +75,16 @@ static void
nfs_put_inode
(
struct
inode
*
inode
)
{
dprintk
(
"NFS: put_inode(%x/%ld)
\n
"
,
inode
->
i_dev
,
inode
->
i_ino
);
}
if
(
inode
->
i_pipe
)
clear_inode
(
inode
);
/*
* This should do any silly-rename cleanups once we
* get silly-renaming working again..
*/
static
void
nfs_delete_inode
(
struct
inode
*
inode
)
{
dprintk
(
"NFS: delete_inode(%x/%ld)
\n
"
,
inode
->
i_dev
,
inode
->
i_ino
);
}
void
...
...
@@ -316,7 +325,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
}
dprintk
(
"NFS: fhget(%x/%ld ct=%d)
\n
"
,
inode
->
i_dev
,
inode
->
i_ino
,
atomic_read
(
&
inode
->
i_count
)
);
inode
->
i_count
);
return
inode
;
}
...
...
fs/nfs/read.c
View file @
c83fb0bd
...
...
@@ -150,7 +150,6 @@ nfs_readpage_result(struct rpc_task *task)
fail
++
;
dprintk
(
"NFS: %d successful reads, %d failures
\n
"
,
succ
,
fail
);
}
iput
(
req
->
ra_inode
);
clear_bit
(
PG_locked
,
&
page
->
flags
);
wake_up
(
&
page
->
wait
);
...
...
@@ -188,7 +187,6 @@ nfs_readpage_async(struct inode *inode, struct page *page)
nfs_readpage_result
,
req
);
if
(
result
>=
0
)
{
atomic_inc
(
&
inode
->
i_count
);
atomic_inc
(
&
page
->
count
);
return
0
;
}
...
...
fs/nfs/write.c
View file @
c83fb0bd
...
...
@@ -338,7 +338,7 @@ create_write_request(struct inode *inode, struct page *page,
wreq
->
wb_page
=
page
;
wreq
->
wb_offset
=
offset
;
wreq
->
wb_bytes
=
bytes
;
atomic_inc
(
&
inode
->
i_count
);
atomic_inc
(
&
page
->
count
);
append_write_request
(
&
NFS_WRITEBACK
(
inode
),
wreq
);
...
...
@@ -695,7 +695,6 @@ nfs_check_error(struct inode *inode)
status
=
req
->
wb_task
.
tk_status
;
remove_write_request
(
&
nfs_failed_requests
,
req
);
iput
(
req
->
wb_inode
);
kfree
(
req
);
return
status
;
}
...
...
@@ -788,7 +787,6 @@ nfs_wback_result(struct rpc_task *task)
dprintk
(
"NFS: %4d saving write failure code
\n
"
,
task
->
tk_pid
);
append_write_request
(
&
nfs_failed_requests
,
req
);
atomic_inc
(
&
inode
->
i_count
);
}
clear_bit
(
PG_uptodate
,
&
page
->
flags
);
}
else
if
(
!
WB_CANCELLED
(
req
))
{
...
...
@@ -818,6 +816,5 @@ nfs_wback_result(struct rpc_task *task)
kfree
(
req
);
free_page
(
page_address
(
page
));
iput
(
inode
);
nr_write_requests
--
;
}
fs/open.c
View file @
c83fb0bd
...
...
@@ -416,6 +416,7 @@ asmlinkage int sys_chroot(const char * filename)
tmp
=
current
->
fs
->
root
;
current
->
fs
->
root
=
dentry
;
dentry
=
tmp
;
error
=
0
;
dput_and_out:
dput
(
dentry
);
...
...
fs/pipe.c
View file @
c83fb0bd
...
...
@@ -230,18 +230,26 @@ static unsigned int connect_poll(struct file * filp, poll_table * wait)
return
POLLOUT
|
POLLWRNORM
;
}
static
int
pipe_re
ad_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
static
int
pipe_re
lease
(
struct
inode
*
inode
)
{
PIPE_READERS
(
*
inode
)
--
;
if
(
!
PIPE_READERS
(
*
inode
)
&&
!
PIPE_READERS
(
*
inode
))
{
free_page
((
unsigned
long
)
PIPE_BASE
(
*
inode
));
PIPE_BASE
(
*
inode
)
=
NULL
;
}
wake_up_interruptible
(
&
PIPE_WAIT
(
*
inode
));
return
0
;
}
static
int
pipe_read_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
PIPE_READERS
(
*
inode
)
--
;
return
pipe_release
(
inode
);
}
static
int
pipe_write_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
PIPE_WRITERS
(
*
inode
)
--
;
wake_up_interruptible
(
&
PIPE_WAIT
(
*
inode
));
return
0
;
return
pipe_release
(
inode
);
}
static
int
pipe_rdwr_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
...
...
@@ -250,8 +258,7 @@ static int pipe_rdwr_release(struct inode * inode, struct file * filp)
PIPE_READERS
(
*
inode
)
--
;
if
(
filp
->
f_mode
&
FMODE_WRITE
)
PIPE_WRITERS
(
*
inode
)
--
;
wake_up_interruptible
(
&
PIPE_WAIT
(
*
inode
));
return
0
;
return
pipe_release
(
inode
);
}
static
int
pipe_read_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
...
...
@@ -370,6 +377,43 @@ struct file_operations rdwr_pipe_fops = {
NULL
};
static
struct
inode
*
get_pipe_inode
(
void
)
{
extern
struct
inode_operations
pipe_inode_operations
;
struct
inode
*
inode
=
get_empty_inode
();
if
(
inode
)
{
unsigned
long
page
=
__get_free_page
(
GFP_USER
);
if
(
!
page
)
{
iput
(
inode
);
inode
=
NULL
;
}
else
{
PIPE_BASE
(
*
inode
)
=
(
char
*
)
page
;
inode
->
i_op
=
&
pipe_inode_operations
;
inode
->
i_count
=
1
;
PIPE_WAIT
(
*
inode
)
=
NULL
;
PIPE_START
(
*
inode
)
=
PIPE_LEN
(
*
inode
)
=
0
;
PIPE_RD_OPENERS
(
*
inode
)
=
PIPE_WR_OPENERS
(
*
inode
)
=
0
;
PIPE_READERS
(
*
inode
)
=
PIPE_WRITERS
(
*
inode
)
=
1
;
PIPE_LOCK
(
*
inode
)
=
0
;
/*
* Mark the inode dirty from the very beginning,
* that way it will never be moved to the dirty
* list because "make_inode_dirty()" will think
* that it already _is_ on the dirty list.
*/
inode
->
i_state
=
1
<<
I_DIRTY
;
inode
->
i_mode
|=
S_IFIFO
|
S_IRUSR
|
S_IWUSR
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_gid
=
current
->
fsgid
;
inode
->
i_atime
=
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_blksize
=
PAGE_SIZE
;
}
}
return
inode
;
}
struct
inode_operations
pipe_inode_operations
=
{
&
rdwr_pipe_fops
,
NULL
,
/* create */
...
...
fs/proc/Makefile
View file @
c83fb0bd
...
...
@@ -8,7 +8,7 @@
# Note 2! The CFLAGS definitions are now in the main makefile...
O_TARGET
:=
proc.o
O_OBJS
:=
inode.o root.o base.o generic.o mem.o link.o
arbitrary.o
fd.o array.o
\
O_OBJS
:=
inode.o root.o base.o generic.o mem.o link.o fd.o array.o
\
kmsg.o scsi.o proc_tty.o
ifdef
CONFIG_OMIRR
O_OBJS
:=
$(O_OBJS)
omirr.o
...
...
fs/proc/arbitrary.c
deleted
100644 → 0
View file @
1b081ced
/*
* $Id: arbitrary.c,v 1.2 1997/06/05 01:27:47 davem Exp $
*
* linux/fs/proc/arbitrary.c - lookup() for arbitrary inodes.
* Copyright (C) 1997, Thomas Schoebel-Theuer,
* <schoebel@informatik.uni-stuttgart.de>.
*/
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
/* Format of dev/inode pairs that can be used as file names:
* [<dev_number_in_hex]:<inode_number_in_decimal>
* (the same format that is already in use in /proc/<pid>/exe,
* /proc/<pid>/cwd and /proc/<pid>/root).
*/
/* Note that readdir does not supply such names, so they must be used
* either "blind" or must be queried another way, for example
* as result of a virtual symlink (see linux/proc/link.c).
*/
int
proc_arbitrary_lookup
(
struct
inode
*
dir
,
const
char
*
name
,
int
len
,
struct
inode
**
result
)
{
int
dev
,
ino
;
char
*
ptr
=
(
char
*
)
name
;
kdev_t
kdev
;
int
i
;
int
error
=
-
EINVAL
;
if
(
*
ptr
++
!=
'['
)
goto
done
;
dev
=
simple_strtoul
(
ptr
,
&
ptr
,
16
);
if
(
*
ptr
++
!=
']'
)
goto
done
;
if
(
*
ptr
++
!=
':'
)
goto
done
;
ino
=
simple_strtoul
(
ptr
,
&
ptr
,
0
);
if
((
long
)
ptr
-
(
long
)
name
!=
len
)
goto
done
;
error
=
-
ENOENT
;
kdev
=
to_kdev_t
(
dev
);
if
(
!
kdev
)
goto
done
;
for
(
i
=
0
;
i
<
NR_SUPER
;
i
++
)
if
(
super_blocks
[
i
].
s_dev
==
kdev
)
break
;
if
(
i
<
NR_SUPER
)
{
*
result
=
iget
(
&
super_blocks
[
i
],
ino
);
if
(
*
result
)
error
=
0
;
}
done:
return
error
;
}
fs/proc/fd.c
View file @
c83fb0bd
...
...
@@ -14,7 +14,7 @@
#include <linux/stat.h>
static
int
proc_readfd
(
struct
inode
*
,
struct
file
*
,
void
*
,
filldir_t
);
static
int
proc_lookupfd
(
struct
inode
*
,
struct
qstr
*
,
struct
inode
*
*
);
static
int
proc_lookupfd
(
struct
inode
*
,
struct
dentry
*
);
static
struct
file_operations
proc_fd_operations
=
{
NULL
,
/* lseek - default */
...
...
@@ -52,15 +52,24 @@ struct inode_operations proc_fd_inode_operations = {
NULL
/* permission */
};
static
int
proc_lookupfd
(
struct
inode
*
dir
,
struct
qstr
*
str
,
struct
inode
**
result
)
/*
* NOTE! Normally we'd indicate that a file does not
* exist by creating a negative dentry and returning
* a successful return code. However, for this case
* we do not want to create negative dentries, because
* the state of the world can change behind our backs.
*
* Thus just return -ENOENT instead.
*/
static
int
proc_lookupfd
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
unsigned
int
ino
,
pid
,
fd
,
c
;
struct
task_struct
*
p
;
struct
super_block
*
sb
;
struct
inode
*
inode
;
const
char
*
name
;
int
len
;
*
result
=
NULL
;
ino
=
dir
->
i_ino
;
pid
=
ino
>>
16
;
ino
&=
0x0000ffff
;
...
...
@@ -71,8 +80,8 @@ static int proc_lookupfd(struct inode * dir, struct qstr *str, struct inode ** r
return
-
ENOENT
;
fd
=
0
;
len
=
str
->
len
;
name
=
str
->
name
;
len
=
dentry
->
d_name
.
len
;
name
=
dentry
->
d_name
.
name
;
while
(
len
--
>
0
)
{
c
=
*
name
-
'0'
;
name
++
;
...
...
@@ -105,8 +114,11 @@ static int proc_lookupfd(struct inode * dir, struct qstr *str, struct inode ** r
ino
=
(
pid
<<
16
)
+
(
PROC_PID_FD_DIR
<<
8
)
+
fd
;
if
(
!
(
*
result
=
proc_get_inode
(
sb
,
ino
,
NULL
)))
inode
=
proc_get_inode
(
sb
,
ino
,
NULL
);
if
(
!
inode
)
return
-
ENOENT
;
d_add
(
dentry
,
inode
);
return
0
;
}
...
...
fs/proc/inode.c
View file @
c83fb0bd
...
...
@@ -25,8 +25,14 @@ static void proc_put_inode(struct inode *inode)
&&
proc_openprom_use
)
(
*
proc_openprom_use
)(
inode
,
0
);
#endif
if
(
inode
->
i_nlink
)
return
;
}
/*
* Does this ever happen?
*/
static
void
proc_delete_inode
(
struct
inode
*
inode
)
{
printk
(
"proc_delete_inode()?
\n
"
);
inode
->
i_size
=
0
;
}
...
...
@@ -39,9 +45,10 @@ static void proc_put_super(struct super_block *sb)
static
struct
super_operations
proc_sops
=
{
proc_read_inode
,
NULL
,
proc_write_inode
,
proc_put_inode
,
proc_delete_inode
,
NULL
,
proc_put_super
,
NULL
,
proc_statfs
,
...
...
fs/proc/root.c
View file @
c83fb0bd
...
...
@@ -24,7 +24,7 @@
#define FIRST_PROCESS_ENTRY 256
static
int
proc_root_readdir
(
struct
inode
*
,
struct
file
*
,
void
*
,
filldir_t
);
static
int
proc_root_lookup
(
struct
inode
*
,
struct
qstr
*
,
struct
inode
*
*
);
static
int
proc_root_lookup
(
struct
inode
*
,
struct
dentry
*
);
static
unsigned
char
proc_alloc_map
[
PROC_NDYNAMIC
/
8
]
=
{
0
};
...
...
@@ -227,7 +227,6 @@ proc_openprom_deflookup(struct inode * dir, struct qstr *str, struct inode ** re
proc_openprom_deflookup
)
return
proc_openprom_inode_operations
.
lookup
(
dir
,
str
,
result
);
iput
(
dir
);
return
-
ENOENT
;
}
#endif
...
...
@@ -622,45 +621,50 @@ void proc_root_init(void)
proc_tty_init
();
}
int
proc_lookup
(
struct
inode
*
dir
,
struct
qstr
*
str
,
struct
inode
**
result
)
/*
* Don't create negative dentries here, return -ENOENT by hand
* instead.
*/
int
proc_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
struct
inode
*
inode
;
struct
proc_dir_entry
*
de
;
*
result
=
NULL
;
if
(
!
dir
||
!
S_ISDIR
(
dir
->
i_mode
))
return
-
ENOTDIR
;
de
=
(
struct
proc_dir_entry
*
)
dir
->
u
.
generic_ip
;
i
f
(
!
de
)
return
-
EINVAL
;
*
result
=
NULL
;
for
(
de
=
de
->
subdir
;
de
;
de
=
de
->
next
)
{
if
(
!
de
||
!
de
->
low_ino
)
continue
;
if
(
de
->
namelen
!=
str
->
len
)
continue
;
if
(
!
memcmp
(
str
->
name
,
de
->
name
,
str
->
len
))
{
int
ino
=
de
->
low_ino
|
(
dir
->
i_ino
&
~
(
0xffff
));
if
(
!
(
*
result
=
proc_get_inode
(
dir
->
i_sb
,
ino
,
de
)))
return
-
EINVAL
;
return
0
;
i
node
=
NULL
;
if
(
de
)
{
for
(
de
=
de
->
subdir
;
de
;
de
=
de
->
next
)
{
if
(
!
de
||
!
de
->
low_ino
)
continue
;
if
(
de
->
namelen
!=
dentry
->
d_name
.
len
)
continue
;
if
(
!
memcmp
(
dentry
->
d_name
.
name
,
de
->
name
,
de
->
namelen
))
{
int
ino
=
de
->
low_ino
|
(
dir
->
i_ino
&
~
(
0xffff
))
;
inode
=
proc_get_inode
(
dir
->
i_sb
,
ino
,
de
);
if
(
!
inode
)
return
-
EINVAL
;
break
;
}
}
}
return
-
ENOENT
;
if
(
!
inode
)
return
-
ENOENT
;
d_add
(
dentry
,
inode
);
return
0
;
}
static
int
proc_root_lookup
(
struct
inode
*
dir
,
struct
qstr
*
str
,
struct
inode
**
result
)
static
int
proc_root_lookup
(
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
unsigned
int
pid
,
c
;
int
ino
,
retval
;
struct
task_struct
*
p
;
const
char
*
name
;
struct
inode
*
inode
;
int
len
;
atomic_inc
(
&
dir
->
i_count
);
if
(
dir
->
i_ino
==
PROC_ROOT_INO
)
{
/* check for safety... */
dir
->
i_nlink
=
proc_root
.
nlink
;
...
...
@@ -672,13 +676,12 @@ static int proc_root_lookup(struct inode * dir,struct qstr *str, struct inode **
read_unlock
(
&
tasklist_lock
);
}
retval
=
proc_lookup
(
dir
,
str
,
result
);
if
(
retval
!=
-
ENOENT
)
return
retval
;
if
(
!
proc_lookup
(
dir
,
dentry
))
return
0
;
pid
=
0
;
name
=
str
->
name
;
len
=
str
->
len
;
name
=
dentry
->
d_name
.
name
;
len
=
dentry
->
d_name
.
len
;
while
(
len
--
>
0
)
{
c
=
*
name
-
'0'
;
name
++
;
...
...
@@ -694,12 +697,14 @@ static int proc_root_lookup(struct inode * dir,struct qstr *str, struct inode **
}
}
p
=
find_task_by_pid
(
pid
);
if
(
!
pid
||
!
p
)
return
-
ENOENT
;
ino
=
(
pid
<<
16
)
+
PROC_PID_INO
;
if
(
!
(
*
result
=
proc_get_inode
(
dir
->
i_sb
,
ino
,
&
proc_pid
)))
return
-
EINVAL
;
inode
=
NULL
;
if
(
pid
&&
p
)
{
unsigned
long
ino
=
(
pid
<<
16
)
+
PROC_PID_INO
;
inode
=
proc_get_inode
(
dir
->
i_sb
,
ino
,
&
proc_pid
);
if
(
!
inode
)
return
-
EINVAL
;
}
d_add
(
dentry
,
inode
);
return
0
;
}
...
...
fs/stat.c
View file @
c83fb0bd
...
...
@@ -48,8 +48,6 @@ static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
tmp
.
st_gid
=
inode
->
i_gid
;
tmp
.
st_rdev
=
kdev_t_to_nr
(
inode
->
i_rdev
);
tmp
.
st_size
=
inode
->
i_size
;
if
(
inode
->
i_pipe
)
tmp
.
st_size
=
PIPE_SIZE
(
*
inode
);
tmp
.
st_atime
=
inode
->
i_atime
;
tmp
.
st_mtime
=
inode
->
i_mtime
;
tmp
.
st_ctime
=
inode
->
i_ctime
;
...
...
@@ -72,8 +70,6 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf)
tmp
.
st_gid
=
inode
->
i_gid
;
tmp
.
st_rdev
=
kdev_t_to_nr
(
inode
->
i_rdev
);
tmp
.
st_size
=
inode
->
i_size
;
if
(
inode
->
i_pipe
)
tmp
.
st_size
=
PIPE_SIZE
(
*
inode
);
tmp
.
st_atime
=
inode
->
i_atime
;
tmp
.
st_mtime
=
inode
->
i_mtime
;
tmp
.
st_ctime
=
inode
->
i_ctime
;
...
...
fs/sysv/dir.c
View file @
c83fb0bd
...
...
@@ -57,6 +57,7 @@ struct inode_operations sysv_dir_inode_operations = {
sysv_mknod
,
/* mknod */
sysv_rename
,
/* rename */
NULL
,
/* readlink */
NULL
,
/* follow_link */
NULL
,
/* readpage */
NULL
,
/* writepage */
NULL
,
/* bmap */
...
...
fs/sysv/file.c
View file @
c83fb0bd
...
...
@@ -64,6 +64,7 @@ struct inode_operations sysv_file_inode_operations = {
NULL
,
/* mknod */
NULL
,
/* rename */
NULL
,
/* readlink */
NULL
,
/* follow_link */
generic_readpage
,
/* readpage */
NULL
,
/* writepage */
sysv_bmap
,
/* bmap */
...
...
@@ -194,7 +195,7 @@ long sysv_file_read(struct inode * inode, struct file * filp,
filp
->
f_reada
=
1
;
if
(
!
IS_RDONLY
(
inode
))
{
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
return
read
;
}
...
...
@@ -255,7 +256,7 @@ static long sysv_file_write(struct inode * inode, struct file * filp,
pos
+=
c
;
if
(
pos
>
inode
->
i_size
)
{
inode
->
i_size
=
pos
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
written
+=
c
;
buf
+=
c
;
...
...
@@ -265,6 +266,6 @@ static long sysv_file_write(struct inode * inode, struct file * filp,
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
filp
->
f_pos
=
pos
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
return
written
;
}
fs/sysv/ialloc.c
View file @
c83fb0bd
...
...
@@ -155,7 +155,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
inode
->
i_dev
=
sb
->
s_dev
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_gid
=
(
dir
->
i_mode
&
S_ISGID
)
?
dir
->
i_gid
:
current
->
fsgid
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
inode
->
i_ino
=
ino
;
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_op
=
NULL
;
...
...
@@ -166,7 +166,7 @@ struct inode * sysv_new_inode(const struct inode * dir)
inode
->
i_size
=
0
;
/* ditto */
sysv_write_inode
(
inode
);
/* ensure inode not allocated again */
/* FIXME: caller may call this too. */
inode
->
i_dirt
=
1
;
/* cleared by sysv_write_inode() */
mark_inode_dirty
(
inode
);
/* cleared by sysv_write_inode() */
/* That's it. */
(
*
sb
->
sv_sb_total_free_inodes
)
--
;
mark_buffer_dirty
(
sb
->
sv_bh2
,
1
);
/* super-block has been modified again */
...
...
fs/sysv/inode.c
View file @
c83fb0bd
...
...
@@ -344,6 +344,7 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
struct
buffer_head
*
bh
;
const
char
*
found
;
kdev_t
dev
=
sb
->
s_dev
;
struct
inode
*
root_inode
;
if
(
1024
!=
sizeof
(
struct
xenix_super_block
))
panic
(
"Xenix FS: bad super-block size"
);
...
...
@@ -483,9 +484,10 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
/* set up enough so that it can read an inode */
sb
->
s_dev
=
dev
;
sb
->
s_op
=
&
sysv_sops
;
sb
->
s_mounted
=
iget
(
sb
,
SYSV_ROOT_INO
);
root_inode
=
iget
(
sb
,
SYSV_ROOT_INO
);
sb
->
s_root
=
d_alloc_root
(
root_inode
,
NULL
);
unlock_super
(
sb
);
if
(
!
sb
->
s_
mounted
)
{
if
(
!
sb
->
s_
root
)
{
printk
(
"SysV FS: get root inode failed
\n
"
);
sysv_put_super
(
sb
);
return
NULL
;
...
...
@@ -534,7 +536,7 @@ void sysv_put_super(struct super_block *sb)
MOD_DEC_USE_COUNT
;
}
void
sysv_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
bufsiz
)
int
sysv_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
bufsiz
)
{
struct
statfs
tmp
;
...
...
@@ -547,7 +549,7 @@ void sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
tmp
.
f_ffree
=
sysv_count_free_inodes
(
sb
);
/* free file nodes in fs */
tmp
.
f_namelen
=
SYSV_NAMELEN
;
/* Don't know what value to put in tmp.f_fsid */
/* file system id */
copy_to_user
(
buf
,
&
tmp
,
bufsiz
)
;
return
copy_to_user
(
buf
,
&
tmp
,
bufsiz
)
?
-
EFAULT
:
0
;
}
...
...
@@ -667,7 +669,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, int nr, int creat
}
*
p
=
tmp
;
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
return
result
;
}
...
...
@@ -900,13 +902,11 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
printk
(
"Bad inode number on dev %s"
": %d is out of range
\n
"
,
kdevname
(
inode
->
i_dev
),
ino
);
inode
->
i_dirt
=
0
;
return
0
;
}
block
=
sb
->
sv_firstinodezone
+
((
ino
-
1
)
>>
sb
->
sv_inodes_per_block_bits
);
if
(
!
(
bh
=
sv_bread
(
sb
,
inode
->
i_dev
,
block
)))
{
printk
(
"unable to read i-node block
\n
"
);
inode
->
i_dirt
=
0
;
return
0
;
}
raw_inode
=
(
struct
sysv_inode
*
)
bh
->
b_data
+
((
ino
-
1
)
&
sb
->
sv_inodes_per_block_1
);
...
...
@@ -937,7 +937,6 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
else
for
(
block
=
0
;
block
<
10
+
1
+
1
+
1
;
block
++
)
write3byte
(
&
raw_inode
->
i_a
.
i_addb
[
3
*
block
],
inode
->
u
.
sysv_i
.
i_data
[
block
]);
inode
->
i_dirt
=
0
;
mark_buffer_dirty
(
bh
,
1
);
return
bh
;
}
...
...
fs/sysv/namei.c
View file @
c83fb0bd
...
...
@@ -175,7 +175,7 @@ static int sysv_add_entry(struct inode * dir,
if
(
pos
>
dir
->
i_size
)
{
de
->
inode
=
0
;
dir
->
i_size
=
pos
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
}
if
(
de
->
inode
)
{
if
(
namecompare
(
namelen
,
SYSV_NAMELEN
,
name
,
de
->
name
))
{
...
...
@@ -184,7 +184,7 @@ static int sysv_add_entry(struct inode * dir,
}
}
else
{
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
for
(
i
=
0
;
i
<
SYSV_NAMELEN
;
i
++
)
de
->
name
[
i
]
=
(
i
<
namelen
)
?
name
[
i
]
:
0
;
mark_buffer_dirty
(
bh
,
1
);
...
...
@@ -219,11 +219,11 @@ int sysv_create(struct inode * dir,const char * name, int len, int mode,
}
inode
->
i_op
=
&
sysv_file_inode_operations
;
inode
->
i_mode
=
mode
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
error
=
sysv_add_entry
(
dir
,
name
,
len
,
&
bh
,
&
de
);
if
(
error
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
iput
(
dir
);
return
error
;
...
...
@@ -276,11 +276,11 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde
init_fifo
(
inode
);
if
(
S_ISBLK
(
mode
)
||
S_ISCHR
(
mode
))
inode
->
i_rdev
=
to_kdev_t
(
rdev
);
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
error
=
sysv_add_entry
(
dir
,
name
,
len
,
&
bh
,
&
de
);
if
(
error
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
iput
(
dir
);
return
error
;
...
...
@@ -325,7 +325,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
if
(
!
dir_block
)
{
iput
(
dir
);
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
return
-
ENOSPC
;
}
...
...
@@ -341,7 +341,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
inode
->
i_mode
=
S_IFDIR
|
(
mode
&
0777
&
~
current
->
fs
->
umask
);
if
(
dir
->
i_mode
&
S_ISGID
)
inode
->
i_mode
|=
S_ISGID
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
error
=
sysv_add_entry
(
dir
,
name
,
len
,
&
bh
,
&
de
);
if
(
error
)
{
iput
(
dir
);
...
...
@@ -352,7 +352,7 @@ int sysv_mkdir(struct inode * dir, const char * name, int len, int mode)
de
->
inode
=
inode
->
i_ino
;
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_nlink
++
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
iput
(
dir
);
iput
(
inode
);
brelse
(
bh
);
...
...
@@ -463,10 +463,10 @@ int sysv_rmdir(struct inode * dir, const char * name, int len)
de
->
inode
=
0
;
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
dir
->
i_nlink
--
;
inode
->
i_ctime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
retval
=
0
;
end_rmdir:
iput
(
dir
);
...
...
@@ -517,10 +517,10 @@ int sysv_unlink(struct inode * dir, const char * name, int len)
de
->
inode
=
0
;
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
inode
->
i_nlink
--
;
inode
->
i_ctime
=
dir
->
i_ctime
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
retval
=
0
;
end_unlink:
brelse
(
bh
);
...
...
@@ -550,7 +550,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
if
(
!
name_block
)
{
iput
(
dir
);
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
return
-
ENOSPC
;
}
...
...
@@ -563,11 +563,11 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
mark_buffer_dirty
(
name_block
,
1
);
brelse
(
name_block
);
inode
->
i_size
=
i
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
bh
=
sysv_find_entry
(
dir
,
name
,
len
,
&
de
);
if
(
bh
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
brelse
(
bh
);
iput
(
dir
);
...
...
@@ -576,7 +576,7 @@ int sysv_symlink(struct inode * dir, const char * name, int len, const char * sy
i
=
sysv_add_entry
(
dir
,
name
,
len
,
&
bh
,
&
de
);
if
(
i
)
{
inode
->
i_nlink
--
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
iput
(
inode
);
iput
(
dir
);
return
i
;
...
...
@@ -624,7 +624,7 @@ int sysv_link(struct inode * oldinode, struct inode * dir, const char * name, in
iput
(
dir
);
oldinode
->
i_nlink
++
;
oldinode
->
i_ctime
=
CURRENT_TIME
;
oldinode
->
i_dirt
=
1
;
mark_inode_dirty
(
oldinode
)
;
iput
(
oldinode
);
return
0
;
}
...
...
@@ -667,8 +667,8 @@ static int subdir(struct inode * new_inode, struct inode * old_inode)
* Anybody can rename anything with this: the permission checks are left to the
* higher-level routines.
*/
static
int
do_sysv_rename
(
struct
inode
*
old_dir
,
const
char
*
old_name
,
int
old_len
,
struct
inode
*
new_dir
,
const
char
*
new_name
,
int
new_len
)
static
int
do_sysv_rename
(
struct
inode
*
old_dir
,
struct
dentry
*
old_dentry
,
struct
inode
*
new_dir
,
struct
dentry
*
new_dentry
)
{
struct
inode
*
old_inode
,
*
new_inode
;
struct
buffer_head
*
old_bh
,
*
new_bh
,
*
dir_bh
;
...
...
@@ -687,21 +687,21 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
start_up:
old_inode
=
new_inode
=
NULL
;
old_bh
=
new_bh
=
dir_bh
=
NULL
;
old_bh
=
sysv_find_entry
(
old_dir
,
old_name
,
old_len
,
&
old_de
);
old_bh
=
sysv_find_entry
(
old_dir
,
old_dentry
->
d_name
.
name
,
old_dentry
->
d_name
.
len
,
&
old_de
);
retval
=
-
ENOENT
;
if
(
!
old_bh
)
goto
end_rename
;
old_inode
=
__iget
(
old_dir
->
i_sb
,
old_de
->
inode
,
0
);
/* don't cross mnt-points */
if
(
!
old_inode
)
goto
end_rename
;
old_inode
=
old_dentry
->
d_inode
;
/* don't cross mnt-points */
retval
=
-
EPERM
;
if
((
old_dir
->
i_mode
&
S_ISVTX
)
&&
current
->
fsuid
!=
old_inode
->
i_uid
&&
current
->
fsuid
!=
old_dir
->
i_uid
&&
!
fsuser
())
goto
end_rename
;
new_bh
=
sysv_find_entry
(
new_dir
,
new_name
,
new_len
,
&
new_de
);
new_inode
=
new_dentry
->
d_inode
;
new_bh
=
sysv_find_entry
(
new_dir
,
new_dentry
->
d_name
.
name
,
new_dentry
->
d_name
.
len
,
&
new_de
);
if
(
new_bh
)
{
new_inode
=
__iget
(
new_dir
->
i_sb
,
new_de
->
inode
,
0
);
if
(
!
new_inode
)
{
brelse
(
new_bh
);
new_bh
=
NULL
;
...
...
@@ -748,7 +748,8 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
goto
end_rename
;
}
if
(
!
new_bh
)
{
retval
=
sysv_add_entry
(
new_dir
,
new_name
,
new_len
,
&
new_bh
,
&
new_de
);
retval
=
sysv_add_entry
(
new_dir
,
new_dentry
->
d_name
.
name
,
new_dentry
->
d_name
.
len
,
&
new_bh
,
&
new_de
);
if
(
retval
)
goto
end_rename
;
}
...
...
@@ -763,13 +764,13 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
old_de
->
inode
=
0
;
new_de
->
inode
=
old_inode
->
i_ino
;
old_dir
->
i_ctime
=
old_dir
->
i_mtime
=
CURRENT_TIME
;
old_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
old_dir
)
;
new_dir
->
i_ctime
=
new_dir
->
i_mtime
=
CURRENT_TIME
;
new_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
new_dir
)
;
if
(
new_inode
)
{
new_inode
->
i_nlink
--
;
new_inode
->
i_ctime
=
CURRENT_TIME
;
new_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
new_inode
)
;
}
mark_buffer_dirty
(
old_bh
,
1
);
mark_buffer_dirty
(
new_bh
,
1
);
...
...
@@ -777,13 +778,13 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
PARENT_INO
(
dir_bh
->
b_data
)
=
new_dir
->
i_ino
;
mark_buffer_dirty
(
dir_bh
,
1
);
old_dir
->
i_nlink
--
;
old_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
old_dir
)
;
if
(
new_inode
)
{
new_inode
->
i_nlink
--
;
new_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
new_inode
)
;
}
else
{
new_dir
->
i_nlink
++
;
new_dir
->
i_dirt
=
1
;
mark_inode_dirty
(
new_dir
)
;
}
}
retval
=
0
;
...
...
@@ -807,8 +808,8 @@ static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old
* the same device that races occur: many renames can happen at once, as long
* as they are on different partitions.
*/
int
sysv_rename
(
struct
inode
*
old_dir
,
const
char
*
old_name
,
int
old_len
,
struct
inode
*
new_dir
,
const
char
*
new_name
,
int
new_len
)
int
sysv_rename
(
struct
inode
*
old_dir
,
struct
dentry
*
old_dentry
,
struct
inode
*
new_dir
,
struct
dentry
*
new_dentry
)
{
static
struct
wait_queue
*
wait
=
NULL
;
static
int
lock
=
0
;
...
...
@@ -817,8 +818,8 @@ int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
while
(
lock
)
sleep_on
(
&
wait
);
lock
=
1
;
result
=
do_sysv_rename
(
old_dir
,
old_
name
,
old_len
,
new_dir
,
new_
name
,
new_len
);
result
=
do_sysv_rename
(
old_dir
,
old_
dentry
,
new_dir
,
new_
dentry
);
lock
=
0
;
wake_up
(
&
wait
);
return
result
;
...
...
fs/sysv/symlink.c
View file @
c83fb0bd
...
...
@@ -21,6 +21,7 @@
#include <asm/uaccess.h>
static
int
sysv_readlink
(
struct
inode
*
,
char
*
,
int
);
static
struct
dentry
*
sysv_follow_link
(
struct
inode
*
,
struct
dentry
*
);
/*
* symlinks can't do much...
...
...
@@ -37,6 +38,7 @@ struct inode_operations sysv_symlink_inode_operations = {
NULL
,
/* mknod */
NULL
,
/* rename */
sysv_readlink
,
/* readlink */
sysv_follow_link
,
/* follow_link */
NULL
,
/* readpage */
NULL
,
/* writepage */
NULL
,
/* bmap */
...
...
@@ -44,6 +46,21 @@ struct inode_operations sysv_symlink_inode_operations = {
NULL
/* permission */
};
static
struct
dentry
*
sysv_follow_link
(
struct
inode
*
inode
,
struct
dentry
*
base
)
{
struct
buffer_head
*
bh
;
bh
=
sysv_file_bread
(
inode
,
0
,
0
);
if
(
!
bh
)
{
dput
(
base
);
return
ERR_PTR
(
-
EIO
);
}
UPDATE_ATIME
(
inode
);
base
=
lookup_dentry
(
bh
->
b_data
,
base
,
1
);
brelse
(
bh
);
return
base
;
}
static
int
sysv_readlink
(
struct
inode
*
inode
,
char
*
buffer
,
int
buflen
)
{
struct
buffer_head
*
bh
;
...
...
@@ -54,7 +71,6 @@ static int sysv_readlink(struct inode * inode, char * buffer, int buflen)
if
(
buflen
>
inode
->
i_sb
->
sv_block_size_1
)
buflen
=
inode
->
i_sb
->
sv_block_size_1
;
bh
=
sysv_file_bread
(
inode
,
0
,
0
);
iput
(
inode
);
if
(
!
bh
)
return
0
;
bh_data
=
bh
->
b_data
;
...
...
fs/sysv/truncate.c
View file @
c83fb0bd
...
...
@@ -64,7 +64,7 @@ static int trunc_direct(struct inode * inode)
continue
;
}
*
p
=
0
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
brelse
(
bh
);
sysv_free_block
(
sb
,
block
);
}
...
...
@@ -257,12 +257,14 @@ static int trunc_tindirect(struct inode * inode, unsigned long offset, unsigned
static
int
trunc_all
(
struct
inode
*
inode
)
{
struct
super_block
*
sb
;
char
*
res
;
sb
=
inode
->
i_sb
;
res
=
(
char
*
)
test_bit
(
I_DIRTY
,
&
inode
->
i_state
);
return
trunc_direct
(
inode
)
|
trunc_indirect
(
inode
,
sb
->
sv_ind0_size
,
&
inode
->
u
.
sysv_i
.
i_data
[
10
],
0
,
&
inode
->
i_dirt
)
|
trunc_dindirect
(
inode
,
sb
->
sv_ind1_size
,
&
inode
->
u
.
sysv_i
.
i_data
[
11
],
0
,
&
inode
->
i_dirt
)
|
trunc_tindirect
(
inode
,
sb
->
sv_ind2_size
,
&
inode
->
u
.
sysv_i
.
i_data
[
12
],
0
,
&
inode
->
i_dirt
);
|
trunc_indirect
(
inode
,
sb
->
sv_ind0_size
,
&
inode
->
u
.
sysv_i
.
i_data
[
10
],
0
,
res
)
|
trunc_dindirect
(
inode
,
sb
->
sv_ind1_size
,
&
inode
->
u
.
sysv_i
.
i_data
[
11
],
0
,
res
)
|
trunc_tindirect
(
inode
,
sb
->
sv_ind2_size
,
&
inode
->
u
.
sysv_i
.
i_data
[
12
],
0
,
res
);
}
...
...
@@ -285,5 +287,5 @@ void sysv_truncate(struct inode * inode)
schedule
();
}
inode
->
i_mtime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
mark_inode_dirty
(
inode
)
;
}
fs/vfat/namei.c
View file @
c83fb0bd
...
...
@@ -877,7 +877,7 @@ static int vfat_find(struct inode *dir,const char *name,int len,
PRINTK
((
"vfat_find: create file 4
\n
"
));
dir
->
i_ctime
=
dir
->
i_mtime
=
dir
->
i_atime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
PRINTK
((
"vfat_find: create file 5
\n
"
));
...
...
@@ -1010,7 +1010,7 @@ static int vfat_create_entry(struct inode *dir,const char *name,int len,
return
-
EIO
;
(
*
result
)
->
i_mtime
=
(
*
result
)
->
i_atime
=
(
*
result
)
->
i_ctime
=
CURRENT_TIME
;
(
*
result
)
->
i_dirt
=
1
;
mark_inode_dirty
(
*
result
)
;
(
*
result
)
->
i_version
=
++
event
;
dir
->
i_version
=
event
;
...
...
@@ -1046,7 +1046,7 @@ static int vfat_create_a_dotdir(struct inode *dir,struct inode *parent,
* XXX all times should be set by caller upon successful completion.
*/
dir
->
i_atime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
)
;
memcpy
(
de
->
name
,
name
,
MSDOS_NAME
);
memset
(
de
->
unused
,
0
,
sizeof
(
de
->
unused
));
de
->
lcase
=
0
;
...
...
@@ -1062,7 +1062,7 @@ static int vfat_create_a_dotdir(struct inode *dir,struct inode *parent,
vfat_read_inode
(
dot
);
if
(
!
dot
)
return
-
EIO
;
dot
->
i_mtime
=
dot
->
i_atime
=
CURRENT_TIME
;
dot
->
i_dirt
=
1
;
mark_inode_dirty
(
dot
)
;
if
(
isdot
)
{
dot
->
i_size
=
dir
->
i_size
;
MSDOS_I
(
dot
)
->
i_start
=
MSDOS_I
(
dir
)
->
i_start
;
...
...
@@ -1173,7 +1173,8 @@ static int vfat_rmdir_free_ino(struct inode *dir,struct buffer_head *bh,
inode
->
i_mtime
=
dir
->
i_mtime
=
CURRENT_TIME
;
inode
->
i_atime
=
dir
->
i_atime
=
CURRENT_TIME
;
dir
->
i_nlink
--
;
inode
->
i_dirt
=
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
);
mark_inode_dirty
(
inode
);
de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
bh
,
1
);
iput
(
inode
);
...
...
@@ -1196,7 +1197,8 @@ static int vfat_unlink_free_ino(struct inode *dir,struct buffer_head *bh,
inode
->
i_atime
=
dir
->
i_atime
=
CURRENT_TIME
;
dir
->
i_version
=
++
event
;
MSDOS_I
(
inode
)
->
i_busy
=
1
;
inode
->
i_dirt
=
dir
->
i_dirt
=
1
;
mark_inode_dirty
(
dir
);
mark_inode_dirty
(
inode
);
de
->
name
[
0
]
=
DELETED_FLAG
;
fat_mark_buffer_dirty
(
sb
,
bh
,
1
);
...
...
@@ -1478,7 +1480,7 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len,
MSDOS_I
(
new_inode
)
->
i_oldlink
=
old_inode
;
fat_cache_inval_inode
(
old_inode
);
PRINTK
((
"vfat_rename 15: old_slots=%d
\n
"
,
old_slots
));
old_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
old_inode
)
;
old_dir
->
i_version
=
++
event
;
/* remove the old entry */
...
...
@@ -1511,7 +1513,7 @@ int vfat_rename(struct inode *old_dir,const char *old_name,int old_len,
}
dotdot_de
->
start
=
MSDOS_I
(
dotdot_inode
)
->
i_start
=
MSDOS_I
(
new_dir
)
->
i_start
;
dotdot_inode
->
i_dirt
=
1
;
mark_inode_dirty
(
dotdot_inode
)
;
fat_mark_buffer_dirty
(
sb
,
dotdot_bh
,
1
);
old_dir
->
i_nlink
--
;
new_dir
->
i_nlink
++
;
...
...
include/linux/dcache.h
View file @
c83fb0bd
...
...
@@ -65,7 +65,7 @@ struct dentry {
* to invalidate a dentry for some reason (NFS
* timeouts or autofs deletes).
*/
inline
void
d_drop
(
struct
dentry
*
dentry
)
static
inline
void
d_drop
(
struct
dentry
*
dentry
)
{
list_del
(
&
dentry
->
d_hash
);
INIT_LIST_HEAD
(
&
dentry
->
d_hash
);
...
...
include/linux/ext2_fs.h
View file @
c83fb0bd
...
...
@@ -483,6 +483,7 @@ extern int ext2_getcluster (struct inode * inode, long block);
extern
void
ext2_read_inode
(
struct
inode
*
);
extern
void
ext2_write_inode
(
struct
inode
*
);
extern
void
ext2_put_inode
(
struct
inode
*
);
extern
void
ext2_delete_inode
(
struct
inode
*
);
extern
int
ext2_sync_inode
(
struct
inode
*
);
extern
void
ext2_discard_prealloc
(
struct
inode
*
);
...
...
@@ -492,7 +493,7 @@ extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
/* namei.c */
extern
void
ext2_release
(
struct
inode
*
,
struct
file
*
);
extern
int
ext2_lookup
(
struct
inode
*
,
struct
qstr
*
,
struct
inode
*
*
);
extern
int
ext2_lookup
(
struct
inode
*
,
struct
dentry
*
);
extern
int
ext2_create
(
struct
inode
*
,
struct
dentry
*
,
int
);
extern
int
ext2_mkdir
(
struct
inode
*
,
struct
dentry
*
,
int
);
extern
int
ext2_rmdir
(
struct
inode
*
,
struct
dentry
*
);
...
...
include/linux/fs.h
View file @
c83fb0bd
...
...
@@ -304,7 +304,7 @@ struct inode {
unsigned
long
i_ino
;
kdev_t
i_dev
;
atomic_
t
i_count
;
unsigned
shor
t
i_count
;
umode_t
i_mode
;
nlink_t
i_nlink
;
uid_t
i_uid
;
...
...
@@ -358,6 +358,7 @@ struct inode {
/* Inode state bits.. */
#define I_DIRTY 0
#define I_LOCK 1
#define I_FREEING 2
extern
void
__mark_inode_dirty
(
struct
inode
*
);
static
inline
void
mark_inode_dirty
(
struct
inode
*
inode
)
...
...
@@ -542,7 +543,7 @@ struct file_operations {
struct
inode_operations
{
struct
file_operations
*
default_file_ops
;
int
(
*
create
)
(
struct
inode
*
,
struct
dentry
*
,
int
);
int
(
*
lookup
)
(
struct
inode
*
,
struct
qstr
*
name
,
struct
inode
*
*
);
int
(
*
lookup
)
(
struct
inode
*
,
struct
dentry
*
);
int
(
*
link
)
(
struct
inode
*
,
struct
inode
*
,
struct
dentry
*
);
int
(
*
unlink
)
(
struct
inode
*
,
struct
dentry
*
);
int
(
*
symlink
)
(
struct
inode
*
,
struct
dentry
*
,
const
char
*
);
...
...
@@ -565,9 +566,10 @@ struct inode_operations {
struct
super_operations
{
void
(
*
read_inode
)
(
struct
inode
*
);
int
(
*
notify_change
)
(
struct
inode
*
,
struct
iattr
*
);
void
(
*
write_inode
)
(
struct
inode
*
);
void
(
*
put_inode
)
(
struct
inode
*
);
void
(
*
delete_inode
)
(
struct
inode
*
);
int
(
*
notify_change
)
(
struct
inode
*
,
struct
iattr
*
);
void
(
*
put_super
)
(
struct
super_block
*
);
void
(
*
write_super
)
(
struct
super_block
*
);
int
(
*
statfs
)
(
struct
super_block
*
,
struct
statfs
*
,
int
);
...
...
@@ -744,7 +746,6 @@ extern struct inode * get_empty_inode(void);
extern
struct
inode
*
get_empty_inode_hashed
(
dev_t
i_dev
,
unsigned
long
i_ino
);
extern
void
insert_inode_hash
(
struct
inode
*
);
extern
struct
inode
*
get_pipe_inode
(
void
);
extern
int
get_unused_fd
(
void
);
extern
void
put_unused_fd
(
int
);
extern
struct
file
*
get_empty_filp
(
void
);
...
...
include/linux/iso_fs.h
View file @
c83fb0bd
...
...
@@ -152,8 +152,7 @@ extern int find_rock_ridge_relocation(struct iso_directory_record *, struct inod
extern
int
isofs_open
(
struct
inode
*
inode
,
struct
file
*
filp
);
extern
void
isofs_release
(
struct
inode
*
inode
,
struct
file
*
filp
);
extern
int
isofs_lookup
(
struct
inode
*
dir
,
struct
qstr
*
dentry
,
struct
inode
**
result
);
extern
int
isofs_lookup
(
struct
inode
*
dir
,
struct
dentry
*
);
extern
unsigned
long
isofs_count_free_inodes
(
struct
super_block
*
sb
);
extern
int
isofs_new_block
(
int
dev
);
extern
int
isofs_free_block
(
int
dev
,
int
block
);
...
...
include/linux/iso_fs_i.h
View file @
c83fb0bd
...
...
@@ -6,7 +6,6 @@
*/
struct
iso_inode_info
{
unsigned
int
i_first_extent
;
unsigned
int
i_backlink
;
unsigned
char
i_file_format
;
};
...
...
include/linux/minix_fs.h
View file @
c83fb0bd
...
...
@@ -121,7 +121,7 @@ extern int minix_remount (struct super_block * sb, int * flags, char * data);
extern
void
minix_read_inode
(
struct
inode
*
);
extern
void
minix_write_inode
(
struct
inode
*
);
extern
void
minix_put_inode
(
struct
inode
*
);
extern
void
minix_statfs
(
struct
super_block
*
,
struct
statfs
*
,
int
);
extern
int
minix_statfs
(
struct
super_block
*
,
struct
statfs
*
,
int
);
extern
int
minix_sync_inode
(
struct
inode
*
);
extern
int
minix_sync_file
(
struct
inode
*
,
struct
file
*
);
...
...
include/linux/msdos_fs.h
View file @
c83fb0bd
...
...
@@ -215,7 +215,7 @@ extern void fat_put_super(struct super_block *sb);
extern
void
fat_read_inode
(
struct
inode
*
inode
,
struct
inode_operations
*
dir_ops
);
extern
struct
super_block
*
fat_read_super
(
struct
super_block
*
s
,
void
*
data
,
int
silent
);
extern
void
msdos_put_super
(
struct
super_block
*
sb
);
extern
void
fat_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
);
extern
int
fat_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
,
int
);
extern
void
fat_write_inode
(
struct
inode
*
inode
);
/* dir.c */
...
...
include/linux/nfsd/nfsfh.h
View file @
c83fb0bd
...
...
@@ -57,7 +57,7 @@ struct knfs_fh {
typedef
struct
svc_fh
{
struct
knfs_fh
fh_handle
;
/* FH data */
struct
svc_export
*
fh_export
;
/* export pointer */
struct
inode
*
fh_inode
;
/* inod
e */
struct
dentry
*
fh_dentry
;
/* fil
e */
size_t
fh_pre_size
;
/* size before operation */
time_t
fh_pre_mtime
;
/* mtime before oper */
time_t
fh_pre_ctime
;
/* ctime before oper */
...
...
@@ -98,7 +98,7 @@ fh_init(struct svc_fh *fhp)
static
inline
void
fh_lock
(
struct
svc_fh
*
fhp
)
{
struct
inode
*
inode
=
fhp
->
fh_inode
;
struct
inode
*
inode
=
fhp
->
fh_
dentry
->
d_
inode
;
/*
dfprintk(FILEOP, "nfsd: fh_lock(%x/%ld) locked = %d\n",
...
...
@@ -118,7 +118,7 @@ fh_lock(struct svc_fh *fhp)
static
inline
void
fh_unlock
(
struct
svc_fh
*
fhp
)
{
struct
inode
*
inode
=
fhp
->
fh_inode
;
struct
inode
*
inode
=
fhp
->
fh_
dentry
->
d_
inode
;
if
(
fhp
->
fh_locked
)
{
if
(
!
fhp
->
fh_post_version
)
...
...
@@ -135,9 +135,9 @@ fh_unlock(struct svc_fh *fhp)
static
inline
void
fh_put
(
struct
svc_fh
*
fhp
)
{
if
(
fhp
->
fh_
inode
)
{
if
(
fhp
->
fh_
dentry
)
{
fh_unlock
(
fhp
);
iput
(
fhp
->
fh_inode
);
dput
(
fhp
->
fh_dentry
);
}
}
#else
...
...
@@ -146,19 +146,19 @@ fh_put(struct svc_fh *fhp)
static
inline
void
__fh_put
(
struct
svc_fh
*
fhp
,
char
*
file
,
int
line
)
{
struct
inode
*
inode
;
struct
dentry
*
dentry
;
if
(
!
(
inode
=
fhp
->
fh_inode
))
if
(
!
(
dentry
=
fhp
->
fh_dentry
))
return
;
if
(
!
atomic_read
(
&
inode
->
i_count
)
)
{
printk
(
"nfsd: trying to free free
inode
in %s:%d
\n
"
"
dev %04x ino %ld, mode %07o
\n
"
,
file
,
line
,
inode
->
i_dev
,
inode
->
i_ino
,
inode
->
i_mod
e
);
if
(
!
dentry
->
d_count
)
{
printk
(
"nfsd: trying to free free
dentry
in %s:%d
\n
"
"
file %s/%s
\n
"
,
file
,
line
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
nam
e
);
}
else
{
fh_unlock
(
fhp
);
iput
(
inode
);
dput
(
dentry
);
}
}
#endif
...
...
include/linux/pipe_fs_i.h
View file @
c83fb0bd
...
...
@@ -5,7 +5,6 @@ struct pipe_inode_info {
struct
wait_queue
*
wait
;
char
*
base
;
unsigned
int
start
;
unsigned
int
len
;
unsigned
int
lock
;
unsigned
int
rd_openers
;
unsigned
int
wr_openers
;
...
...
@@ -16,7 +15,7 @@ struct pipe_inode_info {
#define PIPE_WAIT(inode) ((inode).u.pipe_i.wait)
#define PIPE_BASE(inode) ((inode).u.pipe_i.base)
#define PIPE_START(inode) ((inode).u.pipe_i.start)
#define PIPE_LEN(inode) ((inode).
u.pipe_i.len
)
#define PIPE_LEN(inode) ((inode).
i_size
)
#define PIPE_RD_OPENERS(inode) ((inode).u.pipe_i.rd_openers)
#define PIPE_WR_OPENERS(inode) ((inode).u.pipe_i.wr_openers)
#define PIPE_READERS(inode) ((inode).u.pipe_i.readers)
...
...
include/linux/proc_fs.h
View file @
c83fb0bd
...
...
@@ -323,7 +323,7 @@ extern int proc_match(int, const char *,struct proc_dir_entry *);
* of the /proc/<pid> subdirectories.
*/
extern
int
proc_readdir
(
struct
inode
*
,
struct
file
*
,
void
*
,
filldir_t
);
extern
int
proc_lookup
(
struct
inode
*
,
struct
qstr
*
,
struct
inode
*
*
);
extern
int
proc_lookup
(
struct
inode
*
,
struct
dentry
*
);
struct
openpromfs_dev
{
struct
openpromfs_dev
*
next
;
...
...
include/linux/sysv_fs.h
View file @
c83fb0bd
...
...
@@ -372,8 +372,8 @@ extern int sysv_symlink(struct inode * inode, const char * name, int len,
const
char
*
symname
);
extern
int
sysv_link
(
struct
inode
*
oldinode
,
struct
inode
*
dir
,
const
char
*
name
,
int
len
);
extern
int
sysv_mknod
(
struct
inode
*
dir
,
const
char
*
name
,
int
len
,
int
mode
,
int
rdev
);
extern
int
sysv_rename
(
struct
inode
*
old_dir
,
const
char
*
old_name
,
int
old_len
,
struct
inode
*
new_dir
,
const
char
*
new_name
,
int
new_len
);
extern
int
sysv_rename
(
struct
inode
*
old_dir
,
struct
dentry
*
old_dentry
,
struct
inode
*
new_dir
,
struct
dentry
*
new_dentry
);
extern
struct
inode
*
sysv_new_inode
(
const
struct
inode
*
dir
);
extern
void
sysv_free_inode
(
struct
inode
*
inode
);
extern
unsigned
long
sysv_count_free_inodes
(
struct
super_block
*
sb
);
...
...
@@ -396,7 +396,7 @@ extern void sysv_read_inode(struct inode *);
extern
int
sysv_notify_change
(
struct
inode
*
,
struct
iattr
*
);
extern
void
sysv_write_inode
(
struct
inode
*
);
extern
void
sysv_put_inode
(
struct
inode
*
);
extern
void
sysv_statfs
(
struct
super_block
*
,
struct
statfs
*
,
int
);
extern
int
sysv_statfs
(
struct
super_block
*
,
struct
statfs
*
,
int
);
extern
int
sysv_sync_inode
(
struct
inode
*
);
extern
int
sysv_sync_file
(
struct
inode
*
,
struct
file
*
);
extern
int
sysv_mmap
(
struct
inode
*
,
struct
file
*
,
struct
vm_area_struct
*
);
...
...
kernel/ksyms.c
View file @
c83fb0bd
...
...
@@ -180,6 +180,7 @@ EXPORT_SYMBOL(posix_lock_file);
EXPORT_SYMBOL
(
posix_test_lock
);
EXPORT_SYMBOL
(
posix_block_lock
);
EXPORT_SYMBOL
(
posix_unblock_lock
);
EXPORT_SYMBOL
(
dput
);
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
EXPORT_SYMBOL
(
do_nfsservctl
);
...
...
net/socket.c
View file @
c83fb0bd
...
...
@@ -206,6 +206,19 @@ static int get_fd(struct inode *inode)
return
-
ENFILE
;
}
file
->
f_dentry
=
d_alloc_root
(
inode
,
NULL
);
if
(
!
file
->
f_dentry
)
{
put_filp
(
file
);
put_unused_fd
(
fd
);
return
-
ENOMEM
;
}
/*
* The socket maintains a reference to the inode, so we
* have to increment the count.
*/
inode
->
i_count
++
;
current
->
files
->
fd
[
fd
]
=
file
;
file
->
f_op
=
&
socket_file_ops
;
file
->
f_mode
=
3
;
...
...
net/unix/af_unix.c
View file @
c83fb0bd
...
...
@@ -544,7 +544,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
err
=
PTR_ERR
(
dentry
);
if
(
!
IS_ERR
(
dentry
))
{
inode
=
dentry
->
d_inode
;
atomic_inc
(
&
inode
->
i_count
);
inode
->
i_count
++
;
/* HATEFUL - we should use the dentry */
dput
(
dentry
);
err
=
0
;
}
...
...
@@ -794,7 +794,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
}
if
(
sk
->
protinfo
.
af_unix
.
inode
)
{
atomic_inc
(
&
sk
->
protinfo
.
af_unix
.
inode
->
i_count
);
sk
->
protinfo
.
af_unix
.
inode
->
i_count
++
;
/* Should use dentry */
newsk
->
protinfo
.
af_unix
.
inode
=
sk
->
protinfo
.
af_unix
.
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