Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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)
  • Loading branch information
torvalds committed Mar 3, 2013
2 parents 1c82315 + dcf787f commit 56a79b7
Show file tree
Hide file tree
Showing 26 changed files with 108 additions and 171 deletions.
6 changes: 2 additions & 4 deletions arch/s390/hypfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,10 @@ static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t offset)
{
int rc;
struct super_block *sb;
struct hypfs_sb_info *fs_info;
struct super_block *sb = file_inode(iocb->ki_filp)->i_sb;
struct hypfs_sb_info *fs_info = sb->s_fs_info;
size_t count = iov_length(iov, nr_segs);

sb = iocb->ki_filp->f_path.dentry->d_inode->i_sb;
fs_info = sb->s_fs_info;
/*
* Currently we only allow one update per second for two reasons:
* 1. diag 204 is VERY expensive
Expand Down
9 changes: 4 additions & 5 deletions arch/x86/kernel/msr.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static ssize_t msr_read(struct file *file, char __user *buf,
u32 __user *tmp = (u32 __user *) buf;
u32 data[2];
u32 reg = *ppos;
int cpu = iminor(file->f_path.dentry->d_inode);
int cpu = iminor(file_inode(file));
int err = 0;
ssize_t bytes = 0;

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

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

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

static int msr_open(struct inode *inode, struct file *file)
{
unsigned int cpu;
unsigned int cpu = iminor(file_inode(file));
struct cpuinfo_x86 *c;

if (!capable(CAP_SYS_RAWIO))
return -EPERM;

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

Expand Down
14 changes: 7 additions & 7 deletions drivers/staging/comedi/comedi_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
struct comedi_devinfo __user *arg,
struct file *file)
{
const unsigned minor = iminor(file->f_dentry->d_inode);
const unsigned minor = iminor(file_inode(file));
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
struct comedi_subdevice *s;
struct comedi_devinfo devinfo;
Expand Down Expand Up @@ -1615,7 +1615,7 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg,
static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
const unsigned minor = iminor(file->f_dentry->d_inode);
const unsigned minor = iminor(file_inode(file));
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
struct comedi_device *dev = comedi_dev_from_file_info(info);
int rc;
Expand Down Expand Up @@ -1743,7 +1743,7 @@ static struct vm_operations_struct comedi_vm_ops = {

static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
{
const unsigned minor = iminor(file->f_dentry->d_inode);
const unsigned minor = iminor(file_inode(file));
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
struct comedi_device *dev = comedi_dev_from_file_info(info);
struct comedi_subdevice *s;
Expand Down Expand Up @@ -1823,7 +1823,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
static unsigned int comedi_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
const unsigned minor = iminor(file->f_dentry->d_inode);
const unsigned minor = iminor(file_inode(file));
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
struct comedi_device *dev = comedi_dev_from_file_info(info);
struct comedi_subdevice *s;
Expand Down Expand Up @@ -1869,7 +1869,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
struct comedi_async *async;
int n, m, count = 0, retval = 0;
DECLARE_WAITQUEUE(wait, current);
const unsigned minor = iminor(file->f_dentry->d_inode);
const unsigned minor = iminor(file_inode(file));
struct comedi_file_info *info = comedi_file_info_from_minor(minor);
struct comedi_device *dev = comedi_dev_from_file_info(info);

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

Expand Down Expand Up @@ -2133,7 +2133,7 @@ static int comedi_open(struct inode *inode, struct file *file)

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

if (!dev)
Expand Down
16 changes: 6 additions & 10 deletions drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -960,11 +960,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
int i;
struct inode *inode = file->f_path.dentry->d_inode;
struct tty_struct *tty = file_tty(file);
struct tty_ldisc *ld;

if (tty_paranoia_check(tty, inode, "tty_read"))
if (tty_paranoia_check(tty, file_inode(file), "tty_read"))
return -EIO;
if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
return -EIO;
Expand Down Expand Up @@ -1132,12 +1131,11 @@ void tty_write_message(struct tty_struct *tty, char *msg)
static ssize_t tty_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct inode *inode = file->f_path.dentry->d_inode;
struct tty_struct *tty = file_tty(file);
struct tty_ldisc *ld;
ssize_t ret;

if (tty_paranoia_check(tty, inode, "tty_write"))
if (tty_paranoia_check(tty, file_inode(file), "tty_write"))
return -EIO;
if (!tty || !tty->ops->write ||
(test_bit(TTY_IO_ERROR, &tty->flags)))
Expand Down Expand Up @@ -2047,7 +2045,7 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
struct tty_ldisc *ld;
int ret = 0;

if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
if (tty_paranoia_check(tty, file_inode(filp), "tty_poll"))
return 0;

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

if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
if (tty_paranoia_check(tty, file_inode(filp), "tty_fasync"))
goto out;

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

if (tty_paranoia_check(tty, inode, "tty_ioctl"))
if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl"))
return -EINVAL;

real_tty = tty_pair_get_tty(tty);
Expand Down Expand Up @@ -2780,12 +2777,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static long tty_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct inode *inode = file->f_dentry->d_inode;
struct tty_struct *tty = file_tty(file);
struct tty_ldisc *ld;
int retval = -ENOIOCTLCMD;

if (tty_paranoia_check(tty, inode, "tty_ioctl"))
if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl"))
return -EINVAL;

if (tty->ops->compat_ioctl) {
Expand Down
54 changes: 25 additions & 29 deletions fs/9p/fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,16 @@
*
*/

int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
{
struct v9fs_dentry *dent;

p9_debug(P9_DEBUG_VFS, "fid %d dentry %s\n",
fid->fid, dentry->d_name.name);

dent = dentry->d_fsdata;
if (!dent) {
dent = kmalloc(sizeof(struct v9fs_dentry), GFP_KERNEL);
if (!dent)
return -ENOMEM;

spin_lock_init(&dent->lock);
INIT_LIST_HEAD(&dent->fidlist);
dentry->d_fsdata = dent;
}

spin_lock(&dent->lock);
list_add(&fid->dlist, &dent->fidlist);
spin_unlock(&dent->lock);
hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
}

return 0;
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
{
spin_lock(&dentry->d_lock);
__add_fid(dentry, fid);
spin_unlock(&dentry->d_lock);
}

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

static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
{
struct v9fs_dentry *dent;
struct p9_fid *fid, *ret;

p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
any);
dent = (struct v9fs_dentry *) dentry->d_fsdata;
ret = NULL;
if (dent) {
spin_lock(&dent->lock);
list_for_each_entry(fid, &dent->fidlist, dlist) {
/* we'll recheck under lock if there's anything to look in */
if (dentry->d_fsdata) {
struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
spin_lock(&dentry->d_lock);
hlist_for_each_entry(fid, h, dlist) {
if (any || uid_eq(fid->uid, uid)) {
ret = fid;
break;
}
}
spin_unlock(&dent->lock);
spin_unlock(&dentry->d_lock);
}

return ret;
Expand Down Expand Up @@ -215,8 +202,17 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
}
kfree(wnames);
fid_out:
if (!IS_ERR(fid))
v9fs_fid_add(dentry, fid);
if (!IS_ERR(fid)) {
spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock);
p9_client_clunk(fid);
fid = ERR_PTR(-ENOENT);
} else {
__add_fid(dentry, fid);
spin_unlock(&dentry->d_lock);
}
}
err_out:
up_read(&v9ses->rename_sem);
return fid;
Expand Down
22 changes: 1 addition & 21 deletions fs/9p/fid.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,8 @@
#define FS_9P_FID_H
#include <linux/list.h>

