vfs.c (3c69a99b62fde9de86a612ef1daaa07d95f0a773) vfs.c (7fe2a71dda349a1afa75781f0cc7975be9784d15)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * File operations used by nfsd. Some of these have been ripped from
4 * other parts of the kernel because they weren't exported, others
5 * are partial duplicates with added or changed functionality.
6 *
7 * Note that several functions dget() the dentry upon which they want
8 * to act, most notably those that create directory entries. Response

--- 335 unchanged lines hidden (view full) ---

344 }
345 return nfserrno(get_write_access(inode));
346}
347
348/*
349 * Set various file attributes. After this call fhp needs an fh_put.
350 */
351__be32
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * File operations used by nfsd. Some of these have been ripped from
4 * other parts of the kernel because they weren't exported, others
5 * are partial duplicates with added or changed functionality.
6 *
7 * Note that several functions dget() the dentry upon which they want
8 * to act, most notably those that create directory entries. Response

--- 335 unchanged lines hidden (view full) ---

344 }
345 return nfserrno(get_write_access(inode));
346}
347
348/*
349 * Set various file attributes. After this call fhp needs an fh_put.
350 */
351__be32
352nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
352nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
353 struct nfsd_attrs *attr,
353 int check_guard, time64_t guardtime)
354{
355 struct dentry *dentry;
356 struct inode *inode;
354 int check_guard, time64_t guardtime)
355{
356 struct dentry *dentry;
357 struct inode *inode;
358 struct iattr *iap = attr->na_iattr;
357 int accmode = NFSD_MAY_SATTR;
358 umode_t ftype = 0;
359 __be32 err;
360 int host_err;
361 bool get_write_count;
362 bool size_change = (iap->ia_valid & ATTR_SIZE);
363
364 if (iap->ia_valid & ATTR_SIZE) {

--- 832 unchanged lines hidden (view full) ---

1197 return err;
1198}
1199
1200/**
1201 * nfsd_create_setattr - Set a created file's attributes
1202 * @rqstp: RPC transaction being executed
1203 * @fhp: NFS filehandle of parent directory
1204 * @resfhp: NFS filehandle of new object
359 int accmode = NFSD_MAY_SATTR;
360 umode_t ftype = 0;
361 __be32 err;
362 int host_err;
363 bool get_write_count;
364 bool size_change = (iap->ia_valid & ATTR_SIZE);
365
366 if (iap->ia_valid & ATTR_SIZE) {

--- 832 unchanged lines hidden (view full) ---

1199 return err;
1200}
1201
1202/**
1203 * nfsd_create_setattr - Set a created file's attributes
1204 * @rqstp: RPC transaction being executed
1205 * @fhp: NFS filehandle of parent directory
1206 * @resfhp: NFS filehandle of new object
1205 * @iap: requested attributes of new object
1207 * @attrs: requested attributes of new object
1206 *
1207 * Returns nfs_ok on success, or an nfsstat in network byte order.
1208 */
1209__be32
1210nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
1208 *
1209 * Returns nfs_ok on success, or an nfsstat in network byte order.
1210 */
1211__be32
1212nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
1211 struct svc_fh *resfhp, struct iattr *iap)
1213 struct svc_fh *resfhp, struct nfsd_attrs *attrs)
1212{
1214{
1215 struct iattr *iap = attrs->na_iattr;
1213 __be32 status;
1214
1215 /*
1216 * Mode has already been set by file creation.
1217 */
1218 iap->ia_valid &= ~ATTR_MODE;
1219
1220 /*

--- 4 unchanged lines hidden (view full) ---

1225 if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
1226 iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
1227
1228 /*
1229 * Callers expect new file metadata to be committed even
1230 * if the attributes have not changed.
1231 */
1232 if (iap->ia_valid)
1216 __be32 status;
1217
1218 /*
1219 * Mode has already been set by file creation.
1220 */
1221 iap->ia_valid &= ~ATTR_MODE;
1222
1223 /*

--- 4 unchanged lines hidden (view full) ---

1228 if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
1229 iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
1230
1231 /*
1232 * Callers expect new file metadata to be committed even
1233 * if the attributes have not changed.
1234 */
1235 if (iap->ia_valid)
1233 status = nfsd_setattr(rqstp, resfhp, iap, 0, (time64_t)0);
1236 status = nfsd_setattr(rqstp, resfhp, attrs, 0, (time64_t)0);
1234 else
1235 status = nfserrno(commit_metadata(resfhp));
1236
1237 /*
1238 * Transactional filesystems had a chance to commit changes
1239 * for both parent and child simultaneously making the
1240 * following commit_metadata a noop in many cases.
1241 */

--- 22 unchanged lines hidden (view full) ---

1264{
1265 if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0))
1266 iap->ia_valid &= ~ATTR_SIZE;
1267}
1268
1269/* The parent directory should already be locked: */
1270__be32
1271nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
1237 else
1238 status = nfserrno(commit_metadata(resfhp));
1239
1240 /*
1241 * Transactional filesystems had a chance to commit changes
1242 * for both parent and child simultaneously making the
1243 * following commit_metadata a noop in many cases.
1244 */

