@@ -1181,25 +1181,58 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset,
1181
1181
return err ;
1182
1182
}
1183
1183
1184
- static __be32
1185
- nfsd_create_setattr (struct svc_rqst * rqstp , struct svc_fh * resfhp ,
1186
- struct iattr * iap )
1184
+ /**
1185
+ * nfsd_create_setattr - Set a created file's attributes
1186
+ * @rqstp: RPC transaction being executed
1187
+ * @fhp: NFS filehandle of parent directory
1188
+ * @resfhp: NFS filehandle of new object
1189
+ * @iap: requested attributes of new object
1190
+ *
1191
+ * Returns nfs_ok on success, or an nfsstat in network byte order.
1192
+ */
1193
+ __be32
1194
+ nfsd_create_setattr (struct svc_rqst * rqstp , struct svc_fh * fhp ,
1195
+ struct svc_fh * resfhp , struct iattr * iap )
1187
1196
{
1197
+ __be32 status ;
1198
+
1188
1199
/*
1189
- * Mode has already been set earlier in create:
1200
+ * Mode has already been set by file creation.
1190
1201
*/
1191
1202
iap -> ia_valid &= ~ATTR_MODE ;
1203
+
1192
1204
/*
1193
1205
* Setting uid/gid works only for root. Irix appears to
1194
1206
* send along the gid on create when it tries to implement
1195
1207
* setgid directories via NFS:
1196
1208
*/
1197
1209
if (!uid_eq (current_fsuid (), GLOBAL_ROOT_UID ))
1198
1210
iap -> ia_valid &= ~(ATTR_UID |ATTR_GID );
1211
+
1212
+ /*
1213
+ * Callers expect new file metadata to be committed even
1214
+ * if the attributes have not changed.
1215
+ */
1199
1216
if (iap -> ia_valid )
1200
- return nfsd_setattr (rqstp , resfhp , iap , 0 , (time64_t )0 );
1201
- /* Callers expect file metadata to be committed here */
1202
- return nfserrno (commit_metadata (resfhp ));
1217
+ status = nfsd_setattr (rqstp , resfhp , iap , 0 , (time64_t )0 );
1218
+ else
1219
+ status = nfserrno (commit_metadata (resfhp ));
1220
+
1221
+ /*
1222
+ * Transactional filesystems had a chance to commit changes
1223
+ * for both parent and child simultaneously making the
1224
+ * following commit_metadata a noop in many cases.
1225
+ */
1226
+ if (!status )
1227
+ status = nfserrno (commit_metadata (fhp ));
1228
+
1229
+ /*
1230
+ * Update the new filehandle to pick up the new attributes.
1231
+ */
1232
+ if (!status )
1233
+ status = fh_update (resfhp );
1234
+
1235
+ return status ;
1203
1236
}
1204
1237
1205
1238
/* HPUX client sometimes creates a file in mode 000, and sets size to 0.
@@ -1226,7 +1259,6 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
1226
1259
struct dentry * dentry , * dchild ;
1227
1260
struct inode * dirp ;
1228
1261
__be32 err ;
1229
- __be32 err2 ;
1230
1262
int host_err ;
1231
1263
1232
1264
dentry = fhp -> fh_dentry ;
@@ -1299,22 +1331,8 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
1299
1331
if (host_err < 0 )
1300
1332
goto out_nfserr ;
1301
1333
1302
- err = nfsd_create_setattr (rqstp , resfhp , iap );
1334
+ err = nfsd_create_setattr (rqstp , fhp , resfhp , iap );
1303
1335
1304
- /*
1305
- * nfsd_create_setattr already committed the child. Transactional
1306
- * filesystems had a chance to commit changes for both parent and
1307
- * child simultaneously making the following commit_metadata a
1308
- * noop.
1309
- */
1310
- err2 = nfserrno (commit_metadata (fhp ));
1311
- if (err2 )
1312
- err = err2 ;
1313
- /*
1314
- * Update the file handle to get the new inode info.
1315
- */
1316
- if (!err )
1317
- err = fh_update (resfhp );
1318
1336
out :
1319
1337
dput (dchild );
1320
1338
return err ;
@@ -1505,20 +1523,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1505
1523
}
1506
1524
1507
1525
set_attr :
1508
- err = nfsd_create_setattr (rqstp , resfhp , iap );
1509
-
1510
- /*
1511
- * nfsd_create_setattr already committed the child
1512
- * (and possibly also the parent).
1513
- */
1514
- if (!err )
1515
- err = nfserrno (commit_metadata (fhp ));
1516
-
1517
- /*
1518
- * Update the filehandle to get the new inode info.
1519
- */
1520
- if (!err )
1521
- err = fh_update (resfhp );
1526
+ err = nfsd_create_setattr (rqstp , fhp , resfhp , iap );
1522
1527
1523
1528
out :
1524
1529
fh_unlock (fhp );
0 commit comments