[Patch] Shorter patch for smbfs 2.2.16
klaus-georg.adams at rwg.de
klaus-georg.adams at rwg.de
Wed Jun 28 06:55:20 GMT 2000
Am 27.06.2000 19:58:44 schrieb urban:
> On Tue, 27 Jun 2000 klaus-georg.adams at rwg.de wrote:
>
> >
> > Hi Andrew,
> > your patch from 2.2.15 to 2.2.16, backing out the older protocol levels
breaks
> > reading from an OS/2 LAN Server.
> > The appended patch fixes things for me (against 2.2.16).
>
> This backs out a lot of desired changes. For example I think that 'rm -rf'
> on large directories will no longer work if you apply this because you
> change the cache to the old behaviour.
Yes, this was simply going back to 2.2.15 and adding a fix for the same problem
mentioned in
the mail about 2.4.0-test2.
>
> > - * Jan 2000, cpg at aladdin.de
> > - * - added posix semantics for unlink
> > - * March 2000, tridge
> > - * - removed support for old protocol levels. It didn't work
anyway
> > and
> > - * was cluttering things up a lot.
> > + * 20/03/00 (chrisp)
> > + * - fixed FINDFIRST flags for OS/2 Server
> > + * - added lastname/mask stuff back (OS/2 needs it)
>
> And you remove the nice "posix semantics for unlink".
>
> It looks like you have simply gone back to the 2.2.14/15 version, and then
> added findfirst/lastname things. Maybe you could make a smaller patch that
> only adds back the parts necessary for it to work with OS/2? (or not,
> Tridge can probably see that anyway).
That's what I hoped. I had only seen the ChangeLog entry from tridge regarding
older protocol levels. I hadn't realized that there were other fixes.
The parts that I need for reading from an OS/2 LANman server are:
- support for older protocols (I'm not sure which one exactly)
- the lastname/mask stuff
- the FINDFIRST flags in readdir_long
I have appended a shorter patch, which still works for me, but leaves in most
of the other stuff from 2.2.16
>
> Re: Your other email about listing long directories. I suggested something
> similar to your patch for fixing this in 2.2, but the preferred change was
> to use infolevel 260 instead of 259.
Note: my problem arises with an OS/2 server at a protocol level < NT1, thus
infolevel == 1
> 2.3/2.4-test hasn't received any of the changes that 2.2 has, including
> long dirs, posix unlink, rm -rf fixes. I have a patch vs 2.3.99-pre9 to
> upgrade smbfs to 2.2, that haven't made it past the maintainer yet.
Would you be so kind as to send it to me for testing?
Thanks!
PS: the same problem wrt reading long directories from an OS/2 server
existed in smbclient from samba 2.0.6.
Tridge has accepted a patch from Christoph Pfisterer to samba (which is the
equivalent to
what I posted above) into 2.0.7, so it can't be all wrong.
--
kga
Index: fs/smbfs/dir.c
===================================================================
RCS file: /usr/src/cvsroot/linux/fs/smbfs/dir.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 dir.c
--- fs/smbfs/dir.c 2000/06/13 09:23:24 1.1.1.5
+++ fs/smbfs/dir.c 2000/06/28 06:36:12
@@ -178,6 +178,16 @@
printk("smb_dir_open: (%s/%s)\n", dentry->d_parent->d_name.name,
file->f_dentry->d_name.name);
#endif
+ /*
+ * Directory timestamps in the core protocol aren't updated
+ * when a file is added, so we give them a very short TTL.
+ */
+ if (server->opt.protocol < SMB_PROTOCOL_LANMAN2)
+ {
+ unsigned long age = jiffies - dir->u.smbfs_i.oldmtime;
+ if (age > 2*HZ)
+ smb_invalid_dir_cache(dir);
+ }
if (server->conn_pid)
error = smb_revalidate_inode(dentry);
@@ -420,6 +430,7 @@
dentry->d_parent->d_name.name, dentry->d_name.name, mode);
#endif
+ smb_invalid_dir_cache(dir);
error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
if (!error)
{
@@ -440,6 +451,7 @@
{
int error;
+ smb_invalid_dir_cache(dir);
error = smb_proc_mkdir(dentry);
if (!error)
{
@@ -466,6 +478,7 @@
if (!list_empty(&dentry->d_hash))
goto out;
+ smb_invalid_dir_cache(dir);
error = smb_proc_rmdir(dentry);
out:
@@ -482,6 +495,7 @@
*/
smb_close(dentry->d_inode);
+ smb_invalid_dir_cache(dir);
error = smb_proc_unlink(dentry);
if (!error)
{
@@ -519,6 +533,8 @@
d_delete(new_dentry);
}
+ smb_invalid_dir_cache(old_dir);
+ smb_invalid_dir_cache(new_dir);
error = smb_proc_mv(old_dentry, new_dentry);
if (!error)
{
Index: fs/smbfs/inode.c
===================================================================
RCS file: /usr/src/cvsroot/linux/fs/smbfs/inode.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 inode.c
--- fs/smbfs/inode.c 2000/06/13 09:23:24 1.1.1.3
+++ fs/smbfs/inode.c 2000/06/28 06:36:12
@@ -276,6 +276,8 @@
#endif
if (!S_ISDIR(inode->i_mode))
invalidate_inode_pages(inode);
+ else
+ smb_invalid_dir_cache(inode);
}
out:
return error;
@@ -379,6 +381,13 @@
mnt->dir_mode &= (S_IRWXU | S_IRWXG | S_IRWXO);
mnt->dir_mode |= S_IFDIR;
sb->u.smbfs_sb.mnt = mnt;
+ /*
+ * Display the enabled options
+ */
+ if (mnt->version & SMB_FIX_OLDATTR)
+ printk("SMBFS: Using core getattr (Win 95 speedup)\n");
+ else if (mnt->version & SMB_FIX_DIRATTR)
+ printk("SMBFS: Using dir ff getattr\n");
/*
* Keep the super block locked while we get the root inode.
@@ -501,7 +510,9 @@
if ((attr->ia_valid & ATTR_ATIME) != 0)
{
fattr.f_atime = attr->ia_atime;
- changed = 1;
+ /* Earlier protocols don't have an access time */
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
+ changed = 1;
}
if (changed)
{
Index: fs/smbfs/proc.c
===================================================================
RCS file: /usr/src/cvsroot/linux/fs/smbfs/proc.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 proc.c
--- fs/smbfs/proc.c 2000/06/13 09:23:25 1.1.1.4
+++ fs/smbfs/proc.c 2000/06/28 06:36:12
@@ -14,9 +14,9 @@
* - got rid of resume_key
* Jan 2000, cpg at aladdin.de
* - added posix semantics for unlink
- * March 2000, tridge
- * - removed support for old protocol levels. It didn't work anyway
and
- * was cluttering things up a lot.
+ * 20/03/00 (chrisp)
+ * - fixed FINDFIRST flags for OS/2 Server
+ * - added lastname/mask stuff back (OS/2 needs it)
*/
#include <linux/types.h>
@@ -62,6 +62,28 @@
static int
smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,struct
smb_sb_info *server);
+static void
+str_upper(char *name, int len)
+{
+ while (len--)
+ {
+ if (*name >= 'a' && *name <= 'z')
+ *name -= ('a' - 'A');
+ name++;
+ }
+}
+
+static void
+str_lower(char *name, int len)
+{
+ while (len--)
+ {
+ if (*name >= 'A' && *name <= 'Z')
+ *name += ('a' - 'A');
+ name++;
+ }
+}
+
/* reverse a string inline. This is used by the dircache walking routines */
static void reverse_string(char *buf, int len) {
char c;
@@ -149,8 +171,13 @@
static char *smb_encode_path(struct smb_sb_info *server, char *buf,
struct dentry *dir, struct qstr *name)
{
+ char *start = buf;
+
buf += smb_build_path(dir, name, buf);
+ if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS)
+ str_upper(start, buf - start);
+
return buf;
}
@@ -625,11 +652,6 @@
!capable(CAP_SYS_ADMIN))
goto out;
- if (opt->protocol < SMB_PROTOCOL_NT1) {
- printk(KERN_NOTICE " smbfs: protocols older than NT1 are not
suppported\n");
- goto out;
- }
-
error = -EBADF;
filp = fget(opt->fd);
if (!filp)
@@ -652,7 +674,8 @@
/* now that we have an established connection we can detect the server
type and enable bug workarounds */
- if ((server->opt.max_xmit < 0x1000) &&
+ if (server->opt.protocol == SMB_PROTOCOL_NT1 &&
+ (server->opt.max_xmit < 0x1000) &&
!(server->opt.capabilities & SMB_CAP_NT_SMBS)) {
server->mnt->version |= SMB_FIX_WIN95;
#ifdef SMBFS_DEBUG_VERBOSE
@@ -706,8 +729,11 @@
WSET(buf, smb_uid, server->opt.server_uid);
WSET(buf, smb_mid, 1);
- *(buf+smb_flg) = 0x8;
- WSET(buf, smb_flg2, 0x3);
+ if (server->opt.protocol > SMB_PROTOCOL_CORE)
+ {
+ *(buf+smb_flg) = 0x8;
+ WSET(buf, smb_flg2, 0x3);
+ }
*p++ = wct; /* wct */
p += 2 * wct;
WSET(p, 0, bcc);
@@ -893,7 +919,9 @@
* If the file is open with write permissions,
* update the time stamps to sync mtime and atime.
*/
- if (ino->u.smbfs_i.access != SMB_O_RDONLY) {
+ if ((server->opt.protocol >= SMB_PROTOCOL_LANMAN2) &&
+ !(ino->u.smbfs_i.access == SMB_O_RDONLY))
+ {
struct smb_fattr fattr;
smb_get_inode_attr(ino, &fattr);
smb_proc_setattr_ext(server, ino, &fattr);
@@ -903,8 +931,11 @@
ino->i_mtime);
ino->u.smbfs_i.cache_valid &= ~SMB_F_LOCALWRITE;
/*
- * Force a revalidation after closing
+ * Force a revalidation after closing ... some servers
+ * don't post the size until the file has been closed.
*/
+ if (server->opt.protocol < SMB_PROTOCOL_NT1)
+ ino->u.smbfs_i.oldmtime = 0;
ino->u.smbfs_i.closed = jiffies;
}
return result;
@@ -1310,8 +1341,177 @@
/*
- * Interpret a long filename structure using info level 260
+ * Note that we are now returning the name as a reference to avoid
+ * an extra copy, and that the upper/lower casing is done in place.
+ *
+ * Bugs Noted:
+ * (1) Pathworks servers may pad the name with extra spaces.
+ */
+static __u8 *
+smb_decode_dirent(struct smb_sb_info *server, __u8 *p,
+ struct cache_dirent *entry)
+{
+ int len;
+
+ /*
+ * SMB doesn't have a concept of inode numbers ...
+ */
+ entry->ino = 0;
+
+ p += SMB_STATUS_SIZE; /* reserved (search_status) */
+ entry->name = p + 9;
+ len = strlen(entry->name);
+ if (len > 12)
+ {
+ len = 12;
+ }
+ /*
+ * Trim trailing blanks for Pathworks servers
+ */
+ while (len > 2 && entry->name[len-1] == ' ')
+ len--;
+ entry->len = len;
+
+ switch (server->opt.case_handling)
+ {
+ case SMB_CASE_UPPER:
+ str_upper(entry->name, len);
+ break;
+ case SMB_CASE_LOWER:
+ str_lower(entry->name, len);
+ break;
+ default:
+ break;
+ }
+ pr_debug("smb_decode_dirent: len=%d, name=%s\n", len, entry->name);
+ return p + 22;
+}
+
+/* This routine is used to read in directory entries from the network.
+ Note that it is for short directory name seeks, i.e.: protocol <
+ SMB_PROTOCOL_LANMAN2 */
+
+static int
+smb_proc_readdir_short(struct smb_sb_info *server, struct dentry *dir, int
fpos,
+ void *cachep)
+{
+ char *p;
+ int result;
+ int i, first, entries_seen, entries;
+ int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE;
+ __u16 bcc;
+ __u16 count;
+ 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
+
+ smb_lock_server(server);
+
+ /* N.B. We need to reinitialize the cache to restart */
+ retry:
+ smb_init_dircache(cachep);
+ first = 1;
+ entries = 0;
+ entries_seen = 2; /* implicit . and .. */
+
+ while (1)
+ {
+ p = smb_setup_header(server, SMBsearch, 2, 0);
+ WSET(server->packet, smb_vwv0, entries_asked);
+ WSET(server->packet, smb_vwv1, aDIR);
+ *p++ = 4;
+ if (first == 1)
+ {
+ p = smb_encode_path(server, p, dir, &mask);
+ *p++ = 5;
+ WSET(p, 0, 0);
+ p += 2;
+ first = 0;
+ } else
+ {
+ *p++ = 0;
+ *p++ = 5;
+ WSET(p, 0, SMB_STATUS_SIZE);
+ p += 2;
+ memcpy(p, status, SMB_STATUS_SIZE);
+ p += SMB_STATUS_SIZE;
+ }
+
+ smb_setup_bcc(server, p);
+
+ result = smb_request_ok(server, SMBsearch, 1, -1);
+ if (result < 0)
+ {
+ if ((server->rcls == ERRDOS) &&
+ (server->err == ERRnofiles))
+ break;
+ if (smb_retry(server))
+ goto retry;
+ goto unlock_return;
+ }
+ p = SMB_VWV(server->packet);
+ count = WVAL(p, 0);
+ if (count <= 0)
+ break;
+
+ result = -EIO;
+ bcc = WVAL(p, 2);
+ if (bcc != count * SMB_DIRINFO_SIZE + 3)
+ goto unlock_return;
+ p += 7;
+
+ /* Read the last entry into the status field. */
+ memcpy(status,
+ SMB_BUF(server->packet) + 3 +
+ (count - 1) * SMB_DIRINFO_SIZE,
+ SMB_STATUS_SIZE);
+
+ /* Now we are ready to parse smb directory entries. */
+
+ for (i = 0; i < count; i++)
+ {
+ struct cache_dirent this_ent, *entry = &this_ent;
+
+ p = smb_decode_dirent(server, p, entry);
+ if (entries_seen == 2 && entry->name[0] == '.')
+ {
+ if (entry->len == 1)
+ continue;
+ if (entry->name[1] == '.' && entry->len == 2)
+ continue;
+ }
+ if (entries_seen >= fpos)
+ {
+ pr_debug("smb_proc_readdir: 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
+ }
+ entries_seen++;
+ }
+ }
+ result = entries;
+
+ unlock_return:
+ smb_unlock_server(server);
+ return result;
+}
+/*
+ * Interpret a long filename structure using the specified info level:
+ * 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.
@@ -1320,7 +1520,7 @@
*/
static char *
smb_decode_long_dirent(struct smb_sb_info *server, char *p,
- struct cache_dirent *entry)
+ struct cache_dirent *entry, int level)
{
char *result;
unsigned int len = 0;
@@ -1330,19 +1530,47 @@
*/
entry->ino = 0;
- 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;
+ switch (level)
+ {
+ case 1:
+ len = *((unsigned char *) p + 22);
+ entry->len = len;
+ entry->name = p + 23;
+ result = p + 24 + len;
+ break;
+
+ case 260: /* SMB_FIND_FILE_BOTH_DIRECTORY_INFO = 0x104 */
+ 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(KERN_DEBUG "smb_decode_long_dirent: info 260 at %p, len=%d,
name=%s\n",
p, entry->len, entry->name);
#endif
+ break;
+ default:
+ printk("smb_decode_long_dirent: Unknown level %d\n", level);
+ result = p + WVAL(p, 0);
+ }
+
+ switch (server->opt.case_handling)
+ {
+ case SMB_CASE_UPPER:
+ str_upper(entry->name, len);
+ break;
+ case SMB_CASE_LOWER:
+ str_lower(entry->name, len);
+ break;
+ default:
+ break;
+ }
+
return result;
}
@@ -1366,6 +1594,8 @@
char *p, *mask, *param = server->temp_buf;
__u16 command;
int first, entries, entries_seen;
+
+ /* Both NT and OS/2 accept info level 1 (but see note below). */
int info_level = 260;
const int max_matches = 512;
@@ -1375,11 +1605,18 @@
int resp_param_len = 0;
int ff_searchcount = 0;
int ff_eos = 0;
+ int ff_lastname = 0;
int ff_dir_handle = 0;
int loop_count = 0;
int mask_len, i, result;
static struct qstr star = { "*", 1, 0 };
+ /*
+ * use info level 1 for older servers that don't do 260
+ */
+ if (server->opt.protocol < SMB_PROTOCOL_NT1)
+ info_level = 1;
+
smb_lock_server(server);
retry:
@@ -1416,16 +1653,11 @@
command = TRANSACT2_FINDFIRST;
WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
WSET(param, 2, max_matches); /* max count */
- WSET(param, 4,
- SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
+ WSET(param, 4, SMB_CLOSE_IF_END);
WSET(param, 6, info_level);
DSET(param, 8, 0);
} else
{
- /* we don't need the mask after the first bit */
- mask_len = 0;
- mask[0] = 0;
-
command = TRANSACT2_FINDNEXT;
#ifdef SMBFS_DEBUG_VERBOSE
printk(KERN_DEBUG "smb_proc_readdir_long: handle=0x%X, mask=%s\n",
@@ -1485,10 +1717,12 @@
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
{
ff_searchcount = WVAL(resp_param, 0);
ff_eos = WVAL(resp_param, 2);
+ ff_lastname = WVAL(resp_param, 6);
}
if (ff_searchcount == 0)
@@ -1496,6 +1730,18 @@
break;
}
+ if (ff_lastname > 0 && info_level == 1)
+ {
+ mask_len = *(resp_data + ff_lastname);
+ memcpy(mask, resp_data + ff_lastname + 1,
+ mask_len);
+ mask[mask_len] = 0;
+ } else
+ {
+ mask_len = 0;
+ mask[0] = 0;
+ }
+
/* Now we are ready to parse smb directory entries. */
/* point to the data bytes */
@@ -1504,7 +1750,8 @@
{
struct cache_dirent this_ent, *entry = &this_ent;
- p = smb_decode_long_dirent(server, p, entry);
+ p = smb_decode_long_dirent(server, p, entry,
+ info_level);
/* ignore . and .. from the server */
if (entries_seen == 2 && entry->name[0] == '.')
@@ -1540,7 +1787,98 @@
struct smb_sb_info *server;
server = server_from_dentry(dir);
- return smb_proc_readdir_long(server, dir, fpos, cachep);
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
+ return smb_proc_readdir_long(server, dir, fpos, cachep);
+ else
+ return smb_proc_readdir_short(server, dir, fpos, cachep);
+}
+
+/*
+ * This version uses the trans2 TRANSACT2_FINDFIRST message
+ * to get the attribute data.
+ * Note: called with the server locked.
+ *
+ * Bugs Noted:
+ */
+static int
+smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
+ struct smb_fattr *fattr)
+{
+ char *param = server->temp_buf, *mask = param + 12;
+ __u16 date, time;
+ unsigned char *resp_data = NULL;
+ unsigned char *resp_param = NULL;
+ int resp_data_len = 0;
+ int resp_param_len = 0;
+ int mask_len, result;
+
+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
+ WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
+ WSET(param, 2, 1); /* max count */
+ WSET(param, 4, 1); /* close after this call */
+ WSET(param, 6, 1); /* info_level */
+ DSET(param, 8, 0);
+
+ result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
+ 0, NULL, 12 + mask_len + 1, param,
+ &resp_data_len, &resp_data,
+ &resp_param_len, &resp_param);
+ if (result < 0)
+ {
+ if (smb_retry(server))
+ goto retry;
+ goto out;
+ }
+ if (server->rcls != 0)
+ {
+ 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);
+#endif
+ goto out;
+ }
+ /* Make sure we got enough data ... */
+ 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
+ goto out;
+ }
+
+ /*
+ * Decode the response into the fattr ...
+ */
+ date = WVAL(resp_data, 0);
+ time = WVAL(resp_data, 2);
+ fattr->f_ctime = date_dos2unix(server, date, time);
+
+ date = WVAL(resp_data, 4);
+ time = WVAL(resp_data, 6);
+ fattr->f_atime = date_dos2unix(server, date, time);
+
+ 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
+ fattr->f_size = DVAL(resp_data, 12);
+ /* ULONG allocation size */
+ fattr->attr = WVAL(resp_data, 20);
+ result = 0;
+
+out:
+ return result;
}
/*
@@ -1687,12 +2025,20 @@
/*
* Select whether to use core or trans2 getattr.
- * Win 95 appears to break with the trans2 getattr.
- */
- if (server->mnt->version & SMB_FIX_WIN95) {
- result = smb_proc_getattr_core(server, dir, fattr);
+ */
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) {
+ /*
+ * Win 95 appears to break with the trans2 getattr.
+ */
+ if (server->mnt->version & (SMB_FIX_OLDATTR|SMB_FIX_WIN95))
+ goto core_attr;
+ if (server->mnt->version & SMB_FIX_DIRATTR)
+ result = smb_proc_getattr_ff(server, dir, fattr);
+ else
+ result = smb_proc_getattr_trans2(server, dir, fattr);
} else {
- result = smb_proc_getattr_trans2(server, dir, fattr);
+ core_attr:
+ result = smb_proc_getattr_core(server, dir, fattr);
}
smb_finish_dirent(server, fattr);
@@ -1906,7 +2252,8 @@
#endif
smb_lock_server(server);
/* setting the time on a Win95 server fails (tridge) */
- if (!(server->mnt->version & SMB_FIX_WIN95))
+ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 &&
+ !(server->mnt->version & SMB_FIX_WIN95))
{
if (smb_is_open(inode) &&
More information about the samba
mailing list