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
7bb307e8
Commit
7bb307e8
authored
Feb 23, 2013
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
export kernel_write(), convert open-coded instances
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
94e07a75
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
24 additions
and
61 deletions
+24
-61
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/nandsim.c
+12
-22
fs/ecryptfs/read_write.c
fs/ecryptfs/read_write.c
+1
-5
fs/splice.c
fs/splice.c
+3
-2
include/linux/fs.h
include/linux/fs.h
+1
-0
kernel/sysctl_binary.c
kernel/sysctl_binary.c
+7
-32
No files found.
drivers/mtd/nand/nandsim.c
View file @
7bb307e8
...
@@ -1408,40 +1408,32 @@ static void clear_memalloc(int memalloc)
...
@@ -1408,40 +1408,32 @@ static void clear_memalloc(int memalloc)
current
->
flags
&=
~
PF_MEMALLOC
;
current
->
flags
&=
~
PF_MEMALLOC
;
}
}
static
ssize_t
read_file
(
struct
nandsim
*
ns
,
struct
file
*
file
,
void
*
buf
,
size_t
count
,
loff_t
*
pos
)
static
ssize_t
read_file
(
struct
nandsim
*
ns
,
struct
file
*
file
,
void
*
buf
,
size_t
count
,
loff_t
pos
)
{
{
mm_segment_t
old_fs
;
ssize_t
tx
;
ssize_t
tx
;
int
err
,
memalloc
;
int
err
,
memalloc
;
err
=
get_pages
(
ns
,
file
,
count
,
*
pos
);
err
=
get_pages
(
ns
,
file
,
count
,
pos
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
old_fs
=
get_fs
();
set_fs
(
get_ds
());
memalloc
=
set_memalloc
();
memalloc
=
set_memalloc
();
tx
=
vfs_read
(
file
,
(
char
__user
*
)
buf
,
count
,
pos
);
tx
=
kernel_read
(
file
,
pos
,
buf
,
count
);
clear_memalloc
(
memalloc
);
clear_memalloc
(
memalloc
);
set_fs
(
old_fs
);
put_pages
(
ns
);
put_pages
(
ns
);
return
tx
;
return
tx
;
}
}
static
ssize_t
write_file
(
struct
nandsim
*
ns
,
struct
file
*
file
,
void
*
buf
,
size_t
count
,
loff_t
*
pos
)
static
ssize_t
write_file
(
struct
nandsim
*
ns
,
struct
file
*
file
,
void
*
buf
,
size_t
count
,
loff_t
pos
)
{
{
mm_segment_t
old_fs
;
ssize_t
tx
;
ssize_t
tx
;
int
err
,
memalloc
;
int
err
,
memalloc
;
err
=
get_pages
(
ns
,
file
,
count
,
*
pos
);
err
=
get_pages
(
ns
,
file
,
count
,
pos
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
old_fs
=
get_fs
();
set_fs
(
get_ds
());
memalloc
=
set_memalloc
();
memalloc
=
set_memalloc
();
tx
=
vfs_write
(
file
,
(
char
__user
*
)
buf
,
count
,
pos
);
tx
=
kernel_write
(
file
,
buf
,
count
,
pos
);
clear_memalloc
(
memalloc
);
clear_memalloc
(
memalloc
);
set_fs
(
old_fs
);
put_pages
(
ns
);
put_pages
(
ns
);
return
tx
;
return
tx
;
}
}
...
@@ -1511,7 +1503,7 @@ static void read_page(struct nandsim *ns, int num)
...
@@ -1511,7 +1503,7 @@ static void read_page(struct nandsim *ns, int num)
if
(
do_read_error
(
ns
,
num
))
if
(
do_read_error
(
ns
,
num
))
return
;
return
;
pos
=
(
loff_t
)
ns
->
regs
.
row
*
ns
->
geom
.
pgszoob
+
ns
->
regs
.
column
+
ns
->
regs
.
off
;
pos
=
(
loff_t
)
ns
->
regs
.
row
*
ns
->
geom
.
pgszoob
+
ns
->
regs
.
column
+
ns
->
regs
.
off
;
tx
=
read_file
(
ns
,
ns
->
cfile
,
ns
->
buf
.
byte
,
num
,
&
pos
);
tx
=
read_file
(
ns
,
ns
->
cfile
,
ns
->
buf
.
byte
,
num
,
pos
);
if
(
tx
!=
num
)
{
if
(
tx
!=
num
)
{
NS_ERR
(
"read_page: read error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
NS_ERR
(
"read_page: read error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
return
;
return
;
...
@@ -1573,7 +1565,7 @@ static int prog_page(struct nandsim *ns, int num)
...
@@ -1573,7 +1565,7 @@ static int prog_page(struct nandsim *ns, int num)
u_char
*
pg_off
;
u_char
*
pg_off
;
if
(
ns
->
cfile
)
{
if
(
ns
->
cfile
)
{
loff_t
off
,
pos
;
loff_t
off
;
ssize_t
tx
;
ssize_t
tx
;
int
all
;
int
all
;
...
@@ -1585,8 +1577,7 @@ static int prog_page(struct nandsim *ns, int num)
...
@@ -1585,8 +1577,7 @@ static int prog_page(struct nandsim *ns, int num)
memset
(
ns
->
file_buf
,
0xff
,
ns
->
geom
.
pgszoob
);
memset
(
ns
->
file_buf
,
0xff
,
ns
->
geom
.
pgszoob
);
}
else
{
}
else
{
all
=
0
;
all
=
0
;
pos
=
off
;
tx
=
read_file
(
ns
,
ns
->
cfile
,
pg_off
,
num
,
off
);
tx
=
read_file
(
ns
,
ns
->
cfile
,
pg_off
,
num
,
&
pos
);
if
(
tx
!=
num
)
{
if
(
tx
!=
num
)
{
NS_ERR
(
"prog_page: read error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
NS_ERR
(
"prog_page: read error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
return
-
1
;
return
-
1
;
...
@@ -1595,16 +1586,15 @@ static int prog_page(struct nandsim *ns, int num)
...
@@ -1595,16 +1586,15 @@ static int prog_page(struct nandsim *ns, int num)
for
(
i
=
0
;
i
<
num
;
i
++
)
for
(
i
=
0
;
i
<
num
;
i
++
)
pg_off
[
i
]
&=
ns
->
buf
.
byte
[
i
];
pg_off
[
i
]
&=
ns
->
buf
.
byte
[
i
];
if
(
all
)
{
if
(
all
)
{
pos
=
(
loff_t
)
ns
->
regs
.
row
*
ns
->
geom
.
pgszoob
;
loff_t
pos
=
(
loff_t
)
ns
->
regs
.
row
*
ns
->
geom
.
pgszoob
;
tx
=
write_file
(
ns
,
ns
->
cfile
,
ns
->
file_buf
,
ns
->
geom
.
pgszoob
,
&
pos
);
tx
=
write_file
(
ns
,
ns
->
cfile
,
ns
->
file_buf
,
ns
->
geom
.
pgszoob
,
pos
);
if
(
tx
!=
ns
->
geom
.
pgszoob
)
{
if
(
tx
!=
ns
->
geom
.
pgszoob
)
{
NS_ERR
(
"prog_page: write error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
NS_ERR
(
"prog_page: write error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
return
-
1
;
return
-
1
;
}
}
ns
->
pages_written
[
ns
->
regs
.
row
]
=
1
;
ns
->
pages_written
[
ns
->
regs
.
row
]
=
1
;
}
else
{
}
else
{
pos
=
off
;
tx
=
write_file
(
ns
,
ns
->
cfile
,
pg_off
,
num
,
off
);
tx
=
write_file
(
ns
,
ns
->
cfile
,
pg_off
,
num
,
&
pos
);
if
(
tx
!=
num
)
{
if
(
tx
!=
num
)
{
NS_ERR
(
"prog_page: write error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
NS_ERR
(
"prog_page: write error for page %d ret %ld
\n
"
,
ns
->
regs
.
row
,
(
long
)
tx
);
return
-
1
;
return
-
1
;
...
...
fs/ecryptfs/read_write.c
View file @
7bb307e8
...
@@ -40,16 +40,12 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
...
@@ -40,16 +40,12 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
loff_t
offset
,
size_t
size
)
loff_t
offset
,
size_t
size
)
{
{
struct
file
*
lower_file
;
struct
file
*
lower_file
;
mm_segment_t
fs_save
;
ssize_t
rc
;
ssize_t
rc
;
lower_file
=
ecryptfs_inode_to_private
(
ecryptfs_inode
)
->
lower_file
;
lower_file
=
ecryptfs_inode_to_private
(
ecryptfs_inode
)
->
lower_file
;
if
(
!
lower_file
)
if
(
!
lower_file
)
return
-
EIO
;
return
-
EIO
;
fs_save
=
get_fs
();
rc
=
kernel_write
(
lower_file
,
data
,
size
,
offset
);
set_fs
(
get_ds
());
rc
=
vfs_write
(
lower_file
,
data
,
size
,
&
offset
);
set_fs
(
fs_save
);
mark_inode_dirty_sync
(
ecryptfs_inode
);
mark_inode_dirty_sync
(
ecryptfs_inode
);
return
rc
;
return
rc
;
}
}
...
...
fs/splice.c
View file @
7bb307e8
...
@@ -569,7 +569,7 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
...
@@ -569,7 +569,7 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec,
return
res
;
return
res
;
}
}
s
tatic
s
size_t
kernel_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
,
ssize_t
kernel_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
,
loff_t
pos
)
loff_t
pos
)
{
{
mm_segment_t
old_fs
;
mm_segment_t
old_fs
;
...
@@ -578,11 +578,12 @@ static ssize_t kernel_write(struct file *file, const char *buf, size_t count,
...
@@ -578,11 +578,12 @@ static ssize_t kernel_write(struct file *file, const char *buf, size_t count,
old_fs
=
get_fs
();
old_fs
=
get_fs
();
set_fs
(
get_ds
());
set_fs
(
get_ds
());
/* The cast to a user pointer is valid due to the set_fs() */
/* The cast to a user pointer is valid due to the set_fs() */
res
=
vfs_write
(
file
,
(
const
char
__user
*
)
buf
,
count
,
&
pos
);
res
=
vfs_write
(
file
,
(
__force
const
char
__user
*
)
buf
,
count
,
&
pos
);
set_fs
(
old_fs
);
set_fs
(
old_fs
);
return
res
;
return
res
;
}
}
EXPORT_SYMBOL
(
kernel_write
);
ssize_t
default_file_splice_read
(
struct
file
*
in
,
loff_t
*
ppos
,
ssize_t
default_file_splice_read
(
struct
file
*
in
,
loff_t
*
ppos
,
struct
pipe_inode_info
*
pipe
,
size_t
len
,
struct
pipe_inode_info
*
pipe
,
size_t
len
,
...
...
include/linux/fs.h
View file @
7bb307e8
...
@@ -2277,6 +2277,7 @@ static inline void i_readcount_inc(struct inode *inode)
...
@@ -2277,6 +2277,7 @@ static inline void i_readcount_inc(struct inode *inode)
extern
int
do_pipe_flags
(
int
*
,
int
);
extern
int
do_pipe_flags
(
int
*
,
int
);
extern
int
kernel_read
(
struct
file
*
,
loff_t
,
char
*
,
unsigned
long
);
extern
int
kernel_read
(
struct
file
*
,
loff_t
,
char
*
,
unsigned
long
);
extern
ssize_t
kernel_write
(
struct
file
*
,
const
char
*
,
size_t
,
loff_t
);
extern
struct
file
*
open_exec
(
const
char
*
);
extern
struct
file
*
open_exec
(
const
char
*
);
/* fs/dcache.c -- generic fs support functions */
/* fs/dcache.c -- generic fs support functions */
...
...
kernel/sysctl_binary.c
View file @
7bb307e8
...
@@ -971,7 +971,6 @@ static ssize_t bin_string(struct file *file,
...
@@ -971,7 +971,6 @@ static ssize_t bin_string(struct file *file,
static
ssize_t
bin_intvec
(
struct
file
*
file
,
static
ssize_t
bin_intvec
(
struct
file
*
file
,
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
{
{
mm_segment_t
old_fs
=
get_fs
();
ssize_t
copied
=
0
;
ssize_t
copied
=
0
;
char
*
buffer
;
char
*
buffer
;
ssize_t
result
;
ssize_t
result
;
...
@@ -984,13 +983,10 @@ static ssize_t bin_intvec(struct file *file,
...
@@ -984,13 +983,10 @@ static ssize_t bin_intvec(struct file *file,
if
(
oldval
&&
oldlen
)
{
if
(
oldval
&&
oldlen
)
{
unsigned
__user
*
vec
=
oldval
;
unsigned
__user
*
vec
=
oldval
;
size_t
length
=
oldlen
/
sizeof
(
*
vec
);
size_t
length
=
oldlen
/
sizeof
(
*
vec
);
loff_t
pos
=
0
;
char
*
str
,
*
end
;
char
*
str
,
*
end
;
int
i
;
int
i
;
set_fs
(
KERNEL_DS
);
result
=
kernel_read
(
file
,
0
,
buffer
,
BUFSZ
-
1
);
result
=
vfs_read
(
file
,
buffer
,
BUFSZ
-
1
,
&
pos
);
set_fs
(
old_fs
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out_kfree
;
goto
out_kfree
;
...
@@ -1017,7 +1013,6 @@ static ssize_t bin_intvec(struct file *file,
...
@@ -1017,7 +1013,6 @@ static ssize_t bin_intvec(struct file *file,
if
(
newval
&&
newlen
)
{
if
(
newval
&&
newlen
)
{
unsigned
__user
*
vec
=
newval
;
unsigned
__user
*
vec
=
newval
;
size_t
length
=
newlen
/
sizeof
(
*
vec
);
size_t
length
=
newlen
/
sizeof
(
*
vec
);
loff_t
pos
=
0
;
char
*
str
,
*
end
;
char
*
str
,
*
end
;
int
i
;
int
i
;
...
@@ -1033,9 +1028,7 @@ static ssize_t bin_intvec(struct file *file,
...
@@ -1033,9 +1028,7 @@ static ssize_t bin_intvec(struct file *file,
str
+=
snprintf
(
str
,
end
-
str
,
"%lu
\t
"
,
value
);
str
+=
snprintf
(
str
,
end
-
str
,
"%lu
\t
"
,
value
);
}
}
set_fs
(
KERNEL_DS
);
result
=
kernel_write
(
file
,
buffer
,
str
-
buffer
,
0
);
result
=
vfs_write
(
file
,
buffer
,
str
-
buffer
,
&
pos
);
set_fs
(
old_fs
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out_kfree
;
goto
out_kfree
;
}
}
...
@@ -1049,7 +1042,6 @@ static ssize_t bin_intvec(struct file *file,
...
@@ -1049,7 +1042,6 @@ static ssize_t bin_intvec(struct file *file,
static
ssize_t
bin_ulongvec
(
struct
file
*
file
,
static
ssize_t
bin_ulongvec
(
struct
file
*
file
,
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
{
{
mm_segment_t
old_fs
=
get_fs
();
ssize_t
copied
=
0
;
ssize_t
copied
=
0
;
char
*
buffer
;
char
*
buffer
;
ssize_t
result
;
ssize_t
result
;
...
@@ -1062,13 +1054,10 @@ static ssize_t bin_ulongvec(struct file *file,
...
@@ -1062,13 +1054,10 @@ static ssize_t bin_ulongvec(struct file *file,
if
(
oldval
&&
oldlen
)
{
if
(
oldval
&&
oldlen
)
{
unsigned
long
__user
*
vec
=
oldval
;
unsigned
long
__user
*
vec
=
oldval
;
size_t
length
=
oldlen
/
sizeof
(
*
vec
);
size_t
length
=
oldlen
/
sizeof
(
*
vec
);
loff_t
pos
=
0
;
char
*
str
,
*
end
;
char
*
str
,
*
end
;
int
i
;
int
i
;
set_fs
(
KERNEL_DS
);
result
=
kernel_read
(
file
,
0
,
buffer
,
BUFSZ
-
1
);
result
=
vfs_read
(
file
,
buffer
,
BUFSZ
-
1
,
&
pos
);
set_fs
(
old_fs
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out_kfree
;
goto
out_kfree
;
...
@@ -1095,7 +1084,6 @@ static ssize_t bin_ulongvec(struct file *file,
...
@@ -1095,7 +1084,6 @@ static ssize_t bin_ulongvec(struct file *file,
if
(
newval
&&
newlen
)
{
if
(
newval
&&
newlen
)
{
unsigned
long
__user
*
vec
=
newval
;
unsigned
long
__user
*
vec
=
newval
;
size_t
length
=
newlen
/
sizeof
(
*
vec
);
size_t
length
=
newlen
/
sizeof
(
*
vec
);
loff_t
pos
=
0
;
char
*
str
,
*
end
;
char
*
str
,
*
end
;
int
i
;
int
i
;
...
@@ -1111,9 +1099,7 @@ static ssize_t bin_ulongvec(struct file *file,
...
@@ -1111,9 +1099,7 @@ static ssize_t bin_ulongvec(struct file *file,
str
+=
snprintf
(
str
,
end
-
str
,
"%lu
\t
"
,
value
);
str
+=
snprintf
(
str
,
end
-
str
,
"%lu
\t
"
,
value
);
}
}
set_fs
(
KERNEL_DS
);
result
=
kernel_write
(
file
,
buffer
,
str
-
buffer
,
0
);
result
=
vfs_write
(
file
,
buffer
,
str
-
buffer
,
&
pos
);
set_fs
(
old_fs
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out_kfree
;
goto
out_kfree
;
}
}
...
@@ -1127,19 +1113,15 @@ static ssize_t bin_ulongvec(struct file *file,
...
@@ -1127,19 +1113,15 @@ static ssize_t bin_ulongvec(struct file *file,
static
ssize_t
bin_uuid
(
struct
file
*
file
,
static
ssize_t
bin_uuid
(
struct
file
*
file
,
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
{
{
mm_segment_t
old_fs
=
get_fs
();
ssize_t
result
,
copied
=
0
;
ssize_t
result
,
copied
=
0
;
/* Only supports reads */
/* Only supports reads */
if
(
oldval
&&
oldlen
)
{
if
(
oldval
&&
oldlen
)
{
loff_t
pos
=
0
;
char
buf
[
40
],
*
str
=
buf
;
char
buf
[
40
],
*
str
=
buf
;
unsigned
char
uuid
[
16
];
unsigned
char
uuid
[
16
];
int
i
;
int
i
;
set_fs
(
KERNEL_DS
);
result
=
kernel_read
(
file
,
0
,
buf
,
sizeof
(
buf
)
-
1
);
result
=
vfs_read
(
file
,
buf
,
sizeof
(
buf
)
-
1
,
&
pos
);
set_fs
(
old_fs
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out
;
goto
out
;
...
@@ -1175,18 +1157,14 @@ static ssize_t bin_uuid(struct file *file,
...
@@ -1175,18 +1157,14 @@ static ssize_t bin_uuid(struct file *file,
static
ssize_t
bin_dn_node_address
(
struct
file
*
file
,
static
ssize_t
bin_dn_node_address
(
struct
file
*
file
,
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
void
__user
*
oldval
,
size_t
oldlen
,
void
__user
*
newval
,
size_t
newlen
)
{
{
mm_segment_t
old_fs
=
get_fs
();
ssize_t
result
,
copied
=
0
;
ssize_t
result
,
copied
=
0
;
if
(
oldval
&&
oldlen
)
{
if
(
oldval
&&
oldlen
)
{
loff_t
pos
=
0
;
char
buf
[
15
],
*
nodep
;
char
buf
[
15
],
*
nodep
;
unsigned
long
area
,
node
;
unsigned
long
area
,
node
;
__le16
dnaddr
;
__le16
dnaddr
;
set_fs
(
KERNEL_DS
);
result
=
kernel_read
(
file
,
0
,
buf
,
sizeof
(
buf
)
-
1
);
result
=
vfs_read
(
file
,
buf
,
sizeof
(
buf
)
-
1
,
&
pos
);
set_fs
(
old_fs
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out
;
goto
out
;
...
@@ -1215,7 +1193,6 @@ static ssize_t bin_dn_node_address(struct file *file,
...
@@ -1215,7 +1193,6 @@ static ssize_t bin_dn_node_address(struct file *file,
}
}
if
(
newval
&&
newlen
)
{
if
(
newval
&&
newlen
)
{
loff_t
pos
=
0
;
__le16
dnaddr
;
__le16
dnaddr
;
char
buf
[
15
];
char
buf
[
15
];
int
len
;
int
len
;
...
@@ -1232,9 +1209,7 @@ static ssize_t bin_dn_node_address(struct file *file,
...
@@ -1232,9 +1209,7 @@ static ssize_t bin_dn_node_address(struct file *file,
le16_to_cpu
(
dnaddr
)
>>
10
,
le16_to_cpu
(
dnaddr
)
>>
10
,
le16_to_cpu
(
dnaddr
)
&
0x3ff
);
le16_to_cpu
(
dnaddr
)
&
0x3ff
);
set_fs
(
KERNEL_DS
);
result
=
kernel_write
(
file
,
buf
,
len
,
0
);
result
=
vfs_write
(
file
,
buf
,
len
,
&
pos
);
set_fs
(
old_fs
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
out
;
goto
out
;
}
}
...
...
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