diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-17 13:25:08 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-17 13:25:08 +0000 |
commit | 59223edaa18759982db0a8aced0e77457d10c68e (patch) | |
tree | 89354903b01fa0a447bffeefe00df3044495db2e /fs/smbfs | |
parent | db7d4daea91e105e3859cf461d7e53b9b77454b2 (diff) |
Merge with Linux 2.3.6. Sorry, this isn't tested on silicon, I don't
have a MIPS box at hand.
Diffstat (limited to 'fs/smbfs')
-rw-r--r-- | fs/smbfs/dir.c | 2 | ||||
-rw-r--r-- | fs/smbfs/file.c | 30 | ||||
-rw-r--r-- | fs/smbfs/inode.c | 52 |
3 files changed, 47 insertions, 37 deletions
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 4f942db80..b820642fe 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -318,7 +318,7 @@ smb_renew_times(struct dentry * dentry) for (;;) { dentry->d_time = jiffies; - if (dentry == dentry->d_parent) + if (IS_ROOT(dentry)) break; dentry = dentry->d_parent; } diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index aff45ef9b..2611ceb61 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -188,13 +188,13 @@ smb_writepage(struct file *file, struct page *page) } static int -smb_updatepage(struct file *file, struct page *page, unsigned long offset, unsigned int count, int sync) +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, sync=%d)\n", + pr_debug("SMBFS: smb_updatepage(%s/%s %d@%ld)\n", dentry->d_parent->d_name.name, dentry->d_name.name, - count, page->offset+offset, sync); + count, page->offset+offset); return smb_writepage_sync(dentry, page, offset, count); } @@ -256,6 +256,26 @@ out: return status; } +/* + * This does the "real" work of the write. The generic routine has + * allocated the page, locked it, done all the page alignment stuff + * calculations etc. Now we should just copy the data from user + * space and write it back to the real medium.. + * + * 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 long smb_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf) +{ + long status; + + bytes -= copy_from_user((u8*)page_address(page) + offset, buf, bytes); + status = -EFAULT; + if (bytes) + status = smb_updatepage(file, page, offset, bytes); + return status; +} + /* * Write to a file (through the page cache). */ @@ -287,7 +307,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, result); if (count > 0) { - result = generic_file_write(file, buf, count, ppos); + result = generic_file_write(file, buf, count, ppos, smb_write_one_page); #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, @@ -386,6 +406,6 @@ struct inode_operations smb_file_inode_operations = NULL, /* truncate */ smb_file_permission, /* permission */ NULL, /* smap */ - smb_updatepage, /* updatepage */ + NULL, /* updatepage */ smb_revalidate_inode, /* revalidate */ }; diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 1a278911a..d43292af5 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -36,6 +36,7 @@ static void smb_put_inode(struct inode *); static void smb_delete_inode(struct inode *); static void smb_put_super(struct super_block *); static int smb_statfs(struct super_block *, struct statfs *, int); +static void smb_set_inode_attr(struct inode *, struct smb_fattr *); static struct super_operations smb_sops = { @@ -67,9 +68,7 @@ smb_invent_inos(unsigned long n) return ino; } -static struct smb_fattr *read_fattr = NULL; -static struct semaphore read_semaphore = MUTEX; - +/* We are always generating a new inode here */ struct inode * smb_iget(struct super_block *sb, struct smb_fattr *fattr) { @@ -77,11 +76,19 @@ smb_iget(struct super_block *sb, struct smb_fattr *fattr) pr_debug("smb_iget: %p\n", fattr); - down(&read_semaphore); - read_fattr = fattr; - result = iget(sb, fattr->f_ino); - read_fattr = NULL; - up(&read_semaphore); + result = get_empty_inode(); + result->i_sb = sb; + result->i_dev = sb->s_dev; + result->i_ino = fattr->f_ino; + memset(&(result->u.smbfs_i), 0, sizeof(result->u.smbfs_i)); + smb_set_inode_attr(result, fattr); + if (S_ISREG(result->i_mode)) + result->i_op = &smb_file_inode_operations; + else if (S_ISDIR(result->i_mode)) + result->i_op = &smb_dir_inode_operations; + else + result->i_op = NULL; + insert_inode_hash(result); return result; } @@ -147,24 +154,9 @@ smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) static void smb_read_inode(struct inode *inode) { - pr_debug("smb_iget: %p\n", read_fattr); - - if (!read_fattr || inode->i_ino != read_fattr->f_ino) - { - printk("smb_read_inode called from invalid point\n"); - return; - } - - inode->i_dev = inode->i_sb->s_dev; - memset(&(inode->u.smbfs_i), 0, sizeof(inode->u.smbfs_i)); - smb_set_inode_attr(inode, read_fattr); - - if (S_ISREG(inode->i_mode)) - inode->i_op = &smb_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &smb_dir_inode_operations; - else - inode->i_op = NULL; + /* Now it can be called only by NFS */ + printk("smb_read_inode called from invalid point\n"); + return; } /* @@ -362,8 +354,8 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) sb->s_op = &smb_sops; sb->u.smbfs_sb.sock_file = NULL; - sb->u.smbfs_sb.sem = MUTEX; - sb->u.smbfs_sb.wait = NULL; + init_MUTEX(&sb->u.smbfs_sb.sem); + init_waitqueue_head(&sb->u.smbfs_sb.wait); sb->u.smbfs_sb.conn_pid = 0; sb->u.smbfs_sb.state = CONN_INVALID; /* no connection yet */ sb->u.smbfs_sb.generation = 0; @@ -410,7 +402,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) if (!root_inode) goto out_no_root; - sb->s_root = d_alloc_root(root_inode, NULL); + sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) goto out_no_root; @@ -609,8 +601,6 @@ init_module(void) smb_current_vmalloced = 0; #endif - read_semaphore = MUTEX; - return init_smb_fs(); } |