diff --git a/fs/incfs/vfs.c b/fs/incfs/vfs.c index 17cf59f9c92c..fd43e0e0ffbb 100644 --- a/fs/incfs/vfs.c +++ b/fs/incfs/vfs.c @@ -348,7 +348,6 @@ static int inode_set(struct inode *inode, void *opaque) struct dentry *backing_dentry = search->backing_dentry; struct inode *backing_inode = d_inode(backing_dentry); - inode_init_owner(inode, NULL, backing_inode->i_mode); fsstack_copy_attr_all(inode, backing_inode); if (S_ISREG(inode->i_mode)) { u64 size = read_size_attr(backing_dentry); @@ -380,6 +379,7 @@ static int inode_set(struct inode *inode, void *opaque) pr_warn("incfs: ino conflict with backing FS %ld\n", backing_inode->i_ino); } + return 0; } else if (search->ino == INCFS_PENDING_READS_INODE) { /* It's an inode for .pending_reads pseudo file. */ @@ -1138,6 +1138,27 @@ static int validate_name(char *file_name) return 0; } +static int chmod(struct dentry *dentry, umode_t mode) +{ + struct inode *inode = dentry->d_inode; + struct inode *delegated_inode = NULL; + struct iattr newattrs; + int error; + +retry_deleg: + inode_lock(inode); + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; + error = notify_change(dentry, &newattrs, &delegated_inode); + inode_unlock(inode); + if (delegated_inode) { + error = break_deleg_wait(&delegated_inode); + if (!error) + goto retry_deleg; + } + return error; +} + static long ioctl_create_file(struct mount_info *mi, struct incfs_new_file_args __user *usr_args) { @@ -1238,8 +1259,8 @@ static long ioctl_create_file(struct mount_info *mi, /* Creating a file in the .index dir. */ index_dir_inode = d_inode(mi->mi_index_dir); inode_lock_nested(index_dir_inode, I_MUTEX_PARENT); - error = vfs_create(index_dir_inode, index_file_dentry, - args.mode, true); + error = vfs_create(index_dir_inode, index_file_dentry, args.mode | 0222, + true); inode_unlock(index_dir_inode); if (error) @@ -1249,6 +1270,12 @@ static long ioctl_create_file(struct mount_info *mi, goto out; } + error = chmod(index_file_dentry, args.mode | 0222); + if (error) { + pr_debug("incfs: chmod err: %d\n", error); + goto delete_index_file; + } + /* Save the file's ID as an xattr for easy fetching in future. */ error = vfs_setxattr(index_file_dentry, INCFS_XATTR_ID_NAME, file_id_str, strlen(file_id_str), XATTR_CREATE); @@ -1538,7 +1565,7 @@ static int dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) } inode_lock_nested(dir_node->n_backing_inode, I_MUTEX_PARENT); - err = vfs_mkdir(dir_node->n_backing_inode, backing_dentry, mode); + err = vfs_mkdir(dir_node->n_backing_inode, backing_dentry, mode | 0222); inode_unlock(dir_node->n_backing_inode); if (!err) { struct inode *inode = NULL;