diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-12-04 03:58:56 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-12-04 03:58:56 +0000 |
commit | 1d67e90f19a7acfd9a05dc59678e7d0c5090bd0d (patch) | |
tree | 357efc7b93f8f5102110d20d293f41360ec212fc /fs/smbfs/cache.c | |
parent | aea27b2e18d69af87e673972246e66657b4fa274 (diff) |
Merge with Linux 2.3.21.
Diffstat (limited to 'fs/smbfs/cache.c')
-rw-r--r-- | fs/smbfs/cache.c | 79 |
1 files changed, 69 insertions, 10 deletions
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c index 36f1650ac..14d61aba0 100644 --- a/fs/smbfs/cache.c +++ b/fs/smbfs/cache.c @@ -14,12 +14,67 @@ #include <linux/mm.h> #include <linux/dirent.h> #include <linux/smb_fs.h> +#include <linux/pagemap.h> #include <asm/page.h> #define SMBFS_PARANOIA 1 /* #define SMBFS_DEBUG_VERBOSE 1 */ +#ifdef SMBFS_DEBUG_VERBOSE +/* + * Print a cache_dirent->name, max 80 chars + * You can't just printk non-null terminated strings ... + */ +printk_name(const char *name, int len) +{ + char buf[81]; + + if(len > 80) + len = 80; + strncpy(buf, name, len); + buf[len] = 0; + printk(buf); +} +#endif + +/* + * Get a page for this inode, if new is set then we want to allocate + * the page if it isn't in memory. As I understand it the rest of the + * smb-cache code assumes we return a locked page. + */ +unsigned long +get_cached_page(struct inode * inode, unsigned long offset, int new) +{ + struct page * page; + struct page ** hash; + unsigned long new_page; + + again: + hash = page_hash(inode, offset); + page = __find_lock_page(inode, offset, hash); + if(!page && new) { + /* not in cache, alloc a new page */ + new_page = page_cache_alloc(); + if (!new_page) + return 0; + clear_page(new_page); /* smb code assumes pages are zeroed */ + page = page_cache_entry(new_page); + if (add_to_page_cache_unique(page, inode, offset, hash)) { + /* Hmm, a page has materialized in the + cache. Fine. Go back and get that page + instead ... throwing away this one first. */ + put_cached_page((unsigned long) page); + goto again; + } + } + if(!page) + return 0; + if(!PageLocked(page)) + printk(KERN_ERR "smbfs/cache.c: page isn't locked! This could be fun ...\n"); + return page_address(page); +} + static inline struct inode * get_cache_inode(struct cache_head *cachep) { @@ -38,8 +93,8 @@ smb_get_dircache(struct dentry * dentry) struct cache_head * cachep; #ifdef SMBFS_DEBUG_VERBOSE -printk("smb_get_dircache: finding cache for %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name); + printk("smb_get_dircache: finding cache for %s/%s\n", + dentry->d_parent->d_name.name, dentry->d_name.name); #endif cachep = (struct cache_head *) get_cached_page(inode, 0, 1); if (!cachep) @@ -140,8 +195,10 @@ smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry, unsigned int needed = len + sizeof(struct cache_entry); #ifdef SMBFS_DEBUG_VERBOSE -printk("smb_add_to_cache: cache inode %p, status %d, adding %s at %ld\n", -inode, cachep->status, entry->name, fpos); +printk("smb_add_to_cache: cache inode %p, status %d, adding ", + inode, cachep->status); +printk_name(entry->name, entry->len); +printk(" at %ld\n", fpos); #endif /* * Don't do anything if we've had an error ... @@ -169,8 +226,10 @@ inode, cachep->status, entry->name, fpos); block->cb_data.table[nent].ino = entry->ino; cachep->entries++; #ifdef SMBFS_DEBUG_VERBOSE -printk("smb_add_to_cache: added entry %s, len=%d, pos=%ld, entries=%d\n", -entry->name, len, fpos, cachep->entries); +printk("smb_add_to_cache: added entry "); +printk_name(entry->name, entry->len); +printk(", len=%d, pos=%ld, entries=%d\n", +len, fpos, cachep->entries); #endif return; } @@ -231,7 +290,7 @@ printk("smb_find_in_cache: cache %p, looking for pos=%ld\n", cachep, pos); nent = pos - next_pos; next_pos += index->num_entries; if (pos >= next_pos) - continue; + continue; /* * The entry is in this block. Note: we return * then name as a reference with _no_ null byte. @@ -242,8 +301,9 @@ printk("smb_find_in_cache: cache %p, looking for pos=%ld\n", cachep, pos); offset = block->cb_data.table[nent].offset; entry->name = &block->cb_data.names[offset]; #ifdef SMBFS_DEBUG_VERBOSE -printk("smb_find_in_cache: found %s, len=%d, pos=%ld\n", -entry->name, entry->len, pos); +printk("smb_find_in_cache: found "); +printk_name(entry->name, entry->len); +printk(", len=%d, pos=%ld\n", entry->len, pos); #endif break; } @@ -312,4 +372,3 @@ smb_invalid_dir_cache(struct inode * dir) dir->u.smbfs_i.cache_valid &= ~SMB_F_CACHEVALID; dir->u.smbfs_i.oldmtime = 0; } - |