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