Skip to content

Commit 7a3353c

Browse files
committed
Merge tag 'pull-file' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs file updates from Al Viro: "struct file-related stuff" * tag 'pull-file' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: dma_buf_getfile(): don't bother with ->f_flags reassignments Change calling conventions for filldir_t locks: fix TOCTOU race when granting write lease
2 parents 70df64d + 47091e4 commit 7a3353c

File tree

23 files changed

+169
-169
lines changed

23 files changed

+169
-169
lines changed

Documentation/filesystems/porting.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,3 +922,14 @@ is provided - file_open_root_mnt(). In-tree users adjusted.
922922
no_llseek is gone; don't set .llseek to that - just leave it NULL instead.
923923
Checks for "does that file have llseek(2), or should it fail with ESPIPE"
924924
should be done by looking at FMODE_LSEEK in file->f_mode.
925+
926+
---
927+
928+
*mandatory*
929+
930+
filldir_t (readdir callbacks) calling conventions have changed. Instead of
931+
returning 0 or -E... it returns bool now. false means "no more" (as -E... used
932+
to) and true - "keep going" (as 0 in old calling conventions). Rationale:
933+
callers never looked at specific -E... values anyway. ->iterate() and
934+
->iterate_shared() instance require no changes at all, all filldir_t ones in
935+
the tree converted.

arch/alpha/kernel/osf_sys.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ struct osf_dirent_callback {
108108
int error;
109109
};
110110

111-
static int
111+
static bool
112112
osf_filldir(struct dir_context *ctx, const char *name, int namlen,
113113
loff_t offset, u64 ino, unsigned int d_type)
114114
{
@@ -120,11 +120,11 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,
120120

121121
buf->error = -EINVAL; /* only used if we fail */
122122
if (reclen > buf->count)
123-
return -EINVAL;
123+
return false;
124124
d_ino = ino;
125125
if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
126126
buf->error = -EOVERFLOW;
127-
return -EOVERFLOW;
127+
return false;
128128
}
129129
if (buf->basep) {
130130
if (put_user(offset, buf->basep))
@@ -141,10 +141,10 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,
141141
dirent = (void __user *)dirent + reclen;
142142
buf->dirent = dirent;
143143
buf->count -= reclen;
144-
return 0;
144+
return true;
145145
Efault:
146146
buf->error = -EFAULT;
147-
return -EFAULT;
147+
return false;
148148
}
149149

150150
SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,

drivers/dma-buf/dma-buf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,11 +531,11 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
531531
* value.
532532
*/
533533
inode->i_ino = atomic64_add_return(1, &dmabuf_inode);
534+
flags &= O_ACCMODE | O_NONBLOCK;
534535
file = alloc_file_pseudo(inode, dma_buf_mnt, "dmabuf",
535536
flags, &dma_buf_fops);
536537
if (IS_ERR(file))
537538
goto err_alloc_file;
538-
file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
539539
file->private_data = dmabuf;
540540
file->f_path.dentry->d_fsdata = dmabuf;
541541

fs/afs/dir.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ static int afs_readdir(struct file *file, struct dir_context *ctx);
2424
static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
2525
static int afs_d_delete(const struct dentry *dentry);
2626
static void afs_d_iput(struct dentry *dentry, struct inode *inode);
27-
static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
27+
static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
2828
loff_t fpos, u64 ino, unsigned dtype);
29-
static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
29+
static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
3030
loff_t fpos, u64 ino, unsigned dtype);
3131
static int afs_create(struct user_namespace *mnt_userns, struct inode *dir,
3232
struct dentry *dentry, umode_t mode, bool excl);
@@ -568,7 +568,7 @@ static int afs_readdir(struct file *file, struct dir_context *ctx)
568568
* - if afs_dir_iterate_block() spots this function, it'll pass the FID
569569
* uniquifier through dtype
570570
*/
571-
static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
571+
static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
572572
int nlen, loff_t fpos, u64 ino, unsigned dtype)
573573
{
574574
struct afs_lookup_one_cookie *cookie =
@@ -584,16 +584,16 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
584584

585585
if (cookie->name.len != nlen ||
586586
memcmp(cookie->name.name, name, nlen) != 0) {
587-
_leave(" = 0 [no]");
588-
return 0;
587+
_leave(" = true [keep looking]");
588+
return true;
589589
}
590590

591591
cookie->fid.vnode = ino;
592592
cookie->fid.unique = dtype;
593593
cookie->found = 1;
594594

595-
_leave(" = -1 [found]");
596-
return -1;
595+
_leave(" = false [found]");
596+
return false;
597597
}
598598

