Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/little/linux/fs/fuse/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ struct posix_acl *fuse_get_acl(struct inode *inode, int type)
void *value = NULL;
struct posix_acl *acl;

if (fuse_is_bad(inode))
return ERR_PTR(-EIO);

if (!fc->posix_acl || fc->no_getxattr)
return NULL;

Expand Down Expand Up @@ -53,6 +56,9 @@ int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type)
const char *name;
int ret;

if (fuse_is_bad(inode))
return -EIO;

if (!fc->posix_acl || fc->no_setxattr)
return -EOPNOTSUPP;

Expand Down
37 changes: 32 additions & 5 deletions src/little/linux/fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
int ret;

inode = d_inode_rcu(entry);
if (inode && is_bad_inode(inode))
if (inode && fuse_is_bad(inode))
goto invalid;
else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
(flags & LOOKUP_REVAL)) {
Expand Down Expand Up @@ -463,6 +463,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
bool outarg_valid = true;
bool locked;

if (fuse_is_bad(dir))
return ERR_PTR(-EIO);

locked = fuse_lock_inode(dir);
err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
&outarg, &inode);
Expand Down Expand Up @@ -606,6 +609,9 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
struct fuse_conn *fc = get_fuse_conn(dir);
struct dentry *res = NULL;

if (fuse_is_bad(dir))
return -EIO;

