diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/client.c | 2 | ||||
-rw-r--r-- | fs/nfs/dir.c | 18 | ||||
-rw-r--r-- | fs/nfs/direct.c | 20 | ||||
-rw-r--r-- | fs/nfs/file.c | 44 | ||||
-rw-r--r-- | fs/nfs/getroot.c | 2 | ||||
-rw-r--r-- | fs/nfs/idmap.c | 2 | ||||
-rw-r--r-- | fs/nfs/inode.c | 14 | ||||
-rw-r--r-- | fs/nfs/internal.h | 18 | ||||
-rw-r--r-- | fs/nfs/namespace.c | 8 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 54 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 101 | ||||
-rw-r--r-- | fs/nfs/nfs4renewd.c | 5 | ||||
-rw-r--r-- | fs/nfs/nfsroot.c | 13 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 71 | ||||
-rw-r--r-- | fs/nfs/proc.c | 33 | ||||
-rw-r--r-- | fs/nfs/read.c | 183 | ||||
-rw-r--r-- | fs/nfs/symlink.c | 2 | ||||
-rw-r--r-- | fs/nfs/write.c | 608 |
19 files changed, 530 insertions, 670 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 5fea638743e..23ab145daa2 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -143,7 +143,7 @@ static struct nfs_client *nfs_alloc_client(const char *hostname, INIT_LIST_HEAD(&clp->cl_state_owners); INIT_LIST_HEAD(&clp->cl_unused); spin_lock_init(&clp->cl_lock); - INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); + INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); clp->cl_boot_time = CURRENT_TIME; clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b34cd16f472..dee3d6c0f19 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -172,7 +172,7 @@ static int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) { struct file *file = desc->file; - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct rpc_cred *cred = nfs_file_cred(file); unsigned long timestamp; int error; @@ -183,7 +183,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) again: timestamp = jiffies; - error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->entry->cookie, page, + error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page, NFS_SERVER(inode)->dtsize, desc->plus); if (error < 0) { /* We requested READDIRPLUS, but the server doesn't grok it */ @@ -308,7 +308,7 @@ int find_dirent_index(nfs_readdir_descriptor_t *desc) static inline int find_dirent_page(nfs_readdir_descriptor_t *desc) { - struct inode *inode = desc->file->f_dentry->d_inode; + struct inode *inode = desc->file->f_path.dentry->d_inode; struct page *page; int status; @@ -464,7 +464,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, filldir_t filldir) { struct file *file = desc->file; - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct rpc_cred *cred = nfs_file_cred(file); struct page *page = NULL; int status; @@ -477,7 +477,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, status = -ENOMEM; goto out; } - desc->error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, *desc->dir_cookie, + desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie, page, NFS_SERVER(inode)->dtsize, desc->plus); @@ -516,7 +516,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, */ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) { - struct dentry *dentry = filp->f_dentry; + struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; nfs_readdir_descriptor_t my_desc, *desc = &my_desc; @@ -599,7 +599,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) { - mutex_lock(&filp->f_dentry->d_inode->i_mutex); + mutex_lock(&filp->f_path.dentry->d_inode->i_mutex); switch (origin) { case 1: offset += filp->f_pos; @@ -615,7 +615,7 @@ loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0; } out: - mutex_unlock(&filp->f_dentry->d_inode->i_mutex); + mutex_unlock(&filp->f_path.dentry->d_inode->i_mutex); return offset; } @@ -1102,7 +1102,7 @@ no_open: static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc) { - struct dentry *parent = desc->file->f_dentry; + struct dentry *parent = desc->file->f_path.dentry; struct inode *dir = parent->d_inode; struct nfs_entry *entry = desc->entry; struct dentry *dentry, *alias; diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index bdfabf854a5..bd21d7fde65 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -58,7 +58,7 @@ #define NFSDBG_FACILITY NFSDBG_VFS -static kmem_cache_t *nfs_direct_cachep; +static struct kmem_cache *nfs_direct_cachep; /* * This represents a set of asynchronous requests that we're waiting on @@ -116,7 +116,7 @@ static inline int put_dreq(struct nfs_direct_req *dreq) ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs) { dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n", - iocb->ki_filp->f_dentry->d_name.name, + iocb->ki_filp->f_path.dentry->d_name.name, (long long) pos, nr_segs); return -EINVAL; @@ -143,7 +143,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) { struct nfs_direct_req *dreq; - dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL); + dreq = kmem_cache_alloc(nfs_direct_cachep, GFP_KERNEL); if (!dreq) return NULL; @@ -307,9 +307,7 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo data->task.tk_cookie = (unsigned long) inode; - lock_kernel(); rpc_execute(&data->task); - unlock_kernel(); dfprintk(VFS, "NFS: %5u initiated direct read call (req %s/%Ld, %zu bytes @ offset %Lu)\n", data->task.tk_pid, @@ -475,9 +473,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); - lock_kernel(); rpc_execute(&data->task); - unlock_kernel(); } static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) @@ -641,9 +637,7 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l data->task.tk_priority = RPC_PRIORITY_NORMAL; data->task.tk_cookie = (unsigned long) inode; - lock_kernel(); rpc_execute(&data->task); - unlock_kernel(); dfprintk(VFS, "NFS: %5u initiated direct write call (req %s/%Ld, %zu bytes @ offset %Lu)\n", data->task.tk_pid, @@ -740,8 +734,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, size_t count = iov[0].iov_len; dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", - file->f_dentry->d_parent->d_name.name, - file->f_dentry->d_name.name, + file->f_path.dentry->d_parent->d_name.name, + file->f_path.dentry->d_name.name, (unsigned long) count, (long long) pos); if (nr_segs != 1) @@ -804,8 +798,8 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, size_t count = iov[0].iov_len; dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", - file->f_dentry->d_parent->d_name.name, - file->f_dentry->d_name.name, + file->f_path.dentry->d_parent->d_name.name, + file->f_path.dentry->d_name.name, (unsigned long) count, (long long) pos); if (nr_segs != 1) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index cc93865cea9..fab20d06d93 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -176,7 +176,7 @@ static int nfs_file_flush(struct file *file, fl_owner_t id) { struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; int status; dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); @@ -201,7 +201,7 @@ static ssize_t nfs_file_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { - struct dentry * dentry = iocb->ki_filp->f_dentry; + struct dentry * dentry = iocb->ki_filp->f_path.dentry; struct inode * inode = dentry->d_inode; ssize_t result; size_t count = iov_length(iov, nr_segs); @@ -226,7 +226,7 @@ static ssize_t 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 dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; ssize_t res; @@ -243,7 +243,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, static int nfs_file_mmap(struct file * file, struct vm_area_struct * vma) { - struct dentry *dentry = file->f_dentry; + struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; int status; @@ -307,28 +307,27 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse static void nfs_invalidate_page(struct page *page, unsigned long offset) { - struct inode *inode = page->mapping->host; - + if (offset != 0) + return; /* Cancel any unstarted writes on this page */ - if (offset == 0) - nfs_sync_inode_wait(inode, page->index, 1, FLUSH_INVALIDATE); + nfs_wb_page_priority(page->mapping->host, page, FLUSH_INVALIDATE); } static int nfs_release_page(struct page *page, gfp_t gfp) { - if (gfp & __GFP_FS) - return !nfs_wb_page(page->mapping->host, page); - else - /* - * Avoid deadlock on nfs_wait_on_request(). - */ - return 0; + /* If PagePrivate() is set, then the page is not freeable */ + return 0; +} + +static int nfs_launder_page(struct page *page) +{ + return nfs_wb_page(page->mapping->host, page); } const struct address_space_operations nfs_file_aops = { .readpage = nfs_readpage, .readpages = nfs_readpages, - .set_page_dirty = __set_page_dirty_nobuffers, + .set_page_dirty = nfs_set_page_dirty, .writepage = nfs_writepage, .writepages = nfs_writepages, .prepare_write = nfs_prepare_write, @@ -338,12 +337,13 @@ const struct address_space_operations nfs_file_aops = { #ifdef CONFIG_NFS_DIRECTIO .direct_IO = nfs_direct_IO, #endif + .launder_page = nfs_launder_page, }; static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { - struct dentry * dentry = iocb->ki_filp->f_dentry; + struct dentry * dentry = iocb->ki_filp->f_path.dentry; struct inode * inode = dentry->d_inode; ssize_t result; size_t count = iov_length(iov, nr_segs); @@ -375,6 +375,12 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); result = generic_file_aio_write(iocb, iov, nr_segs, pos); + /* Return error values for O_SYNC and IS_SYNC() */ + if (result >= 0 && (IS_SYNC(inode) || (iocb->ki_filp->f_flags & O_SYNC))) { + int err = nfs_fsync(iocb->ki_filp, dentry, 1); + if (err < 0) + result = err; + } out: return result; @@ -529,8 +535,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) { dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", - filp->f_dentry->d_inode->i_sb->s_id, - filp->f_dentry->d_inode->i_ino, + filp->f_path.dentry->d_inode->i_sb->s_id, + filp->f_path.dentry->d_inode->i_ino, fl->fl_type, fl->fl_flags); /* diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 20c6f39ea38..8391bd7a83c 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -31,7 +31,7 @@ #include <linux/nfs_idmap.h> #include <linux/vfs.h> #include <linux/namei.h> -#include <linux/namespace.h> +#include <linux/mnt_namespace.h> #include <linux/security.h> #include <asm/system.h> diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 82ad7110a1c..9d4a6b2d199 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -377,7 +377,7 @@ idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg, static ssize_t idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) { - struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode); + struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); struct idmap *idmap = (struct idmap *)rpci->private; struct idmap_msg im_in, *im = &idmap->idmap_im; struct idmap_hashtable *h; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 08cc4c5919a..63e47027930 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -55,7 +55,7 @@ static int nfs_update_inode(struct inode *, struct nfs_fattr *); static void nfs_zap_acl_cache(struct inode *); -static kmem_cache_t * nfs_inode_cachep; +static struct kmem_cache * nfs_inode_cachep; static inline unsigned long nfs_fattr_to_ino_t(struct nfs_fattr *fattr) @@ -422,7 +422,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) int err; /* Flush out writes to the server in order to update c/mtime */ - nfs_sync_inode_wait(inode, 0, 0, FLUSH_NOCOMMIT); + nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); /* * We may force a getattr if the user cares about atime. @@ -496,7 +496,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx) */ static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) { - struct inode *inode = filp->f_dentry->d_inode; + struct inode *inode = filp->f_path.dentry->d_inode; struct nfs_inode *nfsi = NFS_I(inode); filp->private_data = get_nfs_open_context(ctx); @@ -528,7 +528,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c static void nfs_file_clear_open_context(struct file *filp) { - struct inode *inode = filp->f_dentry->d_inode; + struct inode *inode = filp->f_path.dentry->d_inode; struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data; if (ctx) { @@ -551,7 +551,7 @@ int nfs_open(struct inode *inode, struct file *filp) cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); if (IS_ERR(cred)) return PTR_ERR(cred); - ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred); + ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred); put_rpccred(cred); if (ctx == NULL) return -ENOMEM; @@ -1080,7 +1080,7 @@ void nfs4_clear_inode(struct inode *inode) struct inode *nfs_alloc_inode(struct super_block *sb) { struct nfs_inode *nfsi; - nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); + nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL); if (!nfsi) return NULL; nfsi->flags = 0UL; @@ -1111,7 +1111,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) #endif } -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) { struct nfs_inode *nfsi = (struct nfs_inode *) foo; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index d205466233f..a28f6ce2e13 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -217,3 +217,21 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize) if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) sb->s_maxbytes = MAX_LFS_FILESIZE; } + +/* + * Determine the number of bytes of data the page contains + */ +static inline +unsigned int nfs_page_length(struct page *page) +{ + loff_t i_size = i_size_read(page->mapping->host); + + if (i_size > 0) { + pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; + if (page->index < end_index) + return PAGE_CACHE_SIZE; + if (page->index == end_index) + return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1; + } + return 0; +} diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index ec1114b33d8..371b804e7cc 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -18,10 +18,10 @@ #define NFSDBG_FACILITY NFSDBG_VFS -static void nfs_expire_automounts(void *list); +static void nfs_expire_automounts(struct work_struct *work); LIST_HEAD(nfs_automount_list); -static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list); +static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); int nfs_mountpoint_expiry_timeout = 500 * HZ; static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, @@ -164,9 +164,9 @@ struct inode_operations nfs_referral_inode_operations = { .follow_link = nfs_follow_mountpoint, }; -static void nfs_expire_automounts(void *data) +static void nfs_expire_automounts(struct work_struct *work) { - struct list_head *list = (struct list_head *)data; + struct list_head *list = &nfs_automount_list; mark_mounts_for_expiry(list); if (!list_empty(list)) diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index e5f128ffc32..acd8fe9762d 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -276,51 +276,6 @@ static int nfs3_proc_read(struct nfs_read_data *rdata) return status; } -static int nfs3_proc_write(struct nfs_write_data *wdata) -{ - int rpcflags = wdata->flags; - struct inode * inode = wdata->inode; - struct nfs_fattr * fattr = wdata->res.fattr; - struct rpc_message msg = { - .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE], - .rpc_argp = &wdata->args, - .rpc_resp = &wdata->res, - .rpc_cred = wdata->cred, - }; - int status; - - dprintk("NFS call write %d @ %Ld\n", wdata->args.count, - (long long) wdata->args.offset); - nfs_fattr_init(fattr); - status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags); - if (status >= 0) - nfs_post_op_update_inode(inode, fattr); - dprintk("NFS reply write: %d\n", status); - return status < 0? status : wdata->res.count; -} - -static int nfs3_proc_commit(struct nfs_write_data *cdata) -{ - struct inode * inode = cdata->inode; - struct nfs_fattr * fattr = cdata->res.fattr; - struct rpc_message msg = { - .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT], - .rpc_argp = &cdata->args, - .rpc_resp = &cdata->res, - .rpc_cred = cdata->cred, - }; - int status; - - dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, - (long long) cdata->args.offset); - nfs_fattr_init(fattr); - status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); - if (status >= 0) - nfs_post_op_update_inode(inode, fattr); - dprintk("NFS reply commit: %d\n", status); - return status; -} - /* * Create a regular file. * For now, we don't implement O_EXCL. @@ -369,7 +324,7 @@ again: /* If the server doesn't support the exclusive creation semantics, * try again with simple 'guarded' mode. */ - if (status == NFSERR_NOTSUPP) { + if (status == -ENOTSUPP) { switch (arg.createmode) { case NFS3_CREATE_EXCLUSIVE: arg.createmode = NFS3_CREATE_GUARDED; @@ -690,8 +645,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, }; int status; - lock_kernel(); - if (plus) msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; @@ -702,7 +655,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); nfs_refresh_inode(dir, &dir_attr); dprintk("NFS reply readdir: %d\n", status); - unlock_kernel(); return status; } @@ -889,7 +841,7 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, int how) static int nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl) { - return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl); + return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl); } const struct nfs_rpc_ops nfs_v3_clientops = { @@ -904,8 +856,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { .access = nfs3_proc_access, .readlink = nfs3_proc_readlink, .read = nfs3_proc_read, - .write = nfs3_proc_write, - .commit = nfs3_proc_commit, .create = nfs3_proc_create, .remove = nfs3_proc_remove, .unlink_setup = nfs3_proc_unlink_setup, diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6f346677332..c26cd978c7c 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -185,7 +185,7 @@ extern const u32 nfs4_fs_locations_bitmap[2]; extern void nfs4_schedule_state_renewal(struct nfs_client *); extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); extern void nfs4_kill_renewd(struct nfs_client *); -extern void nfs4_renew_state(void *); +extern void nfs4_renew_state(struct work_struct *); /* nfs4state.c */ struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8118036cc44..b3fd29baadc 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -636,7 +636,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) smp_wmb(); } else status = data->rpc_status; - rpc_release_task(task); + rpc_put_task(task); return status; } @@ -742,7 +742,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) smp_wmb(); } else status = data->rpc_status; - rpc_release_task(task); + rpc_put_task(task); if (status != 0) return status; @@ -1775,89 +1775,6 @@ static int nfs4_proc_read(struct nfs_read_data *rdata) return err; } -static int _nfs4_proc_write(struct nfs_write_data *wdata) -{ - int rpcflags = wdata->flags; - struct inode *inode = wdata->inode; - struct nfs_fattr *fattr = wdata->res.fattr; - struct nfs_server *server = NFS_SERVER(inode); - struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], - .rpc_argp = &wdata->args, - .rpc_resp = &wdata->res, - .rpc_cred = wdata->cred, - }; - int status; - - dprintk("NFS call write %d @ %Ld\n", wdata->args.count, - (long long) wdata->args.offset); - - wdata->args.bitmask = server->attr_bitmask; - wdata->res.server = server; - wdata->timestamp = jiffies; - nfs_fattr_init(fattr); - status = rpc_call_sync(server->client, &msg, rpcflags); - dprintk("NFS reply write: %d\n", status); - if (status < 0) - return status; - renew_lease(server, wdata->timestamp); - nfs_post_op_update_inode(inode, fattr); - return wdata->res.count; -} - -static int nfs4_proc_write(struct nfs_write_data *wdata) -{ - struct nfs4_exception exception = { }; - int err; - do { - err = nfs4_handle_exception(NFS_SERVER(wdata->inode), - _nfs4_proc_write(wdata), - &exception); - } while (exception.retry); - return err; -} - -static int _nfs4_proc_commit(struct nfs_write_data *cdata) -{ - struct inode *inode = cdata->inode; - struct nfs_fattr *fattr = cdata->res.fattr; - struct nfs_server *server = NFS_SERVER(inode); - struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT], - .rpc_argp = &cdata->args, - .rpc_resp = &cdata->res, - .rpc_cred = cdata->cred, - }; - int status; - - dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, - (long long) cdata->args.offset); - - cdata->args.bitmask = server->attr_bitmask; - cdata->res.server = server; - cdata->timestamp = jiffies; - nfs_fattr_init(fattr); - status = rpc_call_sync(server->client, &msg, 0); - if (status >= 0) - renew_lease(server, cdata->timestamp); - dprintk("NFS reply commit: %d\n", status); - if (status >= 0) - nfs_post_op_update_inode(inode, fattr); - return status; -} - -static int nfs4_proc_commit(struct nfs_write_data *cdata) -{ - struct nfs4_exception exception = { }; - int err; - do { - err = nfs4_handle_exception(NFS_SERVER(cdata->inode), - _nfs4_proc_commit(cdata), - &exception); - } while (exception.retry); - return err; -} - /* * Got race? * We will need to arrange for the VFS layer to provide an atomic open. @@ -1960,7 +1877,7 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct nfs_server *server = NFS_SERVER(dir->d_inode); struct unlink_desc *up; - up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL); + up = kmalloc(sizeof(*up), GFP_KERNEL); if (!up) return -ENOMEM; @@ -2223,13 +2140,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long long)cookie); - lock_kernel(); nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); res.pgbase = args.pgbase; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (status == 0) memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); - unlock_kernel(); dprintk("%s: returns %d\n", __FUNCTION__, status); return status; } @@ -3067,7 +2982,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co if (status == 0) nfs_post_op_update_inode(inode, &data->fattr); } - rpc_release_task(task); + rpc_put_task(task); return status; } @@ -3314,7 +3229,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * if (IS_ERR(task)) goto out; status = nfs4_wait_for_completion_rpc_task(task); - rpc_release_task(task); + rpc_put_task(task); out: return status; } @@ -3430,7 +3345,7 @@ static void nfs4_lock_release(void *calldata) task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, data->arg.lock_seqid); if (!IS_ERR(task)) - rpc_release_task(task); + rpc_put_task(task); dprintk("%s: cancelling lock!\n", __FUNCTION__); } else nfs_free_seqid(data->arg.lock_seqid); @@ -3472,7 +3387,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f ret = -EAGAIN; } else data->cancelled = 1; - rpc_release_task(task); + rpc_put_task(task); dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret); return ret; } @@ -3732,8 +3647,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .access = nfs4_proc_access, .readlink = nfs4_proc_readlink, .read = nfs4_proc_read, - .write = nfs4_proc_write, - .commit = nfs4_proc_commit, .create = nfs4_proc_create, .remove = nfs4_proc_remove, .unlink_setup = nfs4_proc_unlink_setup, diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 7b6df1852e7..823298561c0 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c @@ -59,9 +59,10 @@ #define NFSDBG_FACILITY NFSDBG_PROC void -nfs4_renew_state(void *data) +nfs4_renew_state(struct work_struct *work) { - struct nfs_client *clp = (struct nfs_client *)data; + struct nfs_client *clp = + container_of(work, struct nfs_client, cl_renewd.work); struct rpc_cred *cred; long lease, timeout; unsigned long last, now; diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 8dfefe41a8d..75f819dc025 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c @@ -98,7 +98,7 @@ static char nfs_root_name[256] __initdata = ""; /* Address of NFS server */ -static __u32 servaddr __initdata = 0; +static __be32 servaddr __initdata = 0; /* Name of directory to mount */ static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, }; @@ -327,7 +327,7 @@ static int __init root_nfs_name(char *name) */ static int __init root_nfs_addr(void) { - if ((servaddr = root_server_addr) == INADDR_NONE) { + if ((servaddr = root_server_addr) == htonl(INADDR_NONE)) { printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n"); return -1; } @@ -411,7 +411,7 @@ __setup("nfsroot=", nfs_root_setup); * Construct sockaddr_in from address and port number. */ static inline void -set_sockaddr(struct sockaddr_in *sin, __u32 addr, __u16 port) +set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port) { sin->sin_family = AF_INET; sin->sin_addr.s_addr = addr; @@ -468,14 +468,13 @@ static int __init root_nfs_ports(void) dprintk("Root-NFS: Portmapper on server returned %d " "as nfsd port\n", port); } - nfs_port = htons(nfs_port); if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { printk(KERN_ERR "Root-NFS: Unable to get mountd port " "number from server, using default\n"); port = mountd_port; } - mount_port = htons(port); + mount_port = port; dprintk("Root-NFS: mountd port is %d\n", port); return 0; @@ -496,7 +495,7 @@ static int __init root_nfs_get_handle(void) int version = (nfs_data.flags & NFS_MOUNT_VER3) ? NFS_MNT3_VERSION : NFS_MNT_VERSION; - set_sockaddr(&sin, servaddr, mount_port); + set_sockaddr(&sin, servaddr, htons(mount_port)); status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol); if (status < 0) printk(KERN_ERR "Root-NFS: Server returned error %d " @@ -519,6 +518,6 @@ void * __init nfs_root_data(void) || root_nfs_ports() < 0 || root_nfs_get_handle() < 0) return NULL; - set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port); + set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, htons(nfs_port)); return (void*)&nfs_data; } diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 829af323f28..ca4b1d4ff42 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -17,16 +17,17 @@ #include <linux/nfs_page.h> #include <linux/nfs_fs.h> #include <linux/nfs_mount.h> +#include <linux/writeback.h> #define NFS_PARANOIA 1 -static kmem_cache_t *nfs_page_cachep; +static struct kmem_cache *nfs_page_cachep; static inline struct nfs_page * nfs_page_alloc(void) { struct nfs_page *p; - p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL); + p = kmem_cache_alloc(nfs_page_cachep, GFP_KERNEL); if (p) { memset(p, 0, sizeof(*p)); INIT_LIST_HEAD(&p->wb_list); @@ -268,11 +269,10 @@ nfs_coalesce_requests(struct list_head *head, struct list_head *dst, #define NFS_SCAN_MAXENTRIES 16 /** - * nfs_scan_lock_dirty - Scan the radix tree for dirty requests - * @nfsi: NFS inode + * nfs_scan_dirty - Scan the radix tree for dirty requests + * @mapping: pointer to address space + * @wbc: writeback_control structure * @dst: Destination list - * @idx_start: lower bound of page->index to scan - * @npages: idx_start + npages sets the upper bound to scan. * * Moves elements from one of the inode request lists. * If the number of requests is set to 0, the entire address_space @@ -280,46 +280,63 @@ nfs_coalesce_requests(struct list_head *head, struct list_head *dst, * The requests are *not* checked to ensure that they form a contiguous set. * You must be holding the inode's req_lock when calling this function */ -int -nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst, - unsigned long idx_start, unsigned int npages) +long nfs_scan_dirty(struct address_space *mapping, + struct writeback_control *wbc, + struct list_head *dst) { + struct nfs_inode *nfsi = NFS_I(mapping->host); struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; struct nfs_page *req; - unsigned long idx_end; + pgoff_t idx_start, idx_end; + long res = 0; int found, i; - int res; - res = 0; - if (npages == 0) - idx_end = ~0; - else - idx_end = idx_start + npages - 1; + if (nfsi->ndirty == 0) + return 0; + if (wbc->range_cyclic) { + idx_start = 0; + idx_end = ULONG_MAX; + } else if (wbc->range_end == 0) { + idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; + idx_end = ULONG_MAX; + } else { + idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; + idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; + } |