diff options
| -rw-r--r-- | arch/s390/hypfs/inode.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/msr.c | 9 | ||||
| -rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 14 | ||||
| -rw-r--r-- | drivers/tty/tty_io.c | 16 | ||||
| -rw-r--r-- | fs/9p/fid.c | 54 | ||||
| -rw-r--r-- | fs/9p/fid.h | 22 | ||||
| -rw-r--r-- | fs/9p/vfs_dentry.c | 17 | ||||
| -rw-r--r-- | fs/9p/vfs_inode.c | 40 | ||||
| -rw-r--r-- | fs/9p/vfs_inode_dotl.c | 19 | ||||
| -rw-r--r-- | fs/ext4/indirect.c | 2 | ||||
| -rw-r--r-- | fs/f2fs/file.c | 6 | ||||
| -rw-r--r-- | fs/file_table.c | 2 | ||||
| -rw-r--r-- | fs/fs_struct.c | 6 | ||||
| -rw-r--r-- | fs/fuse/dev.c | 2 | ||||
| -rw-r--r-- | fs/fuse/file.c | 24 | ||||
| -rw-r--r-- | fs/internal.h | 2 | ||||
| -rw-r--r-- | fs/namei.c | 4 | ||||
| -rw-r--r-- | fs/open.c | 3 | ||||
| -rw-r--r-- | fs/seq_file.c | 2 | ||||
| -rw-r--r-- | include/linux/fs.h | 3 | ||||
| -rw-r--r-- | include/linux/fs_struct.h | 4 | ||||
| -rw-r--r-- | include/linux/path.h | 4 | ||||
| -rw-r--r-- | include/net/9p/client.h | 2 | ||||
| -rw-r--r-- | kernel/futex.c | 2 | ||||
| -rw-r--r-- | mm/shmem.c | 5 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 9 | 
26 files changed, 108 insertions, 171 deletions
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 280ded8b79b..8538015ed4a 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -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 diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 4929502c137..ce130493b80 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -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; @@ -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; @@ -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) { @@ -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 */ diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 195d56d8a1e..e336b281b84 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -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; @@ -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; @@ -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; @@ -1823,7 +1823,7 @@ done:  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; @@ -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); @@ -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); @@ -2133,7 +2133,7 @@ ok:  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) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index fd473639ab7..05400acbc45 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -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; @@ -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))) @@ -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); @@ -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); @@ -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); @@ -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) { diff --git a/fs/9p/fid.c b/fs/9p/fid.c index afd4724b2d9..d51ec9fafcc 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -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);  }  /** @@ -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; @@ -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; diff --git a/fs/9p/fid.h b/fs/9p/fid.h index bb0b6e7f58f..2b6787fcb62 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -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 diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 9ad68628522..f039b104a98 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -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) diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index b5340c829de..d86edc8d3fd 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -692,9 +692,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,  				   "inode creation failed %d\n", err);  			goto error;  		} -		err = v9fs_fid_add(dentry, fid); -		if (err < 0) -			goto error; +		v9fs_fid_add(dentry, fid);  		d_instantiate(dentry, inode);  	}  	return ofid; @@ -790,7 +788,6 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,  	struct p9_fid *dfid, *fid;  	struct inode *inode;  	char *name; -	int result = 0;  	p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p flags: %x\n",  		 dir, dentry->d_name.name, dentry, flags); @@ -808,13 +805,11 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,  	name = (char *) dentry->d_name.name;  	fid = p9_client_walk(dfid, 1, &name, 1);  	if (IS_ERR(fid)) { -		result = PTR_ERR(fid); -		if (result == -ENOENT) { -			inode = NULL; -			goto inst_out; +		if (fid == ERR_PTR(-ENOENT)) { +			d_add(dentry, NULL); +			return NULL;  		} - -		return ERR_PTR(result); +		return ERR_CAST(fid);  	}  	/*  	 * Make sure we don't use a wrong inode due to parallel @@ -826,14 +821,9 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,  	else  		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);  	if (IS_ERR(inode)) { -		result = PTR_ERR(inode); -		inode = NULL; -		goto error; +		p9_client_clunk(fid); +		return ERR_CAST(inode);  	} -	result = v9fs_fid_add(dentry, fid); -	if (result < 0) -		goto error_iput; -inst_out:  	/*  	 * If we had a rename on the server and a parallel lookup  	 * for the new name, then make sure we instantiate with @@ -842,15 +832,13 @@ inst_out:  	 * k/b.  	 */  	res = d_materialise_unique(dentry, inode); -	if (!IS_ERR(res)) -		return res; -	result = PTR_ERR(res); -error_iput: -	iput(inode); -error: -	p9_client_clunk(fid); - -	return ERR_PTR(result); +	if (!res) +		v9fs_fid_add(dentry, fid); +	else if (!IS_ERR(res)) +		v9fs_fid_add(res, fid); +	else +		p9_client_clunk(fid); +	return res;  }  static int diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 61e4fa70a6f..53687bbf229 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -333,9 +333,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,  	/* Now set the ACL based on the default value */  	v9fs_set_create_acl(inode, fid, dacl, pacl); -	err = v9fs_fid_add(dentry, fid); -	if (err < 0) -		goto error; +	v9fs_fid_add(dentry, fid);  	d_instantiate(dentry, inode);  	v9inode = V9FS_I(inode); @@ -453,12 +451,11 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,  				 err);  			goto error;  		} -		err = v9fs_fid_add(dentry, fid); -		if (err < 0) -			goto error; +		v9fs_fid_add(dentry, fid);  		v9fs_set_create_acl(inode, fid, dacl, pacl);  		d_instantiate(dentry, inode);  		fid = NULL; +		err = 0;  	} else {  		/*  		 * Not in cached mode. No need to populate @@ -747,11 +744,10 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,  				 err);  			goto error;  		} -		err = v9fs_fid_add(dentry, fid); -		if (err < 0) -			goto error; +		v9fs_fid_add(dentry, fid);  		d_instantiate(dentry, inode);  		fid = NULL; +		err = 0;  	} else {  		/* Not in cached mode. No need to populate inode with stat */  		inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0); @@ -900,11 +896,10 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,  			goto error;  		}  		v9fs_set_create_acl(inode, fid, dacl, pacl); -		err = v9fs_fid_add(dentry, fid); -		if (err < 0) -			goto error; +		v9fs_fid_add(dentry, fid);  		d_instantiate(dentry, inode);  		fid = NULL; +		err = 0;  	} else {  		/*  		 * Not in cached mode. No need to populate inode with stat. diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index c541ab8b64d..b505a145a59 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -1606,7 +1606,7 @@ err:  int ext4_ind_punch_hole(struct file *file, loff_t offset, loff_t length)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct super_block *sb = inode->i_sb;  	ext4_lblk_t first_block, stop_block;  	struct address_space *mapping = inode->i_mapping; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index b7a053d4c6d..958a46da19a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -29,7 +29,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,  						struct vm_fault *vmf)  {  	struct page *page = vmf->page; -	struct inode *inode = vma->vm_file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(vma->vm_file);  	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);  	block_t old_blk_addr;  	struct dnode_of_data dn; @@ -544,7 +544,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,  static long f2fs_fallocate(struct file *file, int mode,  				loff_t offset, loff_t len)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	long ret;  	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) @@ -577,7 +577,7 @@ static inline __u32 f2fs_mask_flags(umode_t mode, __u32 flags)  long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  { -	struct inode *inode = filp->f_dentry->d_inode; +	struct inode *inode = file_inode(filp);  	struct f2fs_inode_info *fi = F2FS_I(inode);  	unsigned int flags;  	int ret; diff --git a/fs/file_table.c b/fs/file_table.c index aa07d3684a2..cd4d87a8295 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -176,6 +176,7 @@ struct file *alloc_file(struct path *path, fmode_t mode,  		return file;  	file->f_path = *path; +	file->f_inode = path->dentry->d_inode;  	file->f_mapping = path->dentry->d_inode->i_mapping;  	file->f_mode = mode;  	file->f_op = fop; @@ -258,6 +259,7 @@ static void __fput(struct file *file)  		drop_file_write_access(file);  	file->f_path.dentry = NULL;  	file->f_path.mnt = NULL; +	file->f_inode = NULL;  	file_free(file);  	dput(dentry);  	mntput(mnt); diff --git a/fs/fs_struct.c b/fs/fs_struct.c index fe6ca583bbc..d8ac61d0c93 100644 --- a/fs/fs_struct.c +++ b/fs/fs_struct.c @@ -10,7 +10,7 @@   * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.   * It can block.   */ -void set_fs_root(struct fs_struct *fs, struct path *path) +void set_fs_root(struct fs_struct *fs, const struct path *path)  {  	struct path old_root; @@ -29,7 +29,7 @@ void set_fs_root(struct fs_struct *fs, struct path *path)   * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.   * It can block.   */ -void set_fs_pwd(struct fs_struct *fs, struct path *path) +void set_fs_pwd(struct fs_struct *fs, const struct path *path)  {  	struct path old_pwd; @@ -53,7 +53,7 @@ static inline int replace_path(struct path *p, const struct path *old, const str  	return 1;  } -void chroot_fs_refs(struct path *old_root, struct path *new_root) +void chroot_fs_refs(const struct path *old_root, const struct path *new_root)  {  	struct task_struct *g, *p;  	struct fs_struct *fs; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index e9bdec0b16d..11dfa0c3fb4 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -532,7 +532,7 @@ void fuse_request_send_background_locked(struct fuse_conn *fc,  void fuse_force_forget(struct file *file, u64 nodeid)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	struct fuse_req *req;  	struct fuse_forget_in inarg; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c8071768b95..34b80ba95ba 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -355,7 +355,7 @@ static int fuse_wait_on_page_writeback(struct inode *inode, pgoff_t index)  static int fuse_flush(struct file *file, fl_owner_t id)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	struct fuse_file *ff = file->private_data;  	struct fuse_req *req; @@ -1215,7 +1215,7 @@ static ssize_t __fuse_direct_read(struct file *file, const struct iovec *iov,  				  unsigned long nr_segs, loff_t *ppos)  {  	ssize_t res; -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	if (is_bad_inode(inode))  		return -EIO; @@ -1238,7 +1238,7 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf,  static ssize_t __fuse_direct_write(struct file *file, const struct iovec *iov,  				   unsigned long nr_segs, loff_t *ppos)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	size_t count = iov_length(iov, nr_segs);  	ssize_t res; @@ -1258,7 +1258,7 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf,  				 size_t count, loff_t *ppos)  {  	struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	ssize_t res;  	if (is_bad_inode(inode)) @@ -1485,7 +1485,7 @@ static const struct vm_operations_struct fuse_file_vm_ops = {  static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)  {  	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) { -		struct inode *inode = file->f_dentry->d_inode; +		struct inode *inode = file_inode(file);  		struct fuse_conn *fc = get_fuse_conn(inode);  		struct fuse_inode *fi = get_fuse_inode(inode);  		struct fuse_file *ff = file->private_data; @@ -1543,7 +1543,7 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file,  			 const struct file_lock *fl, int opcode, pid_t pid,  			 int flock)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	struct fuse_file *ff = file->private_data;  	struct fuse_lk_in *arg = &req->misc.lk_in; @@ -1565,7 +1565,7 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file,  static int fuse_getlk(struct file *file, struct file_lock *fl)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	struct fuse_req *req;  	struct fuse_lk_out outarg; @@ -1590,7 +1590,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)  static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	struct fuse_req *req;  	int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK; @@ -1622,7 +1622,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)  static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	int err; @@ -1645,7 +1645,7 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)  static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)  { -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	int err; @@ -1702,7 +1702,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)  static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence)  {  	loff_t retval; -	struct inode *inode = file->f_path.dentry->d_inode; +	struct inode *inode = file_inode(file);  	/* No i_mutex protection necessary for SEEK_CUR and SEEK_SET */  	if (whence == SEEK_CUR || whence == SEEK_SET) @@ -2079,7 +2079,7 @@ EXPORT_SYMBOL_GPL(fuse_do_ioctl);  long fuse_ioctl_common(struct file *file, unsigned int cmd,  		       unsigned long arg, unsigned int flags)  { -	struct inode *inode = file->f_dentry->d_inode; +	struct inode *inode = file_inode(file);  	struct fuse_conn *fc = get_fuse_conn(inode);  	if (!fuse_allow_current_process(fc)) diff --git a/fs/internal.h b/fs/internal.h index 2f6af7f645e..507141fceb9 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -69,7 +69,7 @@ extern void __mnt_drop_write_file(struct file *);  /*   * fs_struct.c   */ -extern void chroot_fs_refs(struct path *, struct path *); +extern void chroot_fs_refs(const struct path *, const struct path *);  /*   * file_table.c diff --git a/fs/namei.c b/fs/namei.c index dc984fee553..961bc126836 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -451,7 +451,7 @@ int inode_permission(struct inode *inode, int mask)   *   * Given a path increment the reference count to the dentry and the vfsmount.   */ -void path_get(struct path *path) +void path_get(const struct path *path)  {  	mntget(path->mnt);  	dget(path->dentry); @@ -464,7 +464,7 @@ EXPORT_SYMBOL(path_get);   *   * Given a path decrement the reference count to the dentry and the vfsmount.   */ -void path_put(struct path *path) +void path_put(const struct path *path)  {  	dput(path->dentry);  	mntput(path->mnt); diff --git a/fs/open.c b/fs/open.c index e3441f58d2e..68354466879 100644 --- a/fs/open.c +++ b/fs/open.c @@ -704,7 +704,7 @@ static int do_dentry_open(struct file *f,  		f->f_mode = FMODE_PATH;  	path_get(&f->f_path); -	inode = file_inode(f); +	inode = f->f_inode = f->f_path.dentry->d_inode;  	if (f->f_mode & FMODE_WRITE) {  		error = __get_file_write_access(inode, f->f_path.mnt);  		if (error) @@ -767,6 +767,7 @@ cleanup_file:  	path_put(&f->f_path);  	f->f_path.mnt = NULL;  	f->f_path.dentry = NULL; +	f->f_inode = NULL;  	return error;  } diff --git a/fs/seq_file.c b/fs/seq_file.c index 15c6304bab7..38bb59f3f2a 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -339,7 +339,7 @@ EXPORT_SYMBOL(seq_lseek);  /**   *	seq_release -	free the structures associated with sequential file.   *	@file: file in question - *	@inode: file->f_path.dentry->d_inode + *	@inode: its inode   *   *	Frees the structures associated with sequential file; can be used   *	as ->f_op->release() if you don't have private data to destroy. diff --git a/include/linux/fs.h b/include/linux/fs.h index 4e686a09946..74a907b8b95 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -769,6 +769,7 @@ struct file {  	} f_u;  	struct path		f_path;  #define f_dentry	f_path.dentry +	struct inode		*f_inode;	/* cached value */  	const struct file_operations	*f_op;  	/* @@ -2217,7 +2218,7 @@ static inline bool execute_ok(struct inode *inode)  static inline struct inode *file_inode(struct file *f)  { -	return f->f_path.dentry->d_inode; +	return f->f_inode;  }  /* diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index d0ae3a84bcf..729eded4b24 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -17,8 +17,8 @@ struct fs_struct {  extern struct kmem_cache *fs_cachep;  extern void exit_fs(struct task_struct *); -extern void set_fs_root(struct fs_struct *, struct path *); -extern void set_fs_pwd(struct fs_struct *, struct path *); +extern void set_fs_root(struct fs_struct *, const struct path *); +extern void set_fs_pwd(struct fs_struct *, const struct path *);  extern struct fs_struct *copy_fs_struct(struct fs_struct *);  extern void free_fs_struct(struct fs_struct *);  extern int unshare_fs_struct(void); diff --git a/include/linux/path.h b/include/linux/path.h index edc98dec626..d1372186f43 100644 --- a/include/linux/path.h +++ b/include/linux/path.h @@ -9,8 +9,8 @@ struct path {  	struct dentry *dentry;  }; -extern void path_get(struct path *); -extern void path_put(struct path *); +extern void path_get(const struct path *); +extern void path_put(const struct path *);  static inline int path_equal(const struct path *path1, const struct path *path2)  { diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 5ff70f433e8..4c7c01a7391 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -192,7 +192,7 @@ struct p9_fid {  	void *rdir;  	struct list_head flist; -	struct list_head dlist;	/* list of all fids attached to a dentry */ +	struct hlist_node dlist;	/* list of all fids attached to a dentry */  };  /** diff --git a/kernel/futex.c b/kernel/futex.c index fbc07a29ec5..f0090a993da 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -226,7 +226,7 @@ static void drop_futex_key_refs(union futex_key *key)   * Returns a negative error code or 0   * The key words are stored in *key on success.   * - * For shared mappings, it's (page->index, vma->vm_file->f_path.dentry->d_inode, + * For shared mappings, it's (page->index, file_inode(vma->vm_file),   * offset_within_page).  For private mappings, it's (uaddr, current->mm).   * We can usually work out the index without swapping in the page.   * diff --git a/mm/shmem.c b/mm/shmem.c index ed2befb4952..1c44af71fcf 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2932,9 +2932,8 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags  	inode->i_size = size;  	clear_nlink(inode);	/* It is unlinked */  #ifndef CONFIG_MMU -	error = ramfs_nommu_expand_for_mapping(inode, size); -	res = ERR_PTR(error); -	if (error) +	res = ERR_PTR(ramfs_nommu_expand_for_mapping(inode, size)); +	if (IS_ERR(res))  		goto put_dentry;  #endif diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 84b591711ee..2fa28c88900 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3135,11 +3135,6 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,  	switch (cmd) {  	case F_SETFL: -		if (!file->f_path.dentry || !file->f_path.dentry->d_inode) { -			err = -EINVAL; -			break; -		} -  		if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {  			err = file_has_perm(cred, file, FILE__WRITE);  			break; @@ -3162,10 +3157,6 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,  	case F_SETLK64:  	case F_SETLKW64:  #endif -		if (!file->f_path.dentry || !file->f_path.dentry->d_inode) { -			err = -EINVAL; -			break; -		}  		err = file_has_perm(cred, file, FILE__LOCK);  		break;  	}  |