[PATCH] knfsd: fix setattr-on-symlink error return
[firefly-linux-kernel-4.4.55.git] / fs / nfsd / vfs.c
index de340ffd33c3e1dcbc4c4156536021cb5274e169..af7c3c3074b0075243a5850743a07ede58ebd863 100644 (file)
 #endif /* CONFIG_NFSD_V3 */
 #include <linux/nfsd/nfsfh.h>
 #include <linux/quotaops.h>
-#include <linux/dnotify.h>
-#include <linux/xattr_acl.h>
+#include <linux/fsnotify.h>
 #include <linux/posix_acl.h>
-#ifdef CONFIG_NFSD_V4
 #include <linux/posix_acl_xattr.h>
+#ifdef CONFIG_NFSD_V4
 #include <linux/xattr.h>
 #include <linux/nfs4.h>
 #include <linux/nfs4_acl.h>
@@ -255,12 +254,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 
        /* Get inode */
        err = fh_verify(rqstp, fhp, ftype, accmode);
-       if (err || !iap->ia_valid)
+       if (err)
                goto out;
 
        dentry = fhp->fh_dentry;
        inode = dentry->d_inode;
 
+       /* Ignore any mode updates on symlinks */
+       if (S_ISLNK(inode->i_mode))
+               iap->ia_valid &= ~ATTR_MODE;
+
+       if (!iap->ia_valid)
+               goto out;
+
        /* NFSv2 does not differentiate between "set-[ac]time-to-now"
         * which only requires access, and "set-[ac]time-to-X" which
         * requires ownership.
@@ -734,7 +740,7 @@ nfsd_sync(struct file *filp)
        up(&inode->i_sem);
 }
 
-static void
+void
 nfsd_sync_dir(struct dentry *dp)
 {
        nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
@@ -861,7 +867,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                nfsdstats.io_read += err;
                *count = err;
                err = 0;
-               dnotify_parent(file->f_dentry, DN_ACCESS);
+               fsnotify_access(file->f_dentry);
        } else 
                err = nfserrno(err);
 out:
@@ -917,7 +923,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        set_fs(oldfs);
        if (err >= 0) {
                nfsdstats.io_write += cnt;
-               dnotify_parent(file->f_dentry, DN_MODIFY);
+               fsnotify_modify(file->f_dentry);
        }
 
        /* clear setuid/setgid flag after write */
@@ -1872,10 +1878,10 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type)
                return ERR_PTR(-EOPNOTSUPP);
        switch(type) {
                case ACL_TYPE_ACCESS:
-                       name = XATTR_NAME_ACL_ACCESS;
+                       name = POSIX_ACL_XATTR_ACCESS;
                        break;
                case ACL_TYPE_DEFAULT:
-                       name = XATTR_NAME_ACL_DEFAULT;
+                       name = POSIX_ACL_XATTR_DEFAULT;
                        break;
                default:
                        return ERR_PTR(-EOPNOTSUPP);
@@ -1919,17 +1925,17 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
                return -EOPNOTSUPP;
        switch(type) {
                case ACL_TYPE_ACCESS:
-                       name = XATTR_NAME_ACL_ACCESS;
+                       name = POSIX_ACL_XATTR_ACCESS;
                        break;
                case ACL_TYPE_DEFAULT:
-                       name = XATTR_NAME_ACL_DEFAULT;
+                       name = POSIX_ACL_XATTR_DEFAULT;
                        break;
                default:
                        return -EOPNOTSUPP;
        }
 
        if (acl && acl->a_count) {
-               size = xattr_acl_size(acl->a_count);
+               size = posix_acl_xattr_size(acl->a_count);
                value = kmalloc(size, GFP_KERNEL);
                if (!value)
                        return -ENOMEM;