diff options
-rw-r--r-- | fs/nfsd/vfs.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 755ba43c13e1..cc75e4fcd02b 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1151,6 +1151,26 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1151 | } | 1151 | } |
1152 | #endif /* CONFIG_NFSD_V3 */ | 1152 | #endif /* CONFIG_NFSD_V3 */ |
1153 | 1153 | ||
1154 | __be32 | ||
1155 | nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, | ||
1156 | struct iattr *iap) | ||
1157 | { | ||
1158 | /* | ||
1159 | * Mode has already been set earlier in create: | ||
1160 | */ | ||
1161 | iap->ia_valid &= ~ATTR_MODE; | ||
1162 | /* | ||
1163 | * Setting uid/gid works only for root. Irix appears to | ||
1164 | * send along the gid on create when it tries to implement | ||
1165 | * setgid directories via NFS: | ||
1166 | */ | ||
1167 | if (current->fsuid != 0) | ||
1168 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); | ||
1169 | if (iap->ia_valid) | ||
1170 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | ||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1154 | /* | 1174 | /* |
1155 | * Create a file (regular, directory, device, fifo); UNIX sockets | 1175 | * Create a file (regular, directory, device, fifo); UNIX sockets |
1156 | * not yet implemented. | 1176 | * not yet implemented. |
@@ -1167,6 +1187,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1167 | struct dentry *dentry, *dchild = NULL; | 1187 | struct dentry *dentry, *dchild = NULL; |
1168 | struct inode *dirp; | 1188 | struct inode *dirp; |
1169 | __be32 err; | 1189 | __be32 err; |
1190 | __be32 err2; | ||
1170 | int host_err; | 1191 | int host_err; |
1171 | 1192 | ||
1172 | err = nfserr_perm; | 1193 | err = nfserr_perm; |
@@ -1257,16 +1278,9 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1257 | } | 1278 | } |
1258 | 1279 | ||
1259 | 1280 | ||
1260 | /* Set file attributes. Mode has already been set and | 1281 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); |
1261 | * setting uid/gid works only for root. Irix appears to | 1282 | if (err2) |
1262 | * send along the gid when it tries to implement setgid | 1283 | err = err2; |
1263 | * directories via NFS. | ||
1264 | */ | ||
1265 | if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { | ||
1266 | __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | ||
1267 | if (err2) | ||
1268 | err = err2; | ||
1269 | } | ||
1270 | /* | 1284 | /* |
1271 | * Update the file handle to get the new inode info. | 1285 | * Update the file handle to get the new inode info. |
1272 | */ | 1286 | */ |
@@ -1295,6 +1309,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1295 | struct dentry *dentry, *dchild = NULL; | 1309 | struct dentry *dentry, *dchild = NULL; |
1296 | struct inode *dirp; | 1310 | struct inode *dirp; |
1297 | __be32 err; | 1311 | __be32 err; |
1312 | __be32 err2; | ||
1298 | int host_err; | 1313 | int host_err; |
1299 | __u32 v_mtime=0, v_atime=0; | 1314 | __u32 v_mtime=0, v_atime=0; |
1300 | 1315 | ||
@@ -1399,16 +1414,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1399 | iap->ia_atime.tv_nsec = 0; | 1414 | iap->ia_atime.tv_nsec = 0; |
1400 | } | 1415 | } |
1401 | 1416 | ||
1402 | /* Set file attributes. | ||
1403 | * Irix appears to send along the gid when it tries to | ||
1404 | * implement setgid directories via NFS. Clear out all that cruft. | ||
1405 | */ | ||
1406 | set_attr: | 1417 | set_attr: |
1407 | if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { | 1418 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); |
1408 | __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | 1419 | if (err2) |
1409 | if (err2) | 1420 | err = err2; |
1410 | err = err2; | ||
1411 | } | ||
1412 | 1421 | ||
1413 | /* | 1422 | /* |
1414 | * Update the filehandle to get the new inode info. | 1423 | * Update the filehandle to get the new inode info. |