commit ff4be0942bc54f636fce24b682caea2a9df00d08 Author: Linus Torvalds Date: Mon Feb 3 13:17:29 2014 -0800 Push dentry pointer down to vfs_xyzzy() helper functions This actually ends up being closer to what the callers want anyway, so it simplifies most call sites. And we'll eventually want to push down the dentry pointer to the permission checking routines, which in turn requires this. Signed-off-by: Linus Torvalds --- drivers/base/devtmpfs.c | 8 +-- drivers/staging/lustre/lustre/lvfs/lvfs_linux.c | 4 +- fs/cachefiles/namei.c | 11 ++-- fs/ecryptfs/inode.c | 22 +++---- fs/namei.c | 86 +++++++++++++++---------- fs/nfsd/nfs4recover.c | 6 +- fs/nfsd/vfs.c | 28 +++----- include/linux/fs.h | 16 ++--- ipc/mqueue.c | 8 +-- net/unix/af_unix.c | 2 +- 10 files changed, 98 insertions(+), 93 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 25798db14553..fb81de9a78a3 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -157,7 +157,7 @@ static int dev_mkdir(const char *name, umode_t mode) if (IS_ERR(dentry)) return PTR_ERR(dentry); - err = vfs_mkdir(path.dentry->d_inode, dentry, mode); + err = vfs_mkdir(path.dentry, dentry, mode); if (!err) /* mark as kernel-created inode */ dentry->d_inode->i_private = &thread; @@ -207,7 +207,7 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid, if (IS_ERR(dentry)) return PTR_ERR(dentry); - err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt); + err = vfs_mknod(path.dentry, dentry, mode, dev->devt); if (!err) { struct iattr newattrs; @@ -237,7 +237,7 @@ static int dev_rmdir(const char *name) return PTR_ERR(dentry); if (dentry->d_inode) { if (dentry->d_inode->i_private == &thread) - err = vfs_rmdir(parent.dentry->d_inode, dentry); + err = vfs_rmdir(parent.dentry, dentry); else err = -EPERM; } else { @@ -324,7 +324,7 @@ static int handle_remove(const char *nodename, struct device *dev) mutex_lock(&dentry->d_inode->i_mutex); notify_change(dentry, &newattrs, NULL); mutex_unlock(&dentry->d_inode->i_mutex); - err = vfs_unlink(parent.dentry->d_inode, dentry, NULL); + err = vfs_unlink(parent.dentry, dentry, NULL); if (!err || err == -ENOENT) deleted = 1; } diff --git a/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c b/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c index 428ffd8c37b7..c4aa260def19 100644 --- a/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c +++ b/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c @@ -222,8 +222,8 @@ int lustre_rename(struct dentry *dir, struct vfsmount *mnt, if (IS_ERR(dchild_new)) GOTO(put_old, err = PTR_ERR(dchild_new)); - err = ll_vfs_rename(dir->d_inode, dchild_old, mnt, - dir->d_inode, dchild_new, mnt, NULL); + err = ll_vfs_rename(dir, dchild_old, mnt, + dir, dchild_new, mnt, NULL); dput(dchild_new); put_old: diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index ca65f39dc8dc..c4b6712909e3 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -294,7 +294,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, if (ret < 0) { cachefiles_io_error(cache, "Unlink security error"); } else { - ret = vfs_unlink(dir->d_inode, rep, NULL); + ret = vfs_unlink(dir, rep, NULL); if (preemptive) cachefiles_mark_object_buried(cache, rep); @@ -395,8 +395,7 @@ try_again: if (ret < 0) { cachefiles_io_error(cache, "Rename security error %d", ret); } else { - ret = vfs_rename(dir->d_inode, rep, - cache->graveyard->d_inode, grave, NULL); + ret = vfs_rename(dir, rep, cache->graveyard, grave, NULL); if (ret != 0 && ret != -ENOMEM) cachefiles_io_error(cache, "Rename failed with error %d", ret); @@ -537,7 +536,7 @@ lookup_again: if (ret < 0) goto create_error; start = jiffies; - ret = vfs_mkdir(dir->d_inode, next, 0); + ret = vfs_mkdir(dir, next, 0); cachefiles_hist(cachefiles_mkdir_histogram, start); if (ret < 0) goto create_error; @@ -566,7 +565,7 @@ lookup_again: if (ret < 0) goto create_error; start = jiffies; - ret = vfs_create(dir->d_inode, next, S_IFREG, true); + ret = vfs_create(dir, next, S_IFREG, true); cachefiles_hist(cachefiles_create_histogram, start); if (ret < 0) goto create_error; @@ -755,7 +754,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, ret = security_path_mkdir(&path, subdir, 0700); if (ret < 0) goto mkdir_error; - ret = vfs_mkdir(dir->d_inode, subdir, 0700); + ret = vfs_mkdir(dir, subdir, 0700); if (ret < 0) goto mkdir_error; diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index b167ca48b8ee..a7a823f980c5 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -153,7 +153,7 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, dget(lower_dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL); + rc = vfs_unlink(lower_dir_dentry, lower_dentry, NULL); if (rc) { printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); goto out_unlock; @@ -198,7 +198,7 @@ ecryptfs_do_create(struct inode *directory_inode, inode = ERR_CAST(lower_dir_dentry); goto out; } - rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, true); + rc = vfs_create(lower_dir_dentry, lower_dentry, mode, true); if (rc) { printk(KERN_ERR "%s: Failure to create dentry in lower fs; " "rc = [%d]\n", __func__, rc); @@ -208,7 +208,7 @@ ecryptfs_do_create(struct inode *directory_inode, inode = __ecryptfs_get_inode(lower_dentry->d_inode, directory_inode->i_sb); if (IS_ERR(inode)) { - vfs_unlink(lower_dir_dentry->d_inode, lower_dentry, NULL); + vfs_unlink(lower_dir_dentry, lower_dentry, NULL); goto out_lock; } fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); @@ -474,8 +474,7 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, dget(lower_old_dentry); dget(lower_new_dentry); lower_dir_dentry = lock_parent(lower_new_dentry); - rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, - lower_new_dentry, NULL); + rc = vfs_link(lower_old_dentry, lower_dir_dentry, lower_new_dentry, NULL); if (rc || !lower_new_dentry->d_inode) goto out_lock; rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); @@ -520,8 +519,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, strlen(symname)); if (rc) goto out_lock; - rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, - encoded_symname); + rc = vfs_symlink(lower_dir_dentry, lower_dentry, encoded_symname); kfree(encoded_symname); if (rc || !lower_dentry->d_inode) goto out_lock; @@ -546,7 +544,7 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode lower_dentry = ecryptfs_dentry_to_lower(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); + rc = vfs_mkdir(lower_dir_dentry, lower_dentry, mode); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); @@ -572,7 +570,7 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) dget(dentry); lower_dir_dentry = lock_parent(lower_dentry); dget(lower_dentry); - rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); + rc = vfs_rmdir(lower_dir_dentry, lower_dentry); dput(lower_dentry); if (!rc && dentry->d_inode) clear_nlink(dentry->d_inode); @@ -594,7 +592,7 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev lower_dentry = ecryptfs_dentry_to_lower(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); + rc = vfs_mknod(lower_dir_dentry, lower_dentry, mode, dev); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); @@ -639,8 +637,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, rc = -ENOTEMPTY; goto out_lock; } - rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, - lower_new_dir_dentry->d_inode, lower_new_dentry, + rc = vfs_rename(lower_old_dir_dentry, lower_old_dentry, + lower_new_dir_dentry, lower_new_dentry, NULL); if (rc) goto out_lock; diff --git a/fs/namei.c b/fs/namei.c index d580df2e6804..142741e1ac9e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2365,8 +2365,9 @@ static inline int check_sticky(struct inode *dir, struct inode *inode) * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete(struct dentry *parent, struct dentry *victim, bool isdir) { + struct inode *dir = parent->d_inode; struct inode *inode = victim->d_inode; int error; @@ -2408,8 +2409,9 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct dentry *parent, struct dentry *child) { + struct inode *dir = parent->d_inode; audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; @@ -2460,10 +2462,11 @@ void unlock_rename(struct dentry *p1, struct dentry *p2) } } -int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, +int vfs_create(struct dentry *parent, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + struct inode *dir = parent->d_inode; + int error = may_create(parent, dentry); if (error) return error; @@ -2812,8 +2815,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, error = security_path_mknod(&nd->path, dentry, mode, 0); if (error) goto out_dput; - error = vfs_create(dir->d_inode, dentry, mode, - nd->flags & LOOKUP_EXCL); + error = vfs_create(dir, dentry, mode, nd->flags & LOOKUP_EXCL); if (error) goto out_dput; } @@ -3323,9 +3325,10 @@ struct dentry *user_path_create(int dfd, const char __user *pathname, } EXPORT_SYMBOL(user_path_create); -int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) +int vfs_mknod(struct dentry *parent, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + struct inode *dir; + int error = may_create(parent, dentry); if (error) return error; @@ -3333,6 +3336,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) return -EPERM; + dir = parent->d_inode; if (!dir->i_op->mknod) return -EPERM; @@ -3390,14 +3394,14 @@ retry: goto out; switch (mode & S_IFMT) { case 0: case S_IFREG: - error = vfs_create(path.dentry->d_inode,dentry,mode,true); + error = vfs_create(path.dentry,dentry,mode,true); break; case S_IFCHR: case S_IFBLK: - error = vfs_mknod(path.dentry->d_inode,dentry,mode, + error = vfs_mknod(path.dentry,dentry,mode, new_decode_dev(dev)); break; case S_IFIFO: case S_IFSOCK: - error = vfs_mknod(path.dentry->d_inode,dentry,mode,0); + error = vfs_mknod(path.dentry,dentry,mode,0); break; } out: @@ -3414,14 +3418,16 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d return sys_mknodat(AT_FDCWD, filename, mode, dev); } -int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +int vfs_mkdir(struct dentry *parent, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); - unsigned max_links = dir->i_sb->s_max_links; + struct inode *dir; + unsigned max_links; + int error = may_create(parent, dentry); if (error) return error; + dir = parent->d_inode; if (!dir->i_op->mkdir) return -EPERM; @@ -3430,6 +3436,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) if (error) return error; + max_links = dir->i_sb->s_max_links; if (max_links && dir->i_nlink >= max_links) return -EMLINK; @@ -3455,7 +3462,7 @@ retry: mode &= ~current_umask(); error = security_path_mkdir(&path, dentry, mode); if (!error) - error = vfs_mkdir(path.dentry->d_inode, dentry, mode); + error = vfs_mkdir(path.dentry, dentry, mode); done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; @@ -3493,13 +3500,15 @@ void dentry_unhash(struct dentry *dentry) spin_unlock(&dentry->d_lock); } -int vfs_rmdir(struct inode *dir, struct dentry *dentry) +int vfs_rmdir(struct dentry *parent, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + struct inode *dir; + int error = may_delete(parent, dentry, 1); if (error) return error; + dir = parent->d_inode; if (!dir->i_op->rmdir) return -EPERM; @@ -3571,7 +3580,7 @@ retry: error = security_path_rmdir(&nd.path, dentry); if (error) goto exit3; - error = vfs_rmdir(nd.path.dentry->d_inode, dentry); + error = vfs_rmdir(nd.path.dentry, dentry); exit3: dput(dentry); exit2: @@ -3610,10 +3619,11 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) * be appropriate for callers that expect the underlying filesystem not * to be NFS exported. */ -int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) +int vfs_unlink(struct dentry *parent, struct dentry *dentry, struct inode **delegated_inode) { + struct inode *dir = parent->d_inode; struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(parent, dentry, 0); if (error) return error; @@ -3690,7 +3700,7 @@ retry_deleg: error = security_path_unlink(&nd.path, dentry); if (error) goto exit2; - error = vfs_unlink(nd.path.dentry->d_inode, dentry, &delegated_inode); + error = vfs_unlink(nd.path.dentry, dentry, &delegated_inode); exit2: dput(dentry); } @@ -3740,13 +3750,15 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) return do_unlinkat(AT_FDCWD, pathname); } -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) +int vfs_symlink(struct dentry *parent, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + struct inode *dir; + int error = may_create(parent, dentry); if (error) return error; + dir = parent->d_inode; if (!dir->i_op->symlink) return -EPERM; @@ -3780,7 +3792,7 @@ retry: error = security_path_symlink(&path, dentry, from->name); if (!error) - error = vfs_symlink(path.dentry->d_inode, dentry, from->name); + error = vfs_symlink(path.dentry, dentry, from->name); done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; @@ -3815,8 +3827,9 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newn * be appropriate for callers that expect the underlying filesystem not * to be NFS exported. */ -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode) +int vfs_link(struct dentry *old_dentry, struct dentry *new_parent, struct dentry *new_dentry, struct inode **delegated_inode) { + struct inode *dir = new_parent->d_inode; struct inode *inode = old_dentry->d_inode; unsigned max_links = dir->i_sb->s_max_links; int error; @@ -3824,7 +3837,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(new_parent, new_dentry); if (error) return error; @@ -3921,7 +3934,7 @@ retry: error = security_path_link(old_path.dentry, &new_path, new_dentry); if (error) goto out_dput; - error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode); + error = vfs_link(old_path.dentry, new_path.dentry, new_dentry, &delegated_inode); out_dput: done_path_create(&new_path, new_dentry); if (delegated_inode) { @@ -4091,28 +4104,31 @@ out: * be appropriate for callers that expect the underlying filesystem not * to be NFS exported. */ -int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, +int vfs_rename(struct dentry *old_parent, struct dentry *old_dentry, + struct dentry *new_parent, struct dentry *new_dentry, struct inode **delegated_inode) { int error; + struct inode *old_dir, *new_dir; int is_dir = d_is_directory(old_dentry) || d_is_autodir(old_dentry); const unsigned char *old_name; if (old_dentry->d_inode == new_dentry->d_inode) return 0; - error = may_delete(old_dir, old_dentry, is_dir); + error = may_delete(old_parent, old_dentry, is_dir); if (error) return error; if (!new_dentry->d_inode) - error = may_create(new_dir, new_dentry); + error = may_create(new_parent, new_dentry); else - error = may_delete(new_dir, new_dentry, is_dir); + error = may_delete(new_parent, new_dentry, is_dir); if (error) return error; + old_dir = old_parent->d_inode; + new_dir = new_parent->d_inode; if (!old_dir->i_op->rename) return -EPERM; @@ -4213,9 +4229,9 @@ retry_deleg: &newnd.path, new_dentry); if (error) goto exit5; - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry, - &delegated_inode); + error = vfs_rename(old_dir, old_dentry, + new_dir, new_dentry, + &delegated_inode); exit5: dput(new_dentry); exit4: diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 9c271f42604a..666223b0d00a 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -209,7 +209,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) * as well be forgiving and just succeed silently. */ goto out_put; - status = vfs_mkdir(dir->d_inode, dentry, S_IRWXU); + status = vfs_mkdir(dir, dentry, S_IRWXU); out_put: dput(dentry); out_unlock: @@ -323,7 +323,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn) status = -ENOENT; if (!dentry->d_inode) goto out; - status = vfs_rmdir(dir->d_inode, dentry); + status = vfs_rmdir(dir, dentry); out: dput(dentry); out_unlock: @@ -383,7 +383,7 @@ purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn) if (nfs4_has_reclaimed_state(child->d_name.name, nn)) return 0; - status = vfs_rmdir(parent->d_inode, child); + status = vfs_rmdir(parent, child); if (status) printk("failed to remove client recovery directory %pd\n", child); diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 017d3cb5e99b..6faef0e5e43b 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1220,18 +1220,18 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, host_err = 0; switch (type) { case S_IFREG: - host_err = vfs_create(dirp, dchild, iap->ia_mode, true); + host_err = vfs_create(dentry, dchild, iap->ia_mode, true); if (!host_err) nfsd_check_ignore_resizing(iap); break; case S_IFDIR: - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); + host_err = vfs_mkdir(dentry, dchild, iap->ia_mode); break; case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: - host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); + host_err = vfs_mknod(dentry, dchild, iap->ia_mode, rdev); break; } if (host_err < 0) @@ -1388,7 +1388,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, goto out; } - host_err = vfs_create(dirp, dchild, iap->ia_mode, true); + host_err = vfs_create(dentry, dchild, iap->ia_mode, true); if (host_err < 0) { fh_drop_write(fhp); goto out_nfserr; @@ -1528,11 +1528,11 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced); + host_err = vfs_symlink(dentry, dnew, path_alloced); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path); + host_err = vfs_symlink(dentry, dnew, path); err = nfserrno(host_err); if (!err) err = nfserrno(commit_metadata(fhp)); @@ -1560,7 +1560,6 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *name, int len, struct svc_fh *tfhp) { struct dentry *ddir, *dnew, *dold; - struct inode *dirp; __be32 err; int host_err; @@ -1588,7 +1587,6 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, fh_lock_nested(ffhp, I_MUTEX_PARENT); ddir = ffhp->fh_dentry; - dirp = ddir->d_inode; dnew = lookup_one_len(name, ddir, len); host_err = PTR_ERR(dnew); @@ -1600,7 +1598,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, err = nfserr_noent; if (!dold->d_inode) goto out_dput; - host_err = vfs_link(dold, dirp, dnew, NULL); + host_err = vfs_link(dold, ddir, dnew, NULL); if (!host_err) { err = nfserrno(commit_metadata(ffhp)); if (!err) @@ -1633,7 +1631,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, struct svc_fh *tfhp, char *tname, int tlen) { struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap; - struct inode *fdir, *tdir; __be32 err; int host_err; @@ -1645,10 +1642,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, goto out; fdentry = ffhp->fh_dentry; - fdir = fdentry->d_inode; - tdentry = tfhp->fh_dentry; - tdir = tdentry->d_inode; err = nfserr_perm; if (!flen || isdotent(fname, flen) || !tlen || isdotent(tname, tlen)) @@ -1693,7 +1687,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry) goto out_dput_new; - host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL); + host_err = vfs_rename(fdentry, odentry, tdentry, ndentry, NULL); if (!host_err) { host_err = commit_metadata(tfhp); if (!host_err) @@ -1729,7 +1723,6 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, char *fname, int flen) { struct dentry *dentry, *rdentry; - struct inode *dirp; __be32 err; int host_err; @@ -1746,7 +1739,6 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, fh_lock_nested(fhp, I_MUTEX_PARENT); dentry = fhp->fh_dentry; - dirp = dentry->d_inode; rdentry = lookup_one_len(fname, dentry, flen); host_err = PTR_ERR(rdentry); @@ -1763,9 +1755,9 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, type = rdentry->d_inode->i_mode & S_IFMT; if (type != S_IFDIR) - host_err = vfs_unlink(dirp, rdentry, NULL); + host_err = vfs_unlink(dentry, rdentry, NULL); else - host_err = vfs_rmdir(dirp, rdentry); + host_err = vfs_rmdir(dentry, rdentry); if (!host_err) host_err = commit_metadata(fhp); dput(rdentry); diff --git a/include/linux/fs.h b/include/linux/fs.h index 09f553c59813..c9fd8fb28c92 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1449,14 +1449,14 @@ extern bool inode_owner_or_capable(const struct inode *inode); /* * VFS helper functions.. */ -extern int vfs_create(struct inode *, struct dentry *, umode_t, bool); -extern int vfs_mkdir(struct inode *, struct dentry *, umode_t); -extern int vfs_mknod(struct inode *, struct dentry *, umode_t, dev_t); -extern int vfs_symlink(struct inode *, struct dentry *, const char *); -extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **); -extern int vfs_rmdir(struct inode *, struct dentry *); -extern int vfs_unlink(struct inode *, struct dentry *, struct inode **); -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **); +extern int vfs_create(struct dentry *, struct dentry *, umode_t, bool); +extern int vfs_mkdir(struct dentry *, struct dentry *, umode_t); +extern int vfs_mknod(struct dentry *, struct dentry *, umode_t, dev_t); +extern int vfs_symlink(struct dentry *, struct dentry *, const char *); +extern int vfs_link(struct dentry *, struct dentry *, struct dentry *, struct inode **); +extern int vfs_rmdir(struct dentry *, struct dentry *); +extern int vfs_unlink(struct dentry *, struct dentry *, struct inode **); +extern int vfs_rename(struct dentry *, struct dentry *, struct dentry *, struct dentry *, struct inode **); /* * VFS dentry helper functions. diff --git a/ipc/mqueue.c b/ipc/mqueue.c index ccf1f9fd263a..9c254d1e077f 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -728,7 +728,7 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr) /* * Invoked when creating a new queue via sys_mq_open */ -static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, +static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *parent, struct path *path, int oflag, umode_t mode, struct mq_attr *attr) { @@ -754,7 +754,7 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, } mode &= ~current_umask(); - ret = vfs_create(dir, path->dentry, mode, true); + ret = vfs_create(parent, path->dentry, mode, true); path->dentry->d_fsdata = NULL; if (ret) return ERR_PTR(ret); @@ -824,7 +824,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, goto out; } audit_inode_parent_hidden(name, root); - filp = do_create(ipc_ns, root->d_inode, + filp = do_create(ipc_ns, root, &path, oflag, mode, u_attr ? &attr : NULL); } @@ -886,7 +886,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) err = -ENOENT; } else { ihold(inode); - err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL); + err = vfs_unlink(dentry->d_parent, dentry, NULL); } dput(dentry); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 29fc8bee9702..93371f7b9f86 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -845,7 +845,7 @@ static int unix_mknod(const char *sun_path, umode_t mode, struct path *res) */ err = security_path_mknod(&path, dentry, mode, 0); if (!err) { - err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0); + err = vfs_mknod(path.dentry, dentry, mode, 0); if (!err) { res->mnt = mntget(path.mnt); res->dentry = dget(dentry);