forked from mirrors/linux
		
	[PATCH] NFS: Add hooks to allow common NFS attribute code to clear cached acls
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
		
							parent
							
								
									92cfc62cb8
								
							
						
					
					
						commit
						ada70d9425
					
				
					 3 changed files with 28 additions and 7 deletions
				
			
		|  | @ -64,6 +64,7 @@ static void nfs_clear_inode(struct inode *); | |||
| static void nfs_umount_begin(struct super_block *); | ||||
| static int  nfs_statfs(struct super_block *, struct kstatfs *); | ||||
| static int  nfs_show_options(struct seq_file *, struct vfsmount *); | ||||
| static void nfs_zap_acl_cache(struct inode *); | ||||
| 
 | ||||
| static struct rpc_program	nfs_program; | ||||
| 
 | ||||
|  | @ -153,6 +154,7 @@ nfs_clear_inode(struct inode *inode) | |||
| 
 | ||||
| 	nfs_wb_all(inode); | ||||
| 	BUG_ON (!list_empty(&nfsi->open_files)); | ||||
| 	nfs_zap_acl_cache(inode); | ||||
| 	cred = nfsi->cache_access.cred; | ||||
| 	if (cred) | ||||
| 		put_rpccred(cred); | ||||
|  | @ -587,9 +589,19 @@ nfs_zap_caches(struct inode *inode) | |||
| 
 | ||||
| 	memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); | ||||
| 	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 | ||||
| 		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) | ||||
| 		NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; | ||||
| 		NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | ||||
| 	nfs_end_data_update(inode); | ||||
| 	unlock_kernel(); | ||||
| 	return error; | ||||
|  | @ -1033,6 +1045,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
| 		/* This ensures we revalidate dentries */ | ||||
| 		nfsi->cache_change_attribute++; | ||||
| 	} | ||||
| 	if (flags & NFS_INO_INVALID_ACL) | ||||
| 		nfs_zap_acl_cache(inode); | ||||
| 	dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", | ||||
| 		inode->i_sb->s_id, | ||||
| 		(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) | ||||
| 			|| inode->i_uid != fattr->uid | ||||
| 			|| 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? */ | ||||
| 	if (inode->i_nlink != fattr->nlink) | ||||
|  | @ -1292,16 +1306,21 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
| #endif | ||||
| 		nfsi->change_attr = fattr->change_attr; | ||||
| 		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; | ||||
| 	} | ||||
| 
 | ||||
| 	memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||||
| 	/* 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_atime, &fattr->atime, sizeof(inode->i_atime)); | ||||
| 
 | ||||
| 	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || | ||||
| 	    inode->i_uid != fattr->uid || | ||||
| 	    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_nlink = fattr->nlink; | ||||
|  |  | |||
|  | @ -189,6 +189,7 @@ struct nfs_inode { | |||
| #define NFS_INO_INVALID_DATA	0x0010		/* cached data 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_ACL	0x0080		/* cached acls are invalid */ | ||||
| 
 | ||||
| static inline struct nfs_inode *NFS_I(struct inode *inode) | ||||
| { | ||||
|  |  | |||
|  | @ -714,6 +714,7 @@ struct nfs_rpc_ops { | |||
| 	int	(*file_open)   (struct inode *, struct file *); | ||||
| 	int	(*file_release) (struct inode *, struct file *); | ||||
| 	int	(*lock)(struct file *, int, struct file_lock *); | ||||
| 	void	(*clear_acl_cache)(struct inode *); | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Trond Myklebust
						Trond Myklebust