/* Try to get a catalog entry for given catalog id */ int hfsplus_find_cat(struct super_block *sb, u32 cnid, struct hfs_find_data *fd)
{
hfsplus_cat_entry tmp; int err;
u16 type;
type = be16_to_cpu(tmp.type); if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) {
pr_err("found bad thread record in catalog\n"); return -EIO;
}
if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
pr_err("catalog name length corrupted\n"); return -EIO;
}
if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) { /* * Increment subfolder count. Note, the value is only meaningful * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set.
*/
HFSPLUS_I(dir)->subfolders++;
}
}
if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) { /* * Decrement subfolder count. Note, the value is only meaningful * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set. * * Check for zero. Some subfolders may have been created * by an implementation ignorant of this counter.
*/ if (HFSPLUS_I(dir)->subfolders)
HFSPLUS_I(dir)->subfolders--;
}
}
int hfsplus_create_cat(u32 cnid, struct inode *dir, conststruct qstr *str, struct inode *inode)
{ struct super_block *sb = dir->i_sb; struct hfs_find_data fd;
hfsplus_cat_entry entry; int entry_size; int err;
/* * Fail early and avoid ENOSPC during the btree operations. We may * have to split the root node at most once.
*/
err = hfs_bmap_reserve(fd.tree, 2 * fd.tree->depth); if (err) goto err2;
/* * Fail early and avoid ENOSPC during the btree operations. We may * have to split the root node at most once.
*/
err = hfs_bmap_reserve(fd.tree, 2 * (int)fd.tree->depth - 2); if (err) goto out;
/* we only need to take spinlock for exclusion with ->release() */
spin_lock(&HFSPLUS_I(dir)->open_dir_lock);
list_for_each(pos, &HFSPLUS_I(dir)->open_dir_list) { struct hfsplus_readdir_data *rd =
list_entry(pos, struct hfsplus_readdir_data, list); if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0)
rd->file->f_pos--;
}
spin_unlock(&HFSPLUS_I(dir)->open_dir_lock);
/* * Fail early and avoid ENOSPC during the btree operations. We may * have to split the root node at most twice.
*/
err = hfs_bmap_reserve(src_fd.tree, 4 * (int)src_fd.tree->depth - 1); if (err) goto out;
/* find the old dir entry and read the data */
err = hfsplus_cat_build_key(sb, src_fd.search_key,
src_dir->i_ino, src_name); if (unlikely(err)) goto out;
hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset,
src_fd.entrylength);
type = be16_to_cpu(entry.type);
/* create new dir entry with the data from the old entry */
err = hfsplus_cat_build_key(sb, dst_fd.search_key,
dst_dir->i_ino, dst_name); if (unlikely(err)) goto out;
err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); if (err != -ENOENT) { if (!err)
err = -EEXIST; goto out;
}
err = hfs_brec_insert(&dst_fd, &entry, src_fd.entrylength); if (err) goto out;
dst_dir->i_size++; if (type == HFSPLUS_FOLDER)
hfsplus_subfolders_inc(dst_dir);
inode_set_mtime_to_ts(dst_dir, inode_set_ctime_current(dst_dir));
/* finally remove the old entry */
err = hfsplus_cat_build_key(sb, src_fd.search_key,
src_dir->i_ino, src_name); if (unlikely(err)) goto out;
err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); if (err) goto out;
err = hfs_brec_remove(&src_fd); if (err) goto out;
src_dir->i_size--; if (type == HFSPLUS_FOLDER)
hfsplus_subfolders_dec(src_dir);
inode_set_mtime_to_ts(src_dir, inode_set_ctime_current(src_dir));
/* remove old thread entry */
hfsplus_cat_build_key_with_cnid(sb, src_fd.search_key, cnid);
err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); if (err) goto out;
type = hfs_bnode_read_u16(src_fd.bnode, src_fd.entryoffset);
err = hfs_brec_remove(&src_fd); if (err) goto out;
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.