--- 22 unchanged lines hidden (view full) ---

1267{
1268 if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0))
1269 iap->ia_valid &= ~ATTR_SIZE;
1270}
1271
1272/* The parent directory should already be locked: */
1273__be32
1274nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
1272 char *fname, int flen, struct iattr *iap,
1273 int type, dev_t rdev, struct svc_fh *resfhp)
1275 char *fname, int flen, struct nfsd_attrs *attrs,
1276 int type, dev_t rdev, struct svc_fh *resfhp)
1274{
1275 struct dentry *dentry, *dchild;
1276 struct inode *dirp;
1277{
1278 struct dentry *dentry, *dchild;
1279 struct inode *dirp;
1280 struct iattr *iap = attrs->na_iattr;
1277 __be32 err;
1278 int host_err;
1279
1280 dentry = fhp->fh_dentry;
1281 dirp = d_inode(dentry);
1282
1283 dchild = dget(resfhp->fh_dentry);
1284 if (!fhp->fh_locked) {

--- 57 unchanged lines hidden (view full) ---

1342 default:
1343 printk(KERN_WARNING "nfsd: bad file type %o in nfsd_create\n",
1344 type);
1345 host_err = -EINVAL;
1346 }
1347 if (host_err < 0)
1348 goto out_nfserr;
1349
1281 __be32 err;
1282 int host_err;
1283
1284 dentry = fhp->fh_dentry;
1285 dirp = d_inode(dentry);
1286
1287 dchild = dget(resfhp->fh_dentry);
1288 if (!fhp->fh_locked) {

--- 57 unchanged lines hidden (view full) ---

1346 default:
1347 printk(KERN_WARNING "nfsd: bad file type %o in nfsd_create\n",
1348 type);
1349 host_err = -EINVAL;
1350 }
1351 if (host_err < 0)
1352 goto out_nfserr;
1353
1350 err = nfsd_create_setattr(rqstp, fhp, resfhp, iap);
1354 err = nfsd_create_setattr(rqstp, fhp, resfhp, attrs);
1351
1352out:
1353 dput(dchild);
1354 return err;
1355
1356out_nfserr:
1357 err = nfserrno(host_err);
1358 goto out;
1359}
1360
1361/*
1362 * Create a filesystem object (regular, directory, special).
1363 * Note that the parent directory is left locked.
1364 *
1365 * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
1366 */
1367__be32
1368nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1355
1356out:
1357 dput(dchild);
1358 return err;
1359
1360out_nfserr:
1361 err = nfserrno(host_err);
1362 goto out;
1363}
1364
1365/*
1366 * Create a filesystem object (regular, directory, special).
1367 * Note that the parent directory is left locked.
1368 *
1369 * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
1370 */
1371__be32
1372nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1369 char *fname, int flen, struct iattr *iap,
1370 int type, dev_t rdev, struct svc_fh *resfhp)
1373 char *fname, int flen, struct nfsd_attrs *attrs,
1374 int type, dev_t rdev, struct svc_fh *resfhp)
1371{
1372 struct dentry *dentry, *dchild = NULL;
1373 __be32 err;
1374 int host_err;
1375
1376 if (isdotent(fname, flen))
1377 return nfserr_exist;
1378

--- 15 unchanged lines hidden (view full) ---

1394 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
1395 /*
1396 * We unconditionally drop our ref to dchild as fh_compose will have
1397 * already grabbed its own ref for it.
1398 */
1399 dput(dchild);
1400 if (err)
1401 return err;
1375{
1376 struct dentry *dentry, *dchild = NULL;
1377 __be32 err;
1378 int host_err;
1379
1380 if (isdotent(fname, flen))
1381 return nfserr_exist;
1382

--- 15 unchanged lines hidden (view full) ---

1398 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
1399 /*
1400 * We unconditionally drop our ref to dchild as fh_compose will have
1401 * already grabbed its own ref for it.
1402 */
1403 dput(dchild);
1404 if (err)
1405 return err;
1402 return nfsd_create_locked(rqstp, fhp, fname, flen, iap, type,
1406 return nfsd_create_locked(rqstp, fhp, fname, flen, attrs, type,
1403 rdev, resfhp);
1404}
1405
1406/*
1407 * Read a symlink. On entry, *lenp must contain the maximum path length that
1408 * fits into the buffer. On return, it contains the true length.
1409 * N.B. After this call fhp needs an fh_put
1410 */

--- 880 unchanged lines hidden ---
1407 rdev, resfhp);
1408}
1409
1410/*
1411 * Read a symlink. On entry, *lenp must contain the maximum path length that
1412 * fits into the buffer. On return, it contains the true length.
1413 * N.B. After this call fhp needs an fh_put
1414 */

--- 880 unchanged lines hidden ---