~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/backing-file.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/backing-file.c (Version linux-6.11.5) and /fs/backing-file.c (Version linux-5.12.19)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * Common helpers for stackable filesystems an    
  4  *                                                
  5  * Forked from fs/overlayfs/file.c.               
  6  *                                                
  7  * Copyright (C) 2017 Red Hat, Inc.               
  8  * Copyright (C) 2023 CTERA Networks.             
  9  */                                               
 10                                                   
 11 #include <linux/fs.h>                             
 12 #include <linux/backing-file.h>                   
 13 #include <linux/splice.h>                         
 14 #include <linux/mm.h>                             
 15                                                   
 16 #include "internal.h"                             
 17                                                   
 18 /**                                               
 19  * backing_file_open - open a backing file for    
 20  * @user_path:  path that the user reuqested t    
 21  * @flags:      open flags                        
 22  * @real_path:  path of the backing file          
 23  * @cred:       credentials for open              
 24  *                                                
 25  * Open a backing file for a stackable filesys    
 26  * @user_path may be on the stackable filesyst    
 27  * underlying filesystem.  In this case, we wa    
 28  * @user_path of the stackable filesystem. Thi    
 29  * returned file into a container structure th    
 30  * file's path, which can be retrieved using b    
 31  */                                               
 32 struct file *backing_file_open(const struct pa    
 33                                const struct pa    
 34                                const struct cr    
 35 {                                                 
 36         struct file *f;                           
 37         int error;                                
 38                                                   
 39         f = alloc_empty_backing_file(flags, cr    
 40         if (IS_ERR(f))                            
 41                 return f;                         
 42                                                   
 43         path_get(user_path);                      
 44         *backing_file_user_path(f) = *user_pat    
 45         error = vfs_open(real_path, f);           
 46         if (error) {                              
 47                 fput(f);                          
 48                 f = ERR_PTR(error);               
 49         }                                         
 50                                                   
 51         return f;                                 
 52 }                                                 
 53 EXPORT_SYMBOL_GPL(backing_file_open);             
 54                                                   
 55 struct file *backing_tmpfile_open(const struct    
 56                                   const struct    
 57                                   umode_t mode    
 58 {                                                 
 59         struct mnt_idmap *real_idmap = mnt_idm    
 60         struct file *f;                           
 61         int error;                                
 62                                                   
 63         f = alloc_empty_backing_file(flags, cr    
 64         if (IS_ERR(f))                            
 65                 return f;                         
 66                                                   
 67         path_get(user_path);                      
 68         *backing_file_user_path(f) = *user_pat    
 69         error = vfs_tmpfile(real_idmap, real_p    
 70         if (error) {                              
 71                 fput(f);                          
 72                 f = ERR_PTR(error);               
 73         }                                         
 74         return f;                                 
 75 }                                                 
 76 EXPORT_SYMBOL(backing_tmpfile_open);              
 77                                                   
 78 struct backing_aio {                              
 79         struct kiocb iocb;                        
 80         refcount_t ref;                           
 81         struct kiocb *orig_iocb;                  
 82         /* used for aio completion */             
 83         void (*end_write)(struct file *);         
 84         struct work_struct work;                  
 85         long res;                                 
 86 };                                                
 87                                                   
 88 static struct kmem_cache *backing_aio_cachep;     
 89                                                   
 90 #define BACKING_IOCB_MASK \                       
 91         (IOCB_NOWAIT | IOCB_HIPRI | IOCB_DSYNC    
 92                                                   
 93 static rwf_t iocb_to_rw_flags(int flags)          
 94 {                                                 
 95         return (__force rwf_t)(flags & BACKING    
 96 }                                                 
 97                                                   
 98 static void backing_aio_put(struct backing_aio    
 99 {                                                 
100         if (refcount_dec_and_test(&aio->ref))     
101                 fput(aio->iocb.ki_filp);          
102                 kmem_cache_free(backing_aio_ca    
103         }                                         
104 }                                                 
105                                                   
106 static void backing_aio_cleanup(struct backing    
107 {                                                 
108         struct kiocb *iocb = &aio->iocb;          
109         struct kiocb *orig_iocb = aio->orig_io    
110                                                   
111         if (aio->end_write)                       
112                 aio->end_write(orig_iocb->ki_f    
113                                                   
114         orig_iocb->ki_pos = iocb->ki_pos;         
115         backing_aio_put(aio);                     
116 }                                                 
117                                                   
118 static void backing_aio_rw_complete(struct kio    
119 {                                                 
120         struct backing_aio *aio = container_of    
121         struct kiocb *orig_iocb = aio->orig_io    
122                                                   
123         if (iocb->ki_flags & IOCB_WRITE)          
124                 kiocb_end_write(iocb);            
125                                                   
126         backing_aio_cleanup(aio, res);            
127         orig_iocb->ki_complete(orig_iocb, res)    
128 }                                                 
129                                                   
130 static void backing_aio_complete_work(struct w    
131 {                                                 
132         struct backing_aio *aio = container_of    
133                                                   
134         backing_aio_rw_complete(&aio->iocb, ai    
135 }                                                 
136                                                   
137 static void backing_aio_queue_completion(struc    
138 {                                                 
139         struct backing_aio *aio = container_of    
140                                                   
141         /*                                        
142          * Punt to a work queue to serialize u    
143          */                                       
144         aio->res = res;                           
145         INIT_WORK(&aio->work, backing_aio_comp    
146         queue_work(file_inode(aio->orig_iocb->    
147                    &aio->work);                   
148 }                                                 
149                                                   
150 static int backing_aio_init_wq(struct kiocb *i    
151 {                                                 
152         struct super_block *sb = file_inode(io    
153                                                   
154         if (sb->s_dio_done_wq)                    
155                 return 0;                         
156                                                   
157         return sb_init_dio_done_wq(sb);           
158 }                                                 
159                                                   
160                                                   
161 ssize_t backing_file_read_iter(struct file *fi    
162                                struct kiocb *i    
163                                struct backing_    
164 {                                                 
165         struct backing_aio *aio = NULL;           
166         const struct cred *old_cred;              
167         ssize_t ret;                              
168                                                   
169         if (WARN_ON_ONCE(!(file->f_mode & FMOD    
170                 return -EIO;                      
171                                                   
172         if (!iov_iter_count(iter))                
173                 return 0;                         
174                                                   
175         if (iocb->ki_flags & IOCB_DIRECT &&       
176             !(file->f_mode & FMODE_CAN_ODIRECT    
177                 return -EINVAL;                   
178                                                   
179         old_cred = override_creds(ctx->cred);     
180         if (is_sync_kiocb(iocb)) {                
181                 rwf_t rwf = iocb_to_rw_flags(f    
182                                                   
183                 ret = vfs_iter_read(file, iter    
184         } else {                                  
185                 ret = -ENOMEM;                    
186                 aio = kmem_cache_zalloc(backin    
187                 if (!aio)                         
188                         goto out;                 
189                                                   
190                 aio->orig_iocb = iocb;            
191                 kiocb_clone(&aio->iocb, iocb,     
192                 aio->iocb.ki_complete = backin    
193                 refcount_set(&aio->ref, 2);       
194                 ret = vfs_iocb_iter_read(file,    
195                 backing_aio_put(aio);             
196                 if (ret != -EIOCBQUEUED)          
197                         backing_aio_cleanup(ai    
198         }                                         
199 out:                                              
200         revert_creds(old_cred);                   
201                                                   
202         if (ctx->accessed)                        
203                 ctx->accessed(ctx->user_file);    
204                                                   
205         return ret;                               
206 }                                                 
207 EXPORT_SYMBOL_GPL(backing_file_read_iter);        
208                                                   
209 ssize_t backing_file_write_iter(struct file *f    
210                                 struct kiocb *    
211                                 struct backing    
212 {                                                 
213         const struct cred *old_cred;              
214         ssize_t ret;                              
215                                                   
216         if (WARN_ON_ONCE(!(file->f_mode & FMOD    
217                 return -EIO;                      
218                                                   
219         if (!iov_iter_count(iter))                
220                 return 0;                         
221                                                   
222         ret = file_remove_privs(ctx->user_file    
223         if (ret)                                  
224                 return ret;                       
225                                                   
226         if (iocb->ki_flags & IOCB_DIRECT &&       
227             !(file->f_mode & FMODE_CAN_ODIRECT    
228                 return -EINVAL;                   
229                                                   
230         /*                                        
231          * Stacked filesystems don't support d    
232          * this property in case it is set by     
233          */                                       
234         flags &= ~IOCB_DIO_CALLER_COMP;           
235                                                   
236         old_cred = override_creds(ctx->cred);     
237         if (is_sync_kiocb(iocb)) {                
238                 rwf_t rwf = iocb_to_rw_flags(f    
239                                                   
240                 ret = vfs_iter_write(file, ite    
241                 if (ctx->end_write)               
242                         ctx->end_write(ctx->us    
243         } else {                                  
244                 struct backing_aio *aio;          
245                                                   
246                 ret = backing_aio_init_wq(iocb    
247                 if (ret)                          
248                         goto out;                 
249                                                   
250                 ret = -ENOMEM;                    
251                 aio = kmem_cache_zalloc(backin    
252                 if (!aio)                         
253                         goto out;                 
254                                                   
255                 aio->orig_iocb = iocb;            
256                 aio->end_write = ctx->end_writ    
257                 kiocb_clone(&aio->iocb, iocb,     
258                 aio->iocb.ki_flags = flags;       
259                 aio->iocb.ki_complete = backin    
260                 refcount_set(&aio->ref, 2);       
261                 ret = vfs_iocb_iter_write(file    
262                 backing_aio_put(aio);             
263                 if (ret != -EIOCBQUEUED)          
264                         backing_aio_cleanup(ai    
265         }                                         
266 out:                                              
267         revert_creds(old_cred);                   
268                                                   
269         return ret;                               
270 }                                                 
271 EXPORT_SYMBOL_GPL(backing_file_write_iter);       
272                                                   
273 ssize_t backing_file_splice_read(struct file *    
274                                  struct pipe_i    
275                                  unsigned int     
276                                  struct backin    
277 {                                                 
278         const struct cred *old_cred;              
279         ssize_t ret;                              
280                                                   
281         if (WARN_ON_ONCE(!(in->f_mode & FMODE_    
282                 return -EIO;                      
283                                                   
284         old_cred = override_creds(ctx->cred);     
285         ret = vfs_splice_read(in, ppos, pipe,     
286         revert_creds(old_cred);                   
287                                                   
288         if (ctx->accessed)                        
289                 ctx->accessed(ctx->user_file);    
290                                                   
291         return ret;                               
292 }                                                 
293 EXPORT_SYMBOL_GPL(backing_file_splice_read);      
294                                                   
295 ssize_t backing_file_splice_write(struct pipe_    
296                                   struct file     
297                                   unsigned int    
298                                   struct backi    
299 {                                                 
300         const struct cred *old_cred;              
301         ssize_t ret;                              
302                                                   
303         if (WARN_ON_ONCE(!(out->f_mode & FMODE    
304                 return -EIO;                      
305                                                   
306         if (!out->f_op->splice_write)             
307                 return -EINVAL;                   
308                                                   
309         ret = file_remove_privs(ctx->user_file    
310         if (ret)                                  
311                 return ret;                       
312                                                   
313         old_cred = override_creds(ctx->cred);     
314         file_start_write(out);                    
315         ret = out->f_op->splice_write(pipe, ou    
316         file_end_write(out);                      
317         revert_creds(old_cred);                   
318                                                   
319         if (ctx->end_write)                       
320                 ctx->end_write(ctx->user_file)    
321                                                   
322         return ret;                               
323 }                                                 
324 EXPORT_SYMBOL_GPL(backing_file_splice_write);     
325                                                   
326 int backing_file_mmap(struct file *file, struc    
327                       struct backing_file_ctx     
328 {                                                 
329         const struct cred *old_cred;              
330         int ret;                                  
331                                                   
332         if (WARN_ON_ONCE(!(file->f_mode & FMOD    
333             WARN_ON_ONCE(ctx->user_file != vma    
334                 return -EIO;                      
335                                                   
336         if (!file->f_op->mmap)                    
337                 return -ENODEV;                   
338                                                   
339         vma_set_file(vma, file);                  
340                                                   
341         old_cred = override_creds(ctx->cred);     
342         ret = call_mmap(vma->vm_file, vma);       
343         revert_creds(old_cred);                   
344                                                   
345         if (ctx->accessed)                        
346                 ctx->accessed(ctx->user_file);    
347                                                   
348         return ret;                               
349 }                                                 
350 EXPORT_SYMBOL_GPL(backing_file_mmap);             
351                                                   
352 static int __init backing_aio_init(void)          
353 {                                                 
354         backing_aio_cachep = KMEM_CACHE(backin    
355         if (!backing_aio_cachep)                  
356                 return -ENOMEM;                   
357                                                   
358         return 0;                                 
359 }                                                 
360 fs_initcall(backing_aio_init);                    
361                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php