diff options
| -rw-r--r-- | fs/nfs/dir.c | 2 | ||||
| -rw-r--r-- | fs/nfs/file.c | 91 | ||||
| -rw-r--r-- | fs/nfs/inode.c | 2 | ||||
| -rw-r--r-- | fs/nfs/internal.h | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs3proc.c | 1 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 4 | ||||
| -rw-r--r-- | fs/nfs/pnfs.c | 26 | ||||
| -rw-r--r-- | fs/nfs/proc.c | 1 | ||||
| -rw-r--r-- | fs/nfs/read.c | 14 | ||||
| -rw-r--r-- | include/linux/nfs_fs.h | 3 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 1 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 4 |
12 files changed, 89 insertions, 62 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b238d95ac48c..ac2899098147 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1468,12 +1468,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
| 1468 | res = NULL; | 1468 | res = NULL; |
| 1469 | goto out; | 1469 | goto out; |
| 1470 | /* This turned out not to be a regular file */ | 1470 | /* This turned out not to be a regular file */ |
| 1471 | case -EISDIR: | ||
| 1471 | case -ENOTDIR: | 1472 | case -ENOTDIR: |
| 1472 | goto no_open; | 1473 | goto no_open; |
| 1473 | case -ELOOP: | 1474 | case -ELOOP: |
| 1474 | if (!(nd->intent.open.flags & O_NOFOLLOW)) | 1475 | if (!(nd->intent.open.flags & O_NOFOLLOW)) |
| 1475 | goto no_open; | 1476 | goto no_open; |
| 1476 | /* case -EISDIR: */ | ||
| 1477 | /* case -EINVAL: */ | 1477 | /* case -EINVAL: */ |
| 1478 | default: | 1478 | default: |
| 1479 | res = ERR_CAST(inode); | 1479 | res = ERR_CAST(inode); |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 0a1f8312b4dc..eca56d4b39c0 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
| @@ -40,48 +40,8 @@ | |||
| 40 | 40 | ||
| 41 | #define NFSDBG_FACILITY NFSDBG_FILE | 41 | #define NFSDBG_FACILITY NFSDBG_FILE |
| 42 | 42 | ||
| 43 | static int nfs_file_open(struct inode *, struct file *); | ||
| 44 | static int nfs_file_release(struct inode *, struct file *); | ||
| 45 | static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); | ||
| 46 | static int nfs_file_mmap(struct file *, struct vm_area_struct *); | ||
| 47 | static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos, | ||
| 48 | struct pipe_inode_info *pipe, | ||
| 49 | size_t count, unsigned int flags); | ||
| 50 | static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, | ||
| 51 | unsigned long nr_segs, loff_t pos); | ||
| 52 | static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, | ||
| 53 | struct file *filp, loff_t *ppos, | ||
| 54 | size_t count, unsigned int flags); | ||
| 55 | static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, | ||
| 56 | unsigned long nr_segs, loff_t pos); | ||
| 57 | static int nfs_file_flush(struct file *, fl_owner_t id); | ||
| 58 | static int nfs_file_fsync(struct file *, loff_t, loff_t, int datasync); | ||
| 59 | static int nfs_check_flags(int flags); | ||
| 60 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | ||
| 61 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); | ||
| 62 | static int nfs_setlease(struct file *file, long arg, struct file_lock **fl); | ||
| 63 | |||
| 64 | static const struct vm_operations_struct nfs_file_vm_ops; | 43 | static const struct vm_operations_struct nfs_file_vm_ops; |
| 65 | 44 | ||
| 66 | const struct file_operations nfs_file_operations = { | ||
| 67 | .llseek = nfs_file_llseek, | ||
| 68 | .read = do_sync_read, | ||
| 69 | .write = do_sync_write, | ||
| 70 | .aio_read = nfs_file_read, | ||
| 71 | .aio_write = nfs_file_write, | ||
| 72 | .mmap = nfs_file_mmap, | ||
| 73 | .open = nfs_file_open, | ||
| 74 | .flush = nfs_file_flush, | ||
| 75 | .release = nfs_file_release, | ||
| 76 | .fsync = nfs_file_fsync, | ||
| 77 | .lock = nfs_lock, | ||
| 78 | .flock = nfs_flock, | ||
| 79 | .splice_read = nfs_file_splice_read, | ||
| 80 | .splice_write = nfs_file_splice_write, | ||
| 81 | .check_flags = nfs_check_flags, | ||
| 82 | .setlease = nfs_setlease, | ||
| 83 | }; | ||
| 84 | |||
| 85 | const struct inode_operations nfs_file_inode_operations = { | 45 | const struct inode_operations nfs_file_inode_operations = { |
| 86 | .permission = nfs_permission, | 46 | .permission = nfs_permission, |
| 87 | .getattr = nfs_getattr, | 47 | .getattr = nfs_getattr, |
| @@ -886,3 +846,54 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) | |||
| 886 | file->f_path.dentry->d_name.name, arg); | 846 | file->f_path.dentry->d_name.name, arg); |
| 887 | return -EINVAL; | 847 | return -EINVAL; |
| 888 | } | 848 | } |
| 849 | |||
| 850 | const struct file_operations nfs_file_operations = { | ||
| 851 | .llseek = nfs_file_llseek, | ||
| 852 | .read = do_sync_read, | ||
| 853 | .write = do_sync_write, | ||
| 854 | .aio_read = nfs_file_read, | ||
| 855 | .aio_write = nfs_file_write, | ||
| 856 | .mmap = nfs_file_mmap, | ||
| 857 | .open = nfs_file_open, | ||
| 858 | .flush = nfs_file_flush, | ||
| 859 | .release = nfs_file_release, | ||
| 860 | .fsync = nfs_file_fsync, | ||
| 861 | .lock = nfs_lock, | ||
| 862 | .flock = nfs_flock, | ||
| 863 | .splice_read = nfs_file_splice_read, | ||
| 864 | .splice_write = nfs_file_splice_write, | ||
| 865 | .check_flags = nfs_check_flags, | ||
| 866 | .setlease = nfs_setlease, | ||
| 867 | }; | ||
| 868 | |||
| 869 | #ifdef CONFIG_NFS_V4 | ||
| 870 | static int | ||
| 871 | nfs4_file_open(struct inode *inode, struct file *filp) | ||
| 872 | { | ||
| 873 | /* | ||
| 874 | * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to | ||
| 875 | * this point, then something is very wrong | ||
| 876 | */ | ||
| 877 | dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp); | ||
| 878 | return -ENOTDIR; | ||
| 879 | } | ||
| 880 | |||
| 881 | const struct file_operations nfs4_file_operations = { | ||
| 882 | .llseek = nfs_file_llseek, | ||
| 883 | .read = do_sync_read, | ||
| 884 | .write = do_sync_write, | ||
| 885 | .aio_read = nfs_file_read, | ||
| 886 | .aio_write = nfs_file_write, | ||
| 887 | .mmap = nfs_file_mmap, | ||
| 888 | .open = nfs4_file_open, | ||
| 889 | .flush = nfs_file_flush, | ||
| 890 | .release = nfs_file_release, | ||
| 891 | .fsync = nfs_file_fsync, | ||
| 892 | .lock = nfs_lock, | ||
| 893 | .flock = nfs_flock, | ||
| 894 | .splice_read = nfs_file_splice_read, | ||
| 895 | .splice_write = nfs_file_splice_write, | ||
| 896 | .check_flags = nfs_check_flags, | ||
| 897 | .setlease = nfs_setlease, | ||
| 898 | }; | ||
| 899 | #endif /* CONFIG_NFS_V4 */ | ||
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c07a55aec838..50a15fa8cf98 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -291,7 +291,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
| 291 | */ | 291 | */ |
| 292 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops; | 292 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops; |
| 293 | if (S_ISREG(inode->i_mode)) { | 293 | if (S_ISREG(inode->i_mode)) { |
| 294 | inode->i_fop = &nfs_file_operations; | 294 | inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops; |
| 295 | inode->i_data.a_ops = &nfs_file_aops; | 295 | inode->i_data.a_ops = &nfs_file_aops; |
| 296 | inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; | 296 | inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; |
| 297 | } else if (S_ISDIR(inode->i_mode)) { | 297 | } else if (S_ISDIR(inode->i_mode)) { |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index c1a1bd8ddf1c..3f4d95751d52 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
| @@ -299,6 +299,8 @@ extern void nfs_read_prepare(struct rpc_task *task, void *calldata); | |||
| 299 | extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc, | 299 | extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc, |
| 300 | struct list_head *head); | 300 | struct list_head *head); |
| 301 | 301 | ||
| 302 | extern void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio, | ||
| 303 | struct inode *inode); | ||
| 302 | extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio); | 304 | extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio); |
| 303 | extern void nfs_readdata_release(struct nfs_read_data *rdata); | 305 | extern void nfs_readdata_release(struct nfs_read_data *rdata); |
| 304 | 306 | ||
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 85f1690ca08c..d4bc9ed91748 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
| @@ -853,6 +853,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = { | |||
| 853 | .dentry_ops = &nfs_dentry_operations, | 853 | .dentry_ops = &nfs_dentry_operations, |
| 854 | .dir_inode_ops = &nfs3_dir_inode_operations, | 854 | .dir_inode_ops = &nfs3_dir_inode_operations, |
| 855 | .file_inode_ops = &nfs3_file_inode_operations, | 855 | .file_inode_ops = &nfs3_file_inode_operations, |
| 856 | .file_ops = &nfs_file_operations, | ||
| 856 | .getroot = nfs3_proc_get_root, | 857 | .getroot = nfs3_proc_get_root, |
| 857 | .getattr = nfs3_proc_getattr, | 858 | .getattr = nfs3_proc_getattr, |
| 858 | .setattr = nfs3_proc_setattr, | 859 | .setattr = nfs3_proc_setattr, |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b60fddf606f7..be2bbac13817 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -2464,8 +2464,7 @@ static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qst | |||
| 2464 | case -NFS4ERR_BADNAME: | 2464 | case -NFS4ERR_BADNAME: |
| 2465 | return -ENOENT; | 2465 | return -ENOENT; |
| 2466 | case -NFS4ERR_MOVED: | 2466 | case -NFS4ERR_MOVED: |
| 2467 | err = nfs4_get_referral(dir, name, fattr, fhandle); | 2467 | return nfs4_get_referral(dir, name, fattr, fhandle); |
| 2468 | break; | ||
| 2469 | case -NFS4ERR_WRONGSEC: | 2468 | case -NFS4ERR_WRONGSEC: |
| 2470 | nfs_fixup_secinfo_attributes(fattr, fhandle); | 2469 | nfs_fixup_secinfo_attributes(fattr, fhandle); |
| 2471 | } | 2470 | } |
| @@ -6253,6 +6252,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { | |||
| 6253 | .dentry_ops = &nfs4_dentry_operations, | 6252 | .dentry_ops = &nfs4_dentry_operations, |
| 6254 | .dir_inode_ops = &nfs4_dir_inode_operations, | 6253 | .dir_inode_ops = &nfs4_dir_inode_operations, |
| 6255 | .file_inode_ops = &nfs4_file_inode_operations, | 6254 | .file_inode_ops = &nfs4_file_inode_operations, |
| 6255 | .file_ops = &nfs4_file_operations, | ||
| 6256 | .getroot = nfs4_proc_get_root, | 6256 | .getroot = nfs4_proc_get_root, |
| 6257 | .getattr = nfs4_proc_getattr, | 6257 | .getattr = nfs4_proc_getattr, |
| 6258 | .setattr = nfs4_proc_setattr, | 6258 | .setattr = nfs4_proc_setattr, |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index baf73536bc04..8e672a2b2d69 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
| @@ -1260,6 +1260,25 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | |||
| 1260 | } | 1260 | } |
| 1261 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages); | 1261 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages); |
| 1262 | 1262 | ||
| 1263 | static void pnfs_ld_handle_read_error(struct nfs_read_data *data) | ||
| 1264 | { | ||
| 1265 | struct nfs_pageio_descriptor pgio; | ||
| 1266 | |||
| 1267 | put_lseg(data->lseg); | ||
| 1268 | data->lseg = NULL; | ||
| 1269 | dprintk("pnfs write error = %d\n", data->pnfs_error); | ||
| 1270 | |||
| 1271 | nfs_pageio_init_read_mds(&pgio, data->inode); | ||
| 1272 | |||
| 1273 | while (!list_empty(&data->pages)) { | ||
| 1274 | struct nfs_page *req = nfs_list_entry(data->pages.next); | ||
| 1275 | |||
| 1276 | nfs_list_remove_request(req); | ||
| 1277 | nfs_pageio_add_request(&pgio, req); | ||
| 1278 | } | ||
| 1279 | nfs_pageio_complete(&pgio); | ||
| 1280 | } | ||
| 1281 | |||
| 1263 | /* | 1282 | /* |
| 1264 | * Called by non rpc-based layout drivers | 1283 | * Called by non rpc-based layout drivers |
| 1265 | */ | 1284 | */ |
| @@ -1268,11 +1287,8 @@ void pnfs_ld_read_done(struct nfs_read_data *data) | |||
| 1268 | if (likely(!data->pnfs_error)) { | 1287 | if (likely(!data->pnfs_error)) { |
| 1269 | __nfs4_read_done_cb(data); | 1288 | __nfs4_read_done_cb(data); |
| 1270 | data->mds_ops->rpc_call_done(&data->task, data); | 1289 | data->mds_ops->rpc_call_done(&data->task, data); |
| 1271 | } else { | 1290 | } else |
| 1272 | put_lseg(data->lseg); | 1291 | pnfs_ld_handle_read_error(data); |
| 1273 | data->lseg = NULL; | ||
| 1274 | dprintk("pnfs write error = %d\n", data->pnfs_error); | ||
| 1275 | } | ||
| 1276 | data->mds_ops->rpc_release(data); | 1292 | data->mds_ops->rpc_release(data); |
| 1277 | } | 1293 | } |
| 1278 | EXPORT_SYMBOL_GPL(pnfs_ld_read_done); | 1294 | EXPORT_SYMBOL_GPL(pnfs_ld_read_done); |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index ac40b8535d7e..f48125da198a 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
| @@ -710,6 +710,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = { | |||
| 710 | .dentry_ops = &nfs_dentry_operations, | 710 | .dentry_ops = &nfs_dentry_operations, |
| 711 | .dir_inode_ops = &nfs_dir_inode_operations, | 711 | .dir_inode_ops = &nfs_dir_inode_operations, |
| 712 | .file_inode_ops = &nfs_file_inode_operations, | 712 | .file_inode_ops = &nfs_file_inode_operations, |
| 713 | .file_ops = &nfs_file_operations, | ||
| 713 | .getroot = nfs_proc_get_root, | 714 | .getroot = nfs_proc_get_root, |
| 714 | .getattr = nfs_proc_getattr, | 715 | .getattr = nfs_proc_getattr, |
| 715 | .setattr = nfs_proc_setattr, | 716 | .setattr = nfs_proc_setattr, |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 8b48ec63f722..cfa175c223dc 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
| @@ -109,7 +109,7 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data) | |||
| 109 | } | 109 | } |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio, | 112 | void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio, |
| 113 | struct inode *inode) | 113 | struct inode *inode) |
| 114 | { | 114 | { |
| 115 | nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, | 115 | nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, |
| @@ -534,23 +534,13 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata) | |||
| 534 | static void nfs_readpage_release_full(void *calldata) | 534 | static void nfs_readpage_release_full(void *calldata) |
| 535 | { | 535 | { |
| 536 | struct nfs_read_data *data = calldata; | 536 | struct nfs_read_data *data = calldata; |
| 537 | struct nfs_pageio_descriptor pgio; | ||
| 538 | 537 | ||
| 539 | if (data->pnfs_error) { | ||
| 540 | nfs_pageio_init_read_mds(&pgio, data->inode); | ||
| 541 | pgio.pg_recoalesce = 1; | ||
| 542 | } | ||
| 543 | while (!list_empty(&data->pages)) { | 538 | while (!list_empty(&data->pages)) { |
| 544 | struct nfs_page *req = nfs_list_entry(data->pages.next); | 539 | struct nfs_page *req = nfs_list_entry(data->pages.next); |
| 545 | 540 | ||
| 546 | nfs_list_remove_request(req); | 541 | nfs_list_remove_request(req); |
| 547 | if (!data->pnfs_error) | 542 | nfs_readpage_release(req); |
| 548 | nfs_readpage_release(req); | ||
| 549 | else | ||
| 550 | nfs_pageio_add_request(&pgio, req); | ||
| 551 | } | 543 | } |
| 552 | if (data->pnfs_error) | ||
| 553 | nfs_pageio_complete(&pgio); | ||
| 554 | nfs_readdata_release(calldata); | 544 | nfs_readdata_release(calldata); |
| 555 | } | 545 | } |
| 556 | 546 | ||
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index ab2c6343361a..92ecf5585fac 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
| @@ -410,6 +410,9 @@ extern const struct inode_operations nfs_file_inode_operations; | |||
| 410 | extern const struct inode_operations nfs3_file_inode_operations; | 410 | extern const struct inode_operations nfs3_file_inode_operations; |
| 411 | #endif /* CONFIG_NFS_V3 */ | 411 | #endif /* CONFIG_NFS_V3 */ |
| 412 | extern const struct file_operations nfs_file_operations; | 412 | extern const struct file_operations nfs_file_operations; |
| 413 | #ifdef CONFIG_NFS_V4 | ||
| 414 | extern const struct file_operations nfs4_file_operations; | ||
| 415 | #endif /* CONFIG_NFS_V4 */ | ||
| 413 | extern const struct address_space_operations nfs_file_aops; | 416 | extern const struct address_space_operations nfs_file_aops; |
| 414 | extern const struct address_space_operations nfs_dir_aops; | 417 | extern const struct address_space_operations nfs_dir_aops; |
| 415 | 418 | ||
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index c74595ba7094..2a7c533be5dd 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -1192,6 +1192,7 @@ struct nfs_rpc_ops { | |||
| 1192 | const struct dentry_operations *dentry_ops; | 1192 | const struct dentry_operations *dentry_ops; |
| 1193 | const struct inode_operations *dir_inode_ops; | 1193 | const struct inode_operations *dir_inode_ops; |
| 1194 | const struct inode_operations *file_inode_ops; | 1194 | const struct inode_operations *file_inode_ops; |
| 1195 | const struct file_operations *file_ops; | ||
| 1195 | 1196 | ||
| 1196 | int (*getroot) (struct nfs_server *, struct nfs_fh *, | 1197 | int (*getroot) (struct nfs_server *, struct nfs_fh *, |
| 1197 | struct nfs_fsinfo *); | 1198 | struct nfs_fsinfo *); |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index d7f97ef26590..2d78d95955ab 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -2530,8 +2530,10 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
| 2530 | int err; | 2530 | int err; |
| 2531 | err = xs_init_anyaddr(args->dstaddr->sa_family, | 2531 | err = xs_init_anyaddr(args->dstaddr->sa_family, |
| 2532 | (struct sockaddr *)&new->srcaddr); | 2532 | (struct sockaddr *)&new->srcaddr); |
| 2533 | if (err != 0) | 2533 | if (err != 0) { |
| 2534 | xprt_free(xprt); | ||
| 2534 | return ERR_PTR(err); | 2535 | return ERR_PTR(err); |
| 2536 | } | ||
| 2535 | } | 2537 | } |
| 2536 | 2538 | ||
| 2537 | return xprt; | 2539 | return xprt; |
