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