/**
* struct v9fs_dentry - 9p private data stored in dentry d_fsdata
* @lock: protects the fidlist
* @fidlist: list of FIDs currently associated with this dentry
*
* This structure defines the 9p private data associated with
* a particular dentry. In particular, this private data is used
* to lookup which 9P FID handle should be used for a particular VFS
* operation. FID handles are associated with dentries instead of
* inodes in order to more closely map functionality to the Plan 9
* expected behavior for FID reclaimation and tracking.
*
* See Also: Mapping FIDs to Linux VFS model in
* Design and Implementation of the Linux 9P File System documentation
*/
struct v9fs_dentry {
spinlock_t lock; /* protect fidlist */
struct list_head fidlist;
};

struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
#endif
17 changes: 4 additions & 13 deletions fs/9p/vfs_dentry.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,12 @@ static int v9fs_cached_dentry_delete(const struct dentry *dentry)

static void v9fs_dentry_release(struct dentry *dentry)
{
struct v9fs_dentry *dent;
struct p9_fid *temp, *current_fid;

struct hlist_node *p, *n;
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
dentry->d_name.name, dentry);
dent = dentry->d_fsdata;
if (dent) {
list_for_each_entry_safe(current_fid, temp, &dent->fidlist,
dlist) {
p9_client_clunk(current_fid);
}

kfree(dent);
dentry->d_fsdata = NULL;
}
hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
p9_client_clunk(hlist_entry(p, struct p9_fid, dlist));
dentry->d_fsdata = NULL;
}

static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
Expand Down
Loading

0 comments on commit 56a79b7

Please sign in to comment.