link_ino = (u32)(long)dentry->d_fsdata; if (inode->i_ino == link_ino) { /* we can't remove the head of the link, as its blocknr is still used as ino, * so we remove the block of the first link instead.
*/
link_ino = be32_to_cpu(AFFS_TAIL(sb, bh)->link_chain);
link_bh = affs_bread(sb, link_ino); if (!link_bh) goto done;
dir = affs_iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent)); if (IS_ERR(dir)) {
retval = PTR_ERR(dir); goto done;
}
affs_lock_dir(dir); /* * if there's a dentry for that block, make it * refer to inode itself.
*/
affs_fix_dcache(inode, link_ino);
retval = affs_remove_hash(dir, link_bh); if (retval) {
affs_unlock_dir(dir); goto done;
}
mark_buffer_dirty_inode(link_bh, inode);
/* Remove a filesystem object. If the object to be removed has * links to it, one of the links must be changed to inherit * the file or directory. As above, any inode will do. * The buffer will not be freed. If the header is a link, the * block will be marked as free. * This function returns a negative error number in case of * an error, else 0 if the inode is to be deleted or 1 if not.
*/
int
affs_remove_header(struct dentry *dentry)
{ struct super_block *sb; struct inode *inode, *dir; struct buffer_head *bh = NULL; int retval;
dir = d_inode(dentry->d_parent);
sb = dir->i_sb;
retval = -ENOENT;
inode = d_inode(dentry); if (!inode) goto done;
affs_lock_link(inode);
affs_lock_dir(dir); switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) { case ST_USERDIR: /* if we ever want to support links to dirs * i_hash_lock of the inode must only be * taken after some checks
*/
affs_lock_dir(inode);
retval = affs_empty_dir(inode);
affs_unlock_dir(inode); if (retval) goto done_unlock; break; default: break;
}
retval = affs_remove_hash(dir, bh); if (retval) goto done_unlock;
mark_buffer_dirty_inode(bh, inode);
/* Checksum a block, do various consistency checks and optionally return the blocks type number. DATA points to the block. If their pointers are non-null, *PTYPE and *STYPE are set to the primary and secondary block types respectively, *HASHSIZE is set to the size of the hashtable (which lets us calculate the block size).
Returns non-zero if the block is not consistent. */
/* * 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;
/* Check if the name is valid for a affs object. */
int
affs_check_name(constunsignedchar *name, int len, bool notruncate)
{ int i;
if (len > AFFSNAMEMAX) { if (notruncate) return -ENAMETOOLONG;
len = AFFSNAMEMAX;
} for (i = 0; i < len; i++) { if (name[i] < ' ' || name[i] == ':'
|| (name[i] > 0x7e && name[i] < 0xa0)) return -EINVAL;
}
return 0;
}
/* This function copies name to bstr, with at most 30 * characters length. The bstr will be prepended by * a length byte. * NOTE: The name will must be already checked by * affs_check_name()!
*/
int
affs_copy_name(unsignedchar *bstr, struct dentry *dentry)
{
u32 len = min(dentry->d_name.len, AFFSNAMEMAX);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.