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
f0152514
Commit
f0152514
authored
Feb 08, 2002
by
Alexander Viro
Committed by
Linus Torvalds
Feb 08, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] knfsd cleanups
exp_procfs_exports() switched to seq_..., missing lock added.
parent
5278b4c3
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
137 additions
and
115 deletions
+137
-115
fs/nfsd/export.c
fs/nfsd/export.c
+121
-111
fs/nfsd/nfsctl.c
fs/nfsd/nfsctl.c
+16
-4
No files found.
fs/nfsd/export.c
View file @
f0152514
...
...
@@ -19,6 +19,7 @@
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/in.h>
#include <linux/seq_file.h>
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
...
...
@@ -514,6 +515,67 @@ exp_getclientbyname(char *ident)
return
NULL
;
}
/* Iterator */
static
void
*
e_start
(
struct
seq_file
*
m
,
loff_t
*
pos
)
{
loff_t
n
=
*
pos
;
unsigned
client
,
export
;
svc_client
*
clp
;
struct
list_head
*
p
;
exp_readlock
();
if
(
!
n
--
)
return
(
void
*
)
1
;
client
=
n
>>
32
;
export
=
n
&
((
1LL
<<
32
)
-
1
);
for
(
clp
=
clients
;
client
&&
clp
;
clp
=
clp
->
cl_next
,
client
--
)
;
if
(
!
clp
)
return
NULL
;
list_for_each
(
p
,
&
clp
->
cl_list
)
if
(
!
export
--
)
return
list_entry
(
p
,
svc_export
,
ex_list
);
n
&=
~
((
1LL
<<
32
)
-
1
);
do
{
clp
=
clp
->
cl_next
;
n
+=
1LL
<<
32
;
}
while
(
clp
&&
list_empty
(
&
clp
->
cl_list
));
if
(
!
clp
)
return
NULL
;
*
pos
=
n
+
1
;
return
list_entry
(
clp
->
cl_list
.
next
,
svc_export
,
ex_list
);
}
static
void
*
e_next
(
struct
seq_file
*
m
,
void
*
p
,
loff_t
*
pos
)
{
svc_export
*
exp
=
p
;
svc_client
*
clp
;
if
(
p
==
(
void
*
)
1
)
clp
=
clients
;
else
if
(
exp
->
ex_list
.
next
==
&
exp
->
ex_client
->
cl_list
)
clp
=
exp
->
ex_client
->
cl_next
;
else
{
++*
pos
;
return
list_entry
(
exp
->
ex_list
.
next
,
svc_export
,
ex_list
);
}
*
pos
&=
~
((
1LL
<<
32
)
-
1
);
while
(
clp
&&
list_empty
(
&
clp
->
cl_list
))
{
clp
=
clp
->
cl_next
;
*
pos
+=
1LL
<<
32
;
}
if
(
!
clp
)
return
NULL
;
++*
pos
;
return
list_entry
(
clp
->
cl_list
.
next
,
svc_export
,
ex_list
);
}
static
void
e_stop
(
struct
seq_file
*
m
,
void
*
p
)
{
exp_unlock
();
}
struct
flags
{
int
flag
;
char
*
name
[
2
];
...
...
@@ -536,129 +598,77 @@ struct flags {
{
0
,
{
""
,
""
}}
};
static
int
exp_flags
(
char
*
buffer
,
int
flag
)
static
void
exp_flags
(
struct
seq_file
*
m
,
int
flag
)
{
int
len
=
0
,
first
=
0
;
struct
flags
*
flg
=
expflags
;
for
(;
flg
->
flag
;
flg
++
)
{
int
state
=
(
flg
->
flag
&
flag
)
?
0
:
1
;
if
(
!
flg
->
flag
)
break
;
if
(
*
flg
->
name
[
state
])
{
len
+=
sprintf
(
buffer
+
len
,
"%s%s"
,
first
++?
","
:
""
,
flg
->
name
[
state
]);
}
}
return
len
;
}
int
first
=
0
;
struct
flags
*
flg
;
/* mangling borrowed from fs/super.c */
/* Use octal escapes, like mount does, for embedded spaces etc. */
static
unsigned
char
need_escaping
[]
=
{
' '
,
'\t'
,
'\n'
,
'\\'
};
static
int
mangle
(
const
unsigned
char
*
s
,
char
*
buf
,
int
len
)
{
char
*
sp
;
int
n
;
sp
=
buf
;
while
(
*
s
&&
sp
-
buf
<
len
-
3
)
{
for
(
n
=
0
;
n
<
sizeof
(
need_escaping
);
n
++
)
{
if
(
*
s
==
need_escaping
[
n
])
{
*
sp
++
=
'\\'
;
*
sp
++
=
'0'
+
((
*
s
&
0300
)
>>
6
);
*
sp
++
=
'0'
+
((
*
s
&
070
)
>>
3
);
*
sp
++
=
'0'
+
(
*
s
&
07
);
goto
next
;
}
}
*
sp
++
=
*
s
;
next:
s
++
;
}
return
sp
-
buf
;
/* no trailing NUL */
for
(
flg
=
expflags
;
flg
->
flag
;
flg
++
)
{
int
state
=
(
flg
->
flag
&
flag
)
?
0
:
1
;
if
(
*
flg
->
name
[
state
])
seq_printf
(
m
,
"%s%s"
,
first
++?
","
:
""
,
flg
->
name
[
state
]);
}
}
#define FREEROOM ((int)PAGE_SIZE-200-len)
#define MANGLE(s) len += mangle((s), buffer+len, FREEROOM);
int
exp_procfs_exports
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
*
eof
,
void
*
data
)
static
inline
void
mangle
(
struct
seq_file
*
m
,
const
char
*
s
)
{
struct
svc_clnthash
**
hp
,
**
head
,
*
tmp
;
struct
svc_client
*
clp
;
svc_export
*
exp
;
off_t
pos
=
0
;
off_t
begin
=
0
;
int
len
=
0
;
int
j
;
len
+=
sprintf
(
buffer
,
"# Version 1.1
\n
"
);
len
+=
sprintf
(
buffer
+
len
,
"# Path Client(Flags) # IPs
\n
"
);
seq_escape
(
m
,
s
,
"
\t\n\\
"
);
}
for
(
clp
=
clients
;
clp
;
clp
=
clp
->
cl_next
)
{
struct
list_head
*
list
=
&
clp
->
cl_list
;
struct
list_head
*
p
;
list_for_each
(
p
,
list
)
{
int
first
=
0
;
exp
=
list_entry
(
p
,
svc_export
,
ex_list
);
MANGLE
(
exp
->
ex_path
);
buffer
[
len
++
]
=
'\t'
;
MANGLE
(
clp
->
cl_ident
);
buffer
[
len
++
]
=
'('
;
len
+=
exp_flags
(
buffer
+
len
,
exp
->
ex_flags
);
len
+=
sprintf
(
buffer
+
len
,
") # "
);
for
(
j
=
0
;
j
<
clp
->
cl_naddr
;
j
++
)
{
struct
in_addr
addr
=
clp
->
cl_addr
[
j
];
head
=
&
clnt_hash
[
CLIENT_HASH
(
addr
.
s_addr
)];
for
(
hp
=
head
;
(
tmp
=
*
hp
)
!=
NULL
;
hp
=
&
(
tmp
->
h_next
))
{
if
(
tmp
->
h_addr
.
s_addr
==
addr
.
s_addr
)
{
if
(
first
++
)
len
+=
sprintf
(
buffer
+
len
,
"%s"
,
" "
);
if
(
tmp
->
h_client
!=
clp
)
len
+=
sprintf
(
buffer
+
len
,
"("
);
len
+=
sprintf
(
buffer
+
len
,
"%d.%d.%d.%d"
,
htonl
(
addr
.
s_addr
)
>>
24
&
0xff
,
htonl
(
addr
.
s_addr
)
>>
16
&
0xff
,
htonl
(
addr
.
s_addr
)
>>
8
&
0xff
,
htonl
(
addr
.
s_addr
)
>>
0
&
0xff
);
if
(
tmp
->
h_client
!=
clp
)
len
+=
sprintf
(
buffer
+
len
,
")"
);
break
;
}
}
}
static
int
e_show
(
struct
seq_file
*
m
,
void
*
p
)
{
struct
svc_export
*
exp
=
p
;
struct
svc_client
*
clp
;
int
j
,
first
=
0
;
buffer
[
len
++
]
=
'\n'
;
if
(
p
==
(
void
*
)
1
)
{
seq_puts
(
m
,
"# Version 1.1
\n
"
);
seq_puts
(
m
,
"# Path Client(Flags) # IPs
\n
"
);
return
0
;
}
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
goto
done
;
clp
=
exp
->
ex_client
;
mangle
(
m
,
exp
->
ex_path
);
seq_putc
(
m
,
'\t'
);
mangle
(
m
,
clp
->
cl_ident
);
seq_putc
(
m
,
'('
);
exp_flags
(
m
,
exp
->
ex_flags
);
seq_puts
(
m
,
") # "
);
for
(
j
=
0
;
j
<
clp
->
cl_naddr
;
j
++
)
{
struct
svc_clnthash
**
hp
,
**
head
,
*
tmp
;
struct
in_addr
addr
=
clp
->
cl_addr
[
j
];
head
=
&
clnt_hash
[
CLIENT_HASH
(
addr
.
s_addr
)];
for
(
hp
=
head
;
(
tmp
=
*
hp
)
!=
NULL
;
hp
=
&
(
tmp
->
h_next
))
{
if
(
tmp
->
h_addr
.
s_addr
==
addr
.
s_addr
)
break
;
}
if
(
tmp
)
{
if
(
first
++
)
seq_putc
(
m
,
' '
);
if
(
tmp
->
h_client
!=
clp
)
seq_putc
(
m
,
'('
);
seq_printf
(
m
,
"%d.%d.%d.%d"
,
htonl
(
addr
.
s_addr
)
>>
24
&
0xff
,
htonl
(
addr
.
s_addr
)
>>
16
&
0xff
,
htonl
(
addr
.
s_addr
)
>>
8
&
0xff
,
htonl
(
addr
.
s_addr
)
>>
0
&
0xff
);
if
(
tmp
->
h_client
!=
clp
)
seq_putc
(
m
,
')'
);
}
}
*
eof
=
1
;
done:
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
if
(
len
>
length
)
len
=
length
;
return
len
;
seq_putc
(
m
,
'\n'
);
return
0
;
}
struct
seq_operations
nfs_exports_op
=
{
start:
e_start
,
next:
e_next
,
stop:
e_stop
,
show:
e_show
,
};
/*
* Add or modify a client.
* Change requests may involve the list of host addresses. The list of
...
...
fs/nfsd/nfsctl.c
View file @
f0152514
...
...
@@ -20,6 +20,7 @@
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/nfs.h>
#include <linux/sunrpc/svc.h>
...
...
@@ -45,17 +46,28 @@ static int nfsctl_ugidupdate(struct nfsctl_ugidmap *data);
static
int
initialized
;
int
exp_procfs_exports
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
*
eof
,
void
*
data
);
extern
struct
seq_operations
nfs_exports_op
;
static
int
exports_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
seq_open
(
file
,
&
nfs_exports_op
);
}
static
struct
file_operations
exports_operations
=
{
open:
exports_open
,
read:
seq_read
,
llseek:
seq_lseek
,
release:
seq_release
,
};
void
proc_export_init
(
void
)
{
struct
proc_dir_entry
*
entry
;
if
(
!
proc_mkdir
(
"fs/nfs"
,
0
))
return
;
create_proc_read_entry
(
"fs/nfs/exports"
,
0
,
0
,
exp_procfs_exports
,
NULL
);
entry
=
create_proc_entry
(
"fs/nfs/exports"
,
0
,
NULL
);
if
(
entry
)
entry
->
proc_fops
=
&
exports_operations
;
}
/*
* Initialize nfsd
*/
...
...
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