mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-31 16:38:12 +00:00
Change calling conventions for filldir_t
filldir_t instances (directory iterators callbacks) used to return 0 for "OK, keep going" or -E... for "stop". Note that it's *NOT* how the error values are reported - the rules for those are callback-dependent and ->iterate{,_shared}() instances only care about zero vs. non-zero (look at emit_dir() and friends). So let's just return bool ("should we keep going?") - it's less confusing that way. The choice between "true means keep going" and "true means stop" is bikesheddable; we have two groups of callbacks - do something for everything in directory, until we run into problem and find an entry in directory and do something to it. The former tended to use 0/-E... conventions - -E<something> on failure. The latter tended to use 0/1, 1 being "stop, we are done". The callers treated anything non-zero as "stop", ignoring which non-zero value did they get. "true means stop" would be more natural for the second group; "true means keep going" - for the first one. I tried both variants and the things like if allocation failed something = -ENOMEM; return true; just looked unnatural and asking for trouble. [folded suggestion from Matthew Wilcox <willy@infradead.org>] Acked-by: Christian Brauner (Microsoft) <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
d6da19c9ca
commit
25885a35a7
19 changed files with 153 additions and 155 deletions
|
@ -922,3 +922,14 @@ is provided - file_open_root_mnt(). In-tree users adjusted.
|
||||||
no_llseek is gone; don't set .llseek to that - just leave it NULL instead.
|
no_llseek is gone; don't set .llseek to that - just leave it NULL instead.
|
||||||
Checks for "does that file have llseek(2), or should it fail with ESPIPE"
|
Checks for "does that file have llseek(2), or should it fail with ESPIPE"
|
||||||
should be done by looking at FMODE_LSEEK in file->f_mode.
|
should be done by looking at FMODE_LSEEK in file->f_mode.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*mandatory*
|
||||||
|
|
||||||
|
filldir_t (readdir callbacks) calling conventions have changed. Instead of
|
||||||
|
returning 0 or -E... it returns bool now. false means "no more" (as -E... used
|
||||||
|
to) and true - "keep going" (as 0 in old calling conventions). Rationale:
|
||||||
|
callers never looked at specific -E... values anyway. ->iterate() and
|
||||||
|
->iterate_shared() instance require no changes at all, all filldir_t ones in
|
||||||
|
the tree converted.
|
||||||
|
|
|
@ -108,7 +108,7 @@ struct osf_dirent_callback {
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
osf_filldir(struct dir_context *ctx, const char *name, int namlen,
|
osf_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -120,11 +120,11 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
|
|
||||||
buf->error = -EINVAL; /* only used if we fail */
|
buf->error = -EINVAL; /* only used if we fail */
|
||||||
if (reclen > buf->count)
|
if (reclen > buf->count)
|
||||||
return -EINVAL;
|
return false;
|
||||||
d_ino = ino;
|
d_ino = ino;
|
||||||
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
||||||
buf->error = -EOVERFLOW;
|
buf->error = -EOVERFLOW;
|
||||||
return -EOVERFLOW;
|
return false;
|
||||||
}
|
}
|
||||||
if (buf->basep) {
|
if (buf->basep) {
|
||||||
if (put_user(offset, buf->basep))
|
if (put_user(offset, buf->basep))
|
||||||
|
@ -141,10 +141,10 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
dirent = (void __user *)dirent + reclen;
|
dirent = (void __user *)dirent + reclen;
|
||||||
buf->dirent = dirent;
|
buf->dirent = dirent;
|
||||||
buf->count -= reclen;
|
buf->count -= reclen;
|
||||||
return 0;
|
return true;
|
||||||
Efault:
|
Efault:
|
||||||
buf->error = -EFAULT;
|
buf->error = -EFAULT;
|
||||||
return -EFAULT;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
|
SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
|
||||||
|
|
23
fs/afs/dir.c
23
fs/afs/dir.c
|
@ -24,9 +24,9 @@ static int afs_readdir(struct file *file, struct dir_context *ctx);
|
||||||
static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
|
static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
|
||||||
static int afs_d_delete(const struct dentry *dentry);
|
static int afs_d_delete(const struct dentry *dentry);
|
||||||
static void afs_d_iput(struct dentry *dentry, struct inode *inode);
|
static void afs_d_iput(struct dentry *dentry, struct inode *inode);
|
||||||
static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
|
static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
|
||||||
loff_t fpos, u64 ino, unsigned dtype);
|
loff_t fpos, u64 ino, unsigned dtype);
|
||||||
static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
|
static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
|
||||||
loff_t fpos, u64 ino, unsigned dtype);
|
loff_t fpos, u64 ino, unsigned dtype);
|
||||||
static int afs_create(struct user_namespace *mnt_userns, struct inode *dir,
|
static int afs_create(struct user_namespace *mnt_userns, struct inode *dir,
|
||||||
struct dentry *dentry, umode_t mode, bool excl);
|
struct dentry *dentry, umode_t mode, bool excl);
|
||||||
|
@ -568,7 +568,7 @@ static int afs_readdir(struct file *file, struct dir_context *ctx)
|
||||||
* - if afs_dir_iterate_block() spots this function, it'll pass the FID
|
* - if afs_dir_iterate_block() spots this function, it'll pass the FID
|
||||||
* uniquifier through dtype
|
* uniquifier through dtype
|
||||||
*/
|
*/
|
||||||
static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
|
static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
|
||||||
int nlen, loff_t fpos, u64 ino, unsigned dtype)
|
int nlen, loff_t fpos, u64 ino, unsigned dtype)
|
||||||
{
|
{
|
||||||
struct afs_lookup_one_cookie *cookie =
|
struct afs_lookup_one_cookie *cookie =
|
||||||
|
@ -584,16 +584,16 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
|
||||||
|
|
||||||
if (cookie->name.len != nlen ||
|
if (cookie->name.len != nlen ||
|
||||||
memcmp(cookie->name.name, name, nlen) != 0) {
|
memcmp(cookie->name.name, name, nlen) != 0) {
|
||||||
_leave(" = 0 [no]");
|
_leave(" = true [keep looking]");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie->fid.vnode = ino;
|
cookie->fid.vnode = ino;
|
||||||
cookie->fid.unique = dtype;
|
cookie->fid.unique = dtype;
|
||||||
cookie->found = 1;
|
cookie->found = 1;
|
||||||
|
|
||||||
_leave(" = -1 [found]");
|
_leave(" = false [found]");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -636,12 +636,11 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
|
||||||
* - if afs_dir_iterate_block() spots this function, it'll pass the FID
|
* - if afs_dir_iterate_block() spots this function, it'll pass the FID
|
||||||
* uniquifier through dtype
|
* uniquifier through dtype
|
||||||
*/
|
*/
|
||||||
static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
|
static bool afs_lookup_filldir(struct dir_context *ctx, const char *name,
|
||||||
int nlen, loff_t fpos, u64 ino, unsigned dtype)
|
int nlen, loff_t fpos, u64 ino, unsigned dtype)
|
||||||
{
|
{
|
||||||
struct afs_lookup_cookie *cookie =
|
struct afs_lookup_cookie *cookie =
|
||||||
container_of(ctx, struct afs_lookup_cookie, ctx);
|
container_of(ctx, struct afs_lookup_cookie, ctx);
|
||||||
int ret;
|
|
||||||
|
|
||||||
_enter("{%s,%u},%s,%u,,%llu,%u",
|
_enter("{%s,%u},%s,%u,,%llu,%u",
|
||||||
cookie->name.name, cookie->name.len, name, nlen,
|
cookie->name.name, cookie->name.len, name, nlen,
|
||||||
|
@ -663,12 +662,10 @@ static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
|
||||||
cookie->fids[1].unique = dtype;
|
cookie->fids[1].unique = dtype;
|
||||||
cookie->found = 1;
|
cookie->found = 1;
|
||||||
if (cookie->one_only)
|
if (cookie->one_only)
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cookie->nr_fids >= 50 ? -1 : 0;
|
return cookie->nr_fids < 50;
|
||||||
_leave(" = %d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct ecryptfs_getdents_callback {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Inspired by generic filldir in fs/readdir.c */
|
/* Inspired by generic filldir in fs/readdir.c */
|
||||||
static int
|
static bool
|
||||||
ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
|
ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
|
||||||
int lower_namelen, loff_t offset, u64 ino, unsigned int d_type)
|
int lower_namelen, loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -61,18 +61,19 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
|
||||||
container_of(ctx, struct ecryptfs_getdents_callback, ctx);
|
container_of(ctx, struct ecryptfs_getdents_callback, ctx);
|
||||||
size_t name_size;
|
size_t name_size;
|
||||||
char *name;
|
char *name;
|
||||||
int rc;
|
int err;
|
||||||
|
bool res;
|
||||||
|
|
||||||
buf->filldir_called++;
|
buf->filldir_called++;
|
||||||
rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
|
err = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
|
||||||
buf->sb, lower_name,
|
buf->sb, lower_name,
|
||||||
lower_namelen);
|
lower_namelen);
|
||||||
if (rc) {
|
if (err) {
|
||||||
if (rc != -EINVAL) {
|
if (err != -EINVAL) {
|
||||||
ecryptfs_printk(KERN_DEBUG,
|
ecryptfs_printk(KERN_DEBUG,
|
||||||
"%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
|
"%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
|
||||||
__func__, lower_name, rc);
|
__func__, lower_name, err);
|
||||||
return rc;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mask -EINVAL errors as these are most likely due a plaintext
|
/* Mask -EINVAL errors as these are most likely due a plaintext
|
||||||
|
@ -81,16 +82,15 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
|
||||||
* the "lost+found" dentry in the root directory of an Ext4
|
* the "lost+found" dentry in the root directory of an Ext4
|
||||||
* filesystem.
|
* filesystem.
|
||||||
*/
|
*/
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->caller->pos = buf->ctx.pos;
|
buf->caller->pos = buf->ctx.pos;
|
||||||
rc = !dir_emit(buf->caller, name, name_size, ino, d_type);
|
res = dir_emit(buf->caller, name, name_size, ino, d_type);
|
||||||
kfree(name);
|
kfree(name);
|
||||||
if (!rc)
|
if (res)
|
||||||
buf->entries_written++;
|
buf->entries_written++;
|
||||||
|
return res;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,14 +111,8 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx)
|
||||||
lower_file = ecryptfs_file_to_lower(file);
|
lower_file = ecryptfs_file_to_lower(file);
|
||||||
rc = iterate_dir(lower_file, &buf.ctx);
|
rc = iterate_dir(lower_file, &buf.ctx);
|
||||||
ctx->pos = buf.ctx.pos;
|
ctx->pos = buf.ctx.pos;
|
||||||
if (rc < 0)
|
if (rc >= 0 && (buf.entries_written || !buf.filldir_called))
|
||||||
goto out;
|
fsstack_copy_attr_atime(inode, file_inode(lower_file));
|
||||||
if (buf.filldir_called && !buf.entries_written)
|
|
||||||
goto out;
|
|
||||||
if (rc >= 0)
|
|
||||||
fsstack_copy_attr_atime(inode,
|
|
||||||
file_inode(lower_file));
|
|
||||||
out:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,21 +248,20 @@ struct getdents_callback {
|
||||||
* A rather strange filldir function to capture
|
* A rather strange filldir function to capture
|
||||||
* the name matching the specified inode number.
|
* the name matching the specified inode number.
|
||||||
*/
|
*/
|
||||||
static int filldir_one(struct dir_context *ctx, const char *name, int len,
|
static bool filldir_one(struct dir_context *ctx, const char *name, int len,
|
||||||
loff_t pos, u64 ino, unsigned int d_type)
|
loff_t pos, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
struct getdents_callback *buf =
|
struct getdents_callback *buf =
|
||||||
container_of(ctx, struct getdents_callback, ctx);
|
container_of(ctx, struct getdents_callback, ctx);
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
buf->sequence++;
|
buf->sequence++;
|
||||||
if (buf->ino == ino && len <= NAME_MAX) {
|
if (buf->ino == ino && len <= NAME_MAX) {
|
||||||
memcpy(buf->name, name, len);
|
memcpy(buf->name, name, len);
|
||||||
buf->name[len] = '\0';
|
buf->name[len] = '\0';
|
||||||
buf->found = 1;
|
buf->found = 1;
|
||||||
result = -1;
|
return false; // no more
|
||||||
}
|
}
|
||||||
return result;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -705,7 +705,7 @@ static int fat_readdir(struct file *file, struct dir_context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \
|
#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \
|
||||||
static int func(struct dir_context *ctx, const char *name, int name_len, \
|
static bool func(struct dir_context *ctx, const char *name, int name_len, \
|
||||||
loff_t offset, u64 ino, unsigned int d_type) \
|
loff_t offset, u64 ino, unsigned int d_type) \
|
||||||
{ \
|
{ \
|
||||||
struct fat_ioctl_filldir_callback *buf = \
|
struct fat_ioctl_filldir_callback *buf = \
|
||||||
|
@ -714,7 +714,7 @@ static int func(struct dir_context *ctx, const char *name, int name_len, \
|
||||||
struct dirent_type __user *d2 = d1 + 1; \
|
struct dirent_type __user *d2 = d1 + 1; \
|
||||||
\
|
\
|
||||||
if (buf->result) \
|
if (buf->result) \
|
||||||
return -EINVAL; \
|
return false; \
|
||||||
buf->result++; \
|
buf->result++; \
|
||||||
\
|
\
|
||||||
if (name != NULL) { \
|
if (name != NULL) { \
|
||||||
|
@ -750,10 +750,10 @@ static int func(struct dir_context *ctx, const char *name, int name_len, \
|
||||||
put_user(short_len, &d1->d_reclen)) \
|
put_user(short_len, &d1->d_reclen)) \
|
||||||
goto efault; \
|
goto efault; \
|
||||||
} \
|
} \
|
||||||
return 0; \
|
return true; \
|
||||||
efault: \
|
efault: \
|
||||||
buf->result = -EFAULT; \
|
buf->result = -EFAULT; \
|
||||||
return -EFAULT; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
|
FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
|
||||||
|
|
|
@ -66,7 +66,7 @@ struct get_name_filldir {
|
||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int get_name_filldir(struct dir_context *ctx, const char *name,
|
static bool get_name_filldir(struct dir_context *ctx, const char *name,
|
||||||
int length, loff_t offset, u64 inum,
|
int length, loff_t offset, u64 inum,
|
||||||
unsigned int type)
|
unsigned int type)
|
||||||
{
|
{
|
||||||
|
@ -74,12 +74,12 @@ static int get_name_filldir(struct dir_context *ctx, const char *name,
|
||||||
container_of(ctx, struct get_name_filldir, ctx);
|
container_of(ctx, struct get_name_filldir, ctx);
|
||||||
|
|
||||||
if (inum != gnfd->inum.no_addr)
|
if (inum != gnfd->inum.no_addr)
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
memcpy(gnfd->name, name, length);
|
memcpy(gnfd->name, name, length);
|
||||||
gnfd->name[length] = 0;
|
gnfd->name[length] = 0;
|
||||||
|
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gfs2_get_name(struct dentry *parent, char *name,
|
static int gfs2_get_name(struct dentry *parent, char *name,
|
||||||
|
|
|
@ -3779,7 +3779,7 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
|
static bool __query_dir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
struct ksmbd_readdir_data *buf;
|
struct ksmbd_readdir_data *buf;
|
||||||
|
@ -3793,22 +3793,20 @@ static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
|
|
||||||
/* dot and dotdot entries are already reserved */
|
/* dot and dotdot entries are already reserved */
|
||||||
if (!strcmp(".", name) || !strcmp("..", name))
|
if (!strcmp(".", name) || !strcmp("..", name))
|
||||||
return 0;
|
return true;
|
||||||
if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
|
if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
|
||||||
return 0;
|
return true;
|
||||||
if (!match_pattern(name, namlen, priv->search_pattern))
|
if (!match_pattern(name, namlen, priv->search_pattern))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
d_info->name = name;
|
d_info->name = name;
|
||||||
d_info->name_len = namlen;
|
d_info->name_len = namlen;
|
||||||
rc = reserve_populate_dentry(d_info, priv->info_level);
|
rc = reserve_populate_dentry(d_info, priv->info_level);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return false;
|
||||||
if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY) {
|
if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY)
|
||||||
d_info->out_buf_len = 0;
|
d_info->out_buf_len = 0;
|
||||||
return 0;
|
return true;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restart_ctx(struct dir_context *ctx)
|
static void restart_ctx(struct dir_context *ctx)
|
||||||
|
|
|
@ -1105,7 +1105,7 @@ int ksmbd_vfs_unlink(struct user_namespace *user_ns,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __dir_empty(struct dir_context *ctx, const char *name, int namlen,
|
static bool __dir_empty(struct dir_context *ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
struct ksmbd_readdir_data *buf;
|
struct ksmbd_readdir_data *buf;
|
||||||
|
@ -1113,9 +1113,7 @@ static int __dir_empty(struct dir_context *ctx, const char *name, int namlen,
|
||||||
buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
|
buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
|
||||||
buf->dirent_count++;
|
buf->dirent_count++;
|
||||||
|
|
||||||
if (buf->dirent_count > 2)
|
return buf->dirent_count <= 2;
|
||||||
return -ENOTEMPTY;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1142,7 +1140,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __caseless_lookup(struct dir_context *ctx, const char *name,
|
static bool __caseless_lookup(struct dir_context *ctx, const char *name,
|
||||||
int namlen, loff_t offset, u64 ino,
|
int namlen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -1151,13 +1149,13 @@ static int __caseless_lookup(struct dir_context *ctx, const char *name,
|
||||||
buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
|
buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
|
||||||
|
|
||||||
if (buf->used != namlen)
|
if (buf->used != namlen)
|
||||||
return 0;
|
return true;
|
||||||
if (!strncasecmp((char *)buf->private, name, namlen)) {
|
if (!strncasecmp((char *)buf->private, name, namlen)) {
|
||||||
memcpy((char *)buf->private, name, namlen);
|
memcpy((char *)buf->private, name, namlen);
|
||||||
buf->dirent_count = 1;
|
buf->dirent_count = 1;
|
||||||
return -EEXIST;
|
return false;
|
||||||
}
|
}
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -266,7 +266,7 @@ struct nfs4_dir_ctx {
|
||||||
struct list_head names;
|
struct list_head names;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
|
nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -275,14 +275,14 @@ nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
|
||||||
struct name_list *entry;
|
struct name_list *entry;
|
||||||
|
|
||||||
if (namlen != HEXDIR_LEN - 1)
|
if (namlen != HEXDIR_LEN - 1)
|
||||||
return 0;
|
return true;
|
||||||
entry = kmalloc(sizeof(struct name_list), GFP_KERNEL);
|
entry = kmalloc(sizeof(struct name_list), GFP_KERNEL);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
return -ENOMEM;
|
return false;
|
||||||
memcpy(entry->name, name, HEXDIR_LEN - 1);
|
memcpy(entry->name, name, HEXDIR_LEN - 1);
|
||||||
entry->name[HEXDIR_LEN - 1] = '\0';
|
entry->name[HEXDIR_LEN - 1] = '\0';
|
||||||
list_add(&entry->list, &ctx->names);
|
list_add(&entry->list, &ctx->names);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -1811,7 +1811,7 @@ struct readdir_data {
|
||||||
int full;
|
int full;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
|
static bool nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
|
||||||
int namlen, loff_t offset, u64 ino,
|
int namlen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -1823,7 +1823,7 @@ static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
|
||||||
reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64));
|
reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64));
|
||||||
if (buf->used + reclen > PAGE_SIZE) {
|
if (buf->used + reclen > PAGE_SIZE) {
|
||||||
buf->full = 1;
|
buf->full = 1;
|
||||||
return -EINVAL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
de->namlen = namlen;
|
de->namlen = namlen;
|
||||||
|
@ -1833,7 +1833,7 @@ static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
|
||||||
memcpy(de->name, name, namlen);
|
memcpy(de->name, name, namlen);
|
||||||
buf->used += reclen;
|
buf->used += reclen;
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp,
|
static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp,
|
||||||
|
|
|
@ -2032,7 +2032,7 @@ struct ocfs2_empty_dir_priv {
|
||||||
unsigned seen_other;
|
unsigned seen_other;
|
||||||
unsigned dx_dir;
|
unsigned dx_dir;
|
||||||
};
|
};
|
||||||
static int ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
|
static bool ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
|
||||||
int name_len, loff_t pos, u64 ino,
|
int name_len, loff_t pos, u64 ino,
|
||||||
unsigned type)
|
unsigned type)
|
||||||
{
|
{
|
||||||
|
@ -2052,7 +2052,7 @@ static int ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
|
||||||
*/
|
*/
|
||||||
if (name_len == 1 && !strncmp(".", name, 1) && pos == 0) {
|
if (name_len == 1 && !strncmp(".", name, 1) && pos == 0) {
|
||||||
p->seen_dot = 1;
|
p->seen_dot = 1;
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name_len == 2 && !strncmp("..", name, 2) &&
|
if (name_len == 2 && !strncmp("..", name, 2) &&
|
||||||
|
@ -2060,13 +2060,13 @@ static int ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
|
||||||
p->seen_dot_dot = 1;
|
p->seen_dot_dot = 1;
|
||||||
|
|
||||||
if (p->dx_dir && p->seen_dot)
|
if (p->dx_dir && p->seen_dot)
|
||||||
return 1;
|
return false;
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->seen_other = 1;
|
p->seen_other = 1;
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ocfs2_empty_dir_dx(struct inode *inode,
|
static int ocfs2_empty_dir_dx(struct inode *inode,
|
||||||
|
|
|
@ -2057,7 +2057,7 @@ struct ocfs2_orphan_filldir_priv {
|
||||||
enum ocfs2_orphan_reco_type orphan_reco_type;
|
enum ocfs2_orphan_reco_type orphan_reco_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
|
static bool ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
|
||||||
int name_len, loff_t pos, u64 ino,
|
int name_len, loff_t pos, u64 ino,
|
||||||
unsigned type)
|
unsigned type)
|
||||||
{
|
{
|
||||||
|
@ -2066,21 +2066,21 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
|
||||||
struct inode *iter;
|
struct inode *iter;
|
||||||
|
|
||||||
if (name_len == 1 && !strncmp(".", name, 1))
|
if (name_len == 1 && !strncmp(".", name, 1))
|
||||||
return 0;
|
return true;
|
||||||
if (name_len == 2 && !strncmp("..", name, 2))
|
if (name_len == 2 && !strncmp("..", name, 2))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
/* do not include dio entry in case of orphan scan */
|
/* do not include dio entry in case of orphan scan */
|
||||||
if ((p->orphan_reco_type == ORPHAN_NO_NEED_TRUNCATE) &&
|
if ((p->orphan_reco_type == ORPHAN_NO_NEED_TRUNCATE) &&
|
||||||
(!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
|
(!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
|
||||||
OCFS2_DIO_ORPHAN_PREFIX_LEN)))
|
OCFS2_DIO_ORPHAN_PREFIX_LEN)))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
/* Skip bad inodes so that recovery can continue */
|
/* Skip bad inodes so that recovery can continue */
|
||||||
iter = ocfs2_iget(p->osb, ino,
|
iter = ocfs2_iget(p->osb, ino,
|
||||||
OCFS2_FI_FLAG_ORPHAN_RECOVERY, 0);
|
OCFS2_FI_FLAG_ORPHAN_RECOVERY, 0);
|
||||||
if (IS_ERR(iter))
|
if (IS_ERR(iter))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
if (!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
|
if (!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
|
||||||
OCFS2_DIO_ORPHAN_PREFIX_LEN))
|
OCFS2_DIO_ORPHAN_PREFIX_LEN))
|
||||||
|
@ -2090,7 +2090,7 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
|
||||||
* happen concurrently with unlink/rename */
|
* happen concurrently with unlink/rename */
|
||||||
if (OCFS2_I(iter)->ip_next_orphan) {
|
if (OCFS2_I(iter)->ip_next_orphan) {
|
||||||
iput(iter);
|
iput(iter);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno);
|
trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno);
|
||||||
|
@ -2099,7 +2099,7 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
|
||||||
OCFS2_I(iter)->ip_next_orphan = p->head;
|
OCFS2_I(iter)->ip_next_orphan = p->head;
|
||||||
p->head = iter;
|
p->head = iter;
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ocfs2_queue_orphans(struct ocfs2_super *osb,
|
static int ocfs2_queue_orphans(struct ocfs2_super *osb,
|
||||||
|
|
|
@ -170,7 +170,7 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
|
static bool ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
|
||||||
const char *name, int len, u64 ino,
|
const char *name, int len, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -179,22 +179,22 @@ static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
|
||||||
struct ovl_cache_entry *p;
|
struct ovl_cache_entry *p;
|
||||||
|
|
||||||
if (ovl_cache_entry_find_link(name, len, &newp, &parent))
|
if (ovl_cache_entry_find_link(name, len, &newp, &parent))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
p = ovl_cache_entry_new(rdd, name, len, ino, d_type);
|
p = ovl_cache_entry_new(rdd, name, len, ino, d_type);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
rdd->err = -ENOMEM;
|
rdd->err = -ENOMEM;
|
||||||
return -ENOMEM;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(&p->l_node, rdd->list);
|
list_add_tail(&p->l_node, rdd->list);
|
||||||
rb_link_node(&p->node, parent, newp);
|
rb_link_node(&p->node, parent, newp);
|
||||||
rb_insert_color(&p->node, rdd->root);
|
rb_insert_color(&p->node, rdd->root);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ovl_fill_lowest(struct ovl_readdir_data *rdd,
|
static bool ovl_fill_lowest(struct ovl_readdir_data *rdd,
|
||||||
const char *name, int namelen,
|
const char *name, int namelen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -211,7 +211,7 @@ static int ovl_fill_lowest(struct ovl_readdir_data *rdd,
|
||||||
list_add_tail(&p->l_node, &rdd->middle);
|
list_add_tail(&p->l_node, &rdd->middle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rdd->err;
|
return rdd->err == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ovl_cache_free(struct list_head *list)
|
void ovl_cache_free(struct list_head *list)
|
||||||
|
@ -250,7 +250,7 @@ static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ovl_fill_merge(struct dir_context *ctx, const char *name,
|
static bool ovl_fill_merge(struct dir_context *ctx, const char *name,
|
||||||
int namelen, loff_t offset, u64 ino,
|
int namelen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -528,7 +528,7 @@ static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ovl_fill_plain(struct dir_context *ctx, const char *name,
|
static bool ovl_fill_plain(struct dir_context *ctx, const char *name,
|
||||||
int namelen, loff_t offset, u64 ino,
|
int namelen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -540,11 +540,11 @@ static int ovl_fill_plain(struct dir_context *ctx, const char *name,
|
||||||
p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type);
|
p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
rdd->err = -ENOMEM;
|
rdd->err = -ENOMEM;
|
||||||
return -ENOMEM;
|
return false;
|
||||||
}
|
}
|
||||||
list_add_tail(&p->l_node, rdd->list);
|
list_add_tail(&p->l_node, rdd->list);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ovl_dir_read_impure(struct path *path, struct list_head *list,
|
static int ovl_dir_read_impure(struct path *path, struct list_head *list,
|
||||||
|
@ -648,7 +648,7 @@ struct ovl_readdir_translate {
|
||||||
bool xinowarn;
|
bool xinowarn;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ovl_fill_real(struct dir_context *ctx, const char *name,
|
static bool ovl_fill_real(struct dir_context *ctx, const char *name,
|
||||||
int namelen, loff_t offset, u64 ino,
|
int namelen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -1027,7 +1027,7 @@ void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper,
|
||||||
inode_unlock(upper->d_inode);
|
inode_unlock(upper->d_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ovl_check_d_type(struct dir_context *ctx, const char *name,
|
static bool ovl_check_d_type(struct dir_context *ctx, const char *name,
|
||||||
int namelen, loff_t offset, u64 ino,
|
int namelen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -1036,12 +1036,12 @@ static int ovl_check_d_type(struct dir_context *ctx, const char *name,
|
||||||
|
|
||||||
/* Even if d_type is not supported, DT_DIR is returned for . and .. */
|
/* Even if d_type is not supported, DT_DIR is returned for . and .. */
|
||||||
if (!strncmp(name, ".", namelen) || !strncmp(name, "..", namelen))
|
if (!strncmp(name, ".", namelen) || !strncmp(name, "..", namelen))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
if (d_type != DT_UNKNOWN)
|
if (d_type != DT_UNKNOWN)
|
||||||
rdd->d_type_supported = true;
|
rdd->d_type_supported = true;
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
68
fs/readdir.c
68
fs/readdir.c
|
@ -140,7 +140,7 @@ struct readdir_callback {
|
||||||
int result;
|
int result;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
|
static bool fillonedir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
struct readdir_callback *buf =
|
struct readdir_callback *buf =
|
||||||
|
@ -149,14 +149,14 @@ static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
unsigned long d_ino;
|
unsigned long d_ino;
|
||||||
|
|
||||||
if (buf->result)
|
if (buf->result)
|
||||||
return -EINVAL;
|
return false;
|
||||||
buf->result = verify_dirent_name(name, namlen);
|
buf->result = verify_dirent_name(name, namlen);
|
||||||
if (buf->result < 0)
|
if (buf->result)
|
||||||
return buf->result;
|
return false;
|
||||||
d_ino = ino;
|
d_ino = ino;
|
||||||
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
||||||
buf->result = -EOVERFLOW;
|
buf->result = -EOVERFLOW;
|
||||||
return -EOVERFLOW;
|
return false;
|
||||||
}
|
}
|
||||||
buf->result++;
|
buf->result++;
|
||||||
dirent = buf->dirent;
|
dirent = buf->dirent;
|
||||||
|
@ -169,12 +169,12 @@ static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
|
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
|
||||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
||||||
user_write_access_end();
|
user_write_access_end();
|
||||||
return 0;
|
return true;
|
||||||
efault_end:
|
efault_end:
|
||||||
user_write_access_end();
|
user_write_access_end();
|
||||||
efault:
|
efault:
|
||||||
buf->result = -EFAULT;
|
buf->result = -EFAULT;
|
||||||
return -EFAULT;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
|
SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
|
||||||
|
@ -219,7 +219,7 @@ struct getdents_callback {
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int filldir(struct dir_context *ctx, const char *name, int namlen,
|
static bool filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
struct linux_dirent __user *dirent, *prev;
|
struct linux_dirent __user *dirent, *prev;
|
||||||
|
@ -232,18 +232,18 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
|
|
||||||
buf->error = verify_dirent_name(name, namlen);
|
buf->error = verify_dirent_name(name, namlen);
|
||||||
if (unlikely(buf->error))
|
if (unlikely(buf->error))
|
||||||
return buf->error;
|
return false;
|
||||||
buf->error = -EINVAL; /* only used if we fail.. */
|
buf->error = -EINVAL; /* only used if we fail.. */
|
||||||
if (reclen > buf->count)
|
if (reclen > buf->count)
|
||||||
return -EINVAL;
|
return false;
|
||||||
d_ino = ino;
|
d_ino = ino;
|
||||||
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
||||||
buf->error = -EOVERFLOW;
|
buf->error = -EOVERFLOW;
|
||||||
return -EOVERFLOW;
|
return false;
|
||||||
}
|
}
|
||||||
prev_reclen = buf->prev_reclen;
|
prev_reclen = buf->prev_reclen;
|
||||||
if (prev_reclen && signal_pending(current))
|
if (prev_reclen && signal_pending(current))
|
||||||
return -EINTR;
|
return false;
|
||||||
dirent = buf->current_dir;
|
dirent = buf->current_dir;
|
||||||
prev = (void __user *) dirent - prev_reclen;
|
prev = (void __user *) dirent - prev_reclen;
|
||||||
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
||||||
|
@ -260,12 +260,12 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
buf->current_dir = (void __user *)dirent + reclen;
|
buf->current_dir = (void __user *)dirent + reclen;
|
||||||
buf->prev_reclen = reclen;
|
buf->prev_reclen = reclen;
|
||||||
buf->count -= reclen;
|
buf->count -= reclen;
|
||||||
return 0;
|
return true;
|
||||||
efault_end:
|
efault_end:
|
||||||
user_write_access_end();
|
user_write_access_end();
|
||||||
efault:
|
efault:
|
||||||
buf->error = -EFAULT;
|
buf->error = -EFAULT;
|
||||||
return -EFAULT;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
||||||
|
@ -307,7 +307,7 @@ struct getdents_callback64 {
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
static bool filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
struct linux_dirent64 __user *dirent, *prev;
|
struct linux_dirent64 __user *dirent, *prev;
|
||||||
|
@ -319,13 +319,13 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||||
|
|
||||||
buf->error = verify_dirent_name(name, namlen);
|
buf->error = verify_dirent_name(name, namlen);
|
||||||
if (unlikely(buf->error))
|
if (unlikely(buf->error))
|
||||||
return buf->error;
|
return false;
|
||||||
buf->error = -EINVAL; /* only used if we fail.. */
|
buf->error = -EINVAL; /* only used if we fail.. */
|
||||||
if (reclen > buf->count)
|
if (reclen > buf->count)
|
||||||
return -EINVAL;
|
return false;
|
||||||
prev_reclen = buf->prev_reclen;
|
prev_reclen = buf->prev_reclen;
|
||||||
if (prev_reclen && signal_pending(current))
|
if (prev_reclen && signal_pending(current))
|
||||||
return -EINTR;
|
return false;
|
||||||
dirent = buf->current_dir;
|
dirent = buf->current_dir;
|
||||||
prev = (void __user *)dirent - prev_reclen;
|
prev = (void __user *)dirent - prev_reclen;
|
||||||
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
||||||
|
@ -342,13 +342,13 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
|
||||||
buf->prev_reclen = reclen;
|
buf->prev_reclen = reclen;
|
||||||
buf->current_dir = (void __user *)dirent + reclen;
|
buf->current_dir = (void __user *)dirent + reclen;
|
||||||
buf->count -= reclen;
|
buf->count -= reclen;
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
efault_end:
|
efault_end:
|
||||||
user_write_access_end();
|
user_write_access_end();
|
||||||
efault:
|
efault:
|
||||||
buf->error = -EFAULT;
|
buf->error = -EFAULT;
|
||||||
return -EFAULT;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCALL_DEFINE3(getdents64, unsigned int, fd,
|
SYSCALL_DEFINE3(getdents64, unsigned int, fd,
|
||||||
|
@ -397,7 +397,7 @@ struct compat_readdir_callback {
|
||||||
int result;
|
int result;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int compat_fillonedir(struct dir_context *ctx, const char *name,
|
static bool compat_fillonedir(struct dir_context *ctx, const char *name,
|
||||||
int namlen, loff_t offset, u64 ino,
|
int namlen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -407,14 +407,14 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
|
||||||
compat_ulong_t d_ino;
|
compat_ulong_t d_ino;
|
||||||
|
|
||||||
if (buf->result)
|
if (buf->result)
|
||||||
return -EINVAL;
|
return false;
|
||||||
buf->result = verify_dirent_name(name, namlen);
|
buf->result = verify_dirent_name(name, namlen);
|
||||||
if (buf->result < 0)
|
if (buf->result)
|
||||||
return buf->result;
|
return false;
|
||||||
d_ino = ino;
|
d_ino = ino;
|
||||||
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
||||||
buf->result = -EOVERFLOW;
|
buf->result = -EOVERFLOW;
|
||||||
return -EOVERFLOW;
|
return false;
|
||||||
}
|
}
|
||||||
buf->result++;
|
buf->result++;
|
||||||
dirent = buf->dirent;
|
dirent = buf->dirent;
|
||||||
|
@ -427,12 +427,12 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
|
||||||
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
|
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
|
||||||
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
|
||||||
user_write_access_end();
|
user_write_access_end();
|
||||||
return 0;
|
return true;
|
||||||
efault_end:
|
efault_end:
|
||||||
user_write_access_end();
|
user_write_access_end();
|
||||||
efault:
|
efault:
|
||||||
buf->result = -EFAULT;
|
buf->result = -EFAULT;
|
||||||
return -EFAULT;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
|
COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
|
||||||
|
@ -471,7 +471,7 @@ struct compat_getdents_callback {
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
|
static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
struct compat_linux_dirent __user *dirent, *prev;
|
struct compat_linux_dirent __user *dirent, *prev;
|
||||||
|
@ -484,18 +484,18 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
|
|
||||||
buf->error = verify_dirent_name(name, namlen);
|
buf->error = verify_dirent_name(name, namlen);
|
||||||
if (unlikely(buf->error))
|
if (unlikely(buf->error))
|
||||||
return buf->error;
|
return false;
|
||||||
buf->error = -EINVAL; /* only used if we fail.. */
|
buf->error = -EINVAL; /* only used if we fail.. */
|
||||||
if (reclen > buf->count)
|
if (reclen > buf->count)
|
||||||
return -EINVAL;
|
return false;
|
||||||
d_ino = ino;
|
d_ino = ino;
|
||||||
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
|
||||||
buf->error = -EOVERFLOW;
|
buf->error = -EOVERFLOW;
|
||||||
return -EOVERFLOW;
|
return false;
|
||||||
}
|
}
|
||||||
prev_reclen = buf->prev_reclen;
|
prev_reclen = buf->prev_reclen;
|
||||||
if (prev_reclen && signal_pending(current))
|
if (prev_reclen && signal_pending(current))
|
||||||
return -EINTR;
|
return false;
|
||||||
dirent = buf->current_dir;
|
dirent = buf->current_dir;
|
||||||
prev = (void __user *) dirent - prev_reclen;
|
prev = (void __user *) dirent - prev_reclen;
|
||||||
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
if (!user_write_access_begin(prev, reclen + prev_reclen))
|
||||||
|
@ -511,12 +511,12 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
|
||||||
buf->prev_reclen = reclen;
|
buf->prev_reclen = reclen;
|
||||||
buf->current_dir = (void __user *)dirent + reclen;
|
buf->current_dir = (void __user *)dirent + reclen;
|
||||||
buf->count -= reclen;
|
buf->count -= reclen;
|
||||||
return 0;
|
return true;
|
||||||
efault_end:
|
efault_end:
|
||||||
user_write_access_end();
|
user_write_access_end();
|
||||||
efault:
|
efault:
|
||||||
buf->error = -EFAULT;
|
buf->error = -EFAULT;
|
||||||
return -EFAULT;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
|
||||||
|
|
|
@ -189,7 +189,7 @@ struct reiserfs_dentry_buf {
|
||||||
struct dentry *dentries[8];
|
struct dentry *dentries[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
|
fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
|
||||||
loff_t offset, u64 ino, unsigned int d_type)
|
loff_t offset, u64 ino, unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -200,16 +200,16 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
|
||||||
WARN_ON_ONCE(!inode_is_locked(d_inode(dbuf->xadir)));
|
WARN_ON_ONCE(!inode_is_locked(d_inode(dbuf->xadir)));
|
||||||
|
|
||||||
if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
|
if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
|
||||||
return -ENOSPC;
|
return false;
|
||||||
|
|
||||||
if (name[0] == '.' && (namelen < 2 ||
|
if (name[0] == '.' && (namelen < 2 ||
|
||||||
(namelen == 2 && name[1] == '.')))
|
(namelen == 2 && name[1] == '.')))
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
dentry = lookup_one_len(name, dbuf->xadir, namelen);
|
dentry = lookup_one_len(name, dbuf->xadir, namelen);
|
||||||
if (IS_ERR(dentry)) {
|
if (IS_ERR(dentry)) {
|
||||||
dbuf->err = PTR_ERR(dentry);
|
dbuf->err = PTR_ERR(dentry);
|
||||||
return PTR_ERR(dentry);
|
return false;
|
||||||
} else if (d_really_is_negative(dentry)) {
|
} else if (d_really_is_negative(dentry)) {
|
||||||
/* A directory entry exists, but no file? */
|
/* A directory entry exists, but no file? */
|
||||||
reiserfs_error(dentry->d_sb, "xattr-20003",
|
reiserfs_error(dentry->d_sb, "xattr-20003",
|
||||||
|
@ -218,11 +218,11 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
|
||||||
dentry, dbuf->xadir);
|
dentry, dbuf->xadir);
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
dbuf->err = -EIO;
|
dbuf->err = -EIO;
|
||||||
return -EIO;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbuf->dentries[dbuf->count++] = dentry;
|
dbuf->dentries[dbuf->count++] = dentry;
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -797,7 +797,7 @@ struct listxattr_buf {
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int listxattr_filler(struct dir_context *ctx, const char *name,
|
static bool listxattr_filler(struct dir_context *ctx, const char *name,
|
||||||
int namelen, loff_t offset, u64 ino,
|
int namelen, loff_t offset, u64 ino,
|
||||||
unsigned int d_type)
|
unsigned int d_type)
|
||||||
{
|
{
|
||||||
|
@ -813,19 +813,19 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
|
||||||
name);
|
name);
|
||||||
if (!handler /* Unsupported xattr name */ ||
|
if (!handler /* Unsupported xattr name */ ||
|
||||||
(handler->list && !handler->list(b->dentry)))
|
(handler->list && !handler->list(b->dentry)))
|
||||||
return 0;
|
return true;
|
||||||
size = namelen + 1;
|
size = namelen + 1;
|
||||||
if (b->buf) {
|
if (b->buf) {
|
||||||
if (b->pos + size > b->size) {
|
if (b->pos + size > b->size) {
|
||||||
b->pos = -ERANGE;
|
b->pos = -ERANGE;
|
||||||
return -ERANGE;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(b->buf + b->pos, name, namelen);
|
memcpy(b->buf + b->pos, name, namelen);
|
||||||
b->buf[b->pos + namelen] = 0;
|
b->buf[b->pos + namelen] = 0;
|
||||||
}
|
}
|
||||||
b->pos += size;
|
b->pos += size;
|
||||||
}
|
}
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -99,7 +99,7 @@ xchk_dir_check_ftype(
|
||||||
* we check the inode number to make sure it's sane, then we check that
|
* we check the inode number to make sure it's sane, then we check that
|
||||||
* we can look up this filename. Finally, we check the ftype.
|
* we can look up this filename. Finally, we check the ftype.
|
||||||
*/
|
*/
|
||||||
STATIC int
|
STATIC bool
|
||||||
xchk_dir_actor(
|
xchk_dir_actor(
|
||||||
struct dir_context *dir_iter,
|
struct dir_context *dir_iter,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
@ -124,7 +124,7 @@ xchk_dir_actor(
|
||||||
xfs_dir2_dataptr_to_db(mp->m_dir_geo, pos));
|
xfs_dir2_dataptr_to_db(mp->m_dir_geo, pos));
|
||||||
|
|
||||||
if (xchk_should_terminate(sdc->sc, &error))
|
if (xchk_should_terminate(sdc->sc, &error))
|
||||||
return error;
|
return !error;
|
||||||
|
|
||||||
/* Does this inode number make sense? */
|
/* Does this inode number make sense? */
|
||||||
if (!xfs_verify_dir_ino(mp, ino)) {
|
if (!xfs_verify_dir_ino(mp, ino)) {
|
||||||
|
@ -191,8 +191,8 @@ xchk_dir_actor(
|
||||||
* and return zero to xchk_directory.
|
* and return zero to xchk_directory.
|
||||||
*/
|
*/
|
||||||
if (error == 0 && sdc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
|
if (error == 0 && sdc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
|
||||||
return -EFSCORRUPTED;
|
return false;
|
||||||
return error;
|
return !error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scrub a directory btree record. */
|
/* Scrub a directory btree record. */
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct xchk_parent_ctx {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Look for a single entry in a directory pointing to an inode. */
|
/* Look for a single entry in a directory pointing to an inode. */
|
||||||
STATIC int
|
STATIC bool
|
||||||
xchk_parent_actor(
|
xchk_parent_actor(
|
||||||
struct dir_context *dc,
|
struct dir_context *dc,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
@ -62,7 +62,7 @@ xchk_parent_actor(
|
||||||
if (xchk_should_terminate(spc->sc, &error))
|
if (xchk_should_terminate(spc->sc, &error))
|
||||||
spc->cancelled = true;
|
spc->cancelled = true;
|
||||||
|
|
||||||
return error;
|
return !error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count the number of dentries in the parent dir that point to this inode. */
|
/* Count the number of dentries in the parent dir that point to this inode. */
|
||||||
|
|
|
@ -2038,9 +2038,10 @@ umode_t mode_strip_sgid(struct user_namespace *mnt_userns,
|
||||||
* the kernel specify what kind of dirent layout it wants to have.
|
* the kernel specify what kind of dirent layout it wants to have.
|
||||||
* This allows the kernel to read directories into kernel space or
|
* This allows the kernel to read directories into kernel space or
|
||||||
* to have different dirent layouts depending on the binary type.
|
* to have different dirent layouts depending on the binary type.
|
||||||
|
* Return 'true' to keep going and 'false' if there are no more entries.
|
||||||
*/
|
*/
|
||||||
struct dir_context;
|
struct dir_context;
|
||||||
typedef int (*filldir_t)(struct dir_context *, const char *, int, loff_t, u64,
|
typedef bool (*filldir_t)(struct dir_context *, const char *, int, loff_t, u64,
|
||||||
unsigned);
|
unsigned);
|
||||||
|
|
||||||
struct dir_context {
|
struct dir_context {
|
||||||
|
@ -3540,17 +3541,17 @@ static inline bool dir_emit(struct dir_context *ctx,
|
||||||
const char *name, int namelen,
|
const char *name, int namelen,
|
||||||
u64 ino, unsigned type)
|
u64 ino, unsigned type)
|
||||||
{
|
{
|
||||||
return ctx->actor(ctx, name, namelen, ctx->pos, ino, type) == 0;
|
return ctx->actor(ctx, name, namelen, ctx->pos, ino, type);
|
||||||
}
|
}
|
||||||
static inline bool dir_emit_dot(struct file *file, struct dir_context *ctx)
|
static inline bool dir_emit_dot(struct file *file, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
return ctx->actor(ctx, ".", 1, ctx->pos,
|
return ctx->actor(ctx, ".", 1, ctx->pos,
|
||||||
file->f_path.dentry->d_inode->i_ino, DT_DIR) == 0;
|
file->f_path.dentry->d_inode->i_ino, DT_DIR);
|
||||||
}
|
}
|
||||||
static inline bool dir_emit_dotdot(struct file *file, struct dir_context *ctx)
|
static inline bool dir_emit_dotdot(struct file *file, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
return ctx->actor(ctx, "..", 2, ctx->pos,
|
return ctx->actor(ctx, "..", 2, ctx->pos,
|
||||||
parent_ino(file->f_path.dentry), DT_DIR) == 0;
|
parent_ino(file->f_path.dentry), DT_DIR);
|
||||||
}
|
}
|
||||||
static inline bool dir_emit_dots(struct file *file, struct dir_context *ctx)
|
static inline bool dir_emit_dots(struct file *file, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue