X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fafs%2Finode.c;h=08db82e1343a1555fcc911fb4d42954db3fad1a0;hb=3dfcb701e1ff7aa21d6623e46b6ec3f7d0d306e1;hp=c184a4ee59950ddf48a69a1cd3f555134a465029;hpb=18062a91d2ddc40e19fc674afeb7cad58cfa23ab;p=linux-2.6-omap-h63xx.git diff --git a/fs/afs/inode.c b/fs/afs/inode.c index c184a4ee599..08db82e1343 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "internal.h" struct afs_iget_data { @@ -125,7 +126,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key, struct inode *inode; int ret; - _enter(",{%u,%u,%u},,", fid->vid, fid->vnode, fid->unique); + _enter(",{%x:%u.%u},,", fid->vid, fid->vnode, fid->unique); as = sb->s_fs_info; data.volume = as->volume; @@ -195,14 +196,28 @@ struct inode *afs_iget(struct super_block *sb, struct key *key, /* failure */ bad_inode: - make_bad_inode(inode); - unlock_new_inode(inode); - iput(inode); - + iget_failed(inode); _leave(" = %d [bad]", ret); return ERR_PTR(ret); } +/* + * mark the data attached to an inode as obsolete due to a write on the server + * - might also want to ditch all the outstanding writes and dirty pages + */ +void afs_zap_data(struct afs_vnode *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 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); +} + /* * validate a vnode/inode * - there are several things we need to check @@ -258,10 +273,8 @@ int afs_validate(struct afs_vnode *vnode, struct key *key) /* if the vnode's data version number changed then its contents are * different */ - if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { - _debug("zap data {%x:%d}", vnode->fid.vid, vnode->fid.vnode); - invalidate_remote_inode(&vnode->vfs_inode); - } + if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) + afs_zap_data(vnode); clear_bit(AFS_VNODE_MODIFIED, &vnode->flags); mutex_unlock(&vnode->validate_lock); @@ -278,14 +291,15 @@ error_unlock: /* * read the attributes of an inode */ -int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, +int afs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode; inode = dentry->d_inode; - _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version); + _enter("{ ino=%lu v=%llu }", inode->i_ino, + (unsigned long long)inode->i_version); generic_fillattr(inode, stat); return 0; @@ -301,7 +315,7 @@ void afs_clear_inode(struct inode *inode) vnode = AFS_FS_I(inode); - _enter("{%x:%d.%d} v=%u x=%u t=%u }", + _enter("{%x:%u.%d} v=%u x=%u t=%u }", vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique, @@ -323,6 +337,7 @@ void afs_clear_inode(struct inode *inode) vnode->server = NULL; } + ASSERT(list_empty(&vnode->writebacks)); ASSERT(!vnode->cb_promised); #ifdef AFS_CACHING_SUPPORT @@ -339,3 +354,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; +}