Whamcloud - gitweb
90894b39f114651bab6ef4a9bee1d90d39dba129
[fs/lustre-release.git] / lustre / obdfs / rw.c
1 /*
2  * OBDFS Super operations
3  *
4  * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
5  * Copryright (C) 1999 Stelias Computing Inc, 
6  *                (author Peter J. Braam <braam@stelias.com>)
7  * Copryright (C) 1999 Seagate Technology Inc.
8 */
9
10
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/mm.h>
14 #include <linux/string.h>
15 #include <linux/stat.h>
16 #include <linux/errno.h>
17 #include <linux/locks.h>
18 #include <linux/unistd.h>
19
20 #include <asm/system.h>
21 #include <asm/uaccess.h>
22
23 #include <linux/fs.h>
24 #include <linux/stat.h>
25 #include <asm/uaccess.h>
26 #include <linux/vmalloc.h>
27 #include <asm/segment.h>
28 #include <linux/mm.h>
29 #include <linux/pagemap.h>
30 #include <linux/smp_lock.h>
31
32 #include <linux/obd_support.h>
33 #include <linux/obd_ext2.h>
34 #include <linux/obdfs.h>
35
36
37 /* SYNCHRONOUS I/O for an inode */
38 static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
39 {
40         obd_count        num_obdo = 1;
41         obd_count        bufs_per_obdo = 1;
42         struct obdo     *oa;
43         char            *buf = (char *)page_address(page);
44         obd_size         count = PAGE_SIZE;
45         obd_off          offset = ((obd_off)page->index) << PAGE_SHIFT;
46         obd_flag         flags = create ? OBD_BRW_CREATE : 0;
47         int              err;
48
49         ENTRY;
50         if (IOPS(inode, brw) == NULL) {
51                 printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
52                 EXIT;
53                 return -EIO;
54         }
55
56         oa = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD);
57         if ( IS_ERR(oa) ) {
58                 EXIT;
59                 return PTR_ERR(oa);
60         }
61         obdfs_from_inode(oa, inode);
62
63         err = IOPS(inode, brw)(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
64                                &buf, &count, &offset, &flags);
65
66         if ( !err )
67                 obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
68
69         obdo_free(oa);
70         
71         EXIT;
72         return err;
73 } /* obdfs_brw */
74
75 /* returns the page unlocked, but with a reference */
76 int obdfs_readpage(struct file *file, struct page *page)
77 {
78         struct dentry *dentry = file->f_dentry;
79         struct inode *inode = dentry->d_inode;
80         int rc;
81
82         ENTRY;
83         /* PDEBUG(page, "READ"); */
84         rc = obdfs_brw(READ, inode, page, 0);
85         if ( !rc ) {
86                 SetPageUptodate(page);
87                 obd_unlock_page(page);
88         } 
89         /* PDEBUG(page, "READ"); */
90         EXIT;
91         return rc;
92 } /* obdfs_readpage */
93
94 int obdfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
95 {
96         struct inode *inode = page->mapping->host;
97         obd_off offset = ((obd_off)page->index) << PAGE_SHIFT;
98         int rc;
99         ENTRY; 
100         
101         /* PDEBUG(page, "READ"); */
102         if (Page_Uptodate(page)) { 
103                 EXIT;
104                 return 0; 
105         }
106
107         if ( (from <= offset) && (to >= offset + PAGE_SIZE) ) {
108                 EXIT;
109                 return 0;
110         }
111         
112         rc = obdfs_brw(READ, inode, page, 0);
113         if ( !rc ) {
114                 SetPageUptodate(page);
115                 /* obd_unlock_page(page); */ 
116         } 
117         /* PDEBUG(page, "READ"); */
118         EXIT;
119         return rc;
120 }
121
122
123
124
125 static kmem_cache_t *obdfs_pgrq_cachep = NULL;
126
127 int obdfs_init_pgrqcache(void)
128 {
129         ENTRY;
130         if (obdfs_pgrq_cachep == NULL) {
131                 CDEBUG(D_CACHE, "allocating obdfs_pgrq_cache\n");
132                 obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq",
133                                                       sizeof(struct obdfs_pgrq),
134                                                       0, SLAB_HWCACHE_ALIGN,
135                                                       NULL, NULL);
136                 if (obdfs_pgrq_cachep == NULL) {
137                         EXIT;
138                         return -ENOMEM;
139                 } else {
140                         CDEBUG(D_CACHE, "allocated cache at %p\n",
141                                obdfs_pgrq_cachep);
142                 }
143         } else {
144                 CDEBUG(D_CACHE, "using existing cache at %p\n",
145                        obdfs_pgrq_cachep);
146         }
147         EXIT;
148         return 0;
149 } /* obdfs_init_wreqcache */
150
151 inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq)
152 {
153         --obdfs_cache_count;
154         CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n",
155                pgrq->rq_page, obdfs_cache_count);
156         list_del(&pgrq->rq_plist);
157         OBDClearCachePage(pgrq->rq_page);
158         kmem_cache_free(obdfs_pgrq_cachep, pgrq);
159 }
160
161 void obdfs_cleanup_pgrqcache(void)
162 {
163         ENTRY;
164         if (obdfs_pgrq_cachep != NULL) {
165                 CDEBUG(D_CACHE, "destroying obdfs_pgrqcache at %p, count %ld\n",
166                        obdfs_pgrq_cachep, obdfs_cache_count);
167                 if (kmem_cache_destroy(obdfs_pgrq_cachep))
168                         printk(KERN_INFO __FUNCTION__
169                                ": unable to free all of cache\n");
170                 obdfs_pgrq_cachep = NULL;
171         } else
172                 printk(KERN_INFO __FUNCTION__ ": called with NULL pointer\n");
173
174         EXIT;
175 } /* obdfs_cleanup_wreqcache */
176
177
178 /* called with the list lock held */
179 static struct page *obdfs_find_page_index(struct inode *inode,
180                                           unsigned long index)
181 {
182         struct list_head *page_list = obdfs_iplist(inode);
183         struct list_head *tmp;
184         struct page *page;
185
186         ENTRY;
187
188         CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n",
189                inode->i_ino, index);
190         OIDEBUG(inode);
191
192         if (list_empty(page_list)) {
193                 EXIT;
194                 return NULL;
195         }
196         tmp = page_list;
197         while ( (tmp = tmp->next) != page_list ) {
198                 struct obdfs_pgrq *pgrq;
199
200                 pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
201                 page = pgrq->rq_page;
202                 if (index == page->index) {
203                         CDEBUG(D_INFO,
204                                "INDEX SEARCH found page %p, index %ld\n",
205                                page, index);
206                         EXIT;
207                         return page;
208                 }
209         } 
210
211         EXIT;
212         return NULL;
213 } /* obdfs_find_page_index */
214
215
216 /* call and free pages from Linux page cache: called with io lock on inodes */
217 int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
218                     obd_count num_obdos, struct obdo **obdos,
219                     obd_count *oa_bufs, struct page **pages, char **bufs,
220                     obd_size *counts, obd_off *offsets, obd_flag *flags)
221 {
222         int err;
223
224         ENTRY;
225         if (IOPS(inodes[0], brw) == NULL) {
226                 printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
227                 EXIT;
228                 return -EIO;
229         }
230
231         CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
232                num_io, num_obdos);
233         if (obd_debug_level & D_INFO) { /* DEBUGGING */
234                 int i;
235                 printk("OBDOS: ");
236                 for (i = 0; i < num_obdos; i++)
237                         printk("%ld:0x%p ", (long)obdos[i]->o_id, obdos[i]);
238
239                 printk("\nPAGES: ");
240                 for (i = 0; i < num_io; i++)
241                         printk("0x%p ", pages[i]);
242                 printk("\n");
243         }
244
245         err = IOPS(inodes[0], brw)(WRITE, IID(inodes[0]), num_obdos, obdos,
246                                   oa_bufs, bufs, counts, offsets, flags);
247
248         CDEBUG(D_INFO, "BRW done\n");
249         /* release the pages from the page cache */
250         while ( num_io > 0 ) {
251                 --num_io;
252                 CDEBUG(D_INFO, "calling put_page for %p, index %ld\n",
253                        pages[num_io], pages[num_io]->index);
254                 /* PDEBUG(pages[num_io], "do_vec_wr"); */
255                 put_page(pages[num_io]);
256                 /* PDEBUG(pages[num_io], "do_vec_wr"); */
257         }
258         CDEBUG(D_INFO, "put_page done\n");
259
260         while ( num_obdos > 0) {
261                 --num_obdos;
262                 CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id);
263                 /* copy o_blocks to i_blocks */
264                 obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]);
265                 obdo_free(obdos[num_obdos]);
266         }
267         CDEBUG(D_INFO, "obdo_free done\n");
268         EXIT;
269         return err;
270 }
271
272
273 /*
274  * Add a page to the write request cache list for later writing.
275  * ASYNCHRONOUS write method.
276  */
277 static int obdfs_add_page_to_cache(struct inode *inode, struct page *page)
278 {
279         int err = 0;
280         ENTRY;
281
282         /* The PG_obdcache bit is cleared by obdfs_pgrq_del() BEFORE the page
283          * is written, so at worst we will write the page out twice.
284          *
285          * If the page has the PG_obdcache bit set, then the inode MUST be
286          * on the superblock dirty list so we don't need to check this.
287          * Dirty inodes are removed from the superblock list ONLY when they
288          * don't have any more cached pages.  It is possible to have an inode
289          * with no dirty pages on the superblock list, but not possible to
290          * have an inode with dirty pages NOT on the superblock dirty list.
291          */
292         if (!OBDAddCachePage(page)) {
293                 struct obdfs_pgrq *pgrq;
294                 pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL);
295                 if (!pgrq) {
296                         OBDClearCachePage(page);
297                         EXIT;
298                         return -ENOMEM;
299                 }
300                 /* not really necessary since we set all pgrq fields here
301                 memset(pgrq, 0, sizeof(*pgrq)); 
302                 */
303                 
304                 pgrq->rq_page = page;
305                 pgrq->rq_jiffies = jiffies;
306                 get_page(pgrq->rq_page);
307
308                 obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
309                 list_add(&pgrq->rq_plist, obdfs_iplist(inode));
310                 obdfs_cache_count++;
311
312                 /* If inode isn't already on superblock inodes list, add it.
313                  *
314                  * We increment the reference count on the inode to keep it
315                  * from being freed from memory.  This _should_ be an iget()
316                  * with an iput() in both flush_reqs() and put_inode(), but
317                  * since put_inode() is called from iput() we can't call iput()
318                  * again there.  Instead we just increment/decrement i_count,
319                  * which is mostly what iget/iput do for an inode in memory.
320                  */
321                 if ( list_empty(obdfs_islist(inode)) ) {
322                         atomic_inc(&inode->i_count);
323                         CDEBUG(D_INFO,
324                                "adding inode %ld to superblock list %p\n",
325                                inode->i_ino, obdfs_slist(inode));
326                         list_add(obdfs_islist(inode), obdfs_slist(inode));
327                 }
328                 obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
329         }
330
331         /* XXX For testing purposes, we can write out the page here.
332         err = obdfs_flush_reqs(obdfs_slist(inode), ~0UL);
333          */
334
335         EXIT;
336         return err;
337 } /* obdfs_add_page_to_cache */
338
339
340 /* select between SYNC and ASYNC I/O methods */
341 int obdfs_do_writepage(struct page *page, int sync)
342 {
343         struct inode *inode = page->mapping->host;
344         int err;
345
346         ENTRY;
347         /* PDEBUG(page, "WRITEPAGE"); */
348         if ( sync )
349                 err = obdfs_brw(WRITE, inode, page, 1);
350         else {
351                 err = obdfs_add_page_to_cache(inode, page);
352                 CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n",
353                        inode->i_ino, page, err, Page_Uptodate(page));
354         }
355                 
356         if ( !err )
357                 SetPageUptodate(page);
358         /* PDEBUG(page,"WRITEPAGE"); */
359         EXIT;
360         return err;
361 } /* obdfs_do_writepage */
362
363
364
365 /* returns the page unlocked, but with a reference */
366 int obdfs_writepage(struct page *page)
367 {
368         return obdfs_do_writepage(page, 0);
369 }
370
371 int obdfs_commit_write(struct file *file, struct page *page, unsigned from, unsigned to)
372 {
373         int rc;
374         struct inode *inode = page->mapping->host;
375         loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
376         rc = obdfs_writepage(page);
377         kunmap(page);
378         if (pos > inode->i_size) {
379                 inode->i_size = pos;
380                 mark_inode_dirty(inode);
381         }
382         return 0;
383 }
384
385
386 /*
387  * This does the "real" work of the write. The generic routine has
388  * allocated the page, locked it, done all the page alignment stuff
389  * calculations etc. Now we should just copy the data from user
390  * space and write it back to the real medium..
391  *
392  * If the writer ends up delaying the write, the writer needs to
393  * increment the page use counts until he is done with the page.
394  *
395  * Return value is the number of bytes written.
396  */
397 int obdfs_write_one_page(struct file *file, struct page *page,
398                          unsigned long offset, unsigned long bytes,
399                          const char * buf)
400 {
401         struct inode *inode = file->f_dentry->d_inode;
402         int err;
403
404         ENTRY;
405         /* We check for complete page writes here, as we then don't have to
406          * get the page before writing over everything anyways.
407          */
408         if ( !Page_Uptodate(page) && (offset != 0 || bytes != PAGE_SIZE) ) {
409                 err = obdfs_brw(READ, inode, page, 0);
410                 if ( err )
411                         return err;
412                 SetPageUptodate(page);
413         }
414
415         if (copy_from_user((u8*)page_address(page) + offset, buf, bytes))
416                 return -EFAULT;
417
418         lock_kernel();
419         err = obdfs_writepage(page);
420         unlock_kernel();
421
422         return (err < 0 ? err : bytes);
423 } /* obdfs_write_one_page */
424
425 /* 
426  * return an up to date page:
427  *  - if locked is true then is returned locked
428  *  - if create is true the corresponding disk blocks are created 
429  *  - page is held, i.e. caller must release the page
430  *
431  * modeled on NFS code.
432  */
433 struct page *obdfs_getpage(struct inode *inode, unsigned long offset,
434                            int create, int locked)
435 {
436         struct page * page;
437         int index;
438         int err;
439
440         ENTRY;
441
442         offset = offset & PAGE_CACHE_MASK;
443         CDEBUG(D_INFO, "ino: %ld, offset %ld, create %d, locked %d\n",
444                inode->i_ino, offset, create, locked);
445         index = offset >> PAGE_CACHE_SHIFT;
446
447         page = grab_cache_page(&inode->i_data, index);
448
449         /* Yuck, no page */
450         if (! page) {
451             printk(KERN_WARNING " grab_cache_page says no dice ...\n");
452             EXIT;
453             return NULL;
454         }
455
456         /* PDEBUG(page, "GETPAGE: got page - before reading\n"); */
457         /* now check if the data in the page is up to date */
458         if ( Page_Uptodate(page)) { 
459                 if (!locked) {
460                         if (PageLocked(page))
461                                 obd_unlock_page(page);
462                 } else {
463                         printk("file %s, line %d: expecting locked page\n",
464                                __FILE__, __LINE__); 
465                 }
466                 EXIT;
467                 return page;
468         } 
469
470
471 #ifdef EXT2_OBD_DEBUG
472         if ((obd_debug_level & D_INFO) && obdfs_find_page_index(inode, index)) {
473                 CDEBUG(D_INFO, "OVERWRITE: found dirty page %p, index %ld\n",
474                        page, page->index);
475         }
476 #endif
477
478         err = obdfs_brw(READ, inode, page, create);
479
480         if ( err ) {
481                 SetPageError(page);
482                 obd_unlock_page(page);
483                 EXIT;
484                 return page;
485         }
486
487         if ( !locked )
488                 obd_unlock_page(page);
489         SetPageUptodate(page);
490         /* PDEBUG(page,"GETPAGE - after reading"); */
491         EXIT;
492         return page;
493 } /* obdfs_getpage */
494
495
496 void obdfs_truncate(struct inode *inode)
497 {
498         struct obdo *oa;
499         int err;
500         ENTRY;
501
502         obdfs_dequeue_pages(inode);
503
504         if (IOPS(inode, punch) == NULL) {
505                 printk(KERN_ERR __FUNCTION__ ": no punch method!\n");
506                 EXIT;
507                 return;
508         }
509         oa = obdo_alloc();
510         if ( !oa ) {
511                 /* XXX This would give an inconsistent FS, so deal with it as
512                  * best we can for now - an obdo on the stack is not pretty.
513                  */
514                 struct obdo obdo;
515
516                 printk(__FUNCTION__ ": obdo_alloc failed - using stack!\n");
517
518                 obdo.o_valid = OBD_MD_FLNOTOBD;
519                 obdfs_from_inode(&obdo, inode);
520
521                 err = IOPS(inode, punch)(IID(inode), &obdo, obdo.o_size, 0);
522         } else {
523                 oa->o_valid = OBD_MD_FLNOTOBD;
524                 obdfs_from_inode(oa, inode);
525
526                 CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
527                        (long)oa->o_id, oa->o_size);
528                 err = IOPS(inode, punch)(IID(inode), oa, oa->o_size, 0);
529
530                 obdo_free(oa);
531         }
532
533         if (err) {
534                 printk(__FUNCTION__ ": obd_truncate fails (%d)\n", err);
535                 EXIT;
536                 return;
537         }
538         EXIT;
539 } /* obdfs_truncate */