From: Miklos Szeredi Introduce path_symlink(). Make vfs_symlink() static. Signed-off-by: Miklos Szeredi --- fs/ecryptfs/inode.c | 14 +++++++------- fs/namei.c | 26 ++++++++++++++++++-------- fs/nfsd/vfs.c | 12 ++++-------- include/linux/fs.h | 2 +- 4 files changed, 30 insertions(+), 24 deletions(-) Index: linux-2.6/fs/ecryptfs/inode.c =================================================================== --- linux-2.6.orig/fs/ecryptfs/inode.c 2008-05-06 11:04:39.000000000 +0200 +++ linux-2.6/fs/ecryptfs/inode.c 2008-05-06 11:04:40.000000000 +0200 @@ -439,7 +439,7 @@ static int ecryptfs_symlink(struct inode { int rc; struct dentry *lower_dentry; - struct dentry *lower_dir_dentry; + struct path lower_dir; umode_t mode; char *encoded_symname; int encoded_symlen; @@ -447,7 +447,8 @@ static int ecryptfs_symlink(struct inode lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(lower_dentry); - lower_dir_dentry = lock_parent(lower_dentry); + lower_dir.mnt = ecryptfs_dentry_to_lower_mnt(dentry); + lower_dir.dentry = lock_parent(lower_dentry); mode = S_IALLUGO; encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, strlen(symname), @@ -456,18 +457,17 @@ static int ecryptfs_symlink(struct inode rc = encoded_symlen; goto out_lock; } - rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, - encoded_symname, mode); + rc = path_symlink(&lower_dir, lower_dentry, encoded_symname, mode); kfree(encoded_symname); if (rc || !lower_dentry->d_inode) goto out_lock; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); if (rc) goto out_lock; - fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); - fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); + fsstack_copy_attr_times(dir, lower_dir.dentry->d_inode); + fsstack_copy_inode_size(dir, lower_dir.dentry->d_inode); out_lock: - unlock_dir(lower_dir_dentry); + unlock_dir(lower_dir.dentry); dput(lower_dentry); if (!dentry->d_inode) d_drop(dentry); Index: linux-2.6/fs/namei.c =================================================================== --- linux-2.6.orig/fs/namei.c 2008-05-06 11:04:39.000000000 +0200 +++ linux-2.6/fs/namei.c 2008-05-06 11:04:40.000000000 +0200 @@ -2435,7 +2435,7 @@ asmlinkage long sys_unlink(const char __ return do_unlinkat(AT_FDCWD, pathname); } -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) +static int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) { int error = may_create(dir, dentry, NULL); @@ -2456,6 +2456,22 @@ int vfs_symlink(struct inode *dir, struc return error; } +int path_symlink(struct path *dir_path, struct dentry *dentry, + const char *oldname, int mode) +{ + int error = mnt_want_write(dir_path->mnt); + + if (!error) { + struct inode *dir = dir_path->dentry->d_inode; + + error = vfs_symlink(dir, dentry, oldname, mode); + mnt_drop_write(dir_path->mnt); + } + + return error; +} +EXPORT_SYMBOL(path_symlink); + asmlinkage long sys_symlinkat(const char __user *oldname, int newdfd, const char __user *newname) { @@ -2481,12 +2497,7 @@ asmlinkage long sys_symlinkat(const char if (IS_ERR(dentry)) goto out_unlock; - error = mnt_want_write(nd.path.mnt); - if (error) - goto out_dput; - error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); - mnt_drop_write(nd.path.mnt); -out_dput: + error = path_symlink(&nd.path, dentry, from, S_IALLUGO); dput(dentry); out_unlock: mutex_unlock(&nd.path.dentry->d_inode->i_mutex); @@ -3010,6 +3021,5 @@ EXPORT_SYMBOL(vfs_link); EXPORT_SYMBOL(generic_permission); EXPORT_SYMBOL(vfs_readlink); EXPORT_SYMBOL(vfs_rename); -EXPORT_SYMBOL(vfs_symlink); EXPORT_SYMBOL(dentry_unhash); EXPORT_SYMBOL(generic_readlink); Index: linux-2.6/fs/nfsd/vfs.c =================================================================== --- linux-2.6.orig/fs/nfsd/vfs.c 2008-05-06 11:04:39.000000000 +0200 +++ linux-2.6/fs/nfsd/vfs.c 2008-05-06 11:04:40.000000000 +0200 @@ -1518,6 +1518,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str struct svc_fh *resfhp, struct iattr *iap) { + struct path dir_path; struct dentry *dentry, *dnew; __be32 err, cerr; int host_err; @@ -1545,10 +1546,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str if (iap && (iap->ia_valid & ATTR_MODE)) mode = iap->ia_mode & S_IALLUGO; - host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); - if (host_err) - goto out_nfserr; - + fh_to_path(fhp, &dir_path); if (unlikely(path[plen] != 0)) { char *path_alloced = kmalloc(plen+1, GFP_KERNEL); if (path_alloced == NULL) @@ -1556,11 +1554,11 @@ nfsd_symlink(struct svc_rqst *rqstp, str else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); + host_err = path_symlink(&dir_path, dnew, path_alloced, mode); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path, mode); + host_err = path_symlink(&dir_path, dnew, path, mode); if (!host_err) { if (EX_ISSYNC(fhp->fh_export)) @@ -1569,8 +1567,6 @@ nfsd_symlink(struct svc_rqst *rqstp, str err = nfserrno(host_err); fh_unlock(fhp); - mnt_drop_write(fhp->fh_export->ex_path.mnt); - cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); dput(dnew); if (err==0) err = cerr; Index: linux-2.6/include/linux/fs.h =================================================================== --- linux-2.6.orig/include/linux/fs.h 2008-05-06 11:04:39.000000000 +0200 +++ linux-2.6/include/linux/fs.h 2008-05-06 11:04:40.000000000 +0200 @@ -1127,7 +1127,7 @@ extern int vfs_permission(struct nameida extern int path_create(struct path *, struct dentry *, int, struct nameidata *); extern int path_mkdir(struct path *, struct dentry *, int); extern int path_mknod(struct path *, struct dentry *, int, dev_t); -extern int vfs_symlink(struct inode *, struct dentry *, const char *, int); +extern int path_symlink(struct path *, struct dentry *, const char *, int); extern int vfs_link(struct dentry *, struct inode *, struct dentry *); extern int path_rmdir(struct path *, struct dentry *); extern int path_unlink(struct path *, struct dentry *); -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/