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
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