mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
vfs: Add setattr2 for filesystems with per mount permissions
This allows filesystems to use their mount private data to influence the permssions they use in setattr2. It has been separated into a new call to avoid disrupting current setattr users. Change-Id: I19959038309284448f1b7f232d579674ef546385 Signed-off-by: Daniel Rosenberg <drosen@google.com>
This commit is contained in:
parent
19a3f7c232
commit
1620d1d7d4
4 changed files with 28 additions and 10 deletions
11
fs/attr.c
11
fs/attr.c
|
@ -163,7 +163,7 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(setattr_copy);
|
EXPORT_SYMBOL(setattr_copy);
|
||||||
|
|
||||||
int notify_change(struct dentry * dentry, struct iattr * attr)
|
int notify_change2(struct vfsmount *mnt, struct dentry * dentry, struct iattr * attr)
|
||||||
{
|
{
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
umode_t mode = inode->i_mode;
|
umode_t mode = inode->i_mode;
|
||||||
|
@ -233,7 +233,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (inode->i_op->setattr)
|
if (mnt && inode->i_op->setattr2)
|
||||||
|
error = inode->i_op->setattr2(mnt, dentry, attr);
|
||||||
|
else if (inode->i_op->setattr)
|
||||||
error = inode->i_op->setattr(dentry, attr);
|
error = inode->i_op->setattr(dentry, attr);
|
||||||
else
|
else
|
||||||
error = simple_setattr(dentry, attr);
|
error = simple_setattr(dentry, attr);
|
||||||
|
@ -245,5 +247,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(notify_change2);
|
||||||
|
|
||||||
|
int notify_change(struct dentry * dentry, struct iattr * attr)
|
||||||
|
{
|
||||||
|
return notify_change2(NULL, dentry, attr);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(notify_change);
|
EXPORT_SYMBOL(notify_change);
|
||||||
|
|
21
fs/open.c
21
fs/open.c
|
@ -33,8 +33,8 @@
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
int do_truncate2(struct vfsmount *mnt, struct dentry *dentry, loff_t length,
|
||||||
struct file *filp)
|
unsigned int time_attrs, struct file *filp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct iattr newattrs;
|
struct iattr newattrs;
|
||||||
|
@ -56,10 +56,15 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
||||||
newattrs.ia_valid |= ret | ATTR_FORCE;
|
newattrs.ia_valid |= ret | ATTR_FORCE;
|
||||||
|
|
||||||
mutex_lock(&dentry->d_inode->i_mutex);
|
mutex_lock(&dentry->d_inode->i_mutex);
|
||||||
ret = notify_change(dentry, &newattrs);
|
ret = notify_change2(mnt, dentry, &newattrs);
|
||||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
||||||
|
struct file *filp)
|
||||||
|
{
|
||||||
|
return do_truncate2(NULL, dentry, length, time_attrs, filp);
|
||||||
|
}
|
||||||
|
|
||||||
static long do_sys_truncate(const char __user *pathname, loff_t length)
|
static long do_sys_truncate(const char __user *pathname, loff_t length)
|
||||||
{
|
{
|
||||||
|
@ -115,7 +120,7 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
|
||||||
if (!error)
|
if (!error)
|
||||||
error = security_path_truncate(&path);
|
error = security_path_truncate(&path);
|
||||||
if (!error)
|
if (!error)
|
||||||
error = do_truncate(path.dentry, length, 0, NULL);
|
error = do_truncate2(mnt, path.dentry, length, 0, NULL);
|
||||||
|
|
||||||
put_write_and_out:
|
put_write_and_out:
|
||||||
put_write_access(inode);
|
put_write_access(inode);
|
||||||
|
@ -136,6 +141,7 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
|
||||||
{
|
{
|
||||||
struct inode * inode;
|
struct inode * inode;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
struct vfsmount *mnt;
|
||||||
struct file * file;
|
struct file * file;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -152,6 +158,7 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
|
||||||
small = 0;
|
small = 0;
|
||||||
|
|
||||||
dentry = file->f_path.dentry;
|
dentry = file->f_path.dentry;
|
||||||
|
mnt = file->f_path.mnt;
|
||||||
inode = dentry->d_inode;
|
inode = dentry->d_inode;
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
|
if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
|
||||||
|
@ -170,7 +177,7 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
|
||||||
if (!error)
|
if (!error)
|
||||||
error = security_path_truncate(&file->f_path);
|
error = security_path_truncate(&file->f_path);
|
||||||
if (!error)
|
if (!error)
|
||||||
error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
|
error = do_truncate2(mnt, dentry, length, ATTR_MTIME|ATTR_CTIME, file);
|
||||||
out_putf:
|
out_putf:
|
||||||
fput(file);
|
fput(file);
|
||||||
out:
|
out:
|
||||||
|
@ -467,7 +474,7 @@ static int chmod_common(struct path *path, umode_t mode)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||||
error = notify_change(path->dentry, &newattrs);
|
error = notify_change2(path->mnt, path->dentry, &newattrs);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&inode->i_mutex);
|
mutex_unlock(&inode->i_mutex);
|
||||||
mnt_drop_write(path->mnt);
|
mnt_drop_write(path->mnt);
|
||||||
|
@ -527,7 +534,7 @@ static int chown_common(struct path *path, uid_t user, gid_t group)
|
||||||
mutex_lock(&inode->i_mutex);
|
mutex_lock(&inode->i_mutex);
|
||||||
error = security_path_chown(path, user, group);
|
error = security_path_chown(path, user, group);
|
||||||
if (!error)
|
if (!error)
|
||||||
error = notify_change(path->dentry, &newattrs);
|
error = notify_change2(path->mnt, path->dentry, &newattrs);
|
||||||
mutex_unlock(&inode->i_mutex);
|
mutex_unlock(&inode->i_mutex);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -102,7 +102,7 @@ static int utimes_common(struct path *path, struct timespec *times)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_lock(&inode->i_mutex);
|
mutex_lock(&inode->i_mutex);
|
||||||
error = notify_change(path->dentry, &newattrs);
|
error = notify_change2(path->mnt, path->dentry, &newattrs);
|
||||||
mutex_unlock(&inode->i_mutex);
|
mutex_unlock(&inode->i_mutex);
|
||||||
|
|
||||||
mnt_drop_write_and_out:
|
mnt_drop_write_and_out:
|
||||||
|
|
|
@ -1698,6 +1698,7 @@ struct inode_operations {
|
||||||
struct inode *, struct dentry *);
|
struct inode *, struct dentry *);
|
||||||
void (*truncate) (struct inode *);
|
void (*truncate) (struct inode *);
|
||||||
int (*setattr) (struct dentry *, struct iattr *);
|
int (*setattr) (struct dentry *, struct iattr *);
|
||||||
|
int (*setattr2) (struct vfsmount *, struct dentry *, struct iattr *);
|
||||||
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
|
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
|
||||||
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
|
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
|
||||||
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
|
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
|
||||||
|
@ -2078,6 +2079,8 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
|
||||||
|
|
||||||
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
|
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
|
||||||
struct file *filp);
|
struct file *filp);
|
||||||
|
extern int do_truncate2(struct vfsmount *, struct dentry *, loff_t start,
|
||||||
|
unsigned int time_attrs, struct file *filp);
|
||||||
extern int do_fallocate(struct file *file, int mode, loff_t offset,
|
extern int do_fallocate(struct file *file, int mode, loff_t offset,
|
||||||
loff_t len);
|
loff_t len);
|
||||||
extern long do_sys_open(int dfd, const char __user *filename, int flags,
|
extern long do_sys_open(int dfd, const char __user *filename, int flags,
|
||||||
|
@ -2276,6 +2279,7 @@ extern void emergency_remount(void);
|
||||||
extern sector_t bmap(struct inode *, sector_t);
|
extern sector_t bmap(struct inode *, sector_t);
|
||||||
#endif
|
#endif
|
||||||
extern int notify_change(struct dentry *, struct iattr *);
|
extern int notify_change(struct dentry *, struct iattr *);
|
||||||
|
extern int notify_change2(struct vfsmount *, struct dentry *, struct iattr *);
|
||||||
extern int inode_permission(struct inode *, int);
|
extern int inode_permission(struct inode *, int);
|
||||||
extern int inode_permission2(struct vfsmount *, struct inode *, int);
|
extern int inode_permission2(struct vfsmount *, struct inode *, int);
|
||||||
extern int generic_permission(struct inode *, int);
|
extern int generic_permission(struct inode *, int);
|
||||||
|
|
Loading…
Reference in a new issue