caae78e032
All of our inode creation code paths duplicate the calls to btrfs_init_inode_security() and btrfs_add_link(). Subvolume creation additionally duplicates property inheritance and the call to btrfs_set_inode_index(). Fix this by moving the common code into btrfs_create_new_inode(). This accomplishes a few things at once: 1. It reduces code duplication. 2. It allows us to set up the inode completely before inserting the inode item, removing calls to btrfs_update_inode(). 3. It fixes a leak of an inode on disk in some error cases. For example, in btrfs_create(), if btrfs_new_inode() succeeds, then we have inserted an inode item and its inode ref. However, if something after that fails (e.g., btrfs_init_inode_security()), then we end the transaction and then decrement the link count on the inode. If the transaction is committed and the system crashes before the failed inode is deleted, then we leak that inode on disk. Instead, this refactoring aborts the transaction when we can't recover more gracefully. 4. It exposes various ways that subvolume creation diverges from mkdir in terms of inheriting flags, properties, permissions, and POSIX ACLs, a lot of which appears to be accidental. This patch explicitly does _not_ change the existing non-standard behavior, but it makes those differences more clear in the code and documents them so that we can discuss whether they should be changed. Reviewed-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me> Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
27 lines
767 B
C
27 lines
767 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2014 Filipe David Borba Manana <fdmanana@gmail.com>
|
|
*/
|
|
|
|
#ifndef BTRFS_PROPS_H
|
|
#define BTRFS_PROPS_H
|
|
|
|
#include "ctree.h"
|
|
|
|
void __init btrfs_props_init(void);
|
|
|
|
int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
|
|
const char *name, const char *value, size_t value_len,
|
|
int flags);
|
|
int btrfs_validate_prop(const struct btrfs_inode *inode, const char *name,
|
|
const char *value, size_t value_len);
|
|
bool btrfs_ignore_prop(const struct btrfs_inode *inode, const char *name);
|
|
|
|
int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path);
|
|
|
|
int btrfs_inode_inherit_props(struct btrfs_trans_handle *trans,
|
|
struct inode *inode,
|
|
struct inode *dir);
|
|
|
|
#endif
|