Linux SMB Mount utils patch

Paul PELaufer at CSUPomona.edu
Fri Sep 4 03:54:50 GMT 1998


Hi,
	I'm sure that you are all aware that the mount utilities that ship
with samba are designed to compile and run only with Linux 2.1 series
development kernels.
	I'll _try_ keep this short and sweet while doing my best to
explain what I have done, since I have a tendancy to  ramble on. I
have two boxes, one Linux with libc5, and another with Linux and Glibc2
(aka libc6).  The Samba package itself compiles and runs fine on the libc5
box (although it was necessary to turn off optimization to compile with
gcc 2.7.2.3).  The glibc2 box was able to compile after adding
"-DNO_SEMUN" to the compiler flags, since newer glibc2 includes don't
define it as older ones did. This is also fixed in the included patch.
	The main problem is that the mount utilities will only compile
properly on libc5. Since glibc2 now includes magic numbers for mount, it
is no longer necessary (or desired) to include <linux/fs.h>.  Also, the
Linux kernel uses 16 bit numbers for uid_t, gid_t, and mode_t, whilst
glibc2 uses 32 bits. This causes problems obviously when trying to mount
the share. Basically the permissions and ownership as all screwed up.  The
fix is to replace uid_t with __kernel_uid_t and the others the same
way. With these small changes all the mount utilities compile correctly,
with the exception of smbumount, which required $(LIBS) be added to the
object dependancies in the Makefile.
	So now I have a copy of Samba and the smb mount utils that works
properly with glibc2. I cleaned up my changes so that samba now
automatically detects whether or not your glibc2 defines struct semun, I
fixed all references to uid_t etc., #ifndef GLIBC2 -ed out the #include
<linux/fs.h> references, and added $(LIBS) to smbumount's object
dependencies.
	The result of this is that the smb mount utils for Linux
development kernels should now compile, and work, properly on all Linux
2.1 installations regardless of the installed libc version. I have tested
my patch on libc 5.4.46, glibc 2.0.95 and glibc 2.0.94 with Linux kernel
versions 2.1.115 through 2.1.119.
	The only questionable part of this patch was fixing the kernel's
headers. To do this, I copied the linux/smb_*.h headers to samba's source
directory, had the mount utils use the new copy, and modified the new
copy. I think this is preferable to messing with the real kernel headers.
	If anyone else was having trouble with glibc2 and the mount
utilities, please try this patch and tell me your results.

Note: I am not subscribed to this list, so please CC all
responses/flames/complaints/etc. to PELaufer at CSUPomona.edu

Thank you,
Paul Laufer
-------------- next part --------------
diff -urN samba-1.9.18p10-orig/source/Makefile samba-1.9.18p10/source/Makefile
--- samba-1.9.18p10-orig/source/Makefile	Mon Jun 15 10:32:28 1998
+++ samba-1.9.18p10/source/Makefile	Thu Sep  3 12:56:17 1998
@@ -200,7 +200,7 @@
 # you must use the smbfs utilities from
 # ftp://ftp.gwdg.de/pub/linux/misc/smbfs
 
-# MOUNT_PROGS = smbmount smbmnt smbumount
+MOUNT_PROGS = smbmount smbmnt smbumount
 
 # Use this for Linux with shadow passwords - but not using PAM!
 # contributed by Andrew.Tridgell at anu.edu.au
@@ -783,7 +783,7 @@
 
 smbumount: $(UMOUNT_OBJ)
 	@echo Linking smbumount
-	@$(CC) $(CFLAGS) -o smbumount $(UMOUNT_OBJ)
+	@$(CC) $(CFLAGS) -o smbumount $(UMOUNT_OBJ) $(LIBS)
 
 smbtorture: torture.o clientgen.o getsmbpass.o $(UTILOBJ)
 	@echo Linking smbtorture
diff -urN samba-1.9.18p10-orig/source/includes.h samba-1.9.18p10/source/includes.h
--- samba-1.9.18p10-orig/source/includes.h	Wed Aug 19 16:41:46 1998
+++ samba-1.9.18p10/source/includes.h	Thu Sep  3 12:54:45 1998
@@ -1175,6 +1175,10 @@
 #ifdef USE_SYSV_IPC
 #include <sys/ipc.h>
 #include <sys/sem.h>
