error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry);
if (likely(!error)) {
- error = vfs_symlink(parent_inode, dentry, link);
+ error = vfs_symlink(parent_inode, dentry, link, S_IALLUGO);
dentry->d_fsdata = info;
if (handle)
*handle = dentry;
goto exit2;
}
-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
+int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
{
int error = may_create(dir, dentry, NULL);
dentry = lookup_create(&nd, 0);
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
- error = vfs_symlink(nd.dentry->d_inode, dentry, from);
+ error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
dput(dentry);
}
up(&nd.dentry->d_inode->i_sem);
{
struct dentry *dentry, *dnew;
int err, cerr;
+ umode_t mode;
err = nfserr_noent;
if (!flen || !plen)
if (IS_ERR(dnew))
goto out_nfserr;
+ mode = S_IALLUGO;
+ /* Only the MODE ATTRibute is even vaguely meaningful */
+ if (iap && (iap->ia_valid & ATTR_MODE))
+ mode = iap->ia_mode & S_IALLUGO;
+
if (unlikely(path[plen] != 0)) {
char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
if (path_alloced == NULL)
else {
strncpy(path_alloced, path, plen);
path_alloced[plen] = 0;
- err = vfs_symlink(dentry->d_inode, dnew, path_alloced);
+ err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
kfree(path_alloced);
}
} else
- err = vfs_symlink(dentry->d_inode, dnew, path);
+ err = vfs_symlink(dentry->d_inode, dnew, path, mode);
if (!err) {
if (EX_ISSYNC(fhp->fh_export))
nfsd_sync_dir(dentry);
- if (iap) {
- iap->ia_valid &= ATTR_MODE; /* Only the MODE ATTRibute is
- * even vaguely meaningful */
- if (iap->ia_valid) {
- iap->ia_valid |= ATTR_CTIME;
- iap->ia_mode = (iap->ia_mode&S_IALLUGO)
- | S_IFLNK;
- if (notify_change(dnew, iap)==0)
- if (EX_ISSYNC(fhp->fh_export))
- write_inode_now(dentry->d_inode, 1);
- /* errors from notify_change are not
- * propagated to client
- */
- }
- }
} else
err = nfserrno(err);
fh_unlock(fhp);
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
extern int vfs_mkdir(struct inode *, struct dentry *, int);
extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
-extern int vfs_symlink(struct inode *, struct dentry *, const char *);
+extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
extern int vfs_rmdir(struct inode *, struct dentry *);
extern int vfs_unlink(struct inode *, struct dentry *);