599599
/*
@@ -636,12 +636,11 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
636636
* - if afs_dir_iterate_block() spots this function, it'll pass the FID
637637
* uniquifier through dtype
638638
*/
639-
static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
639+
static bool afs_lookup_filldir(struct dir_context *ctx, const char *name,
640640
int nlen, loff_t fpos, u64 ino, unsigned dtype)
641641
{
642642
struct afs_lookup_cookie *cookie =
643643
container_of(ctx, struct afs_lookup_cookie, ctx);
644-
int ret;
645644

646645
_enter("{%s,%u},%s,%u,,%llu,%u",
647646
cookie->name.name, cookie->name.len, name, nlen,
@@ -663,12 +662,10 @@ static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
663662
cookie->fids[1].unique = dtype;
664663
cookie->found = 1;
665664
if (cookie->one_only)
666-
return -1;
665+
return false;
667666
}
668667

669-
ret = cookie->nr_fids >= 50 ? -1 : 0;
670-
_leave(" = %d", ret);
671-
return ret;
668+
return cookie->nr_fids < 50;
672669
}
673670

674671
/*

fs/ecryptfs/file.c

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,27 @@ struct ecryptfs_getdents_callback {
5353
};
5454

5555
/* Inspired by generic filldir in fs/readdir.c */
56-
static int
56+
static bool
5757
ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
5858
int lower_namelen, loff_t offset, u64 ino, unsigned int d_type)
5959
{
6060
struct ecryptfs_getdents_callback *buf =
6161
container_of(ctx, struct ecryptfs_getdents_callback, ctx);
6262
size_t name_size;
6363
char *name;
64-
int rc;
64+
int err;
65+
bool res;
6566

6667
buf->filldir_called++;
67-
rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
68-
buf->sb, lower_name,
69-
lower_namelen);
70-
if (rc) {
71-
if (rc != -EINVAL) {
68+
err = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
69+
buf->sb, lower_name,
70+
lower_namelen);
71+
if (err) {
72+
if (err != -EINVAL) {
7273
ecryptfs_printk(KERN_DEBUG,
7374
"%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
74-
__func__, lower_name, rc);
75-
return rc;
75+
__func__, lower_name, err);
76+
return false;
7677
}
7778

7879
/* 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,
8182
* the "lost+found" dentry in the root directory of an Ext4
8283
* filesystem.
8384
*/
84-
return 0;
85+
return true;
8586
}
8687

8788
buf->caller->pos = buf->ctx.pos;
88-
rc = !dir_emit(buf->caller, name, name_size, ino, d_type);
89+
res = dir_emit(buf->caller, name, name_size, ino, d_type);
8990
kfree(name);
90-
if (!rc)
91+
if (res)
9192
buf->entries_written++;
92-
93-
return rc;
93+
return res;
9494
}
9595