+#if _SEM_SEMUN_UNDEFINED && GLIBC2
+#define NO_SEMUN /* this version of glibc2 does not define struct semun for us */
+#undef _SEM_SEMUN_UNDEFINED
+#endif /*_SEM_SEMUN_UNDEFINED && GLIBC2 */;
 #include <sys/shm.h>
 #ifdef NO_SEMUN
 union semun {
diff -urN samba-1.9.18p10-orig/source/smb_fs.h samba-1.9.18p10/source/smb_fs.h
--- samba-1.9.18p10-orig/source/smb_fs.h	Wed Dec 31 16:00:00 1969
+++ samba-1.9.18p10/source/smb_fs.h	Thu Sep  3 12:54:45 1998
@@ -0,0 +1,224 @@
+/*
+ *  smb_fs.h
+ *
+ *  Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
+ *  Copyright (C) 1997 by Volker Lendecke
+ *
+ */
+
+#ifndef _LINUX_SMB_FS_H
+#define _LINUX_SMB_FS_H
+
+#include <linux/smb.h>
+
+/*
+ * ioctl commands
+ */
+#define	SMB_IOC_GETMOUNTUID		_IOR('u', 1, __kernel_uid_t)
+#define SMB_IOC_NEWCONN                 _IOW('u', 2, struct smb_conn_opt)
+
+#ifdef __KERNEL__
+
+#include <asm/unaligned.h>
+
+#define WVAL(buf,pos) \
+(le16_to_cpu(get_unaligned((__u16 *)((__u8 *)(buf) + (pos)))))
+#define DVAL(buf,pos) \
+(le32_to_cpu(get_unaligned((__u32 *)((__u8 *)(buf) + (pos)))))
+#define WSET(buf,pos,val) \
+put_unaligned(cpu_to_le16((__u16)(val)), (__u16 *)((__u8 *)(buf) + (pos)))
+#define DSET(buf,pos,val) \
+put_unaligned(cpu_to_le32((__u32)(val)), (__u32 *)((__u8 *)(buf) + (pos)))
+
+/* where to find the base of the SMB packet proper */
+#define smb_base(buf) ((__u8 *)(((__u8 *)(buf))+4))
+
+#include <linux/vmalloc.h>
+
+#ifdef DEBUG_SMB_MALLOC
+
+extern int smb_malloced;
+extern int smb_current_vmalloced;
+
+static inline void *
+smb_vmalloc(unsigned int size)
+{
+        smb_malloced += 1;
+        smb_current_vmalloced += 1;
+        return vmalloc(size);
+}
+
+static inline void
+smb_vfree(void *obj)
+{
+        smb_current_vmalloced -= 1;
+        vfree(obj);
+}
+
+#else /* DEBUG_SMB_MALLOC */
+
+#define smb_kmalloc(s,p) kmalloc(s,p)
+#define smb_kfree_s(o,s) kfree_s(o,s)
+#define smb_vmalloc(s)   vmalloc(s)
+#define smb_vfree(o)     vfree(o)
+
+#endif /* DEBUG_SMB_MALLOC */
+
+/*
+ * Flags for the in-memory inode
+ */
+#define SMB_F_CACHEVALID	0x01	/* directory cache valid */
+#define SMB_F_LOCALWRITE	0x02	/* file modified locally */
+
+/*
+ * Bug fix flags
+ */
+#define SMB_FIX_WIN95	0x0001	/* Win 95 server */
+#define SMB_FIX_OLDATTR	0x0002	/* Use core getattr (Win 95 speedup) */
+#define SMB_FIX_DIRATTR	0x0004	/* Use find_first for getattr */
+
+/* linux/fs/smbfs/mmap.c */
+int smb_mmap(struct file *, struct vm_area_struct *);
+
+/* linux/fs/smbfs/file.c */
+extern struct inode_operations smb_file_inode_operations;
+
+/* linux/fs/smbfs/dir.c */
+extern struct inode_operations smb_dir_inode_operations;
+void smb_renew_times(struct dentry *);
+
+/* linux/fs/smbfs/ioctl.c */
+int smb_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
+
+/* linux/fs/smbfs/inode.c */
+struct super_block *smb_read_super(struct super_block *, void *, int);
+void smb_get_inode_attr(struct inode *, struct smb_fattr *);
+void smb_invalidate_inodes(struct smb_sb_info *);
+int  smb_revalidate_inode(struct dentry *);
+int  smb_notify_change(struct dentry *, struct iattr *);
+unsigned long smb_invent_inos(unsigned long);
+struct inode *smb_iget(struct super_block *, struct smb_fattr *);
+extern int init_smb_fs(void);
+
+/* linux/fs/smbfs/proc.c */
+__u32 smb_len(unsigned char *);
+__u8 *smb_encode_smb_length(__u8 *, __u32);
+__u8 *smb_setup_header(struct smb_sb_info *, __u8, __u16, __u16);
+int smb_get_rsize(struct smb_sb_info *);
+int smb_get_wsize(struct smb_sb_info *);
+int smb_newconn(struct smb_sb_info *, struct smb_conn_opt *);
+int smb_errno(struct smb_sb_info *);
+int smb_close(struct inode *);
+void smb_close_dentry(struct dentry *);
+int smb_close_fileid(struct dentry *, __u16);
+int smb_open(struct dentry *, int);
+int smb_proc_read(struct dentry *, off_t, int, char *);
+int smb_proc_write(struct dentry *, off_t, int, const char *);
+int smb_proc_create(struct dentry *, __u16, time_t, __u16 *);
+int smb_proc_mv(struct dentry *, struct dentry *);
+int smb_proc_mkdir(struct dentry *);
+int smb_proc_rmdir(struct dentry *);
+int smb_proc_unlink(struct dentry *);
+int smb_proc_readdir(struct dentry *, int, void *);
+int smb_proc_getattr(struct dentry *, struct smb_fattr *);
+int smb_proc_setattr(struct dentry *, struct smb_fattr *);
+int smb_proc_settime(struct dentry *, struct smb_fattr *);
+int smb_proc_dskattr(struct super_block *, struct statfs *);
+int smb_proc_reconnect(struct smb_sb_info *);
+int smb_proc_connect(struct smb_sb_info *);
+int smb_proc_disconnect(struct smb_sb_info *);
+int smb_proc_trunc(struct smb_sb_info *, __u16, __u32);
+void smb_init_root_dirent(struct smb_sb_info *, struct smb_fattr *);
+
+static inline int
+smb_is_open(struct inode *i)
+{
+	return (i->u.smbfs_i.open == SMB_SERVER(i)->generation);
+}
+
+/* linux/fs/smbfs/sock.c */
+int smb_round_length(int);
+int smb_valid_socket(struct inode *);
+void smb_close_socket(struct smb_sb_info *);
+int smb_release(struct smb_sb_info *server);
+int smb_connect(struct smb_sb_info *server);
+int smb_request(struct smb_sb_info *server);
+int smb_request_read_raw(struct smb_sb_info *, unsigned char *, int);
+int smb_request_write_raw(struct smb_sb_info *, unsigned const char *, int);
+int smb_catch_keepalive(struct smb_sb_info *server);
+int smb_dont_catch_keepalive(struct smb_sb_info *server);
+int smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
+		       int ldata, unsigned char *data,
+		       int lparam, unsigned char *param,
+		       int *lrdata, unsigned char **rdata,
+		       int *lrparam, unsigned char **rparam);
+
+/* fs/smbfs/cache.c */
+
+/*
+ * The cache index describes the pages mapped starting
+ * at offset PAGE_SIZE.  We keep only a minimal amount
+ * of information here.
+ */
+struct cache_index {
+	unsigned short num_entries;
+	unsigned short space;
+	struct cache_block * block;
+};
+
+#define NINDEX (PAGE_SIZE-64)/sizeof(struct cache_index)
+/*
+ * The cache head is mapped as the page at offset 0.
+ */
+struct cache_head {
+	int	valid;
+	int	status;		/* error code or 0 */
+	int	entries;	/* total entries */
+	int	pages;		/* number of data pages */
+	int	idx;		/* index of current data page */
+	struct cache_index index[NINDEX];
+};
+
+/*
+ * An array of cache_entry structures holds information
+ * for each object in the cache_block.
+ */
+struct cache_entry {
+	ino_t ino;
+	unsigned short namelen;
+	unsigned short offset;
+};
+
+/*
+ * The cache blocks hold the actual data.  The entry table grows up
+ * while the names grow down, and we have space until they meet.
+ */
+struct cache_block {
+	union {
+		struct cache_entry table[1];
+		char	names[PAGE_SIZE];
+	} cb_data;
+};
+
+/*
+ * To return an entry, we can pass a reference to the
+ * name instead of having to copy it.
+ */
+struct cache_dirent {
+	ino_t ino;
+	unsigned long pos;
+	int len;
+	char * name;
+};
+
+struct cache_head * smb_get_dircache(struct dentry *);
+void smb_init_dircache(struct cache_head *);
+void smb_free_dircache(struct cache_head *);
+int  smb_refill_dircache(struct cache_head *, struct dentry *);
+void smb_add_to_cache(struct cache_head *, struct cache_dirent *, off_t);
+int  smb_find_in_cache(struct cache_head *, off_t, struct cache_dirent *);
+void smb_invalid_dir_cache(struct inode *);
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_SMB_FS_H */
diff -urN samba-1.9.18p10-orig/source/smb_mount.h samba-1.9.18p10/source/smb_mount.h
--- samba-1.9.18p10-orig/source/smb_mount.h	Wed Dec 31 16:00:00 1969
+++ samba-1.9.18p10/source/smb_mount.h	Thu Sep  3 12:54:45 1998
@@ -0,0 +1,26 @@
+/*
+ *  smb_mount.h
+ *
+ *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
+ *  Copyright (C) 1997 by Volker Lendecke
+ *
+ */
+
+#ifndef _LINUX_SMB_MOUNT_H
+#define _LINUX_SMB_MOUNT_H
+
+#include <linux/types.h>
+
+#define SMB_MOUNT_VERSION 6
+
+struct smb_mount_data {
+	int version;
+        __kernel_uid_t mounted_uid;      /* Who may umount() this filesystem? */
+
+        __kernel_uid_t uid;
+        __kernel_gid_t gid;
+        __kernel_mode_t file_mode;
+        __kernel_mode_t dir_mode;
+};
+
+#endif
diff -urN samba-1.9.18p10-orig/source/smbmnt.c samba-1.9.18p10/source/smbmnt.c
--- samba-1.9.18p10-orig/source/smbmnt.c	Fri Jan 23 00:30:04 1998
+++ samba-1.9.18p10/source/smbmnt.c	Thu Sep  3 13:35:16 1998
@@ -27,9 +27,11 @@
 #include <sys/mount.h>
 #include <mntent.h>
 
