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
0714a533
Commit
0714a533
authored
Nov 24, 2011
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vfs: now it can be done - make mnt_parent point to struct mount
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
3376f34f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
53 additions
and
50 deletions
+53
-50
fs/dcache.c
fs/dcache.c
+4
-3
fs/mount.h
fs/mount.h
+2
-2
fs/namei.c
fs/namei.c
+13
-11
fs/namespace.c
fs/namespace.c
+26
-26
fs/pnode.c
fs/pnode.c
+8
-8
No files found.
fs/dcache.c
View file @
0714a533
...
...
@@ -2452,6 +2452,7 @@ static int prepend_path(const struct path *path,
{
struct
dentry
*
dentry
=
path
->
dentry
;
struct
vfsmount
*
vfsmnt
=
path
->
mnt
;
struct
mount
*
mnt
=
real_mount
(
vfsmnt
);
bool
slash
=
false
;
int
error
=
0
;
...
...
@@ -2460,12 +2461,12 @@ static int prepend_path(const struct path *path,
struct
dentry
*
parent
;
if
(
dentry
==
vfsmnt
->
mnt_root
||
IS_ROOT
(
dentry
))
{
struct
mount
*
mnt
=
real_mount
(
vfsmnt
);
/* Global root? */
if
(
!
mnt_has_parent
(
mnt
))
goto
global_root
;
dentry
=
vfsmnt
->
mnt_mountpoint
;
vfsmnt
=
mnt
->
mnt_parent
;
dentry
=
mnt
->
mnt
.
mnt_mountpoint
;
mnt
=
mnt
->
mnt_parent
;
vfsmnt
=
&
mnt
->
mnt
;
continue
;
}
parent
=
dentry
->
d_parent
;
...
...
fs/mount.h
View file @
0714a533
...
...
@@ -2,7 +2,7 @@
struct
mount
{
struct
list_head
mnt_hash
;
struct
vfs
mount
*
mnt_parent
;
struct
mount
*
mnt_parent
;
struct
vfsmount
mnt
;
};
...
...
@@ -13,7 +13,7 @@ static inline struct mount *real_mount(struct vfsmount *mnt)
static
inline
int
mnt_has_parent
(
struct
mount
*
mnt
)
{
return
&
mnt
->
mnt
!=
mnt
->
mnt_parent
;
return
mnt
!=
mnt
->
mnt_parent
;
}
extern
struct
mount
*
__lookup_mnt
(
struct
vfsmount
*
,
struct
dentry
*
,
int
);
fs/namei.c
View file @
0714a533
...
...
@@ -677,36 +677,38 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
static
int
follow_up_rcu
(
struct
path
*
path
)
{
struct
vfsmount
*
parent
;
struct
mount
*
mnt
=
real_mount
(
path
->
mnt
);
struct
mount
*
parent
;
struct
dentry
*
mountpoint
;
parent
=
real_mount
(
path
->
mnt
)
->
mnt_parent
;
if
(
pare
nt
==
path
->
mnt
)
parent
=
mnt
->
mnt_parent
;
if
(
&
parent
->
m
nt
==
path
->
mnt
)
return
0
;
mountpoint
=
path
->
mnt
->
mnt_mountpoint
;
mountpoint
=
mnt
->
mnt
.
mnt_mountpoint
;
path
->
dentry
=
mountpoint
;
path
->
mnt
=
pare
nt
;
path
->
mnt
=
&
parent
->
m
nt
;
return
1
;
}
int
follow_up
(
struct
path
*
path
)
{
struct
vfsmount
*
parent
;
struct
mount
*
mnt
=
real_mount
(
path
->
mnt
);
struct
mount
*
parent
;
struct
dentry
*
mountpoint
;
br_read_lock
(
vfsmount_lock
);
parent
=
real_mount
(
path
->
mnt
)
->
mnt_parent
;
if
(
pare
nt
==
path
->
mnt
)
{
parent
=
mnt
->
mnt_parent
;
if
(
&
parent
->
m
nt
==
path
->
mnt
)
{
br_read_unlock
(
vfsmount_lock
);
return
0
;
}
mntget
(
pare
nt
);
mountpoint
=
dget
(
path
->
mnt
->
mnt_mountpoint
);
mntget
(
&
parent
->
m
nt
);
mountpoint
=
dget
(
mnt
->
mnt
.
mnt_mountpoint
);
br_read_unlock
(
vfsmount_lock
);
dput
(
path
->
dentry
);
path
->
dentry
=
mountpoint
;
mntput
(
path
->
mnt
);
path
->
mnt
=
pare
nt
;
path
->
mnt
=
&
parent
->
m
nt
;
return
1
;
}
...
...
fs/namespace.c
View file @
0714a533
...
...
@@ -476,7 +476,7 @@ struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
if
(
tmp
==
head
)
break
;
p
=
list_entry
(
tmp
,
struct
mount
,
mnt_hash
);
if
(
p
->
mnt_pare
nt
==
mnt
&&
p
->
mnt
.
mnt_mountpoint
==
dentry
)
{
if
(
&
p
->
mnt_parent
->
m
nt
==
mnt
&&
p
->
mnt
.
mnt_mountpoint
==
dentry
)
{
found
=
p
;
break
;
}
...
...
@@ -558,8 +558,8 @@ static void dentry_reset_mounted(struct dentry *dentry)
static
void
detach_mnt
(
struct
mount
*
mnt
,
struct
path
*
old_path
)
{
old_path
->
dentry
=
mnt
->
mnt
.
mnt_mountpoint
;
old_path
->
mnt
=
mnt
->
mnt_pare
nt
;
mnt
->
mnt_parent
=
&
mnt
->
mnt
;
old_path
->
mnt
=
&
mnt
->
mnt_parent
->
m
nt
;
mnt
->
mnt_parent
=
mnt
;
mnt
->
mnt
.
mnt_mountpoint
=
mnt
->
mnt
.
mnt_root
;
list_del_init
(
&
mnt
->
mnt
.
mnt_child
);
list_del_init
(
&
mnt
->
mnt_hash
);
...
...
@@ -572,7 +572,7 @@ static void detach_mnt(struct mount *mnt, struct path *old_path)
void
mnt_set_mountpoint
(
struct
vfsmount
*
mnt
,
struct
dentry
*
dentry
,
struct
mount
*
child_mnt
)
{
child_mnt
->
mnt_parent
=
mntget
(
mnt
);
child_mnt
->
mnt_parent
=
real_mount
(
mntget
(
mnt
)
);
child_mnt
->
mnt
.
mnt_mountpoint
=
dget
(
dentry
);
spin_lock
(
&
dentry
->
d_lock
);
dentry
->
d_flags
|=
DCACHE_MOUNTED
;
...
...
@@ -610,12 +610,12 @@ static inline void __mnt_make_shortterm(struct vfsmount *mnt)
*/
static
void
commit_tree
(
struct
mount
*
mnt
)
{
struct
vfs
mount
*
parent
=
mnt
->
mnt_parent
;
struct
mount
*
parent
=
mnt
->
mnt_parent
;
struct
vfsmount
*
m
;
LIST_HEAD
(
head
);
struct
mnt_namespace
*
n
=
parent
->
mnt_ns
;
struct
mnt_namespace
*
n
=
parent
->
mnt
.
mnt
_ns
;
BUG_ON
(
parent
==
&
mnt
->
mnt
);
BUG_ON
(
parent
==
mnt
);
list_add_tail
(
&
head
,
&
mnt
->
mnt
.
mnt_list
);
list_for_each_entry
(
m
,
&
head
,
mnt_list
)
{
...
...
@@ -626,8 +626,8 @@ static void commit_tree(struct mount *mnt)
list_splice
(
&
head
,
n
->
list
.
prev
);
list_add_tail
(
&
mnt
->
mnt_hash
,
mount_hashtable
+
hash
(
pare
nt
,
mnt
->
mnt
.
mnt_mountpoint
));
list_add_tail
(
&
mnt
->
mnt
.
mnt_child
,
&
parent
->
mnt_mounts
);
hash
(
&
parent
->
m
nt
,
mnt
->
mnt
.
mnt_mountpoint
));
list_add_tail
(
&
mnt
->
mnt
.
mnt_child
,
&
parent
->
mnt
.
mnt
_mounts
);
touch_mnt_namespace
(
n
);
}
...
...
@@ -639,9 +639,9 @@ static struct mount *next_mnt(struct mount *p, struct vfsmount *root)
if
(
&
p
->
mnt
==
root
)
return
NULL
;
next
=
p
->
mnt
.
mnt_child
.
next
;
if
(
next
!=
&
p
->
mnt_parent
->
mnt_mounts
)
if
(
next
!=
&
p
->
mnt_parent
->
mnt
.
mnt
_mounts
)
break
;
p
=
real_mount
(
p
->
mnt_parent
)
;
p
=
p
->
mnt_parent
;
}
}
return
list_entry
(
next
,
struct
mount
,
mnt
.
mnt_child
);
...
...
@@ -682,7 +682,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
mnt
->
mnt
.
mnt_root
=
root
;
mnt
->
mnt
.
mnt_sb
=
root
->
d_sb
;
mnt
->
mnt
.
mnt_mountpoint
=
mnt
->
mnt
.
mnt_root
;
mnt
->
mnt_parent
=
&
mnt
->
mnt
;
mnt
->
mnt_parent
=
mnt
;
return
&
mnt
->
mnt
;
}
EXPORT_SYMBOL_GPL
(
vfs_kern_mount
);
...
...
@@ -710,7 +710,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
mnt
->
mnt
.
mnt_sb
=
sb
;
mnt
->
mnt
.
mnt_root
=
dget
(
root
);
mnt
->
mnt
.
mnt_mountpoint
=
mnt
->
mnt
.
mnt_root
;
mnt
->
mnt_parent
=
&
mnt
->
mnt
;
mnt
->
mnt_parent
=
mnt
;
if
(
flag
&
CL_SLAVE
)
{
list_add
(
&
mnt
->
mnt
.
mnt_slave
,
&
old
->
mnt
.
mnt_slave_list
);
...
...
@@ -1027,7 +1027,7 @@ static int show_mountinfo(struct seq_file *m, void *v)
struct
path
root
=
p
->
root
;
int
err
=
0
;
seq_printf
(
m
,
"%i %i %u:%u "
,
mnt
->
mnt_id
,
r
->
mnt_parent
->
mnt_id
,
seq_printf
(
m
,
"%i %i %u:%u "
,
mnt
->
mnt_id
,
r
->
mnt_parent
->
mnt
.
mnt
_id
,
MAJOR
(
sb
->
s_dev
),
MINOR
(
sb
->
s_dev
));
if
(
sb
->
s_op
->
show_path
)
err
=
sb
->
s_op
->
show_path
(
m
,
mnt
);
...
...
@@ -1202,9 +1202,9 @@ void release_mounts(struct list_head *head)
br_write_lock
(
vfsmount_lock
);
dentry
=
mnt
->
mnt
.
mnt_mountpoint
;
m
=
mnt
->
mnt_pare
nt
;
m
=
&
mnt
->
mnt_parent
->
m
nt
;
mnt
->
mnt
.
mnt_mountpoint
=
mnt
->
mnt
.
mnt_root
;
mnt
->
mnt_parent
=
&
mnt
->
mnt
;
mnt
->
mnt_parent
=
mnt
;
m
->
mnt_ghosts
--
;
br_write_unlock
(
vfsmount_lock
);
dput
(
dentry
);
...
...
@@ -1237,7 +1237,7 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill)
__mnt_make_shortterm
(
&
p
->
mnt
);
list_del_init
(
&
p
->
mnt
.
mnt_child
);
if
(
mnt_has_parent
(
p
))
{
p
->
mnt_parent
->
mnt_ghosts
++
;
p
->
mnt_parent
->
mnt
.
mnt
_ghosts
++
;
dentry_reset_mounted
(
p
->
mnt
.
mnt_mountpoint
);
}
change_mnt_propagation
(
p
,
MS_PRIVATE
);
...
...
@@ -1435,9 +1435,9 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
s
=
skip_mnt_tree
(
s
);
continue
;
}
while
(
p
!=
real_mount
(
s
->
mnt_parent
)
)
{
p
=
real_mount
(
p
->
mnt_parent
)
;
q
=
real_mount
(
q
->
mnt_parent
)
;
while
(
p
!=
s
->
mnt_parent
)
{
p
=
p
->
mnt_parent
;
q
=
q
->
mnt_parent
;
}
p
=
s
;
path
.
mnt
=
&
q
->
mnt
;
...
...
@@ -1899,7 +1899,7 @@ static int do_move_mount(struct path *path, char *old_name)
/*
* Don't move a mount residing in a shared parent.
*/
if
(
IS_MNT_SHARED
(
old
->
mnt_pare
nt
))
if
(
IS_MNT_SHARED
(
&
old
->
mnt_parent
->
m
nt
))
goto
out1
;
/*
* Don't move a mount tree containing unbindable mounts to a destination
...
...
@@ -1909,7 +1909,7 @@ static int do_move_mount(struct path *path, char *old_name)
tree_contains_unbindable
(
old
))
goto
out1
;
err
=
-
ELOOP
;
for
(
p
=
real_mount
(
path
->
mnt
);
mnt_has_parent
(
p
);
p
=
real_mount
(
p
->
mnt_parent
)
)
for
(
p
=
real_mount
(
path
->
mnt
);
mnt_has_parent
(
p
);
p
=
p
->
mnt_parent
)
if
(
p
==
old
)
goto
out1
;
...
...
@@ -2159,7 +2159,7 @@ static int select_submounts(struct mount *parent, struct list_head *graveyard)
*/
if
(
this_parent
!=
parent
)
{
next
=
this_parent
->
mnt
.
mnt_child
.
next
;
this_parent
=
real_mount
(
this_parent
->
mnt_parent
)
;
this_parent
=
this_parent
->
mnt_parent
;
goto
resume
;
}
return
found
;
...
...
@@ -2565,7 +2565,7 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry,
{
while
(
&
mnt
->
mnt
!=
root
->
mnt
&&
mnt_has_parent
(
mnt
))
{
dentry
=
mnt
->
mnt
.
mnt_mountpoint
;
mnt
=
real_mount
(
mnt
->
mnt_parent
)
;
mnt
=
mnt
->
mnt_parent
;
}
return
&
mnt
->
mnt
==
root
->
mnt
&&
is_subdir
(
dentry
,
root
->
dentry
);
}
...
...
@@ -2636,8 +2636,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
new_mnt
=
real_mount
(
new
.
mnt
);
root_mnt
=
real_mount
(
root
.
mnt
);
if
(
IS_MNT_SHARED
(
old
.
mnt
)
||
IS_MNT_SHARED
(
new_mnt
->
mnt_pare
nt
)
||
IS_MNT_SHARED
(
root_mnt
->
mnt_pare
nt
))
IS_MNT_SHARED
(
&
new_mnt
->
mnt_parent
->
m
nt
)
||
IS_MNT_SHARED
(
&
root_mnt
->
mnt_parent
->
m
nt
))
goto
out4
;
if
(
!
check_mnt
(
root
.
mnt
)
||
!
check_mnt
(
new
.
mnt
))
goto
out4
;
...
...
fs/pnode.c
View file @
0714a533
...
...
@@ -292,10 +292,10 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
{
struct
vfsmount
*
m
;
struct
mount
*
child
;
struct
vfs
mount
*
parent
=
mnt
->
mnt_parent
;
struct
mount
*
parent
=
mnt
->
mnt_parent
;
int
ret
=
0
;
if
(
&
mnt
->
mnt
==
parent
)
if
(
mnt
==
parent
)
return
do_refcount_check
(
mnt
,
refcnt
);
/*
...
...
@@ -306,8 +306,8 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
if
(
!
list_empty
(
&
mnt
->
mnt
.
mnt_mounts
)
||
do_refcount_check
(
mnt
,
refcnt
))
return
1
;
for
(
m
=
propagation_next
(
parent
,
pare
nt
);
m
;
m
=
propagation_next
(
m
,
pare
nt
))
{
for
(
m
=
propagation_next
(
&
parent
->
mnt
,
&
parent
->
m
nt
);
m
;
m
=
propagation_next
(
m
,
&
parent
->
m
nt
))
{
child
=
__lookup_mnt
(
m
,
mnt
->
mnt
.
mnt_mountpoint
,
0
);
if
(
child
&&
list_empty
(
&
child
->
mnt
.
mnt_mounts
)
&&
(
ret
=
do_refcount_check
(
child
,
1
)))
...
...
@@ -322,13 +322,13 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
*/
static
void
__propagate_umount
(
struct
mount
*
mnt
)
{
struct
vfs
mount
*
parent
=
mnt
->
mnt_parent
;
struct
mount
*
parent
=
mnt
->
mnt_parent
;
struct
vfsmount
*
m
;
BUG_ON
(
parent
==
&
mnt
->
mnt
);
BUG_ON
(
parent
==
mnt
);
for
(
m
=
propagation_next
(
parent
,
pare
nt
);
m
;
m
=
propagation_next
(
m
,
pare
nt
))
{
for
(
m
=
propagation_next
(
&
parent
->
mnt
,
&
parent
->
m
nt
);
m
;
m
=
propagation_next
(
m
,
&
parent
->
m
nt
))
{
struct
mount
*
child
=
__lookup_mnt
(
m
,
mnt
->
mnt
.
mnt_mountpoint
,
0
);
...
...
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