patch-2.4.25 linux-2.4.25/fs/smbfs/inode.c

Next file: linux-2.4.25/fs/smbfs/proc.c
Previous file: linux-2.4.25/fs/smbfs/file.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.24/fs/smbfs/inode.c linux-2.4.25/fs/smbfs/inode.c
@@ -79,8 +79,16 @@
 		result->i_fop = &smb_file_operations;
 		result->i_data.a_ops = &smb_file_aops;
 	} else if (S_ISDIR(result->i_mode)) {
-		result->i_op = &smb_dir_inode_operations;
+		struct smb_sb_info *server = &(sb->u.smbfs_sb);
+		if (server->opt.capabilities & SMB_CAP_UNIX)
+			result->i_op = &smb_dir_inode_operations_unix;
+		else
+			result->i_op = &smb_dir_inode_operations;
 		result->i_fop = &smb_dir_operations;
+	} else if(S_ISLNK(result->i_mode)) {
+		result->i_op = &smb_link_inode_operations;
+	} else {
+		init_special_inode(result, result->i_mode, fattr->f_rdev);
 	}
 	insert_inode_hash(result);
 	return result;
@@ -187,7 +195,14 @@
 		/*
 		 * Check whether the type part of the mode changed,
 		 * and don't update the attributes if it did.
+		 *
+		 * And don't dick with the root inode
 		 */
+		if (inode->i_ino == 2)
+			return error;
+		if (S_ISLNK(inode->i_mode))
+			return error;	/* VFS will deal with it */
+
 		if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {
 			smb_set_inode_attr(inode, &fattr);
 		} else {
@@ -424,6 +439,7 @@
 	struct inode *root_inode;
 	struct smb_fattr root;
 	int ver;
+	void *mem;
 
 	if (!raw_data)
 		goto out_no_data;
@@ -435,6 +451,7 @@
 
 	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
 	sb->s_blocksize_bits = 10;
+	sb->s_maxbytes = MAX_NON_LFS;
 	sb->s_magic = SMB_SUPER_MAGIC;
 	sb->s_op = &smb_sops;
 
@@ -462,10 +479,13 @@
 
 	/* Allocate the mount data structure */
 	/* FIXME: merge this with the other malloc and get a whole page? */
-	mnt = smb_kmalloc(sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
-	if (!mnt)
+	mem = smb_kmalloc(sizeof(struct smb_ops) +
+			  sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
+	if (!mem)
 		goto out_no_mount;
-	server->mnt = mnt;
+	server->mnt = mnt = mem;
+	server->ops = mem + sizeof(struct smb_mount_data_kernel);
+	smb_install_null_ops(server->ops);
 
 	memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
 	strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
@@ -479,7 +499,6 @@
 		mnt->version = oldmnt->version;
 
 		/* FIXME: is this enough to convert uid/gid's ? */
-		mnt->mounted_uid = oldmnt->mounted_uid;
 		mnt->uid = oldmnt->uid;
 		mnt->gid = oldmnt->gid;
 
@@ -490,10 +509,9 @@
 	} else {
 		if (parse_options(mnt, raw_data))
 			goto out_bad_option;
-
-		mnt->mounted_uid = current->uid;
 	}
 	smb_setcodepage(server, &mnt->codepage);
+	mnt->mounted_uid = current->uid;
 
 	/*
 	 * Display the enabled options
@@ -587,8 +605,7 @@
 		error = smb_open(dentry, O_WRONLY);
 		if (error)
 			goto out;
-		error = smb_proc_trunc(server, inode->u.smbfs_i.fileid,
-					 attr->ia_size);
+		error = server->ops->truncate(inode, attr->ia_size);
 		if (error)
 			goto out;
 		error = vmtruncate(inode, attr->ia_size);
@@ -597,6 +614,16 @@
 		refresh = 1;
 	}
 
+	if (server->opt.capabilities & SMB_CAP_UNIX) {
+		/* For now we don't want to set the size with setattr_unix */
+		attr->ia_valid &= ~ATTR_SIZE;
+		/* FIXME: only call if we actually want to set something? */
+		error = smb_proc_setattr_unix(dentry, attr, 0, 0);
+		if (!error)
+			refresh = 1;
+		goto out;
+	}
+
 	/*
 	 * Initialize the fattr and check for changed fields.
 	 * Note: CTIME under SMB is creation time rather than

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)