Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ada70d94 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

[PATCH] NFS: Add hooks to allow common NFS attribute code to clear cached acls

parent 92cfc62c
Loading
Loading
Loading
Loading
+26 −7
Original line number Original line Diff line number Diff line
@@ -64,6 +64,7 @@ static void nfs_clear_inode(struct inode *);
static void nfs_umount_begin(struct super_block *);
static void nfs_umount_begin(struct super_block *);
static int  nfs_statfs(struct super_block *, struct kstatfs *);
static int  nfs_statfs(struct super_block *, struct kstatfs *);
static int  nfs_show_options(struct seq_file *, struct vfsmount *);
static int  nfs_show_options(struct seq_file *, struct vfsmount *);
static void nfs_zap_acl_cache(struct inode *);


static struct rpc_program	nfs_program;
static struct rpc_program	nfs_program;


@@ -153,6 +154,7 @@ nfs_clear_inode(struct inode *inode)


	nfs_wb_all(inode);
	nfs_wb_all(inode);
	BUG_ON (!list_empty(&nfsi->open_files));
	BUG_ON (!list_empty(&nfsi->open_files));
	nfs_zap_acl_cache(inode);
	cred = nfsi->cache_access.cred;
	cred = nfsi->cache_access.cred;
	if (cred)
	if (cred)
		put_rpccred(cred);
		put_rpccred(cred);
@@ -587,9 +589,19 @@ nfs_zap_caches(struct inode *inode)


	memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
	memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS;
		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
	else
	else
		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS;
		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
}

static void nfs_zap_acl_cache(struct inode *inode)
{
	void (*clear_acl_cache)(struct inode *);

	clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache;
	if (clear_acl_cache != NULL)
		clear_acl_cache(inode);
	NFS_I(inode)->flags &= ~NFS_INO_INVALID_ACL;
}
}


/*
/*
@@ -789,7 +801,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
		}
		}
	}
	}
	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
		NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS;
		NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
	nfs_end_data_update(inode);
	nfs_end_data_update(inode);
	unlock_kernel();
	unlock_kernel();
	return error;
	return error;
@@ -1033,6 +1045,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
		/* This ensures we revalidate dentries */
		/* This ensures we revalidate dentries */
		nfsi->cache_change_attribute++;
		nfsi->cache_change_attribute++;
	}
	}
	if (flags & NFS_INO_INVALID_ACL)
		nfs_zap_acl_cache(inode);
	dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
	dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
		inode->i_sb->s_id,
		inode->i_sb->s_id,
		(long long)NFS_FILEID(inode));
		(long long)NFS_FILEID(inode));
@@ -1183,7 +1197,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
			|| inode->i_uid != fattr->uid
			|| inode->i_uid != fattr->uid
			|| inode->i_gid != fattr->gid)
			|| inode->i_gid != fattr->gid)
		nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
		nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;


	/* Has the link count changed? */
	/* Has the link count changed? */
	if (inode->i_nlink != fattr->nlink)
	if (inode->i_nlink != fattr->nlink)
@@ -1292,16 +1306,21 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
#endif
#endif
		nfsi->change_attr = fattr->change_attr;
		nfsi->change_attr = fattr->change_attr;
		if (!data_unstable)
		if (!data_unstable)
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS;
			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
	}
	}


	/* If ctime has changed we should definitely clear access+acl caches */
	if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
		if (!data_unstable)
			invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
	}
	memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
	memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));


	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
	    inode->i_uid != fattr->uid ||
	    inode->i_uid != fattr->uid ||
	    inode->i_gid != fattr->gid)
	    inode->i_gid != fattr->gid)
		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS;
		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;


	inode->i_mode = fattr->mode;
	inode->i_mode = fattr->mode;
	inode->i_nlink = fattr->nlink;
	inode->i_nlink = fattr->nlink;
+1 −0
Original line number Original line Diff line number Diff line
@@ -189,6 +189,7 @@ struct nfs_inode {
#define NFS_INO_INVALID_DATA	0x0010		/* cached data is invalid */
#define NFS_INO_INVALID_DATA	0x0010		/* cached data is invalid */
#define NFS_INO_INVALID_ATIME	0x0020		/* cached atime is invalid */
#define NFS_INO_INVALID_ATIME	0x0020		/* cached atime is invalid */
#define NFS_INO_INVALID_ACCESS	0x0040		/* cached access cred invalid */
#define NFS_INO_INVALID_ACCESS	0x0040		/* cached access cred invalid */
#define NFS_INO_INVALID_ACL	0x0080		/* cached acls are invalid */


static inline struct nfs_inode *NFS_I(struct inode *inode)
static inline struct nfs_inode *NFS_I(struct inode *inode)
{
{
+1 −0
Original line number Original line Diff line number Diff line
@@ -714,6 +714,7 @@ struct nfs_rpc_ops {
	int	(*file_open)   (struct inode *, struct file *);
	int	(*file_open)   (struct inode *, struct file *);
	int	(*file_release) (struct inode *, struct file *);
	int	(*file_release) (struct inode *, struct file *);
	int	(*lock)(struct file *, int, struct file_lock *);
	int	(*lock)(struct file *, int, struct file_lock *);
	void	(*clear_acl_cache)(struct inode *);
};
};


/*
/*