diff options
Diffstat (limited to 'fs/cifs/cifsfs.c')
| -rw-r--r-- | fs/cifs/cifsfs.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 3936aa7f2c22..8e21e0fe65d5 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -283,10 +283,13 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 283 | return 0; | 283 | return 0; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static int cifs_permission(struct inode *inode, int mask) | 286 | static int cifs_permission(struct inode *inode, int mask, unsigned int flags) |
| 287 | { | 287 | { |
| 288 | struct cifs_sb_info *cifs_sb; | 288 | struct cifs_sb_info *cifs_sb; |
| 289 | 289 | ||
| 290 | if (flags & IPERM_FLAG_RCU) | ||
| 291 | return -ECHILD; | ||
| 292 | |||
| 290 | cifs_sb = CIFS_SB(inode->i_sb); | 293 | cifs_sb = CIFS_SB(inode->i_sb); |
| 291 | 294 | ||
| 292 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { | 295 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { |
| @@ -298,7 +301,7 @@ static int cifs_permission(struct inode *inode, int mask) | |||
| 298 | on the client (above and beyond ACL on servers) for | 301 | on the client (above and beyond ACL on servers) for |
| 299 | servers which do not support setting and viewing mode bits, | 302 | servers which do not support setting and viewing mode bits, |
| 300 | so allowing client to check permissions is useful */ | 303 | so allowing client to check permissions is useful */ |
| 301 | return generic_permission(inode, mask, NULL); | 304 | return generic_permission(inode, mask, flags, NULL); |
| 302 | } | 305 | } |
| 303 | 306 | ||
| 304 | static struct kmem_cache *cifs_inode_cachep; | 307 | static struct kmem_cache *cifs_inode_cachep; |
| @@ -334,10 +337,17 @@ cifs_alloc_inode(struct super_block *sb) | |||
| 334 | return &cifs_inode->vfs_inode; | 337 | return &cifs_inode->vfs_inode; |
| 335 | } | 338 | } |
| 336 | 339 | ||
| 340 | static void cifs_i_callback(struct rcu_head *head) | ||
| 341 | { | ||
| 342 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
| 343 | INIT_LIST_HEAD(&inode->i_dentry); | ||
| 344 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); | ||
| 345 | } | ||
| 346 | |||
| 337 | static void | 347 | static void |
| 338 | cifs_destroy_inode(struct inode *inode) | 348 | cifs_destroy_inode(struct inode *inode) |
| 339 | { | 349 | { |
| 340 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); | 350 | call_rcu(&inode->i_rcu, cifs_i_callback); |
| 341 | } | 351 | } |
| 342 | 352 | ||
| 343 | static void | 353 | static void |
