diff options
author | David P. Quigley <dpquigl@tycho.nsa.gov> | 2009-09-03 14:25:56 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-09-09 20:11:22 -0400 |
commit | b1ab7e4b2a88d3ac13771463be8f302ce1616cfc (patch) | |
tree | c08825120cb290a4307d36ee0bee806ad2aae83c /fs/xattr.c | |
parent | 733e5e4b4eb1bc1e27acbe092200154051171426 (diff) |
VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx.
This factors out the part of the vfs_setxattr function that performs the
setting of the xattr and its notification. This is needed so the SELinux
implementation of inode_setsecctx can handle the setting of the xattr while
maintaining the proper separation of layers.
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/xattr.c')
-rw-r--r-- | fs/xattr.c | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index 1c3d0af59ddf..6d4f6d3449fb 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -66,22 +66,28 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
66 | return inode_permission(inode, mask); | 66 | return inode_permission(inode, mask); |
67 | } | 67 | } |
68 | 68 | ||
69 | int | 69 | /** |
70 | vfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 70 | * __vfs_setxattr_noperm - perform setxattr operation without performing |
71 | size_t size, int flags) | 71 | * permission checks. |
72 | * | ||
73 | * @dentry - object to perform setxattr on | ||
74 | * @name - xattr name to set | ||
75 | * @value - value to set @name to | ||
76 | * @size - size of @value | ||
77 | * @flags - flags to pass into filesystem operations | ||
78 | * | ||
79 | * returns the result of the internal setxattr or setsecurity operations. | ||
80 | * | ||
81 | * This function requires the caller to lock the inode's i_mutex before it | ||
82 | * is executed. It also assumes that the caller will make the appropriate | ||
83 | * permission checks. | ||
84 | */ | ||
85 | int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | ||
86 | const void *value, size_t size, int flags) | ||
72 | { | 87 | { |
73 | struct inode *inode = dentry->d_inode; | 88 | struct inode *inode = dentry->d_inode; |
74 | int error; | 89 | int error = -EOPNOTSUPP; |
75 | |||
76 | error = xattr_permission(inode, name, MAY_WRITE); | ||
77 | if (error) | ||
78 | return error; | ||
79 | 90 | ||
80 | mutex_lock(&inode->i_mutex); | ||
81 | error = security_inode_setxattr(dentry, name, value, size, flags); | ||
82 | if (error) | ||
83 | goto out; | ||
84 | error = -EOPNOTSUPP; | ||
85 | if (inode->i_op->setxattr) { | 91 | if (inode->i_op->setxattr) { |
86 | error = inode->i_op->setxattr(dentry, name, value, size, flags); | 92 | error = inode->i_op->setxattr(dentry, name, value, size, flags); |
87 | if (!error) { | 93 | if (!error) { |
@@ -97,6 +103,29 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
97 | if (!error) | 103 | if (!error) |
98 | fsnotify_xattr(dentry); | 104 | fsnotify_xattr(dentry); |
99 | } | 105 | } |
106 | |||
107 | return error; | ||
108 | } | ||
109 | |||
110 | |||
111 | int | ||
112 | vfs_setxattr(struct dentry *dentry, const char *name, const void *value, | ||
113 | size_t size, int flags) | ||
114 | { | ||
115 | struct inode *inode = dentry->d_inode; | ||
116 | int error; | ||
117 | |||
118 | error = xattr_permission(inode, name, MAY_WRITE); | ||
119 | if (error) | ||
120 | return error; | ||
121 | |||
122 | mutex_lock(&inode->i_mutex); | ||
123 | error = security_inode_setxattr(dentry, name, value, size, flags); | ||
124 | if (error) | ||
125 | goto out; | ||
126 | |||
127 | error = __vfs_setxattr_noperm(dentry, name, value, size, flags); | ||
128 | |||
100 | out: | 129 | out: |
101 | mutex_unlock(&inode->i_mutex); | 130 | mutex_unlock(&inode->i_mutex); |
102 | return error; | 131 | return error; |