Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
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
Hide 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
);
/* We cannot find the parent,
It better just *be* there */
if
(
parent
)
if
(
parent
)
return
NULL
;
/* We cannot find the parent,
return
ERR_PTR
(
-
ESTALE
);
It better just *be* there */
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
);
unlock_kernel
();
}
else
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