aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c169
1 files changed, 75 insertions, 94 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index af7c3c3074b0..eef0576a7785 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -48,8 +48,8 @@
48#include <linux/fsnotify.h> 48#include <linux/fsnotify.h>
49#include <linux/posix_acl.h> 49#include <linux/posix_acl.h>
50#include <linux/posix_acl_xattr.h> 50#include <linux/posix_acl_xattr.h>
51#ifdef CONFIG_NFSD_V4
52#include <linux/xattr.h> 51#include <linux/xattr.h>
52#ifdef CONFIG_NFSD_V4
53#include <linux/nfs4.h> 53#include <linux/nfs4.h>
54#include <linux/nfs4_acl.h> 54#include <linux/nfs4_acl.h>
55#include <linux/nfsd_idmap.h> 55#include <linux/nfsd_idmap.h>
@@ -365,8 +365,30 @@ out_nfserr:
365 goto out; 365 goto out;
366} 366}
367 367
368#if defined(CONFIG_NFSD_V4) 368#if defined(CONFIG_NFSD_V2_ACL) || \
369 defined(CONFIG_NFSD_V3_ACL) || \
370 defined(CONFIG_NFSD_V4)
371static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
372{
373 ssize_t buflen;
374 int error;
375
376 buflen = vfs_getxattr(dentry, key, NULL, 0);
377 if (buflen <= 0)
378 return buflen;
379
380 *buf = kmalloc(buflen, GFP_KERNEL);
381 if (!*buf)
382 return -ENOMEM;
369 383
384 error = vfs_getxattr(dentry, key, *buf, buflen);
385 if (error < 0)
386 return error;
387 return buflen;
388}
389#endif
390
391#if defined(CONFIG_NFSD_V4)
370static int 392static int
371set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) 393set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
372{ 394{
@@ -374,7 +396,6 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
374 size_t buflen; 396 size_t buflen;
375 char *buf = NULL; 397 char *buf = NULL;
376 int error = 0; 398 int error = 0;
377 struct inode *inode = dentry->d_inode;
378 399
379 buflen = posix_acl_xattr_size(pacl->a_count); 400 buflen = posix_acl_xattr_size(pacl->a_count);
380 buf = kmalloc(buflen, GFP_KERNEL); 401 buf = kmalloc(buflen, GFP_KERNEL);
@@ -388,15 +409,7 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
388 goto out; 409 goto out;
389 } 410 }
390 411
391 error = -EOPNOTSUPP; 412 error = vfs_setxattr(dentry, key, buf, len, 0);
392 if (inode->i_op && inode->i_op->setxattr) {
393 down(&inode->i_sem);
394 security_inode_setxattr(dentry, key, buf, len, 0);
395 error = inode->i_op->setxattr(dentry, key, buf, len, 0);
396 if (!error)
397 security_inode_post_setxattr(dentry, key, buf, len, 0);
398 up(&inode->i_sem);
399 }
400out: 413out:
401 kfree(buf); 414 kfree(buf);
402 return error; 415 return error;
@@ -455,44 +468,19 @@ out_nfserr:
455static struct posix_acl * 468static struct posix_acl *
456_get_posix_acl(struct dentry *dentry, char *key) 469_get_posix_acl(struct dentry *dentry, char *key)
457{ 470{
458 struct inode *inode = dentry->d_inode; 471 void *buf = NULL;
459 char *buf = NULL;
460 int buflen, error = 0;
461 struct posix_acl *pacl = NULL; 472 struct posix_acl *pacl = NULL;
473 int buflen;
462 474
463 error = -EOPNOTSUPP; 475 buflen = nfsd_getxattr(dentry, key, &buf);
464 if (inode->i_op == NULL) 476 if (!buflen)
465 goto out_err; 477 buflen = -ENODATA;
466 if (inode->i_op->getxattr == NULL) 478 if (buflen <= 0)
467 goto out_err; 479 return ERR_PTR(buflen);
468
469 error = security_inode_getxattr(dentry, key);
470 if (error)
471 goto out_err;
472
473 buflen = inode->i_op->getxattr(dentry, key, NULL, 0);
474 if (buflen <= 0) {
475 error = buflen < 0 ? buflen : -ENODATA;
476 goto out_err;
477 }
478
479 buf = kmalloc(buflen, GFP_KERNEL);
480 if (buf == NULL) {
481 error = -ENOMEM;
482 goto out_err;
483 }
484
485 error = inode->i_op->getxattr(dentry, key, buf, buflen);
486 if (error < 0)
487 goto out_err;
488 480
489 pacl = posix_acl_from_xattr(buf, buflen); 481 pacl = posix_acl_from_xattr(buf, buflen);
490 out:
491 kfree(buf); 482 kfree(buf);
492 return pacl; 483 return pacl;
493 out_err:
494 pacl = ERR_PTR(error);
495 goto out;
496} 484}
497 485
498int 486int
@@ -717,27 +705,33 @@ nfsd_close(struct file *filp)
717 * As this calls fsync (not fdatasync) there is no need for a write_inode 705 * As this calls fsync (not fdatasync) there is no need for a write_inode
718 * after it. 706 * after it.
719 */ 707 */
720static inline void nfsd_dosync(struct file *filp, struct dentry *dp, 708static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
721 struct file_operations *fop) 709 struct file_operations *fop)
722{ 710{
723 struct inode *inode = dp->d_inode; 711 struct inode *inode = dp->d_inode;
724 int (*fsync) (struct file *, struct dentry *, int); 712 int (*fsync) (struct file *, struct dentry *, int);
713 int err = nfs_ok;
725 714
726 filemap_fdatawrite(inode->i_mapping); 715 filemap_fdatawrite(inode->i_mapping);
727 if (fop && (fsync = fop->fsync)) 716 if (fop && (fsync = fop->fsync))
728 fsync(filp, dp, 0); 717 err=fsync(filp, dp, 0);
729 filemap_fdatawait(inode->i_mapping); 718 filemap_fdatawait(inode->i_mapping);
719
720 return nfserrno(err);
730} 721}
731 722
732 723
733static void 724static int
734nfsd_sync(struct file *filp) 725nfsd_sync(struct file *filp)
735{ 726{
727 int err;
736 struct inode *inode = filp->f_dentry->d_inode; 728 struct inode *inode = filp->f_dentry->d_inode;
737 dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name); 729 dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
738 down(&inode->i_sem); 730 mutex_lock(&inode->i_mutex);
739 nfsd_dosync(filp, filp->f_dentry, filp->f_op); 731 err=nfsd_dosync(filp, filp->f_dentry, filp->f_op);
740 up(&inode->i_sem); 732 mutex_unlock(&inode->i_mutex);
733
734 return err;
741} 735}
742 736
743void 737void
@@ -874,6 +868,16 @@ out:
874 return err; 868 return err;
875} 869}
876 870
871static void kill_suid(struct dentry *dentry)
872{
873 struct iattr ia;
874 ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
875
876 mutex_lock(&dentry->d_inode->i_mutex);
877 notify_change(dentry, &ia);
878 mutex_unlock(&dentry->d_inode->i_mutex);
879}
880
877static inline int 881static inline int
878nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, 882nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
879 loff_t offset, struct kvec *vec, int vlen, 883 loff_t offset, struct kvec *vec, int vlen,
@@ -927,14 +931,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
927 } 931 }
928 932
929 /* clear setuid/setgid flag after write */ 933 /* clear setuid/setgid flag after write */
930 if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) { 934 if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
931 struct iattr ia; 935 kill_suid(dentry);
932 ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
933
934 down(&inode->i_sem);
935 notify_change(dentry, &ia);
936 up(&inode->i_sem);
937 }
938 936
939 if (err >= 0 && stable) { 937 if (err >= 0 && stable) {
940 static ino_t last_ino; 938 static ino_t last_ino;
@@ -962,7 +960,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
962 960
963 if (inode->i_state & I_DIRTY) { 961 if (inode->i_state & I_DIRTY) {
964 dprintk("nfsd: write sync %d\n", current->pid); 962 dprintk("nfsd: write sync %d\n", current->pid);
965 nfsd_sync(file); 963 err=nfsd_sync(file);
966 } 964 }
967#if 0 965#if 0
968 wake_up(&inode->i_wait); 966 wake_up(&inode->i_wait);
@@ -1066,7 +1064,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1066 return err; 1064 return err;
1067 if (EX_ISSYNC(fhp->fh_export)) { 1065 if (EX_ISSYNC(fhp->fh_export)) {
1068 if (file->f_op && file->f_op->fsync) { 1066 if (file->f_op && file->f_op->fsync) {
1069 nfsd_sync(file); 1067 err = nfsd_sync(file);
1070 } else { 1068 } else {
1071 err = nfserr_notsupp; 1069 err = nfserr_notsupp;
1072 } 1070 }
@@ -1874,39 +1872,25 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type)
1874 ssize_t size; 1872 ssize_t size;
1875 struct posix_acl *acl; 1873 struct posix_acl *acl;
1876 1874
1877 if (!IS_POSIXACL(inode) || !inode->i_op || !inode->i_op->getxattr) 1875 if (!IS_POSIXACL(inode))
1876 return ERR_PTR(-EOPNOTSUPP);
1877
1878 switch (type) {
1879 case ACL_TYPE_ACCESS:
1880 name = POSIX_ACL_XATTR_ACCESS;
1881 break;
1882 case ACL_TYPE_DEFAULT:
1883 name = POSIX_ACL_XATTR_DEFAULT;
1884 break;
1885 default:
1878 return ERR_PTR(-EOPNOTSUPP); 1886 return ERR_PTR(-EOPNOTSUPP);
1879 switch(type) {
1880 case ACL_TYPE_ACCESS:
1881 name = POSIX_ACL_XATTR_ACCESS;
1882 break;
1883 case ACL_TYPE_DEFAULT:
1884 name = POSIX_ACL_XATTR_DEFAULT;
1885 break;
1886 default:
1887 return ERR_PTR(-EOPNOTSUPP);
1888 } 1887 }
1889 1888
1890 size = inode->i_op->getxattr(fhp->fh_dentry, name, NULL, 0); 1889 size = nfsd_getxattr(fhp->fh_dentry, name, &value);
1890 if (size < 0)
1891 return ERR_PTR(size);
1891 1892
1892 if (size < 0) {
1893 acl = ERR_PTR(size);
1894 goto getout;
1895 } else if (size > 0) {
1896 value = kmalloc(size, GFP_KERNEL);
1897 if (!value) {
1898 acl = ERR_PTR(-ENOMEM);
1899 goto getout;
1900 }
1901 size = inode->i_op->getxattr(fhp->fh_dentry, name, value, size);
1902 if (size < 0) {
1903 acl = ERR_PTR(size);
1904 goto getout;
1905 }
1906 }
1907 acl = posix_acl_from_xattr(value, size); 1893 acl = posix_acl_from_xattr(value, size);
1908
1909getout:
1910 kfree(value); 1894 kfree(value);
1911 return acl; 1895 return acl;
1912} 1896}
@@ -1947,16 +1931,13 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
1947 } else 1931 } else
1948 size = 0; 1932 size = 0;
1949 1933
1950 if (!fhp->fh_locked)
1951 fh_lock(fhp); /* unlocking is done automatically */
1952 if (size) 1934 if (size)
1953 error = inode->i_op->setxattr(fhp->fh_dentry, name, 1935 error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
1954 value, size, 0);
1955 else { 1936 else {
1956 if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) 1937 if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
1957 error = 0; 1938 error = 0;
1958 else { 1939 else {
1959 error = inode->i_op->removexattr(fhp->fh_dentry, name); 1940 error = vfs_removexattr(fhp->fh_dentry, name);
1960 if (error == -ENODATA) 1941 if (error == -ENODATA)
1961 error = 0; 1942 error = 0;
1962 } 1943 }