static void smb_put_inode(struct inode *inode) { struct smb_dirent *finfo = SMB_FINFO(inode); if (finfo->opened != 0) { /* smb_proc_close wants mtime in finfo */ finfo->mtime = inode->i_mtime; if (smb_proc_close(SMB_SERVER(inode), finfo)) { /* We can't do anything but complain. */ printk("smb_put_inode: could not close\n"); } } smb_free_inode_info(SMB_INOP(inode)); if (S_ISDIR(inode->i_mode)) { DDPRINTK("smb_put_inode: put directory %ld\n", inode->i_ino); smb_invalid_dir_cache(inode->i_ino); } clear_inode(inode); }
/* DO MORE */ int smb_notify_change(struct inode *inode, struct iattr *attr) { int error = 0; if ((error = inode_change_ok(inode, attr)) < 0) return error; if (((attr->ia_valid & ATTR_UID) && (attr->ia_uid != SMB_SERVER(inode)->m.uid))) return -EPERM; if (((attr->ia_valid & ATTR_GID) && (attr->ia_uid != SMB_SERVER(inode)->m.gid))) return -EPERM; if (((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)))) return -EPERM; if ((attr->ia_valid & ATTR_SIZE) != 0) { if ((error = smb_make_open(inode, O_WRONLY)) < 0) goto fail; if ((error = smb_proc_trunc(SMB_SERVER(inode), SMB_FINFO(inode)->fileid, attr->ia_size)) < 0) goto fail; } if ((attr->ia_valid & (ATTR_CTIME | ATTR_MTIME | ATTR_ATIME)) != 0) { struct smb_dirent finfo; finfo.attr = 0; if ((attr->ia_valid & ATTR_CTIME) != 0) finfo.ctime = attr->ia_ctime; else finfo.ctime = inode->i_ctime; if ((attr->ia_valid & ATTR_MTIME) != 0) finfo.mtime = attr->ia_mtime; else finfo.mtime = inode->i_mtime; if ((attr->ia_valid & ATTR_ATIME) != 0) finfo.atime = attr->ia_atime; else finfo.atime = inode->i_atime; if ((error = smb_proc_setattr(SMB_SERVER(inode), inode, &finfo)) >= 0) { inode->i_ctime = finfo.ctime; inode->i_mtime = finfo.mtime; inode->i_atime = finfo.atime; } } fail: smb_invalid_dir_cache((unsigned long)(SMB_INOP(inode)->dir)); return error; }
/* * Fill in the supplied page for mmap */ static unsigned long smb_file_mmap_nopage(struct vm_area_struct *area, unsigned long address, int no_share) { struct inode *inode = area->vm_inode; unsigned long page; unsigned int clear; unsigned long tmp; int n; int i; int pos; page = __get_free_page(GFP_KERNEL); if (!page) return 0; address &= PAGE_MASK; pos = address - area->vm_start + area->vm_offset; clear = 0; if (address + PAGE_SIZE > area->vm_end) { clear = address + PAGE_SIZE - area->vm_end; } /* what we can read in one go */ n = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 3 - 10; if (smb_make_open(inode, O_RDONLY) < 0) { clear = PAGE_SIZE; } else { for (i = 0; i < (PAGE_SIZE - clear); i += n) { int hunk, result; hunk = PAGE_SIZE - i; if (hunk > n) hunk = n; DDPRINTK("smb_file_mmap_nopage: reading\n"); DDPRINTK("smb_file_mmap_nopage: pos = %d\n", pos); result = smb_proc_read(SMB_SERVER(inode), SMB_FINFO(inode), pos, hunk, (char *) (page + i), 0); DDPRINTK("smb_file_mmap_nopage: result= %d\n", result); if (result < 0) break; pos += result; if (result < n) { i += result; break; } } } tmp = page + PAGE_SIZE; while (clear--) { *(char *) --tmp = 0; } return page; }