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
3704412b
Commit
3704412b
authored
May 22, 2013
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[readdir] convert ocfs2
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
2c6a2473
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
61 additions
and
113 deletions
+61
-113
fs/ocfs2/dir.c
fs/ocfs2/dir.c
+50
-101
fs/ocfs2/dir.h
fs/ocfs2/dir.h
+2
-3
fs/ocfs2/file.c
fs/ocfs2/file.c
+2
-2
fs/ocfs2/journal.c
fs/ocfs2/journal.c
+7
-7
No files found.
fs/ocfs2/dir.c
View file @
3704412b
...
...
@@ -1761,11 +1761,10 @@ int __ocfs2_add_entry(handle_t *handle,
static
int
ocfs2_dir_foreach_blk_id
(
struct
inode
*
inode
,
u64
*
f_version
,
loff_t
*
f_pos
,
void
*
priv
,
filldir_t
filldir
,
int
*
filldir_err
)
struct
dir_context
*
ctx
)
{
int
ret
,
i
,
filldir_ret
;
unsigned
long
offset
=
*
f_
pos
;
int
ret
,
i
;
unsigned
long
offset
=
ctx
->
pos
;
struct
buffer_head
*
di_bh
=
NULL
;
struct
ocfs2_dinode
*
di
;
struct
ocfs2_inline_data
*
data
;
...
...
@@ -1781,8 +1780,7 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
di
=
(
struct
ocfs2_dinode
*
)
di_bh
->
b_data
;
data
=
&
di
->
id2
.
i_data
;
while
(
*
f_pos
<
i_size_read
(
inode
))
{
revalidate:
while
(
ctx
->
pos
<
i_size_read
(
inode
))
{
/* If the dir block has changed since the last call to
* readdir(2), then we might be pointing to an invalid
* dirent right now. Scan from the start of the block
...
...
@@ -1802,50 +1800,31 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
break
;
i
+=
le16_to_cpu
(
de
->
rec_len
);
}
*
f_
pos
=
offset
=
i
;
ctx
->
pos
=
offset
=
i
;
*
f_version
=
inode
->
i_version
;
}
de
=
(
struct
ocfs2_dir_entry
*
)
(
data
->
id_data
+
*
f_
pos
);
if
(
!
ocfs2_check_dir_entry
(
inode
,
de
,
di_bh
,
*
f_
pos
))
{
de
=
(
struct
ocfs2_dir_entry
*
)
(
data
->
id_data
+
ctx
->
pos
);
if
(
!
ocfs2_check_dir_entry
(
inode
,
de
,
di_bh
,
ctx
->
pos
))
{
/* On error, skip the f_pos to the end. */
*
f_
pos
=
i_size_read
(
inode
);
goto
out
;
ctx
->
pos
=
i_size_read
(
inode
);
break
;
}
offset
+=
le16_to_cpu
(
de
->
rec_len
);
if
(
le64_to_cpu
(
de
->
inode
))
{
/* We might block in the next section
* if the data destination is
* currently swapped out. So, use a
* version stamp to detect whether or
* not the directory has been modified
* during the copy operation.
*/
u64
version
=
*
f_version
;
unsigned
char
d_type
=
DT_UNKNOWN
;
if
(
de
->
file_type
<
OCFS2_FT_MAX
)
d_type
=
ocfs2_filetype_table
[
de
->
file_type
];
filldir_ret
=
filldir
(
priv
,
de
->
name
,
de
->
name_len
,
*
f_pos
,
le64_to_cpu
(
de
->
inode
),
d_type
);
if
(
filldir_ret
)
{
if
(
filldir_err
)
*
filldir_err
=
filldir_ret
;
break
;
}
if
(
version
!=
*
f_version
)
goto
revalidate
;
if
(
!
dir_emit
(
ctx
,
de
->
name
,
de
->
name_len
,
le64_to_cpu
(
de
->
inode
),
d_type
))
goto
out
;
}
*
f_
pos
+=
le16_to_cpu
(
de
->
rec_len
);
ctx
->
pos
+=
le16_to_cpu
(
de
->
rec_len
);
}
out:
brelse
(
di_bh
);
return
0
;
}
...
...
@@ -1855,27 +1834,26 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
*/
static
int
ocfs2_dir_foreach_blk_el
(
struct
inode
*
inode
,
u64
*
f_version
,
loff_t
*
f_pos
,
void
*
priv
,
filldir_t
filldir
,
int
*
filldir_err
)
struct
dir_context
*
ctx
,
bool
persist
)
{
int
error
=
0
;
unsigned
long
offset
,
blk
,
last_ra_blk
=
0
;
int
i
,
stored
;
int
i
;
struct
buffer_head
*
bh
,
*
tmp
;
struct
ocfs2_dir_entry
*
de
;
struct
super_block
*
sb
=
inode
->
i_sb
;
unsigned
int
ra_sectors
=
16
;
int
stored
=
0
;
stored
=
0
;
bh
=
NULL
;
offset
=
(
*
f_pos
)
&
(
sb
->
s_blocksize
-
1
);
offset
=
ctx
->
pos
&
(
sb
->
s_blocksize
-
1
);
while
(
!
error
&&
!
stored
&&
*
f_
pos
<
i_size_read
(
inode
))
{
blk
=
(
*
f_pos
)
>>
sb
->
s_blocksize_bits
;
while
(
ctx
->
pos
<
i_size_read
(
inode
))
{
blk
=
ctx
->
pos
>>
sb
->
s_blocksize_bits
;
if
(
ocfs2_read_dir_block
(
inode
,
blk
,
&
bh
,
0
))
{
/* Skip the corrupt dirblock and keep trying */
*
f_
pos
+=
sb
->
s_blocksize
-
offset
;
ctx
->
pos
+=
sb
->
s_blocksize
-
offset
;
continue
;
}
...
...
@@ -1897,7 +1875,6 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
ra_sectors
=
8
;
}
revalidate:
/* If the dir block has changed since the last call to
* readdir(2), then we might be pointing to an invalid
* dirent right now. Scan from the start of the block
...
...
@@ -1917,93 +1894,64 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
i
+=
le16_to_cpu
(
de
->
rec_len
);
}
offset
=
i
;
*
f_pos
=
((
*
f_pos
)
&
~
(
sb
->
s_blocksize
-
1
))
ctx
->
pos
=
(
ctx
->
pos
&
~
(
sb
->
s_blocksize
-
1
))
|
offset
;
*
f_version
=
inode
->
i_version
;
}
while
(
!
error
&&
*
f_
pos
<
i_size_read
(
inode
)
while
(
ctx
->
pos
<
i_size_read
(
inode
)
&&
offset
<
sb
->
s_blocksize
)
{
de
=
(
struct
ocfs2_dir_entry
*
)
(
bh
->
b_data
+
offset
);
if
(
!
ocfs2_check_dir_entry
(
inode
,
de
,
bh
,
offset
))
{
/* On error, skip the f_pos to the
next block. */
*
f_pos
=
((
*
f_pos
)
|
(
sb
->
s_blocksize
-
1
))
+
1
;
ctx
->
pos
=
(
ctx
->
pos
|
(
sb
->
s_blocksize
-
1
))
+
1
;
brelse
(
bh
);
goto
out
;
continue
;
}
offset
+=
le16_to_cpu
(
de
->
rec_len
);
if
(
le64_to_cpu
(
de
->
inode
))
{
/* We might block in the next section
* if the data destination is
* currently swapped out. So, use a
* version stamp to detect whether or
* not the directory has been modified
* during the copy operation.
*/
unsigned
long
version
=
*
f_version
;
unsigned
char
d_type
=
DT_UNKNOWN
;
if
(
de
->
file_type
<
OCFS2_FT_MAX
)
d_type
=
ocfs2_filetype_table
[
de
->
file_type
];
error
=
filldir
(
priv
,
de
->
name
,
if
(
!
dir_emit
(
ctx
,
de
->
name
,
de
->
name_len
,
*
f_pos
,
le64_to_cpu
(
de
->
inode
),
d_type
);
if
(
error
)
{
if
(
filldir_err
)
*
filldir_err
=
error
;
break
;
d_type
))
{
brelse
(
bh
);
return
0
;
}
if
(
version
!=
*
f_version
)
goto
revalidate
;
stored
++
;
stored
++
;
}
*
f_pos
+=
le16_to_cpu
(
de
->
rec_len
);
offset
+=
le16_to_cpu
(
de
->
rec_len
);
ctx
->
pos
+=
le16_to_cpu
(
de
->
rec_len
);
}
offset
=
0
;
brelse
(
bh
);
bh
=
NULL
;
if
(
!
persist
&&
stored
)
break
;
}
stored
=
0
;
out:
return
stored
;
return
0
;
}
static
int
ocfs2_dir_foreach_blk
(
struct
inode
*
inode
,
u64
*
f_version
,
loff_t
*
f_pos
,
void
*
priv
,
filldir_t
filldir
,
int
*
filldir_err
)
struct
dir_context
*
ctx
,
bool
persist
)
{
if
(
OCFS2_I
(
inode
)
->
ip_dyn_features
&
OCFS2_INLINE_DATA_FL
)
return
ocfs2_dir_foreach_blk_id
(
inode
,
f_version
,
f_pos
,
priv
,
filldir
,
filldir_err
);
return
ocfs2_dir_foreach_blk_el
(
inode
,
f_version
,
f_pos
,
priv
,
filldir
,
filldir_err
);
return
ocfs2_dir_foreach_blk_id
(
inode
,
f_version
,
ctx
);
return
ocfs2_dir_foreach_blk_el
(
inode
,
f_version
,
ctx
,
persist
);
}
/*
* This is intended to be called from inside other kernel functions,
* so we fake some arguments.
*/
int
ocfs2_dir_foreach
(
struct
inode
*
inode
,
loff_t
*
f_pos
,
void
*
priv
,
filldir_t
filldir
)
int
ocfs2_dir_foreach
(
struct
inode
*
inode
,
struct
dir_context
*
ctx
)
{
int
ret
=
0
,
filldir_err
=
0
;
u64
version
=
inode
->
i_version
;
while
(
*
f_pos
<
i_size_read
(
inode
))
{
ret
=
ocfs2_dir_foreach_blk
(
inode
,
&
version
,
f_pos
,
priv
,
filldir
,
&
filldir_err
);
if
(
ret
||
filldir_err
)
break
;
}
if
(
ret
>
0
)
ret
=
-
EIO
;
ocfs2_dir_foreach_blk
(
inode
,
&
version
,
ctx
,
true
);
return
0
;
}
...
...
@@ -2011,15 +1959,15 @@ int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv,
* ocfs2_readdir()
*
*/
int
ocfs2_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
int
ocfs2_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
)
{
int
error
=
0
;
struct
inode
*
inode
=
file_inode
(
fil
p
);
struct
inode
*
inode
=
file_inode
(
fil
e
);
int
lock_level
=
0
;
trace_ocfs2_readdir
((
unsigned
long
long
)
OCFS2_I
(
inode
)
->
ip_blkno
);
error
=
ocfs2_inode_lock_atime
(
inode
,
fil
p
->
f_path
.
mnt
,
&
lock_level
);
error
=
ocfs2_inode_lock_atime
(
inode
,
fil
e
->
f_path
.
mnt
,
&
lock_level
);
if
(
lock_level
&&
error
>=
0
)
{
/* We release EX lock which used to update atime
* and get PR lock again to reduce contention
...
...
@@ -2035,8 +1983,7 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
goto
bail_nolock
;
}
error
=
ocfs2_dir_foreach_blk
(
inode
,
&
filp
->
f_version
,
&
filp
->
f_pos
,
dirent
,
filldir
,
NULL
);
error
=
ocfs2_dir_foreach_blk
(
inode
,
&
file
->
f_version
,
ctx
,
false
);
ocfs2_inode_unlock
(
inode
,
lock_level
);
if
(
error
)
...
...
@@ -2120,6 +2067,7 @@ int ocfs2_check_dir_for_entry(struct inode *dir,
}
struct
ocfs2_empty_dir_priv
{
struct
dir_context
ctx
;
unsigned
seen_dot
;
unsigned
seen_dot_dot
;
unsigned
seen_other
;
...
...
@@ -2204,8 +2152,9 @@ static int ocfs2_empty_dir_dx(struct inode *inode,
int
ocfs2_empty_dir
(
struct
inode
*
inode
)
{
int
ret
;
loff_t
start
=
0
;
struct
ocfs2_empty_dir_priv
priv
;
struct
ocfs2_empty_dir_priv
priv
=
{
.
ctx
.
actor
=
ocfs2_empty_dir_filldir
};
memset
(
&
priv
,
0
,
sizeof
(
priv
));
...
...
@@ -2219,7 +2168,7 @@ int ocfs2_empty_dir(struct inode *inode)
*/
}
ret
=
ocfs2_dir_foreach
(
inode
,
&
start
,
&
priv
,
ocfs2_empty_dir_filldir
);
ret
=
ocfs2_dir_foreach
(
inode
,
&
priv
.
ctx
);
if
(
ret
)
mlog_errno
(
ret
);
...
...
fs/ocfs2/dir.h
View file @
3704412b
...
...
@@ -92,9 +92,8 @@ int ocfs2_find_files_on_disk(const char *name,
struct
ocfs2_dir_lookup_result
*
res
);
int
ocfs2_lookup_ino_from_name
(
struct
inode
*
dir
,
const
char
*
name
,
int
namelen
,
u64
*
blkno
);
int
ocfs2_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
);
int
ocfs2_dir_foreach
(
struct
inode
*
inode
,
loff_t
*
f_pos
,
void
*
priv
,
filldir_t
filldir
);
int
ocfs2_readdir
(
struct
file
*
file
,
struct
dir_context
*
ctx
);
int
ocfs2_dir_foreach
(
struct
inode
*
inode
,
struct
dir_context
*
ctx
);
int
ocfs2_prepare_dir_for_insert
(
struct
ocfs2_super
*
osb
,
struct
inode
*
dir
,
struct
buffer_head
*
parent_fe_bh
,
...
...
fs/ocfs2/file.c
View file @
3704412b
...
...
@@ -2712,7 +2712,7 @@ const struct file_operations ocfs2_fops = {
const
struct
file_operations
ocfs2_dops
=
{
.
llseek
=
generic_file_llseek
,
.
read
=
generic_read_dir
,
.
readdir
=
ocfs2_readdir
,
.
iterate
=
ocfs2_readdir
,
.
fsync
=
ocfs2_sync_file
,
.
release
=
ocfs2_dir_release
,
.
open
=
ocfs2_dir_open
,
...
...
@@ -2759,7 +2759,7 @@ const struct file_operations ocfs2_fops_no_plocks = {
const
struct
file_operations
ocfs2_dops_no_plocks
=
{
.
llseek
=
generic_file_llseek
,
.
read
=
generic_read_dir
,
.
readdir
=
ocfs2_readdir
,
.
iterate
=
ocfs2_readdir
,
.
fsync
=
ocfs2_sync_file
,
.
release
=
ocfs2_dir_release
,
.
open
=
ocfs2_dir_open
,
...
...
fs/ocfs2/journal.c
View file @
3704412b
...
...
@@ -1941,6 +1941,7 @@ void ocfs2_orphan_scan_start(struct ocfs2_super *osb)
}
struct
ocfs2_orphan_filldir_priv
{
struct
dir_context
ctx
;
struct
inode
*
head
;
struct
ocfs2_super
*
osb
;
};
...
...
@@ -1977,11 +1978,11 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
{
int
status
;
struct
inode
*
orphan_dir_inode
=
NULL
;
struct
ocfs2_orphan_filldir_priv
priv
;
loff_t
pos
=
0
;
priv
.
osb
=
osb
;
priv
.
head
=
*
head
;
struct
ocfs2_orphan_filldir_priv
priv
=
{
.
ctx
.
actor
=
ocfs2_orphan_filldir
,
.
osb
=
osb
,
.
head
=
*
head
}
;
orphan_dir_inode
=
ocfs2_get_system_file_inode
(
osb
,
ORPHAN_DIR_SYSTEM_INODE
,
...
...
@@ -1999,8 +2000,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
goto
out
;
}
status
=
ocfs2_dir_foreach
(
orphan_dir_inode
,
&
pos
,
&
priv
,
ocfs2_orphan_filldir
);
status
=
ocfs2_dir_foreach
(
orphan_dir_inode
,
&
priv
.
ctx
);
if
(
status
)
{
mlog_errno
(
status
);
goto
out_cluster
;
...
...
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