9696
/**
@@ -111,14 +111,8 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx)
111111
lower_file = ecryptfs_file_to_lower(file);
112112
rc = iterate_dir(lower_file, &buf.ctx);
113113
ctx->pos = buf.ctx.pos;
114-
if (rc < 0)
115-
goto out;
116-
if (buf.filldir_called && !buf.entries_written)
117-
goto out;
118-
if (rc >= 0)
119-
fsstack_copy_attr_atime(inode,
120-
file_inode(lower_file));
121-
out:
114+
if (rc >= 0 && (buf.entries_written || !buf.filldir_called))
115+
fsstack_copy_attr_atime(inode, file_inode(lower_file));
122116
return rc;
123117
}
124118

fs/exportfs/expfs.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,21 +248,20 @@ struct getdents_callback {
248248
* A rather strange filldir function to capture
249249
* the name matching the specified inode number.
250250
*/
251-
static int filldir_one(struct dir_context *ctx, const char *name, int len,
251+
static bool filldir_one(struct dir_context *ctx, const char *name, int len,
252252
loff_t pos, u64 ino, unsigned int d_type)
253253
{
254254
struct getdents_callback *buf =
255255
container_of(ctx, struct getdents_callback, ctx);
256-
int result = 0;
257256

258257
buf->sequence++;
259258
if (buf->ino == ino && len <= NAME_MAX) {
260259
memcpy(buf->name, name, len);
261260
buf->name[len] = '\0';
262261
buf->found = 1;
263-
result = -1;
262+
return false; // no more
264263
}
265-
return result;
264+
return true;
266265
}
267266

268267
/**

fs/fat/dir.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ static int fat_readdir(struct file *file, struct dir_context *ctx)
705705
}
706706

707707
#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \
708-
static int func(struct dir_context *ctx, const char *name, int name_len, \
708+
static bool func(struct dir_context *ctx, const char *name, int name_len, \
709709
loff_t offset, u64 ino, unsigned int d_type) \
710710
{ \
711711
struct fat_ioctl_filldir_callback *buf = \
@@ -714,7 +714,7 @@ static int func(struct dir_context *ctx, const char *name, int name_len, \
714714
struct dirent_type __user *d2 = d1 + 1; \
715715
\
716716
if (buf->result) \
717-
return -EINVAL; \
717+
return false; \
718718
buf->result++; \
719719
\
720720
if (name != NULL) { \
@@ -750,10 +750,10 @@ static int func(struct dir_context *ctx, const char *name, int name_len, \
750750
put_user(short_len, &d1->d_reclen)) \
751751
goto efault; \
752752
} \
753-
return 0; \
753+
return true; \
754754
efault: \
755755
buf->result = -EFAULT; \
756-
return -EFAULT; \
756+
return false; \
757757
}
758758

759759
FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)

fs/file_table.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,7 @@ static void __fput(struct file *file)
324324
}
325325
fops_put(file->f_op);
326326
put_pid(file->f_owner.pid);
327-
if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
328-
i_readcount_dec(inode);
329-
if (mode & FMODE_WRITER) {
330-
put_write_access(inode);
331-
__mnt_drop_write(mnt);
332-
}
327+
put_file_access(file);
333328
dput(dentry);
334329
if (unlikely(mode & FMODE_NEED_UNMOUNT))
335330
dissolve_on_fput(mnt);

fs/gfs2/export.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,20 @@ struct get_name_filldir {
6666
char *name;
6767
};
6868

69-
static int get_name_filldir(struct dir_context *ctx, const char *name,
69+
static bool get_name_filldir(struct dir_context *ctx, const char *name,
7070
int length, loff_t offset, u64 inum,
7171
unsigned int type)
7272
{
7373
struct get_name_filldir *gnfd =
7474
container_of(ctx, struct get_name_filldir, ctx);
7575

7676
if (inum != gnfd->inum.no_addr)
77-
return 0;
77+
return true;
7878

7979
memcpy(gnfd->name, name, length);
8080
gnfd->name[length] = 0;
8181

82-
return 1;
82+
return false;
8383
}
8484

8585
static int gfs2_get_name(struct dentry *parent, char *name,

fs/internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
102102
extern struct file *alloc_empty_file(int, const struct cred *);
103103
extern struct file *alloc_empty_file_noaccount(int, const struct cred *);
104104

105+
static inline void put_file_access(struct file *file)
106+
{
107+
if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
108+
i_readcount_dec(file->f_inode);
109+
} else if (file->f_mode & FMODE_WRITER) {
110+
put_write_access(file->f_inode);
111+
__mnt_drop_write(file->f_path.mnt);
112+
}
113+
}
114+
105115
/*
106116
* super.c
107117
*/

0 commit comments

Comments
 (0)