aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/inode.c17
-rw-r--r--fs/nfs/nfs3proc.c2
-rw-r--r--fs/nfs/nfs4proc.c6
-rw-r--r--fs/nfs/proc.c2
-rw-r--r--include/linux/nfs_fs.h2
5 files changed, 18 insertions, 11 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b0cbc1ba82da..3a2d127de499 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -556,6 +556,7 @@ EXPORT_SYMBOL_GPL(nfs_setattr);
556 * This is a copy of the common vmtruncate, but with the locking 556 * This is a copy of the common vmtruncate, but with the locking
557 * corrected to take into account the fact that NFS requires 557 * corrected to take into account the fact that NFS requires
558 * inode->i_size to be updated under the inode->i_lock. 558 * inode->i_size to be updated under the inode->i_lock.
559 * Note: must be called with inode->i_lock held!
559 */ 560 */
560static int nfs_vmtruncate(struct inode * inode, loff_t offset) 561static int nfs_vmtruncate(struct inode * inode, loff_t offset)
561{ 562{
@@ -565,14 +566,14 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset)
565 if (err) 566 if (err)
566 goto out; 567 goto out;
567 568
568 spin_lock(&inode->i_lock);
569 i_size_write(inode, offset); 569 i_size_write(inode, offset);
570 /* Optimisation */ 570 /* Optimisation */
571 if (offset == 0) 571 if (offset == 0)
572 NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA; 572 NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA;
573 spin_unlock(&inode->i_lock);
574 573
574 spin_unlock(&inode->i_lock);
575 truncate_pagecache(inode, offset); 575 truncate_pagecache(inode, offset);
576 spin_lock(&inode->i_lock);
576out: 577out:
577 return err; 578 return err;
578} 579}
@@ -585,10 +586,15 @@ out:
585 * Note: we do this in the *proc.c in order to ensure that 586 * Note: we do this in the *proc.c in order to ensure that
586 * it works for things like exclusive creates too. 587 * it works for things like exclusive creates too.
587 */ 588 */
588void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) 589void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
590 struct nfs_fattr *fattr)
589{ 591{
592 /* Barrier: bump the attribute generation count. */
593 nfs_fattr_set_barrier(fattr);
594
595 spin_lock(&inode->i_lock);
596 NFS_I(inode)->attr_gencount = fattr->gencount;
590 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) { 597 if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
591 spin_lock(&inode->i_lock);
592 if ((attr->ia_valid & ATTR_MODE) != 0) { 598 if ((attr->ia_valid & ATTR_MODE) != 0) {
593 int mode = attr->ia_mode & S_IALLUGO; 599 int mode = attr->ia_mode & S_IALLUGO;
594 mode |= inode->i_mode & ~S_IALLUGO; 600 mode |= inode->i_mode & ~S_IALLUGO;
@@ -600,12 +606,13 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
600 inode->i_gid = attr->ia_gid; 606 inode->i_gid = attr->ia_gid;
601 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS 607 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
602 | NFS_INO_INVALID_ACL); 608 | NFS_INO_INVALID_ACL);
603 spin_unlock(&inode->i_lock);
604 } 609 }
605 if ((attr->ia_valid & ATTR_SIZE) != 0) { 610 if ((attr->ia_valid & ATTR_SIZE) != 0) {
606 nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC); 611 nfs_inc_stats(inode, NFSIOS_SETATTRTRUNC);
607 nfs_vmtruncate(inode, attr->ia_size); 612 nfs_vmtruncate(inode, attr->ia_size);
608 } 613 }
614 nfs_update_inode(inode, fattr);
615 spin_unlock(&inode->i_lock);
609} 616}
610EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); 617EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
611 618
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 78e557c3ab87..11109a137c0c 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -138,7 +138,7 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
138 nfs_fattr_init(fattr); 138 nfs_fattr_init(fattr);
139 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 139 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
140 if (status == 0) 140 if (status == 0)
141 nfs_setattr_update_inode(inode, sattr); 141 nfs_setattr_update_inode(inode, sattr, fattr);
142 dprintk("NFS reply setattr: %d\n", status); 142 dprintk("NFS reply setattr: %d\n", status);
143 return status; 143 return status;
144} 144}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4e41340e957d..c499e02a58ca 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2416,8 +2416,8 @@ static int _nfs4_do_open(struct inode *dir,
2416 opendata->o_res.f_attr, sattr, 2416 opendata->o_res.f_attr, sattr,
2417 state, label, olabel); 2417 state, label, olabel);
2418 if (status == 0) { 2418 if (status == 0) {
2419 nfs_setattr_update_inode(state->inode, sattr); 2419 nfs_setattr_update_inode(state->inode, sattr,
2420 nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr); 2420 opendata->o_res.f_attr);
2421 nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel); 2421 nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel);
2422 } 2422 }
2423 } 2423 }
@@ -3291,7 +3291,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
3291 3291
3292 status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, label); 3292 status = nfs4_do_setattr(inode, cred, fattr, sattr, state, NULL, label);
3293 if (status == 0) { 3293 if (status == 0) {
3294 nfs_setattr_update_inode(inode, sattr); 3294 nfs_setattr_update_inode(inode, sattr, fattr);
3295 nfs_setsecurity(inode, fattr, label); 3295 nfs_setsecurity(inode, fattr, label);
3296 } 3296 }
3297 nfs4_label_free(label); 3297 nfs4_label_free(label);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index b09cc23d6f43..6202bc0f11bb 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -139,7 +139,7 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
139 nfs_fattr_init(fattr); 139 nfs_fattr_init(fattr);
140 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); 140 status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
141 if (status == 0) 141 if (status == 0)
142 nfs_setattr_update_inode(inode, sattr); 142 nfs_setattr_update_inode(inode, sattr, fattr);
143 dprintk("NFS reply setattr: %d\n", status); 143 dprintk("NFS reply setattr: %d\n", status);
144 return status; 144 return status;
145} 145}
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 3a4ffb5856cd..f26e64e0aff8 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -356,7 +356,7 @@ extern int nfs_revalidate_inode_rcu(struct nfs_server *server, struct inode *ino
356extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); 356extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
357extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); 357extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
358extern int nfs_setattr(struct dentry *, struct iattr *); 358extern int nfs_setattr(struct dentry *, struct iattr *);
359extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr); 359extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr, struct nfs_fattr *);
360extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, 360extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
361 struct nfs4_label *label); 361 struct nfs4_label *label);
362extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); 362extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);