X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Fsmbfs%2Ffile.c;h=92d5e8ffb63923062680d09906f8baa7ad53d8c8;hb=9a1607071c293e48b08bd703733480b1d55c7b93;hp=50784d13c87b55a542d9db3dce156ede054b5a1a;hpb=543ade1fc901db4c3dbe9fb27241fb977f1f3eea;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 50784d1..92d5e8f 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -102,7 +103,7 @@ static int smb_readpage(struct file *file, struct page *page) { int error; - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; page_cache_get(page); error = smb_readpage_sync(dentry, page); @@ -205,7 +206,7 @@ static int smb_updatepage(struct file *file, struct page *page, unsigned long offset, unsigned int count) { - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count, ((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset); @@ -218,7 +219,7 @@ smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct file * file = iocb->ki_filp; - struct dentry * dentry = file->f_dentry; + struct dentry * dentry = file->f_path.dentry; ssize_t status; VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), @@ -233,7 +234,7 @@ smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov, VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n", (long)dentry->d_inode->i_size, - dentry->d_inode->i_flags, dentry->d_inode->i_atime); + dentry->d_inode->i_flags, dentry->d_inode->i_atime.tv_sec); status = generic_file_aio_read(iocb, iov, nr_segs, pos); out: @@ -243,7 +244,7 @@ out: static int smb_file_mmap(struct file * file, struct vm_area_struct * vma) { - struct dentry * dentry = file->f_dentry; + struct dentry * dentry = file->f_path.dentry; int status; VERBOSE("file %s/%s, address %lu - %lu\n", @@ -261,13 +262,14 @@ out: } static ssize_t -smb_file_sendfile(struct file *file, loff_t *ppos, - size_t count, read_actor_t actor, void *target) +smb_file_splice_read(struct file *file, loff_t *ppos, + struct pipe_inode_info *pipe, size_t count, + unsigned int flags) { - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; ssize_t status; - VERBOSE("file %s/%s, pos=%Ld, count=%d\n", + VERBOSE("file %s/%s, pos=%Ld, count=%lu\n", DENTRY_PATH(dentry), *ppos, count); status = smb_revalidate_inode(dentry); @@ -276,7 +278,7 @@ smb_file_sendfile(struct file *file, loff_t *ppos, DENTRY_PATH(dentry), status); goto out; } - status = generic_file_sendfile(file, ppos, count, actor, target); + status = generic_file_splice_read(file, ppos, pipe, count, flags); out: return status; } @@ -290,29 +292,45 @@ out: * 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 int smb_prepare_write(struct file *file, struct page *page, - unsigned offset, unsigned to) +static int smb_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) { + pgoff_t index = pos >> PAGE_CACHE_SHIFT; + *pagep = grab_cache_page_write_begin(mapping, index, flags); + if (!*pagep) + return -ENOMEM; return 0; } -static int smb_commit_write(struct file *file, struct page *page, - unsigned offset, unsigned to) +static int smb_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) { int status; + unsigned offset = pos & (PAGE_CACHE_SIZE - 1); - status = -EFAULT; lock_kernel(); - status = smb_updatepage(file, page, offset, to-offset); + status = smb_updatepage(file, page, offset, copied); unlock_kernel(); + + if (!status) { + if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE) + SetPageUptodate(page); + status = copied; + } + + unlock_page(page); + page_cache_release(page); + return status; } const struct address_space_operations smb_file_aops = { .readpage = smb_readpage, .writepage = smb_writepage, - .prepare_write = smb_prepare_write, - .commit_write = smb_commit_write + .write_begin = smb_write_begin, + .write_end = smb_write_end, }; /* @@ -323,7 +341,7 @@ smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct file * file = iocb->ki_filp; - struct dentry * dentry = file->f_dentry; + struct dentry * dentry = file->f_path.dentry; ssize_t result; VERBOSE("file %s/%s, count=%lu@%lu\n", @@ -345,7 +363,8 @@ smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov, result = generic_file_aio_write(iocb, iov, nr_segs, pos); VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", (long) file->f_pos, (long) dentry->d_inode->i_size, - dentry->d_inode->i_mtime, dentry->d_inode->i_atime); + dentry->d_inode->i_mtime.tv_sec, + dentry->d_inode->i_atime.tv_sec); } out: return result; @@ -355,7 +374,7 @@ static int smb_file_open(struct inode *inode, struct file * file) { int result; - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; int smb_mode = (file->f_mode & O_ACCMODE) - 1; lock_kernel(); @@ -389,7 +408,7 @@ smb_file_release(struct inode *inode, struct file * file) * privileges, so we need our own check for this. */ static int -smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) +smb_file_permission(struct inode *inode, int mask) { int mode = inode->i_mode; int error = 0; @@ -398,14 +417,23 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) /* Look at user permissions */ mode >>= 6; - if ((mode & 7 & mask) != mask) + if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC)) error = -EACCES; return error; } +static loff_t smb_remote_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret; + lock_kernel(); + ret = generic_file_llseek_unlocked(file, offset, origin); + unlock_kernel(); + return ret; +} + const struct file_operations smb_file_operations = { - .llseek = remote_llseek, + .llseek = smb_remote_llseek, .read = do_sync_read, .aio_read = smb_file_aio_read, .write = do_sync_write, @@ -415,10 +443,10 @@ const struct file_operations smb_file_operations = .open = smb_file_open, .release = smb_file_release, .fsync = smb_fsync, - .sendfile = smb_file_sendfile, + .splice_read = smb_file_splice_read, }; -struct inode_operations smb_file_inode_operations = +const struct inode_operations smb_file_inode_operations = { .permission = smb_file_permission, .getattr = smb_getattr,