Use credential guards for scoped credential override with automatic
restoration on scope exit.

Signed-off-by: Christian Brauner <[email protected]>
---
 fs/nfs/localio.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
index 48bfe54b48a4..0c89a9d1e089 100644
--- a/fs/nfs/localio.c
+++ b/fs/nfs/localio.c
@@ -781,18 +781,11 @@ static void nfs_local_write_aio_complete(struct kiocb 
*kiocb, long ret)
        nfs_local_pgio_aio_complete(iocb); /* Calls 
nfs_local_write_aio_complete_work */
 }
 
-static void nfs_local_call_write(struct work_struct *work)
+static ssize_t do_nfs_local_call_write(struct nfs_local_kiocb *iocb,
+                                      struct file *filp)
 {
-       struct nfs_local_kiocb *iocb =
-               container_of(work, struct nfs_local_kiocb, work);
-       struct file *filp = iocb->kiocb.ki_filp;
-       unsigned long old_flags = current->flags;
-       const struct cred *save_cred;
        ssize_t status;
 
-       current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO;
-       save_cred = override_creds(filp->f_cred);
-
        file_start_write(filp);
        for (int i = 0; i < iocb->n_iters ; i++) {
                if (iocb->iter_is_dio_aligned[i]) {
@@ -837,7 +830,22 @@ static void nfs_local_call_write(struct work_struct *work)
        }
        file_end_write(filp);
 
-       revert_creds(save_cred);
+       return status;
+}
+
+static void nfs_local_call_write(struct work_struct *work)
+{
+       struct nfs_local_kiocb *iocb =
+               container_of(work, struct nfs_local_kiocb, work);
+       struct file *filp = iocb->kiocb.ki_filp;
+       unsigned long old_flags = current->flags;
+       ssize_t status;
+
+       current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO;
+
+       scoped_with_creds(filp->f_cred)
+               status = do_nfs_local_call_write(iocb, filp);
+
        current->flags = old_flags;
 
        if (status != -EIOCBQUEUED) {

-- 
2.47.3


Reply via email to