Skip to content

Commit e547204

Browse files
committed
Merge tag 'nfs-for-4.12-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust: "Bugfixes include: - stable fix for exclusive create if the server supports the umask attribute - trunking detection should handle ERESTARTSYS/EINTR - stable fix for a race in the LAYOUTGET function - stable fix to revert "nfs_rename() handle -ERESTARTSYS dentry left behind" - nfs4_callback_free_slot() cannot call nfs4_slot_tbl_drain_complete()" * tag 'nfs-for-4.12-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: NFSv4.1: nfs4_callback_free_slot() cannot call nfs4_slot_tbl_drain_complete() Revert "NFS: nfs_rename() handle -ERESTARTSYS dentry left behind" NFSv4.1: Fix a race in nfs4_proc_layoutget NFS: Trunking detection should handle ERESTARTSYS/EINTR NFSv4.2: Don't send mode again in post-EXCLUSIVE4_1 SETATTR with umask
2 parents 5a37be4 + 2e31b4c commit e547204

File tree

4 files changed

+29
-30
lines changed

4 files changed

+29
-30
lines changed

fs/nfs/callback_xdr.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,6 @@ static void nfs4_callback_free_slot(struct nfs4_session *session,
753753
* A single slot, so highest used slotid is either 0 or -1
754754
*/
755755
nfs4_free_slot(tbl, slot);
756-
nfs4_slot_tbl_drain_complete(tbl);
757756
spin_unlock(&tbl->slot_tbl_lock);
758757
}
759758

fs/nfs/dir.c

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,29 +1946,6 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
19461946
}
19471947
EXPORT_SYMBOL_GPL(nfs_link);
19481948

1949-
static void
1950-
nfs_complete_rename(struct rpc_task *task, struct nfs_renamedata *data)
1951-
{
1952-
struct dentry *old_dentry = data->old_dentry;
1953-
struct dentry *new_dentry = data->new_dentry;
1954-
struct inode *old_inode = d_inode(old_dentry);
1955-
struct inode *new_inode = d_inode(new_dentry);
1956-
1957-
nfs_mark_for_revalidate(old_inode);
1958-
1959-
switch (task->tk_status) {
1960-
case 0:
1961-
if (new_inode != NULL)
1962-
nfs_drop_nlink(new_inode);
1963-
d_move(old_dentry, new_dentry);
1964-
nfs_set_verifier(new_dentry,
1965-
nfs_save_change_attribute(data->new_dir));
1966-
break;
1967-
case -ENOENT:
1968-
nfs_dentry_handle_enoent(old_dentry);
1969-
}
1970-
}
1971-
19721949
/*
19731950
* RENAME
19741951
* FIXME: Some nfsds, like the Linux user space nfsd, may generate a
@@ -1999,7 +1976,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
19991976
{
20001977
struct inode *old_inode = d_inode(old_dentry);
20011978
struct inode *new_inode = d_inode(new_dentry);
2002-
struct dentry *dentry = NULL;
1979+
struct dentry *dentry = NULL, *rehash = NULL;
20031980
struct rpc_task *task;
20041981
int error = -EBUSY;
20051982

@@ -2022,8 +1999,10 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
20221999
* To prevent any new references to the target during the
20232000
* rename, we unhash the dentry in advance.
20242001
*/
2025-
if (!d_unhashed(new_dentry))
2002+
if (!d_unhashed(new_dentry)) {
20262003
d_drop(new_dentry);
2004+
rehash = new_dentry;
2005+
}
20272006

20282007
if (d_count(new_dentry) > 2) {
20292008
int err;
@@ -2040,6 +2019,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
20402019
goto out;
20412020

20422021
new_dentry = dentry;
2022+
rehash = NULL;
20432023
new_inode = NULL;
20442024
}
20452025
}
@@ -2048,8 +2028,7 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
20482028
if (new_inode != NULL)
20492029
NFS_PROTO(new_inode)->return_delegation(new_inode);
20502030

2051-
task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
2052-
nfs_complete_rename);
2031+
task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
20532032
if (IS_ERR(task)) {
20542033
error = PTR_ERR(task);
20552034
goto out;
@@ -2059,9 +2038,27 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
20592038
if (error == 0)
20602039
error = task->tk_status;
20612040
rpc_put_task(task);
2041+
nfs_mark_for_revalidate(old_inode);
20622042
out:
2043+
if (rehash)
2044+
d_rehash(rehash);
20632045
trace_nfs_rename_exit(old_dir, old_dentry,
20642046
new_dir, new_dentry, error);
2047+
if (!error) {
2048+
if (new_inode != NULL)
2049+
nfs_drop_nlink(new_inode);
2050+
/*
2051+
* The d_move() should be here instead of in an async RPC completion
2052+
* handler because we need the proper locks to move the dentry. If
2053+
* we're interrupted by a signal, the async RPC completion handler
2054+
* should mark the directories for revalidation.
2055+
*/
2056+
d_move(old_dentry, new_dentry);
2057+
nfs_set_verifier(new_dentry,
2058+
nfs_save_change_attribute(new_dir));
2059+
} else if (error == -ENOENT)
2060+
nfs_dentry_handle_enoent(old_dentry);
2061+
20652062
/* new dentry created? */
20662063
if (dentry)
20672064
dput(dentry);

fs/nfs/nfs4proc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,7 +2589,8 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
25892589

25902590
/* Except MODE, it seems harmless of setting twice. */
25912591
if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
2592-
attrset[1] & FATTR4_WORD1_MODE)
2592+
(attrset[1] & FATTR4_WORD1_MODE ||
2593+
attrset[2] & FATTR4_WORD2_MODE_UMASK))
25932594
sattr->ia_valid &= ~ATTR_MODE;
25942595

25952596
if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
@@ -8416,6 +8417,7 @@ static void nfs4_layoutget_release(void *calldata)
84168417
size_t max_pages = max_response_pages(server);
84178418

84188419
dprintk("--> %s\n", __func__);
8420+
nfs4_sequence_free_slot(&lgp->res.seq_res);
84198421
nfs4_free_pages(lgp->args.layout.pages, max_pages);
84208422
pnfs_put_layout_hdr(NFS_I(inode)->layout);
84218423
put_nfs_open_context(lgp->args.ctx);
@@ -8490,7 +8492,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout, gfp_t gfp_flags)
84908492
/* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */
84918493
if (status == 0 && lgp->res.layoutp->len)
84928494
lseg = pnfs_layout_process(lgp);
8493-
nfs4_sequence_free_slot(&lgp->res.seq_res);
84948495
rpc_put_task(task);
84958496
dprintk("<-- %s status=%d\n", __func__, status);
84968497
if (status)

fs/nfs/nfs4state.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,6 +2134,8 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
21342134
put_rpccred(cred);
21352135
switch (status) {
21362136
case 0:
2137+
case -EINTR:
2138+
case -ERESTARTSYS:
21372139
break;
21382140
case -ETIMEDOUT:
21392141
if (clnt->cl_softrtry)

0 commit comments

Comments
 (0)