Merge branch 'for-2.6.34' of git://linux-nfs.org/~bfields/linux

* 'for-2.6.34' of git://linux-nfs.org/~bfields/linux: (22 commits)
nfsd4: fix minor memory leak
svcrpc: treat uid's as unsigned
nfsd: ensure sockets are closed on error
Revert "sunrpc: move the close processing after do recvfrom method"
Revert "sunrpc: fix peername failed on closed listener"
sunrpc: remove unnecessary svc_xprt_put
NFSD: NFSv4 callback client should use RPC_TASK_SOFTCONN
xfs_export_operations.commit_metadata
commit_metadata export operation replacing nfsd_sync_dir
lockd: don't clear sm_monitored on nsm_reboot_lookup
lockd: release reference to nsm_handle in nlm_host_rebooted
nfsd: Use vfs_fsync_range() in nfsd_commit
NFSD: Create PF_INET6 listener in write_ports
SUNRPC: NFS kernel APIs shouldn't return ENOENT for "transport not found"
SUNRPC: Bury "#ifdef IPV6" in svc_create_xprt()
NFSD: Support AF_INET6 in svc_addsock() function
SUNRPC: Use rpc_pton() in ip_map_parse()
nfsd: 4.1 has an rfc number
nfsd41: Create the recovery entry for the NFSv4.1 client
nfsd: use vfs_fsync for non-directories
...

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