From: Marc Fiuczynski Date: Mon, 7 Mar 2005 20:23:50 +0000 (+0000) Subject: Fixed merge goof and incorported the vserver 1.9.2 specific changes. X-Git-Tag: planetlab-3_0-rc14~5 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=2c107a7638ee3b128101bf8fa5e292e96b3e8fad;p=linux-2.6.git Fixed merge goof and incorported the vserver 1.9.2 specific changes. Note that the vserver specific changes are no longer part of 1.9.3 and subsequent versions. --- diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 91bd05377..ee2addb5c 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -72,7 +72,7 @@ struct inode_operations nfs_file_inode_operations = { static int nfs_check_flags(int flags) { - if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT)) + if (flags & (O_APPEND | O_DIRECT)) return -EINVAL; return 0; @@ -89,7 +89,7 @@ nfs_file_open(struct inode *inode, struct file *filp) int res; res = nfs_check_flags(filp->f_flags); - if (res) + if (!res) return res; lock_kernel(); @@ -156,7 +156,163 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) } static ssize_t -nfs_file_sendfile(struct file *f +nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, + read_actor_t actor, void *target) +{ + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; + ssize_t res; + + dfprintk(VFS, "nfs: sendfile(%s/%s, %lu@%Lu)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + (unsigned long) count, (unsigned long long) *ppos); + + res = nfs_revalidate_inode(NFS_SERVER(inode), inode); + if (!res) + res = generic_file_sendfile(filp, ppos, count, actor, target); + return res; +} + +static int +nfs_file_mmap(struct file * file, struct vm_area_struct * vma) +{ + struct dentry *dentry = file->f_dentry; + struct inode *inode = dentry->d_inode; + int status; + + dfprintk(VFS, "nfs: mmap(%s/%s)\n", + dentry->d_parent->d_name.name, dentry->d_name.name); + + status = nfs_revalidate_inode(NFS_SERVER(inode), inode); + if (!status) + status = generic_file_mmap(file, vma); + return status; +} + +/* + * Flush any dirty pages for this process, and check for write errors. + * The return status from this call provides a reliable indication of + * whether any write errors occurred for this process. + */ +static int +nfs_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + struct inode *inode = dentry->d_inode; + int status; + + dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); + + lock_kernel(); + status = nfs_wb_all(inode); + if (!status) { + status = file->f_error; + file->f_error = 0; + } + unlock_kernel(); + 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 int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) +{ + return nfs_flush_incompatible(file, page); +} + +static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) +{ + long status; + + lock_kernel(); + status = nfs_updatepage(file, page, offset, to-offset); + unlock_kernel(); + return status; +} + +struct address_space_operations nfs_file_aops = { + .readpage = nfs_readpage, + .readpages = nfs_readpages, + .set_page_dirty = __set_page_dirty_nobuffers, + .writepage = nfs_writepage, + .writepages = nfs_writepages, + .prepare_write = nfs_prepare_write, + .commit_write = nfs_commit_write, +#ifdef CONFIG_NFS_DIRECTIO + .direct_IO = nfs_direct_IO, +#endif +}; + +/* + * Write to a file (through the page cache). + */ +static ssize_t +nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) +{ + struct dentry * dentry = iocb->ki_filp->f_dentry; + struct inode * inode = dentry->d_inode; + ssize_t result; + +#ifdef CONFIG_NFS_DIRECTIO + if (iocb->ki_filp->f_flags & O_DIRECT) + return nfs_file_direct_write(iocb, buf, count, pos); +#endif + + dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + inode->i_ino, (unsigned long) count, (unsigned long) pos); + + result = -EBUSY; + if (IS_SWAPFILE(inode)) + goto out_swapfile; + result = nfs_revalidate_inode(NFS_SERVER(inode), inode); + if (result) + goto out; + + result = count; + if (!count) + goto out; + + result = generic_file_aio_write(iocb, buf, count, pos); +out: + return result; + +out_swapfile: + printk(KERN_INFO "NFS: attempt to write to active swap file!\n"); + goto out; +} + +/* + * Lock a (portion of) a file + */ +int +nfs_lock(struct file *filp, int cmd, struct file_lock *fl) +{ + struct inode * inode = filp->f_mapping->host; + int status = 0; + int status2; + + dprintk("NFS: nfs_lock(f=%s/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n", + inode->i_sb->s_id, inode->i_ino, + fl->fl_type, fl->fl_flags, + (long long)fl->fl_start, (long long)fl->fl_end); + + if (!inode) + return -EINVAL; + + /* No mandatory locks over NFS */ + if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) + return -ENOLCK; + + if (NFS_PROTO(inode)->version != 4) { + /* Fake OK code if mounted without NLM support */ + if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) { if (IS_GETLK(cmd)) status = LOCK_USE_CLNT; goto out_ok;