Skip to content

Commit 56a79b7

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull more VFS bits from Al Viro: "Unfortunately, it looks like xattr series will have to wait until the next cycle ;-/ This pile contains 9p cleanups and fixes (races in v9fs_fid_add() etc), fixup for nommu breakage in shmem.c, several cleanups and a bit more file_inode() work" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: constify path_get/path_put and fs_struct.c stuff fix nommu breakage in shmem.c cache the value of file_inode() in struct file 9p: if v9fs_fid_lookup() gets to asking server, it'd better have hashed dentry 9p: make sure ->lookup() adds fid to the right dentry 9p: untangle ->lookup() a bit 9p: double iput() in ->lookup() if d_materialise_unique() fails 9p: v9fs_fid_add() can't fail now v9fs: get rid of v9fs_dentry 9p: turn fid->dlist into hlist 9p: don't bother with private lock in ->d_fsdata; dentry->d_lock will do just fine more file_inode() open-coded instances selinux: opened file can't have NULL or negative ->f_path.dentry (In the meantime, the hlist traversal macros have changed, so this required a semantic conflict fixup for the newly hlistified fid->dlist)
2 parents 1c82315 + dcf787f commit 56a79b7

File tree

26 files changed

+108
-171
lines changed

26 files changed

+108
-171
lines changed