-#include <linux/fs.h>
-#include <linux/smb.h>
-#include <linux/smb_mount.h>
+#ifndef GLIBC2 /* libc5 doesn't define mount magic numbers for us, but Glibc2 does */
+	#include <linux/fs.h> /* breaks Glibc2 */
+#endif
+/* #include <linux/smb.h> */
+#include "smb_mount.h"
 
 #include <asm/unistd.h>
 
diff -urN samba-1.9.18p10-orig/source/smbmount.c samba-1.9.18p10/source/smbmount.c
--- samba-1.9.18p10-orig/source/smbmount.c	Tue May 12 15:52:51 1998
+++ samba-1.9.18p10/source/smbmount.c	Thu Sep  3 12:54:45 1998
@@ -30,7 +30,7 @@
 #endif
 
 #include "includes.h"
-#include <linux/smb_fs.h>
+#include "smb_fs.h"
 static struct smb_conn_opt conn_options;
 
 #ifndef REGISTER
diff -urN samba-1.9.18p10-orig/source/smbumount.c samba-1.9.18p10/source/smbumount.c
--- samba-1.9.18p10-orig/source/smbumount.c	Mon Jun 15 10:32:32 1998
+++ samba-1.9.18p10/source/smbumount.c	Thu Sep  3 12:54:45 1998
@@ -28,10 +28,10 @@
 #include <mntent.h>
 
 #include <sys/ioctl.h>
-#include <linux/fs.h>
-#include <linux/smb.h>
-#include <linux/smb_mount.h>
-#include <linux/smb_fs.h>
+/* #include <linux/fs.h> */
+/* #include <linux/smb.h> */
+#include "smb_mount.h"
+#include "smb_fs.h"
 
 #include "includes.h"
 
@@ -47,7 +47,7 @@
 umount_ok(const char *mount_point)
 {
         int fid = open(mount_point, O_RDONLY, 0);
-        uid_t mount_uid;
+        __kernel_uid_t mount_uid;
 
         if (fid == -1) {
                 fprintf(stderr, "Could not open %s: %s\n",
@@ -94,7 +94,7 @@
 	if (realpath (path, canonical))
 		return canonical;
 
-	pstrcpy (canonical, path);
+	pstrcpy (canonical, (char *) path);
 	return canonical;
 }
 


More information about the samba mailing list