diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-21 22:00:56 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-21 22:00:56 +0000 |
commit | 168660f24dfc46c2702acbe4701a446f42a59578 (patch) | |
tree | f431368afbf6b1b71809cf3fd904d800ea126f4d /fs/smbfs | |
parent | 6420f767924fa73b0ea267864d96820815f4ba5a (diff) |
Merge with Linux 2.4.0-test5-pre3.
Diffstat (limited to 'fs/smbfs')
-rw-r--r-- | fs/smbfs/ChangeLog | 40 | ||||
-rw-r--r-- | fs/smbfs/Makefile | 9 | ||||
-rw-r--r-- | fs/smbfs/cache.c | 86 | ||||
-rw-r--r-- | fs/smbfs/dir.c | 154 | ||||
-rw-r--r-- | fs/smbfs/file.c | 122 | ||||
-rw-r--r-- | fs/smbfs/inode.c | 68 | ||||
-rw-r--r-- | fs/smbfs/ioctl.c | 35 | ||||
-rw-r--r-- | fs/smbfs/proc.c | 529 | ||||
-rw-r--r-- | fs/smbfs/smb_debug.h | 34 | ||||
-rw-r--r-- | fs/smbfs/sock.c | 145 |
10 files changed, 575 insertions, 647 deletions
diff --git a/fs/smbfs/ChangeLog b/fs/smbfs/ChangeLog new file mode 100644 index 000000000..c47cc1417 --- /dev/null +++ b/fs/smbfs/ChangeLog @@ -0,0 +1,40 @@ +ChangeLog for smbfs. + +2000-07-15 Urban Widmark <urban@svenskatest.se> + + * *.c: more debug (%.*s) & indent fixes + +2000-06-24: Matt Maynard <matthewm@corel.com> + + * dir.c: dentry->d_inode->i_mtime isn't updated for all servers + (NT?) and all operations (mv oldfile.txt newfile.txt) Removed for + less efficient but better working directory cache. + * proc.c: included aDIR smbclient fix for renaming directories on + OS/2 servers (win95/98?) (orig by John Janosik) + +2000-07-01 Urban Widmark <urban@svenskatest.se> + + * *.c: replace ugly #ifdef's with less ugly debug macros. + +2000-01-?? cpg@aladdin.de + + * proc.c: added posix semantics for unlink + +1999-11-16 Andrew Tridgell + + * proc.c: use level 260 for most conns, or level 1 for <NT1 + * proc.c: don't sleep every time with win95 on a FINDNEXT + * proc.c: fixed loop_count bug + * proc.c: got rid of resume_key + +[there are a few missing here :) ] + +1997-09-28 Riccardo Facchetti + + * proc.c: Fixed smb_d_path [now smb_build_path()] to be non-recursive + +1996-06-28 Yuri Per + + * proc.c: Fixed long file name support (smb_proc_readdir_long) + +You are in the wrong end for adding new entries. New entries at the top. diff --git a/fs/smbfs/Makefile b/fs/smbfs/Makefile index 202cc5932..3ea59f6cc 100644 --- a/fs/smbfs/Makefile +++ b/fs/smbfs/Makefile @@ -11,8 +11,13 @@ O_TARGET := smbfs.o O_OBJS := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o M_OBJS := $(O_TARGET) -# If you want debugging output, please uncomment the following line +# If you want debugging output, you may add these flags to the EXTRA_CFLAGS +# SMBFS_PARANOIA should normally be enabled. -# EXTRA_CFLAGS += -DDEBUG -DDEBUG_SMB_MALLOC=1 +EXTRA_CFLAGS += -DSMBFS_PARANOIA +#EXTRA_CFLAGS += -DSMBFS_DEBUG +#EXTRA_CFLAGS += -DSMBFS_DEBUG_VERBOSE +#EXTRA_CFLAGS += -DDEBUG_SMB_MALLOC +#EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP include $(TOPDIR)/Rules.make diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c index 46354e5a5..0b42c2387 100644 --- a/fs/smbfs/cache.c +++ b/fs/smbfs/cache.c @@ -6,6 +6,8 @@ * Routines to support directory cacheing using the page cache. * Right now this only works for smbfs, but will be generalized * for use with other filesystems. + * + * Please add a note about your changes to smbfs in the ChangeLog file. */ #include <linux/sched.h> @@ -18,25 +20,8 @@ #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]; +#include "smb_debug.h" - if(len > 80) - len = 80; - strncpy(buf, name, len); - buf[len] = 0; - printk("%s", buf); -} -#endif static inline struct address_space * get_cache_inode(struct cache_head *cachep) @@ -101,9 +86,7 @@ smb_free_cache_blocks(struct cache_head * cachep) struct page * page; int i; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_free_cache_blocks: freeing %d blocks\n", cachep->pages); -#endif + VERBOSE("freeing %d blocks\n", cachep->pages); for (i = 0; i < cachep->pages; i++, index++) { if (!index->block) continue; @@ -122,9 +105,7 @@ void smb_free_dircache(struct cache_head * cachep) { struct page *page; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_free_dircache: freeing cache\n"); -#endif + VERBOSE("freeing cache\n"); smb_free_cache_blocks(cachep); page = page_cache_entry((unsigned long) cachep); kunmap(page); @@ -139,9 +120,7 @@ printk("smb_free_dircache: freeing cache\n"); void smb_init_dircache(struct cache_head * cachep) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_init_dircache: initializing cache, %d blocks\n", cachep->pages); -#endif + VERBOSE("initializing cache, %d blocks\n", cachep->pages); smb_free_cache_blocks(cachep); memset(cachep, 0, sizeof(struct cache_head)); } @@ -162,12 +141,9 @@ smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry, unsigned int nent, offset, len = entry->len; unsigned int needed = len + sizeof(struct cache_entry); -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_add_to_cache: cache %p, status %d, adding ", - mapping, cachep->status); -printk_name(entry->name, entry->len); -printk(" at %ld\n", fpos); -#endif + VERBOSE("cache %p, status %d, adding %.*s at %ld\n", + mapping, cachep->status, entry->len, entry->name, fpos); + /* * Don't do anything if we've had an error ... */ @@ -192,12 +168,9 @@ printk(" at %ld\n", fpos); block->cb_data.table[nent].offset = offset; block->cb_data.table[nent].ino = entry->ino; cachep->entries++; -#ifdef SMBFS_DEBUG_VERBOSE -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 + + VERBOSE("added entry %.*s, len=%d, pos=%ld, entries=%d\n", + entry->len, entry->name, len, fpos, cachep->entries); return; } /* @@ -238,9 +211,8 @@ smb_find_in_cache(struct cache_head * cachep, off_t pos, unsigned int i, nent, offset = 0; off_t next_pos = 2; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_find_in_cache: cache %p, looking for pos=%ld\n", cachep, pos); -#endif + VERBOSE("smb_find_in_cache: cache %p, looking for pos=%ld\n", + cachep, pos); for (i = 0; i < cachep->pages; i++, index++) { if (pos < next_pos) @@ -258,11 +230,9 @@ printk("smb_find_in_cache: cache %p, looking for pos=%ld\n", cachep, pos); entry->len = block->cb_data.table[nent].namelen; offset = block->cb_data.table[nent].offset; entry->name = &block->cb_data.names[offset]; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_find_in_cache: found "); -printk_name(entry->name, entry->len); -printk(", len=%d, pos=%ld\n", entry->len, pos); -#endif + + VERBOSE("found %.*s, len=%d, pos=%ld\n", + entry->len, entry->name, entry->len, pos); break; } return offset; @@ -274,10 +244,8 @@ smb_refill_dircache(struct cache_head * cachep, struct dentry *dentry) struct inode * inode = dentry->d_inode; int result; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_refill_dircache: cache %s/%s, blocks=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, cachep->pages); -#endif + VERBOSE("smb_refill_dircache: cache %s/%s, blocks=%d\n", + DENTRY_PATH(dentry), cachep->pages); /* * Fill the cache, starting at position 2. */ @@ -286,9 +254,7 @@ retry: result = smb_proc_readdir(dentry, 2, cachep); if (result < 0) { -#ifdef SMBFS_PARANOIA -printk("smb_refill_dircache: readdir failed, result=%d\n", result); -#endif + PARANOIA("readdir failed, result=%d\n", result); goto out; } @@ -298,9 +264,7 @@ printk("smb_refill_dircache: readdir failed, result=%d\n", result); */ if (!(inode->u.smbfs_i.cache_valid & SMB_F_CACHEVALID)) { -#ifdef SMBFS_PARANOIA -printk("smb_refill_dircache: cache invalidated, retrying\n"); -#endif + PARANOIA("cache invalidated, retrying\n"); goto retry; } @@ -309,12 +273,8 @@ printk("smb_refill_dircache: cache invalidated, retrying\n"); { cachep->valid = 1; } -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_refill_cache: cache %s/%s status=%d, entries=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -cachep->status, cachep->entries); -#endif - + VERBOSE("cache %s/%s status=%d, entries=%d\n", + DENTRY_PATH(dentry), cachep->status, cachep->entries); out: return result; } diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 7f08aa22d..807d8f2e3 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -4,19 +4,20 @@ * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke * Copyright (C) 1997 by Volker Lendecke * + * Please add a note about your changes to smbfs in the ChangeLog file. */ #include <linux/sched.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/smp_lock.h> +#include <linux/ctype.h> #include <linux/smb_fs.h> #include <linux/smbno.h> -#define SMBFS_PARANOIA 1 -/* #define SMBFS_DEBUG_VERBOSE 1 */ -/* #define pr_debug printk */ +#include "smb_debug.h" + #define SMBFS_MAX_AGE 5*HZ static int smb_readdir(struct file *, void *, filldir_t); @@ -58,10 +59,23 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir) struct cache_head *cachep; int result; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_readdir: reading %s/%s, f_pos=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, (int) filp->f_pos); -#endif + VERBOSE("reading %s/%s, f_pos=%d\n", + DENTRY_PATH(dentry), (int) filp->f_pos); + + result = 0; + switch ((unsigned int) filp->f_pos) + { + case 0: + if (filldir(dirent, ".", 1, 0, dir->i_ino) < 0) + goto out; + filp->f_pos = 1; + case 1: + if (filldir(dirent, "..", 2, 1, + dentry->d_parent->d_inode->i_ino) < 0) + goto out; + filp->f_pos = 2; + } + /* * Make sure our inode is up-to-date. */ @@ -75,10 +89,16 @@ dentry->d_parent->d_name.name, dentry->d_name.name, (int) filp->f_pos); cachep = smb_get_dircache(dentry); if (!cachep) goto out; + /* * Make sure the cache is up-to-date. + * + * To detect changes on the server we refill on each "new" access. + * + * Directory mtime would be nice to use for finding changes, + * unfortunately some servers (NT4) doesn't update on local changes. */ - if (!cachep->valid) + if (!cachep->valid || filp->f_pos == 2) { result = smb_refill_dircache(cachep, dentry); if (result) @@ -86,18 +106,6 @@ dentry->d_parent->d_name.name, dentry->d_name.name, (int) filp->f_pos); } result = 0; - switch ((unsigned int) filp->f_pos) - { - case 0: - if (filldir(dirent, ".", 1, 0, dir->i_ino) < 0) - goto out_free; - filp->f_pos = 1; - case 1: - if (filldir(dirent, "..", 2, 1, - dentry->d_parent->d_inode->i_ino) < 0) - goto out_free; - filp->f_pos = 2; - } while (1) { @@ -143,10 +151,10 @@ smb_dir_open(struct inode *dir, struct file *file) struct dentry *dentry = file->f_dentry; struct smb_sb_info *server; int error = 0; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_dir_open: (%s/%s)\n", dentry->d_parent->d_name.name, -file->f_dentry->d_name.name); -#endif + + VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name, + file->f_dentry->d_name.name); + /* * Directory timestamps in the core protocol aren't updated * when a file is added, so we give them a very short TTL. @@ -199,39 +207,27 @@ smb_lookup_validate(struct dentry * dentry, int flags) */ valid = (age <= SMBFS_MAX_AGE); #ifdef SMBFS_DEBUG_VERBOSE -if (!valid) -printk("smb_lookup_validate: %s/%s not valid, age=%lu\n", -dentry->d_parent->d_name.name, dentry->d_name.name, age); + if (!valid) + VERBOSE("%s/%s not valid, age=%lu\n", + DENTRY_PATH(dentry), age); #endif - if (inode) - { + if (inode) { lock_kernel(); - if (is_bad_inode(inode)) - { -#ifdef SMBFS_PARANOIA -printk("smb_lookup_validate: %s/%s has dud inode\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif + if (is_bad_inode(inode)) { + PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry)); valid = 0; } else if (!valid) valid = (smb_revalidate_inode(dentry) == 0); unlock_kernel(); - } else - { - /* - * What should we do for negative dentries? - */ + } else { + /* + * What should we do for negative dentries? + */ } return valid; } -/* - * XXX: It would be better to use the tolower from linux/ctype.h, - * but _ctype is needed and it is not exported. - */ -#define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-('A'-'a') : (c)) - static int smb_hash_dentry(struct dentry *dir, struct qstr *this) { @@ -270,19 +266,14 @@ out: static int smb_delete_dentry(struct dentry * dentry) { - if (dentry->d_inode) - { - if (is_bad_inode(dentry->d_inode)) - { -#ifdef SMBFS_PARANOIA -printk("smb_delete_dentry: bad inode, unhashing %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif + if (dentry->d_inode) { + if (is_bad_inode(dentry->d_inode)) { + PARANOIA("bad inode, unhashing %s/%s\n", + DENTRY_PATH(dentry)); return 1; } - } else - { - /* N.B. Unhash negative dentries? */ + } else { + /* N.B. Unhash negative dentries? */ } return 0; } @@ -295,8 +286,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name); void smb_renew_times(struct dentry * dentry) { - for (;;) - { + for (;;) { dentry->d_time = jiffies; if (IS_ROOT(dentry)) break; @@ -317,9 +307,9 @@ smb_lookup(struct inode *dir, struct dentry *dentry) error = smb_proc_getattr(dentry, &finfo); #ifdef SMBFS_PARANOIA -if (error && error != -ENOENT) -printk("smb_lookup: find %s/%s failed, error=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, error); + if (error && error != -ENOENT) + PARANOIA("find %s/%s failed, error=%d\n", + DENTRY_PATH(dentry), error); #endif inode = NULL; @@ -354,10 +344,8 @@ smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id) int error; struct smb_fattr fattr; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_instantiate: file %s/%s, fileid=%u\n", -dentry->d_parent->d_name.name, dentry->d_name.name, fileid); -#endif + VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid); + error = smb_proc_getattr(dentry, &fattr); if (error) goto out_close; @@ -383,10 +371,8 @@ out_no_inode: out_close: if (have_id) { -#ifdef SMBFS_PARANOIA -printk("smb_instantiate: %s/%s failed, error=%d, closing %u\n", -dentry->d_parent->d_name.name, dentry->d_name.name, error, fileid); -#endif + PARANOIA("%s/%s failed, error=%d, closing %u\n", + DENTRY_PATH(dentry), error, fileid); smb_close_fileid(dentry, fileid); } goto out; @@ -399,22 +385,15 @@ smb_create(struct inode *dir, struct dentry *dentry, int mode) __u16 fileid; int error; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_create: creating %s/%s, mode=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, mode); -#endif + VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode); smb_invalid_dir_cache(dir); error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid); - if (!error) - { + if (!error) { error = smb_instantiate(dentry, fileid, 1); - } else - { -#ifdef SMBFS_PARANOIA -printk("smb_create: %s/%s failed, error=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, error); -#endif + } else { + PARANOIA("%s/%s failed, error=%d\n", + DENTRY_PATH(dentry), error); } return error; } @@ -427,8 +406,7 @@ smb_mkdir(struct inode *dir, struct dentry *dentry, int mode) smb_invalid_dir_cache(dir); error = smb_proc_mkdir(dentry); - if (!error) - { + if (!error) { error = smb_instantiate(dentry, 0, 0); } return error; @@ -452,7 +430,6 @@ smb_rmdir(struct inode *dir, struct dentry *dentry) if (!d_unhashed(dentry)) goto out; - smb_invalid_dir_cache(dir); error = smb_proc_rmdir(dentry); out: @@ -469,7 +446,6 @@ smb_unlink(struct inode *dir, struct dentry *dentry) */ smb_close(dentry->d_inode); - smb_invalid_dir_cache(dir); error = smb_proc_unlink(dentry); if (!error) smb_renew_times(dentry); @@ -494,10 +470,8 @@ smb_rename(struct inode *old_dir, struct dentry *old_dentry, error = smb_proc_unlink(new_dentry); if (error) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_rename: unlink %s/%s, error=%d\n", -new_dentry->d_parent->d_name.name, new_dentry->d_name.name, error); -#endif + VERBOSE("unlink %s/%s, error=%d\n", + DENTRY_PATH(new_dentry), error); goto out; } /* FIXME */ diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 247bae08f..ec709e3e3 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke * Copyright (C) 1997 by Volker Lendecke * + * Please add a note about your changes to smbfs in the ChangeLog file. */ #include <linux/sched.h> @@ -22,17 +23,12 @@ #include <linux/smbno.h> #include <linux/smb_fs.h> -#define SMBFS_PARANOIA 1 -/* #define SMBFS_DEBUG_VERBOSE 1 */ -/* #define pr_debug printk */ +#include "smb_debug.h" static int smb_fsync(struct file *file, struct dentry * dentry, int datasync) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_fsync: sync file %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif + VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry)); return 0; } @@ -48,21 +44,14 @@ smb_readpage_sync(struct dentry *dentry, struct page *page) int count = PAGE_SIZE; int result; - /* We can't replace this with ClearPageError. why? is it a problem? - fs/buffer.c:brw_page does the same. */ - /* ClearPageError(page); */ + VERBOSE("file %s/%s, count=%d@%ld, rsize=%d\n", + DENTRY_PATH(dentry), count, offset, rsize); -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_readpage_sync: file %s/%s, count=%d@%ld, rsize=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, rsize); -#endif result = smb_open(dentry, SMB_O_RDONLY); if (result < 0) { -#ifdef SMBFS_PARANOIA -printk("smb_readpage_sync: %s/%s open failed, error=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, result); -#endif + PARANOIA("%s/%s open failed, error=%d\n", + DENTRY_PATH(dentry), result); goto io_error; } @@ -91,17 +80,16 @@ io_error: return result; } +/* + * We are called with the page locked and the caller unlocks. + */ static int smb_readpage(struct file *file, struct page *page) { int error; struct dentry *dentry = file->f_dentry; - pr_debug("SMB: smb_readpage %08lx\n", page_address(page)); -#ifdef SMBFS_PARANOIA - if (!PageLocked(page)) - printk("smb_readpage: page not already locked!\n"); -#endif + DEBUG1("readpage %08lx\n", page_address(page)); get_page(page); error = smb_readpage_sync(dentry, page); @@ -123,10 +111,8 @@ smb_writepage_sync(struct dentry *dentry, struct page *page, int result, written = 0; offset += page->index << PAGE_CACHE_SHIFT; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_writepage_sync: file %s/%s, count=%d@%ld, wsize=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, wsize); -#endif + VERBOSE("file %s/%s, count=%d@%ld, wsize=%d\n", + DENTRY_PATH(dentry), count, offset, wsize); do { if (count < wsize) @@ -137,8 +123,9 @@ dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, wsize); break; /* N.B. what if result < wsize?? */ #ifdef SMBFS_PARANOIA -if (result < wsize) -printk("smb_writepage_sync: short write, wsize=%d, result=%d\n", wsize, result); + if (result < wsize) + PARANOIA("short write, wsize=%d, result=%d\n", + wsize, result); #endif buffer += wsize; offset += wsize; @@ -187,13 +174,13 @@ do_it: } static int -smb_updatepage(struct file *file, struct page *page, unsigned long offset, unsigned int count) +smb_updatepage(struct file *file, struct page *page, unsigned long offset, + unsigned int count) { struct dentry *dentry = file->f_dentry; - pr_debug("SMBFS: smb_updatepage(%s/%s %d@%ld)\n", - dentry->d_parent->d_name.name, dentry->d_name.name, - count, (page->index << PAGE_CACHE_SHIFT)+offset); + DEBUG1("(%s/%s %d@%ld)\n", DENTRY_PATH(dentry), + count, (page->index << PAGE_CACHE_SHIFT)+offset); return smb_writepage_sync(dentry, page, offset, count); } @@ -204,27 +191,21 @@ smb_file_read(struct file * file, char * buf, size_t count, loff_t *ppos) struct dentry * dentry = file->f_dentry; ssize_t status; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_file_read: file %s/%s, count=%lu@%lu\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -(unsigned long) count, (unsigned long) *ppos); -#endif + VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), + (unsigned long) count, (unsigned long) *ppos); status = smb_revalidate_inode(dentry); if (status) { -#ifdef SMBFS_PARANOIA -printk("smb_file_read: %s/%s validation failed, error=%Zd\n", -dentry->d_parent->d_name.name, dentry->d_name.name, status); -#endif + PARANOIA("%s/%s validation failed, error=%Zd\n", + DENTRY_PATH(dentry), status); goto out; } -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_file_read: before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n", -dentry->d_inode->i_size, dentry->d_inode->i_nrpages, dentry->d_inode->i_flags, -dentry->d_inode->i_atime); -#endif + VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n", + (long)dentry->d_inode->i_size, + dentry->d_inode->i_flags, dentry->d_inode->i_atime); + status = generic_file_read(file, buf, count, ppos); out: return status; @@ -236,18 +217,14 @@ smb_file_mmap(struct file * file, struct vm_area_struct * vma) struct dentry * dentry = file->f_dentry; int status; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_file_mmap: file %s/%s, address %lu - %lu\n", -dentry->d_parent->d_name.name, dentry->d_name.name, vma->vm_start, vma->vm_end); -#endif + VERBOSE("file %s/%s, address %lu - %lu\n", + DENTRY_PATH(dentry), vma->vm_start, vma->vm_end); status = smb_revalidate_inode(dentry); if (status) { -#ifdef SMBFS_PARANOIA -printk("smb_file_mmap: %s/%s validation failed, error=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, status); -#endif + PARANOIA("%s/%s validation failed, error=%d\n", + DENTRY_PATH(dentry), status); goto out; } status = generic_file_mmap(file, vma); @@ -264,13 +241,15 @@ out: * If the writer ends up delaying the write, the writer needs to * increment the page use counts until he is done with the page. */ -static int smb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) +static int smb_prepare_write(struct file *file, struct page *page, + unsigned offset, unsigned to) { kmap(page); return 0; } -static int smb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) +static int smb_commit_write(struct file *file, struct page *page, + unsigned offset, unsigned to) { int status; @@ -298,20 +277,16 @@ smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) struct dentry * dentry = file->f_dentry; ssize_t result; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_file_write: file %s/%s, count=%lu@%lu, pages=%ld\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -(unsigned long) count, (unsigned long) *ppos, dentry->d_inode->i_nrpages); -#endif + VERBOSE("file %s/%s, count=%lu@%lu\n", + DENTRY_PATH(dentry), + (unsigned long) count, (unsigned long) *ppos); result = smb_revalidate_inode(dentry); if (result) { -#ifdef SMBFS_PARANOIA -printk("smb_file_write: %s/%s validation failed, error=%Zd\n", -dentry->d_parent->d_name.name, dentry->d_name.name, result); -#endif - goto out; + PARANOIA("%s/%s validation failed, error=%Zd\n", + DENTRY_PATH(dentry), result); + goto out; } result = smb_open(dentry, SMB_O_WRONLY); @@ -321,11 +296,9 @@ dentry->d_parent->d_name.name, dentry->d_name.name, result); if (count > 0) { result = generic_file_write(file, buf, count, ppos); -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_file_write: pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", -(long) file->f_pos, dentry->d_inode->i_size, dentry->d_inode->i_mtime, -dentry->d_inode->i_atime); -#endif + VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", + (long) file->f_pos, (long) dentry->d_inode->i_size, + dentry->d_inode->i_mtime, dentry->d_inode->i_atime); } out: return result; @@ -361,9 +334,8 @@ smb_file_permission(struct inode *inode, int mask) int mode = inode->i_mode; int error = 0; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_file_permission: mode=%x, mask=%x\n", mode, mask); -#endif + VERBOSE("mode=%x, mask=%x\n", mode, mask); + /* Look at user permissions */ mode >>= 6; if ((mode & 7 & mask) != mask) diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index caa8cc533..d7cb992b8 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke * Copyright (C) 1997 by Volker Lendecke * + * Please add a note about your changes to smbfs in the ChangeLog file. */ #include <linux/module.h> @@ -27,8 +28,7 @@ #include <asm/system.h> #include <asm/uaccess.h> -#define SMBFS_PARANOIA 1 -/* #define SMBFS_DEBUG_VERBOSE 1 */ +#include "smb_debug.h" static void smb_delete_inode(struct inode *); static void smb_put_super(struct super_block *); @@ -66,7 +66,7 @@ smb_iget(struct super_block *sb, struct smb_fattr *fattr) { struct inode *result; - pr_debug("smb_iget: %p\n", fattr); + DEBUG1("smb_iget: %p\n", fattr); result = get_empty_inode(); if (!result) @@ -154,9 +154,7 @@ smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) void smb_invalidate_inodes(struct smb_sb_info *server) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_invalidate_inodes\n"); -#endif + VERBOSE("\n"); shrink_dcache_sb(SB_of(server)); invalidate_inodes(SB_of(server)); } @@ -191,11 +189,10 @@ smb_refresh_inode(struct dentry *dentry) * To limit damage, mark the inode as bad so that * subsequent lookup validations will fail. */ -#ifdef SMBFS_PARANOIA -printk("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -inode->i_mode, fattr.f_mode); -#endif + PARANOIA("%s/%s changed mode, %07o to %07o\n", + DENTRY_PATH(dentry), + inode->i_mode, fattr.f_mode); + fattr.f_mode = inode->i_mode; /* save mode */ make_bad_inode(inode); inode->i_mode = fattr.f_mode; /* restore mode */ @@ -226,7 +223,7 @@ smb_revalidate_inode(struct dentry *dentry) time_t last_time; int error = 0; - pr_debug("smb_revalidate_inode\n"); + DEBUG1("smb_revalidate_inode\n"); /* * If this is a file opened with write permissions, * the inode will be up-to-date. @@ -243,10 +240,8 @@ smb_revalidate_inode(struct dentry *dentry) */ if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10)) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_revalidate_inode: up-to-date, jiffies=%lu, oldtime=%lu\n", -jiffies, inode->u.smbfs_i.oldmtime); -#endif + VERBOSE("up-to-date, jiffies=%lu, oldtime=%lu\n", + jiffies, inode->u.smbfs_i.oldmtime); goto out; } @@ -258,11 +253,10 @@ jiffies, inode->u.smbfs_i.oldmtime); error = smb_refresh_inode(dentry); if (error || inode->i_mtime != last_time) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_revalidate: %s/%s changed, old=%ld, new=%ld\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -(long) last_time, (long) inode->i_mtime); -#endif + VERBOSE("%s/%s changed, old=%ld, new=%ld\n", + DENTRY_PATH(dentry), + (long) last_time, (long) inode->i_mtime); + if (!S_ISDIR(inode->i_mode)) invalidate_inode_pages(inode); else @@ -280,11 +274,10 @@ out: static void smb_delete_inode(struct inode *ino) { - pr_debug("smb_delete_inode\n"); + DEBUG1("\n"); lock_kernel(); if (smb_close(ino)) - printk("smb_delete_inode: could not close inode %ld\n", - ino->i_ino); + PARANOIA("could not close inode %ld\n", ino->i_ino); unlock_kernel(); clear_inode(ino); } @@ -348,7 +341,8 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) if (!mnt) goto out_no_mount; *mnt = *((struct smb_mount_data *) raw_data); - /* ** temp ** pass config flags in file mode */ + /* FIXME: passes config flags in high bits of file mode. Should be a + separate flags field. (but smbmount includes kernel headers ...) */ mnt->version = (mnt->file_mode >> 9); mnt->file_mode &= (S_IRWXU | S_IRWXG | S_IRWXO); mnt->file_mode |= S_IFREG; @@ -357,6 +351,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) sb->u.smbfs_sb.mnt = mnt; /* * Display the enabled options + * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2) */ if (mnt->version & SMB_FIX_OLDATTR) printk("SMBFS: Using core getattr (Win 95 speedup)\n"); @@ -391,7 +386,7 @@ out_wrong_data: printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION); goto out_fail; out_no_data: - printk("smb_read_super: missing data argument\n"); + printk(KERN_ERR "smb_read_super: missing data argument\n"); out_fail: return NULL; } @@ -434,11 +429,9 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr) if ((attr->ia_valid & ATTR_SIZE) != 0) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_notify_change: changing %s/%s, old size=%ld, new size=%ld\n", -dentry->d_parent->d_name.name, dentry->d_name.name, -(long) inode->i_size, (long) attr->ia_size); -#endif + VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n", + DENTRY_PATH(dentry), + (long) inode->i_size, (long) attr->ia_size); error = smb_open(dentry, O_WRONLY); if (error) goto out; @@ -484,10 +477,8 @@ dentry->d_parent->d_name.name, dentry->d_name.name, */ if ((attr->ia_valid & ATTR_MODE) != 0) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_notify_change: %s/%s mode change, old=%x, new=%lx\n", -dentry->d_parent->d_name.name, dentry->d_name.name, fattr.f_mode,attr->ia_mode); -#endif + VERBOSE("%s/%s mode change, old=%x, new=%x\n", + DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode); changed = 0; if (attr->ia_mode & S_IWUSR) { @@ -496,8 +487,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, fattr.f_mode,attr->ia_mode); fattr.attr &= ~aRONLY; changed = 1; } - } else - { + } else { if (!(fattr.attr & aRONLY)) { fattr.attr |= aRONLY; @@ -530,7 +520,7 @@ static DECLARE_FSTYPE( smb_fs_type, "smbfs", smb_read_super, 0); static int __init init_smb_fs(void) { - pr_debug("smbfs: init_module called\n"); + DEBUG1("registering ...\n"); #ifdef DEBUG_SMB_MALLOC smb_malloced = 0; @@ -543,7 +533,7 @@ static int __init init_smb_fs(void) static void __exit exit_smb_fs(void) { - pr_debug("smbfs: cleanup_module called\n"); + DEBUG1("unregistering ...\n"); unregister_filesystem(&smb_fs_type); #ifdef DEBUG_SMB_MALLOC printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced); diff --git a/fs/smbfs/ioctl.c b/fs/smbfs/ioctl.c index dee105a5e..73dc857b6 100644 --- a/fs/smbfs/ioctl.c +++ b/fs/smbfs/ioctl.c @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996 by Volker Lendecke * Copyright (C) 1997 by Volker Lendecke * + * Please add a note about your changes to smbfs in the ChangeLog file. */ #include <linux/errno.h> @@ -23,39 +24,29 @@ smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { struct smb_sb_info *server = SMB_SERVER(inode); + struct smb_conn_opt opt; int result = -EINVAL; - switch (cmd) - { + switch (cmd) { case SMB_IOC_GETMOUNTUID: - result = put_user(NEW_TO_OLD_UID(server->mnt->mounted_uid), (uid16_t *) arg); + result = put_user(NEW_TO_OLD_UID(server->mnt->mounted_uid), + (uid16_t *) arg); break; case SMB_IOC_GETMOUNTUID32: result = put_user(server->mnt->mounted_uid, (uid_t *) arg); break; case SMB_IOC_NEWCONN: - { - struct smb_conn_opt opt; - - if (arg) - { - result = -EFAULT; - if (!copy_from_user(&opt, (void *)arg, sizeof(opt))) - result = smb_newconn(server, &opt); - } - else - { -#if 0 - /* obsolete option ... print a warning */ - printk("SMBFS: ioctl deprecated, please upgrade " - "smbfs package\n"); -#endif - result = 0; - } + /* require an argument == the mount data, else it is EINVAL */ + if (!arg) + break; + + result = -EFAULT; + if (!copy_from_user(&opt, (void *)arg, sizeof(opt))) + result = smb_newconn(server, &opt); break; - } default: } + return result; } diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index 669deb0d7..68922335c 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c @@ -4,9 +4,7 @@ * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke * Copyright (C) 1997 by Volker Lendecke * - * 28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per - * 28/09/97 - Fixed smb_d_path [now smb_build_path()] to be non-recursive - * by Riccardo Facchetti + * Please add a note about your changes to smbfs in the ChangeLog file. */ #include <linux/types.h> @@ -25,10 +23,11 @@ #include <asm/string.h> -#define SMBFS_PARANOIA 1 -/* #define SMBFS_DEBUG_TIMESTAMP 1 */ -/* #define SMBFS_DEBUG_VERBOSE 1 */ -/* #define pr_debug printk */ +#include "smb_debug.h" + +/* Features. Undefine if they cause problems, this should perhaps be a + config option. */ +#define SMBFS_POSIX_UNLINK 1 #define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN) #define SMB_CMD(packet) (*(packet+8)) @@ -39,16 +38,15 @@ #define SMB_DIRINFO_SIZE 43 #define SMB_STATUS_SIZE 21 -/* yes, this deliberately has two parts */ -#define DENTRY_PATH(dentry) (dentry)->d_parent->d_name.name,(dentry)->d_name.name - -static int smb_proc_setattr_ext(struct smb_sb_info *, struct inode *, - struct smb_fattr *); -static inline int -min(int a, int b) -{ - return a < b ? a : b; -} +static int +smb_proc_setattr_ext(struct smb_sb_info *, struct inode *, + struct smb_fattr *); +static int +smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry, + __u16 attr); +static int +smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir, + struct smb_fattr *fattr); static void str_upper(char *name, int len) @@ -72,7 +70,9 @@ str_lower(char *name, int len) } } -static void reverse_string(char *buf, int len) { +/* reverse a string inline. This is used by the dircache walking routines */ +static void reverse_string(char *buf, int len) +{ char c; char *end = buf+len-1; @@ -225,12 +225,10 @@ date_unix2dos(struct smb_sb_info *server, if ((year + 3) / 4 + 365 * year > day) year--; day -= (year + 3) / 4 + 365 * year; - if (day == 59 && !(year & 3)) - { + if (day == 59 && !(year & 3)) { nl_day = day; month = 2; - } else - { + } else { nl_day = (year & 3) || day <= 59 ? day : day - 1; for (month = 0; month < 12; month++) if (day_n[month] > nl_day) @@ -287,16 +285,16 @@ smb_verify(__u8 * packet, int command, int wct, int bcc) return 0; bad_command: - printk("smb_verify: command=%x, SMB_CMD=%x??\n", - command, SMB_CMD(packet)); + printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n", + command, SMB_CMD(packet)); goto fail; bad_wct: - printk("smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n", - command, wct, SMB_WCT(packet)); + printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n", + command, wct, SMB_WCT(packet)); goto fail; bad_bcc: - printk("smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n", - command, bcc, SMB_BCC(packet)); + printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n", + command, bcc, SMB_BCC(packet)); fail: return -EIO; } @@ -328,10 +326,10 @@ smb_get_rsize(struct smb_sb_info *server) { int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2; int size = smb_get_xmitsize(server, overhead); -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_get_rsize: packet=%d, xmit=%d, size=%d\n", -server->packet_size, server->opt.max_xmit, size); -#endif + + VERBOSE("packet=%d, xmit=%d, size=%d\n", + server->packet_size, server->opt.max_xmit, size); + return size; } @@ -343,10 +341,10 @@ smb_get_wsize(struct smb_sb_info *server) { int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2; int size = smb_get_xmitsize(server, overhead); -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_get_wsize: packet=%d, xmit=%d, size=%d\n", -server->packet_size, server->opt.max_xmit, size); -#endif + + VERBOSE("packet=%d, xmit=%d, size=%d\n", + server->packet_size, server->opt.max_xmit, size); + return size; } @@ -357,10 +355,8 @@ smb_errno(struct smb_sb_info *server) int error = server->err; char *class = "Unknown"; -#ifdef SMBFS_DEBUG_VERBOSE - printk("smb_errno: errcls %d code %d from command 0x%x\n", + VERBOSE("errcls %d code %d from command 0x%x\n", errcls, error, SMB_CMD(server->packet)); -#endif if (errcls == ERRDOS) switch (error) @@ -463,8 +459,8 @@ smb_errno(struct smb_sb_info *server) class = "ERRCMD"; err_unknown: - printk("smb_errno: class %s, code %d from command 0x%x\n", - class, error, SMB_CMD(server->packet)); + printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n", + class, error, SMB_CMD(server->packet)); return EIO; } @@ -482,10 +478,10 @@ smb_unlock_server(struct smb_sb_info *server) /* * smb_retry: This function should be called when smb_request_ok has - indicated an error. If the error was indicated because the - connection was killed, we try to reconnect. If smb_retry returns 0, - the error was indicated for another reason, so a retry would not be - of any use. + * indicated an error. If the error was indicated because the + * connection was killed, we try to reconnect. If smb_retry returns 0, + * the error was indicated for another reason, so a retry would not be + * of any use. * N.B. The server must be locked for this call. */ static int @@ -501,7 +497,7 @@ smb_retry(struct smb_sb_info *server) if (pid == 0) { - printk("smb_retry: no connection process\n"); + printk(KERN_ERR "smb_retry: no connection process\n"); server->state = CONN_RETRIED; goto out; } @@ -517,29 +513,28 @@ smb_retry(struct smb_sb_info *server) error = kill_proc(pid, SIGUSR1, 1); if (error) { - printk("smb_retry: signal failed, error=%d\n", error); + printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error); goto out_restore; } -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_retry: signalled pid %d, waiting for new connection\n", -server->conn_pid); -#endif + VERBOSE("signalled pid %d, waiting for new connection\n", + server->conn_pid); + /* * Wait for the new connection. */ interruptible_sleep_on_timeout(&server->wait, 5*HZ); if (signal_pending(current)) - printk("smb_retry: caught signal\n"); + printk(KERN_INFO "smb_retry: caught signal\n"); /* * Check for a valid connection. */ if (server->state == CONN_VALID) { -#ifdef SMBFS_PARANOIA -printk("smb_retry: new pid=%d, generation=%d\n", -server->conn_pid, server->generation); -#endif + /* This should be changed to VERBOSE, except many smbfs + problems is with the userspace daemon not reconnecting. */ + PARANOIA("sucessful, new pid=%d, generation=%d\n", + server->conn_pid, server->generation); result = 1; } @@ -570,20 +565,18 @@ smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc) /* Make sure we have a connection */ if (s->state != CONN_VALID) { - if (!smb_retry(s)) + if (!smb_retry(s)) goto out; } if (smb_request(s) < 0) { - pr_debug("smb_request failed\n"); + DEBUG1("smb_request failed\n"); goto out; } if (smb_valid_packet(s->packet) != 0) { -#ifdef SMBFS_PARANOIA -printk("smb_request_ok: invalid packet!\n"); -#endif + PARANOIA("invalid packet!\n"); goto out; } @@ -596,7 +589,7 @@ printk("smb_request_ok: invalid packet!\n"); { result = -smb_errno(s); if (!result) - printk("smb_request_ok: rcls=%d, err=%d mapped to 0\n", + printk(KERN_DEBUG "smb_request_ok: rcls=%d, err=%d mapped to 0\n", s->rcls, s->err); /* * Exit now even if the error was squashed ... @@ -624,9 +617,8 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) struct file *filp; int error; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_newconn: fd=%d, pid=%d\n", opt->fd, current->pid); -#endif + VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid); + /* * Make sure we don't already have a pid ... */ @@ -666,15 +658,13 @@ printk("smb_newconn: fd=%d, pid=%d\n", opt->fd, current->pid); !(server->opt.capabilities & SMB_CAP_NT_SMBS)) { server->mnt->version |= SMB_FIX_WIN95; #ifdef SMBFS_DEBUG_VERBOSE - printk("smb_newconn: detected WIN95 server\n"); + printk(KERN_NOTICE "smb_newconn: detected WIN95 server\n"); #endif } -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_newconn: protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n", - server->opt.protocol, server->opt.max_xmit, server->conn_pid, - server->opt.capabilities); -#endif + VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n", + server->opt.protocol, server->opt.max_xmit, server->conn_pid, + server->opt.capabilities); out: wake_up_interruptible(&server->wait); @@ -695,9 +685,10 @@ smb_setup_header(struct smb_sb_info * server, __u8 command, __u16 wct, __u16 bcc __u8 *p = server->packet; __u8 *buf = server->packet; -if (xmit_len > server->packet_size) -printk("smb_setup_header: Aieee, xmit len > packet! len=%d, size=%d\n", -xmit_len, server->packet_size); + if (xmit_len > server->packet_size) + printk(KERN_DEBUG "smb_setup_header: " + "Aieee, xmit len > packet! len=%d, size=%d\n", + xmit_len, server->packet_size); p = smb_encode_smb_length(p, xmit_len - 4); @@ -778,10 +769,8 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish) if (mode == read_write && (error == -EACCES || error == -ETXTBSY || error == -EROFS)) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_open: %s/%s R/W failed, error=%d, retrying R/O\n", - DENTRY_PATH(dentry), error); -#endif + VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n", + DENTRY_PATH(dentry), error); mode = read_only; goto retry; } @@ -813,7 +802,7 @@ smb_open(struct dentry *dentry, int wish) result = -ENOENT; if (!inode) { - printk("smb_open: no inode for dentry %s/%s\n", + printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n", DENTRY_PATH(dentry)); goto out; } @@ -828,10 +817,8 @@ smb_open(struct dentry *dentry, int wish) smb_unlock_server(server); if (result) { -#ifdef SMBFS_PARANOIA -printk("smb_open: %s/%s open failed, result=%d\n", - DENTRY_PATH(dentry), result); -#endif + PARANOIA("%s/%s open failed, result=%d\n", + DENTRY_PATH(dentry), result); goto out; } /* @@ -847,10 +834,8 @@ printk("smb_open: %s/%s open failed, result=%d\n", if (inode->u.smbfs_i.access != wish && inode->u.smbfs_i.access != SMB_O_RDWR) { -#ifdef SMBFS_PARANOIA -printk("smb_open: %s/%s access denied, access=%x, wish=%x\n", - DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish); -#endif + PARANOIA("%s/%s access denied, access=%x, wish=%x\n", + DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish); result = -EACCES; } out: @@ -991,10 +976,8 @@ smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data) result = data_len; out: -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_read: file %s/%s, count=%d, result=%d\n", - DENTRY_PATH(dentry), count, result); -#endif + VERBOSE("file %s/%s, count=%d, result=%d\n", + DENTRY_PATH(dentry), count, result); smb_unlock_server(server); return result; } @@ -1005,11 +988,10 @@ smb_proc_write(struct dentry *dentry, off_t offset, int count, const char *data) struct smb_sb_info *server = server_from_dentry(dentry); int result; __u8 *p; + + VERBOSE("file %s/%s, count=%d@%ld, packet_size=%d\n", + DENTRY_PATH(dentry), count, offset, server->packet_size); -#if SMBFS_DEBUG_VERBOSE -printk("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n", - DENTRY_PATH(dentry), count, offset, server->packet_size); -#endif smb_lock_server(server); p = smb_setup_header(server, SMBwrite, 5, count + 3); WSET(server->packet, smb_vwv0, dentry->d_inode->u.smbfs_i.fileid); @@ -1072,7 +1054,7 @@ smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry) retry: p = smb_setup_header(server, SMBmv, 1, 0); - WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN); + WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR); *p++ = 4; p = smb_encode_path(server, p, old_dentry, NULL); *p++ = 4; @@ -1134,10 +1116,37 @@ smb_proc_rmdir(struct dentry *dentry) return smb_proc_generic_command(dentry, SMBrmdir); } +#if SMBFS_POSIX_UNLINK +/* + * Removes readonly attribute from a file. Used by unlink to give posix + * semantics. + * Note: called with the server locked. + */ +static int +smb_set_rw(struct dentry *dentry,struct smb_sb_info *server) +{ + int result; + struct smb_fattr fattr; + + /* first get current attribute */ + result = smb_proc_do_getattr(server, dentry, &fattr); + if (result < 0) + return result; + + /* if RONLY attribute is set, remove it */ + if (fattr.attr & aRONLY) { /* read only attribute is set */ + fattr.attr &= ~aRONLY; + result = smb_proc_setattr_core(server, dentry, fattr.attr); + } + return result; +} +#endif + int smb_proc_unlink(struct dentry *dentry) { struct smb_sb_info *server = server_from_dentry(dentry); + int flag = 0; char *p; int result; @@ -1152,6 +1161,28 @@ smb_proc_unlink(struct dentry *dentry) if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0) { +#if SMBFS_POSIX_UNLINK + if (result == -EACCES && !flag) { + /* Posix semantics is for the read-only state + of a file to be ignored in unlink(). In the + SMB world a unlink() is refused on a + read-only file. To make things easier for + unix users we try to override the files + permission if the unlink fails with the + right error. + This introduces a race condition that could + lead to a file being written by someone who + shouldn't have access, but as far as I can + tell that is unavoidable */ + + /* remove RONLY attribute and try again */ + result = smb_set_rw(dentry,server); + if (result == 0) { + flag = 1; + goto retry; + } + } +#endif if (smb_retry(server)) goto retry; goto out; @@ -1278,7 +1309,7 @@ smb_decode_dirent(struct smb_sb_info *server, __u8 *p, default: break; } - pr_debug("smb_decode_dirent: len=%d, name=%s\n", len, entry->name); + DEBUG1("len=%d, name=%s\n", len, entry->name); return p + 22; } @@ -1299,10 +1330,7 @@ smb_proc_readdir_short(struct smb_sb_info *server, struct dentry *dir, int fpos, char status[SMB_STATUS_SIZE]; static struct qstr mask = { "*.*", 3, 0 }; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_readdir_short: %s/%s, pos=%d\n", - DENTRY_PATH(dir), fpos); -#endif + VERBOSE("%s/%s, pos=%d\n", DENTRY_PATH(dir), fpos); smb_lock_server(server); @@ -1326,8 +1354,7 @@ printk("smb_proc_readdir_short: %s/%s, pos=%d\n", WSET(p, 0, 0); p += 2; first = 0; - } else - { + } else { *p++ = 0; *p++ = 5; WSET(p, 0, SMB_STATUS_SIZE); @@ -1381,16 +1408,12 @@ printk("smb_proc_readdir_short: %s/%s, pos=%d\n", } if (entries_seen >= fpos) { - pr_debug("smb_proc_readdir: fpos=%u\n", - entries_seen); + DEBUG1("fpos=%u\n", entries_seen); smb_add_to_cache(cachep, entry, entries_seen); entries++; - } else - { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_readdir: skipped, seen=%d, i=%d, fpos=%d\n", -entries_seen, i, fpos); -#endif + } else { + VERBOSE("skipped, seen=%d, i=%d, fpos=%d\n", + entries_seen, i, fpos); } entries_seen++; } @@ -1404,12 +1427,11 @@ entries_seen, i, fpos); /* * Interpret a long filename structure using the specified info level: - * level 1 -- Win NT, Win 95, OS/2 - * level 259 -- File name and length only, Win NT, Win 95 + * level 1 for anything below NT1 protocol + * level 260 for NT1 protocol * * We return a reference to the name string to avoid copying, and perform - * any needed upper/lower casing in place. Note!! Level 259 entries may - * not have any space beyond the name, so don't try to write a null byte! + * any needed upper/lower casing in place. * * Bugs Noted: * (1) Win NT 4.0 appends a null byte to names and counts it in the length! @@ -1426,43 +1448,35 @@ smb_decode_long_dirent(struct smb_sb_info *server, char *p, */ entry->ino = 0; - switch (level) - { + switch (level) { case 1: - len = *((unsigned char *) p + 26); + len = *((unsigned char *) p + 22); entry->len = len; - entry->name = p + 27; - result = p + 28 + len; - break; + entry->name = p + 23; + result = p + 24 + len; - case 259: /* SMB_FIND_FILE_NAMES_INFO = 0x103 */ - result = p + DVAL(p, 0); - /* DVAL(p, 4) should be resume key? Seems to be 0 .. */ - len = DVAL(p, 8); - if (len > 255) - len = 255; - entry->name = p + 12; - /* - * Kludge alert: Win NT 4.0 adds a trailing null byte and - * counts it in the name length, but Win 95 doesn't. Hence - * we test for a trailing null and decrement the length ... - */ + VERBOSE("info 1 at %p, len=%d, name=%.*s\n", + p, entry->len, entry->len, entry->name); + break; + case 260: + result = p + WVAL(p, 0); + len = DVAL(p, 60); + if (len > 255) len = 255; + /* NT4 null terminates */ + entry->name = p + 94; if (len && entry->name[len-1] == '\0') len--; entry->len = len; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_decode_long_dirent: info 259 at %p, len=%d, name=%s\n", -p, len, entry->name); -#endif - break; + VERBOSE("info 260 at %p, len=%d, name=%.*s\n", + p, entry->len, entry->len, entry->name); + break; default: - printk("smb_decode_long_dirent: Unknown level %d\n", level); + PARANOIA("Unknown info level %d\n", level); result = p + WVAL(p, 0); } - switch (server->opt.case_handling) - { + switch (server->opt.case_handling) { case SMB_CASE_UPPER: str_upper(entry->name, len); break; @@ -1476,7 +1490,17 @@ p, len, entry->name); return result; } +/* findfirst/findnext flags */ +#define SMB_CLOSE_AFTER_FIRST (1<<0) +#define SMB_CLOSE_IF_END (1<<1) +#define SMB_REQUIRE_RESUME_KEY (1<<2) +#define SMB_CONTINUE_BIT (1<<3) + /* + * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in + * source/libsmb/clilist.c. When looking for smb bugs in the readdir code, + * go there for advise. + * * Bugs Noted: * (1) When using Info Level 1 Win NT 4.0 truncates directory listings * for certain patterns of names and/or lengths. The breakage pattern @@ -1492,14 +1516,13 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos, int first, entries, entries_seen; /* Both NT and OS/2 accept info level 1 (but see note below). */ - int info_level = 1; + int info_level = 260; const int max_matches = 512; unsigned char *resp_data = NULL; unsigned char *resp_param = NULL; int resp_data_len = 0; int resp_param_len = 0; - int ff_resume_key = 0; /* this isn't being used */ int ff_searchcount = 0; int ff_eos = 0; int ff_lastname = 0; @@ -1509,14 +1532,10 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos, static struct qstr star = { "*", 1, 0 }; /* - * Check whether to change the info level. There appears to be - * a bug in Win NT 4.0's handling of info level 1, whereby it - * truncates the directory scan for certain patterns of files. - * Hence we use level 259 for NT. + * use info level 1 for older servers that don't do 260 */ - if (server->opt.protocol >= SMB_PROTOCOL_NT1 && - !(server->mnt->version & SMB_FIX_WIN95)) - info_level = 259; + if (server->opt.protocol < SMB_PROTOCOL_NT1) + info_level = 1; smb_lock_server(server); @@ -1527,9 +1546,8 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos, mask = param + 12; mask_len = smb_encode_path(server, mask, dir, &star) - mask; first = 1; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_readdir_long: starting fpos=%d, mask=%s\n", fpos, mask); -#endif + VERBOSE("starting fpos=%d, mask=%s\n", fpos, mask); + /* * We must reinitialize the dircache when retrying. */ @@ -1538,49 +1556,33 @@ printk("smb_proc_readdir_long: starting fpos=%d, mask=%s\n", fpos, mask); entries_seen = 2; ff_eos = 0; - while (ff_eos == 0) - { + while (ff_eos == 0) { loop_count += 1; - if (loop_count > 200) - { + if (loop_count > 10) { printk(KERN_WARNING "smb_proc_readdir_long: " "Looping in FIND_NEXT??\n"); entries = -EIO; break; } - if (first != 0) - { + if (first != 0) { command = TRANSACT2_FINDFIRST; WSET(param, 0, aSYSTEM | aHIDDEN | aDIR); WSET(param, 2, max_matches); /* max count */ - WSET(param, 4, 8 + 4 + 2); /* resume required + - close on end + - continue */ + WSET(param, 4, SMB_CLOSE_IF_END); WSET(param, 6, info_level); DSET(param, 8, 0); - } else - { + } else { command = TRANSACT2_FINDNEXT; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_readdir_long: handle=0x%X, resume=%d, lastname=%d, mask=%s\n", -ff_dir_handle, ff_resume_key, ff_lastname, mask); -#endif + + VERBOSE("handle=0x%X, lastname=%d, mask=%s\n", + ff_dir_handle, ff_lastname, mask); + WSET(param, 0, ff_dir_handle); /* search handle */ WSET(param, 2, max_matches); /* max count */ WSET(param, 4, info_level); - DSET(param, 6, ff_resume_key); /* ff_resume_key */ - WSET(param, 10, 8 + 4 + 2); /* resume required + - close on end + - continue */ - if (server->mnt->version & SMB_FIX_WIN95) - { - /* Windows 95 is not able to deliver answers - * to FIND_NEXT fast enough, so sleep 0.2 sec - */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ/5); - } + DSET(param, 6, 0); + WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END); } result = smb_trans2_request(server, command, @@ -1588,65 +1590,59 @@ ff_dir_handle, ff_resume_key, ff_lastname, mask); &resp_data_len, &resp_data, &resp_param_len, &resp_param); - if (result < 0) - { - if (smb_retry(server)) - { -#ifdef SMBFS_PARANOIA -printk("smb_proc_readdir_long: error=%d, retrying\n", result); -#endif + if (result < 0) { + if (smb_retry(server)) { + PARANOIA("error=%d, retrying\n", result); goto retry; } -#ifdef SMBFS_PARANOIA -printk("smb_proc_readdir_long: error=%d, breaking\n", result); -#endif + PARANOIA("error=%d, breaking\n", result); entries = result; break; } - if (server->rcls != 0) - { -#ifdef SMBFS_PARANOIA -printk("smb_proc_readdir_long: name=%s, entries=%d, rcls=%d, err=%d\n", -mask, entries, server->rcls, server->err); -#endif + + if (server->rcls == ERRSRV && server->err == ERRerror) { + /* a damn Win95 bug - sometimes it clags if you + ask it too fast */ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/5); + continue; + } + + if (server->rcls != 0) { + PARANOIA("name=%s, entries=%d, rcls=%d, err=%d\n", + mask, entries, server->rcls, server->err); entries = -smb_errno(server); break; } /* parse out some important return info */ - if (first != 0) - { + if (first != 0) { ff_dir_handle = WVAL(resp_param, 0); ff_searchcount = WVAL(resp_param, 2); ff_eos = WVAL(resp_param, 4); ff_lastname = WVAL(resp_param, 8); - } else - { + } else { ff_searchcount = WVAL(resp_param, 0); ff_eos = WVAL(resp_param, 2); ff_lastname = WVAL(resp_param, 6); } if (ff_searchcount == 0) - { break; - } /* we might need the lastname for continuations */ mask_len = 0; - if (ff_lastname > 0) - { + if (ff_lastname > 0) { lastname = resp_data + ff_lastname; - switch (info_level) - { - case 259: - if (ff_lastname < resp_data_len) + switch (info_level) { + case 260: + if (ff_lastname < resp_data_len) mask_len = resp_data_len - ff_lastname; break; case 1: /* Win NT 4.0 doesn't set the length byte */ lastname++; - if (ff_lastname + 2 < resp_data_len) + if (ff_lastname + 2 < resp_data_len) mask_len = strlen(lastname); break; } @@ -1657,47 +1653,39 @@ mask, entries, server->rcls, server->err); mask_len = 255; if (mask_len) strncpy(mask, lastname, mask_len); - ff_resume_key = 0; } mask[mask_len] = 0; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_readdir_long: new mask, len=%d@%d, mask=%s\n", -mask_len, ff_lastname, mask); -#endif + VERBOSE("new mask, len=%d@%d, mask=%s\n", + mask_len, ff_lastname, mask); + /* Now we are ready to parse smb directory entries. */ /* point to the data bytes */ p = resp_data; - for (i = 0; i < ff_searchcount; i++) - { + for (i = 0; i < ff_searchcount; i++) { struct cache_dirent this_ent, *entry = &this_ent; p = smb_decode_long_dirent(server, p, entry, info_level); - pr_debug("smb_readdir_long: got %s\n", entry->name); - /* ignore . and .. from the server */ - if (entries_seen == 2 && entry->name[0] == '.') - { + if (entries_seen == 2 && entry->name[0] == '.') { if (entry->len == 1) continue; if (entry->name[1] == '.' && entry->len == 2) continue; } - if (entries_seen >= fpos) - { + if (entries_seen >= fpos) { smb_add_to_cache(cachep, entry, entries_seen); entries += 1; } entries_seen++; } -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_readdir_long: received %d entries, eos=%d, resume=%d\n", -ff_searchcount, ff_eos, ff_resume_key); -#endif + VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos); + first = 0; + loop_count = 0; } smb_unlock_server(server); @@ -1737,9 +1725,7 @@ smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry, retry: mask_len = smb_encode_path(server, mask, dentry, NULL) - mask; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_getattr_ff: name=%s, len=%d\n", mask, mask_len); -#endif + VERBOSE("name=%s, len=%d\n", mask, mask_len); WSET(param, 0, aSYSTEM | aHIDDEN | aDIR); WSET(param, 2, 1); /* max count */ WSET(param, 4, 1); /* close after this call */ @@ -1760,9 +1746,9 @@ printk("smb_proc_getattr_ff: name=%s, len=%d\n", mask, mask_len); { result = -smb_errno(server); #ifdef SMBFS_PARANOIA -if (result != -ENOENT) -printk("smb_proc_getattr_ff: error for %s, rcls=%d, err=%d\n", -mask, server->rcls, server->err); + if (result != -ENOENT) + PARANOIA("error for %s, rcls=%d, err=%d\n", + mask, server->rcls, server->err); #endif goto out; } @@ -1770,10 +1756,8 @@ mask, server->rcls, server->err); result = -EINVAL; if (resp_data_len < 22 || WVAL(resp_param, 2) != 1) { -#ifdef SMBFS_PARANOIA -printk("smb_proc_getattr_ff: bad result for %s, len=%d, count=%d\n", -mask, resp_data_len, WVAL(resp_param, 2)); -#endif + PARANOIA("bad result for %s, len=%d, count=%d\n", + mask, resp_data_len, WVAL(resp_param, 2)); goto out; } @@ -1791,10 +1775,8 @@ mask, resp_data_len, WVAL(resp_param, 2)); date = WVAL(resp_data, 8); time = WVAL(resp_data, 10); fattr->f_mtime = date_dos2unix(server, date, time); -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_getattr_ff: name=%s, date=%x, time=%x, mtime=%ld\n", -mask, date, time, fattr->f_mtime); -#endif + VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n", + mask, date, time, fattr->f_mtime); fattr->f_size = DVAL(resp_data, 12); /* ULONG allocation size */ fattr->attr = WVAL(resp_data, 20); @@ -1832,8 +1814,8 @@ smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir, fattr->f_ctime = fattr->f_mtime; fattr->f_atime = fattr->f_mtime; #ifdef SMBFS_DEBUG_TIMESTAMP -printk("getattr_core: %s/%s, mtime=%ld\n", - DENTRY_PATH(dir), fattr->f_mtime); + printk("getattr_core: %s/%s, mtime=%ld\n", + DENTRY_PATH(dir), fattr->f_mtime); #endif result = 0; @@ -1877,20 +1859,16 @@ smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir, } if (server->rcls != 0) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_getattr_trans2: for %s: result=%d, rcls=%d, err=%d\n", -¶m[6], result, server->rcls, server->err); -#endif + VERBOSE("for %s: result=%d, rcls=%d, err=%d\n", + ¶m[6], result, server->rcls, server->err); result = -smb_errno(server); goto out; } result = -ENOENT; if (resp_data_len < 22) { -#ifdef SMBFS_PARANOIA -printk("smb_proc_getattr_trans2: not enough data for %s, len=%d\n", -¶m[6], resp_data_len); -#endif + PARANOIA("not enough data for %s, len=%d\n", + ¶m[6], resp_data_len); goto out; } @@ -1914,8 +1892,8 @@ printk("smb_proc_getattr_trans2: not enough data for %s, len=%d\n", time = WVAL(resp_data, 8 + off_time); attr->f_mtime = date_dos2unix(server, date, time); #ifdef SMBFS_DEBUG_TIMESTAMP -printk("getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", - DENTRY_PATH(dir), date, time, attr->f_mtime); + printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", + DENTRY_PATH(dir), date, time, attr->f_mtime); #endif attr->f_size = DVAL(resp_data, 12); attr->attr = WVAL(resp_data, 20); @@ -1925,13 +1903,15 @@ out: return result; } -int -smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr) +/* + * Note: called with the server locked + */ +static int +smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir, + struct smb_fattr *fattr) { - struct smb_sb_info *server = server_from_dentry(dir); int result; - smb_lock_server(server); smb_init_dirent(server, fattr); /* @@ -1940,7 +1920,8 @@ smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr) if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) { /* * Win 95 appears to break with the trans2 getattr. - */ + * Note: mnt->version options are set at mount time (inode.c) + */ if (server->mnt->version & (SMB_FIX_OLDATTR|SMB_FIX_WIN95)) goto core_attr; if (server->mnt->version & SMB_FIX_DIRATTR) @@ -1953,7 +1934,17 @@ smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr) } smb_finish_dirent(server, fattr); + return result; +} +int +smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr) +{ + struct smb_sb_info *server = server_from_dentry(dir); + int result; + + smb_lock_server(server); + result = smb_proc_do_getattr(server, dir, fattr); smb_unlock_server(server); return result; } @@ -2016,10 +2007,8 @@ smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr) struct smb_sb_info *server = server_from_dentry(dir); int result; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_setattr: setting %s/%s, open=%d\n", - DENTRY_PATH(dir), smb_is_open(dir->d_inode)); -#endif + VERBOSE("setting %s/%s, open=%d\n", + DENTRY_PATH(dir), smb_is_open(dir->d_inode)); smb_lock_server(server); result = smb_proc_setattr_core(server, dir, fattr->attr); smb_unlock_server(server); @@ -2050,8 +2039,8 @@ smb_proc_setattr_ext(struct smb_sb_info *server, WSET(server->packet, smb_vwv5, date); WSET(server->packet, smb_vwv6, time); #ifdef SMBFS_DEBUG_TIMESTAMP -printk("smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n", -date, time, fattr->f_mtime); + printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n", + date, time, fattr->f_mtime); #endif result = smb_request_ok(server, SMBsetattrE, 0, 0); @@ -2100,8 +2089,8 @@ smb_proc_setattr_trans2(struct smb_sb_info *server, WSET(data, 8, date); WSET(data, 10, time); #ifdef SMBFS_DEBUG_TIMESTAMP -printk("setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", - DENTRY_PATH(dir), date, time, fattr->f_mtime); + printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", + DENTRY_PATH(dir), date, time, fattr->f_mtime); #endif DSET(data, 12, 0); /* size */ DSET(data, 16, 0); /* blksize */ @@ -2146,10 +2135,9 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr) struct inode *inode = dentry->d_inode; int result; -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_proc_settime: setting %s/%s, open=%d\n", - DENTRY_PATH(dentry), smb_is_open(inode)); -#endif + VERBOSE("setting %s/%s, open=%d\n", + DENTRY_PATH(dentry), smb_is_open(inode)); + smb_lock_server(server); /* setting the time on a Win95 server fails (tridge) */ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && @@ -2160,8 +2148,7 @@ printk("smb_proc_settime: setting %s/%s, open=%d\n", result = smb_proc_setattr_ext(server, inode, fattr); else result = smb_proc_setattr_trans2(server, dentry, fattr); - } else - { + } else { /* * Fail silently on directories ... timestamp can't be set? */ diff --git a/fs/smbfs/smb_debug.h b/fs/smbfs/smb_debug.h new file mode 100644 index 000000000..a656c356e --- /dev/null +++ b/fs/smbfs/smb_debug.h @@ -0,0 +1,34 @@ +/* + * Defines some debug macros for smbfs. + */ + +/* This makes a dentry parent/child name pair. Useful for debugging printk's */ +#define DENTRY_PATH(dentry) \ + (dentry)->d_parent->d_name.name,(dentry)->d_name.name + +/* + * safety checks that should never happen ??? + * these are normally enabled. + */ +#ifdef SMBFS_PARANOIA +#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " ## x) +#else +#define PARANOIA(x...) do { ; } while(0) +#endif + +/* lots of debug messages */ +#ifdef SMBFS_DEBUG_VERBOSE +#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x) +#else +#define VERBOSE(x...) do { ; } while(0) +#endif + +/* + * "normal" debug messages, but not with a normal DEBUG define ... way + * too common name. + */ +#ifdef SMBFS_DEBUG +#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x) +#else +#define DEBUG1(x...) do { ; } while(0) +#endif diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index a2325d3c8..0c52bf871 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke * Copyright (C) 1997 by Volker Lendecke * + * Please add a note about your changes to smbfs in the ChangeLog file. */ #include <linux/sched.h> @@ -25,8 +26,8 @@ #include <asm/uaccess.h> -#define SMBFS_PARANOIA 1 -/* #define SMBFS_DEBUG_VERBOSE 1 */ +#include "smb_debug.h" + static int _recvfrom(struct socket *socket, unsigned char *ubuf, int size, @@ -115,14 +116,10 @@ smb_data_callback(void* ptr) set_fs(get_ds()); lock_kernel(); - while (1) - { + while (1) { result = -EIO; - if (job->sk->dead) - { -#ifdef SMBFS_PARANOIA - printk("smb_data_callback: sock dead!\n"); -#endif + if (job->sk->dead) { + PARANOIA("sock dead!\n"); break; } @@ -137,7 +134,7 @@ smb_data_callback(void* ptr) result = _recvfrom(socket, (void *) peek_buf, 4, MSG_DONTWAIT); - pr_debug("smb_data_callback: got SESSION KEEPALIVE\n"); + DEBUG1("got SESSION KEEPALIVE\n"); if (result == -EAGAIN) break; @@ -156,7 +153,7 @@ smb_data_ready(struct sock *sk, int len) struct data_callback* job; job = kmalloc(sizeof(struct data_callback),GFP_ATOMIC); if(job == 0) { - printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n"); + printk("smb_data_ready: lost SESSION KEEPALIVE due to OOM.\n"); found_data(sk); return; } @@ -184,7 +181,7 @@ server_sock(struct smb_sb_info *server) { #ifdef SMBFS_PARANOIA if (!smb_valid_socket(file->f_dentry->d_inode)) - printk("smb_server_sock: bad socket!\n"); + PARANOIA("bad socket!\n"); #endif return &file->f_dentry->d_inode->u.socket_i; } @@ -203,7 +200,7 @@ smb_catch_keepalive(struct smb_sb_info *server) socket = server_sock(server); if (!socket) { - printk("smb_catch_keepalive: did not get valid server!\n"); + printk(KERN_DEBUG "smb_catch_keepalive: did not get valid server!\n"); server->data_ready = NULL; goto out; } @@ -211,11 +208,11 @@ smb_catch_keepalive(struct smb_sb_info *server) sk = socket->sk; if (sk == NULL) { - pr_debug("smb_catch_keepalive: sk == NULL"); + DEBUG1("sk == NULL"); server->data_ready = NULL; goto out; } - pr_debug("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n", + DEBUG1("sk->d_r = %x, server->d_r = %x\n", (unsigned int) (sk->data_ready), (unsigned int) (server->data_ready)); @@ -223,8 +220,7 @@ smb_catch_keepalive(struct smb_sb_info *server) * Install the callback atomically to avoid races ... */ data_ready = xchg(&sk->data_ready, smb_data_ready); - if (data_ready != smb_data_ready) - { + if (data_ready != smb_data_ready) { server->data_ready = data_ready; error = 0; } else @@ -245,27 +241,27 @@ smb_dont_catch_keepalive(struct smb_sb_info *server) socket = server_sock(server); if (!socket) { - printk("smb_dont_catch_keepalive: did not get valid server!\n"); + printk(KERN_DEBUG "smb_dont_catch_keepalive: did not get valid server!\n"); goto out; } sk = socket->sk; if (sk == NULL) { - printk("smb_dont_catch_keepalive: sk == NULL"); + DEBUG1("sk == NULL"); goto out; } /* Is this really an error?? */ if (server->data_ready == NULL) { - printk("smb_dont_catch_keepalive: " + printk(KERN_DEBUG "smb_dont_catch_keepalive: " "server->data_ready == NULL\n"); goto out; } - pr_debug("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n", - (unsigned int) (sk->data_ready), - (unsigned int) (server->data_ready)); + DEBUG1("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n", + (unsigned int) (sk->data_ready), + (unsigned int) (server->data_ready)); /* * Restore the original callback atomically to avoid races ... @@ -274,7 +270,7 @@ smb_dont_catch_keepalive(struct smb_sb_info *server) server->data_ready = NULL; if (data_ready != smb_data_ready) { - printk("smb_dont_catch_keepalive: " + printk(KERN_ERR "smb_dont_catch_keepalive: " "sk->data_ready != smb_data_ready\n"); } error = 0; @@ -292,12 +288,10 @@ smb_close_socket(struct smb_sb_info *server) if (file) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_close_socket: closing socket %p\n", server_sock(server)); -#endif + VERBOSE("closing socket %p\n", server_sock(server)); #ifdef SMBFS_PARANOIA -if (server_sock(server)->sk->data_ready == smb_data_ready) -printk("smb_close_socket: still catching keepalives!\n"); + if (server_sock(server)->sk->data_ready == smb_data_ready) + PARANOIA("still catching keepalives!\n"); #endif server->sock_file = NULL; fput(file); @@ -322,8 +316,7 @@ smb_send_raw(struct socket *socket, unsigned char *source, int length) } if (result < 0) { - pr_debug("smb_send_raw: sendto error = %d\n", - -result); + DEBUG1("smb_send_raw: sendto error = %d\n", -result); return result; } already_sent += result; @@ -349,8 +342,7 @@ smb_receive_raw(struct socket *socket, unsigned char *target, int length) } if (result < 0) { - pr_debug("smb_receive_raw: recvfrom error = %d\n", - -result); + DEBUG1("recvfrom error = %d\n", -result); return result; } already_read += result; @@ -373,9 +365,7 @@ smb_get_length(struct socket *socket, unsigned char *header) if (result < 0) { -#ifdef SMBFS_PARANOIA -printk("smb_get_length: recv error = %d\n", -result); -#endif + PARANOIA("recv error = %d\n", -result); return result; } switch (peek_buf[0]) @@ -385,13 +375,11 @@ printk("smb_get_length: recv error = %d\n", -result); break; case 0x85: - pr_debug("smb_get_length: Got SESSION KEEP ALIVE\n"); + DEBUG1("Got SESSION KEEP ALIVE\n"); goto re_recv; default: -#ifdef SMBFS_PARANOIA -printk("smb_get_length: Invalid NBT packet, code=%x\n", peek_buf[0]); -#endif + PARANOIA("Invalid NBT packet, code=%x\n", peek_buf[0]); return -EIO; } @@ -450,17 +438,15 @@ smb_receive(struct smb_sb_info *server) result = smb_receive_raw(socket, packet + 4, len); if (result < 0) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_receive: receive error: %d\n", result); -#endif + VERBOSE("receive error: %d\n", result); goto out; } server->rcls = *(packet + smb_rcls); server->err = WVAL(packet, smb_err); #ifdef SMBFS_DEBUG_VERBOSE -if (server->rcls != 0) -printk("smb_receive: rcls=%d, err=%d\n", server->rcls, server->err); + if (server->rcls != 0) + VERBOSE("rcls=%d, err=%d\n", server->rcls, server->err); #endif out: return result; @@ -523,10 +509,9 @@ smb_receive_trans2(struct smb_sb_info *server, */ if (parm_count == parm_tot && data_count == data_tot) { -#ifdef SMBFS_DEBUG_VERBOSE -printk("smb_receive_trans2: fast track, parm=%u %u %u, data=%u %u %u\n", -parm_disp, parm_offset, parm_count, data_disp, data_offset, data_count); -#endif + VERBOSE("fast track, parm=%u %u %u, data=%u %u %u\n", + parm_disp, parm_offset, parm_count, + data_disp, data_offset, data_count); *parm = base + parm_offset; *data = base + data_offset; goto success; @@ -563,10 +548,9 @@ parm_disp, parm_offset, parm_count, data_disp, data_offset, data_count); memcpy(*parm + parm_disp, base + parm_offset, parm_count); memcpy(*data + data_disp, base + data_offset, data_count); -#ifdef SMBFS_PARANOIA -printk("smb_receive_trans2: copied, parm=%u of %u, data=%u of %u\n", -parm_len, parm_tot, data_len, data_tot); -#endif + PARANOIA("copied, parm=%u of %u, data=%u of %u\n", + parm_len, parm_tot, data_len, data_tot); + /* * Check whether we've received all of the data. Note that * we use the packet totals -- total lengths might shrink! @@ -586,12 +570,9 @@ parm_len, parm_tot, data_len, data_tot); server->packet_size = buf_len; server->packet = rcv_buf; rcv_buf = inbuf; - } else - { -#ifdef SMBFS_PARANOIA -printk("smb_receive_trans2: copying data, old size=%d, new size=%u\n", -server->packet_size, buf_len); -#endif + } else { + PARANOIA("copying data, old size=%d, new size=%u\n", + server->packet_size, buf_len); memcpy(inbuf, rcv_buf, parm_len + data_len); } @@ -604,24 +585,22 @@ out: return result; out_no_mem: -#ifdef SMBFS_PARANOIA - printk("smb_receive_trans2: couldn't allocate data area\n"); -#endif + PARANOIA("couldn't allocate data area\n"); result = -ENOMEM; goto out; out_too_long: - printk("smb_receive_trans2: data/param too long, data=%d, parm=%d\n", + printk(KERN_ERR "smb_receive_trans2: data/param too long, data=%d, parm=%d\n", data_tot, parm_tot); goto out_error; out_data_grew: - printk("smb_receive_trans2: data/params grew!\n"); + printk(KERN_ERR "smb_receive_trans2: data/params grew!\n"); goto out_error; out_bad_parm: - printk("smb_receive_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n", + printk(KERN_ERR "smb_receive_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n", parm_disp, parm_count, parm_tot); goto out_error; out_bad_data: - printk("smb_receive_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n", + printk(KERN_ERR "smb_receive_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n", data_disp, data_count, data_tot); out_error: result = -EIO; @@ -653,7 +632,7 @@ smb_request(struct smb_sb_info *server) goto bad_conn; len = smb_len(buffer) + 4; - pr_debug("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]); + DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]); spin_lock_irqsave(¤t->sigmask_lock, flags); sigpipe = sigismember(¤t->signal, SIGPIPE); @@ -686,7 +665,7 @@ smb_request(struct smb_sb_info *server) int result2 = smb_catch_keepalive(server); if (result2 < 0) { - printk("smb_request: catch keepalive failed\n"); + printk(KERN_ERR "smb_request: catch keepalive failed\n"); result = result2; } } @@ -698,28 +677,27 @@ smb_request(struct smb_sb_info *server) if (server->rcls) { int error = smb_errno(server); if (error == EBADSLT) { - printk("smb_request: tree ID invalid\n"); + printk(KERN_ERR "smb_request: tree ID invalid\n"); result = error; goto bad_conn; } } out: - pr_debug("smb_request: result = %d\n", result); + DEBUG1("result = %d\n", result); return result; bad_conn: -#ifdef SMBFS_PARANOIA -printk("smb_request: result %d, setting invalid\n", result); -#endif + PARANOIA("result %d, setting invalid\n", result); server->state = CONN_INVALID; smb_invalidate_inodes(server); goto out; bad_no_packet: - printk("smb_request: no packet!\n"); + printk(KERN_ERR "smb_request: no packet!\n"); goto out; bad_no_conn: - printk("smb_request: connection %d not valid!\n", server->state); + printk(KERN_ERR "smb_request: connection %d not valid!\n", + server->state); goto out; } @@ -738,13 +716,13 @@ smb_send_trans2(struct smb_sb_info *server, __u16 trans2_command, const int smb_parameters = 15; const int oparam = - ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3); + ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3); const int odata = - ROUND_UP(oparam + lparam); + ROUND_UP(oparam + lparam); const int bcc = - odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2); + odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2); const int packet_length = - SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2; + SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2; unsigned char padding[4] = {0,}; @@ -821,8 +799,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, mm_segment_t fs; int result; - pr_debug("smb_trans2_request: com=%d, ld=%d, lp=%d\n", - trans2_command, ldata, lparam); + DEBUG1("com=%d, ld=%d, lp=%d\n", trans2_command, ldata, lparam); /* * These are initialized in smb_request_ok, but not here?? @@ -881,7 +858,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, if (server->rcls) { int error = smb_errno(server); if (error == EBADSLT) { - printk("smb_request: tree ID invalid\n"); + printk(KERN_ERR "smb_request: tree ID invalid\n"); result = error; goto bad_conn; } @@ -891,9 +868,7 @@ out: return result; bad_conn: -#ifdef SMBFS_PARANOIA -printk("smb_trans2_request: result=%d, setting invalid\n", result); -#endif + PARANOIA("result=%d, setting invalid\n", result); server->state = CONN_INVALID; smb_invalidate_inodes(server); goto out; |