sd = dentry->d_parent->d_fsdata; /* * Fake invisibility if dir belongs to a group/default groups hierarchy * being attached
*/ if (!configfs_dirent_is_ready(sd)) return -ENOENT;
parent_item = configfs_get_config_item(dentry->d_parent);
type = parent_item->ci_type;
ret = -EPERM; if (!type || !type->ct_item_ops ||
!type->ct_item_ops->allow_link) goto out_put;
/* * This is really sick. What they wanted was a hybrid of * link(2) and symlink(2) - they wanted the target resolved * at syscall time (as link(2) would've done), be a directory * (which link(2) would've refused to do) *AND* be a deep * fucking magic, making the target busy from rmdir POV. * symlink(2) is nothing of that sort, and the locking it * gets matches the normal symlink(2) semantics. Without * attempts to resolve the target (which might very well * not even exist yet) done prior to locking the parent * directory. This perversion, OTOH, needs to resolve * the target, which would lead to obvious deadlocks if * attempted with any directories locked. * * Unfortunately, that garbage is userland ABI and we should've * said "no" back in 2005. Too late now, so we get to * play very ugly games with locking. * * Try *ANYTHING* of that sort in new code, and you will * really regret it. Just ask yourself - what could a BOFH * do to me and do I want to find it out first-hand? * * AV, a thoroughly annoyed bastard.
*/
inode_unlock(dir);
ret = get_target(symname, &path, &target_item, dentry->d_sb);
inode_lock(dir); if (ret) goto out_put;
if (dentry->d_inode || d_unhashed(dentry))
ret = -EEXIST; else
ret = inode_permission(&nop_mnt_idmap, dir,
MAY_WRITE | MAY_EXEC); if (!ret)
ret = type->ct_item_ops->allow_link(parent_item, target_item); if (!ret) {
mutex_lock(&configfs_symlink_mutex);
ret = create_link(parent_item, target_item, dentry);
mutex_unlock(&configfs_symlink_mutex); if (ret && type->ct_item_ops->drop_link)
type->ct_item_ops->drop_link(parent_item,
target_item);
}
/* * drop_link() must be called before * decrementing target's ->s_links, so that the order of * drop_link(this, target) and drop_item(target) is preserved.
*/ if (type && type->ct_item_ops &&
type->ct_item_ops->drop_link)
type->ct_item_ops->drop_link(parent_item,
target_sd->s_element);
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.