/* * Force the next attempt to use the cache to be a timeout. * If we can't find the page that's fine, it will cause a refresh. */ void smb_invalid_dir_cache(struct inode * dir) { struct smb_sb_info *server = server_from_inode(dir); union smb_dir_cache *cache = NULL; struct page *page = NULL; page = grab_cache_page(&dir->i_data, 0); if (!page) goto out; if (!PageUptodate(page)) goto out_unlock; cache = kmap(page); cache->head.time = jiffies - SMB_MAX_AGE(server); kunmap(page); SetPageUptodate(page); out_unlock: unlock_page(page); page_cache_release(page); out: return; }
int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { struct smb_sb_info *server = server_from_inode(inode); struct smb_conn_opt opt; int result = -EINVAL; switch (cmd) { case SMB_IOC_GETMOUNTUID: result = put_user(NEW_TO_OLD_UID(server->mnt->mounted_uid), (uid16_t *) arg); break; case SMB_IOC_GETMOUNTUID32: result = put_user(server->mnt->mounted_uid, (uid_t *) arg); break; case SMB_IOC_NEWCONN: /* arg is smb_conn_opt, or NULL if no connection was made */ if (!arg) { result = smb_wakeup(server); break; } result = -EFAULT; if (!copy_from_user(&opt, (void *)arg, sizeof(opt))) result = smb_newconn(server, &opt); break; default: break; } return result; }
/* * Write a page synchronously. * Offset is the data offset within the page. */ static int smb_writepage_sync(struct inode *inode, struct page *page, unsigned long pageoffset, unsigned int count) { 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 ret = 0; offset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageoffset; VERBOSE("file ino=%ld, fileid=%d, count=%d@%Ld, wsize=%d\n", inode->i_ino, SMB_I(inode)->fileid, count, offset, wsize); do { int write_ret; if (count < wsize) wsize = count; write_ret = server->ops->write(inode, offset, wsize, buffer); if (write_ret < 0) { PARANOIA("failed write, wsize=%d, write_ret=%d\n", wsize, write_ret); ret = write_ret; break; } /* N.B. what if result < wsize?? */ #ifdef SMBFS_PARANOIA if (write_ret < wsize) PARANOIA("short write, wsize=%d, write_ret=%d\n", wsize, write_ret); #endif buffer += wsize; offset += wsize; count -= wsize; /* * Update the inode now rather than waiting for a refresh. */ inode->i_mtime = inode->i_atime = current_fs_time(inode->i_sb); SMB_I(inode)->flags |= SMB_F_LOCALWRITE; if (offset > inode->i_size) inode->i_size = offset; } while (count); kunmap(page); return ret; }