if (d_in_lookup(entry)) {
res = fuse_lookup(dir, entry, 0);
if (IS_ERR(res))
Expand Down Expand Up @@ -654,6 +660,9 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
int err;
struct fuse_forget_link *forget;

if (fuse_is_bad(dir))
return -EIO;

forget = fuse_alloc_forget();
if (!forget)
return -ENOMEM;
Expand Down Expand Up @@ -781,6 +790,9 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
struct fuse_mount *fm = get_fuse_mount(dir);
FUSE_ARGS(args);

if (fuse_is_bad(dir))
return -EIO;

args.opcode = FUSE_UNLINK;
args.nodeid = get_node_id(dir);
args.in_numargs = 1;
Expand Down Expand Up @@ -817,6 +829,9 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
struct fuse_mount *fm = get_fuse_mount(dir);
FUSE_ARGS(args);

if (fuse_is_bad(dir))
return -EIO;

args.opcode = FUSE_RMDIR;
args.nodeid = get_node_id(dir);
args.in_numargs = 1;
Expand Down Expand Up @@ -895,6 +910,9 @@ static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
struct fuse_conn *fc = get_fuse_conn(olddir);
int err;

if (fuse_is_bad(olddir))
return -EIO;

if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
return -EINVAL;

Expand Down Expand Up @@ -1030,7 +1048,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
if (!err) {
if (fuse_invalid_attr(&outarg.attr) ||
(inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
make_bad_inode(inode);
fuse_make_bad(inode);
err = -EIO;
} else {
fuse_change_attributes(inode, &outarg.attr,
Expand Down Expand Up @@ -1232,6 +1250,9 @@ static int fuse_permission(struct inode *inode, int mask)
bool refreshed = false;
int err = 0;

if (fuse_is_bad(inode))
return -EIO;

if (!fuse_allow_current_process(fc))
return -EACCES;

Expand Down Expand Up @@ -1327,7 +1348,7 @@ static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
int err;

err = -EIO;
if (is_bad_inode(inode))
if (fuse_is_bad(inode))
goto out_err;

if (fc->cache_symlinks)
Expand Down Expand Up @@ -1375,7 +1396,7 @@ static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
struct fuse_conn *fc = get_fuse_conn(inode);
int err;

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return -EIO;

if (fc->no_fsyncdir)
Expand Down Expand Up @@ -1664,7 +1685,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,

if (fuse_invalid_attr(&outarg.attr) ||
(inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
make_bad_inode(inode);
fuse_make_bad(inode);
err = -EIO;
goto error;
}
Expand Down Expand Up @@ -1727,6 +1748,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
int ret;

if (fuse_is_bad(inode))
return -EIO;

if (!fuse_allow_current_process(get_fuse_conn(inode)))
return -EACCES;

Expand Down Expand Up @@ -1785,6 +1809,9 @@ static int fuse_getattr(const struct path *path, struct kstat *stat,
struct inode *inode = d_inode(path->dentry);
struct fuse_conn *fc = get_fuse_conn(inode);

if (fuse_is_bad(inode))
return -EIO;

if (!fuse_allow_current_process(fc)) {
if (!request_mask) {
/*
Expand Down
19 changes: 11 additions & 8 deletions src/little/linux/fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
bool dax_truncate = (file->f_flags & O_TRUNC) &&
fc->atomic_o_trunc && FUSE_IS_DAX(inode);

if (fuse_is_bad(inode))
return -EIO;

err = generic_file_open(inode, file);
if (err)
return err;
Expand Down Expand Up @@ -463,7 +466,7 @@ static int fuse_flush(struct file *file, fl_owner_t id)
FUSE_ARGS(args);
int err;

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return -EIO;

err = write_inode_now(inode, 1);
Expand Down Expand Up @@ -535,7 +538,7 @@ static int fuse_fsync(struct file *file, loff_t start, loff_t end,
struct fuse_conn *fc = get_fuse_conn(inode);
int err;

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return -EIO;

inode_lock(inode);
Expand Down Expand Up @@ -859,7 +862,7 @@ static int fuse_readpage(struct file *file, struct page *page)
int err;

err = -EIO;
if (is_bad_inode(inode))
if (fuse_is_bad(inode))
goto out;

err = fuse_do_readpage(file, page);
Expand Down Expand Up @@ -952,7 +955,7 @@ static void fuse_readahead(struct readahead_control *rac)
struct fuse_conn *fc = get_fuse_conn(inode);
unsigned int i, max_pages, nr_pages = 0;

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return;

max_pages = min_t(unsigned int, fc->max_pages,
Expand Down Expand Up @@ -1555,7 +1558,7 @@ static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
struct fuse_file *ff = file->private_data;
struct inode *inode = file_inode(file);

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return -EIO;

if (FUSE_IS_DAX(inode))
Expand All @@ -1573,7 +1576,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
struct fuse_file *ff = file->private_data;
struct inode *inode = file_inode(file);

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return -EIO;

if (FUSE_IS_DAX(inode))
Expand Down Expand Up @@ -2172,7 +2175,7 @@ static int fuse_writepages(struct address_space *mapping,
int err;

err = -EIO;
if (is_bad_inode(inode))
if (fuse_is_bad(inode))
goto out;

data.inode = inode;
Expand Down Expand Up @@ -2954,7 +2957,7 @@ long fuse_ioctl_common(struct file *file, unsigned int cmd,
if (!fuse_allow_current_process(fc))
return -EACCES;

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return -EIO;

return fuse_do_ioctl(file, cmd, arg, flags);
Expand Down
12 changes: 12 additions & 0 deletions src/little/linux/fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ enum {
FUSE_I_INIT_RDPLUS,
/** An operation changing file size is in progress */
FUSE_I_SIZE_UNSTABLE,
/* Bad inode */
FUSE_I_BAD,
};

struct fuse_conn;
Expand Down Expand Up @@ -858,6 +860,16 @@ static inline u64 fuse_get_attr_version(struct fuse_conn *fc)
return atomic64_read(&fc->attr_version);
}

static inline void fuse_make_bad(struct inode *inode)
{
set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state);
}

static inline bool fuse_is_bad(struct inode *inode)
{
return unlikely(test_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state));
}

/** Device operations */
extern const struct file_operations fuse_dev_operations;

Expand Down
4 changes: 2 additions & 2 deletions src/little/linux/fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ static void fuse_evict_inode(struct inode *inode)
fi->forget = NULL;
}
}
if (S_ISREG(inode->i_mode) && !is_bad_inode(inode)) {
if (S_ISREG(inode->i_mode) && !fuse_is_bad(inode)) {
WARN_ON(!list_empty(&fi->write_files));
WARN_ON(!list_empty(&fi->queued_writes));
}
Expand Down Expand Up @@ -342,7 +342,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
unlock_new_inode(inode);
} else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
/* Inode has changed type, any I/O on the old should fail */
make_bad_inode(inode);
fuse_make_bad(inode);
iput(inode);
goto retry;
}
Expand Down
4 changes: 2 additions & 2 deletions src/little/linux/fs/fuse/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static int fuse_direntplus_link(struct file *file,
dput(dentry);
goto retry;
}
if (is_bad_inode(inode)) {
if (fuse_is_bad(inode)) {
dput(dentry);
return -EIO;
}
Expand Down Expand Up @@ -568,7 +568,7 @@ int fuse_readdir(struct file *file, struct dir_context *ctx)
struct inode *inode = file_inode(file);
int err;

if (is_bad_inode(inode))
if (fuse_is_bad(inode))
return -EIO;

mutex_lock(&ff->readdir.lock);
Expand Down
9 changes: 9 additions & 0 deletions src/little/linux/fs/fuse/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
struct fuse_getxattr_out outarg;
ssize_t ret;

if (fuse_is_bad(inode))
return -EIO;

if (!fuse_allow_current_process(fm->fc))
return -EACCES;

Expand Down Expand Up @@ -178,6 +181,9 @@ static int fuse_xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, void *value, size_t size)
{
if (fuse_is_bad(inode))
return -EIO;

return fuse_getxattr(inode, name, value, size);
}

Expand All @@ -186,6 +192,9 @@ static int fuse_xattr_set(const struct xattr_handler *handler,
const char *name, const void *value, size_t size,
int flags)
{
if (fuse_is_bad(inode))
return -EIO;

if (!value)
return fuse_removexattr(inode, name);

Expand Down