for (i = 0; i < dir->nr_buffers; i++)
bforget(dir->bhs[i]);
__adfs_dir_cleanup(dir);
}
int adfs_dir_read_buffers(struct super_block *sb, u32 indaddr, unsignedint size, struct adfs_dir *dir)
{ struct buffer_head **bhs; unsignedint i, num; int block;
num = ALIGN(size, sb->s_blocksize) >> sb->s_blocksize_bits; if (num > ARRAY_SIZE(dir->bh)) { /* We only allow one extension */ if (dir->bhs != dir->bh) return -EINVAL;
bhs = kcalloc(num, sizeof(*bhs), GFP_KERNEL); if (!bhs) return -ENOMEM;
if (dir->nr_buffers)
memcpy(bhs, dir->bhs, dir->nr_buffers * sizeof(*bhs));
dir->bhs = bhs;
}
for (i = dir->nr_buffers; i < num; i++) {
block = __adfs_block_map(sb, indaddr, i); if (!block) {
adfs_error(sb, "dir %06x has a hole at offset %u",
indaddr, i); goto error;
}
dir->bhs[i] = sb_bread(sb, block); if (!dir->bhs[i]) {
adfs_error(sb, "dir %06x failed read at offset %u, mapped block 0x%08x",
indaddr, i, block); goto error;
}
ret = adfs_dir_read(sb, ADFS_I(inode)->indaddr, inode->i_size, dir); if (ret) return ret;
if (ADFS_I(inode)->parent_id != dir->parent_id) {
adfs_error(sb, "parent directory id changed under me! (%06x but got %06x)\n",
ADFS_I(inode)->parent_id, dir->parent_id);
adfs_dir_relse(dir);
ret = -EIO;
}
/* * RISC OS allows the use of '/' in directory entry names, so we need * to fix these up. '/' is typically used for FAT compatibility to * represent '.', so do the same conversion here. In any case, '.' * will never be in a RISC OS name since it is used as the pathname * separator. Handle the case where we may generate a '.' or '..' * name, replacing the first character with '^' (the RISC OS "parent * directory" character.)
*/ for (i = dots = 0; i < obj->name_len; i++) if (obj->name[i] == '/') {
obj->name[i] = '.';
dots++;
}
/* * If the object is a file, and the user requested the ,xyz hex * filetype suffix to the name, check the filetype and append.
*/ if (!(obj->attr & ADFS_NDA_DIRECTORY) && ADFS_SB(dir->sb)->s_ftsuffix) {
u16 filetype = adfs_filetype(obj->loadaddr);
int
adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
{ conststruct adfs_dir_ops *ops = ADFS_SB(sb)->s_dir; struct adfs_dir dir; int ret;
if (!IS_ENABLED(CONFIG_ADFS_FS_RW)) return -EINVAL;
if (!ops->update) return -EINVAL;
down_write(&adfs_dir_rwsem);
ret = adfs_dir_read(sb, obj->parent_id, 0, &dir); if (ret) goto unlock;
ret = ops->update(&dir, obj); if (ret) goto forget;
ret = ops->commit(&dir); if (ret) goto forget;
up_write(&adfs_dir_rwsem);
adfs_dir_mark_dirty(&dir);
if (wait)
ret = adfs_dir_sync(&dir);
adfs_dir_relse(&dir); return ret;
/* * If the updated failed because the entry wasn't found, we can * just release the buffers. If it was any other error, forget * the dirtied buffers so they aren't written back to the media.
*/
forget: if (ret == -ENOENT)
adfs_dir_relse(&dir); else
adfs_dir_forget(&dir);
unlock:
up_write(&adfs_dir_rwsem);
return ret;
}
staticunsignedchar adfs_tolower(unsignedchar c)
{ if (c >= 'A' && c <= 'Z')
c += 'a' - 'A'; return c;
}
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.