vfs: Add IOP_XATTR inode operations flag
The IOP_XATTR inode operations flag in inode->i_opflags indicates that the inode has xattr support. The flag is automatically set by new_inode() on filesystems with xattr support (where sb->s_xattr is defined), and cleared otherwise. Filesystems can explicitly clear it for inodes that should not have xattr support. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									b6ba11773d
								
							
						
					
					
						commit
						d0a5b995a3
					
				| @ -140,6 +140,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode) | |||||||
| 	inode->i_fop = &no_open_fops; | 	inode->i_fop = &no_open_fops; | ||||||
| 	inode->__i_nlink = 1; | 	inode->__i_nlink = 1; | ||||||
| 	inode->i_opflags = 0; | 	inode->i_opflags = 0; | ||||||
|  | 	if (sb->s_xattr) | ||||||
|  | 		inode->i_opflags |= IOP_XATTR; | ||||||
| 	i_uid_write(inode, 0); | 	i_uid_write(inode, 0); | ||||||
| 	i_gid_write(inode, 0); | 	i_gid_write(inode, 0); | ||||||
| 	atomic_set(&inode->i_writecount, 0); | 	atomic_set(&inode->i_writecount, 0); | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								fs/xattr.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								fs/xattr.c
									
									
									
									
									
								
							| @ -53,10 +53,13 @@ strcmp_prefix(const char *a, const char *a_prefix) | |||||||
|  * Find the xattr_handler with the matching prefix. |  * Find the xattr_handler with the matching prefix. | ||||||
|  */ |  */ | ||||||
| static const struct xattr_handler * | static const struct xattr_handler * | ||||||
| xattr_resolve_name(const struct xattr_handler **handlers, const char **name) | xattr_resolve_name(struct inode *inode, const char **name) | ||||||
| { | { | ||||||
|  | 	const struct xattr_handler **handlers = inode->i_sb->s_xattr; | ||||||
| 	const struct xattr_handler *handler; | 	const struct xattr_handler *handler; | ||||||
| 
 | 
 | ||||||
|  | 	if (!(inode->i_opflags & IOP_XATTR)) | ||||||
|  | 		return ERR_PTR(-EOPNOTSUPP); | ||||||
| 	for_each_xattr_handler(handlers, handler) { | 	for_each_xattr_handler(handlers, handler) { | ||||||
| 		const char *n; | 		const char *n; | ||||||
| 
 | 
 | ||||||
| @ -298,6 +301,7 @@ nolsm: | |||||||
| 		error = -EOPNOTSUPP; | 		error = -EOPNOTSUPP; | ||||||
| 
 | 
 | ||||||
| 	return error; | 	return error; | ||||||
|  | 
 | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(vfs_getxattr); | EXPORT_SYMBOL_GPL(vfs_getxattr); | ||||||
| 
 | 
 | ||||||
| @ -700,7 +704,7 @@ generic_getxattr(struct dentry *dentry, struct inode *inode, | |||||||
| { | { | ||||||
| 	const struct xattr_handler *handler; | 	const struct xattr_handler *handler; | ||||||
| 
 | 
 | ||||||
| 	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 	handler = xattr_resolve_name(inode, &name); | ||||||
| 	if (IS_ERR(handler)) | 	if (IS_ERR(handler)) | ||||||
| 		return PTR_ERR(handler); | 		return PTR_ERR(handler); | ||||||
| 	return handler->get(handler, dentry, inode, | 	return handler->get(handler, dentry, inode, | ||||||
| @ -755,7 +759,7 @@ generic_setxattr(struct dentry *dentry, struct inode *inode, const char *name, | |||||||
| 
 | 
 | ||||||
| 	if (size == 0) | 	if (size == 0) | ||||||
| 		value = "";  /* empty EA, do not remove */ | 		value = "";  /* empty EA, do not remove */ | ||||||
| 	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 	handler = xattr_resolve_name(inode, &name); | ||||||
| 	if (IS_ERR(handler)) | 	if (IS_ERR(handler)) | ||||||
| 		return PTR_ERR(handler); | 		return PTR_ERR(handler); | ||||||
| 	return handler->set(handler, dentry, inode, name, value, size, flags); | 	return handler->set(handler, dentry, inode, name, value, size, flags); | ||||||
| @ -770,7 +774,7 @@ generic_removexattr(struct dentry *dentry, const char *name) | |||||||
| { | { | ||||||
| 	const struct xattr_handler *handler; | 	const struct xattr_handler *handler; | ||||||
| 
 | 
 | ||||||
| 	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 	handler = xattr_resolve_name(d_inode(dentry), &name); | ||||||
| 	if (IS_ERR(handler)) | 	if (IS_ERR(handler)) | ||||||
| 		return PTR_ERR(handler); | 		return PTR_ERR(handler); | ||||||
| 	return handler->set(handler, dentry, d_inode(dentry), name, NULL, | 	return handler->set(handler, dentry, d_inode(dentry), name, NULL, | ||||||
|  | |||||||
| @ -591,6 +591,7 @@ is_uncached_acl(struct posix_acl *acl) | |||||||
| #define IOP_FASTPERM	0x0001 | #define IOP_FASTPERM	0x0001 | ||||||
| #define IOP_LOOKUP	0x0002 | #define IOP_LOOKUP	0x0002 | ||||||
| #define IOP_NOFOLLOW	0x0004 | #define IOP_NOFOLLOW	0x0004 | ||||||
|  | #define IOP_XATTR	0x0008 | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Keep mostly read-only and often accessed (especially for |  * Keep mostly read-only and often accessed (especially for | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user