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
7f98bfdb
Commit
7f98bfdb
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.1.65
parent
3e213f64
Changes
25
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1396 additions
and
344 deletions
+1396
-344
CREDITS
CREDITS
+11
-0
Makefile
Makefile
+1
-1
arch/i386/kernel/entry.S
arch/i386/kernel/entry.S
+4
-0
arch/i386/kernel/traps.c
arch/i386/kernel/traps.c
+10
-0
arch/i386/mm/fault.c
arch/i386/mm/fault.c
+64
-39
drivers/block/README.fd
drivers/block/README.fd
+1
-1
drivers/block/floppy.c
drivers/block/floppy.c
+2
-2
drivers/net/eepro100.c
drivers/net/eepro100.c
+108
-42
drivers/scsi/ppa.h
drivers/scsi/ppa.h
+1
-1
drivers/sound/lowlevel/awe_config.h
drivers/sound/lowlevel/awe_config.h
+1
-1
drivers/sound/soundcard.c
drivers/sound/soundcard.c
+1
-1
fs/dcache.c
fs/dcache.c
+87
-77
fs/inode.c
fs/inode.c
+19
-22
fs/lockd/svcsubs.c
fs/lockd/svcsubs.c
+13
-4
fs/namei.c
fs/namei.c
+5
-3
fs/nfsd/export.c
fs/nfsd/export.c
+9
-13
fs/nfsd/nfsctl.c
fs/nfsd/nfsctl.c
+12
-8
fs/nfsd/nfsfh.c
fs/nfsd/nfsfh.c
+904
-36
fs/nfsd/nfsproc.c
fs/nfsd/nfsproc.c
+7
-8
fs/nfsd/nfsxdr.c
fs/nfsd/nfsxdr.c
+3
-3
fs/nfsd/vfs.c
fs/nfsd/vfs.c
+93
-49
fs/select.c
fs/select.c
+11
-0
include/asm-alpha/softirq.h
include/asm-alpha/softirq.h
+1
-1
include/linux/nfsd/nfsfh.h
include/linux/nfsd/nfsfh.h
+28
-31
net/sunrpc/svcsock.c
net/sunrpc/svcsock.c
+0
-1
No files found.
CREDITS
View file @
7f98bfdb
...
...
@@ -451,6 +451,17 @@ S: 1123 North Oak Park Avenue
S: Oak Park, Illinois 60302
S: USA
N: Jim Freeman
E: jfree@caldera.com
W: http://www.sovereign.org/
D: Initial GPL'd Frame Relay driver
D: Dynamic PPP devices
D: Sundry modularizations (PPP, IPX, ...) and fixes
S: Caldera, Inc.
S: 240 West Center St.
S: Orem, Utah 84059-1920
S: USA
N: Bob Frey
E: bobf@advansys.com
D: AdvanSys SCSI driver
...
...
Makefile
View file @
7f98bfdb
VERSION
=
2
PATCHLEVEL
=
1
SUBLEVEL
=
6
4
SUBLEVEL
=
6
5
ARCH
:=
$(
shell
uname
-m
|
sed
-e
s/i.86/i386/
-e
s/sun4u/sparc64/
)
...
...
arch/i386/kernel/entry.S
View file @
7f98bfdb
...
...
@@ -349,6 +349,10 @@ ENTRY(page_fault)
pushl
$
SYMBOL_NAME
(
do_page_fault
)
jmp
error_code
ENTRY
(
page_fault_f00f
)
pushl
$
SYMBOL_NAME
(
do_page_fault_f00f
)
jmp
error_code
ENTRY
(
spurious_interrupt_bug
)
pushl
$
0
pushl
$
SYMBOL_NAME
(
do_spurious_interrupt_bug
)
...
...
arch/i386/kernel/traps.c
View file @
7f98bfdb
...
...
@@ -103,6 +103,7 @@ asmlinkage void segment_not_present(void);
asmlinkage
void
stack_segment
(
void
);
asmlinkage
void
general_protection
(
void
);
asmlinkage
void
page_fault
(
void
);
asmlinkage
void
page_fault_f00f
(
void
);
asmlinkage
void
coprocessor_error
(
void
);
asmlinkage
void
reserved
(
void
);
asmlinkage
void
alignment_check
(
void
);
...
...
@@ -417,6 +418,14 @@ __initfunc(void trap_init_f00f_bug(void))
{
unsigned
long
page
;
/*
* We use a special page fault handler, to actually detect
* 'bounced' traps/exceptions #0-6. This new page fault
* handler is a few tens of cycles slower than the 'normal'
* one.
*/
set_trap_gate
(
14
,
&
page_fault_f00f
);
/*
* Allocate a new page in virtual address space,
* and move the IDT to have entry #7 starting at
...
...
@@ -433,6 +442,7 @@ __initfunc(void trap_init_f00f_bug(void))
*/
idt
=
(
struct
desc_struct
*
)(
page
-
7
*
8
);
__asm__
__volatile__
(
"lidt %0"
:
"=m"
(
idt_descr
));
}
...
...
arch/i386/mm/fault.c
View file @
7f98bfdb
...
...
@@ -74,15 +74,6 @@ int __verify_write(const void * addr, unsigned long size)
return
0
;
}
asmlinkage
void
do_divide_error
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_debug
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_nmi
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_int3
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_overflow
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_bounds
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_invalid_op
(
struct
pt_regs
*
,
unsigned
long
);
extern
int
pentium_f00f_bug
;
/*
* This routine handles page faults. It determines the address,
...
...
@@ -94,45 +85,17 @@ extern int pentium_f00f_bug;
* bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode
*/
asmlinkage
void
do_page_fault
(
struct
pt_regs
*
regs
,
unsigned
long
error_code
)
static
void
__do_page_fault
(
struct
pt_regs
*
regs
,
unsigned
long
error_code
,
unsigned
long
address
)
{
struct
task_struct
*
tsk
;
struct
mm_struct
*
mm
;
struct
vm_area_struct
*
vma
;
unsigned
long
address
;
unsigned
long
page
;
unsigned
long
fixup
;
int
write
;
/* get the address */
__asm__
(
"movl %%cr2,%0"
:
"=r"
(
address
));
/*
* Pentium F0 0F C7 C8 bug workaround. Do this first,
* to make sure we don't have locking problems with
* asynchronous traps (ie NMI).
*/
if
(
!
(
error_code
&
7
)
&&
pentium_f00f_bug
)
{
unsigned
long
nr
;
nr
=
(
address
-
(
unsigned
long
)
idt
)
>>
3
;
if
(
nr
<
7
)
{
static
void
(
*
handler
[])(
struct
pt_regs
*
,
unsigned
long
)
=
{
do_divide_error
,
/* 0 - divide overflow */
do_debug
,
/* 1 - debug trap */
do_nmi
,
/* 2 - NMI */
do_int3
,
/* 3 - int 3 */
do_overflow
,
/* 4 - overflow */
do_bounds
,
/* 5 - bound range */
do_invalid_op
};
/* 6 - invalid opcode */
handler
[
nr
](
regs
,
0
);
return
;
}
}
lock_kernel
();
tsk
=
current
;
mm
=
tsk
->
mm
;
...
...
@@ -253,3 +216,65 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
out:
unlock_kernel
();
}
/*
* One of these two functions is the real page fault handler, which one depends
* on wether the CPU has the F00F bug:
*/
asmlinkage
void
do_page_fault
(
struct
pt_regs
*
regs
,
unsigned
long
error_code
)
{
unsigned
long
address
;
/* get the address */
__asm__
(
"movl %%cr2,%0"
:
"=r"
(
address
));
__do_page_fault
(
regs
,
error_code
,
address
);
}
asmlinkage
void
do_divide_error
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_debug
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_nmi
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_int3
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_overflow
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_bounds
(
struct
pt_regs
*
,
unsigned
long
);
asmlinkage
void
do_invalid_op
(
struct
pt_regs
*
,
unsigned
long
);
extern
int
pentium_f00f_bug
;
asmlinkage
void
do_page_fault_f00f
(
struct
pt_regs
*
regs
,
unsigned
long
error_code
)
{
unsigned
long
address
;
/* get the address */
__asm__
(
"movl %%cr2,%0"
:
"=r"
(
address
));
/*
* Pentium F0 0F C7 C8 bug workaround. Do this first,
* to make sure we don't have locking problems with
* asynchronous traps (ie NMI).
*/
if
(
!
(
error_code
&
5
)
&&
pentium_f00f_bug
)
{
unsigned
long
nr
;
nr
=
(
address
-
(
unsigned
long
)
idt
)
>>
3
;
if
(
nr
<
7
)
{
static
void
(
*
handler
[])(
struct
pt_regs
*
,
unsigned
long
)
=
{
do_divide_error
,
/* 0 - divide overflow */
do_debug
,
/* 1 - debug trap */
do_nmi
,
/* 2 - NMI */
do_int3
,
/* 3 - int 3 */
do_overflow
,
/* 4 - overflow */
do_bounds
,
/* 5 - bound range */
do_invalid_op
};
/* 6 - invalid opcode */
if
(
nr
==
3
||
nr
==
4
)
regs
->
eip
++
;
handler
[
nr
](
regs
,
0
);
return
;
}
}
__do_page_fault
(
regs
,
error_code
,
address
);
}
drivers/block/README.fd
View file @
7f98bfdb
...
...
@@ -4,7 +4,7 @@ FAQ list:
=========
A FAQ list may be found in the fdutils package (see below), and also
at http://
www.club.innet.lu/~year3160
/floppy/FAQ.html
at http://
poboxes.com/Alain.Knaff
/floppy/FAQ.html
Lilo config options (Thinkpad users, read this)
...
...
drivers/block/floppy.c
View file @
7f98bfdb
...
...
@@ -3274,7 +3274,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return
0
;
case
BLKRAGET
:
return
put_user
(
read_ahead
[
MAJOR
(
inode
->
i_rdev
)],
(
int
*
)
param
);
(
long
*
)
param
);
case
BLKFLSBUF
:
if
(
!
suser
())
return
-
EACCES
;
fsync_dev
(
inode
->
i_rdev
);
...
...
@@ -3283,7 +3283,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case
BLKGETSIZE
:
ECALL
(
get_floppy_geometry
(
drive
,
type
,
&
g
));
return
put_user
(
g
->
size
,
(
int
*
)
param
);
return
put_user
(
g
->
size
,
(
long
*
)
param
);
/* BLKRRPART is not defined as floppies don't have
* partition tables */
}
...
...
drivers/net/eepro100.c
View file @
7f98bfdb
This diff is collapsed.
Click to expand it.
drivers/scsi/ppa.h
View file @
7f98bfdb
...
...
@@ -100,7 +100,7 @@ static char *PPA_MODE_STRING[] =
int
ppa_sg
=
SG_ALL
;
/* enable/disable scatter-gather. */
/* other options */
#define PPA_CAN_QUEUE
0
/* use "queueing" interface */
#define PPA_CAN_QUEUE
1
/* use "queueing" interface */
#define PPA_BURST_SIZE 512
/* data burst size */
#define PPA_SELECT_TMO 5000
/* how long to wait for target ? */
#define PPA_SPIN_TMO 50000
/* ppa_wait loop limiter */
...
...
drivers/sound/lowlevel/awe_config.h
View file @
7f98bfdb
...
...
@@ -37,7 +37,7 @@
/* if you have lowlevel.h in the lowlevel directory (OSS-Lite), define
* the following line.
*/
#
undef
HAS_LOWLEVEL_H
#
define
HAS_LOWLEVEL_H
/* if your system doesn't support patch manager (OSS 3.7 or newer),
* define the following line.
...
...
drivers/sound/soundcard.c
View file @
7f98bfdb
...
...
@@ -327,7 +327,7 @@ sound_mmap (struct file *file, struct vm_area_struct *vma)
vma
->
vm_page_prot
))
return
-
EAGAIN
;
vma
->
vm_dentry
=
file
->
f_dentry
;
vma
->
vm_dentry
=
dget
(
file
->
f_dentry
)
;
dmap
->
mapping_flags
|=
DMA_MAP_MAPPED
;
...
...
fs/dcache.c
View file @
7f98bfdb
...
...
@@ -118,6 +118,11 @@ void dput(struct dentry *dentry)
}
list_add
(
&
dentry
->
d_lru
,
&
dentry_unused
);
dentry_stat
.
nr_unused
++
;
/*
* Update the timestamp
*/
dentry
->
d_reftime
=
jiffies
;
out:
if
(
count
>=
0
)
{
dentry
->
d_count
=
count
;
...
...
@@ -135,15 +140,12 @@ void dput(struct dentry *dentry)
* Try to invalidate the dentry if it turns out to be
* possible. If there are other users of the dentry we
* can't invalidate it.
*
* We should probably try to see if we can invalidate
* any unused children - right now we refuse to invalidate
* too much. That would require a better child list
* data structure, though.
*/
int
d_invalidate
(
struct
dentry
*
dentry
)
{
/* We might want to do a partial shrink_dcache here */
/* Check whether to do a partial shrink_dcache */
if
(
dentry
->
d_count
>
1
&&
!
list_empty
(
&
dentry
->
d_subdirs
))
shrink_dcache_parent
(
dentry
);
if
(
dentry
->
d_count
!=
1
)
return
-
EBUSY
;
...
...
@@ -152,27 +154,31 @@ int d_invalidate(struct dentry * dentry)
}
/*
* Selects less valuable dentries to be pruned when
* we need inodes or memory. The selected dentries
* are moved to the old end of the list where
* prune_dcache() can find them.
* Select less valuable dentries to be pruned when we need
* inodes or memory. The selected dentries are moved to the
* old end of the list where prune_dcache() can find them.
*
* Negative dentries are included in the selection so that
* they don't accumulate at the end of the list. The count
* returned is the total number of dentries selected, which
* may be much larger than the requested number of inodes.
*/
int
select_dcache
(
int
count
,
int
page_count
)
int
select_dcache
(
int
inode_
count
,
int
page_count
)
{
struct
list_head
*
tail
=
&
dentry_unused
;
struct
list_head
*
next
=
dentry_unused
.
prev
;
int
forward
=
0
,
young
=
0
,
depth
=
dentry_stat
.
nr_unused
>>
1
;
int
found
=
0
,
pages
=
0
;
struct
list_head
*
next
,
*
tail
=
&
dentry_unused
;
int
found
=
0
,
forward
=
0
,
young
=
8
;
int
depth
=
dentry_stat
.
nr_unused
>>
1
;
unsigned
long
min_value
=
0
,
max_value
=
4
;
#ifdef DCACHE_DEBUG
printk
(
"select_dcache: %d unused, count=%d, pages=%d
\n
"
,
dentry_stat
.
nr_unused
,
count
,
page_count
);
#endif
if
(
page_count
)
max_value
=
-
1
;
next
=
tail
->
prev
;
while
(
next
!=
&
dentry_unused
&&
depth
--
)
{
struct
list_head
*
tmp
=
next
;
struct
dentry
*
dentry
=
list_entry
(
tmp
,
struct
dentry
,
d_lru
);
struct
inode
*
inode
=
dentry
->
d_inode
;
unsigned
long
value
=
0
;
unsigned
long
value
=
0
;
next
=
tmp
->
prev
;
if
(
forward
)
...
...
@@ -184,56 +190,57 @@ dentry_stat.nr_unused, count, page_count);
continue
;
}
/*
* Select dentries based on the page cache count ...
* should factor in number of uses as well.
*/
if
(
inode
)
{
if
(
inode
->
i_state
)
continue
;
value
=
inode
->
i_nrpages
;
}
/*
* Consider various exemptions ...
* Check the dentry's age to see whether to change direction.
*/
if
(
!
page_count
)
{
if
(
!
inode
)
continue
;
if
(
value
>=
3
)
continue
;
}
else
if
(
!
forward
)
{
if
(
inode
)
{
int
age
=
CURRENT_TIME
-
inode
->
i_atime
;
if
(
age
<
dentry_stat
.
age_limit
)
{
if
(
++
young
>
8
)
{
forward
=
1
;
next
=
dentry_unused
.
next
;
if
(
!
forward
)
{
int
age
=
(
jiffies
-
dentry
->
d_reftime
)
/
HZ
;
if
(
age
<
dentry_stat
.
age_limit
)
{
if
(
!--
young
)
{
forward
=
1
;
next
=
dentry_unused
.
next
;
/*
* Update the limits -- we don't want
* files with too few or too many pages.
*/
if
(
page_count
)
{
min_value
=
3
;
max_value
=
15
;
}
#ifdef DCACHE_DEBUG
printk
(
"select_dcache: age=%d, pages=%d, scanning forward
\n
"
,
age
,
pages
);
printk
(
"select_dcache: %s/%s age=%d, scanning forward
\n
"
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
,
age
);
#endif
}
continue
;
}
continue
;
}
}
else
{
/*
* If we're scanning from the front, don't take
* files with only a trivial amount of memory.
*/
if
(
value
<
3
||
value
>
15
)
}
/*
* Select dentries based on the page cache count ...
* should factor in number of uses as well. We take
* all negative dentries so that they don't accumulate.
* (We skip inodes that aren't immediately available.)
*/
if
(
inode
)
{
value
=
inode
->
i_nrpages
;
if
(
value
>=
max_value
||
value
<
min_value
)
continue
;
if
(
inode
->
i_state
||
inode
->
i_count
>
1
)
continue
;
}
/*
* Move the
dentry behind the tail
* Move the
selected dentries behind the tail.
*/
if
(
tmp
!=
tail
->
prev
)
{
list_del
(
tmp
);
list_add
(
tmp
,
tail
->
prev
);
}
tail
=
tmp
;
pages
+=
value
;
if
(
++
found
>=
count
)
found
++
;
if
(
inode
&&
--
inode_count
<=
0
)
break
;
if
(
page_count
&&
pages
>=
page_count
)
if
(
page_count
&&
(
page_count
-=
value
)
<=
0
)
break
;
}
return
found
;
...
...
@@ -430,7 +437,7 @@ void check_dcache_memory()
if
(
goal
)
{
if
(
goal
>
50
)
goal
=
50
;
count
=
select_dcache
(
128
,
goal
);
count
=
select_dcache
(
32
,
goal
);
#ifdef DCACHE_DEBUG
printk
(
"check_dcache_memory: goal=%d, count=%d
\n
"
,
goal
,
count
);
#endif
...
...
@@ -453,7 +460,7 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
* Prune the dcache if there are too many unused dentries.
*/
if
(
dentry_stat
.
nr_unused
>
3
*
(
nr_inodes
>>
1
))
{
#ifdef DCACHE_
PARANOIA
#ifdef DCACHE_
DEBUG
printk
(
"d_alloc: %d unused, pruning dcache
\n
"
,
dentry_stat
.
nr_unused
);
#endif
prune_dcache
(
8
);
...
...
@@ -579,30 +586,33 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
int
d_validate
(
struct
dentry
*
dentry
,
struct
dentry
*
dparent
,
unsigned
int
hash
,
unsigned
int
len
)
{
struct
list_head
*
base
=
d_hash
(
dparent
,
hash
);
struct
list_head
*
lhp
=
base
;
while
((
lhp
=
lhp
->
next
)
!=
base
)
{
if
(
dentry
==
list_entry
(
lhp
,
struct
dentry
,
d_hash
))
goto
found_it
;
}
/* Special case, local mount points don't live in the hashes.
* So if we exhausted the chain, search the super blocks.
*/
if
(
dentry
&&
dentry
==
dparent
)
{
struct
super_block
*
sb
;
struct
list_head
*
base
,
*
lhp
;
int
valid
=
1
;
if
(
dentry
!=
dparent
)
{
base
=
d_hash
(
dparent
,
hash
);
lhp
=
base
;
while
((
lhp
=
lhp
->
next
)
!=
base
)
{
if
(
dentry
==
list_entry
(
lhp
,
struct
dentry
,
d_hash
))
goto
out
;
}
}
else
{
/*
* Special case: local mount points don't live in
* the hashes, so we search the super blocks.
*/
struct
super_block
*
sb
=
super_blocks
+
0
;
for
(
sb
=
super_blocks
+
0
;
sb
<
super_blocks
+
NR_SUPER
;
sb
++
)
{
for
(;
sb
<
super_blocks
+
NR_SUPER
;
sb
++
)
{
if
(
!
sb
->
s_dev
)
continue
;
if
(
sb
->
s_root
==
dentry
)
goto
found_i
t
;
goto
ou
t
;
}
}
return
0
;
found_it:
return
(
dentry
->
d_parent
==
dparent
)
&&
(
dentry
->
d_name
.
hash
==
hash
)
&&
(
dentry
->
d_name
.
len
==
len
);
valid
=
0
;
out:
return
valid
;
}
/*
...
...
fs/inode.c
View file @
7f98bfdb
...
...
@@ -358,33 +358,30 @@ static int free_inodes(int goal)
*/
static
void
try_to_free_inodes
(
int
goal
)
{
int
retr
ied
=
0
,
found
;
int
retr
y
=
1
,
found
;
/*
* Check whether to preshrink the dcache ...
*/
if
(
inodes_stat
.
preshrink
)
{
spin_unlock
(
&
inode_lock
);
select_dcache
(
goal
,
0
);
prune_dcache
(
goal
);
spin_lock
(
&
inode_lock
);
}
if
(
inodes_stat
.
preshrink
)
goto
preshrink
;
repeat:
found
=
free_inodes
(
goal
);
/*
* If we didn't free any inodes, do a limited
* pruning of the dcache to help the next time.
*/
if
(
!
found
)
{
retry
=
0
;
do
{
if
(
free_inodes
(
goal
))
break
;
/*
* If we didn't free any inodes, do a limited
* pruning of the dcache to help the next time.
*/
preshrink:
spin_unlock
(
&
inode_lock
);
select_dcache
(
goal
,
0
);
prune_dcache
(
goal
);
found
=
select_dcache
(
goal
,
0
);
if
(
found
<
goal
)
found
=
goal
;
prune_dcache
(
found
);
spin_lock
(
&
inode_lock
);
if
(
inodes_stat
.
preshrink
&&
!
retried
++
)
goto
repeat
;
}
}
while
(
retry
--
);
}
/*
...
...
@@ -440,11 +437,11 @@ static struct inode * grow_inodes(void)
* If the allocation failed, do an extensive pruning of
* the dcache and then try again to free some inodes.
*/
prune_dcache
(
128
);
prune_dcache
(
inodes_stat
.
nr_inodes
>>
2
);
inodes_stat
.
preshrink
=
1
;
spin_lock
(
&
inode_lock
);
free_inodes
(
128
);
free_inodes
(
inodes_stat
.
nr_inodes
>>
2
);
{
struct
list_head
*
tmp
=
inode_unused
.
next
;
if
(
tmp
!=
&
inode_unused
)
{
...
...
fs/lockd/svcsubs.c
View file @
7f98bfdb
...
...
@@ -32,10 +32,16 @@ static struct semaphore nlm_file_sema = MUTEX;
* Lookup file info. If it doesn't exist, create a file info struct
* and open a (VFS) file for the given inode.
*
* The NFS filehandle must have been validated prior to this call,
* as we assume that the dentry pointer is valid.
*
* FIXME:
* Note that we open the file O_RDONLY even when creating write locks.
* This is not quite right, but for now, we assume the client performs
* the proper R/W checking.
*
* The dentry in the FH may not be validated .. can we call this with
* the full svc_fh?
*/
u32
nlm_lookup_file
(
struct
svc_rqst
*
rqstp
,
struct
nlm_file
**
result
,
...
...
@@ -43,21 +49,24 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
{
struct
nlm_file
*
file
;
struct
knfs_fh
*
fh
=
(
struct
knfs_fh
*
)
f
;
unsigned
int
hash
=
FILE_HASH
(
fh
->
fh_dhash
);
struct
dentry
*
dentry
=
fh
->
fh_dcookie
;
unsigned
int
hash
=
FILE_HASH
(
dentry
->
d_name
.
hash
);
u32
nfserr
;
dprintk
(
"lockd: nlm_file_lookup(%p)
\n
"
,
fh
->
fh_dentry
);
dprintk
(
"lockd: nlm_file_lookup(%s/%s)
\n
"
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
);
/* Lock file table */
down
(
&
nlm_file_sema
);
for
(
file
=
nlm_files
[
hash
];
file
;
file
=
file
->
f_next
)
{
if
(
file
->
f_handle
.
fh_d
entry
==
fh
->
fh_
dentry
if
(
file
->
f_handle
.
fh_d
cookie
==
dentry
&&
!
memcmp
(
&
file
->
f_handle
,
fh
,
sizeof
(
*
fh
)))
goto
found
;
}
dprintk
(
"lockd: creating file for %p
\n
"
,
fh
->
fh_dentry
);
dprintk
(
"lockd: creating file for %s/%s
\n
"
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
);
if
(
!
(
file
=
(
struct
nlm_file
*
)
kmalloc
(
sizeof
(
*
file
),
GFP_KERNEL
)))
{
up
(
&
nlm_file_sema
);
return
nlm_lck_denied_nolocks
;
...
...
fs/namei.c
View file @
7f98bfdb
...
...
@@ -235,9 +235,11 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
result
=
ERR_PTR
(
-
ENOMEM
);
if
(
dentry
)
{
int
error
=
dir
->
i_op
->
lookup
(
dir
,
dentry
);
result
=
ERR_PTR
(
error
);
if
(
!
error
)
result
=
dentry
;
result
=
dentry
;
if
(
error
)
{
dput
(
dentry
);
result
=
ERR_PTR
(
error
);
}
}
}
up
(
&
dir
->
i_sem
);
...
...
fs/nfsd/export.c
View file @
7f98bfdb
...
...
@@ -179,27 +179,24 @@ exp_export(struct nfsctl_export *nxp)
}
/* Look up the dentry */
err
=
-
EINVAL
;
dentry
=
lookup_dentry
(
nxp
->
ex_path
,
NULL
,
0
);
if
(
IS_ERR
(
dentry
))
{
err
=
-
EINVAL
;
if
(
IS_ERR
(
dentry
))
goto
finish
;
}
err
=
-
ENOENT
;
inode
=
dentry
->
d_inode
;
if
(
!
inode
)
{
err
=
-
ENOENT
;
if
(
!
inode
)
goto
finish
;
}
err
=
-
EINVAL
;
if
(
inode
->
i_dev
!=
nxp
->
ex_dev
||
inode
->
i_ino
!=
nxp
->
ex_ino
)
{
/* I'm just being paranoid... */
err
=
-
EINVAL
;
goto
finish
;
}
/* We currently export only dirs. */
if
(
!
S_ISDIR
(
inode
->
i_mode
))
{
err
=
-
ENOTDIR
;
err
=
-
ENOTDIR
;
if
(
!
S_ISDIR
(
inode
->
i_mode
))
goto
finish
;
}
/* If this is a sub-export, must be root of FS */
if
((
parent
=
exp_parent
(
clp
,
dev
))
!=
NULL
)
{
...
...
@@ -211,10 +208,9 @@ exp_export(struct nfsctl_export *nxp)
}
}
if
(
!
(
exp
=
kmalloc
(
sizeof
(
*
exp
),
GFP_USER
)))
{
err
=
-
ENOMEM
;
err
=
-
ENOMEM
;
if
(
!
(
exp
=
kmalloc
(
sizeof
(
*
exp
),
GFP_USER
)))
goto
finish
;
}
dprintk
(
"nfsd: created export entry %p for client %p
\n
"
,
exp
,
clp
);
strcpy
(
exp
->
ex_path
,
nxp
->
ex_path
);
...
...
fs/nfsd/nfsctl.c
View file @
7f98bfdb
...
...
@@ -17,11 +17,11 @@
#include <linux/fcntl.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/nfs.h>
#include <linux/version.h>
#include <linux/unistd.h>
#include <linux/malloc.h>
#include <linux/nfs.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/cache.h>
...
...
@@ -38,6 +38,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
extern
void
nfsd_fh_init
(
void
);
extern
long
sys_call_table
[];
static
int
nfsctl_svc
(
struct
nfsctl_svc
*
data
);
...
...
@@ -64,6 +65,7 @@ nfsd_init(void)
nfsd_export_init
();
/* Exports table */
nfsd_lockd_init
();
/* lockd->nfsd callbacks */
nfsd_racache_init
();
/* Readahead param cache */
nfsd_fh_init
();
/* FH table */
initialized
=
1
;
}
...
...
@@ -141,31 +143,33 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
union
nfsctl_res
*
res
=
NULL
;
int
err
;
MOD_INC_USE_COUNT
;
lock_kernel
();
if
(
!
initialized
)
nfsd_init
();
err
=
-
EPERM
;
if
(
!
suser
())
{
err
=
-
EPERM
;
goto
done
;
}
err
=
-
EFAULT
;
if
(
!
access_ok
(
VERIFY_READ
,
argp
,
sizeof
(
*
argp
))
||
(
resp
&&
!
access_ok
(
VERIFY_WRITE
,
resp
,
sizeof
(
*
resp
))))
{
err
=
-
EFAULT
;
goto
done
;
}
err
=
-
ENOMEM
;
/* ??? */
if
(
!
(
arg
=
kmalloc
(
sizeof
(
*
arg
),
GFP_USER
))
||
(
resp
&&
!
(
res
=
kmalloc
(
sizeof
(
*
res
),
GFP_USER
))))
{
err
=
-
ENOMEM
;
/* ??? */
goto
done
;
}
err
=
-
EINVAL
;
copy_from_user
(
arg
,
argp
,
sizeof
(
*
argp
));
if
(
arg
->
ca_version
!=
NFSCTL_VERSION
)
{
printk
(
KERN_WARNING
"nfsd: incompatible version in syscall.
\n
"
);
err
=
-
EINVAL
;
goto
done
;
}
MOD_INC_USE_COUNT
;
switch
(
cmd
)
{
case
NFSCTL_SVC
:
err
=
nfsctl_svc
(
&
arg
->
ca_svc
);
...
...
@@ -193,7 +197,6 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
default:
err
=
-
EINVAL
;
}
MOD_DEC_USE_COUNT
;
if
(
!
err
&&
resp
)
copy_to_user
(
resp
,
res
,
sizeof
(
*
resp
));
...
...
@@ -205,6 +208,7 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
kfree
(
res
);
unlock_kernel
();
MOD_DEC_USE_COUNT
;
return
err
;
}
...
...
@@ -224,7 +228,6 @@ int
init_module
(
void
)
{
printk
(
"Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
\n
"
);
nfsd_init
();
do_nfsservctl
=
handle_sys_nfsservctl
;
return
0
;
}
...
...
@@ -242,6 +245,7 @@ cleanup_module(void)
do_nfsservctl
=
NULL
;
nfsd_export_shutdown
();
nfsd_cache_shutdown
();
nfsd_fh_free
();
#ifdef CONFIG_PROC_FS
nfsd_stat_shutdown
();
#endif
...
...
fs/nfsd/nfsfh.c
View file @
7f98bfdb
This diff is collapsed.
Click to expand it.
fs/nfsd/nfsproc.c
View file @
7f98bfdb
...
...
@@ -78,6 +78,8 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
/*
* Look up a path name component
* Note: the dentry in the resp->fh may be negative if the file
* doesn't exist yet.
* N.B. After this call resp->fh needs an fh_put
*/
static
int
...
...
@@ -88,10 +90,8 @@ nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
dprintk
(
"nfsd: LOOKUP %p %s
\n
"
,
SVCFH_DENTRY
(
&
argp
->
fh
),
argp
->
name
);
nfserr
=
nfsd_lookup
(
rqstp
,
&
argp
->
fh
,
argp
->
name
,
argp
->
len
,
&
resp
->
fh
);
nfserr
=
nfsd_lookup
(
rqstp
,
&
argp
->
fh
,
argp
->
name
,
argp
->
len
,
&
resp
->
fh
);
fh_put
(
&
argp
->
fh
);
RETURN
(
nfserr
);
...
...
@@ -209,11 +209,10 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
nfserr
=
fh_verify
(
rqstp
,
dirfhp
,
S_IFDIR
,
MAY_EXEC
);
if
(
nfserr
)
goto
done
;
/* must fh_put dirfhp even on error */
dirp
=
dirfhp
->
fh_
handle
.
fh_
dentry
->
d_inode
;
dirp
=
dirfhp
->
fh_dentry
->
d_inode
;
/* Check for MAY_WRITE separately. */
nfserr
=
nfsd_permission
(
dirfhp
->
fh_export
,
dirfhp
->
fh_handle
.
fh_dentry
,
nfserr
=
nfsd_permission
(
dirfhp
->
fh_export
,
dirfhp
->
fh_dentry
,
MAY_WRITE
);
if
(
nfserr
==
nfserr_rofs
)
{
rdonly
=
1
;
/* Non-fatal error for echo > /dev/null */
...
...
@@ -224,7 +223,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
exists
=
!
nfsd_lookup
(
rqstp
,
dirfhp
,
argp
->
name
,
argp
->
len
,
newfhp
);
if
(
newfhp
->
fh_dverified
)
inode
=
newfhp
->
fh_
handle
.
fh_
dentry
->
d_inode
;
inode
=
newfhp
->
fh_dentry
->
d_inode
;
/* Get rid of this soon... */
if
(
exists
&&
!
inode
)
{
...
...
fs/nfsd/nfsxdr.c
View file @
7f98bfdb
...
...
@@ -363,7 +363,7 @@ int
nfssvc_encode_attrstat
(
struct
svc_rqst
*
rqstp
,
u32
*
p
,
struct
nfsd_attrstat
*
resp
)
{
if
(
!
(
p
=
encode_fattr
(
rqstp
,
p
,
resp
->
fh
.
fh_
handle
.
fh_
dentry
->
d_inode
)))
if
(
!
(
p
=
encode_fattr
(
rqstp
,
p
,
resp
->
fh
.
fh_dentry
->
d_inode
)))
return
0
;
return
xdr_ressize_check
(
rqstp
,
p
);
}
...
...
@@ -373,7 +373,7 @@ nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
struct
nfsd_diropres
*
resp
)
{
if
(
!
(
p
=
encode_fh
(
p
,
&
resp
->
fh
))
||
!
(
p
=
encode_fattr
(
rqstp
,
p
,
resp
->
fh
.
fh_
handle
.
fh_
dentry
->
d_inode
)))
||
!
(
p
=
encode_fattr
(
rqstp
,
p
,
resp
->
fh
.
fh_dentry
->
d_inode
)))
return
0
;
return
xdr_ressize_check
(
rqstp
,
p
);
}
...
...
@@ -391,7 +391,7 @@ int
nfssvc_encode_readres
(
struct
svc_rqst
*
rqstp
,
u32
*
p
,
struct
nfsd_readres
*
resp
)
{
if
(
!
(
p
=
encode_fattr
(
rqstp
,
p
,
resp
->
fh
.
fh_
handle
.
fh_
dentry
->
d_inode
)))
if
(
!
(
p
=
encode_fattr
(
rqstp
,
p
,
resp
->
fh
.
fh_dentry
->
d_inode
)))
return
0
;
*
p
++
=
htonl
(
resp
->
count
);
p
+=
XDR_QUADLEN
(
resp
->
count
);
...
...
fs/nfsd/vfs.c
View file @
7f98bfdb
...
...
@@ -36,6 +36,8 @@
#include <asm/uaccess.h>
#endif
extern
void
fh_update
(
struct
svc_fh
*
);
#define NFSDDBG_FACILITY NFSDDBG_FILEOP
/* Open mode for nfsd_open */
...
...
@@ -108,10 +110,11 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
dprintk
(
"nfsd: nfsd_lookup(fh %p, %s)
\n
"
,
SVCFH_DENTRY
(
fhp
),
name
);
/* Obtain dentry and export. */
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFDIR
,
MAY_NOP
))
!=
0
)
return
err
;
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFDIR
,
MAY_NOP
);
if
(
err
)
goto
out
;
dparent
=
fhp
->
fh_
handle
.
fh_
dentry
;
dparent
=
fhp
->
fh_dentry
;
exp
=
fhp
->
fh_export
;
/* Fast path... */
...
...
@@ -121,11 +124,16 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
!
nfsd_iscovered
(
dparent
,
exp
))
{
struct
dentry
*
dchild
;
dchild
=
lookup_dentry
(
name
,
dget
(
dparent
),
1
);
/* Lookup the name, but don't follow links */
dchild
=
lookup_dentry
(
name
,
dget
(
dparent
),
0
);
err
=
PTR_ERR
(
dchild
);
if
(
IS_ERR
(
dchild
))
return
nfserrno
(
-
err
);
/*
* Note: we compose the filehandle now, but as the
* dentry may be negative, it may need to be updated.
*/
fh_compose
(
resfh
,
exp
,
dchild
);
return
(
dchild
->
d_inode
?
0
:
nfserr_noent
);
}
...
...
@@ -135,6 +143,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
return
nfserr_noent
;
if
(
nfsd_iscovered
(
dparent
,
exp
))
return
nfserr_acces
;
out:
return
err
;
}
...
...
@@ -158,10 +167,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap)
ftype
=
S_IFREG
;
/* Get inode */
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
ftype
,
accmode
))
!=
0
)
return
err
;
err
=
fh_verify
(
rqstp
,
fhp
,
ftype
,
accmode
);
if
(
err
)
goto
out
;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry
=
fhp
->
fh_dentry
;
inode
=
dentry
->
d_inode
;
/* The size case is special... */
...
...
@@ -169,7 +179,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap)
if
(
iap
->
ia_size
<
inode
->
i_size
)
{
err
=
nfsd_permission
(
fhp
->
fh_export
,
dentry
,
MAY_TRUNC
);
if
(
err
!=
0
)
return
err
;
goto
out
;
}
if
((
err
=
get_write_access
(
inode
))
!=
0
)
return
nfserrno
(
-
err
);
...
...
@@ -211,8 +221,9 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap)
if
(
EX_ISSYNC
(
fhp
->
fh_export
))
write_inode_now
(
inode
);
}
return
0
;
err
=
0
;
out:
return
err
;
}
/*
...
...
@@ -230,20 +241,23 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
access
=
wflag
?
MAY_WRITE
:
MAY_READ
;
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
type
,
access
))
!=
0
)
return
err
;
goto
out
;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry
=
fhp
->
fh_dentry
;
inode
=
dentry
->
d_inode
;
/* Disallow access to files with the append-only bit set or
* with mandatory locking enabled */
err
=
nfserr_perm
;
if
(
IS_APPEND
(
inode
)
||
IS_ISMNDLK
(
inode
))
return
nfserr_perm
;
goto
out
;
if
(
!
inode
->
i_op
||
!
inode
->
i_op
->
default_file_ops
)
return
nfserr_perm
;
goto
out
;
if
(
wflag
&&
(
err
=
get_write_access
(
inode
))
!=
0
)
return
nfserrno
(
-
err
);
if
(
wflag
&&
(
err
=
get_write_access
(
inode
))
!=
0
)
{
err
=
nfserrno
(
-
err
);
goto
out
;
}
memset
(
filp
,
0
,
sizeof
(
*
filp
));
filp
->
f_op
=
inode
->
i_op
->
default_file_ops
;
...
...
@@ -252,6 +266,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
filp
->
f_mode
=
wflag
?
FMODE_WRITE
:
FMODE_READ
;
filp
->
f_dentry
=
dentry
;
err
=
0
;
if
(
filp
->
f_op
->
open
)
{
err
=
filp
->
f_op
->
open
(
inode
,
filp
);
if
(
err
)
{
...
...
@@ -262,11 +277,11 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
* is really on callers stack frame. -DaveM
*/
filp
->
f_count
--
;
return
nfserrno
(
-
err
);
err
=
nfserrno
(
-
err
);
}
}
return
0
;
out:
return
err
;
}
/*
...
...
@@ -281,7 +296,8 @@ nfsd_close(struct file *filp)
if
(
!
inode
->
i_count
)
printk
(
KERN_WARNING
"nfsd: inode count == 0!
\n
"
);
if
(
!
dentry
->
d_count
)
printk
(
KERN_WARNING
"nfsd: wheee, dentry count == 0!
\n
"
);
printk
(
KERN_WARNING
"nfsd: wheee, %s/%s d_count == 0!
\n
"
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
);
if
(
filp
->
f_op
&&
filp
->
f_op
->
release
)
filp
->
f_op
->
release
(
inode
,
filp
);
if
(
filp
->
f_mode
&
FMODE_WRITE
)
...
...
@@ -299,6 +315,9 @@ nfsd_sync(struct inode *inode, struct file *filp)
/*
* Obtain the readahead parameters for the given file
*
* N.B. is raparm cache for a file cleared when the file closes??
* (dentry might be reused later.)
*/
static
inline
struct
raparms
*
nfsd_get_raparms
(
struct
dentry
*
dentry
)
...
...
@@ -506,39 +525,53 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct
inode
*
dirp
;
int
err
;
err
=
nfserr_perm
;
if
(
!
flen
)
return
nfserr_perm
;
goto
out
;
if
(
!
(
iap
->
ia_valid
&
ATTR_MODE
))
iap
->
ia_mode
=
0
;
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFDIR
,
MAY_CREATE
))
!=
0
)
return
err
;
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFDIR
,
MAY_CREATE
);
if
(
err
)
goto
out
;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry
=
fhp
->
fh_dentry
;
dirp
=
dentry
->
d_inode
;
/* Get all the sanity checks out of the way before we lock the parent. */
if
(
!
dirp
->
i_op
||
!
dirp
->
i_op
->
lookup
)
{
return
nfserrno
(
-
ENOTDIR
);
}
else
if
(
type
==
S_IFREG
)
{
err
=
nfserr_notdir
;
if
(
!
dirp
->
i_op
||
!
dirp
->
i_op
->
lookup
)
goto
out
;
err
=
nfserr_perm
;
if
(
type
==
S_IFREG
)
{
if
(
!
dirp
->
i_op
->
create
)
return
nfserr_perm
;
goto
out
;
}
else
if
(
type
==
S_IFDIR
)
{
if
(
!
dirp
->
i_op
->
mkdir
)
return
nfserr_perm
;
goto
out
;
}
else
if
((
type
==
S_IFCHR
)
||
(
type
==
S_IFBLK
)
||
(
type
==
S_IFIFO
))
{
if
(
!
dirp
->
i_op
->
mknod
)
return
nfserr_perm
;
goto
out
;
}
else
{
return
nfserr_perm
;
goto
out
;
}
if
(
!
resfhp
->
fh_dverified
)
{
/*
* The response filehandle may have been setup already ...
*/
if
(
!
resfhp
->
fh_dverified
)
{
dchild
=
lookup_dentry
(
fname
,
dget
(
dentry
),
0
);
err
=
PTR_ERR
(
dchild
);
if
(
IS_ERR
(
dchild
))
return
nfserrno
(
-
err
);
}
else
dchild
=
resfhp
->
fh_handle
.
fh_dentry
;
dchild
=
resfhp
->
fh_dentry
;
/*
* Make sure the child dentry is still negative ...
*/
if
(
dchild
->
d_inode
)
{
printk
(
"nfsd_create: dentry %s/%s not negative!
\n
"
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
);
}
/* Looks good, lock the directory. */
fh_lock
(
fhp
);
...
...
@@ -562,9 +595,15 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
if
(
EX_ISSYNC
(
fhp
->
fh_export
))
write_inode_now
(
dirp
);
/* If needed, assemble the file handle for the newly created file. */
if
(
!
resfhp
->
fh_dverified
)
/*
* Assemble the file handle for the newly created file,
* or update the filehandle to get the new inode info.
*/
if
(
!
resfhp
->
fh_dverified
)
{
fh_compose
(
resfhp
,
fhp
->
fh_export
,
dchild
);
}
else
{
fh_update
(
resfhp
);
}
/* Set file attributes. Mode has already been set and
* setting uid/gid works only for root. Irix appears to
...
...
@@ -574,7 +613,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
err
=
0
;
if
((
iap
->
ia_valid
&=
(
ATTR_UID
|
ATTR_GID
|
ATTR_MODE
))
!=
0
)
err
=
nfsd_setattr
(
rqstp
,
resfhp
,
iap
);
out:
return
err
;
}
...
...
@@ -597,7 +636,7 @@ nfsd_truncate(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned long size)
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFREG
,
MAY_WRITE
|
MAY_TRUNC
))
!=
0
)
return
err
;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry
=
fhp
->
fh_dentry
;
inode
=
dentry
->
d_inode
;
if
((
err
=
get_write_access
(
inode
))
!=
0
)
...
...
@@ -635,7 +674,7 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFLNK
,
MAY_READ
))
!=
0
)
return
err
;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry
=
fhp
->
fh_dentry
;
inode
=
dentry
->
d_inode
;
if
(
!
inode
->
i_op
||
!
inode
->
i_op
->
readlink
)
...
...
@@ -673,7 +712,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFDIR
,
MAY_CREATE
))
!=
0
)
return
err
;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry
=
fhp
->
fh_dentry
;
dirp
=
dentry
->
d_inode
;
if
(
nfsd_iscovered
(
dentry
,
fhp
->
fh_export
)
||
...
...
@@ -720,7 +759,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
(
err
=
fh_verify
(
rqstp
,
tfhp
,
S_IFREG
,
MAY_NOP
))
!=
0
)
return
err
;
ddir
=
ffhp
->
fh_
handle
.
fh_
dentry
;
ddir
=
ffhp
->
fh_dentry
;
dirp
=
ddir
->
d_inode
;
dnew
=
lookup_dentry
(
fname
,
dget
(
ddir
),
1
);
...
...
@@ -731,7 +770,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
err
=
-
EEXIST
;
if
(
dnew
->
d_inode
)
goto
dput_and_out
;
dest
=
tfhp
->
fh_
handle
.
fh_
dentry
->
d_inode
;
dest
=
tfhp
->
fh_dentry
->
d_inode
;
err
=
-
EPERM
;
if
(
!
len
)
...
...
@@ -794,10 +833,10 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
||
(
err
=
fh_verify
(
rqstp
,
tfhp
,
S_IFDIR
,
MAY_CREATE
))
!=
0
)
return
err
;
fdentry
=
ffhp
->
fh_
handle
.
fh_
dentry
;
fdentry
=
ffhp
->
fh_dentry
;
fdir
=
fdentry
->
d_inode
;
tdentry
=
tfhp
->
fh_
handle
.
fh_
dentry
;
tdentry
=
tfhp
->
fh_dentry
;
tdir
=
tdentry
->
d_inode
;
if
(
!
flen
||
(
fname
[
0
]
==
'.'
&&
...
...
@@ -816,6 +855,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
if
(
IS_ERR
(
ndentry
))
goto
out_dput_old
;
/* N.B. check this ... problems in locking?? */
nfsd_double_down
(
&
tdir
->
i_sem
,
&
fdir
->
i_sem
);
err
=
-
EXDEV
;
if
(
fdir
->
i_dev
!=
tdir
->
i_dev
)
...
...
@@ -856,7 +896,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
S_IFDIR
,
MAY_REMOVE
))
!=
0
)
return
err
;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry
=
fhp
->
fh_dentry
;
dirp
=
dentry
->
d_inode
;
rdentry
=
lookup_dentry
(
fname
,
dget
(
dentry
),
0
);
...
...
@@ -975,20 +1015,24 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct statfs *stat)
unsigned
long
oldfs
;
int
err
;
if
((
err
=
fh_verify
(
rqstp
,
fhp
,
0
,
MAY_NOP
))
!=
0
)
return
err
;
dentry
=
fhp
->
fh_handle
.
fh_dentry
;
err
=
fh_verify
(
rqstp
,
fhp
,
0
,
MAY_NOP
);
if
(
err
)
goto
out
;
dentry
=
fhp
->
fh_dentry
;
inode
=
dentry
->
d_inode
;
err
=
nfserr_io
;
if
(
!
(
sb
=
inode
->
i_sb
)
||
!
sb
->
s_op
->
statfs
)
return
nfserr_io
;
goto
out
;
oldfs
=
get_fs
();
set_fs
(
KERNEL_DS
);
sb
->
s_op
->
statfs
(
sb
,
stat
,
sizeof
(
*
stat
));
set_fs
(
oldfs
);
err
=
0
;
return
0
;
out:
return
err
;
}
/*
...
...
fs/select.c
View file @
7f98bfdb
...
...
@@ -328,6 +328,17 @@ asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct
zero_fd_set
(
n
,
&
fds
->
res_out
);
zero_fd_set
(
n
,
&
fds
->
res_ex
);
error
=
do_select
(
n
,
fds
,
wait
);
if
(
tvp
&&
!
(
current
->
personality
&
STICKY_TIMEOUTS
))
{
unsigned
long
timeout
=
current
->
timeout
-
jiffies
-
1
;
unsigned
long
sec
=
0
,
usec
=
0
;
if
((
long
)
timeout
>
0
)
{
sec
=
timeout
/
HZ
;
usec
=
timeout
%
HZ
;
usec
*=
(
1000000
/
HZ
);
}
put_user
(
sec
,
&
tvp
->
tv_sec
);
put_user
(
usec
,
&
tvp
->
tv_usec
);
}
current
->
timeout
=
0
;
if
(
error
<
0
)
goto
out
;
...
...
include/asm-alpha/softirq.h
View file @
7f98bfdb
...
...
@@ -14,7 +14,7 @@ static inline void clear_active_bhs(unsigned long x)
unsigned
long
temp
;
__asm__
__volatile__
(
"1: ldq_l %0,%1
\n
"
"
and
%0,%2,%0
\n
"
"
bic
%0,%2,%0
\n
"
" stq_c %0,%1
\n
"
" beq %0,2f
\n
"
".section .text2,
\"
ax
\"\n
"
...
...
include/linux/nfsd/nfsfh.h
View file @
7f98bfdb
...
...
@@ -27,12 +27,12 @@
* ino/dev of the exported inode.
*/
struct
nfs_fhbase
{
struct
dentry
*
fb_dentry
;
struct
dentry
*
fb_dparent
;
unsigned
int
fb_dhash
;
unsigned
int
fb_dlen
;
ino_t
fb_xino
;
struct
dentry
*
fb_dentry
;
/* dentry cookie */
ino_t
fb_ino
;
/* our inode number */
ino_t
fb_dirino
;
/* dir inode number */
dev_t
fb_dev
;
/* our device */
dev_t
fb_xdev
;
ino_t
fb_xino
;
};
#define NFS_FH_PADDING (NFS_FHSIZE - sizeof(struct nfs_fhbase))
...
...
@@ -41,13 +41,12 @@ struct knfs_fh {
__u8
fh_cookie
[
NFS_FH_PADDING
];
};
#define fh_dentry fh_base.fb_dentry
#define fh_dparent fh_base.fb_dparent
#define fh_dhash fh_base.fb_dhash
#define fh_dlen fh_base.fb_dlen
#define fh_xino fh_base.fb_xino
#define fh_dcookie fh_base.fb_dentry
#define fh_ino fh_base.fb_ino
#define fh_dirino fh_base.fb_dirino
#define fh_dev fh_base.fb_dev
#define fh_xdev fh_base.fb_xdev
#define fh_xino fh_base.fb_xino
#ifdef __KERNEL__
...
...
@@ -57,6 +56,7 @@ struct knfs_fh {
*/
typedef
struct
svc_fh
{
struct
knfs_fh
fh_handle
;
/* FH data */
struct
dentry
*
fh_dentry
;
/* validated dentry */
struct
svc_export
*
fh_export
;
/* export pointer */
size_t
fh_pre_size
;
/* size before operation */
time_t
fh_pre_mtime
;
/* mtime before oper */
...
...
@@ -69,17 +69,26 @@ typedef struct svc_fh {
/*
* Shorthand for dprintk()'s
*/
#define SVCFH_DENTRY(f) ((f)->fh_
handle.fh_
dentry)
#define SVCFH_DENTRY(f) ((f)->fh_dentry)
/*
* Function prototypes
*/
u32
fh_verify
(
struct
svc_rqst
*
,
struct
svc_fh
*
,
int
,
int
);
void
fh_compose
(
struct
svc_fh
*
,
struct
svc_export
*
,
struct
dentry
*
);
u32
fh_verify
(
struct
svc_rqst
*
,
struct
svc_fh
*
,
int
,
int
);
void
fh_compose
(
struct
svc_fh
*
,
struct
svc_export
*
,
struct
dentry
*
);
void
fh_put
(
struct
svc_fh
*
);
void
nfsd_fh_init
(
void
);
void
nfsd_fh_free
(
void
);
static
__inline__
struct
svc_fh
*
fh_copy
(
struct
svc_fh
*
dst
,
struct
svc_fh
*
src
)
{
if
(
src
->
fh_dverified
)
{
struct
dentry
*
dentry
=
src
->
fh_dentry
;
printk
(
"fh_copy: copying %s/%s, already verified!
\n
"
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
);
}
*
dst
=
*
src
;
return
dst
;
}
...
...
@@ -97,7 +106,7 @@ fh_init(struct svc_fh *fhp)
static
inline
void
fh_lock
(
struct
svc_fh
*
fhp
)
{
struct
inode
*
inode
=
fhp
->
fh_
handle
.
fh_
dentry
->
d_inode
;
struct
inode
*
inode
=
fhp
->
fh_dentry
->
d_inode
;
/*
dfprintk(FILEOP, "nfsd: fh_lock(%x/%ld) locked = %d\n",
...
...
@@ -117,7 +126,7 @@ fh_lock(struct svc_fh *fhp)
static
inline
void
fh_unlock
(
struct
svc_fh
*
fhp
)
{
struct
inode
*
inode
=
fhp
->
fh_
handle
.
fh_
dentry
->
d_inode
;
struct
inode
*
inode
=
fhp
->
fh_dentry
->
d_inode
;
if
(
fhp
->
fh_locked
)
{
if
(
!
fhp
->
fh_post_version
)
...
...
@@ -130,17 +139,7 @@ fh_unlock(struct svc_fh *fhp)
/*
* Release an inode
*/
#ifndef NFSD_DEBUG
static
inline
void
fh_put
(
struct
svc_fh
*
fhp
)
{
if
(
fhp
->
fh_dverified
)
{
fh_unlock
(
fhp
);
dput
(
fhp
->
fh_handle
.
fh_dentry
);
fhp
->
fh_dverified
=
0
;
}
}
#else
#if 0
#define fh_put(fhp) __fh_put(fhp, __FILE__, __LINE__)
static inline void
...
...
@@ -151,7 +150,7 @@ __fh_put(struct svc_fh *fhp, char *file, int line)
if (!fhp->fh_dverified)
return;
dentry
=
fhp
->
fh_
handle
.
fh_
dentry
;
dentry = fhp->fh_dentry;
if (!dentry->d_count) {
printk("nfsd: trying to free free dentry in %s:%d\n"
" file %s/%s\n",
...
...
@@ -159,14 +158,12 @@ __fh_put(struct svc_fh *fhp, char *file, int line)
dentry->d_parent->d_name.name, dentry->d_name.name);
} else {
fh_unlock(fhp);
dput
(
dentry
);
fhp->fh_dverified = 0;
dput(dentry);
}
}
#endif
#endif
/* __KERNEL__ */
#endif
/* NFSD_FH_H */
net/sunrpc/svcsock.c
View file @
7f98bfdb
...
...
@@ -766,7 +766,6 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp)
}
}
printk
(
"svc_recv: svsk=%p, use count=%d
\n
"
,
svsk
,
svsk
->
sk_inuse
);
dprintk
(
"svc: server %p servicing socket %p
\n
"
,
rqstp
,
svsk
);
len
=
svsk
->
sk_recvfrom
(
rqstp
);
...
...
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