at v2.6.13 423 lines 10 kB view raw
1/* 2 * file.c 3 * 4 * Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke 5 * Copyright (C) 1997 by Volker Lendecke 6 * 7 * Please add a note about your changes to smbfs in the ChangeLog file. 8 */ 9 10#include <linux/time.h> 11#include <linux/kernel.h> 12#include <linux/errno.h> 13#include <linux/fcntl.h> 14#include <linux/stat.h> 15#include <linux/mm.h> 16#include <linux/slab.h> 17#include <linux/pagemap.h> 18#include <linux/smp_lock.h> 19#include <linux/net.h> 20 21#include <asm/uaccess.h> 22#include <asm/system.h> 23 24#include <linux/smbno.h> 25#include <linux/smb_fs.h> 26 27#include "smb_debug.h" 28#include "proto.h" 29 30static int 31smb_fsync(struct file *file, struct dentry * dentry, int datasync) 32{ 33 struct smb_sb_info *server = server_from_dentry(dentry); 34 int result; 35 36 VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry)); 37 38 /* 39 * The VFS will writepage() all dirty pages for us, but we 40 * should send a SMBflush to the server, letting it know that 41 * we want things synchronized with actual storage. 42 * 43 * Note: this function requires all pages to have been written already 44 * (should be ok with writepage_sync) 45 */ 46 result = smb_proc_flush(server, SMB_I(dentry->d_inode)->fileid); 47 return result; 48} 49 50/* 51 * Read a page synchronously. 52 */ 53static int 54smb_readpage_sync(struct dentry *dentry, struct page *page) 55{ 56 char *buffer = kmap(page); 57 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; 58 struct smb_sb_info *server = server_from_dentry(dentry); 59 unsigned int rsize = smb_get_rsize(server); 60 int count = PAGE_SIZE; 61 int result; 62 63 VERBOSE("file %s/%s, count=%d@%Ld, rsize=%d\n", 64 DENTRY_PATH(dentry), count, offset, rsize); 65 66 result = smb_open(dentry, SMB_O_RDONLY); 67 if (result < 0) 68 goto io_error; 69 70 do { 71 if (count < rsize) 72 rsize = count; 73 74 result = server->ops->read(dentry->d_inode,offset,rsize,buffer); 75 if (result < 0) 76 goto io_error; 77 78 count -= result; 79 offset += result; 80 buffer += result; 81 dentry->d_inode->i_atime = 82 current_fs_time(dentry->d_inode->i_sb); 83 if (result < rsize) 84 break; 85 } while (count); 86 87 memset(buffer, 0, count); 88 flush_dcache_page(page); 89 SetPageUptodate(page); 90 result = 0; 91 92io_error: 93 kunmap(page); 94 unlock_page(page); 95 return result; 96} 97 98/* 99 * We are called with the page locked and we unlock it when done. 100 */ 101static int 102smb_readpage(struct file *file, struct page *page) 103{ 104 int error; 105 struct dentry *dentry = file->f_dentry; 106 107 page_cache_get(page); 108 error = smb_readpage_sync(dentry, page); 109 page_cache_release(page); 110 return error; 111} 112 113/* 114 * Write a page synchronously. 115 * Offset is the data offset within the page. 116 */ 117static int 118smb_writepage_sync(struct inode *inode, struct page *page, 119 unsigned long pageoffset, unsigned int count) 120{ 121 loff_t offset; 122 char *buffer = kmap(page) + pageoffset; 123 struct smb_sb_info *server = server_from_inode(inode); 124 unsigned int wsize = smb_get_wsize(server); 125 int ret = 0; 126 127 offset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageoffset; 128 VERBOSE("file ino=%ld, fileid=%d, count=%d@%Ld, wsize=%d\n", 129 inode->i_ino, SMB_I(inode)->fileid, count, offset, wsize); 130 131 do { 132 int write_ret; 133 134 if (count < wsize) 135 wsize = count; 136 137 write_ret = server->ops->write(inode, offset, wsize, buffer); 138 if (write_ret < 0) { 139 PARANOIA("failed write, wsize=%d, write_ret=%d\n", 140 wsize, write_ret); 141 ret = write_ret; 142 break; 143 } 144 /* N.B. what if result < wsize?? */ 145#ifdef SMBFS_PARANOIA 146 if (write_ret < wsize) 147 PARANOIA("short write, wsize=%d, write_ret=%d\n", 148 wsize, write_ret); 149#endif 150 buffer += wsize; 151 offset += wsize; 152 count -= wsize; 153 /* 154 * Update the inode now rather than waiting for a refresh. 155 */ 156 inode->i_mtime = inode->i_atime = current_fs_time(inode->i_sb); 157 SMB_I(inode)->flags |= SMB_F_LOCALWRITE; 158 if (offset > inode->i_size) 159 inode->i_size = offset; 160 } while (count); 161 162 kunmap(page); 163 return ret; 164} 165 166/* 167 * Write a page to the server. This will be used for NFS swapping only 168 * (for now), and we currently do this synchronously only. 169 * 170 * We are called with the page locked and we unlock it when done. 171 */ 172static int 173smb_writepage(struct page *page, struct writeback_control *wbc) 174{ 175 struct address_space *mapping = page->mapping; 176 struct inode *inode; 177 unsigned long end_index; 178 unsigned offset = PAGE_CACHE_SIZE; 179 int err; 180 181 if (!mapping) 182 BUG(); 183 inode = mapping->host; 184 if (!inode) 185 BUG(); 186 187 end_index = inode->i_size >> PAGE_CACHE_SHIFT; 188 189 /* easy case */ 190 if (page->index < end_index) 191 goto do_it; 192 /* things got complicated... */ 193 offset = inode->i_size & (PAGE_CACHE_SIZE-1); 194 /* OK, are we completely out? */ 195 if (page->index >= end_index+1 || !offset) 196 return 0; /* truncated - don't care */ 197do_it: 198 page_cache_get(page); 199 err = smb_writepage_sync(inode, page, 0, offset); 200 SetPageUptodate(page); 201 unlock_page(page); 202 page_cache_release(page); 203 return err; 204} 205 206static int 207smb_updatepage(struct file *file, struct page *page, unsigned long offset, 208 unsigned int count) 209{ 210 struct dentry *dentry = file->f_dentry; 211 212 DEBUG1("(%s/%s %d@%ld)\n", DENTRY_PATH(dentry), 213 count, (page->index << PAGE_CACHE_SHIFT)+offset); 214 215 return smb_writepage_sync(dentry->d_inode, page, offset, count); 216} 217 218static ssize_t 219smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) 220{ 221 struct dentry * dentry = file->f_dentry; 222 ssize_t status; 223 224 VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), 225 (unsigned long) count, (unsigned long) *ppos); 226 227 status = smb_revalidate_inode(dentry); 228 if (status) { 229 PARANOIA("%s/%s validation failed, error=%Zd\n", 230 DENTRY_PATH(dentry), status); 231 goto out; 232 } 233 234 VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n", 235 (long)dentry->d_inode->i_size, 236 dentry->d_inode->i_flags, dentry->d_inode->i_atime); 237 238 status = generic_file_read(file, buf, count, ppos); 239out: 240 return status; 241} 242 243static int 244smb_file_mmap(struct file * file, struct vm_area_struct * vma) 245{ 246 struct dentry * dentry = file->f_dentry; 247 int status; 248 249 VERBOSE("file %s/%s, address %lu - %lu\n", 250 DENTRY_PATH(dentry), vma->vm_start, vma->vm_end); 251 252 status = smb_revalidate_inode(dentry); 253 if (status) { 254 PARANOIA("%s/%s validation failed, error=%d\n", 255 DENTRY_PATH(dentry), status); 256 goto out; 257 } 258 status = generic_file_mmap(file, vma); 259out: 260 return status; 261} 262 263static ssize_t 264smb_file_sendfile(struct file *file, loff_t *ppos, 265 size_t count, read_actor_t actor, void *target) 266{ 267 struct dentry *dentry = file->f_dentry; 268 ssize_t status; 269 270 VERBOSE("file %s/%s, pos=%Ld, count=%d\n", 271 DENTRY_PATH(dentry), *ppos, count); 272 273 status = smb_revalidate_inode(dentry); 274 if (status) { 275 PARANOIA("%s/%s validation failed, error=%Zd\n", 276 DENTRY_PATH(dentry), status); 277 goto out; 278 } 279 status = generic_file_sendfile(file, ppos, count, actor, target); 280out: 281 return status; 282} 283 284/* 285 * This does the "real" work of the write. The generic routine has 286 * allocated the page, locked it, done all the page alignment stuff 287 * calculations etc. Now we should just copy the data from user 288 * space and write it back to the real medium.. 289 * 290 * If the writer ends up delaying the write, the writer needs to 291 * increment the page use counts until he is done with the page. 292 */ 293static int smb_prepare_write(struct file *file, struct page *page, 294 unsigned offset, unsigned to) 295{ 296 return 0; 297} 298 299static int smb_commit_write(struct file *file, struct page *page, 300 unsigned offset, unsigned to) 301{ 302 int status; 303 304 status = -EFAULT; 305 lock_kernel(); 306 status = smb_updatepage(file, page, offset, to-offset); 307 unlock_kernel(); 308 return status; 309} 310 311struct address_space_operations smb_file_aops = { 312 .readpage = smb_readpage, 313 .writepage = smb_writepage, 314 .prepare_write = smb_prepare_write, 315 .commit_write = smb_commit_write 316}; 317 318/* 319 * Write to a file (through the page cache). 320 */ 321static ssize_t 322smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 323{ 324 struct dentry * dentry = file->f_dentry; 325 ssize_t result; 326 327 VERBOSE("file %s/%s, count=%lu@%lu\n", 328 DENTRY_PATH(dentry), 329 (unsigned long) count, (unsigned long) *ppos); 330 331 result = smb_revalidate_inode(dentry); 332 if (result) { 333 PARANOIA("%s/%s validation failed, error=%Zd\n", 334 DENTRY_PATH(dentry), result); 335 goto out; 336 } 337 338 result = smb_open(dentry, SMB_O_WRONLY); 339 if (result) 340 goto out; 341 342 if (count > 0) { 343 result = generic_file_write(file, buf, count, ppos); 344 VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", 345 (long) file->f_pos, (long) dentry->d_inode->i_size, 346 dentry->d_inode->i_mtime, dentry->d_inode->i_atime); 347 } 348out: 349 return result; 350} 351 352static int 353smb_file_open(struct inode *inode, struct file * file) 354{ 355 int result; 356 struct dentry *dentry = file->f_dentry; 357 int smb_mode = (file->f_mode & O_ACCMODE) - 1; 358 359 lock_kernel(); 360 result = smb_open(dentry, smb_mode); 361 if (result) 362 goto out; 363 SMB_I(inode)->openers++; 364out: 365 unlock_kernel(); 366 return result; 367} 368 369static int 370smb_file_release(struct inode *inode, struct file * file) 371{ 372 lock_kernel(); 373 if (!--SMB_I(inode)->openers) { 374 /* We must flush any dirty pages now as we won't be able to 375 write anything after close. mmap can trigger this. 376 "openers" should perhaps include mmap'ers ... */ 377 filemap_fdatawrite(inode->i_mapping); 378 filemap_fdatawait(inode->i_mapping); 379 smb_close(inode); 380 } 381 unlock_kernel(); 382 return 0; 383} 384 385/* 386 * Check whether the required access is compatible with 387 * an inode's permission. SMB doesn't recognize superuser 388 * privileges, so we need our own check for this. 389 */ 390static int 391smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) 392{ 393 int mode = inode->i_mode; 394 int error = 0; 395 396 VERBOSE("mode=%x, mask=%x\n", mode, mask); 397 398 /* Look at user permissions */ 399 mode >>= 6; 400 if ((mode & 7 & mask) != mask) 401 error = -EACCES; 402 return error; 403} 404 405struct file_operations smb_file_operations = 406{ 407 .llseek = remote_llseek, 408 .read = smb_file_read, 409 .write = smb_file_write, 410 .ioctl = smb_ioctl, 411 .mmap = smb_file_mmap, 412 .open = smb_file_open, 413 .release = smb_file_release, 414 .fsync = smb_fsync, 415 .sendfile = smb_file_sendfile, 416}; 417 418struct inode_operations smb_file_inode_operations = 419{ 420 .permission = smb_file_permission, 421 .getattr = smb_getattr, 422 .setattr = smb_notify_change, 423};