diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/vfs.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6e50aaa56ca2..0c076293155d 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1176,6 +1176,21 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, | |||
1176 | return 0; | 1176 | return 0; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | /* HPUX client sometimes creates a file in mode 000, and sets size to 0. | ||
1180 | * setting size to 0 may fail for some specific file systems by the permission | ||
1181 | * checking which requires WRITE permission but the mode is 000. | ||
1182 | * we ignore the resizing(to 0) on the just new created file, since the size is | ||
1183 | * 0 after file created. | ||
1184 | * | ||
1185 | * call this only after vfs_create() is called. | ||
1186 | * */ | ||
1187 | static void | ||
1188 | nfsd_check_ignore_resizing(struct iattr *iap) | ||
1189 | { | ||
1190 | if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0)) | ||
1191 | iap->ia_valid &= ~ATTR_SIZE; | ||
1192 | } | ||
1193 | |||
1179 | /* | 1194 | /* |
1180 | * Create a file (regular, directory, device, fifo); UNIX sockets | 1195 | * Create a file (regular, directory, device, fifo); UNIX sockets |
1181 | * not yet implemented. | 1196 | * not yet implemented. |
@@ -1271,6 +1286,8 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1271 | switch (type) { | 1286 | switch (type) { |
1272 | case S_IFREG: | 1287 | case S_IFREG: |
1273 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); | 1288 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); |
1289 | if (!host_err) | ||
1290 | nfsd_check_ignore_resizing(iap); | ||
1274 | break; | 1291 | break; |
1275 | case S_IFDIR: | 1292 | case S_IFDIR: |
1276 | host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); | 1293 | host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); |
@@ -1424,6 +1441,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1424 | /* setattr will sync the child (or not) */ | 1441 | /* setattr will sync the child (or not) */ |
1425 | } | 1442 | } |
1426 | 1443 | ||
1444 | nfsd_check_ignore_resizing(iap); | ||
1445 | |||
1427 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1446 | if (createmode == NFS3_CREATE_EXCLUSIVE) { |
1428 | /* Cram the verifier into atime/mtime */ | 1447 | /* Cram the verifier into atime/mtime */ |
1429 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME | 1448 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME |