diff options
Diffstat (limited to 'fs/affs/inode.c')
-rw-r--r-- | fs/affs/inode.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 676e43470..9dc72d6e0 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -220,44 +220,49 @@ affs_write_inode(struct inode *inode) } int -affs_notify_change(struct inode *inode, struct iattr *attr) +affs_notify_change(struct dentry *dentry, struct iattr *attr) { + struct inode *inode = dentry->d_inode; int error; pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid); error = inode_change_ok(inode,attr); if (error) - return error; + goto out; if (((attr->ia_valid & ATTR_UID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETUID)) || ((attr->ia_valid & ATTR_GID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETGID)) || ((attr->ia_valid & ATTR_MODE) && - (inode->i_sb->u.affs_sb.s_flags & (SF_SETMODE | SF_IMMUTABLE)))) - error = -EPERM; - - if (error) - return (inode->i_sb->u.affs_sb.s_flags & SF_QUIET) ? 0 : error; + (inode->i_sb->u.affs_sb.s_flags & (SF_SETMODE | SF_IMMUTABLE)))) { + if (!(inode->i_sb->u.affs_sb.s_flags & SF_QUIET)) + error = -EPERM; + goto out; + } if (attr->ia_valid & ATTR_MODE) inode->u.affs_i.i_protect = mode_to_prot(attr->ia_mode); - inode_setattr(inode,attr); - - return 0; + inode_setattr(inode, attr); + mark_inode_dirty(inode); + error = 0; +out: + return error; } void affs_put_inode(struct inode *inode) { - pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n",inode->i_ino,inode->i_nlink); - lock_super(inode->i_sb); - if (inode->u.affs_i.i_ec) { - pr_debug("AFFS: freeing ext cache\n"); - free_page((unsigned long)inode->u.affs_i.i_ec); - inode->u.affs_i.i_ec = NULL; + pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", + inode->i_ino,inode->i_nlink); + if (inode->i_count == 1) { + unsigned long cache_page = (unsigned long) inode->u.affs_i.i_ec; + if (cache_page) { + pr_debug("AFFS: freeing ext cache\n"); + inode->u.affs_i.i_ec = NULL; + free_page(cache_page); + } } - unlock_super(inode->i_sb); } void |