forked from Minki/linux
affs-for-5.9-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAl9Qx/MACgkQxWXV+ddt WDvT8g//bO9+xB3dRYLVl5FWur826Zz/dmzpp+A3QCI0er1+zh8/3FHD6dvGyBQu CHQE1GFTdewry1usuGu08WopGiywnCa1svmp+qCJDugiDAG/ciTq2zQWemV2gRXU 1/9yZ62B3eBKuiL+lFNPYFzqWhsX0zP21nxHEkTJi2d8enJDNcmrrWjBrVHUVa1o D0al0zPvaXpcknadhsNSkJnvgMeTcSz89AEIEC5OVfitbaIX09UAadG9kjPLlGJN KNL+/vmAARNe1ze5qjTf3++E1LH28CdJ7rrlhAqyR4L4rApCQw8ZQv3h8EbnidSy VJgDQCk35Z6IxVwbUKYEGiperV2dnsZHukzPT/sqjGrHO0Ct+Fy+YeK+4aw9yaof mWG7RGeczj9t/FbKEGmELlEOHKmJw+PHi5byTokPfsA8smrfaPKNJKlb5bbjALni hOThGiYr18n3RrSidpZ0GVxRcl8j3OwHSVDS/9U3eAF7Z31QtTDoX0MHbK6PrbvW KvGkqIwyLknshS868lyAzXSdg6K4wYqvuh2Z/TuFFPV2MGbsXxHEFgM7M1wueV6x iLhqUDYn2ki79FqqCYsUqWzDMc8m/4v//T4KPTj+BN9H8ij9bdzTXpaHrZAqLX0Y ielkB51hdAlCML/Ctd5xojn5YOXgo5TkSC32QOHvxovSI1qJCIo= =lVnf -----END PGP SIGNATURE----- Merge tag 'affs-for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull affs fix from David Sterba: "One fix to make permissions work the same way as on AmigaOS" * tag 'affs-for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: affs: fix basic permission bits to actually work
This commit is contained in:
commit
26acd8b07a
@ -110,13 +110,15 @@ The Amiga protection flags RWEDRWEDHSPARWED are handled as follows:
|
||||
|
||||
- R maps to r for user, group and others. On directories, R implies x.
|
||||
|
||||
- If both W and D are allowed, w will be set.
|
||||
- W maps to w.
|
||||
|
||||
- E maps to x.
|
||||
|
||||
- H and P are always retained and ignored under Linux.
|
||||
- D is ignored.
|
||||
|
||||
- A is always reset when a file is written to.
|
||||
- H, S and P are always retained and ignored under Linux.
|
||||
|
||||
- A is cleared when a file is written to.
|
||||
|
||||
User id and group id will be used unless set[gu]id are given as mount
|
||||
options. Since most of the Amiga file systems are single user systems
|
||||
@ -128,11 +130,13 @@ Linux -> Amiga:
|
||||
|
||||
The Linux rwxrwxrwx file mode is handled as follows:
|
||||
|
||||
- r permission will set R for user, group and others.
|
||||
- r permission will allow R for user, group and others.
|
||||
|
||||
- w permission will set W and D for user, group and others.
|
||||
- w permission will allow W for user, group and others.
|
||||
|
||||
- x permission of the user will set E for plain files.
|
||||
- x permission of the user will allow E for plain files.
|
||||
|
||||
- D will be allowed for user, group and others.
|
||||
|
||||
- All other flags (suid, sgid, ...) are ignored and will
|
||||
not be retained.
|
||||
|
@ -420,24 +420,51 @@ affs_mode_to_prot(struct inode *inode)
|
||||
u32 prot = AFFS_I(inode)->i_protect;
|
||||
umode_t mode = inode->i_mode;
|
||||
|
||||
/*
|
||||
* First, clear all RWED bits for owner, group, other.
|
||||
* Then, recalculate them afresh.
|
||||
*
|
||||
* We'll always clear the delete-inhibit bit for the owner, as that is
|
||||
* the classic single-user mode AmigaOS protection bit and we need to
|
||||
* stay compatible with all scenarios.
|
||||
*
|
||||
* Since multi-user AmigaOS is an extension, we'll only set the
|
||||
* delete-allow bit if any of the other bits in the same user class
|
||||
* (group/other) are used.
|
||||
*/
|
||||
prot &= ~(FIBF_NOEXECUTE | FIBF_NOREAD
|
||||
| FIBF_NOWRITE | FIBF_NODELETE
|
||||
| FIBF_GRP_EXECUTE | FIBF_GRP_READ
|
||||
| FIBF_GRP_WRITE | FIBF_GRP_DELETE
|
||||
| FIBF_OTR_EXECUTE | FIBF_OTR_READ
|
||||
| FIBF_OTR_WRITE | FIBF_OTR_DELETE);
|
||||
|
||||
/* Classic single-user AmigaOS flags. These are inverted. */
|
||||
if (!(mode & 0100))
|
||||
prot |= FIBF_NOEXECUTE;
|
||||
if (!(mode & 0400))
|
||||
prot |= FIBF_NOREAD;
|
||||
if (!(mode & 0200))
|
||||
prot |= FIBF_NOWRITE;
|
||||
|
||||
/* Multi-user extended flags. Not inverted. */
|
||||
if (mode & 0010)
|
||||
prot |= FIBF_GRP_EXECUTE;
|
||||
if (mode & 0040)
|
||||
prot |= FIBF_GRP_READ;
|
||||
if (mode & 0020)
|
||||
prot |= FIBF_GRP_WRITE;
|
||||
if (mode & 0070)
|
||||
prot |= FIBF_GRP_DELETE;
|
||||
|
||||
if (mode & 0001)
|
||||
prot |= FIBF_OTR_EXECUTE;
|
||||
if (mode & 0004)
|
||||
prot |= FIBF_OTR_READ;
|
||||
if (mode & 0002)
|
||||
prot |= FIBF_OTR_WRITE;
|
||||
if (mode & 0007)
|
||||
prot |= FIBF_OTR_DELETE;
|
||||
|
||||
AFFS_I(inode)->i_protect = prot;
|
||||
}
|
||||
|
@ -429,6 +429,24 @@ static int affs_write_begin(struct file *file, struct address_space *mapping,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int affs_write_end(struct file *file, struct address_space *mapping,
|
||||
loff_t pos, unsigned int len, unsigned int copied,
|
||||
struct page *page, void *fsdata)
|
||||
{
|
||||
struct inode *inode = mapping->host;
|
||||
int ret;
|
||||
|
||||
ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
|
||||
|
||||
/* Clear Archived bit on file writes, as AmigaOS would do */
|
||||
if (AFFS_I(inode)->i_protect & FIBF_ARCHIVED) {
|
||||
AFFS_I(inode)->i_protect &= ~FIBF_ARCHIVED;
|
||||
mark_inode_dirty(inode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
|
||||
{
|
||||
return generic_block_bmap(mapping,block,affs_get_block);
|
||||
@ -438,7 +456,7 @@ const struct address_space_operations affs_aops = {
|
||||
.readpage = affs_readpage,
|
||||
.writepage = affs_writepage,
|
||||
.write_begin = affs_write_begin,
|
||||
.write_end = generic_write_end,
|
||||
.write_end = affs_write_end,
|
||||
.direct_IO = affs_direct_IO,
|
||||
.bmap = _affs_bmap
|
||||
};
|
||||
@ -795,6 +813,12 @@ done:
|
||||
if (tmp > inode->i_size)
|
||||
inode->i_size = AFFS_I(inode)->mmu_private = tmp;
|
||||
|
||||
/* Clear Archived bit on file writes, as AmigaOS would do */
|
||||
if (AFFS_I(inode)->i_protect & FIBF_ARCHIVED) {
|
||||
AFFS_I(inode)->i_protect &= ~FIBF_ARCHIVED;
|
||||
mark_inode_dirty(inode);
|
||||
}
|
||||
|
||||
err_first_bh:
|
||||
unlock_page(page);
|
||||
put_page(page);
|
||||
|
Loading…
Reference in New Issue
Block a user