Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
tools/testing/selftests/net/forwarding/Makefilef62c5acc80("selftests/net/forwarding: add missing tests to Makefile")50fe062c80("selftests: forwarding: new test, verify host mdb entries") https://lore.kernel.org/all/20220502111539.0b7e4621@canb.auug.org.au/ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -384,6 +384,17 @@ static inline bool btrfs_inode_in_log(struct btrfs_inode *inode, u64 generation)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the inode has flags compatible with compression
|
||||
*/
|
||||
static inline bool btrfs_inode_can_compress(const struct btrfs_inode *inode)
|
||||
{
|
||||
if (inode->flags & BTRFS_INODE_NODATACOW ||
|
||||
inode->flags & BTRFS_INODE_NODATASUM)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct btrfs_dio_private {
|
||||
struct inode *inode;
|
||||
|
||||
|
||||
@@ -480,17 +480,6 @@ static noinline int add_async_extent(struct async_chunk *cow,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the inode has flags compatible with compression
|
||||
*/
|
||||
static inline bool inode_can_compress(struct btrfs_inode *inode)
|
||||
{
|
||||
if (inode->flags & BTRFS_INODE_NODATACOW ||
|
||||
inode->flags & BTRFS_INODE_NODATASUM)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the inode needs to be submitted to compression, based on mount
|
||||
* options, defragmentation, properties or heuristics.
|
||||
@@ -500,7 +489,7 @@ static inline int inode_need_compress(struct btrfs_inode *inode, u64 start,
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
||||
|
||||
if (!inode_can_compress(inode)) {
|
||||
if (!btrfs_inode_can_compress(inode)) {
|
||||
WARN(IS_ENABLED(CONFIG_BTRFS_DEBUG),
|
||||
KERN_ERR "BTRFS: unexpected compression for ino %llu\n",
|
||||
btrfs_ino(inode));
|
||||
@@ -2019,7 +2008,7 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page
|
||||
ASSERT(!zoned || btrfs_is_data_reloc_root(inode->root));
|
||||
ret = run_delalloc_nocow(inode, locked_page, start, end,
|
||||
page_started, nr_written);
|
||||
} else if (!inode_can_compress(inode) ||
|
||||
} else if (!btrfs_inode_can_compress(inode) ||
|
||||
!inode_need_compress(inode, start, end)) {
|
||||
if (zoned)
|
||||
ret = run_delalloc_zoned(inode, locked_page, start, end,
|
||||
|
||||
@@ -17,9 +17,11 @@ static DEFINE_HASHTABLE(prop_handlers_ht, BTRFS_PROP_HANDLERS_HT_BITS);
|
||||
struct prop_handler {
|
||||
struct hlist_node node;
|
||||
const char *xattr_name;
|
||||
int (*validate)(const char *value, size_t len);
|
||||
int (*validate)(const struct btrfs_inode *inode, const char *value,
|
||||
size_t len);
|
||||
int (*apply)(struct inode *inode, const char *value, size_t len);
|
||||
const char *(*extract)(struct inode *inode);
|
||||
bool (*ignore)(const struct btrfs_inode *inode);
|
||||
int inheritable;
|
||||
};
|
||||
|
||||
@@ -55,7 +57,8 @@ find_prop_handler(const char *name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int btrfs_validate_prop(const char *name, const char *value, size_t value_len)
|
||||
int btrfs_validate_prop(const struct btrfs_inode *inode, const char *name,
|
||||
const char *value, size_t value_len)
|
||||
{
|
||||
const struct prop_handler *handler;
|
||||
|
||||
@@ -69,7 +72,29 @@ int btrfs_validate_prop(const char *name, const char *value, size_t value_len)
|
||||
if (value_len == 0)
|
||||
return 0;
|
||||
|
||||
return handler->validate(value, value_len);
|
||||
return handler->validate(inode, value, value_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a property should be ignored (not set) for an inode.
|
||||
*
|
||||
* @inode: The target inode.
|
||||
* @name: The property's name.
|
||||
*
|
||||
* The caller must be sure the given property name is valid, for example by
|
||||
* having previously called btrfs_validate_prop().
|
||||
*
|
||||
* Returns: true if the property should be ignored for the given inode
|
||||
* false if the property must not be ignored for the given inode
|
||||
*/
|
||||
bool btrfs_ignore_prop(const struct btrfs_inode *inode, const char *name)
|
||||
{
|
||||
const struct prop_handler *handler;
|
||||
|
||||
handler = find_prop_handler(name, NULL);
|
||||
ASSERT(handler != NULL);
|
||||
|
||||
return handler->ignore(inode);
|
||||
}
|
||||
|
||||
int btrfs_set_prop(struct btrfs_trans_handle *trans, struct inode *inode,
|
||||
@@ -252,8 +277,12 @@ int btrfs_load_inode_props(struct inode *inode, struct btrfs_path *path)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int prop_compression_validate(const char *value, size_t len)
|
||||
static int prop_compression_validate(const struct btrfs_inode *inode,
|
||||
const char *value, size_t len)
|
||||
{
|
||||
if (!btrfs_inode_can_compress(inode))
|
||||
return -EINVAL;
|
||||
|
||||
if (!value)
|
||||
return 0;
|
||||
|
||||
@@ -310,6 +339,22 @@ static int prop_compression_apply(struct inode *inode, const char *value,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool prop_compression_ignore(const struct btrfs_inode *inode)
|
||||
{
|
||||
/*
|
||||
* Compression only has effect for regular files, and for directories
|
||||
* we set it just to propagate it to new files created inside them.
|
||||
* Everything else (symlinks, devices, sockets, fifos) is pointless as
|
||||
* it will do nothing, so don't waste metadata space on a compression
|
||||
* xattr for anything that is neither a file nor a directory.
|
||||
*/
|
||||
if (!S_ISREG(inode->vfs_inode.i_mode) &&
|
||||
!S_ISDIR(inode->vfs_inode.i_mode))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *prop_compression_extract(struct inode *inode)
|
||||
{
|
||||
switch (BTRFS_I(inode)->prop_compress) {
|
||||
@@ -330,6 +375,7 @@ static struct prop_handler prop_handlers[] = {
|
||||
.validate = prop_compression_validate,
|
||||
.apply = prop_compression_apply,
|
||||
.extract = prop_compression_extract,
|
||||
.ignore = prop_compression_ignore,
|
||||
.inheritable = 1
|
||||
},
|
||||
};
|
||||
@@ -356,6 +402,9 @@ static int inherit_props(struct btrfs_trans_handle *trans,
|
||||
if (!h->inheritable)
|
||||
continue;
|
||||
|
||||
if (h->ignore(BTRFS_I(inode)))
|
||||
continue;
|
||||
|
||||
value = h->extract(parent);
|
||||
if (!value)
|
||||
continue;
|
||||
@@ -364,7 +413,7 @@ static int inherit_props(struct btrfs_trans_handle *trans,
|
||||
* This is not strictly necessary as the property should be
|
||||
* valid, but in case it isn't, don't propagate it further.
|
||||
*/
|
||||
ret = h->validate(value, strlen(value));
|
||||
ret = h->validate(BTRFS_I(inode), value, strlen(value));
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@ 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 char *name, const char *value, size_t value_len);
|
||||
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);
|
||||
|
||||
|
||||
@@ -5804,6 +5804,18 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
|
||||
mutex_lock(&inode->log_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* For symlinks, we must always log their content, which is stored in an
|
||||
* inline extent, otherwise we could end up with an empty symlink after
|
||||
* log replay, which is invalid on linux (symlink(2) returns -ENOENT if
|
||||
* one attempts to create an empty symlink).
|
||||
* We don't need to worry about flushing delalloc, because when we create
|
||||
* the inline extent when the symlink is created (we never have delalloc
|
||||
* for symlinks).
|
||||
*/
|
||||
if (S_ISLNK(inode->vfs_inode.i_mode))
|
||||
inode_only = LOG_INODE_ALL;
|
||||
|
||||
/*
|
||||
* Before logging the inode item, cache the value returned by
|
||||
* inode_logged(), because after that we have the need to figure out if
|
||||
@@ -6182,7 +6194,7 @@ again:
|
||||
}
|
||||
|
||||
ctx->log_new_dentries = false;
|
||||
if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
|
||||
if (type == BTRFS_FT_DIR)
|
||||
log_mode = LOG_INODE_ALL;
|
||||
ret = btrfs_log_inode(trans, BTRFS_I(di_inode),
|
||||
log_mode, ctx);
|
||||
|
||||
@@ -262,7 +262,8 @@ int btrfs_setxattr_trans(struct inode *inode, const char *name,
|
||||
inode_inc_iversion(inode);
|
||||
inode->i_ctime = current_time(inode);
|
||||
ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
|
||||
BUG_ON(ret);
|
||||
if (ret)
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
out:
|
||||
if (start_trans)
|
||||
btrfs_end_transaction(trans);
|
||||
@@ -403,10 +404,13 @@ static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
|
||||
name = xattr_full_name(handler, name);
|
||||
ret = btrfs_validate_prop(name, value, size);
|
||||
ret = btrfs_validate_prop(BTRFS_I(inode), name, value, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (btrfs_ignore_prop(BTRFS_I(inode), name))
|
||||
return 0;
|
||||
|
||||
trans = btrfs_start_transaction(root, 2);
|
||||
if (IS_ERR(trans))
|
||||
return PTR_ERR(trans);
|
||||
@@ -416,7 +420,8 @@ static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
|
||||
inode_inc_iversion(inode);
|
||||
inode->i_ctime = current_time(inode);
|
||||
ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
|
||||
BUG_ON(ret);
|
||||
if (ret)
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
}
|
||||
|
||||
btrfs_end_transaction(trans);
|
||||
|
||||
@@ -2274,6 +2274,8 @@ retry:
|
||||
list_for_each_entry(req, &ci->i_unsafe_dirops,
|
||||
r_unsafe_dir_item) {
|
||||
s = req->r_session;
|
||||
if (!s)
|
||||
continue;
|
||||
if (unlikely(s->s_mds >= max_sessions)) {
|
||||
spin_unlock(&ci->i_unsafe_lock);
|
||||
for (i = 0; i < max_sessions; i++) {
|
||||
@@ -2294,6 +2296,8 @@ retry:
|
||||
list_for_each_entry(req, &ci->i_unsafe_iops,
|
||||
r_unsafe_target_item) {
|
||||
s = req->r_session;
|
||||
if (!s)
|
||||
continue;
|
||||
if (unlikely(s->s_mds >= max_sessions)) {
|
||||
spin_unlock(&ci->i_unsafe_lock);
|
||||
for (i = 0; i < max_sessions; i++) {
|
||||
@@ -3870,6 +3874,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
|
||||
dout("handle_cap_export inode %p ci %p mds%d mseq %d target %d\n",
|
||||
inode, ci, mds, mseq, target);
|
||||
retry:
|
||||
down_read(&mdsc->snap_rwsem);
|
||||
spin_lock(&ci->i_ceph_lock);
|
||||
cap = __get_cap_for_mds(ci, mds);
|
||||
if (!cap || cap->cap_id != le64_to_cpu(ex->cap_id))
|
||||
@@ -3933,6 +3938,7 @@ retry:
|
||||
}
|
||||
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
up_read(&mdsc->snap_rwsem);
|
||||
mutex_unlock(&session->s_mutex);
|
||||
|
||||
/* open target session */
|
||||
@@ -3958,6 +3964,7 @@ retry:
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
up_read(&mdsc->snap_rwsem);
|
||||
mutex_unlock(&session->s_mutex);
|
||||
if (tsession) {
|
||||
mutex_unlock(&tsession->s_mutex);
|
||||
|
||||
@@ -4434,8 +4434,6 @@ static void maybe_recover_session(struct ceph_mds_client *mdsc)
|
||||
|
||||
bool check_session_state(struct ceph_mds_session *s)
|
||||
{
|
||||
struct ceph_fs_client *fsc = s->s_mdsc->fsc;
|
||||
|
||||
switch (s->s_state) {
|
||||
case CEPH_MDS_SESSION_OPEN:
|
||||
if (s->s_ttl && time_after(jiffies, s->s_ttl)) {
|
||||
@@ -4444,10 +4442,6 @@ bool check_session_state(struct ceph_mds_session *s)
|
||||
}
|
||||
break;
|
||||
case CEPH_MDS_SESSION_CLOSING:
|
||||
/* Should never reach this when not force unmounting */
|
||||
WARN_ON_ONCE(s->s_ttl &&
|
||||
READ_ONCE(fsc->mount_state) != CEPH_MOUNT_SHUTDOWN);
|
||||
fallthrough;
|
||||
case CEPH_MDS_SESSION_NEW:
|
||||
case CEPH_MDS_SESSION_RESTARTING:
|
||||
case CEPH_MDS_SESSION_CLOSED:
|
||||
|
||||
@@ -3783,6 +3783,7 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode)
|
||||
if (!(kiocb->ki_flags & IOCB_DIRECT) || !file->f_op->iopoll)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
kiocb->private = NULL;
|
||||
kiocb->ki_flags |= IOCB_HIPRI | IOCB_ALLOC_CACHE;
|
||||
kiocb->ki_complete = io_complete_rw_iopoll;
|
||||
req->iopoll_completed = 0;
|
||||
@@ -5207,6 +5208,8 @@ static int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
|
||||
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
|
||||
return -EINVAL;
|
||||
if (unlikely(sqe->addr2 || sqe->file_index))
|
||||
return -EINVAL;
|
||||
|
||||
sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
|
||||
sr->len = READ_ONCE(sqe->len);
|
||||
@@ -5418,6 +5421,8 @@ static int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
|
||||
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
|
||||
return -EINVAL;
|
||||
if (unlikely(sqe->addr2 || sqe->file_index))
|
||||
return -EINVAL;
|
||||
|
||||
sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr));
|
||||
sr->len = READ_ONCE(sqe->len);
|
||||
@@ -10588,7 +10593,7 @@ static int io_ringfd_unregister(struct io_ring_ctx *ctx, void __user *__arg,
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (reg.resv || reg.offset >= IO_RINGFD_REG_MAX) {
|
||||
if (reg.resv || reg.data || reg.offset >= IO_RINGFD_REG_MAX) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1406,7 +1406,12 @@ static void __kernfs_remove(struct kernfs_node *kn)
|
||||
*/
|
||||
void kernfs_remove(struct kernfs_node *kn)
|
||||
{
|
||||
struct kernfs_root *root = kernfs_root(kn);
|
||||
struct kernfs_root *root;
|
||||
|
||||
if (!kn)
|
||||
return;
|
||||
|
||||
root = kernfs_root(kn);
|
||||
|
||||
down_write(&root->kernfs_rwsem);
|
||||
__kernfs_remove(kn);
|
||||
|
||||
Reference in New Issue
Block a user