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