mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 13:41:30 +00:00
vfs: syscall: Add open_tree(2) to reference or clone a mount
open_tree(dfd, pathname, flags) Returns an O_PATH-opened file descriptor or an error. dfd and pathname specify the location to open, in usual fashion (see e.g. fstatat(2)). flags should be an OR of some of the following: * AT_PATH_EMPTY, AT_NO_AUTOMOUNT, AT_SYMLINK_NOFOLLOW - same meanings as usual * OPEN_TREE_CLOEXEC - make the resulting descriptor close-on-exec * OPEN_TREE_CLONE or OPEN_TREE_CLONE | AT_RECURSIVE - instead of opening the location in question, create a detached mount tree matching the subtree rooted at location specified by dfd/pathname. With AT_RECURSIVE the entire subtree is cloned, without it - only the part within in the mount containing the location in question. In other words, the same as mount --rbind or mount --bind would've taken. The detached tree will be dissolved on the final close of obtained file. Creation of such detached trees requires the same capabilities as doing mount --bind. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: David Howells <dhowells@redhat.com> cc: linux-api@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
9e98c678c2
commit
a07b200047
9 changed files with 159 additions and 28 deletions
|
@ -255,6 +255,7 @@ static void __fput(struct file *file)
|
|||
struct dentry *dentry = file->f_path.dentry;
|
||||
struct vfsmount *mnt = file->f_path.mnt;
|
||||
struct inode *inode = file->f_inode;
|
||||
fmode_t mode = file->f_mode;
|
||||
|
||||
if (unlikely(!(file->f_mode & FMODE_OPENED)))
|
||||
goto out;
|
||||
|
@ -277,18 +278,20 @@ static void __fput(struct file *file)
|
|||
if (file->f_op->release)
|
||||
file->f_op->release(inode, file);
|
||||
if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL &&
|
||||
!(file->f_mode & FMODE_PATH))) {
|
||||
!(mode & FMODE_PATH))) {
|
||||
cdev_put(inode->i_cdev);
|
||||
}
|
||||
fops_put(file->f_op);
|
||||
put_pid(file->f_owner.pid);
|
||||
if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
|
||||
if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
|
||||
i_readcount_dec(inode);
|
||||
if (file->f_mode & FMODE_WRITER) {
|
||||
if (mode & FMODE_WRITER) {
|
||||
put_write_access(inode);
|
||||
__mnt_drop_write(mnt);
|
||||
}
|
||||
dput(dentry);
|
||||
if (unlikely(mode & FMODE_NEED_UNMOUNT))
|
||||
dissolve_on_fput(mnt);
|
||||
mntput(mnt);
|
||||
out:
|
||||
file_free(file);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue