diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-09 13:29:39 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-06-24 08:17:07 -0400 |
| commit | 1cbd20d820c36f52543e3e4cd0067ebf52aa388f (patch) | |
| tree | 51d53ee4b6f79031eb493d7d2f2a57a7be3a3955 | |
| parent | 073aaa1b142461d91f83da66db1184d7c1b1edea (diff) | |
switch xfs to generic acl caching helpers
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_acl.c | 73 | ||||
| -rw-r--r-- | fs/xfs/xfs_acl.h | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_iget.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.h | 5 |
4 files changed, 9 insertions, 75 deletions
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 1e9d1246eebc..b23a54506446 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c | |||
| @@ -25,14 +25,10 @@ | |||
| 25 | #include <linux/posix_acl_xattr.h> | 25 | #include <linux/posix_acl_xattr.h> |
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | #define XFS_ACL_NOT_CACHED ((void *)-1) | ||
| 29 | |||
| 30 | /* | 28 | /* |
| 31 | * Locking scheme: | 29 | * Locking scheme: |
| 32 | * - all ACL updates are protected by inode->i_mutex, which is taken before | 30 | * - all ACL updates are protected by inode->i_mutex, which is taken before |
| 33 | * calling into this file. | 31 | * calling into this file. |
| 34 | * - access and updates to the ip->i_acl and ip->i_default_acl pointers are | ||
| 35 | * protected by inode->i_lock. | ||
| 36 | */ | 32 | */ |
| 37 | 33 | ||
| 38 | STATIC struct posix_acl * | 34 | STATIC struct posix_acl * |
| @@ -102,59 +98,35 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) | |||
| 102 | } | 98 | } |
| 103 | } | 99 | } |
| 104 | 100 | ||
| 105 | /* | ||
| 106 | * Update the cached ACL pointer in the inode. | ||
| 107 | * | ||
| 108 | * Because we don't hold any locks while reading/writing the attribute | ||
| 109 | * from/to disk another thread could have raced and updated the cached | ||
| 110 | * ACL value before us. In that case we release the previous cached value | ||
| 111 | * and update it with our new value. | ||
| 112 | */ | ||
| 113 | STATIC void | ||
| 114 | xfs_update_cached_acl(struct inode *inode, struct posix_acl **p_acl, | ||
| 115 | struct posix_acl *acl) | ||
| 116 | { | ||
| 117 | spin_lock(&inode->i_lock); | ||
| 118 | if (*p_acl && *p_acl != XFS_ACL_NOT_CACHED) | ||
| 119 | posix_acl_release(*p_acl); | ||
| 120 | *p_acl = posix_acl_dup(acl); | ||
| 121 | spin_unlock(&inode->i_lock); | ||
| 122 | } | ||
| 123 | |||
| 124 | struct posix_acl * | 101 | struct posix_acl * |
| 125 | xfs_get_acl(struct inode *inode, int type) | 102 | xfs_get_acl(struct inode *inode, int type) |
| 126 | { | 103 | { |
| 127 | struct xfs_inode *ip = XFS_I(inode); | 104 | struct xfs_inode *ip = XFS_I(inode); |
| 128 | struct posix_acl *acl = NULL, **p_acl; | 105 | struct posix_acl *acl; |
| 129 | struct xfs_acl *xfs_acl; | 106 | struct xfs_acl *xfs_acl; |
| 130 | int len = sizeof(struct xfs_acl); | 107 | int len = sizeof(struct xfs_acl); |
| 131 | char *ea_name; | 108 | char *ea_name; |
| 132 | int error; | 109 | int error; |
| 133 | 110 | ||
| 111 | acl = get_cached_acl(inode, type); | ||
| 112 | if (acl != ACL_NOT_CACHED) | ||
| 113 | return acl; | ||
| 114 | |||
| 134 | switch (type) { | 115 | switch (type) { |
| 135 | case ACL_TYPE_ACCESS: | 116 | case ACL_TYPE_ACCESS: |
| 136 | ea_name = SGI_ACL_FILE; | 117 | ea_name = SGI_ACL_FILE; |
| 137 | p_acl = &ip->i_acl; | ||
| 138 | break; | 118 | break; |
| 139 | case ACL_TYPE_DEFAULT: | 119 | case ACL_TYPE_DEFAULT: |
| 140 | ea_name = SGI_ACL_DEFAULT; | 120 | ea_name = SGI_ACL_DEFAULT; |
| 141 | p_acl = &ip->i_default_acl; | ||
| 142 | break; | 121 | break; |
| 143 | default: | 122 | default: |
| 144 | return ERR_PTR(-EINVAL); | 123 | BUG(); |
| 145 | } | 124 | } |
| 146 | 125 | ||
| 147 | spin_lock(&inode->i_lock); | ||
| 148 | if (*p_acl != XFS_ACL_NOT_CACHED) | ||
| 149 | acl = posix_acl_dup(*p_acl); | ||
| 150 | spin_unlock(&inode->i_lock); | ||
| 151 | |||
| 152 | /* | 126 | /* |
| 153 | * If we have a cached ACLs value just return it, not need to | 127 | * If we have a cached ACLs value just return it, not need to |
| 154 | * go out to the disk. | 128 | * go out to the disk. |
| 155 | */ | 129 | */ |
| 156 | if (acl) | ||
| 157 | return acl; | ||
| 158 | 130 | ||
| 159 | xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); | 131 | xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); |
| 160 | if (!xfs_acl) | 132 | if (!xfs_acl) |
| @@ -165,7 +137,7 @@ xfs_get_acl(struct inode *inode, int type) | |||
| 165 | /* | 137 | /* |
| 166 | * If the attribute doesn't exist make sure we have a negative | 138 | * If the attribute doesn't exist make sure we have a negative |
| 167 | * cache entry, for any other error assume it is transient and | 139 | * cache entry, for any other error assume it is transient and |
| 168 | * leave the cache entry as XFS_ACL_NOT_CACHED. | 140 | * leave the cache entry as ACL_NOT_CACHED. |
| 169 | */ | 141 | */ |
| 170 | if (error == -ENOATTR) { | 142 | if (error == -ENOATTR) { |
| 171 | acl = NULL; | 143 | acl = NULL; |
| @@ -179,7 +151,7 @@ xfs_get_acl(struct inode *inode, int type) | |||
| 179 | goto out; | 151 | goto out; |
| 180 | 152 | ||
| 181 | out_update_cache: | 153 | out_update_cache: |
| 182 | xfs_update_cached_acl(inode, p_acl, acl); | 154 | set_cached_acl(inode, type, acl); |
| 183 | out: | 155 | out: |
| 184 | kfree(xfs_acl); | 156 | kfree(xfs_acl); |
| 185 | return acl; | 157 | return acl; |
| @@ -189,7 +161,6 @@ STATIC int | |||
| 189 | xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 161 | xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) |
| 190 | { | 162 | { |
| 191 | struct xfs_inode *ip = XFS_I(inode); | 163 | struct xfs_inode *ip = XFS_I(inode); |
| 192 | struct posix_acl **p_acl; | ||
| 193 | char *ea_name; | 164 | char *ea_name; |
| 194 | int error; | 165 | int error; |
| 195 | 166 | ||
| @@ -199,13 +170,11 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
| 199 | switch (type) { | 170 | switch (type) { |
| 200 | case ACL_TYPE_ACCESS: | 171 | case ACL_TYPE_ACCESS: |
| 201 | ea_name = SGI_ACL_FILE; | 172 | ea_name = SGI_ACL_FILE; |
| 202 | p_acl = &ip->i_acl; | ||
| 203 | break; | 173 | break; |
| 204 | case ACL_TYPE_DEFAULT: | 174 | case ACL_TYPE_DEFAULT: |
| 205 | if (!S_ISDIR(inode->i_mode)) | 175 | if (!S_ISDIR(inode->i_mode)) |
| 206 | return acl ? -EACCES : 0; | 176 | return acl ? -EACCES : 0; |
| 207 | ea_name = SGI_ACL_DEFAULT; | 177 | ea_name = SGI_ACL_DEFAULT; |
| 208 | p_acl = &ip->i_default_acl; | ||
| 209 | break; | 178 | break; |
| 210 | default: | 179 | default: |
| 211 | return -EINVAL; | 180 | return -EINVAL; |
| @@ -242,7 +211,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
| 242 | } | 211 | } |
| 243 | 212 | ||
| 244 | if (!error) | 213 | if (!error) |
| 245 | xfs_update_cached_acl(inode, p_acl, acl); | 214 | set_cached_acl(inode, type, acl); |
| 246 | return error; | 215 | return error; |
| 247 | } | 216 | } |
| 248 | 217 | ||
| @@ -384,30 +353,6 @@ xfs_acl_chmod(struct inode *inode) | |||
| 384 | return error; | 353 | return error; |
| 385 | } | 354 | } |
| 386 | 355 | ||
| 387 | void | ||
| 388 | xfs_inode_init_acls(struct xfs_inode *ip) | ||
| 389 | { | ||
| 390 | /* | ||
| 391 | * No need for locking, inode is not live yet. | ||
| 392 | */ | ||
| 393 | ip->i_acl = XFS_ACL_NOT_CACHED; | ||
| 394 | ip->i_default_acl = XFS_ACL_NOT_CACHED; | ||
| 395 | } | ||
| 396 | |||
| 397 | void | ||
| 398 | xfs_inode_clear_acls(struct xfs_inode *ip) | ||
| 399 | { | ||
| 400 | /* | ||
| 401 | * No need for locking here, the inode is not live anymore | ||
| 402 | * and just about to be freed. | ||
| 403 | */ | ||
| 404 | if (ip->i_acl != XFS_ACL_NOT_CACHED) | ||
| 405 | posix_acl_release(ip->i_acl); | ||
| 406 | if (ip->i_default_acl != XFS_ACL_NOT_CACHED) | ||
| 407 | posix_acl_release(ip->i_default_acl); | ||
| 408 | } | ||
| 409 | |||
| 410 | |||
| 411 | /* | 356 | /* |
| 412 | * System xattr handlers. | 357 | * System xattr handlers. |
| 413 | * | 358 | * |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 63dc1f2efad5..947b150df8ed 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
| @@ -46,8 +46,6 @@ extern int xfs_check_acl(struct inode *inode, int mask); | |||
| 46 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); | 46 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); |
| 47 | extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); | 47 | extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); |
| 48 | extern int xfs_acl_chmod(struct inode *inode); | 48 | extern int xfs_acl_chmod(struct inode *inode); |
| 49 | extern void xfs_inode_init_acls(struct xfs_inode *ip); | ||
| 50 | extern void xfs_inode_clear_acls(struct xfs_inode *ip); | ||
| 51 | extern int posix_acl_access_exists(struct inode *inode); | 49 | extern int posix_acl_access_exists(struct inode *inode); |
| 52 | extern int posix_acl_default_exists(struct inode *inode); | 50 | extern int posix_acl_default_exists(struct inode *inode); |
| 53 | 51 | ||
| @@ -57,8 +55,6 @@ extern struct xattr_handler xfs_xattr_system_handler; | |||
| 57 | # define xfs_get_acl(inode, type) NULL | 55 | # define xfs_get_acl(inode, type) NULL |
| 58 | # define xfs_inherit_acl(inode, default_acl) 0 | 56 | # define xfs_inherit_acl(inode, default_acl) 0 |
| 59 | # define xfs_acl_chmod(inode) 0 | 57 | # define xfs_acl_chmod(inode) 0 |
| 60 | # define xfs_inode_init_acls(ip) | ||
| 61 | # define xfs_inode_clear_acls(ip) | ||
| 62 | # define posix_acl_access_exists(inode) 0 | 58 | # define posix_acl_access_exists(inode) 0 |
| 63 | # define posix_acl_default_exists(inode) 0 | 59 | # define posix_acl_default_exists(inode) 0 |
| 64 | #endif /* CONFIG_XFS_POSIX_ACL */ | 60 | #endif /* CONFIG_XFS_POSIX_ACL */ |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 76c540f719e4..5fcec6f020a7 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -83,7 +83,6 @@ xfs_inode_alloc( | |||
| 83 | memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); | 83 | memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); |
| 84 | ip->i_size = 0; | 84 | ip->i_size = 0; |
| 85 | ip->i_new_size = 0; | 85 | ip->i_new_size = 0; |
| 86 | xfs_inode_init_acls(ip); | ||
| 87 | 86 | ||
| 88 | /* | 87 | /* |
| 89 | * Initialize inode's trace buffers. | 88 | * Initialize inode's trace buffers. |
| @@ -560,7 +559,6 @@ xfs_ireclaim( | |||
| 560 | ASSERT(atomic_read(&ip->i_pincount) == 0); | 559 | ASSERT(atomic_read(&ip->i_pincount) == 0); |
| 561 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | 560 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); |
| 562 | ASSERT(completion_done(&ip->i_flush)); | 561 | ASSERT(completion_done(&ip->i_flush)); |
| 563 | xfs_inode_clear_acls(ip); | ||
| 564 | kmem_zone_free(xfs_inode_zone, ip); | 562 | kmem_zone_free(xfs_inode_zone, ip); |
| 565 | } | 563 | } |
| 566 | 564 | ||
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 77016702938b..1804f866a71d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
| @@ -273,11 +273,6 @@ typedef struct xfs_inode { | |||
| 273 | /* VFS inode */ | 273 | /* VFS inode */ |
| 274 | struct inode i_vnode; /* embedded VFS inode */ | 274 | struct inode i_vnode; /* embedded VFS inode */ |
| 275 | 275 | ||
| 276 | #ifdef CONFIG_XFS_POSIX_ACL | ||
| 277 | struct posix_acl *i_acl; | ||
| 278 | struct posix_acl *i_default_acl; | ||
| 279 | #endif | ||
| 280 | |||
| 281 | /* Trace buffers per inode. */ | 276 | /* Trace buffers per inode. */ |
| 282 | #ifdef XFS_INODE_TRACE | 277 | #ifdef XFS_INODE_TRACE |
| 283 | struct ktrace *i_trace; /* general inode trace */ | 278 | struct ktrace *i_trace; /* general inode trace */ |
