--- linux-2.4.19/fs/ext3/inode.c 2002-10-16 01:05:24.000000000 +0200 +++ linux-2.4.19.new/fs/ext3/inode.c 2002-10-16 01:04:42.000000000 +0200 @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include @@ -2176,6 +2178,16 @@ /* inode->i_attr_flags |= ATTR_FLAG_NOATIME; unused */ inode->i_flags |= S_NOATIME; } +#ifdef CONFIG_EXT3_FS_POSIX_ACL + if (inode->u.ext3_i.i_file_acl) { + /* The filesystem is mounted with ACL support, and there + are extended attributes for this inode. However we do + not yet know whether there are actually any ACLs. */ + inode->u.ext3_i.i_acl = EXT3_ACL_NOT_CACHED; + inode->u.ext3_i.i_default_acl = EXT3_ACL_NOT_CACHED; + } +#endif + return; bad_inode: @@ -2364,10 +2376,6 @@ * be freed, so we have a strong guarantee that no future commit will * leave these blocks visible to the user.) * - * This is only needed for regular files. rmdir() has its own path, and - * we can never truncate a direcory except on final unlink (at which - * point i_nlink is zero so recovery is easy.) - * * Called with the BKL. */ @@ -2388,7 +2396,8 @@ return error; } - if (attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) { + if (S_ISREG(inode->i_mode) && + attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) { handle_t *handle; handle = ext3_journal_start(inode, 3); @@ -2410,9 +2419,27 @@ /* If inode_setattr's call to ext3_truncate failed to get a * transaction handle at all, we need to clean up the in-core * orphan list manually. */ - if (inode->i_nlink) + if (S_ISREG(inode->i_mode) && inode->i_nlink) ext3_orphan_del(NULL, inode); +#ifdef CONFIG_EXT3_FS_POSIX_ACL + if (!rc && (ia_valid & ATTR_MODE)) { + handle_t *handle; + + handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); + goto err_out; + } + if (!(ia_valid & ATTR_SIZE)) + down(&inode->i_sem); + rc = ext3_acl_chmod(handle, inode); + if (!(ia_valid & ATTR_SIZE)) + up(&inode->i_sem); + ext3_journal_stop(handle, inode); + } +#endif + err_out: ext3_std_error(inode->i_sb, error); if (!error)