mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "overlayfs merge + leak fix for d_splice_alias() failure exits" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: overlayfs: embed middle into overlay_readdir_data overlayfs: embed root into overlay_readdir_data overlayfs: make ovl_cache_entry->name an array instead of pointer overlayfs: don't hold ->i_mutex over opening the real directory fix inode leaks on d_splice_alias() failure exits fs: limit filesystem stacking depth overlay: overlay filesystem documentation overlayfs: implement show_options overlayfs: add statfs support overlay filesystem shmem: support RENAME_WHITEOUT ext4: support RENAME_WHITEOUT vfs: add RENAME_WHITEOUT vfs: add whiteout support vfs: export check_sticky() vfs: introduce clone_private_mount() vfs: export __inode_permission() to modules vfs: export do_splice_direct() to modules vfs: add i_op->dentry_open()
This commit is contained in:
commit
d1e14f1d63
27 changed files with 3814 additions and 58 deletions
36
mm/shmem.c
36
mm/shmem.c
|
|
@ -2345,6 +2345,32 @@ static int shmem_exchange(struct inode *old_dir, struct dentry *old_dentry, stru
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int shmem_whiteout(struct inode *old_dir, struct dentry *old_dentry)
|
||||
{
|
||||
struct dentry *whiteout;
|
||||
int error;
|
||||
|
||||
whiteout = d_alloc(old_dentry->d_parent, &old_dentry->d_name);
|
||||
if (!whiteout)
|
||||
return -ENOMEM;
|
||||
|
||||
error = shmem_mknod(old_dir, whiteout,
|
||||
S_IFCHR | WHITEOUT_MODE, WHITEOUT_DEV);
|
||||
dput(whiteout);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* Cheat and hash the whiteout while the old dentry is still in
|
||||
* place, instead of playing games with FS_RENAME_DOES_D_MOVE.
|
||||
*
|
||||
* d_lookup() will consistently find one of them at this point,
|
||||
* not sure which one, but that isn't even important.
|
||||
*/
|
||||
d_rehash(whiteout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The VFS layer already does all the dentry stuff for rename,
|
||||
* we just have to decrement the usage count for the target if
|
||||
|
|
@ -2356,7 +2382,7 @@ static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struc
|
|||
struct inode *inode = old_dentry->d_inode;
|
||||
int they_are_dirs = S_ISDIR(inode->i_mode);
|
||||
|
||||
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
|
||||
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & RENAME_EXCHANGE)
|
||||
|
|
@ -2365,6 +2391,14 @@ static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struc
|
|||
if (!simple_empty(new_dentry))
|
||||
return -ENOTEMPTY;
|
||||
|
||||
if (flags & RENAME_WHITEOUT) {
|
||||
int error;
|
||||
|
||||
error = shmem_whiteout(old_dir, old_dentry);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (new_dentry->d_inode) {
|
||||
(void) shmem_unlink(new_dir, new_dentry);
|
||||
if (they_are_dirs) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue