summaryrefslogtreecommitdiffstats
path: root/fs/smbfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/smbfs')
-rw-r--r--fs/smbfs/ChangeLog40
-rw-r--r--fs/smbfs/Makefile9
-rw-r--r--fs/smbfs/cache.c86
-rw-r--r--fs/smbfs/dir.c154
-rw-r--r--fs/smbfs/file.c122
-rw-r--r--fs/smbfs/inode.c68
-rw-r--r--fs/smbfs/ioctl.c35
-rw-r--r--fs/smbfs/proc.c529
-rw-r--r--fs/smbfs/smb_debug.h34
-rw-r--r--fs/smbfs/sock.c145
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",
-&param[6], result, server->rcls, server->err);
-#endif
+ VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
+ &param[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",
-&param[6], resp_data_len);
-#endif
+ PARANOIA("not enough data for %s, len=%d\n",
+ &param[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(&current->sigmask_lock, flags);
sigpipe = sigismember(&current->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;