arch/s390/hypfs/inode.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,10 @@ static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov,
171171
unsigned long nr_segs, loff_t offset)
172172
{
173173
int rc;
174-
struct super_block *sb;
175-
struct hypfs_sb_info *fs_info;
174+
struct super_block *sb = file_inode(iocb->ki_filp)->i_sb;
175+
struct hypfs_sb_info *fs_info = sb->s_fs_info;
176176
size_t count = iov_length(iov, nr_segs);
177177

178-
sb = iocb->ki_filp->f_path.dentry->d_inode->i_sb;
179-
fs_info = sb->s_fs_info;
180178
/*
181179
* Currently we only allow one update per second for two reasons:
182180
* 1. diag 204 is VERY expensive

arch/x86/kernel/msr.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ static ssize_t msr_read(struct file *file, char __user *buf,
7171
u32 __user *tmp = (u32 __user *) buf;
7272
u32 data[2];
7373
u32 reg = *ppos;
74-
int cpu = iminor(file->f_path.dentry->d_inode);
74+
int cpu = iminor(file_inode(file));
7575
int err = 0;
7676
ssize_t bytes = 0;
7777

@@ -99,7 +99,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
9999
const u32 __user *tmp = (const u32 __user *)buf;
100100
u32 data[2];
101101
u32 reg = *ppos;
102-
int cpu = iminor(file->f_path.dentry->d_inode);
102+
int cpu = iminor(file_inode(file));
103103
int err = 0;
104104
ssize_t bytes = 0;
105105

@@ -125,7 +125,7 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
125125
{
126126
u32 __user *uregs = (u32 __user *)arg;
127127
u32 regs[8];
128-
int cpu = iminor(file->f_path.dentry->d_inode);
128+
int cpu = iminor(file_inode(file));
129129
int err;
130130

131131
switch (ioc) {
@@ -171,13 +171,12 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
171171

172172
static int msr_open(struct inode *inode, struct file *file)
173173
{
174-
unsigned int cpu;
174+
unsigned int cpu = iminor(file_inode(file));
175175
struct cpuinfo_x86 *c;
176176

177177
if (!capable(CAP_SYS_RAWIO))
178178
return -EPERM;
179179

180-
cpu = iminor(file->f_path.dentry->d_inode);
181180
if (cpu >= nr_cpu_ids || !cpu_online(cpu))
182181
return -ENXIO; /* No such CPU */
183182

drivers/staging/comedi/comedi_fops.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
580580
struct comedi_devinfo __user *arg,
581581
struct file *file)
582582
{
583-
const unsigned minor = iminor(file->f_dentry->d_inode);
583+
const unsigned minor = iminor(file_inode(file));
584584
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
585585
struct comedi_subdevice *s;
586586
struct comedi_devinfo devinfo;
@@ -1615,7 +1615,7 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg,
16151615
static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
16161616
unsigned long arg)
16171617
{
1618-
const unsigned minor = iminor(file->f_dentry->d_inode);
1618+
const unsigned minor = iminor(file_inode(file));
16191619
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
16201620
struct comedi_device *dev = comedi_dev_from_file_info(info);
16211621
int rc;
@@ -1743,7 +1743,7 @@ static struct vm_operations_struct comedi_vm_ops = {
17431743

17441744
static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
17451745
{
1746-
const unsigned minor = iminor(file->f_dentry->d_inode);
1746+
const unsigned minor = iminor(file_inode(file));
17471747
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
17481748
struct comedi_device *dev = comedi_dev_from_file_info(info);
17491749
struct comedi_subdevice *s;
@@ -1823,7 +1823,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
18231823
static unsigned int comedi_poll(struct file *file, poll_table *wait)
18241824
{
18251825
unsigned int mask = 0;
1826-
const unsigned minor = iminor(file->f_dentry->d_inode);
1826+
const unsigned minor = iminor(file_inode(file));
18271827
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
18281828
struct comedi_device *dev = comedi_dev_from_file_info(info);
18291829
struct comedi_subdevice *s;
@@ -1869,7 +1869,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
18691869
struct comedi_async *async;
18701870
int n, m, count = 0, retval = 0;
18711871
DECLARE_WAITQUEUE(wait, current);
1872-
const unsigned minor = iminor(file->f_dentry->d_inode);
1872+
const unsigned minor = iminor(file_inode(file));
18731873
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
18741874
struct comedi_device *dev = comedi_dev_from_file_info(info);
18751875

@@ -1964,7 +1964,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
19641964
struct comedi_async *async;
19651965
int n, m, count = 0, retval = 0;
19661966
DECLARE_WAITQUEUE(wait, current);
1967-
const unsigned minor = iminor(file->f_dentry->d_inode);
1967+
const unsigned minor = iminor(file_inode(file));
19681968
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
19691969
struct comedi_device *dev = comedi_dev_from_file_info(info);
19701970

@@ -2133,7 +2133,7 @@ static int comedi_open(struct inode *inode, struct file *file)
21332133

21342134
static int comedi_fasync(int fd, struct file *file, int on)
21352135
{
2136-
const unsigned minor = iminor(file->f_dentry->d_inode);
2136+
const unsigned minor = iminor(file_inode(file));
21372137
struct comedi_device *dev = comedi_dev_from_minor(minor);
21382138

21392139
if (!dev)

drivers/tty/tty_io.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -960,11 +960,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
960960
loff_t *ppos)
961961
{
962962
int i;
963-
struct inode *inode = file->f_path.dentry->d_inode;
964963
struct tty_struct *tty = file_tty(file);
965964
struct tty_ldisc *ld;
966965

967-
if (tty_paranoia_check(tty, inode, "tty_read"))
966+
if (tty_paranoia_check(tty, file_inode(file), "tty_read"))
968967
return -EIO;
969968
if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
970969
return -EIO;
@@ -1132,12 +1131,11 @@ void tty_write_message(struct tty_struct *tty, char *msg)
11321131
static ssize_t tty_write(struct file *file, const char __user *buf,
11331132
size_t count, loff_t *ppos)
11341133
{
1135-
struct inode *inode = file->f_path.dentry->d_inode;
11361134
struct tty_struct *tty = file_tty(file);
11371135
struct tty_ldisc *ld;
11381136
ssize_t ret;
11391137

1140-
if (tty_paranoia_check(tty, inode, "tty_write"))
1138+
if (tty_paranoia_check(tty, file_inode(file), "tty_write"))
11411139
return -EIO;
11421140
if (!tty || !tty->ops->write ||
11431141
(test_bit(TTY_IO_ERROR, &tty->flags)))
@@ -2047,7 +2045,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
20472045
struct tty_ldisc *ld;
20482046
int ret = 0;
20492047

2050-
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
2048+
if (tty_paranoia_check(tty, file_inode(filp), "tty_poll"))
20512049
return 0;
20522050

20532051
ld = tty_ldisc_ref_wait(tty);
@@ -2063,7 +2061,7 @@ static int __tty_fasync(int fd, struct file *filp, int on)
20632061
unsigned long flags;
20642062
int retval = 0;
20652063

2066-
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
2064+
if (tty_paranoia_check(tty, file_inode(filp), "tty_fasync"))
20672065
goto out;
20682066

20692067
retval = fasync_helper(fd, filp, on, &tty->fasync);
@@ -2637,9 +2635,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
26372635
void __user *p = (void __user *)arg;
26382636
int retval;
26392637
struct tty_ldisc *ld;
2640-
struct inode *inode = file->f_dentry->d_inode;
26412638

2642-
if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2639+
if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl"))
26432640
return -EINVAL;
26442641

26452642
real_tty = tty_pair_get_tty(tty);
@@ -2780,12 +2777,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
27802777
static long tty_compat_ioctl(struct file *file, unsigned int cmd,
27812778
unsigned long arg)
27822779
{
2783-
struct inode *inode = file->f_dentry->d_inode;
27842780
struct tty_struct *tty = file_tty(file);
27852781
struct tty_ldisc *ld;
27862782
int retval = -ENOIOCTLCMD;
27872783

2788-
if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2784+
if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl"))
27892785
return -EINVAL;
27902786

27912787
if (tty->ops->compat_ioctl) {

fs/9p/fid.c

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,16 @@
4141
*
4242
*/
4343

44-
int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
44+
static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
4545
{
46-
struct v9fs_dentry *dent;
47-
48-
p9_debug(P9_DEBUG_VFS, "fid %d dentry %s\n",
49-
fid->fid, dentry->d_name.name);
50-
51-
dent = dentry->d_fsdata;
52-
if (!dent) {
53-
dent = kmalloc(sizeof(struct v9fs_dentry), GFP_KERNEL);
54-
if (!dent)
55-
return -ENOMEM;
56-
57-
spin_lock_init(&dent->lock);
58-
INIT_LIST_HEAD(&dent->fidlist);
59-
dentry->d_fsdata = dent;
60-
}
61-
62-
spin_lock(&dent->lock);
63-
list_add(&fid->dlist, &dent->fidlist);
64-
spin_unlock(&dent->lock);
46+
hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
47+
}
6548

66-
return 0;
49+
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
50+
{
51+
spin_lock(&dentry->d_lock);
52+
__add_fid(dentry, fid);
53+
spin_unlock(&dentry->d_lock);
6754
}
6855

6956
/**
@@ -76,23 +63,23 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
7663

7764
static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
7865
{
79-
struct v9fs_dentry *dent;
8066
struct p9_fid *fid, *ret;
8167

8268
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
8369
dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
8470
any);
85-
dent = (struct v9fs_dentry *) dentry->d_fsdata;
8671
ret = NULL;
87-
if (dent) {
88-
spin_lock(&dent->lock);
89-
list_for_each_entry(fid, &dent->fidlist, dlist) {
72+
/* we'll recheck under lock if there's anything to look in */
73+
if (dentry->d_fsdata) {
74+
struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
75+
spin_lock(&dentry->d_lock);
76+
hlist_for_each_entry(fid, h, dlist) {
9077
if (any || uid_eq(fid->uid, uid)) {
9178
ret = fid;
9279
break;
9380
}
9481
}
95-
spin_unlock(&dent->lock);
82+
spin_unlock(&dentry->d_lock);
9683
}
9784

9885
return ret;
@@ -215,8 +202,17 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
215202
}
216203
kfree(wnames);
217204
fid_out:
218-
if (!IS_ERR(fid))
219-
v9fs_fid_add(dentry, fid);
205+
if (!IS_ERR(fid)) {
206+
spin_lock(&dentry->d_lock);
207+
if (d_unhashed(dentry)) {
208+
spin_unlock(&dentry->d_lock);
209+
p9_client_clunk(fid);
210+
fid = ERR_PTR(-ENOENT);
211+
} else {
212+
__add_fid(dentry, fid);
213+
spin_unlock(&dentry->d_lock);
214+
}
215+
}
220216
err_out:
221217
up_read(&v9ses->rename_sem);
222218
return fid;

fs/9p/fid.h

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,8 @@
2323
#define FS_9P_FID_H
2424
#include <linux/list.h>
2525

26-
/**
27-
* struct v9fs_dentry - 9p private data stored in dentry d_fsdata
28-
* @lock: protects the fidlist
29-
* @fidlist: list of FIDs currently associated with this dentry
30-
*
31-
* This structure defines the 9p private data associated with
32-
* a particular dentry. In particular, this private data is used
33-
* to lookup which 9P FID handle should be used for a particular VFS
34-
* operation. FID handles are associated with dentries instead of
35-
* inodes in order to more closely map functionality to the Plan 9
36-
* expected behavior for FID reclaimation and tracking.
37-
*
38-
* See Also: Mapping FIDs to Linux VFS model in
39-
* Design and Implementation of the Linux 9P File System documentation
40-
*/
41-
struct v9fs_dentry {
42-
spinlock_t lock; /* protect fidlist */
43-
struct list_head fidlist;
44-
};
45-
4626
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
4727
struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
48-
int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
28+
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
4929
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
5030
#endif

fs/9p/vfs_dentry.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,12 @@ static int v9fs_cached_dentry_delete(const struct dentry *dentry)
8383

8484
static void v9fs_dentry_release(struct dentry *dentry)
8585
{
86-
struct v9fs_dentry *dent;
87-
struct p9_fid *temp, *current_fid;
88-
86+
struct hlist_node *p, *n;
8987
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
9088
dentry->d_name.name, dentry);
91-
dent = dentry->d_fsdata;
92-
if (dent) {
93-
list_for_each_entry_safe(current_fid, temp, &dent->fidlist,
94-
dlist) {
95-
p9_client_clunk(current_fid);
96-
}
97-
98-
kfree(dent);
99-
dentry->d_fsdata = NULL;
100-
}
89+
hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
90+
p9_client_clunk(hlist_entry(p, struct p9_fid, dlist));
91+
dentry->d_fsdata = NULL;
10192
}
10293

10394
static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)

0 commit comments

Comments
 (0)