diff options
| -rw-r--r-- | Documentation/filesystems/nfs/nfs41-server.txt | 5 | ||||
| -rw-r--r-- | fs/lockd/host.c | 2 | ||||
| -rw-r--r-- | fs/lockd/mon.c | 12 | ||||
| -rw-r--r-- | fs/lockd/svc.c | 2 | ||||
| -rw-r--r-- | fs/nfs/callback.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfs4callback.c | 5 | ||||
| -rw-r--r-- | fs/nfsd/nfs4recover.c | 4 | ||||
| -rw-r--r-- | fs/nfsd/nfs4state.c | 4 | ||||
| -rw-r--r-- | fs/nfsd/nfs4xdr.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfsctl.c | 24 | ||||
| -rw-r--r-- | fs/nfsd/vfs.c | 153 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_export.c | 20 | ||||
| -rw-r--r-- | include/linux/exportfs.h | 5 | ||||
| -rw-r--r-- | net/sunrpc/svc_xprt.c | 27 | ||||
| -rw-r--r-- | net/sunrpc/svcauth_unix.c | 49 | ||||
| -rw-r--r-- | net/sunrpc/svcsock.c | 3 |
16 files changed, 174 insertions, 145 deletions
diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt index 1bd0d0c05171..6a53a84afc72 100644 --- a/Documentation/filesystems/nfs/nfs41-server.txt +++ b/Documentation/filesystems/nfs/nfs41-server.txt | |||
| @@ -17,8 +17,7 @@ kernels must turn 4.1 on or off *before* turning support for version 4 | |||
| 17 | on or off; rpc.nfsd does this correctly.) | 17 | on or off; rpc.nfsd does this correctly.) |
| 18 | 18 | ||
| 19 | The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based | 19 | The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based |
| 20 | on the latest NFSv4.1 Internet Draft: | 20 | on RFC 5661. |
| 21 | http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29 | ||
| 22 | 21 | ||
| 23 | From the many new features in NFSv4.1 the current implementation | 22 | From the many new features in NFSv4.1 the current implementation |
| 24 | focuses on the mandatory-to-implement NFSv4.1 Sessions, providing | 23 | focuses on the mandatory-to-implement NFSv4.1 Sessions, providing |
| @@ -44,7 +43,7 @@ interoperability problems with future clients. Known issues: | |||
| 44 | trunking, but this is a mandatory feature, and its use is | 43 | trunking, but this is a mandatory feature, and its use is |
| 45 | recommended to clients in a number of places. (E.g. to ensure | 44 | recommended to clients in a number of places. (E.g. to ensure |
| 46 | timely renewal in case an existing connection's retry timeouts | 45 | timely renewal in case an existing connection's retry timeouts |
| 47 | have gotten too long; see section 8.3 of the draft.) | 46 | have gotten too long; see section 8.3 of the RFC.) |
| 48 | Therefore, lack of this feature may cause future clients to | 47 | Therefore, lack of this feature may cause future clients to |
| 49 | fail. | 48 | fail. |
| 50 | - Incomplete backchannel support: incomplete backchannel gss | 49 | - Incomplete backchannel support: incomplete backchannel gss |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 4600c2037b8b..bb464d12104c 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
| @@ -479,8 +479,8 @@ again: mutex_lock(&nlm_host_mutex); | |||
| 479 | } | 479 | } |
| 480 | } | 480 | } |
| 481 | } | 481 | } |
| 482 | |||
| 483 | mutex_unlock(&nlm_host_mutex); | 482 | mutex_unlock(&nlm_host_mutex); |
| 483 | nsm_release(nsm); | ||
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | /* | 486 | /* |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index f956651d0f65..fefa4df3f005 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
| @@ -349,9 +349,9 @@ retry: | |||
| 349 | * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle | 349 | * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle |
| 350 | * @info: pointer to NLMPROC_SM_NOTIFY arguments | 350 | * @info: pointer to NLMPROC_SM_NOTIFY arguments |
| 351 | * | 351 | * |
| 352 | * Returns a matching nsm_handle if found in the nsm cache; the returned | 352 | * Returns a matching nsm_handle if found in the nsm cache. The returned |
| 353 | * nsm_handle's reference count is bumped and sm_monitored is cleared. | 353 | * nsm_handle's reference count is bumped. Otherwise returns NULL if some |
| 354 | * Otherwise returns NULL if some error occurred. | 354 | * error occurred. |
| 355 | */ | 355 | */ |
| 356 | struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info) | 356 | struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info) |
| 357 | { | 357 | { |
| @@ -370,12 +370,6 @@ struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info) | |||
| 370 | atomic_inc(&cached->sm_count); | 370 | atomic_inc(&cached->sm_count); |
| 371 | spin_unlock(&nsm_lock); | 371 | spin_unlock(&nsm_lock); |
| 372 | 372 | ||
| 373 | /* | ||
| 374 | * During subsequent lock activity, force a fresh | ||
| 375 | * notification to be set up for this host. | ||
| 376 | */ | ||
| 377 | cached->sm_monitored = 0; | ||
| 378 | |||
| 379 | dprintk("lockd: host %s (%s) rebooted, cnt %d\n", | 373 | dprintk("lockd: host %s (%s) rebooted, cnt %d\n", |
| 380 | cached->sm_name, cached->sm_addrbuf, | 374 | cached->sm_name, cached->sm_addrbuf, |
| 381 | atomic_read(&cached->sm_count)); | 375 | atomic_read(&cached->sm_count)); |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index e50cfa3d9654..7d150517ddf0 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
| @@ -243,11 +243,9 @@ static int make_socks(struct svc_serv *serv) | |||
| 243 | if (err < 0) | 243 | if (err < 0) |
| 244 | goto out_err; | 244 | goto out_err; |
| 245 | 245 | ||
| 246 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 247 | err = create_lockd_family(serv, PF_INET6); | 246 | err = create_lockd_family(serv, PF_INET6); |
| 248 | if (err < 0 && err != -EAFNOSUPPORT) | 247 | if (err < 0 && err != -EAFNOSUPPORT) |
| 249 | goto out_err; | 248 | goto out_err; |
| 250 | #endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */ | ||
| 251 | 249 | ||
| 252 | warned = 0; | 250 | warned = 0; |
| 253 | return 0; | 251 | return 0; |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 73ab220354df..36dfdae95123 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
| @@ -118,7 +118,6 @@ nfs4_callback_up(struct svc_serv *serv) | |||
| 118 | dprintk("NFS: Callback listener port = %u (af %u)\n", | 118 | dprintk("NFS: Callback listener port = %u (af %u)\n", |
| 119 | nfs_callback_tcpport, PF_INET); | 119 | nfs_callback_tcpport, PF_INET); |
| 120 | 120 | ||
| 121 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 122 | ret = svc_create_xprt(serv, "tcp", PF_INET6, | 121 | ret = svc_create_xprt(serv, "tcp", PF_INET6, |
| 123 | nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); | 122 | nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); |
| 124 | if (ret > 0) { | 123 | if (ret > 0) { |
| @@ -129,7 +128,6 @@ nfs4_callback_up(struct svc_serv *serv) | |||
| 129 | ret = 0; | 128 | ret = 0; |
| 130 | else | 129 | else |
| 131 | goto out_err; | 130 | goto out_err; |
| 132 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
| 133 | 131 | ||
| 134 | return svc_prepare_thread(serv, &serv->sv_pools[0]); | 132 | return svc_prepare_thread(serv, &serv->sv_pools[0]); |
| 135 | 133 | ||
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index c6eed2a3b093..4bc22c763de7 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
| @@ -525,6 +525,8 @@ static struct rpc_cred *callback_cred; | |||
| 525 | 525 | ||
| 526 | int set_callback_cred(void) | 526 | int set_callback_cred(void) |
| 527 | { | 527 | { |
| 528 | if (callback_cred) | ||
| 529 | return 0; | ||
| 528 | callback_cred = rpc_lookup_machine_cred(); | 530 | callback_cred = rpc_lookup_machine_cred(); |
| 529 | if (!callback_cred) | 531 | if (!callback_cred) |
| 530 | return -ENOMEM; | 532 | return -ENOMEM; |
| @@ -542,7 +544,8 @@ void do_probe_callback(struct nfs4_client *clp) | |||
| 542 | }; | 544 | }; |
| 543 | int status; | 545 | int status; |
| 544 | 546 | ||
| 545 | status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_SOFT, | 547 | status = rpc_call_async(cb->cb_client, &msg, |
| 548 | RPC_TASK_SOFT | RPC_TASK_SOFTCONN, | ||
| 546 | &nfsd4_cb_probe_ops, (void *)clp); | 549 | &nfsd4_cb_probe_ops, (void *)clp); |
| 547 | if (status) { | 550 | if (status) { |
| 548 | warn_no_callback_path(clp, status); | 551 | warn_no_callback_path(clp, status); |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 5a754f7b71ed..98fb98e330b4 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
| @@ -119,9 +119,7 @@ out_no_tfm: | |||
| 119 | static void | 119 | static void |
| 120 | nfsd4_sync_rec_dir(void) | 120 | nfsd4_sync_rec_dir(void) |
| 121 | { | 121 | { |
| 122 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); | 122 | vfs_fsync(NULL, rec_dir.dentry, 0); |
| 123 | nfsd_sync_dir(rec_dir.dentry); | ||
| 124 | mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); | ||
| 125 | } | 123 | } |
| 126 | 124 | ||
| 127 | int | 125 | int |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index fcafe6087f69..c97fddbd17db 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -2482,8 +2482,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
| 2482 | } | 2482 | } |
| 2483 | memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); | 2483 | memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); |
| 2484 | 2484 | ||
| 2485 | if (nfsd4_has_session(&resp->cstate)) | 2485 | if (nfsd4_has_session(&resp->cstate)) { |
| 2486 | open->op_stateowner->so_confirmed = 1; | 2486 | open->op_stateowner->so_confirmed = 1; |
| 2487 | nfsd4_create_clid_dir(open->op_stateowner->so_client); | ||
| 2488 | } | ||
| 2487 | 2489 | ||
| 2488 | /* | 2490 | /* |
| 2489 | * Attempt to hand out a delegation. No error return, because the | 2491 | * Attempt to hand out a delegation. No error return, because the |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index bbf72d8f9fc0..78c7e24e5129 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
| @@ -1434,7 +1434,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
| 1434 | } | 1434 | } |
| 1435 | op->opnum = ntohl(*argp->p++); | 1435 | op->opnum = ntohl(*argp->p++); |
| 1436 | 1436 | ||
| 1437 | if (op->opnum >= OP_ACCESS && op->opnum < ops->nops) | 1437 | if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP) |
| 1438 | op->status = ops->decoders[op->opnum](argp, &op->u); | 1438 | op->status = ops->decoders[op->opnum](argp, &op->u); |
| 1439 | else { | 1439 | else { |
| 1440 | op->opnum = OP_ILLEGAL; | 1440 | op->opnum = OP_ILLEGAL; |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 2604c3e70ea5..0f0e77f2012f 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
| @@ -988,6 +988,7 @@ static ssize_t __write_ports_delfd(char *buf) | |||
| 988 | static ssize_t __write_ports_addxprt(char *buf) | 988 | static ssize_t __write_ports_addxprt(char *buf) |
| 989 | { | 989 | { |
| 990 | char transport[16]; | 990 | char transport[16]; |
| 991 | struct svc_xprt *xprt; | ||
| 991 | int port, err; | 992 | int port, err; |
| 992 | 993 | ||
| 993 | if (sscanf(buf, "%15s %4u", transport, &port) != 2) | 994 | if (sscanf(buf, "%15s %4u", transport, &port) != 2) |
| @@ -1002,13 +1003,24 @@ static ssize_t __write_ports_addxprt(char *buf) | |||
| 1002 | 1003 | ||
| 1003 | err = svc_create_xprt(nfsd_serv, transport, | 1004 | err = svc_create_xprt(nfsd_serv, transport, |
| 1004 | PF_INET, port, SVC_SOCK_ANONYMOUS); | 1005 | PF_INET, port, SVC_SOCK_ANONYMOUS); |
| 1005 | if (err < 0) { | 1006 | if (err < 0) |
| 1006 | /* Give a reasonable perror msg for bad transport string */ | 1007 | goto out_err; |
| 1007 | if (err == -ENOENT) | 1008 | |
| 1008 | err = -EPROTONOSUPPORT; | 1009 | err = svc_create_xprt(nfsd_serv, transport, |
| 1009 | return err; | 1010 | PF_INET6, port, SVC_SOCK_ANONYMOUS); |
| 1010 | } | 1011 | if (err < 0 && err != -EAFNOSUPPORT) |
| 1012 | goto out_close; | ||
| 1011 | return 0; | 1013 | return 0; |
| 1014 | out_close: | ||
| 1015 | xprt = svc_find_xprt(nfsd_serv, transport, PF_INET, port); | ||
| 1016 | if (xprt != NULL) { | ||
| 1017 | svc_close_xprt(xprt); | ||
| 1018 | svc_xprt_put(xprt); | ||
| 1019 | } | ||
| 1020 | out_err: | ||
| 1021 | /* Decrease the count, but don't shut down the service */ | ||
| 1022 | nfsd_serv->sv_nrthreads--; | ||
| 1023 | return err; | ||
| 1012 | } | 1024 | } |
| 1013 | 1025 | ||
| 1014 | /* | 1026 | /* |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 8eca17df4f63..a11b0e8678ee 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #include <linux/jhash.h> | 26 | #include <linux/jhash.h> |
| 27 | #include <linux/ima.h> | 27 | #include <linux/ima.h> |
| 28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
| 29 | #include <linux/exportfs.h> | ||
| 30 | #include <linux/writeback.h> | ||
| 29 | 31 | ||
| 30 | #ifdef CONFIG_NFSD_V3 | 32 | #ifdef CONFIG_NFSD_V3 |
| 31 | #include "xdr3.h" | 33 | #include "xdr3.h" |
| @@ -270,6 +272,32 @@ out: | |||
| 270 | return err; | 272 | return err; |
| 271 | } | 273 | } |
| 272 | 274 | ||
| 275 | /* | ||
| 276 | * Commit metadata changes to stable storage. | ||
| 277 | */ | ||
| 278 | static int | ||
| 279 | commit_metadata(struct svc_fh *fhp) | ||
| 280 | { | ||
| 281 | struct inode *inode = fhp->fh_dentry->d_inode; | ||
| 282 | const struct export_operations *export_ops = inode->i_sb->s_export_op; | ||
| 283 | int error = 0; | ||
| 284 | |||
| 285 | if (!EX_ISSYNC(fhp->fh_export)) | ||
| 286 | return 0; | ||
| 287 | |||
| 288 | if (export_ops->commit_metadata) { | ||
| 289 | error = export_ops->commit_metadata(inode); | ||
| 290 | } else { | ||
| 291 | struct writeback_control wbc = { | ||
| 292 | .sync_mode = WB_SYNC_ALL, | ||
| 293 | .nr_to_write = 0, /* metadata only */ | ||
| 294 | }; | ||
| 295 | |||
| 296 | error = sync_inode(inode, &wbc); | ||
| 297 | } | ||
| 298 | |||
| 299 | return error; | ||
| 300 | } | ||
| 273 | 301 | ||
| 274 | /* | 302 | /* |
| 275 | * Set various file attributes. | 303 | * Set various file attributes. |
| @@ -767,43 +795,6 @@ nfsd_close(struct file *filp) | |||
| 767 | } | 795 | } |
| 768 | 796 | ||
| 769 | /* | 797 | /* |
| 770 | * Sync a file | ||
| 771 | * As this calls fsync (not fdatasync) there is no need for a write_inode | ||
| 772 | * after it. | ||
| 773 | */ | ||
| 774 | static inline int nfsd_dosync(struct file *filp, struct dentry *dp, | ||
| 775 | const struct file_operations *fop) | ||
| 776 | { | ||
| 777 | struct inode *inode = dp->d_inode; | ||
| 778 | int (*fsync) (struct file *, struct dentry *, int); | ||
| 779 | int err; | ||
| 780 | |||
| 781 | err = filemap_write_and_wait(inode->i_mapping); | ||
| 782 | if (err == 0 && fop && (fsync = fop->fsync)) | ||
| 783 | err = fsync(filp, dp, 0); | ||
| 784 | return err; | ||
| 785 | } | ||
| 786 | |||
| 787 | static int | ||
| 788 | nfsd_sync(struct file *filp) | ||
| 789 | { | ||
| 790 | int err; | ||
| 791 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 792 | dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name); | ||
| 793 | mutex_lock(&inode->i_mutex); | ||
| 794 | err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op); | ||
| 795 | mutex_unlock(&inode->i_mutex); | ||
| 796 | |||
| 797 | return err; | ||
| 798 | } | ||
| 799 | |||
| 800 | int | ||
| 801 | nfsd_sync_dir(struct dentry *dp) | ||
| 802 | { | ||
| 803 | return nfsd_dosync(NULL, dp, dp->d_inode->i_fop); | ||
| 804 | } | ||
| 805 | |||
| 806 | /* | ||
| 807 | * Obtain the readahead parameters for the file | 798 | * Obtain the readahead parameters for the file |
| 808 | * specified by (dev, ino). | 799 | * specified by (dev, ino). |
| 809 | */ | 800 | */ |
| @@ -1006,7 +997,7 @@ static int wait_for_concurrent_writes(struct file *file) | |||
| 1006 | 997 | ||
| 1007 | if (inode->i_state & I_DIRTY) { | 998 | if (inode->i_state & I_DIRTY) { |
| 1008 | dprintk("nfsd: write sync %d\n", task_pid_nr(current)); | 999 | dprintk("nfsd: write sync %d\n", task_pid_nr(current)); |
| 1009 | err = nfsd_sync(file); | 1000 | err = vfs_fsync(file, file->f_path.dentry, 0); |
| 1010 | } | 1001 | } |
| 1011 | last_ino = inode->i_ino; | 1002 | last_ino = inode->i_ino; |
| 1012 | last_dev = inode->i_sb->s_dev; | 1003 | last_dev = inode->i_sb->s_dev; |
| @@ -1154,8 +1145,9 @@ out: | |||
| 1154 | #ifdef CONFIG_NFSD_V3 | 1145 | #ifdef CONFIG_NFSD_V3 |
| 1155 | /* | 1146 | /* |
| 1156 | * Commit all pending writes to stable storage. | 1147 | * Commit all pending writes to stable storage. |
| 1157 | * Strictly speaking, we could sync just the indicated file region here, | 1148 | * |
| 1158 | * but there's currently no way we can ask the VFS to do so. | 1149 | * Note: we only guarantee that data that lies within the range specified |
| 1150 | * by the 'offset' and 'count' parameters will be synced. | ||
| 1159 | * | 1151 | * |
| 1160 | * Unfortunately we cannot lock the file to make sure we return full WCC | 1152 | * Unfortunately we cannot lock the file to make sure we return full WCC |
| 1161 | * data to the client, as locking happens lower down in the filesystem. | 1153 | * data to the client, as locking happens lower down in the filesystem. |
| @@ -1165,23 +1157,32 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
| 1165 | loff_t offset, unsigned long count) | 1157 | loff_t offset, unsigned long count) |
| 1166 | { | 1158 | { |
| 1167 | struct file *file; | 1159 | struct file *file; |
| 1168 | __be32 err; | 1160 | loff_t end = LLONG_MAX; |
| 1161 | __be32 err = nfserr_inval; | ||
| 1169 | 1162 | ||
| 1170 | if ((u64)count > ~(u64)offset) | 1163 | if (offset < 0) |
| 1171 | return nfserr_inval; | 1164 | goto out; |
| 1165 | if (count != 0) { | ||
| 1166 | end = offset + (loff_t)count - 1; | ||
| 1167 | if (end < offset) | ||
| 1168 | goto out; | ||
| 1169 | } | ||
| 1172 | 1170 | ||
| 1173 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file); | 1171 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file); |
| 1174 | if (err) | 1172 | if (err) |
| 1175 | return err; | 1173 | goto out; |
| 1176 | if (EX_ISSYNC(fhp->fh_export)) { | 1174 | if (EX_ISSYNC(fhp->fh_export)) { |
| 1177 | if (file->f_op && file->f_op->fsync) { | 1175 | int err2 = vfs_fsync_range(file, file->f_path.dentry, |
| 1178 | err = nfserrno(nfsd_sync(file)); | 1176 | offset, end, 0); |
| 1179 | } else { | 1177 | |
| 1178 | if (err2 != -EINVAL) | ||
| 1179 | err = nfserrno(err2); | ||
| 1180 | else | ||
| 1180 | err = nfserr_notsupp; | 1181 | err = nfserr_notsupp; |
| 1181 | } | ||
| 1182 | } | 1182 | } |
| 1183 | 1183 | ||
| 1184 | nfsd_close(file); | 1184 | nfsd_close(file); |
| 1185 | out: | ||
| 1185 | return err; | 1186 | return err; |
| 1186 | } | 1187 | } |
| 1187 | #endif /* CONFIG_NFSD_V3 */ | 1188 | #endif /* CONFIG_NFSD_V3 */ |
| @@ -1334,12 +1335,14 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
| 1334 | goto out_nfserr; | 1335 | goto out_nfserr; |
| 1335 | } | 1336 | } |
| 1336 | 1337 | ||
| 1337 | if (EX_ISSYNC(fhp->fh_export)) { | 1338 | err = nfsd_create_setattr(rqstp, resfhp, iap); |
| 1338 | err = nfserrno(nfsd_sync_dir(dentry)); | ||
| 1339 | write_inode_now(dchild->d_inode, 1); | ||
| 1340 | } | ||
| 1341 | 1339 | ||
| 1342 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); | 1340 | /* |
| 1341 | * nfsd_setattr already committed the child. Transactional filesystems | ||
| 1342 | * had a chance to commit changes for both parent and child | ||
| 1343 | * simultaneously making the following commit_metadata a noop. | ||
| 1344 | */ | ||
| 1345 | err2 = nfserrno(commit_metadata(fhp)); | ||
| 1343 | if (err2) | 1346 | if (err2) |
| 1344 | err = err2; | 1347 | err = err2; |
| 1345 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | 1348 | mnt_drop_write(fhp->fh_export->ex_path.mnt); |
| @@ -1371,7 +1374,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
| 1371 | struct dentry *dentry, *dchild = NULL; | 1374 | struct dentry *dentry, *dchild = NULL; |
| 1372 | struct inode *dirp; | 1375 | struct inode *dirp; |
| 1373 | __be32 err; | 1376 | __be32 err; |
| 1374 | __be32 err2; | ||
| 1375 | int host_err; | 1377 | int host_err; |
| 1376 | __u32 v_mtime=0, v_atime=0; | 1378 | __u32 v_mtime=0, v_atime=0; |
| 1377 | 1379 | ||
| @@ -1466,11 +1468,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
| 1466 | if (created) | 1468 | if (created) |
| 1467 | *created = 1; | 1469 | *created = 1; |
| 1468 | 1470 | ||
| 1469 | if (EX_ISSYNC(fhp->fh_export)) { | ||
| 1470 | err = nfserrno(nfsd_sync_dir(dentry)); | ||
| 1471 | /* setattr will sync the child (or not) */ | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | nfsd_check_ignore_resizing(iap); | 1471 | nfsd_check_ignore_resizing(iap); |
| 1475 | 1472 | ||
| 1476 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1473 | if (createmode == NFS3_CREATE_EXCLUSIVE) { |
| @@ -1485,9 +1482,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
| 1485 | } | 1482 | } |
| 1486 | 1483 | ||
| 1487 | set_attr: | 1484 | set_attr: |
| 1488 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); | 1485 | err = nfsd_create_setattr(rqstp, resfhp, iap); |
| 1489 | if (err2) | 1486 | |
| 1490 | err = err2; | 1487 | /* |
| 1488 | * nfsd_setattr already committed the child (and possibly also the parent). | ||
| 1489 | */ | ||
| 1490 | if (!err) | ||
| 1491 | err = nfserrno(commit_metadata(fhp)); | ||
| 1491 | 1492 | ||
| 1492 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | 1493 | mnt_drop_write(fhp->fh_export->ex_path.mnt); |
| 1493 | /* | 1494 | /* |
| @@ -1602,12 +1603,9 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
| 1602 | } | 1603 | } |
| 1603 | } else | 1604 | } else |
| 1604 | host_err = vfs_symlink(dentry->d_inode, dnew, path); | 1605 | host_err = vfs_symlink(dentry->d_inode, dnew, path); |
| 1605 | |||
| 1606 | if (!host_err) { | ||
| 1607 | if (EX_ISSYNC(fhp->fh_export)) | ||
| 1608 | host_err = nfsd_sync_dir(dentry); | ||
| 1609 | } | ||
| 1610 | err = nfserrno(host_err); | 1606 | err = nfserrno(host_err); |
| 1607 | if (!err) | ||
| 1608 | err = nfserrno(commit_metadata(fhp)); | ||
| 1611 | fh_unlock(fhp); | 1609 | fh_unlock(fhp); |
| 1612 | 1610 | ||
| 1613 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | 1611 | mnt_drop_write(fhp->fh_export->ex_path.mnt); |
| @@ -1669,11 +1667,9 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
| 1669 | } | 1667 | } |
| 1670 | host_err = vfs_link(dold, dirp, dnew); | 1668 | host_err = vfs_link(dold, dirp, dnew); |
| 1671 | if (!host_err) { | 1669 | if (!host_err) { |
| 1672 | if (EX_ISSYNC(ffhp->fh_export)) { | 1670 | err = nfserrno(commit_metadata(ffhp)); |
| 1673 | err = nfserrno(nfsd_sync_dir(ddir)); | 1671 | if (!err) |
| 1674 | write_inode_now(dest, 1); | 1672 | err = nfserrno(commit_metadata(tfhp)); |
| 1675 | } | ||
| 1676 | err = 0; | ||
| 1677 | } else { | 1673 | } else { |
| 1678 | if (host_err == -EXDEV && rqstp->rq_vers == 2) | 1674 | if (host_err == -EXDEV && rqstp->rq_vers == 2) |
| 1679 | err = nfserr_acces; | 1675 | err = nfserr_acces; |
| @@ -1769,10 +1765,10 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
| 1769 | goto out_dput_new; | 1765 | goto out_dput_new; |
| 1770 | 1766 | ||
| 1771 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); | 1767 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); |
| 1772 | if (!host_err && EX_ISSYNC(tfhp->fh_export)) { | 1768 | if (!host_err) { |
| 1773 | host_err = nfsd_sync_dir(tdentry); | 1769 | host_err = commit_metadata(tfhp); |
| 1774 | if (!host_err) | 1770 | if (!host_err) |
| 1775 | host_err = nfsd_sync_dir(fdentry); | 1771 | host_err = commit_metadata(ffhp); |
| 1776 | } | 1772 | } |
| 1777 | 1773 | ||
| 1778 | mnt_drop_write(ffhp->fh_export->ex_path.mnt); | 1774 | mnt_drop_write(ffhp->fh_export->ex_path.mnt); |
| @@ -1853,12 +1849,9 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
| 1853 | 1849 | ||
| 1854 | dput(rdentry); | 1850 | dput(rdentry); |
| 1855 | 1851 | ||
| 1856 | if (host_err) | 1852 | if (!host_err) |
| 1857 | goto out_drop; | 1853 | host_err = commit_metadata(fhp); |
| 1858 | if (EX_ISSYNC(fhp->fh_export)) | ||
| 1859 | host_err = nfsd_sync_dir(dentry); | ||
| 1860 | 1854 | ||
| 1861 | out_drop: | ||
| 1862 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | 1855 | mnt_drop_write(fhp->fh_export->ex_path.mnt); |
| 1863 | out_nfserr: | 1856 | out_nfserr: |
| 1864 | err = nfserrno(host_err); | 1857 | err = nfserrno(host_err); |
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index 87b8cbd23d4b..846b75aeb2ab 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "xfs_vnodeops.h" | 29 | #include "xfs_vnodeops.h" |
| 30 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_inode.h" | 31 | #include "xfs_inode.h" |
| 32 | #include "xfs_inode_item.h" | ||
| 32 | 33 | ||
| 33 | /* | 34 | /* |
| 34 | * Note that we only accept fileids which are long enough rather than allow | 35 | * Note that we only accept fileids which are long enough rather than allow |
| @@ -215,9 +216,28 @@ xfs_fs_get_parent( | |||
| 215 | return d_obtain_alias(VFS_I(cip)); | 216 | return d_obtain_alias(VFS_I(cip)); |
| 216 | } | 217 | } |
| 217 | 218 | ||
| 219 | STATIC int | ||
| 220 | xfs_fs_nfs_commit_metadata( | ||
| 221 | struct inode *inode) | ||
| 222 | { | ||
| 223 | struct xfs_inode *ip = XFS_I(inode); | ||
| 224 | struct xfs_mount *mp = ip->i_mount; | ||
| 225 | int error = 0; | ||
| 226 | |||
| 227 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
| 228 | if (xfs_ipincount(ip)) { | ||
| 229 | error = _xfs_log_force_lsn(mp, ip->i_itemp->ili_last_lsn, | ||
| 230 | XFS_LOG_SYNC, NULL); | ||
| 231 | } | ||
| 232 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 233 | |||
| 234 | return error; | ||
| 235 | } | ||
| 236 | |||
| 218 | const struct export_operations xfs_export_operations = { | 237 | const struct export_operations xfs_export_operations = { |
| 219 | .encode_fh = xfs_fs_encode_fh, | 238 | .encode_fh = xfs_fs_encode_fh, |
| 220 | .fh_to_dentry = xfs_fs_fh_to_dentry, | 239 | .fh_to_dentry = xfs_fs_fh_to_dentry, |
| 221 | .fh_to_parent = xfs_fs_fh_to_parent, | 240 | .fh_to_parent = xfs_fs_fh_to_parent, |
| 222 | .get_parent = xfs_fs_get_parent, | 241 | .get_parent = xfs_fs_get_parent, |
| 242 | .commit_metadata = xfs_fs_nfs_commit_metadata, | ||
| 223 | }; | 243 | }; |
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index dc12f416a49f..a9cd507f8cd2 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h | |||
| @@ -96,6 +96,7 @@ struct fid { | |||
| 96 | * @fh_to_parent: find the implied object's parent and get a dentry for it | 96 | * @fh_to_parent: find the implied object's parent and get a dentry for it |
| 97 | * @get_name: find the name for a given inode in a given directory | 97 | * @get_name: find the name for a given inode in a given directory |
| 98 | * @get_parent: find the parent of a given directory | 98 | * @get_parent: find the parent of a given directory |
| 99 | * @commit_metadata: commit metadata changes to stable storage | ||
| 99 | * | 100 | * |
| 100 | * See Documentation/filesystems/nfs/Exporting for details on how to use | 101 | * See Documentation/filesystems/nfs/Exporting for details on how to use |
| 101 | * this interface correctly. | 102 | * this interface correctly. |
| @@ -137,6 +138,9 @@ struct fid { | |||
| 137 | * is also a directory. In the event that it cannot be found, or storage | 138 | * is also a directory. In the event that it cannot be found, or storage |
| 138 | * space cannot be allocated, a %ERR_PTR should be returned. | 139 | * space cannot be allocated, a %ERR_PTR should be returned. |
| 139 | * | 140 | * |
| 141 | * commit_metadata: | ||
| 142 | * @commit_metadata should commit metadata changes to stable storage. | ||
| 143 | * | ||
| 140 | * Locking rules: | 144 | * Locking rules: |
| 141 | * get_parent is called with child->d_inode->i_mutex down | 145 | * get_parent is called with child->d_inode->i_mutex down |
| 142 | * get_name is not (which is possibly inconsistent) | 146 | * get_name is not (which is possibly inconsistent) |
| @@ -152,6 +156,7 @@ struct export_operations { | |||
| 152 | int (*get_name)(struct dentry *parent, char *name, | 156 | int (*get_name)(struct dentry *parent, char *name, |
| 153 | struct dentry *child); | 157 | struct dentry *child); |
| 154 | struct dentry * (*get_parent)(struct dentry *child); | 158 | struct dentry * (*get_parent)(struct dentry *child); |
| 159 | int (*commit_metadata)(struct inode *inode); | ||
| 155 | }; | 160 | }; |
| 156 | 161 | ||
| 157 | extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, | 162 | extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 7d1f9e928f69..8f0f1fb3dc52 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
| @@ -173,11 +173,13 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | |||
| 173 | .sin_addr.s_addr = htonl(INADDR_ANY), | 173 | .sin_addr.s_addr = htonl(INADDR_ANY), |
| 174 | .sin_port = htons(port), | 174 | .sin_port = htons(port), |
| 175 | }; | 175 | }; |
| 176 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 176 | struct sockaddr_in6 sin6 = { | 177 | struct sockaddr_in6 sin6 = { |
| 177 | .sin6_family = AF_INET6, | 178 | .sin6_family = AF_INET6, |
| 178 | .sin6_addr = IN6ADDR_ANY_INIT, | 179 | .sin6_addr = IN6ADDR_ANY_INIT, |
| 179 | .sin6_port = htons(port), | 180 | .sin6_port = htons(port), |
| 180 | }; | 181 | }; |
| 182 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
| 181 | struct sockaddr *sap; | 183 | struct sockaddr *sap; |
| 182 | size_t len; | 184 | size_t len; |
| 183 | 185 | ||
| @@ -186,10 +188,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | |||
| 186 | sap = (struct sockaddr *)&sin; | 188 | sap = (struct sockaddr *)&sin; |
| 187 | len = sizeof(sin); | 189 | len = sizeof(sin); |
| 188 | break; | 190 | break; |
| 191 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 189 | case PF_INET6: | 192 | case PF_INET6: |
| 190 | sap = (struct sockaddr *)&sin6; | 193 | sap = (struct sockaddr *)&sin6; |
| 191 | len = sizeof(sin6); | 194 | len = sizeof(sin6); |
| 192 | break; | 195 | break; |
| 196 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
| 193 | default: | 197 | default: |
| 194 | return ERR_PTR(-EAFNOSUPPORT); | 198 | return ERR_PTR(-EAFNOSUPPORT); |
| 195 | } | 199 | } |
| @@ -231,7 +235,10 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
| 231 | err: | 235 | err: |
| 232 | spin_unlock(&svc_xprt_class_lock); | 236 | spin_unlock(&svc_xprt_class_lock); |
| 233 | dprintk("svc: transport %s not found\n", xprt_name); | 237 | dprintk("svc: transport %s not found\n", xprt_name); |
| 234 | return -ENOENT; | 238 | |
| 239 | /* This errno is exposed to user space. Provide a reasonable | ||
| 240 | * perror msg for a bad transport. */ | ||
| 241 | return -EPROTONOSUPPORT; | ||
| 235 | } | 242 | } |
| 236 | EXPORT_SYMBOL_GPL(svc_create_xprt); | 243 | EXPORT_SYMBOL_GPL(svc_create_xprt); |
| 237 | 244 | ||
| @@ -699,8 +706,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 699 | spin_unlock_bh(&pool->sp_lock); | 706 | spin_unlock_bh(&pool->sp_lock); |
| 700 | 707 | ||
| 701 | len = 0; | 708 | len = 0; |
| 702 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags) && | 709 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { |
| 703 | !test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 710 | dprintk("svc_recv: found XPT_CLOSE\n"); |
| 711 | svc_delete_xprt(xprt); | ||
| 712 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
| 704 | struct svc_xprt *newxpt; | 713 | struct svc_xprt *newxpt; |
| 705 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | 714 | newxpt = xprt->xpt_ops->xpo_accept(xprt); |
| 706 | if (newxpt) { | 715 | if (newxpt) { |
| @@ -726,7 +735,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 726 | svc_xprt_received(newxpt); | 735 | svc_xprt_received(newxpt); |
| 727 | } | 736 | } |
| 728 | svc_xprt_received(xprt); | 737 | svc_xprt_received(xprt); |
| 729 | } else if (!test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 738 | } else { |
| 730 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 739 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
| 731 | rqstp, pool->sp_id, xprt, | 740 | rqstp, pool->sp_id, xprt, |
| 732 | atomic_read(&xprt->xpt_ref.refcount)); | 741 | atomic_read(&xprt->xpt_ref.refcount)); |
| @@ -739,11 +748,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 739 | dprintk("svc: got len=%d\n", len); | 748 | dprintk("svc: got len=%d\n", len); |
| 740 | } | 749 | } |
| 741 | 750 | ||
| 742 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | ||
| 743 | dprintk("svc_recv: found XPT_CLOSE\n"); | ||
| 744 | svc_delete_xprt(xprt); | ||
| 745 | } | ||
| 746 | |||
| 747 | /* No data, incomplete (TCP) read, or accept() */ | 751 | /* No data, incomplete (TCP) read, or accept() */ |
| 748 | if (len == 0 || len == -EAGAIN) { | 752 | if (len == 0 || len == -EAGAIN) { |
| 749 | rqstp->rq_res.len = 0; | 753 | rqstp->rq_res.len = 0; |
| @@ -889,11 +893,8 @@ void svc_delete_xprt(struct svc_xprt *xprt) | |||
| 889 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | 893 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
| 890 | serv->sv_tmpcnt--; | 894 | serv->sv_tmpcnt--; |
| 891 | 895 | ||
| 892 | for (dr = svc_deferred_dequeue(xprt); dr; | 896 | while ((dr = svc_deferred_dequeue(xprt)) != NULL) |
| 893 | dr = svc_deferred_dequeue(xprt)) { | ||
| 894 | svc_xprt_put(xprt); | ||
| 895 | kfree(dr); | 897 | kfree(dr); |
| 896 | } | ||
| 897 | 898 | ||
| 898 | svc_xprt_put(xprt); | 899 | svc_xprt_put(xprt); |
| 899 | spin_unlock_bh(&serv->sv_lock); | 900 | spin_unlock_bh(&serv->sv_lock); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index d8c041114497..afdcb0459a83 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | #define RPCDBG_FACILITY RPCDBG_AUTH | 16 | #define RPCDBG_FACILITY RPCDBG_AUTH |
| 17 | 17 | ||
| 18 | #include <linux/sunrpc/clnt.h> | ||
| 18 | 19 | ||
| 19 | /* | 20 | /* |
| 20 | * AUTHUNIX and AUTHNULL credentials are both handled here. | 21 | * AUTHUNIX and AUTHNULL credentials are both handled here. |
| @@ -187,10 +188,13 @@ static int ip_map_parse(struct cache_detail *cd, | |||
| 187 | * for scratch: */ | 188 | * for scratch: */ |
| 188 | char *buf = mesg; | 189 | char *buf = mesg; |
| 189 | int len; | 190 | int len; |
| 190 | int b1, b2, b3, b4, b5, b6, b7, b8; | ||
| 191 | char c; | ||
| 192 | char class[8]; | 191 | char class[8]; |
| 193 | struct in6_addr addr; | 192 | union { |
| 193 | struct sockaddr sa; | ||
| 194 | struct sockaddr_in s4; | ||
| 195 | struct sockaddr_in6 s6; | ||
| 196 | } address; | ||
| 197 | struct sockaddr_in6 sin6; | ||
| 194 | int err; | 198 | int err; |
| 195 | 199 | ||
| 196 | struct ip_map *ipmp; | 200 | struct ip_map *ipmp; |
| @@ -209,24 +213,24 @@ static int ip_map_parse(struct cache_detail *cd, | |||
| 209 | len = qword_get(&mesg, buf, mlen); | 213 | len = qword_get(&mesg, buf, mlen); |
| 210 | if (len <= 0) return -EINVAL; | 214 | if (len <= 0) return -EINVAL; |
| 211 | 215 | ||
| 212 | if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) == 4) { | 216 | if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0) |
| 213 | addr.s6_addr32[0] = 0; | ||
| 214 | addr.s6_addr32[1] = 0; | ||
| 215 | addr.s6_addr32[2] = htonl(0xffff); | ||
| 216 | addr.s6_addr32[3] = | ||
| 217 | htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); | ||
| 218 | } else if (sscanf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c", | ||
| 219 | &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) { | ||
| 220 | addr.s6_addr16[0] = htons(b1); | ||
| 221 | addr.s6_addr16[1] = htons(b2); | ||
| 222 | addr.s6_addr16[2] = htons(b3); | ||
| 223 | addr.s6_addr16[3] = htons(b4); | ||
| 224 | addr.s6_addr16[4] = htons(b5); | ||
| 225 | addr.s6_addr16[5] = htons(b6); | ||
| 226 | addr.s6_addr16[6] = htons(b7); | ||
| 227 | addr.s6_addr16[7] = htons(b8); | ||
| 228 | } else | ||
| 229 | return -EINVAL; | 217 | return -EINVAL; |
| 218 | switch (address.sa.sa_family) { | ||
| 219 | case AF_INET: | ||
| 220 | /* Form a mapped IPv4 address in sin6 */ | ||
| 221 | memset(&sin6, 0, sizeof(sin6)); | ||
| 222 | sin6.sin6_family = AF_INET6; | ||
| 223 | sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); | ||
| 224 | sin6.sin6_addr.s6_addr32[3] = address.s4.sin_addr.s_addr; | ||
| 225 | break; | ||
| 226 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 227 | case AF_INET6: | ||
| 228 | memcpy(&sin6, &address.s6, sizeof(sin6)); | ||
| 229 | break; | ||
| 230 | #endif | ||
| 231 | default: | ||
| 232 | return -EINVAL; | ||
| 233 | } | ||
| 230 | 234 | ||
| 231 | expiry = get_expiry(&mesg); | 235 | expiry = get_expiry(&mesg); |
| 232 | if (expiry ==0) | 236 | if (expiry ==0) |
| @@ -243,7 +247,8 @@ static int ip_map_parse(struct cache_detail *cd, | |||
| 243 | } else | 247 | } else |
| 244 | dom = NULL; | 248 | dom = NULL; |
| 245 | 249 | ||
| 246 | ipmp = ip_map_lookup(class, &addr); | 250 | /* IPv6 scope IDs are ignored for now */ |
| 251 | ipmp = ip_map_lookup(class, &sin6.sin6_addr); | ||
| 247 | if (ipmp) { | 252 | if (ipmp) { |
| 248 | err = ip_map_update(ipmp, | 253 | err = ip_map_update(ipmp, |
| 249 | container_of(dom, struct unix_domain, h), | 254 | container_of(dom, struct unix_domain, h), |
| @@ -619,7 +624,7 @@ static int unix_gid_show(struct seq_file *m, | |||
| 619 | else | 624 | else |
| 620 | glen = 0; | 625 | glen = 0; |
| 621 | 626 | ||
| 622 | seq_printf(m, "%d %d:", ug->uid, glen); | 627 | seq_printf(m, "%u %d:", ug->uid, glen); |
| 623 | for (i = 0; i < glen; i++) | 628 | for (i = 0; i < glen; i++) |
| 624 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); | 629 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); |
| 625 | seq_printf(m, "\n"); | 630 | seq_printf(m, "\n"); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 870929e08e5d..a29f259204e6 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
| @@ -968,6 +968,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
| 968 | return len; | 968 | return len; |
| 969 | err_delete: | 969 | err_delete: |
| 970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
| 971 | svc_xprt_received(&svsk->sk_xprt); | ||
| 971 | err_again: | 972 | err_again: |
| 972 | return -EAGAIN; | 973 | return -EAGAIN; |
| 973 | } | 974 | } |
| @@ -1357,7 +1358,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, | |||
| 1357 | 1358 | ||
| 1358 | if (!so) | 1359 | if (!so) |
| 1359 | return err; | 1360 | return err; |
| 1360 | if (so->sk->sk_family != AF_INET) | 1361 | if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6)) |
| 1361 | err = -EAFNOSUPPORT; | 1362 | err = -EAFNOSUPPORT; |
| 1362 | else if (so->sk->sk_protocol != IPPROTO_TCP && | 1363 | else if (so->sk->sk_protocol != IPPROTO_TCP && |
| 1363 | so->sk->sk_protocol != IPPROTO_UDP) | 1364 | so->sk->sk_protocol != IPPROTO_UDP) |
