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
01663d94
Commit
01663d94
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.3.26pre2
parent
faf76fb3
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
52 additions
and
61 deletions
+52
-61
fs/ext2/truncate.c
fs/ext2/truncate.c
+1
-2
fs/isofs/inode.c
fs/isofs/inode.c
+1
-1
fs/nfs/inode.c
fs/nfs/inode.c
+1
-1
include/linux/blkdev.h
include/linux/blkdev.h
+4
-7
include/linux/fs.h
include/linux/fs.h
+2
-2
ipc/shm.c
ipc/shm.c
+2
-7
mm/filemap.c
mm/filemap.c
+41
-41
No files found.
fs/ext2/truncate.c
View file @
01663d94
...
@@ -50,8 +50,7 @@ static int ext2_secrm_seed = 152; /* Random generator base */
...
@@ -50,8 +50,7 @@ static int ext2_secrm_seed = 152; /* Random generator base */
* there's no need to test for changes during the operation.
* there's no need to test for changes during the operation.
*/
*/
#define DIRECT_BLOCK(inode) \
#define DIRECT_BLOCK(inode) \
((inode->i_size + inode->i_sb->s_blocksize - 1) / \
((unsigned long) ((inode->i_size + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits))
inode->i_sb->s_blocksize)
#define INDIRECT_BLOCK(inode,offset) ((int)DIRECT_BLOCK(inode) - offset)
#define INDIRECT_BLOCK(inode,offset) ((int)DIRECT_BLOCK(inode) - offset)
#define DINDIRECT_BLOCK(inode,offset) \
#define DINDIRECT_BLOCK(inode,offset) \
(INDIRECT_BLOCK(inode,offset) / addr_per_block)
(INDIRECT_BLOCK(inode,offset) / addr_per_block)
...
...
fs/isofs/inode.c
View file @
01663d94
...
@@ -1009,7 +1009,7 @@ int isofs_get_block(struct inode *inode, long iblock,
...
@@ -1009,7 +1009,7 @@ int isofs_get_block(struct inode *inode, long iblock,
abort_beyond_end:
abort_beyond_end:
printk
(
"_isofs_bmap: block >= EOF (%ld, %ld)
\n
"
,
printk
(
"_isofs_bmap: block >= EOF (%ld, %ld)
\n
"
,
iblock
,
inode
->
i_size
);
iblock
,
(
unsigned
long
)
inode
->
i_size
);
goto
abort
;
goto
abort
;
abort_too_many_sections:
abort_too_many_sections:
...
...
fs/nfs/inode.c
View file @
01663d94
...
@@ -680,7 +680,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
...
@@ -680,7 +680,7 @@ printk("nfs_notify_change: revalidate failed, error=%d\n", error);
*/
*/
if
(
attr
->
ia_valid
&
ATTR_SIZE
)
{
if
(
attr
->
ia_valid
&
ATTR_SIZE
)
{
if
(
attr
->
ia_size
!=
fattr
.
size
)
if
(
attr
->
ia_size
!=
fattr
.
size
)
printk
(
"nfs_notify_change: attr=%
l
d, fattr=%d??
\n
"
,
printk
(
"nfs_notify_change: attr=%
L
d, fattr=%d??
\n
"
,
attr
->
ia_size
,
fattr
.
size
);
attr
->
ia_size
,
fattr
.
size
);
inode
->
i_size
=
attr
->
ia_size
;
inode
->
i_size
=
attr
->
ia_size
;
inode
->
i_mtime
=
fattr
.
mtime
.
seconds
;
inode
->
i_mtime
=
fattr
.
mtime
.
seconds
;
...
...
include/linux/blkdev.h
View file @
01663d94
...
@@ -83,12 +83,9 @@ extern int * max_segments[MAX_BLKDEV];
...
@@ -83,12 +83,9 @@ extern int * max_segments[MAX_BLKDEV];
#define MAX_SEGMENTS MAX_SECTORS
#define MAX_SEGMENTS MAX_SECTORS
#define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)
#define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)
#if 0 /* small readahead */
#define MAX_READAHEAD PageAlignSize(4096*7)
/* read-ahead in pages.. */
#define MIN_READAHEAD PageAlignSize(4096*2)
#define MAX_READAHEAD 31
#else
/* large readahead */
#define MIN_READAHEAD 3
#define MAX_READAHEAD PageAlignSize(4096*31)
#define MIN_READAHEAD PageAlignSize(4096*3)
#endif
#endif
#endif
include/linux/fs.h
View file @
01663d94
...
@@ -302,7 +302,7 @@ struct iattr {
...
@@ -302,7 +302,7 @@ struct iattr {
umode_t
ia_mode
;
umode_t
ia_mode
;
uid_t
ia_uid
;
uid_t
ia_uid
;
gid_t
ia_gid
;
gid_t
ia_gid
;
off_t
ia_size
;
l
off_t
ia_size
;
time_t
ia_atime
;
time_t
ia_atime
;
time_t
ia_mtime
;
time_t
ia_mtime
;
time_t
ia_ctime
;
time_t
ia_ctime
;
...
@@ -347,7 +347,7 @@ struct inode {
...
@@ -347,7 +347,7 @@ struct inode {
uid_t
i_uid
;
uid_t
i_uid
;
gid_t
i_gid
;
gid_t
i_gid
;
kdev_t
i_rdev
;
kdev_t
i_rdev
;
off_t
i_size
;
l
off_t
i_size
;
time_t
i_atime
;
time_t
i_atime
;
time_t
i_mtime
;
time_t
i_mtime
;
time_t
i_ctime
;
time_t
i_ctime
;
...
...
ipc/shm.c
View file @
01663d94
...
@@ -208,14 +208,12 @@ static int newseg (key_t key, int shmflg, size_t size)
...
@@ -208,14 +208,12 @@ static int newseg (key_t key, int shmflg, size_t size)
int
id
,
err
;
int
id
,
err
;
unsigned
int
shmall
,
shmmni
;
unsigned
int
shmall
,
shmmni
;
lock_kernel
();
shmall
=
shm_prm
[
1
];
shmall
=
shm_prm
[
1
];
shmmni
=
shm_prm
[
2
];
shmmni
=
shm_prm
[
2
];
if
(
shmmni
>
IPCMNI
)
{
if
(
shmmni
>
IPCMNI
)
{
printk
(
"shmmni reset to max of %u
\n
"
,
IPCMNI
);
printk
(
"shmmni reset to max of %u
\n
"
,
IPCMNI
);
shmmni
=
shm_prm
[
2
]
=
IPCMNI
;
shmmni
=
shm_prm
[
2
]
=
IPCMNI
;
}
}
unlock_kernel
();
if
(
shmmni
<
used_segs
)
if
(
shmmni
<
used_segs
)
return
-
ENOSPC
;
return
-
ENOSPC
;
...
@@ -282,10 +280,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
...
@@ -282,10 +280,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
int
err
,
id
=
0
;
int
err
,
id
=
0
;
size_t
shmmax
;
size_t
shmmax
;
lock_kernel
();
shmmax
=
shm_prm
[
0
];
shmmax
=
shm_prm
[
0
];
unlock_kernel
();
if
(
size
>
shmmax
)
if
(
size
>
shmmax
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -387,11 +382,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
...
@@ -387,11 +382,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
err
=
-
EFAULT
;
err
=
-
EFAULT
;
if
(
!
buf
)
if
(
!
buf
)
goto
out
;
goto
out
;
lock_kernel
();
shminfo
.
shmmni
=
shminfo
.
shmseg
=
shm_prm
[
2
];
shminfo
.
shmmni
=
shminfo
.
shmseg
=
shm_prm
[
2
];
shminfo
.
shmmax
=
shm_prm
[
0
];
shminfo
.
shmmax
=
shm_prm
[
0
];
shminfo
.
shmall
=
shm_prm
[
1
];
shminfo
.
shmall
=
shm_prm
[
1
];
unlock_kernel
();
shminfo
.
shmmin
=
SHMMIN
;
shminfo
.
shmmin
=
SHMMIN
;
if
(
copy_to_user
(
buf
,
&
shminfo
,
sizeof
(
struct
shminfo
)))
if
(
copy_to_user
(
buf
,
&
shminfo
,
sizeof
(
struct
shminfo
)))
goto
out_unlocked
;
goto
out_unlocked
;
...
...
mm/filemap.c
View file @
01663d94
...
@@ -567,7 +567,7 @@ static int read_cluster_nonblocking(struct file * file, unsigned long offset)
...
@@ -567,7 +567,7 @@ static int read_cluster_nonblocking(struct file * file, unsigned long offset)
break
;
break
;
}
}
return
;
return
error
;
}
}
/*
/*
...
@@ -837,13 +837,14 @@ static inline int get_max_readahead(struct inode * inode)
...
@@ -837,13 +837,14 @@ static inline int get_max_readahead(struct inode * inode)
static
void
generic_file_readahead
(
int
reada_ok
,
static
void
generic_file_readahead
(
int
reada_ok
,
struct
file
*
filp
,
struct
inode
*
inode
,
struct
file
*
filp
,
struct
inode
*
inode
,
unsigned
long
ppos
,
struct
page
*
page
)
struct
page
*
page
)
{
{
unsigned
long
index
=
page
->
index
;
unsigned
long
max_ahead
,
ahead
;
unsigned
long
max_ahead
,
ahead
;
unsigned
long
raend
;
unsigned
long
raend
;
int
max_readahead
=
get_max_readahead
(
inode
);
int
max_readahead
=
get_max_readahead
(
inode
);
raend
=
filp
->
f_raend
&
PAGE_CACHE_MASK
;
raend
=
filp
->
f_raend
;
max_ahead
=
0
;
max_ahead
=
0
;
/*
/*
...
@@ -855,14 +856,14 @@ static void generic_file_readahead(int reada_ok,
...
@@ -855,14 +856,14 @@ static void generic_file_readahead(int reada_ok,
* page only.
* page only.
*/
*/
if
(
PageLocked
(
page
))
{
if
(
PageLocked
(
page
))
{
if
(
!
filp
->
f_ralen
||
ppos
>=
raend
||
ppos
+
filp
->
f_ralen
<
raend
)
{
if
(
!
filp
->
f_ralen
||
index
>=
raend
||
index
+
filp
->
f_ralen
<
raend
)
{
raend
=
ppos
;
raend
=
index
;
if
(
raend
<
inode
->
i_size
)
if
(
raend
<
(
unsigned
long
)
(
inode
->
i_size
>>
PAGE_CACHE_SHIFT
)
)
max_ahead
=
filp
->
f_ramax
;
max_ahead
=
filp
->
f_ramax
;
filp
->
f_rawin
=
0
;
filp
->
f_rawin
=
0
;
filp
->
f_ralen
=
PAGE_CACHE_SIZE
;
filp
->
f_ralen
=
PAGE_CACHE_SIZE
;
if
(
!
max_ahead
)
{
if
(
!
max_ahead
)
{
filp
->
f_raend
=
ppos
+
filp
->
f_ralen
;
filp
->
f_raend
=
index
+
filp
->
f_ralen
;
filp
->
f_rawin
+=
filp
->
f_ralen
;
filp
->
f_rawin
+=
filp
->
f_ralen
;
}
}
}
}
...
@@ -876,7 +877,7 @@ static void generic_file_readahead(int reada_ok,
...
@@ -876,7 +877,7 @@ static void generic_file_readahead(int reada_ok,
* We will later force unplug device in order to force asynchronous read IO.
* We will later force unplug device in order to force asynchronous read IO.
*/
*/
else
if
(
reada_ok
&&
filp
->
f_ramax
&&
raend
>=
PAGE_CACHE_SIZE
&&
else
if
(
reada_ok
&&
filp
->
f_ramax
&&
raend
>=
PAGE_CACHE_SIZE
&&
ppos
<=
raend
&&
ppos
+
filp
->
f_ralen
>=
raend
)
{
index
<=
raend
&&
index
+
filp
->
f_ralen
>=
raend
)
{
/*
/*
* Add ONE page to max_ahead in order to try to have about the same IO max size
* Add ONE page to max_ahead in order to try to have about the same IO max size
* as synchronous read-ahead (MAX_READAHEAD + 1)*PAGE_CACHE_SIZE.
* as synchronous read-ahead (MAX_READAHEAD + 1)*PAGE_CACHE_SIZE.
...
@@ -952,17 +953,16 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -952,17 +953,16 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
{
{
struct
dentry
*
dentry
=
filp
->
f_dentry
;
struct
dentry
*
dentry
=
filp
->
f_dentry
;
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
inode
*
inode
=
dentry
->
d_inode
;
unsigned
long
pos
,
pgpos
;
unsigned
long
index
,
offset
;
struct
page
*
cached_page
;
struct
page
*
cached_page
;
int
reada_ok
;
int
reada_ok
;
int
error
;
int
error
;
int
max_readahead
=
get_max_readahead
(
inode
);
int
max_readahead
=
get_max_readahead
(
inode
);
unsigned
long
pgoff
;
cached_page
=
NULL
;
cached_page
=
NULL
;
pos
=
*
ppos
;
index
=
*
ppos
>>
PAGE_CACHE_SHIFT
;
pgpos
=
pos
&
PAGE_CACHE_MASK
;
offset
=
*
ppos
&
~
PAGE_CACHE_MASK
;
pgoff
=
pos
>>
PAGE_CACHE_SHIFT
;
/*
/*
* If the current position is outside the previous read-ahead window,
* If the current position is outside the previous read-ahead window,
* we reset the current read-ahead context and set read ahead max to zero
* we reset the current read-ahead context and set read ahead max to zero
...
@@ -970,7 +970,7 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -970,7 +970,7 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
* otherwise, we assume that the file accesses are sequential enough to
* otherwise, we assume that the file accesses are sequential enough to
* continue read-ahead.
* continue read-ahead.
*/
*/
if
(
pgpos
>
filp
->
f_raend
||
pgpos
+
filp
->
f_rawin
<
filp
->
f_raend
)
{
if
(
index
>
filp
->
f_raend
||
index
+
filp
->
f_rawin
<
filp
->
f_raend
)
{
reada_ok
=
0
;
reada_ok
=
0
;
filp
->
f_raend
=
0
;
filp
->
f_raend
=
0
;
filp
->
f_ralen
=
0
;
filp
->
f_ralen
=
0
;
...
@@ -986,12 +986,12 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -986,12 +986,12 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
* Then, at least MIN_READAHEAD if read ahead is ok,
* Then, at least MIN_READAHEAD if read ahead is ok,
* and at most MAX_READAHEAD in all cases.
* and at most MAX_READAHEAD in all cases.
*/
*/
if
(
pos
+
desc
->
count
<=
(
PAGE_CACHE_SIZE
>>
1
))
{
if
(
!
index
&&
offset
+
desc
->
count
<=
(
PAGE_CACHE_SIZE
>>
1
))
{
filp
->
f_ramax
=
0
;
filp
->
f_ramax
=
0
;
}
else
{
}
else
{
unsigned
long
needed
;
unsigned
long
needed
;
needed
=
((
pos
+
desc
->
count
)
&
PAGE_CACHE_MASK
)
-
pgpos
;
needed
=
((
offset
+
desc
->
count
)
>>
PAGE_CACHE_SHIFT
)
+
1
;
if
(
filp
->
f_ramax
<
needed
)
if
(
filp
->
f_ramax
<
needed
)
filp
->
f_ramax
=
needed
;
filp
->
f_ramax
=
needed
;
...
@@ -1004,17 +1004,27 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -1004,17 +1004,27 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
for
(;;)
{
for
(;;)
{
struct
page
*
page
,
**
hash
;
struct
page
*
page
,
**
hash
;
unsigned
long
end_index
,
nr
;
if
(
pos
>=
inode
->
i_size
)
end_index
=
inode
->
i_size
>>
PAGE_CACHE_SHIFT
;
if
(
index
>
end_index
)
break
;
break
;
nr
=
PAGE_CACHE_SIZE
;
if
(
index
==
end_index
)
{
nr
=
inode
->
i_size
&
~
PAGE_CACHE_MASK
;
if
(
nr
<=
offset
)
break
;
}
nr
=
nr
-
offset
;
/*
/*
* Try to find the data in the page cache..
* Try to find the data in the page cache..
*/
*/
hash
=
page_hash
(
&
inode
->
i_data
,
pgoff
);
hash
=
page_hash
(
&
inode
->
i_data
,
index
);
spin_lock
(
&
pagecache_lock
);
spin_lock
(
&
pagecache_lock
);
page
=
__find_page_nolock
(
&
inode
->
i_data
,
pgoff
,
*
hash
);
page
=
__find_page_nolock
(
&
inode
->
i_data
,
index
,
*
hash
);
if
(
!
page
)
if
(
!
page
)
goto
no_cached_page
;
goto
no_cached_page
;
found_page:
found_page:
...
@@ -1024,19 +1034,10 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -1024,19 +1034,10 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
if
(
!
Page_Uptodate
(
page
))
if
(
!
Page_Uptodate
(
page
))
goto
page_not_up_to_date
;
goto
page_not_up_to_date
;
page_ok:
page_ok:
/*
* Ok, we have the page, and it's up-to-date, so
* now we can copy it to user space...
*/
{
unsigned
long
offset
,
nr
;
offset
=
pos
&
~
PAGE_CACHE_MASK
;
nr
=
PAGE_CACHE_SIZE
-
offset
;
if
(
nr
>
inode
->
i_size
-
pos
)
nr
=
inode
->
i_size
-
pos
;
/*
/*
* Ok, we have the page, and it's up-to-date, so
* now we can copy it to user space...
*
* The actor routine returns how many bytes were actually used..
* The actor routine returns how many bytes were actually used..
* NOTE! This may not be the same as how much of a user buffer
* NOTE! This may not be the same as how much of a user buffer
* we filled up (we may be padding etc), so we can only update
* we filled up (we may be padding etc), so we can only update
...
@@ -1044,20 +1045,20 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -1044,20 +1045,20 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
* pointers and the remaining count).
* pointers and the remaining count).
*/
*/
nr
=
actor
(
desc
,
page
,
offset
,
nr
);
nr
=
actor
(
desc
,
page
,
offset
,
nr
);
pos
+=
nr
;
offset
+=
nr
;
pgoff
=
pos
>>
PAGE_CACHE_SHIFT
;
index
+=
offset
>>
PAGE_CACHE_SHIFT
;
offset
&=
~
PAGE_CACHE_MASK
;
page_cache_release
(
page
);
page_cache_release
(
page
);
if
(
nr
&&
desc
->
count
)
if
(
nr
&&
desc
->
count
)
continue
;
continue
;
break
;
break
;
}
/*
/*
* Ok, the page was not immediately readable, so let's try to read ahead while we're at it..
* Ok, the page was not immediately readable, so let's try to read ahead while we're at it..
*/
*/
page_not_up_to_date:
page_not_up_to_date:
generic_file_readahead
(
reada_ok
,
filp
,
inode
,
generic_file_readahead
(
reada_ok
,
filp
,
inode
,
page
);
pos
&
PAGE_CACHE_MASK
,
page
);
if
(
Page_Uptodate
(
page
))
if
(
Page_Uptodate
(
page
))
goto
page_ok
;
goto
page_ok
;
...
@@ -1078,8 +1079,7 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -1078,8 +1079,7 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
goto
page_ok
;
goto
page_ok
;
/* Again, try some read-ahead while waiting for the page to finish.. */
/* Again, try some read-ahead while waiting for the page to finish.. */
generic_file_readahead
(
reada_ok
,
filp
,
inode
,
generic_file_readahead
(
reada_ok
,
filp
,
inode
,
page
);
pos
&
PAGE_CACHE_MASK
,
page
);
wait_on_page
(
page
);
wait_on_page
(
page
);
if
(
Page_Uptodate
(
page
))
if
(
Page_Uptodate
(
page
))
goto
page_ok
;
goto
page_ok
;
...
@@ -1111,7 +1111,7 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -1111,7 +1111,7 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
* dropped the page cache lock. Check for that.
* dropped the page cache lock. Check for that.
*/
*/
spin_lock
(
&
pagecache_lock
);
spin_lock
(
&
pagecache_lock
);
page
=
__find_page_nolock
(
&
inode
->
i_data
,
pgoff
,
*
hash
);
page
=
__find_page_nolock
(
&
inode
->
i_data
,
index
,
*
hash
);
if
(
page
)
if
(
page
)
goto
found_page
;
goto
found_page
;
}
}
...
@@ -1120,14 +1120,14 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
...
@@ -1120,14 +1120,14 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t *
* Ok, add the new page to the hash-queues...
* Ok, add the new page to the hash-queues...
*/
*/
page
=
cached_page
;
page
=
cached_page
;
__add_to_page_cache
(
page
,
&
inode
->
i_data
,
pgoff
,
hash
);
__add_to_page_cache
(
page
,
&
inode
->
i_data
,
index
,
hash
);
spin_unlock
(
&
pagecache_lock
);
spin_unlock
(
&
pagecache_lock
);
cached_page
=
NULL
;
cached_page
=
NULL
;
goto
readpage
;
goto
readpage
;
}
}
*
ppos
=
pos
;
*
ppos
=
((
loff_t
)
index
<<
PAGE_CACHE_SHIFT
)
+
offset
;
filp
->
f_reada
=
1
;
filp
->
f_reada
=
1
;
if
(
cached_page
)
if
(
cached_page
)
page_cache_free
(
cached_page
);
page_cache_free
(
cached_page
);
...
...
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