Skip to content

Commit

Permalink
AFS: AFS fixups
Browse files Browse the repository at this point in the history
Make some miscellaneous changes to the AFS filesystem:

 (1) Assert RCU barriers on module exit to make sure RCU has finished with
     callbacks in this module.

 (2) Correctly handle the AFS server returning a zero-length read.

 (3) Split out data zapping calls into one function (afs_zap_data).

 (4) Rename some afs_file_*() functions to afs_*() where they apply to
     non-regular files too.

 (5) Be consistent about the presentation of volume ID:vnode ID in debugging
     output.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
dhowells authored and Linus Torvalds committed May 9, 2007
1 parent ef71c15 commit 416351f
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 109 deletions.
9 changes: 3 additions & 6 deletions fs/afs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void afs_init_callback_state(struct afs_server *server)
while (!RB_EMPTY_ROOT(&server->cb_promises)) {
vnode = rb_entry(server->cb_promises.rb_node,
struct afs_vnode, cb_promise);
_debug("UNPROMISE { vid=%x vn=%u uq=%u}",
_debug("UNPROMISE { vid=%x:%u uq=%u}",
vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
rb_erase(&vnode->cb_promise, &server->cb_promises);
vnode->cb_promised = false;
Expand Down Expand Up @@ -84,11 +84,8 @@ void afs_broken_callback_work(struct work_struct *work)

/* 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:%u}",
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);
}

out:
Expand Down
18 changes: 9 additions & 9 deletions fs/afs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const struct inode_operations afs_dir_inode_operations = {
.rmdir = afs_rmdir,
.rename = afs_rename,
.permission = afs_permission,
.getattr = afs_inode_getattr,
.getattr = afs_getattr,
};

static struct dentry_operations afs_fs_dentry_operations = {
Expand Down Expand Up @@ -491,7 +491,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,

vnode = AFS_FS_I(dir);

_enter("{%x:%d},%p{%s},",
_enter("{%x:%u},%p{%s},",
vnode->fid.vid, vnode->fid.vnode, dentry, dentry->d_name.name);

ASSERTCMP(dentry->d_inode, ==, NULL);
Expand Down Expand Up @@ -731,7 +731,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, int mode)

dvnode = AFS_FS_I(dir);

_enter("{%x:%d},{%s},%o",
_enter("{%x:%u},{%s},%o",
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);

ret = -ENAMETOOLONG;
Expand Down Expand Up @@ -796,7 +796,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)

dvnode = AFS_FS_I(dir);

_enter("{%x:%d},{%s}",
_enter("{%x:%u},{%s}",
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);

ret = -ENAMETOOLONG;
Expand Down Expand Up @@ -842,7 +842,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)

dvnode = AFS_FS_I(dir);

_enter("{%x:%d},{%s}",
_enter("{%x:%u},{%s}",
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);

ret = -ENAMETOOLONG;
Expand Down Expand Up @@ -916,7 +916,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, int mode,

dvnode = AFS_FS_I(dir);

_enter("{%x:%d},{%s},%o,",
_enter("{%x:%u},{%s},%o,",
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);

ret = -ENAMETOOLONG;
Expand Down Expand Up @@ -983,7 +983,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
vnode = AFS_FS_I(from->d_inode);
dvnode = AFS_FS_I(dir);

_enter("{%x:%d},{%x:%d},{%s}",
_enter("{%x:%u},{%x:%u},{%s}",
vnode->fid.vid, vnode->fid.vnode,
dvnode->fid.vid, dvnode->fid.vnode,
dentry->d_name.name);
Expand Down Expand Up @@ -1032,7 +1032,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,

dvnode = AFS_FS_I(dir);

_enter("{%x:%d},{%s},%s",
_enter("{%x:%u},{%s},%s",
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name,
content);

Expand Down Expand Up @@ -1104,7 +1104,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
orig_dvnode = AFS_FS_I(old_dir);
new_dvnode = AFS_FS_I(new_dir);

_enter("{%x:%d},{%x:%d},{%x:%d},{%s}",
_enter("{%x:%u},{%x:%u},{%x:%u},{%s}",
orig_dvnode->fid.vid, orig_dvnode->fid.vnode,
vnode->fid.vid, vnode->fid.vnode,
new_dvnode->fid.vid, new_dvnode->fid.vnode,
Expand Down
75 changes: 26 additions & 49 deletions fs/afs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
#include <linux/pagemap.h>
#include "internal.h"

static int afs_file_readpage(struct file *file, struct page *page);
static void afs_file_invalidatepage(struct page *page, unsigned long offset);
static int afs_file_releasepage(struct page *page, gfp_t gfp_flags);
static int afs_readpage(struct file *file, struct page *page);
static void afs_invalidatepage(struct page *page, unsigned long offset);
static int afs_releasepage(struct page *page, gfp_t gfp_flags);

const struct file_operations afs_file_operations = {
.open = afs_open,
Expand All @@ -32,15 +32,15 @@ const struct file_operations afs_file_operations = {
};

const struct inode_operations afs_file_inode_operations = {
.getattr = afs_inode_getattr,
.getattr = afs_getattr,
.permission = afs_permission,
};

const struct address_space_operations afs_fs_aops = {
.readpage = afs_file_readpage,
.readpage = afs_readpage,
.set_page_dirty = __set_page_dirty_nobuffers,
.releasepage = afs_file_releasepage,
.invalidatepage = afs_file_invalidatepage,
.releasepage = afs_releasepage,
.invalidatepage = afs_invalidatepage,
};

/*
Expand All @@ -52,7 +52,7 @@ int afs_open(struct inode *inode, struct file *file)
struct key *key;
int ret;

_enter("{%x:%x},", vnode->fid.vid, vnode->fid.vnode);
_enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);

key = afs_request_key(vnode->volume->cell);
if (IS_ERR(key)) {
Expand All @@ -78,7 +78,7 @@ int afs_release(struct inode *inode, struct file *file)
{
struct afs_vnode *vnode = AFS_FS_I(inode);

_enter("{%x:%x},", vnode->fid.vid, vnode->fid.vnode);
_enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);

key_put(file->private_data);
_leave(" = 0");
Expand All @@ -89,10 +89,10 @@ int afs_release(struct inode *inode, struct file *file)
* deal with notification that a page was read from the cache
*/
#ifdef AFS_CACHING_SUPPORT
static void afs_file_readpage_read_complete(void *cookie_data,
struct page *page,
void *data,
int error)
static void afs_readpage_read_complete(void *cookie_data,
struct page *page,
void *data,
int error)
{
_enter("%p,%p,%p,%d", cookie_data, page, data, error);

Expand All @@ -109,10 +109,10 @@ static void afs_file_readpage_read_complete(void *cookie_data,
* deal with notification that a page was written to the cache
*/
#ifdef AFS_CACHING_SUPPORT
static void afs_file_readpage_write_complete(void *cookie_data,
struct page *page,
void *data,
int error)
static void afs_readpage_write_complete(void *cookie_data,
struct page *page,
void *data,
int error)
{
_enter("%p,%p,%p,%d", cookie_data, page, data, error);

Expand All @@ -121,9 +121,9 @@ static void afs_file_readpage_write_complete(void *cookie_data,
#endif

/*
* AFS read page from file (or symlink)
* AFS read page from file, directory or symlink
*/
static int afs_file_readpage(struct file *file, struct page *page)
static int afs_readpage(struct file *file, struct page *page)
{
struct afs_vnode *vnode;
struct inode *inode;
Expand Down Expand Up @@ -218,31 +218,14 @@ static int afs_file_readpage(struct file *file, struct page *page)
return ret;
}

/*
* get a page cookie for the specified page
*/
#ifdef AFS_CACHING_SUPPORT
int afs_cache_get_page_cookie(struct page *page,
struct cachefs_page **_page_cookie)
{
int ret;

_enter("");
ret = cachefs_page_get_private(page,_page_cookie, GFP_NOIO);

_leave(" = %d", ret);
return ret;
}
#endif

/*
* invalidate part or all of a page
*/
static void afs_file_invalidatepage(struct page *page, unsigned long offset)
static void afs_invalidatepage(struct page *page, unsigned long offset)
{
int ret = 1;

_enter("{%lu},%lu", page->index, offset);
kenter("{%lu},%lu", page->index, offset);

BUG_ON(!PageLocked(page));

Expand Down Expand Up @@ -274,23 +257,17 @@ static void afs_file_invalidatepage(struct page *page, unsigned long offset)
/*
* release a page and cleanup its private data
*/
static int afs_file_releasepage(struct page *page, gfp_t gfp_flags)
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
{
struct cachefs_page *pageio;
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);

_enter("{%lu},%x", page->index, gfp_flags);
_enter("{{%x:%u}[%lu],%lx},%x",
vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
gfp_flags);

if (PagePrivate(page)) {
#ifdef AFS_CACHING_SUPPORT
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
cachefs_uncache_page(vnode->cache, page);
#endif

pageio = (struct cachefs_page *) page_private(page);
set_page_private(page, 0);
ClearPagePrivate(page);

kfree(pageio);
}

_leave(" = 0");
Expand Down
37 changes: 20 additions & 17 deletions fs/afs/fsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ int afs_fs_fetch_file_status(struct afs_server *server,
struct afs_call *call;
__be32 *bp;

_enter(",%x,{%x:%d},,",
_enter(",%x,{%x:%u},,",
key_serial(key), vnode->fid.vid, vnode->fid.vnode);

call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
Expand Down Expand Up @@ -265,25 +265,20 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
call->offset = 0;
call->unmarshall++;

if (call->count < PAGE_SIZE) {
page = call->reply3;
buffer = kmap_atomic(page, KM_USER0);
memset(buffer + PAGE_SIZE - call->count, 0,
call->count);
kunmap_atomic(buffer, KM_USER0);
}

/* extract the returned data */
case 2:
_debug("extract data");
page = call->reply3;
buffer = kmap_atomic(page, KM_USER0);
ret = afs_extract_data(call, skb, last, buffer, call->count);
kunmap_atomic(buffer, KM_USER0);
switch (ret) {
case 0: break;
case -EAGAIN: return 0;
default: return ret;
if (call->count > 0) {
page = call->reply3;
buffer = kmap_atomic(page, KM_USER0);
ret = afs_extract_data(call, skb, last, buffer,
call->count);
kunmap_atomic(buffer, KM_USER0);
switch (ret) {
case 0: break;
case -EAGAIN: return 0;
default: return ret;
}
}

call->offset = 0;
Expand Down Expand Up @@ -318,6 +313,14 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
if (!last)
return 0;

if (call->count < PAGE_SIZE) {
_debug("clear");
page = call->reply3;
buffer = kmap_atomic(page, KM_USER0);
memset(buffer + call->count, 0, PAGE_SIZE - call->count);
kunmap_atomic(buffer, KM_USER0);
}

_leave(" = 0 [done]");
return 0;
}
Expand Down
25 changes: 18 additions & 7 deletions fs/afs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,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;
Expand Down Expand Up @@ -203,6 +203,19 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
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)
{
kenter("zap data {%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);
}

/*
* validate a vnode/inode
* - there are several things we need to check
Expand Down Expand Up @@ -258,10 +271,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);
Expand All @@ -278,7 +289,7 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
/*
* 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;
Expand All @@ -301,7 +312,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,
Expand Down
Loading

0 comments on commit 416351f

Please sign in to comment.