Commit de8999dc authored by Urban Widmark's avatar Urban Widmark Committed by Linus Torvalds

[PATCH] smbfs LFS

This patch adds LFS and moves some smb operations into per-protocol level
structs. It wants the nls patch to applied already.
parent 9ef6e588
ChangeLog for smbfs.
2001-08-23 Jochen Dolze <dolze@epcnet.de>
* proc.c: Correct rsize/wsize computation for readX/writeX
2001-0?-?? Urban Widmark <urban@teststation.com>
* *.c: Add LFS
* *.c: Move to a "driver" style handling of different servertypes.
(Not all operations are done this way. yet.)
2001-12-31 Ren Scharfe <l.s.r@web.de>
* inode.c: added smb_show_options to show mount options in /proc/mounts
......
......@@ -187,7 +187,7 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
ctl.filled = 0;
ctl.valid = 1;
read_really:
result = smb_proc_readdir(filp, dirent, filldir, &ctl);
result = server->ops->readdir(filp, dirent, filldir, &ctl);
if (ctl.idx == -1)
goto invalid_cache; /* retry */
ctl.head.end = ctl.fpos - 1;
......
......@@ -55,12 +55,13 @@ static int
smb_readpage_sync(struct dentry *dentry, struct page *page)
{
char *buffer = kmap(page);
unsigned long offset = page->index << PAGE_CACHE_SHIFT;
int rsize = smb_get_rsize(server_from_dentry(dentry));
loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
struct smb_sb_info *server = server_from_dentry(dentry);
unsigned int rsize = smb_get_rsize(server);
int count = PAGE_SIZE;
int result;
VERBOSE("file %s/%s, count=%d@%ld, rsize=%d\n",
VERBOSE("file %s/%s, count=%d@%Ld, rsize=%d\n",
DENTRY_PATH(dentry), count, offset, rsize);
result = smb_open(dentry, SMB_O_RDONLY);
......@@ -74,7 +75,7 @@ smb_readpage_sync(struct dentry *dentry, struct page *page)
if (count < rsize)
rsize = count;
result = smb_proc_read(dentry->d_inode, offset, rsize, buffer);
result = server->ops->read(dentry->d_inode,offset,rsize,buffer);
if (result < 0)
goto io_error;
......@@ -118,21 +119,23 @@ smb_readpage(struct file *file, struct page *page)
*/
static int
smb_writepage_sync(struct inode *inode, struct page *page,
unsigned long offset, unsigned int count)
unsigned long pageoffset, unsigned int count)
{
char *buffer = kmap(page) + offset;
int wsize = smb_get_wsize(server_from_inode(inode));
loff_t offset;
char *buffer = kmap(page) + pageoffset;
struct smb_sb_info *server = server_from_inode(inode);
unsigned int wsize = smb_get_wsize(server);
int result, written = 0;
offset += page->index << PAGE_CACHE_SHIFT;
VERBOSE("file ino=%ld, fileid=%d, count=%d@%ld, wsize=%d\n",
inode->i_ino, SMB_I(inode)->fileid, count, offset, wsize);
offset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageoffset;
VERBOSE("file ino=%ld, fileid=%d, count=%d@%Ld, wsize=%d\n",
inode->i_ino, inode->u.smbfs_i.fileid, count, offset, wsize);
do {
if (count < wsize)
wsize = count;
result = smb_proc_write(inode, offset, wsize, buffer);
result = server->ops->write(inode, offset, wsize, buffer);
if (result < 0) {
PARANOIA("failed write, wsize=%d, result=%d\n",
wsize, result);
......
......@@ -445,8 +445,7 @@ smb_put_super(struct super_block *sb)
if (server->conn_pid)
kill_proc(server->conn_pid, SIGTERM, 1);
smb_kfree(server->mnt);
smb_kfree(server->temp_buf);
smb_kfree(server->ops);
if (server->packet)
smb_vfree(server->packet);
......@@ -468,6 +467,7 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
struct inode *root_inode;
struct smb_fattr root;
int ver;
void *mem;
if (!raw_data)
goto out_no_data;
......@@ -494,22 +494,29 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
if (!server->packet)
goto out_no_mem;
/* Allocate the global temp buffer */
server->temp_buf = smb_kmalloc(2*SMB_MAXPATHLEN+20, GFP_KERNEL);
if (!server->temp_buf)
/* Allocate the global temp buffer and some superblock helper structs */
VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) +
sizeof(struct smb_mount_data_kernel) +
2*SMB_MAXPATHLEN + 20);
mem = smb_kmalloc(sizeof(struct smb_ops) +
sizeof(struct smb_mount_data_kernel) +
2*SMB_MAXPATHLEN + 20, GFP_KERNEL);
if (!mem)
goto out_no_temp;
server->ops = mem;
server->mnt = mem + sizeof(struct smb_ops);
server->name_buf = mem + sizeof(struct smb_ops) +
sizeof(struct smb_mount_data_kernel);
server->temp_buf = mem + sizeof(struct smb_ops) +
sizeof(struct smb_mount_data_kernel) +
SMB_MAXPATHLEN + 1;
/* Setup NLS stuff */
server->remote_nls = NULL;
server->local_nls = NULL;
server->name_buf = server->temp_buf + SMB_MAXPATHLEN + 20;
/* 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)
goto out_no_mount;
server->mnt = mnt;
mnt = server->mnt;
memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
......@@ -565,9 +572,7 @@ int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
out_no_root:
iput(root_inode);
out_bad_option:
smb_kfree(server->mnt);
out_no_mount:
smb_kfree(server->temp_buf);
smb_kfree(mem);
out_no_temp:
smb_vfree(server->packet);
out_no_mem:
......@@ -630,8 +635,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
error = smb_open(dentry, O_WRONLY);
if (error)
goto out;
error = smb_proc_trunc(server, SMB_I(inode)->fileid,
attr->ia_size);
error = server->ops->truncate(inode, attr->ia_size);
if (error)
goto out;
error = vmtruncate(inode, attr->ia_size);
......
This diff is collapsed.
/*
* Autogenerated with cproto on: Tue Oct 2 20:40:54 CEST 2001
* Autogenerated with cproto on: Thu Nov 22 21:18:04 CET 2001
*/
/* proc.c */
......@@ -14,17 +14,13 @@ extern __u8 *smb_setup_header(struct smb_sb_info *server, __u8 command, __u16 wc
extern int smb_open(struct dentry *dentry, int wish);
extern int smb_close(struct inode *ino);
extern int smb_close_fileid(struct dentry *dentry, __u16 fileid);
extern int smb_proc_read(struct inode *inode, off_t offset, int count, char *data);
extern int smb_proc_write(struct inode *inode, off_t offset, int count, const char *data);
extern int smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid);
extern int smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry);
extern int smb_proc_mkdir(struct dentry *dentry);
extern int smb_proc_rmdir(struct dentry *dentry);
extern int smb_proc_unlink(struct dentry *dentry);
extern int smb_proc_flush(struct smb_sb_info *server, __u16 fileid);
extern int smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length);
extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
extern int smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir, struct smb_cache_control *ctl);
extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr);
......
......@@ -86,7 +86,7 @@ struct smb_fattr {
uid_t f_uid;
gid_t f_gid;
kdev_t f_rdev;
off_t f_size;
loff_t f_size;
time_t f_atime;
time_t f_mtime;
time_t f_ctime;
......
......@@ -117,6 +117,7 @@ smb_kfree(void *obj)
#define SMB_CAP_NT_FIND 0x0200
#define SMB_CAP_DFS 0x1000
#define SMB_CAP_LARGE_READX 0x4000
#define SMB_CAP_LARGE_WRITEX 0x8000
/*
......@@ -159,6 +160,30 @@ struct smb_cache_control {
int filled, valid, idx;
};
#define SMB_OPS_NUM_STATIC 5
struct smb_ops {
int (*read)(struct inode *inode, loff_t offset, int count,
char *data);
int (*write)(struct inode *inode, loff_t offset, int count, const
char *data);
int (*readdir)(struct file *filp, void *dirent, filldir_t filldir,
struct smb_cache_control *ctl);
int (*getattr)(struct smb_sb_info *server, struct dentry *dir,
struct smb_fattr *fattr);
/* int (*setattr)(...); */ /* setattr is really icky! */
int (*truncate)(struct inode *inode, loff_t length);
/* --- --- --- end of "static" entries --- --- --- */
int (*convert)(char *output, int olen,
const char *input, int ilen,
struct nls_table *nls_from,
struct nls_table *nls_to);
};
static inline int
smb_is_open(struct inode *i)
{
......
......@@ -54,8 +54,7 @@ struct smb_sb_info {
to put it on the stack. This points to temp_buf space. */
char *name_buf;
int (*convert)(char *, int, const char *, int,
struct nls_table *, struct nls_table *);
struct smb_ops *ops;
};
......
......@@ -281,4 +281,33 @@
#define TRANSACT2_FINDNOTIFYNEXT 12
#define TRANSACT2_MKDIR 13
/* Information Levels - Shared? */
#define SMB_INFO_STANDARD 1
#define SMB_INFO_QUERY_EA_SIZE 2
#define SMB_INFO_QUERY_EAS_FROM_LIST 3
#define SMB_INFO_QUERY_ALL_EAS 4
#define SMB_INFO_IS_NAME_VALID 6
/* Information Levels - TRANSACT2_FINDFIRST */
#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
#define SMB_FIND_FILE_NAMES_INFO 0x103
#define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104
/* Information Levels - TRANSACT2_QPATHINFO */
#define SMB_QUERY_FILE_BASIC_INFO 0x101
#define SMB_QUERY_FILE_STANDARD_INFO 0x102
#define SMB_QUERY_FILE_EA_INFO 0x103
#define SMB_QUERY_FILE_NAME_INFO 0x104
#define SMB_QUERY_FILE_ALL_INFO 0x107
#define SMB_QUERY_FILE_ALT_NAME_INFO 0x108
#define SMB_QUERY_FILE_STREAM_INFO 0x109
#define SMB_QUERY_FILE_COMPRESSION_INFO 0x10b
/* Information Levels - TRANSACT2_SETFILEINFO */
#define SMB_SET_FILE_BASIC_INFO 0x101
#define SMB_SET_FILE_DISPOSITION_INFO 0x102
#define SMB_SET_FILE_ALLOCATION_INFO 0x103
#define SMB_SET_FILE_END_OF_FILE_INFO 0x104
#endif /* _SMBNO_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment