From 6131ffaa1f091415b7a24abb01f033d9c0a727f4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 27 Feb 2013 16:59:05 -0500 Subject: more file_inode() open-coded instances Signed-off-by: Al Viro --- fs/ext4/indirect.c | 2 +- fs/f2fs/file.c | 6 +++--- fs/fuse/dev.c | 2 +- fs/fuse/file.c | 24 ++++++++++++------------ fs/seq_file.c | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) (limited to 'fs') 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/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/seq_file.c b/fs/seq_file.c index f2bc3dfd0b8..f9538ea2a75 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. -- cgit v1.2.3 From 634095dab2a2001844fc8b26673c0cb14a766cdf Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 27 Feb 2013 22:37:21 -0500 Subject: 9p: don't bother with private lock in ->d_fsdata; dentry->d_lock will do just fine Signed-off-by: Al Viro --- fs/9p/fid.c | 9 ++++----- fs/9p/fid.h | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/9p/fid.c b/fs/9p/fid.c index afd4724b2d9..71bc36a03e7 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -54,14 +54,13 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) if (!dent) return -ENOMEM; - spin_lock_init(&dent->lock); INIT_LIST_HEAD(&dent->fidlist); dentry->d_fsdata = dent; } - spin_lock(&dent->lock); + spin_lock(&dentry->d_lock); list_add(&fid->dlist, &dent->fidlist); - spin_unlock(&dent->lock); + spin_unlock(&dentry->d_lock); return 0; } @@ -85,14 +84,14 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) dent = (struct v9fs_dentry *) dentry->d_fsdata; ret = NULL; if (dent) { - spin_lock(&dent->lock); + spin_lock(&dentry->d_lock); list_for_each_entry(fid, &dent->fidlist, dlist) { if (any || uid_eq(fid->uid, uid)) { ret = fid; break; } } - spin_unlock(&dent->lock); + spin_unlock(&dentry->d_lock); } return ret; diff --git a/fs/9p/fid.h b/fs/9p/fid.h index bb0b6e7f58f..469b5d51769 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -25,7 +25,6 @@ /** * 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 @@ -35,11 +34,12 @@ * inodes in order to more closely map functionality to the Plan 9 * expected behavior for FID reclaimation and tracking. * + * Protected by ->d_lock of dentry it belongs to. + * * 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; }; -- cgit v1.2.3 From c4d30967f3020cda9df9ee22af79cd1f2c284244 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 27 Feb 2013 22:51:08 -0500 Subject: 9p: turn fid->dlist into hlist Signed-off-by: Al Viro --- fs/9p/fid.c | 7 ++++--- fs/9p/fid.h | 2 +- fs/9p/vfs_dentry.c | 9 +++------ 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 71bc36a03e7..49de4264db9 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -54,12 +54,12 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) if (!dent) return -ENOMEM; - INIT_LIST_HEAD(&dent->fidlist); + INIT_HLIST_HEAD(&dent->fidlist); dentry->d_fsdata = dent; } spin_lock(&dentry->d_lock); - list_add(&fid->dlist, &dent->fidlist); + hlist_add_head(&fid->dlist, &dent->fidlist); spin_unlock(&dentry->d_lock); return 0; @@ -84,8 +84,9 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) dent = (struct v9fs_dentry *) dentry->d_fsdata; ret = NULL; if (dent) { + struct hlist_node *n; spin_lock(&dentry->d_lock); - list_for_each_entry(fid, &dent->fidlist, dlist) { + hlist_for_each_entry(fid, n, &dent->fidlist, dlist) { if (any || uid_eq(fid->uid, uid)) { ret = fid; break; diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 469b5d51769..86eeb34ce46 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -40,7 +40,7 @@ * Design and Implementation of the Linux 9P File System documentation */ struct v9fs_dentry { - struct list_head fidlist; + struct hlist_head fidlist; }; struct p9_fid *v9fs_fid_lookup(struct dentry *dentry); diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 9ad68628522..fcd49833ef8 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -84,16 +84,13 @@ 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; - 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); - } + struct hlist_node *p, *n; + hlist_for_each_safe(p, n, &dent->fidlist) + p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); kfree(dent); dentry->d_fsdata = NULL; -- cgit v1.2.3 From aaeb7ecfb48ad4c8942a26874322d8918524a04f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 Feb 2013 01:13:19 -0500 Subject: v9fs: get rid of v9fs_dentry ->d_fsdata can act as hlist_head... Signed-off-by: Al Viro --- fs/9p/fid.c | 26 +++++--------------------- fs/9p/fid.h | 20 -------------------- fs/9p/vfs_dentry.c | 14 ++++---------- 3 files changed, 9 insertions(+), 51 deletions(-) (limited to 'fs') diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 49de4264db9..ddf618936d8 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -43,25 +43,9 @@ int v9fs_fid_add(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; - - INIT_HLIST_HEAD(&dent->fidlist); - dentry->d_fsdata = dent; - } - spin_lock(&dentry->d_lock); - hlist_add_head(&fid->dlist, &dent->fidlist); + hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata); spin_unlock(&dentry->d_lock); - return 0; } @@ -75,18 +59,18 @@ 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) { + /* 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; struct hlist_node *n; spin_lock(&dentry->d_lock); - hlist_for_each_entry(fid, n, &dent->fidlist, dlist) { + hlist_for_each_entry(fid, n, h, dlist) { if (any || uid_eq(fid->uid, uid)) { ret = fid; break; diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 86eeb34ce46..377eb6f2e7f 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -23,26 +23,6 @@ #define FS_9P_FID_H #include -/** - * struct v9fs_dentry - 9p private data stored in dentry d_fsdata - * @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. - * - * Protected by ->d_lock of dentry it belongs to. - * - * See Also: Mapping FIDs to Linux VFS model in - * Design and Implementation of the Linux 9P File System documentation - */ -struct v9fs_dentry { - struct hlist_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); diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index fcd49833ef8..f039b104a98 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -83,18 +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 hlist_node *p, *n; p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_name.name, dentry); - dent = dentry->d_fsdata; - if (dent) { - struct hlist_node *p, *n; - hlist_for_each_safe(p, n, &dent->fidlist) - p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); - - 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) -- cgit v1.2.3 From 2ea03e1d62d56c37737e43550c360b43a5e40a32 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 Feb 2013 01:18:14 -0500 Subject: 9p: v9fs_fid_add() can't fail now Signed-off-by: Al Viro --- fs/9p/fid.c | 3 +-- fs/9p/fid.h | 2 +- fs/9p/vfs_inode.c | 9 ++------- fs/9p/vfs_inode_dotl.c | 19 +++++++------------ 4 files changed, 11 insertions(+), 22 deletions(-) (limited to 'fs') diff --git a/fs/9p/fid.c b/fs/9p/fid.c index ddf618936d8..73ca55042cb 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -41,12 +41,11 @@ * */ -int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) +void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) { spin_lock(&dentry->d_lock); hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata); spin_unlock(&dentry->d_lock); - return 0; } /** diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 377eb6f2e7f..2b6787fcb62 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -25,6 +25,6 @@ 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_inode.c b/fs/9p/vfs_inode.c index b5340c829de..ce601d71a42 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; @@ -830,9 +828,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, inode = NULL; goto error; } - result = v9fs_fid_add(dentry, fid); - if (result < 0) - goto error_iput; + v9fs_fid_add(dentry, fid); inst_out: /* * If we had a rename on the server and a parallel lookup @@ -845,7 +841,6 @@ inst_out: if (!IS_ERR(res)) return res; result = PTR_ERR(res); -error_iput: iput(inode); error: p9_client_clunk(fid); 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. -- cgit v1.2.3 From 3509b678a6bb93a49d9603c9c8028c8d95019539 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 Feb 2013 01:21:38 -0500 Subject: 9p: double iput() in ->lookup() if d_materialise_unique() fails d_materialise_unique() does iput() itself. Signed-off-by: Al Viro --- fs/9p/vfs_inode.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs') diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index ce601d71a42..cbee5ec4039 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -841,7 +841,6 @@ inst_out: if (!IS_ERR(res)) return res; result = PTR_ERR(res); - iput(inode); error: p9_client_clunk(fid); -- cgit v1.2.3 From 7b5be621993567d39f09a5190c4d651241be296f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 Feb 2013 01:28:21 -0500 Subject: 9p: untangle ->lookup() a bit Signed-off-by: Al Viro --- fs/9p/vfs_inode.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'fs') diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index cbee5ec4039..80ff01bcae3 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -788,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); @@ -806,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 @@ -824,12 +821,10 @@ 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); } v9fs_fid_add(dentry, fid); -inst_out: /* * If we had a rename on the server and a parallel lookup * for the new name, then make sure we instantiate with @@ -838,13 +833,9 @@ inst_out: * k/b. */ res = d_materialise_unique(dentry, inode); - if (!IS_ERR(res)) - return res; - result = PTR_ERR(res); -error: - p9_client_clunk(fid); - - return ERR_PTR(result); + if (IS_ERR(res)) + p9_client_clunk(fid); + return res; } static int -- cgit v1.2.3 From a3b2157e72e321fa313389ac744bbf6d6cb6986d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 Feb 2013 01:29:48 -0500 Subject: 9p: make sure ->lookup() adds fid to the right dentry Signed-off-by: Al Viro --- fs/9p/vfs_inode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 80ff01bcae3..d86edc8d3fd 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -824,7 +824,6 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, p9_client_clunk(fid); return ERR_CAST(inode); } - v9fs_fid_add(dentry, fid); /* * If we had a rename on the server and a parallel lookup * for the new name, then make sure we instantiate with @@ -833,7 +832,11 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, * k/b. */ res = d_materialise_unique(dentry, inode); - if (IS_ERR(res)) + if (!res) + v9fs_fid_add(dentry, fid); + else if (!IS_ERR(res)) + v9fs_fid_add(res, fid); + else p9_client_clunk(fid); return res; } -- cgit v1.2.3 From 5e608671dfbfd6a9556c31df65a4f147439eed59 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 28 Feb 2013 01:50:20 -0500 Subject: 9p: if v9fs_fid_lookup() gets to asking server, it'd better have hashed dentry ... otherwise the path we'd built isn't worth much. Don't accept such fids obtained from paths unless dentry is still alived by the end of the work. Signed-off-by: Al Viro --- fs/9p/fid.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 73ca55042cb..616abaf1c6c 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -41,10 +41,15 @@ * */ +static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid) +{ + hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata); +} + void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) { spin_lock(&dentry->d_lock); - hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata); + __add_fid(dentry, fid); spin_unlock(&dentry->d_lock); } @@ -198,8 +203,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; -- cgit v1.2.3 From dd37978c50bc8b354e5c4633f69387f16572fdac Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 1 Mar 2013 19:48:30 -0500 Subject: cache the value of file_inode() in struct file Note that this thing does *not* contribute to inode refcount; it's pinned down by dentry. Signed-off-by: Al Viro --- fs/file_table.c | 2 ++ fs/open.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'fs') 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/open.c b/fs/open.c index 62f907e3bc3..806d4589559 100644 --- a/fs/open.c +++ b/fs/open.c @@ -689,7 +689,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) @@ -752,6 +752,7 @@ cleanup_file: path_put(&f->f_path); f->f_path.mnt = NULL; f->f_path.dentry = NULL; + f->f_inode = NULL; return error; } -- cgit v1.2.3 From dcf787f39162ce32ca325b3e784aba2d2444619a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 1 Mar 2013 23:51:07 -0500 Subject: constify path_get/path_put and fs_struct.c stuff Signed-off-by: Al Viro --- fs/fs_struct.c | 6 +++--- fs/internal.h | 2 +- fs/namei.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'fs') 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/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); -- cgit v1.2.3