mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
locks: break delegations on any attribute modification
NFSv4 uses leases to guarantee that clients can cache metadata as well as data. Cc: Mikulas Patocka <[email protected]> Cc: David Howells <[email protected]> Cc: Tyler Hicks <[email protected]> Cc: Dustin Kirkland <[email protected]> Acked-by: Jeff Layton <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]> Signed-off-by: Al Viro <[email protected]>
This commit is contained in:
parent
146a8595c6
commit
27ac0ffeac
10 changed files with 69 additions and 17 deletions
22
fs/open.c
22
fs/open.c
|
|
@ -57,7 +57,8 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
|||
newattrs.ia_valid |= ret | ATTR_FORCE;
|
||||
|
||||
mutex_lock(&dentry->d_inode->i_mutex);
|
||||
ret = notify_change(dentry, &newattrs);
|
||||
/* Note any delegations or leases have already been broken: */
|
||||
ret = notify_change(dentry, &newattrs, NULL);
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -464,21 +465,28 @@ out:
|
|||
static int chmod_common(struct path *path, umode_t mode)
|
||||
{
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
struct inode *delegated_inode = NULL;
|
||||
struct iattr newattrs;
|
||||
int error;
|
||||
|
||||
error = mnt_want_write(path->mnt);
|
||||
if (error)
|
||||
return error;
|
||||
retry_deleg:
|
||||
mutex_lock(&inode->i_mutex);
|
||||
error = security_path_chmod(path, mode);
|
||||
if (error)
|
||||
goto out_unlock;
|
||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
error = notify_change(path->dentry, &newattrs);
|
||||
error = notify_change(path->dentry, &newattrs, &delegated_inode);
|
||||
out_unlock:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (delegated_inode) {
|
||||
error = break_deleg_wait(&delegated_inode);
|
||||
if (!error)
|
||||
goto retry_deleg;
|
||||
}
|
||||
mnt_drop_write(path->mnt);
|
||||
return error;
|
||||
}
|
||||
|
|
@ -522,6 +530,7 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
|
|||
static int chown_common(struct path *path, uid_t user, gid_t group)
|
||||
{
|
||||
struct inode *inode = path->dentry->d_inode;
|
||||
struct inode *delegated_inode = NULL;
|
||||
int error;
|
||||
struct iattr newattrs;
|
||||
kuid_t uid;
|
||||
|
|
@ -546,12 +555,17 @@ static int chown_common(struct path *path, uid_t user, gid_t group)
|
|||
if (!S_ISDIR(inode->i_mode))
|
||||
newattrs.ia_valid |=
|
||||
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
|
||||
retry_deleg:
|
||||
mutex_lock(&inode->i_mutex);
|
||||
error = security_path_chown(path, uid, gid);
|
||||
if (!error)
|
||||
error = notify_change(path->dentry, &newattrs);
|
||||
error = notify_change(path->dentry, &newattrs, &delegated_inode);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
if (delegated_inode) {
|
||||
error = break_deleg_wait(&delegated_inode);
|
||||
if (!error)
|
||||
goto retry_deleg;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue