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
23db8620
Commit
23db8620
authored
May 17, 2013
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[readdir] convert nfs
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
725bebb2
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
25 additions
and
26 deletions
+25
-26
fs/nfs/dir.c
fs/nfs/dir.c
+25
-26
No files found.
fs/nfs/dir.c
View file @
23db8620
...
@@ -46,7 +46,7 @@
...
@@ -46,7 +46,7 @@
static
int
nfs_opendir
(
struct
inode
*
,
struct
file
*
);
static
int
nfs_opendir
(
struct
inode
*
,
struct
file
*
);
static
int
nfs_closedir
(
struct
inode
*
,
struct
file
*
);
static
int
nfs_closedir
(
struct
inode
*
,
struct
file
*
);
static
int
nfs_readdir
(
struct
file
*
,
void
*
,
filldir_t
);
static
int
nfs_readdir
(
struct
file
*
,
struct
dir_context
*
);
static
int
nfs_fsync_dir
(
struct
file
*
,
loff_t
,
loff_t
,
int
);
static
int
nfs_fsync_dir
(
struct
file
*
,
loff_t
,
loff_t
,
int
);
static
loff_t
nfs_llseek_dir
(
struct
file
*
,
loff_t
,
int
);
static
loff_t
nfs_llseek_dir
(
struct
file
*
,
loff_t
,
int
);
static
void
nfs_readdir_clear_array
(
struct
page
*
);
static
void
nfs_readdir_clear_array
(
struct
page
*
);
...
@@ -54,7 +54,7 @@ static void nfs_readdir_clear_array(struct page*);
...
@@ -54,7 +54,7 @@ static void nfs_readdir_clear_array(struct page*);
const
struct
file_operations
nfs_dir_operations
=
{
const
struct
file_operations
nfs_dir_operations
=
{
.
llseek
=
nfs_llseek_dir
,
.
llseek
=
nfs_llseek_dir
,
.
read
=
generic_read_dir
,
.
read
=
generic_read_dir
,
.
readdir
=
nfs_readdir
,
.
iterate
=
nfs_readdir
,
.
open
=
nfs_opendir
,
.
open
=
nfs_opendir
,
.
release
=
nfs_closedir
,
.
release
=
nfs_closedir
,
.
fsync
=
nfs_fsync_dir
,
.
fsync
=
nfs_fsync_dir
,
...
@@ -147,6 +147,7 @@ typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int);
...
@@ -147,6 +147,7 @@ typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int);
typedef
struct
{
typedef
struct
{
struct
file
*
file
;
struct
file
*
file
;
struct
page
*
page
;
struct
page
*
page
;
struct
dir_context
*
ctx
;
unsigned
long
page_index
;
unsigned
long
page_index
;
u64
*
dir_cookie
;
u64
*
dir_cookie
;
u64
last_cookie
;
u64
last_cookie
;
...
@@ -252,7 +253,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
...
@@ -252,7 +253,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
static
static
int
nfs_readdir_search_for_pos
(
struct
nfs_cache_array
*
array
,
nfs_readdir_descriptor_t
*
desc
)
int
nfs_readdir_search_for_pos
(
struct
nfs_cache_array
*
array
,
nfs_readdir_descriptor_t
*
desc
)
{
{
loff_t
diff
=
desc
->
file
->
f_
pos
-
desc
->
current_index
;
loff_t
diff
=
desc
->
ctx
->
pos
-
desc
->
current_index
;
unsigned
int
index
;
unsigned
int
index
;
if
(
diff
<
0
)
if
(
diff
<
0
)
...
@@ -289,7 +290,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
...
@@ -289,7 +290,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
||
(
nfsi
->
cache_validity
&
(
NFS_INO_INVALID_ATTR
|
NFS_INO_INVALID_DATA
)))
{
||
(
nfsi
->
cache_validity
&
(
NFS_INO_INVALID_ATTR
|
NFS_INO_INVALID_DATA
)))
{
ctx
->
duped
=
0
;
ctx
->
duped
=
0
;
ctx
->
attr_gencount
=
nfsi
->
attr_gencount
;
ctx
->
attr_gencount
=
nfsi
->
attr_gencount
;
}
else
if
(
new_pos
<
desc
->
file
->
f_
pos
)
{
}
else
if
(
new_pos
<
desc
->
ctx
->
pos
)
{
if
(
ctx
->
duped
>
0
if
(
ctx
->
duped
>
0
&&
ctx
->
dup_cookie
==
*
desc
->
dir_cookie
)
{
&&
ctx
->
dup_cookie
==
*
desc
->
dir_cookie
)
{
if
(
printk_ratelimit
())
{
if
(
printk_ratelimit
())
{
...
@@ -307,7 +308,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
...
@@ -307,7 +308,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
ctx
->
dup_cookie
=
*
desc
->
dir_cookie
;
ctx
->
dup_cookie
=
*
desc
->
dir_cookie
;
ctx
->
duped
=
-
1
;
ctx
->
duped
=
-
1
;
}
}
desc
->
file
->
f_
pos
=
new_pos
;
desc
->
ctx
->
pos
=
new_pos
;
desc
->
cache_entry_index
=
i
;
desc
->
cache_entry_index
=
i
;
return
0
;
return
0
;
}
}
...
@@ -405,13 +406,13 @@ int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
...
@@ -405,13 +406,13 @@ int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
}
}
static
static
bool
nfs_use_readdirplus
(
struct
inode
*
dir
,
struct
file
*
filp
)
bool
nfs_use_readdirplus
(
struct
inode
*
dir
,
struct
dir_context
*
ctx
)
{
{
if
(
!
nfs_server_capable
(
dir
,
NFS_CAP_READDIRPLUS
))
if
(
!
nfs_server_capable
(
dir
,
NFS_CAP_READDIRPLUS
))
return
false
;
return
false
;
if
(
test_and_clear_bit
(
NFS_INO_ADVISE_RDPLUS
,
&
NFS_I
(
dir
)
->
flags
))
if
(
test_and_clear_bit
(
NFS_INO_ADVISE_RDPLUS
,
&
NFS_I
(
dir
)
->
flags
))
return
true
;
return
true
;
if
(
filp
->
f_
pos
==
0
)
if
(
ctx
->
pos
==
0
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
...
@@ -702,8 +703,7 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
...
@@ -702,8 +703,7 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
* Once we've found the start of the dirent within a page: fill 'er up...
* Once we've found the start of the dirent within a page: fill 'er up...
*/
*/
static
static
int
nfs_do_filldir
(
nfs_readdir_descriptor_t
*
desc
,
void
*
dirent
,
int
nfs_do_filldir
(
nfs_readdir_descriptor_t
*
desc
)
filldir_t
filldir
)
{
{
struct
file
*
file
=
desc
->
file
;
struct
file
*
file
=
desc
->
file
;
int
i
=
0
;
int
i
=
0
;
...
@@ -721,13 +721,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
...
@@ -721,13 +721,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
struct
nfs_cache_array_entry
*
ent
;
struct
nfs_cache_array_entry
*
ent
;
ent
=
&
array
->
array
[
i
];
ent
=
&
array
->
array
[
i
];
if
(
filldir
(
dirent
,
ent
->
string
.
name
,
ent
->
string
.
len
,
if
(
!
dir_emit
(
desc
->
ctx
,
ent
->
string
.
name
,
ent
->
string
.
len
,
file
->
f_pos
,
nfs_compat_user_ino64
(
ent
->
ino
),
nfs_compat_user_ino64
(
ent
->
ino
),
ent
->
d_type
))
{
ent
->
d_type
)
<
0
)
{
desc
->
eof
=
1
;
desc
->
eof
=
1
;
break
;
break
;
}
}
file
->
f_
pos
++
;
desc
->
ctx
->
pos
++
;
if
(
i
<
(
array
->
size
-
1
))
if
(
i
<
(
array
->
size
-
1
))
*
desc
->
dir_cookie
=
array
->
array
[
i
+
1
].
cookie
;
*
desc
->
dir_cookie
=
array
->
array
[
i
+
1
].
cookie
;
else
else
...
@@ -759,8 +758,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
...
@@ -759,8 +758,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
* directory in the page cache by the time we get here.
* directory in the page cache by the time we get here.
*/
*/
static
inline
static
inline
int
uncached_readdir
(
nfs_readdir_descriptor_t
*
desc
,
void
*
dirent
,
int
uncached_readdir
(
nfs_readdir_descriptor_t
*
desc
)
filldir_t
filldir
)
{
{
struct
page
*
page
=
NULL
;
struct
page
*
page
=
NULL
;
int
status
;
int
status
;
...
@@ -785,7 +783,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
...
@@ -785,7 +783,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
if
(
status
<
0
)
if
(
status
<
0
)
goto
out_release
;
goto
out_release
;
status
=
nfs_do_filldir
(
desc
,
dirent
,
filldir
);
status
=
nfs_do_filldir
(
desc
);
out:
out:
dfprintk
(
DIRCACHE
,
"NFS: %s: returns %d
\n
"
,
dfprintk
(
DIRCACHE
,
"NFS: %s: returns %d
\n
"
,
...
@@ -800,35 +798,36 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
...
@@ -800,35 +798,36 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
last cookie cache takes care of the common case of reading the
last cookie cache takes care of the common case of reading the
whole directory.
whole directory.
*/
*/
static
int
nfs_readdir
(
struct
file
*
fil
p
,
void
*
dirent
,
filldir_t
filldir
)
static
int
nfs_readdir
(
struct
file
*
fil
e
,
struct
dir_context
*
ctx
)
{
{
struct
dentry
*
dentry
=
fil
p
->
f_path
.
dentry
;
struct
dentry
*
dentry
=
fil
e
->
f_path
.
dentry
;
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
inode
*
inode
=
dentry
->
d_inode
;
nfs_readdir_descriptor_t
my_desc
,
nfs_readdir_descriptor_t
my_desc
,
*
desc
=
&
my_desc
;
*
desc
=
&
my_desc
;
struct
nfs_open_dir_context
*
dir_ctx
=
fil
p
->
private_data
;
struct
nfs_open_dir_context
*
dir_ctx
=
fil
e
->
private_data
;
int
res
;
int
res
;
dfprintk
(
FILE
,
"NFS: readdir(%s/%s) starting at cookie %llu
\n
"
,
dfprintk
(
FILE
,
"NFS: readdir(%s/%s) starting at cookie %llu
\n
"
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
,
(
long
long
)
filp
->
f_
pos
);
(
long
long
)
ctx
->
pos
);
nfs_inc_stats
(
inode
,
NFSIOS_VFSGETDENTS
);
nfs_inc_stats
(
inode
,
NFSIOS_VFSGETDENTS
);
/*
/*
*
filp->f_
pos points to the dirent entry number.
*
ctx->
pos points to the dirent entry number.
* *desc->dir_cookie has the cookie for the next entry. We have
* *desc->dir_cookie has the cookie for the next entry. We have
* to either find the entry with the appropriate number or
* to either find the entry with the appropriate number or
* revalidate the cookie.
* revalidate the cookie.
*/
*/
memset
(
desc
,
0
,
sizeof
(
*
desc
));
memset
(
desc
,
0
,
sizeof
(
*
desc
));
desc
->
file
=
filp
;
desc
->
file
=
file
;
desc
->
ctx
=
ctx
;
desc
->
dir_cookie
=
&
dir_ctx
->
dir_cookie
;
desc
->
dir_cookie
=
&
dir_ctx
->
dir_cookie
;
desc
->
decode
=
NFS_PROTO
(
inode
)
->
decode_dirent
;
desc
->
decode
=
NFS_PROTO
(
inode
)
->
decode_dirent
;
desc
->
plus
=
nfs_use_readdirplus
(
inode
,
filp
)
?
1
:
0
;
desc
->
plus
=
nfs_use_readdirplus
(
inode
,
ctx
)
?
1
:
0
;
nfs_block_sillyrename
(
dentry
);
nfs_block_sillyrename
(
dentry
);
res
=
nfs_revalidate_mapping
(
inode
,
fil
p
->
f_mapping
);
res
=
nfs_revalidate_mapping
(
inode
,
fil
e
->
f_mapping
);
if
(
res
<
0
)
if
(
res
<
0
)
goto
out
;
goto
out
;
...
@@ -840,7 +839,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
...
@@ -840,7 +839,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
/* This means either end of directory */
/* This means either end of directory */
if
(
*
desc
->
dir_cookie
&&
desc
->
eof
==
0
)
{
if
(
*
desc
->
dir_cookie
&&
desc
->
eof
==
0
)
{
/* Or that the server has 'lost' a cookie */
/* Or that the server has 'lost' a cookie */
res
=
uncached_readdir
(
desc
,
dirent
,
filldir
);
res
=
uncached_readdir
(
desc
);
if
(
res
==
0
)
if
(
res
==
0
)
continue
;
continue
;
}
}
...
@@ -857,7 +856,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
...
@@ -857,7 +856,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if
(
res
<
0
)
if
(
res
<
0
)
break
;
break
;
res
=
nfs_do_filldir
(
desc
,
dirent
,
filldir
);
res
=
nfs_do_filldir
(
desc
);
if
(
res
<
0
)
if
(
res
<
0
)
break
;
break
;
}
while
(
!
desc
->
eof
);
}
while
(
!
desc
->
eof
);
...
...
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