@@ -1135,16 +1135,9 @@ nfsd_check_ignore_resizing(struct iattr *iap)
1135
1135
iap -> ia_valid &= ~ATTR_SIZE ;
1136
1136
}
1137
1137
1138
- /*
1139
- * Create a file (regular, directory, device, fifo); UNIX sockets
1140
- * not yet implemented.
1141
- * If the response fh has been verified, the parent directory should
1142
- * already be locked. Note that the parent directory is left locked.
1143
- *
1144
- * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
1145
- */
1138
+ /* The parent directory should already be locked: */
1146
1139
__be32
1147
- nfsd_create (struct svc_rqst * rqstp , struct svc_fh * fhp ,
1140
+ nfsd_create_locked (struct svc_rqst * rqstp , struct svc_fh * fhp ,
1148
1141
char * fname , int flen , struct iattr * iap ,
1149
1142
int type , dev_t rdev , struct svc_fh * resfhp )
1150
1143
{
@@ -1154,50 +1147,15 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1154
1147
__be32 err2 ;
1155
1148
int host_err ;
1156
1149
1157
- err = nfserr_exist ;
1158
- if (isdotent (fname , flen ))
1159
- goto out ;
1160
-
1161
- /*
1162
- * Even though it is a create, first let's see if we are even allowed
1163
- * to peek inside the parent
1164
- */
1165
- err = fh_verify (rqstp , fhp , S_IFDIR , NFSD_MAY_EXEC );
1166
- if (err )
1167
- goto out ;
1168
-
1169
1150
dentry = fhp -> fh_dentry ;
1170
1151
dirp = d_inode (dentry );
1171
1152
1172
- /*
1173
- * Check whether the response file handle has been verified yet.
1174
- * If it has, the parent directory should already be locked.
1175
- */
1176
- if (!resfhp -> fh_dentry ) {
1177
- host_err = fh_want_write (fhp );
1178
- if (host_err )
1179
- goto out_nfserr ;
1180
-
1181
- /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
1182
- fh_lock_nested (fhp , I_MUTEX_PARENT );
1183
- dchild = lookup_one_len (fname , dentry , flen );
1184
- host_err = PTR_ERR (dchild );
1185
- if (IS_ERR (dchild ))
1186
- goto out_nfserr ;
1187
- err = fh_compose (resfhp , fhp -> fh_export , dchild , fhp );
1188
- if (err )
1189
- goto out ;
1190
- } else {
1191
- /* called from nfsd_proc_create */
1192
- dchild = dget (resfhp -> fh_dentry );
1193
- if (!fhp -> fh_locked ) {
1194
- /* not actually possible */
1195
- printk (KERN_ERR
1196
- "nfsd_create: parent %pd2 not locked!\n" ,
1153
+ dchild = dget (resfhp -> fh_dentry );
1154
+ if (!fhp -> fh_locked ) {
1155
+ WARN_ONCE (1 , "nfsd_create: parent %pd2 not locked!\n" ,
1197
1156
dentry );
1198
- err = nfserr_io ;
1199
- goto out ;
1200
- }
1157
+ err = nfserr_io ;
1158
+ goto out ;
1201
1159
}
1202
1160
/*
1203
1161
* Make sure the child dentry is still negative ...
@@ -1225,9 +1183,6 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1225
1183
goto out ;
1226
1184
}
1227
1185
1228
- /*
1229
- * Get the dir op function pointer.
1230
- */
1231
1186
err = 0 ;
1232
1187
host_err = 0 ;
1233
1188
switch (type ) {
@@ -1254,7 +1209,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1254
1209
/*
1255
1210
* nfsd_create_setattr already committed the child. Transactional
1256
1211
* filesystems had a chance to commit changes for both parent and
1257
- * child * simultaneously making the following commit_metadata a
1212
+ * child simultaneously making the following commit_metadata a
1258
1213
* noop.
1259
1214
*/
1260
1215
err2 = nfserrno (commit_metadata (fhp ));
@@ -1275,6 +1230,54 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1275
1230
goto out ;
1276
1231
}
1277
1232
1233
+ /*
1234
+ * Create a filesystem object (regular, directory, special).
1235
+ * Note that the parent directory is left locked.
1236
+ *
1237
+ * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
1238
+ */
1239
+ __be32
1240
+ nfsd_create (struct svc_rqst * rqstp , struct svc_fh * fhp ,
1241
+ char * fname , int flen , struct iattr * iap ,
1242
+ int type , dev_t rdev , struct svc_fh * resfhp )
1243
+ {
1244
+ struct dentry * dentry , * dchild = NULL ;
1245
+ struct inode * dirp ;
1246
+ __be32 err ;
1247
+ int host_err ;
1248
+
1249
+ if (isdotent (fname , flen ))
1250
+ return nfserr_exist ;
1251
+
1252
+ /*
1253
+ * Even though it is a create, first let's see if we are even allowed
1254
+ * to peek inside the parent
1255
+ */
1256
+ err = fh_verify (rqstp , fhp , S_IFDIR , NFSD_MAY_EXEC );
1257
+ if (err )
1258
+ return err ;
1259
+
1260
+ dentry = fhp -> fh_dentry ;
1261
+ dirp = d_inode (dentry );
1262
+
1263
+ host_err = fh_want_write (fhp );
1264
+ if (host_err )
1265
+ return nfserrno (host_err );
1266
+
1267
+ fh_lock_nested (fhp , I_MUTEX_PARENT );
1268
+ dchild = lookup_one_len (fname , dentry , flen );
1269
+ host_err = PTR_ERR (dchild );
1270
+ if (IS_ERR (dchild ))
1271
+ return nfserrno (host_err );
1272
+ err = fh_compose (resfhp , fhp -> fh_export , dchild , fhp );
1273
+ if (err ) {
1274
+ dput (dchild );
1275
+ return err ;
1276
+ }
1277
+ return nfsd_create_locked (rqstp , fhp , fname , flen , iap , type ,
1278
+ rdev , resfhp );
1279
+ }
1280
+
1278
1281
#ifdef CONFIG_NFSD_V3
1279
1282
1280
1283
/*
0 commit comments