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
acb977dc
Commit
acb977dc
authored
Feb 17, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge home.transmeta.com:/home/torvalds/v2.5/knfsd
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
222099f6
c0d68f59
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
95 additions
and
114 deletions
+95
-114
fs/fat/inode.c
fs/fat/inode.c
+5
-4
fs/filesystems.c
fs/filesystems.c
+11
-11
fs/nfsd/export.c
fs/nfsd/export.c
+17
-27
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3proc.c
+1
-1
fs/nfsd/nfsctl.c
fs/nfsd/nfsctl.c
+20
-27
fs/nfsd/vfs.c
fs/nfsd/vfs.c
+40
-44
include/linux/nfsd/interface.h
include/linux/nfsd/interface.h
+1
-0
No files found.
fs/fat/inode.c
View file @
acb977dc
...
@@ -430,12 +430,13 @@ struct dentry *fat_fh_to_dentry(struct super_block *sb, __u32 *fh,
...
@@ -430,12 +430,13 @@ struct dentry *fat_fh_to_dentry(struct super_block *sb, __u32 *fh,
struct
dentry
*
result
;
struct
dentry
*
result
;
if
(
fhtype
!=
3
)
if
(
fhtype
!=
3
)
return
NULL
;
return
ERR_PTR
(
-
ESTALE
)
;
if
(
len
<
5
)
if
(
len
<
5
)
return
NULL
;
return
ERR_PTR
(
-
ESTALE
);
if
(
parent
)
/* We cannot find the parent,
return
NULL
;
/* We cannot find the parent,
It better just *be* there */
It better just *be* there */
if
(
parent
)
return
ERR_PTR
(
-
ESTALE
);
inode
=
iget
(
sb
,
fh
[
0
]);
inode
=
iget
(
sb
,
fh
[
0
]);
if
(
!
inode
||
is_bad_inode
(
inode
)
||
if
(
!
inode
||
is_bad_inode
(
inode
)
||
...
...
fs/filesystems.c
View file @
acb977dc
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
*
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1991, 1992 Linus Torvalds
*
*
*
table of configured filesystems
*
nfsservctl system-call when nfsd is not compiled in.
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
@@ -14,28 +14,28 @@
...
@@ -14,28 +14,28 @@
#include <linux/nfsd/interface.h>
#include <linux/nfsd/interface.h>
#include <linux/linkage.h>
#include <linux/linkage.h>
#if
defined(CONFIG_NFSD_MODULE
)
#if
! defined(CONFIG_NFSD
)
struct
nfsd_linkage
*
nfsd_linkage
=
NULL
;
struct
nfsd_linkage
*
nfsd_linkage
;
long
long
asmlinkage
sys_nfsservctl
(
int
cmd
,
void
*
argp
,
void
*
resp
)
asmlinkage
sys_nfsservctl
(
int
cmd
,
void
*
argp
,
void
*
resp
)
{
{
int
ret
=
-
ENOSYS
;
int
ret
=
-
ENOSYS
;
#if defined(CONFIG_MODULES)
lock_kernel
();
lock_kernel
();
if
(
nfsd_linkage
||
if
(
nfsd_linkage
||
(
request_module
(
"nfsd"
)
==
0
&&
nfsd_linkage
))
(
request_module
(
"nfsd"
)
==
0
&&
nfsd_linkage
))
{
__MOD_INC_USE_COUNT
(
nfsd_linkage
->
owner
);
unlock_kernel
();
ret
=
nfsd_linkage
->
do_nfsservctl
(
cmd
,
argp
,
resp
);
ret
=
nfsd_linkage
->
do_nfsservctl
(
cmd
,
argp
,
resp
);
__MOD_DEC_USE_COUNT
(
nfsd_linkage
->
owner
);
}
else
unlock_kernel
();
unlock_kernel
();
#endif
return
ret
;
return
ret
;
}
}
EXPORT_SYMBOL
(
nfsd_linkage
);
EXPORT_SYMBOL
(
nfsd_linkage
);
#elif ! defined (CONFIG_NFSD)
asmlinkage
int
sys_nfsservctl
(
int
cmd
,
void
*
argp
,
void
*
resp
)
{
return
-
ENOSYS
;
}
#endif
/* CONFIG_NFSD */
#endif
/* CONFIG_NFSD */
fs/nfsd/export.c
View file @
acb977dc
...
@@ -59,7 +59,6 @@ struct svc_clnthash {
...
@@ -59,7 +59,6 @@ struct svc_clnthash {
};
};
static
struct
svc_clnthash
*
clnt_hash
[
CLIENT_HASHMAX
];
static
struct
svc_clnthash
*
clnt_hash
[
CLIENT_HASHMAX
];
static
svc_client
*
clients
;
static
svc_client
*
clients
;
static
int
initialized
;
static
int
hash_lock
;
static
int
hash_lock
;
static
int
want_lock
;
static
int
want_lock
;
...
@@ -73,18 +72,17 @@ svc_export *
...
@@ -73,18 +72,17 @@ svc_export *
exp_get
(
svc_client
*
clp
,
kdev_t
dev
,
ino_t
ino
)
exp_get
(
svc_client
*
clp
,
kdev_t
dev
,
ino_t
ino
)
{
{
struct
list_head
*
head
,
*
p
;
struct
list_head
*
head
,
*
p
;
svc_export
*
exp
=
NULL
;
if
(
!
clp
)
if
(
!
clp
)
return
NULL
;
return
NULL
;
head
=
&
clp
->
cl_export
[
EXPORT_HASH
(
dev
)];
head
=
&
clp
->
cl_export
[
EXPORT_HASH
(
dev
)];
list_for_each
(
p
,
head
)
{
list_for_each
(
p
,
head
)
{
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
svc_export
*
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
if
(
exp
->
ex_ino
==
ino
&&
kdev_same
(
exp
->
ex_dev
,
dev
))
if
(
exp
->
ex_ino
==
ino
&&
kdev_same
(
exp
->
ex_dev
,
dev
))
break
;
}
return
exp
;
return
exp
;
}
return
NULL
;
}
}
svc_export
*
svc_export
*
...
@@ -92,18 +90,17 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry)
...
@@ -92,18 +90,17 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry)
{
{
struct
list_head
*
head
,
*
p
;
struct
list_head
*
head
,
*
p
;
int
hash
=
EXPORT_HASH
(
mnt
->
mnt_sb
->
s_dev
);
int
hash
=
EXPORT_HASH
(
mnt
->
mnt_sb
->
s_dev
);
svc_export
*
exp
=
NULL
;
if
(
!
clp
)
if
(
!
clp
)
return
NULL
;
return
NULL
;
head
=
&
clp
->
cl_export
[
hash
];
head
=
&
clp
->
cl_export
[
hash
];
list_for_each
(
p
,
head
)
{
list_for_each
(
p
,
head
)
{
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
svc_export
*
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
if
(
exp
->
ex_dentry
==
dentry
&&
exp
->
ex_mnt
==
mnt
)
if
(
exp
->
ex_dentry
==
dentry
&&
exp
->
ex_mnt
==
mnt
)
break
;
break
;
}
}
return
exp
;
return
NULL
;
}
}
/*
/*
...
@@ -114,14 +111,13 @@ exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry)
...
@@ -114,14 +111,13 @@ exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry)
{
{
struct
list_head
*
head
=
&
clp
->
cl_export
[
EXPORT_HASH
(
sb
->
s_dev
)];
struct
list_head
*
head
=
&
clp
->
cl_export
[
EXPORT_HASH
(
sb
->
s_dev
)];
struct
list_head
*
p
;
struct
list_head
*
p
;
svc_export
*
exp
=
NULL
;
list_for_each
(
p
,
head
)
{
list_for_each
(
p
,
head
)
{
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
svc_export
*
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
if
(
is_subdir
(
dentry
,
exp
->
ex_dentry
))
if
(
is_subdir
(
dentry
,
exp
->
ex_dentry
))
break
;
}
return
exp
;
return
exp
;
}
return
NULL
;
}
}
/*
/*
...
@@ -134,16 +130,15 @@ exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry)
...
@@ -134,16 +130,15 @@ exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry)
{
{
struct
list_head
*
head
=
&
clp
->
cl_export
[
EXPORT_HASH
(
sb
->
s_dev
)];
struct
list_head
*
head
=
&
clp
->
cl_export
[
EXPORT_HASH
(
sb
->
s_dev
)];
struct
list_head
*
p
;
struct
list_head
*
p
;
svc_export
*
exp
=
NULL
;
struct
dentry
*
ndentry
;
struct
dentry
*
ndentry
;
list_for_each
(
p
,
head
)
{
list_for_each
(
p
,
head
)
{
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
svc_export
*
exp
=
list_entry
(
p
,
svc_export
,
ex_hash
);
ndentry
=
exp
->
ex_dentry
;
ndentry
=
exp
->
ex_dentry
;
if
(
ndentry
&&
is_subdir
(
ndentry
->
d_parent
,
dentry
))
if
(
ndentry
&&
is_subdir
(
ndentry
->
d_parent
,
dentry
))
break
;
}
return
exp
;
return
exp
;
}
return
NULL
;
}
}
/* Update parent pointers of all exports */
/* Update parent pointers of all exports */
...
@@ -477,9 +472,6 @@ exp_getclient(struct sockaddr_in *sin)
...
@@ -477,9 +472,6 @@ exp_getclient(struct sockaddr_in *sin)
struct
svc_clnthash
**
hp
,
**
head
,
*
tmp
;
struct
svc_clnthash
**
hp
,
**
head
,
*
tmp
;
unsigned
long
addr
=
sin
->
sin_addr
.
s_addr
;
unsigned
long
addr
=
sin
->
sin_addr
.
s_addr
;
if
(
!
initialized
)
return
NULL
;
head
=
&
clnt_hash
[
CLIENT_HASH
(
addr
)];
head
=
&
clnt_hash
[
CLIENT_HASH
(
addr
)];
for
(
hp
=
head
;
(
tmp
=
*
hp
)
!=
NULL
;
hp
=
&
(
tmp
->
h_next
))
{
for
(
hp
=
head
;
(
tmp
=
*
hp
)
!=
NULL
;
hp
=
&
(
tmp
->
h_next
))
{
...
@@ -552,9 +544,10 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
...
@@ -552,9 +544,10 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
if
(
p
==
(
void
*
)
1
)
if
(
p
==
(
void
*
)
1
)
clp
=
clients
;
clp
=
clients
;
else
if
(
exp
->
ex_list
.
next
==
&
exp
->
ex_client
->
cl_list
)
else
if
(
exp
->
ex_list
.
next
==
&
exp
->
ex_client
->
cl_list
)
{
clp
=
exp
->
ex_client
->
cl_next
;
clp
=
exp
->
ex_client
->
cl_next
;
else
{
*
pos
+=
1LL
<<
32
;
}
else
{
++*
pos
;
++*
pos
;
return
list_entry
(
exp
->
ex_list
.
next
,
svc_export
,
ex_list
);
return
list_entry
(
exp
->
ex_list
.
next
,
svc_export
,
ex_list
);
}
}
...
@@ -875,13 +868,11 @@ nfsd_export_init(void)
...
@@ -875,13 +868,11 @@ nfsd_export_init(void)
int
i
;
int
i
;
dprintk
(
"nfsd: initializing export module.
\n
"
);
dprintk
(
"nfsd: initializing export module.
\n
"
);
if
(
initialized
)
return
;
for
(
i
=
0
;
i
<
CLIENT_HASHMAX
;
i
++
)
for
(
i
=
0
;
i
<
CLIENT_HASHMAX
;
i
++
)
clnt_hash
[
i
]
=
NULL
;
clnt_hash
[
i
]
=
NULL
;
clients
=
NULL
;
clients
=
NULL
;
initialized
=
1
;
}
}
/*
/*
...
@@ -893,8 +884,7 @@ nfsd_export_shutdown(void)
...
@@ -893,8 +884,7 @@ nfsd_export_shutdown(void)
int
i
;
int
i
;
dprintk
(
"nfsd: shutting down export module.
\n
"
);
dprintk
(
"nfsd: shutting down export module.
\n
"
);
if
(
!
initialized
)
return
;
if
(
exp_writelock
()
<
0
)
{
if
(
exp_writelock
()
<
0
)
{
printk
(
KERN_WARNING
"Weird: hashtable locked in exp_shutdown"
);
printk
(
KERN_WARNING
"Weird: hashtable locked in exp_shutdown"
);
return
;
return
;
...
...
fs/nfsd/nfs3proc.c
View file @
acb977dc
...
@@ -339,7 +339,7 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
...
@@ -339,7 +339,7 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
||
(
argp
->
ftype
==
NF3BLK
&&
argp
->
major
>=
MAX_BLKDEV
)
||
(
argp
->
ftype
==
NF3BLK
&&
argp
->
major
>=
MAX_BLKDEV
)
||
argp
->
minor
>
0xFF
)
||
argp
->
minor
>
0xFF
)
RETURN_STATUS
(
nfserr_inval
);
RETURN_STATUS
(
nfserr_inval
);
rdev
=
((
argp
->
major
)
<<
8
)
|
(
argp
->
minor
);
rdev
=
MKDEV
(
argp
->
major
,
argp
->
minor
);
}
else
}
else
if
(
argp
->
ftype
!=
NF3SOCK
&&
argp
->
ftype
!=
NF3FIFO
)
if
(
argp
->
ftype
!=
NF3SOCK
&&
argp
->
ftype
!=
NF3FIFO
)
RETURN_STATUS
(
nfserr_inval
);
RETURN_STATUS
(
nfserr_inval
);
...
...
fs/nfsd/nfsctl.c
View file @
acb977dc
...
@@ -44,8 +44,6 @@ static int nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *);
...
@@ -44,8 +44,6 @@ static int nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *);
static
int
nfsctl_ugidupdate
(
struct
nfsctl_ugidmap
*
data
);
static
int
nfsctl_ugidupdate
(
struct
nfsctl_ugidmap
*
data
);
#endif
#endif
static
int
initialized
;
extern
struct
seq_operations
nfs_exports_op
;
extern
struct
seq_operations
nfs_exports_op
;
static
int
exports_open
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
exports_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
...
@@ -68,20 +66,6 @@ void proc_export_init(void)
...
@@ -68,20 +66,6 @@ void proc_export_init(void)
entry
->
proc_fops
=
&
exports_operations
;
entry
->
proc_fops
=
&
exports_operations
;
}
}
/*
* Initialize nfsd
*/
static
void
nfsd_init
(
void
)
{
nfsd_stat_init
();
/* Statistics */
nfsd_cache_init
();
/* RPC reply cache */
nfsd_export_init
();
/* Exports table */
nfsd_lockd_init
();
/* lockd->nfsd callbacks */
proc_export_init
();
initialized
=
1
;
}
static
inline
int
static
inline
int
nfsctl_svc
(
struct
nfsctl_svc
*
data
)
nfsctl_svc
(
struct
nfsctl_svc
*
data
)
{
{
...
@@ -203,10 +187,8 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
...
@@ -203,10 +187,8 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
int
err
;
int
err
;
int
argsize
,
respsize
;
int
argsize
,
respsize
;
MOD_INC_USE_COUNT
;
lock_kernel
();
lock_kernel
();
if
(
!
initialized
)
nfsd_init
();
err
=
-
EPERM
;
err
=
-
EPERM
;
if
(
!
capable
(
CAP_SYS_ADMIN
))
{
if
(
!
capable
(
CAP_SYS_ADMIN
))
{
goto
done
;
goto
done
;
...
@@ -276,38 +258,47 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
...
@@ -276,38 +258,47 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
kfree
(
res
);
kfree
(
res
);
unlock_kernel
();
unlock_kernel
();
MOD_DEC_USE_COUNT
;
return
err
;
return
err
;
}
}
#ifdef MODULE
/* New-style module support since 2.1.18 */
EXPORT_NO_SYMBOLS
;
EXPORT_NO_SYMBOLS
;
MODULE_AUTHOR
(
"Olaf Kirch <okir@monad.swb.de>"
);
MODULE_AUTHOR
(
"Olaf Kirch <okir@monad.swb.de>"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
#ifdef MODULE
struct
nfsd_linkage
nfsd_linkage_s
=
{
struct
nfsd_linkage
nfsd_linkage_s
=
{
do_nfsservctl:
handle_sys_nfsservctl
,
do_nfsservctl:
handle_sys_nfsservctl
,
owner:
THIS_MODULE
,
};
};
#endif
/*
/*
* Initialize the module
* Initialize the module
*/
*/
in
t
static
int
__ini
t
init_module
(
void
)
nfsd_init
(
void
)
{
{
printk
(
KERN_INFO
"Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
\n
"
);
printk
(
KERN_INFO
"Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
\n
"
);
#ifdef MODULE
nfsd_linkage
=
&
nfsd_linkage_s
;
nfsd_linkage
=
&
nfsd_linkage_s
;
#endif
nfsd_stat_init
();
/* Statistics */
nfsd_cache_init
();
/* RPC reply cache */
nfsd_export_init
();
/* Exports table */
nfsd_lockd_init
();
/* lockd->nfsd callbacks */
proc_export_init
();
return
0
;
return
0
;
}
}
/*
/*
* Clean up the mess before unloading the module
* Clean up the mess before unloading the module
*/
*/
void
static
void
__exit
cleanup_module
(
void
)
nfsd_exit
(
void
)
{
{
#ifdef MODULE
nfsd_linkage
=
NULL
;
nfsd_linkage
=
NULL
;
#endif
nfsd_export_shutdown
();
nfsd_export_shutdown
();
nfsd_cache_shutdown
();
nfsd_cache_shutdown
();
remove_proc_entry
(
"fs/nfs/exports"
,
NULL
);
remove_proc_entry
(
"fs/nfs/exports"
,
NULL
);
...
@@ -315,4 +306,6 @@ cleanup_module(void)
...
@@ -315,4 +306,6 @@ cleanup_module(void)
nfsd_stat_shutdown
();
nfsd_stat_shutdown
();
nfsd_lockd_shutdown
();
nfsd_lockd_shutdown
();
}
}
#endif
module_init
(
nfsd_init
);
module_exit
(
nfsd_exit
);
fs/nfsd/vfs.c
View file @
acb977dc
...
@@ -209,36 +209,37 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
...
@@ -209,36 +209,37 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
dentry
=
fhp
->
fh_dentry
;
dentry
=
fhp
->
fh_dentry
;
inode
=
dentry
->
d_inode
;
inode
=
dentry
->
d_inode
;
err
=
inode_change_ok
(
inode
,
iap
);
/* NFSv2 does not differentiate between "set-[ac]time-to-now"
/* could be a "touch" (utimes) request where the user is not the owner but does
* which only requires access, and "set-[ac]time-to-X" which
* have write permission. In this case the user should be allowed to set
* requires ownership.
* both times to the current time. We could just assume any such SETATTR
* So if it looks like it might be "set both to the same time which
* is intended to set the times to "now", but we do a couple of simple tests
* is close to now", and if inode_change_ok fails, then we
* to increase our confidence.
* convert to "set to now" instead of "set to explicit time"
*
* We only call inode_change_ok as the last test as technically
* it is not an interface that we should be using. It is only
* valid if the filesystem does not define it's own i_op->setattr.
*/
*/
#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
#define MAX_TOUCH_TIME_ERROR (30*60)
#define MAX_TOUCH_TIME_ERROR (30*60)
if
(
err
if
((
iap
->
ia_valid
&
BOTH_TIME_SET
)
==
BOTH_TIME_SET
&&
(
iap
->
ia_valid
&
BOTH_TIME_SET
)
==
BOTH_TIME_SET
&&
iap
->
ia_mtime
==
iap
->
ia_atime
&&
iap
->
ia_mtime
==
iap
->
ia_atime
)
{
)
{
/* looks good. now just make sure time is in the right ballpark.
/* Looks probable. Now just make sure time is in the right ballpark.
* solaris, at least, doesn't seem to care what the time request is
* Solaris, at least, doesn't seem to care what the time request is.
* We require it be within 30 minutes of now.
*/
*/
time_t
delta
=
iap
->
ia_atime
-
CURRENT_TIME
;
time_t
delta
=
iap
->
ia_atime
-
CURRENT_TIME
;
if
(
delta
<
0
)
delta
=
-
delta
;
if
(
delta
<
0
)
delta
=
-
delta
;
if
(
delta
<
MAX_TOUCH_TIME_ERROR
)
{
if
(
delta
<
MAX_TOUCH_TIME_ERROR
&&
inode_change_ok
(
inode
,
iap
)
!=
0
)
{
/* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
/* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
* this will cause notify_change to set these times to "now"
* this will cause notify_change to set these times to "now"
*/
*/
iap
->
ia_valid
&=
~
BOTH_TIME_SET
;
iap
->
ia_valid
&=
~
BOTH_TIME_SET
;
err
=
inode_change_ok
(
inode
,
iap
);
}
}
}
}
if
(
err
)
goto
out_nfserr
;
/* The size case is special. It changes the file as well as the attributes. */
/* The size case is special. It changes the file as well as the attributes. */
if
(
iap
->
ia_valid
&
ATTR_SIZE
)
{
if
(
iap
->
ia_valid
&
ATTR_SIZE
)
{
if
(
iap
->
ia_size
<
inode
->
i_size
)
{
if
(
iap
->
ia_size
<
inode
->
i_size
)
{
...
@@ -511,24 +512,33 @@ nfsd_close(struct file *filp)
...
@@ -511,24 +512,33 @@ nfsd_close(struct file *filp)
* As this calls fsync (not fdatasync) there is no need for a write_inode
* As this calls fsync (not fdatasync) there is no need for a write_inode
* after it.
* after it.
*/
*/
inline
void
nfsd_dosync
(
struct
file
*
filp
,
struct
dentry
*
dp
,
struct
file_operations
*
fop
)
{
struct
inode
*
inode
=
dp
->
d_inode
;
int
(
*
fsync
)
(
struct
file
*
,
struct
dentry
*
,
int
);
filemap_fdatasync
(
inode
->
i_mapping
);
if
(
fop
&&
(
fsync
=
fop
->
fsync
))
fsync
(
filp
,
dp
,
0
);
filemap_fdatawait
(
inode
->
i_mapping
);
}
void
void
nfsd_sync
(
struct
file
*
filp
)
nfsd_sync
(
struct
file
*
filp
)
{
{
struct
inode
*
inode
=
filp
->
f_dentry
->
d_inode
;
dprintk
(
"nfsd: sync file %s
\n
"
,
filp
->
f_dentry
->
d_name
.
name
);
dprintk
(
"nfsd: sync file %s
\n
"
,
filp
->
f_dentry
->
d_name
.
name
);
down
(
&
filp
->
f_dentry
->
d_
inode
->
i_sem
);
down
(
&
inode
->
i_sem
);
filp
->
f_op
->
fsync
(
filp
,
filp
->
f_dentry
,
0
);
nfsd_dosync
(
filp
,
filp
->
f_dentry
,
filp
->
f_op
);
up
(
&
filp
->
f_dentry
->
d_
inode
->
i_sem
);
up
(
&
inode
->
i_sem
);
}
}
void
void
nfsd_sync_dir
(
struct
dentry
*
dp
)
nfsd_sync_dir
(
struct
dentry
*
dp
)
{
{
struct
inode
*
inode
=
dp
->
d_inode
;
nfsd_dosync
(
NULL
,
dp
,
dp
->
d_inode
->
i_fop
);
int
(
*
fsync
)
(
struct
file
*
,
struct
dentry
*
,
int
);
if
(
inode
->
i_fop
&&
(
fsync
=
inode
->
i_fop
->
fsync
))
{
fsync
(
NULL
,
dp
,
0
);
}
}
}
/*
/*
...
@@ -1382,7 +1392,6 @@ int
...
@@ -1382,7 +1392,6 @@ int
nfsd_readdir
(
struct
svc_rqst
*
rqstp
,
struct
svc_fh
*
fhp
,
loff_t
offset
,
nfsd_readdir
(
struct
svc_rqst
*
rqstp
,
struct
svc_fh
*
fhp
,
loff_t
offset
,
encode_dent_fn
func
,
u32
*
buffer
,
int
*
countp
,
u32
*
verf
)
encode_dent_fn
func
,
u32
*
buffer
,
int
*
countp
,
u32
*
verf
)
{
{
struct
inode
*
inode
;
u32
*
p
;
u32
*
p
;
int
oldlen
,
eof
,
err
;
int
oldlen
,
eof
,
err
;
struct
file
file
;
struct
file
file
;
...
@@ -1394,9 +1403,6 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
...
@@ -1394,9 +1403,6 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
if
(
offset
>
~
(
u32
)
0
)
if
(
offset
>
~
(
u32
)
0
)
goto
out_close
;
goto
out_close
;
err
=
nfserr_notdir
;
if
(
!
file
.
f_op
->
readdir
)
goto
out_close
;
file
.
f_pos
=
offset
;
file
.
f_pos
=
offset
;
/* Set up the readdir context */
/* Set up the readdir context */
...
@@ -1411,25 +1417,16 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
...
@@ -1411,25 +1417,16 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
* readdir() is not guaranteed to fill up the entire buffer, but
* readdir() is not guaranteed to fill up the entire buffer, but
* may choose to do less.
* may choose to do less.
*/
*/
inode
=
file
.
f_dentry
->
d_inode
;
down
(
&
inode
->
i_sem
);
do
{
while
(
1
)
{
oldlen
=
cd
.
buflen
;
oldlen
=
cd
.
buflen
;
/*
err
=
vfs_readdir
(
&
file
,
(
filldir_t
)
func
,
&
cd
);
dprintk("nfsd: f_op->readdir(%s/%ld @ %d) buflen = %d (%d)\n",
file.f_inode->i_sb->s_id, file.f_inode->i_ino,
(int) file.f_pos, (int) oldlen, (int) cd.buflen);
*/
err
=
file
.
f_op
->
readdir
(
&
file
,
&
cd
,
(
filldir_t
)
func
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
out_nfserr
;
goto
out_nfserr
;
if
(
oldlen
==
cd
.
buflen
)
break
;
}
while
(
oldlen
!=
cd
.
buflen
&&
!
cd
.
eob
);
if
(
cd
.
eob
)
break
;
}
up
(
&
inode
->
i_sem
);
/* If we didn't fill the buffer completely, we're at EOF */
/* If we didn't fill the buffer completely, we're at EOF */
eof
=
!
cd
.
eob
;
eof
=
!
cd
.
eob
;
...
@@ -1456,7 +1453,6 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
...
@@ -1456,7 +1453,6 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
return
err
;
return
err
;
out_nfserr:
out_nfserr:
up
(
&
inode
->
i_sem
);
err
=
nfserrno
(
err
);
err
=
nfserrno
(
err
);
goto
out_close
;
goto
out_close
;
}
}
...
...
include/linux/nfsd/interface.h
View file @
acb977dc
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
extern
struct
nfsd_linkage
{
extern
struct
nfsd_linkage
{
long
(
*
do_nfsservctl
)(
int
cmd
,
void
*
argp
,
void
*
resp
);
long
(
*
do_nfsservctl
)(
int
cmd
,
void
*
argp
,
void
*
resp
);
struct
module
*
owner
;
}
*
nfsd_linkage
;
}
*
nfsd_linkage
;
#endif
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment