[GFS2] patch to check for recursive lock requests in gfs2_rename code path
[powerpc.git] / fs / afs / inode.c
index 9c984cc..d196840 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/sched.h>
 #include "internal.h"
 
 struct afs_iget_data {
@@ -209,11 +210,15 @@ bad_inode:
  */
 void afs_zap_data(struct afs_vnode *vnode)
 {
-       kenter("zap data {%x:%u}", vnode->fid.vid, vnode->fid.vnode);
+       _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
 
        /* nuke all the non-dirty pages that aren't locked, mapped or being
-        * written back */
-       invalidate_remote_inode(&vnode->vfs_inode);
+        * written back in a regular file and completely discard the pages in a
+        * directory or symlink */
+       if (S_ISREG(vnode->vfs_inode.i_mode))
+               invalidate_remote_inode(&vnode->vfs_inode);
+       else
+               invalidate_inode_pages2(vnode->vfs_inode.i_mapping);
 }
 
 /*
@@ -334,6 +339,7 @@ void afs_clear_inode(struct inode *inode)
                vnode->server = NULL;
        }
 
+       ASSERT(list_empty(&vnode->writebacks));
        ASSERT(!vnode->cb_promised);
 
 #ifdef AFS_CACHING_SUPPORT
@@ -350,3 +356,47 @@ void afs_clear_inode(struct inode *inode)
 
        _leave("");
 }
+
+/*
+ * set the attributes of an inode
+ */
+int afs_setattr(struct dentry *dentry, struct iattr *attr)
+{
+       struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
+       struct key *key;
+       int ret;
+
+       _enter("{%x:%u},{n=%s},%x",
+              vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name,
+              attr->ia_valid);
+
+       if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
+                               ATTR_MTIME))) {
+               _leave(" = 0 [unsupported]");
+               return 0;
+       }
+
+       /* flush any dirty data outstanding on a regular file */
+       if (S_ISREG(vnode->vfs_inode.i_mode)) {
+               filemap_write_and_wait(vnode->vfs_inode.i_mapping);
+               afs_writeback_all(vnode);
+       }
+
+       if (attr->ia_valid & ATTR_FILE) {
+               key = attr->ia_file->private_data;
+       } else {
+               key = afs_request_key(vnode->volume->cell);
+               if (IS_ERR(key)) {
+                       ret = PTR_ERR(key);
+                       goto error;
+               }
+       }
+
+       ret = afs_vnode_setattr(vnode, key, attr);
+       if (!(attr->ia_valid & ATTR_FILE))
+               key_put(key);
+
+error:
+       _leave(" = %d", ret);
+       return ret;
+}