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
c6e6354f
Commit
c6e6354f
authored
May 21, 2002
by
Alexander Viro
Committed by
Linus Torvalds
May 21, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] clean up readdir() for in-memory
sane readdir() for ramfs-style filesystems
parent
cc41b90f
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
93 additions
and
44 deletions
+93
-44
fs/autofs4/root.c
fs/autofs4/root.c
+3
-0
fs/libfs.c
fs/libfs.c
+84
-44
include/linux/fs.h
include/linux/fs.h
+3
-0
kernel/ksyms.c
kernel/ksyms.c
+3
-0
No files found.
fs/autofs4/root.c
View file @
c6e6354f
...
...
@@ -27,6 +27,9 @@ static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigne
static
struct
dentry
*
autofs4_root_lookup
(
struct
inode
*
,
struct
dentry
*
);
struct
file_operations
autofs4_root_operations
=
{
open:
dcache_dir_open
,
release:
dcache_dir_close
,
llseek:
dcache_dir_lseek
,
read:
generic_read_dir
,
readdir:
dcache_readdir
,
ioctl:
autofs4_root_ioctl
,
...
...
fs/libfs.c
View file @
c6e6354f
...
...
@@ -30,6 +30,59 @@ int simple_sync_file(struct file * file, struct dentry *dentry, int datasync)
return
0
;
}
int
dcache_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
static
struct
qstr
cursor_name
=
{
len
:
1
,
name
:
"."
};
file
->
private_data
=
d_alloc
(
file
->
f_dentry
,
&
cursor_name
);
return
file
->
private_data
?
0
:
-
ENOMEM
;
}
int
dcache_dir_close
(
struct
inode
*
inode
,
struct
file
*
file
)
{
dput
(
file
->
private_data
);
return
0
;
}
loff_t
dcache_dir_lseek
(
struct
file
*
file
,
loff_t
offset
,
int
origin
)
{
down
(
&
file
->
f_dentry
->
d_inode
->
i_sem
);
switch
(
origin
)
{
case
1
:
offset
+=
file
->
f_pos
;
case
0
:
if
(
offset
>=
0
)
break
;
default:
up
(
&
file
->
f_dentry
->
d_inode
->
i_sem
);
return
-
EINVAL
;
}
if
(
offset
!=
file
->
f_pos
)
{
file
->
f_pos
=
offset
;
if
(
file
->
f_pos
>=
2
)
{
struct
list_head
*
p
;
struct
dentry
*
cursor
=
file
->
private_data
;
loff_t
n
=
file
->
f_pos
-
2
;
spin_lock
(
&
dcache_lock
);
p
=
file
->
f_dentry
->
d_subdirs
.
next
;
while
(
n
&&
p
!=
&
file
->
f_dentry
->
d_subdirs
)
{
struct
dentry
*
next
;
next
=
list_entry
(
p
,
struct
dentry
,
d_child
);
if
(
!
list_empty
(
&
next
->
d_hash
)
&&
next
->
d_inode
)
n
--
;
p
=
p
->
next
;
}
list_del
(
&
cursor
->
d_child
);
list_add_tail
(
&
cursor
->
d_child
,
p
);
spin_unlock
(
&
dcache_lock
);
}
}
up
(
&
file
->
f_dentry
->
d_inode
->
i_sem
);
return
offset
;
}
/*
* Directory is locked and all positive dentries in it are safe, since
* for ramfs-type trees they can't go away without unlink() or rmdir(),
...
...
@@ -38,67 +91,51 @@ int simple_sync_file(struct file * file, struct dentry *dentry, int datasync)
int
dcache_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
{
int
i
;
struct
dentry
*
dentry
=
filp
->
f_dentry
;
struct
dentry
*
cursor
=
filp
->
private_data
;
struct
list_head
*
p
,
*
q
=
&
cursor
->
d_child
;
ino_t
ino
;
int
i
=
filp
->
f_pos
;
lock_kernel
();
i
=
filp
->
f_pos
;
switch
(
i
)
{
case
0
:
if
(
filldir
(
dirent
,
"."
,
1
,
i
,
dentry
->
d_inode
->
i_ino
,
DT_DIR
)
<
0
)
ino
=
dentry
->
d_inode
->
i_ino
;
if
(
filldir
(
dirent
,
"."
,
1
,
i
,
ino
,
DT_DIR
)
<
0
)
break
;
i
++
;
filp
->
f_pos
++
;
i
++
;
/* fallthrough */
case
1
:
if
(
filldir
(
dirent
,
".."
,
2
,
i
,
parent_ino
(
dentry
),
DT_DIR
)
<
0
)
ino
=
parent_ino
(
dentry
);
if
(
filldir
(
dirent
,
".."
,
2
,
i
,
ino
,
DT_DIR
)
<
0
)
break
;
i
++
;
filp
->
f_pos
++
;
i
++
;
/* fallthrough */
default:
{
struct
list_head
*
list
;
int
j
=
i
-
2
;
default:
spin_lock
(
&
dcache_lock
);
list
=
dentry
->
d_subdirs
.
next
;
for
(;;)
{
if
(
list
==
&
dentry
->
d_subdirs
)
{
spin_unlock
(
&
dcache_lock
);
unlock_kernel
();
return
0
;
}
if
(
!
j
)
break
;
j
--
;
list
=
list
->
next
;
if
(
filp
->
f_pos
==
2
)
{
list_del
(
q
);
list_add
(
q
,
&
dentry
->
d_subdirs
);
}
for
(
p
=
q
->
next
;
p
!=
&
dentry
->
d_subdirs
;
p
=
p
->
next
)
{
struct
dentry
*
next
;
next
=
list_entry
(
p
,
struct
dentry
,
d_child
);
if
(
list_empty
(
&
next
->
d_hash
)
||
!
next
->
d_inode
)
continue
;
while
(
1
)
{
struct
dentry
*
de
=
list_entry
(
list
,
struct
dentry
,
d_child
);
/*
* See comment on top of function on why we
* can just drop the lock here..
*/
if
(
!
list_empty
(
&
de
->
d_hash
)
&&
de
->
d_inode
)
{
spin_unlock
(
&
dcache_lock
);
if
(
filldir
(
dirent
,
de
->
d_name
.
name
,
de
->
d_name
.
len
,
filp
->
f_pos
,
de
->
d_inode
->
i_ino
,
DT_UNKNOWN
)
<
0
)
break
;
if
(
filldir
(
dirent
,
next
->
d_name
.
name
,
next
->
d_name
.
len
,
filp
->
f_pos
,
next
->
d_inode
->
i_ino
,
DT_UNKNOWN
)
<
0
)
return
0
;
spin_lock
(
&
dcache_lock
);
}
/* next is still alive */
list_del
(
q
);
list_add
(
q
,
p
);
p
=
q
;
filp
->
f_pos
++
;
list
=
list
->
next
;
if
(
list
!=
&
dentry
->
d_subdirs
)
continue
;
spin_unlock
(
&
dcache_lock
);
break
;
}
}
spin_unlock
(
&
dcache_lock
);
}
unlock_kernel
();
return
0
;
}
...
...
@@ -108,6 +145,9 @@ ssize_t generic_read_dir(struct file *filp, char *buf, size_t siz, loff_t *ppos)
}
struct
file_operations
simple_dir_operations
=
{
open:
dcache_dir_open
,
release:
dcache_dir_close
,
llseek:
dcache_dir_lseek
,
read:
generic_read_dir
,
readdir:
dcache_readdir
,
};
...
...
include/linux/fs.h
View file @
c6e6354f
...
...
@@ -1296,6 +1296,9 @@ extern void drop_super(struct super_block *sb);
extern
kdev_t
ROOT_DEV
;
extern
char
root_device_name
[];
extern
int
dcache_dir_open
(
struct
inode
*
,
struct
file
*
);
extern
int
dcache_dir_close
(
struct
inode
*
,
struct
file
*
);
extern
loff_t
dcache_dir_lseek
(
struct
file
*
,
loff_t
,
int
);
extern
int
dcache_readdir
(
struct
file
*
,
void
*
,
filldir_t
);
extern
int
simple_statfs
(
struct
super_block
*
,
struct
statfs
*
);
extern
struct
dentry
*
simple_lookup
(
struct
inode
*
,
struct
dentry
*
);
...
...
kernel/ksyms.c
View file @
c6e6354f
...
...
@@ -281,6 +281,9 @@ EXPORT_SYMBOL(__get_lease);
EXPORT_SYMBOL
(
lease_get_mtime
);
EXPORT_SYMBOL
(
lock_may_read
);
EXPORT_SYMBOL
(
lock_may_write
);
EXPORT_SYMBOL
(
dcache_dir_open
);
EXPORT_SYMBOL
(
dcache_dir_close
);
EXPORT_SYMBOL
(
dcache_dir_lseek
);
EXPORT_SYMBOL
(
dcache_readdir
);
EXPORT_SYMBOL
(
simple_statfs
);
EXPORT_SYMBOL
(
simple_lookup
);
...
...
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