Whamcloud - gitweb
7b6a16789db3c778c308849dc4a43d2fc7faed2b
[fs/lustre-release.git] / lustre / llite / rw.c
1 /*
2  * Lustre Light I/O Page Cache
3  *
4  * Copyright (C) 2002, Cluster File Systems, Inc. 
5  */
6
7 #include <linux/config.h>
8 #include <linux/kernel.h>
9 #include <linux/mm.h>
10 #include <linux/string.h>
11 #include <linux/stat.h>
12 #include <linux/errno.h>
13 #include <linux/locks.h>
14 #include <linux/unistd.h>
15 #include <linux/version.h>
16 #include <asm/system.h>
17 #include <asm/uaccess.h>
18
19 #include <linux/fs.h>
20 #include <linux/stat.h>
21 #include <asm/uaccess.h>
22 #include <linux/vmalloc.h>
23 #include <asm/segment.h>
24 #include <linux/mm.h>
25 #include <linux/pagemap.h>
26 #include <linux/smp_lock.h>
27
28 #include <linux/obd_support.h>
29 #include <linux/lustre_lib.h>
30 #include <linux/lustre_idl.h>
31 #include <linux/lustre_mds.h>
32 #include <linux/lustre_light.h>
33
34 int ll_inode_setattr(struct inode *inode, struct iattr *attr);
35
36 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10))
37 /*
38  * Add a page to the dirty page list.
39  */
40 void __set_page_dirty(struct page *page)
41 {
42         struct address_space *mapping;
43         spinlock_t *pg_lock;
44
45         pg_lock = PAGECACHE_LOCK(page);
46         spin_lock(pg_lock);
47
48         mapping = page->mapping;
49         spin_lock(&mapping->page_lock);
50
51         list_del(&page->list);
52         list_add(&page->list, &mapping->dirty_pages);
53
54         spin_unlock(&mapping->page_lock);
55         spin_unlock(pg_lock);
56
57         if (mapping->host)
58                 mark_inode_dirty_pages(mapping->host);
59 }
60 #else
61 /*
62  * Add a page to the dirty page list.
63  */
64 void set_page_dirty(struct page *page)
65 {
66         if (!test_and_set_bit(PG_dirty, &page->flags)) {
67                 struct address_space *mapping = page->mapping;
68
69                 if (mapping) {
70                         spin_lock(&pagecache_lock);
71                         list_del(&page->list);
72                         list_add(&page->list, &mapping->dirty_pages);
73                         spin_unlock(&pagecache_lock);
74
75                         if (mapping->host)
76                                 mark_inode_dirty_pages(mapping->host);
77                 }
78         }
79 }
80 #endif
81
82 static void inline ll_oa_from_inode(struct obdo *oa, struct inode *inode)
83 {
84         struct ll_inode_info *oinfo = ll_i2info(inode);
85
86         if ( oa->o_valid & OBD_MD_FLID )
87                 oa->o_id = oinfo->lli_objid;
88         if ( oa->o_valid & OBD_MD_FLATIME )
89                 oa->o_atime = inode->i_atime;
90         if ( oa->o_valid & OBD_MD_FLMTIME )
91                 oa->o_mtime = inode->i_mtime;
92         if ( oa->o_valid & OBD_MD_FLCTIME )
93                 oa->o_ctime = inode->i_ctime;
94         if ( oa->o_valid & OBD_MD_FLSIZE )
95                 oa->o_size = inode->i_size;
96         if ( oa->o_valid & OBD_MD_FLBLOCKS )   /* allocation of space */
97                 oa->o_blocks = inode->i_blocks;
98         if ( oa->o_valid & OBD_MD_FLBLKSZ )
99                 oa->o_blksize = inode->i_blksize;
100         if ( oa->o_valid & OBD_MD_FLMODE )
101                 oa->o_mode = inode->i_mode;
102         if ( oa->o_valid & OBD_MD_FLUID )
103                 oa->o_uid = inode->i_uid;
104         if ( oa->o_valid & OBD_MD_FLGID )
105                 oa->o_gid = inode->i_gid;
106         if ( oa->o_valid & OBD_MD_FLFLAGS )
107                 oa->o_flags = inode->i_flags;
108         if ( oa->o_valid & OBD_MD_FLNLINK )
109                 oa->o_nlink = inode->i_nlink;
110         if ( oa->o_valid & OBD_MD_FLGENER ) 
111                 oa->o_generation = inode->i_generation;
112
113         CDEBUG(D_INFO, "src inode %ld, dst obdo %ld valid 0x%08x\n",
114                inode->i_ino, (long)oa->o_id, oa->o_valid);
115         obdo_from_inode(oa, inode);
116         
117         /* this will transfer metadata for the logical object to 
118            the oa: that metadata could contain the constituent objects
119         */
120         if (ll_has_inline(inode)) {
121                 CDEBUG(D_INODE, "copying inline data from inode to obdo\n");
122                 memcpy(oa->o_inline, oinfo->lli_inline, OBD_INLINESZ);
123                 oa->o_obdflags |= OBD_FL_INLINEDATA;
124                 oa->o_valid |= OBD_MD_FLINLINE;
125         }
126 } /* ll_oa_from_inode */
127
128
129
130 /*
131  * Remove page from dirty list
132  */
133 void __set_page_clean(struct page *page)
134 {
135         struct address_space *mapping = page->mapping;
136         struct inode *inode;
137         
138         if (!mapping)
139                 return;
140
141         list_del(&page->list);
142         list_add(&page->list, &mapping->clean_pages);
143
144         inode = mapping->host;
145         if (list_empty(&mapping->dirty_pages)) { 
146                 CDEBUG(D_INODE, "inode clean\n");
147                 inode->i_state &= ~I_DIRTY_PAGES;
148         }
149         EXIT;
150 }
151
152 /* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */
153 static int ll_brw(int rw, struct inode *inode, struct page *page, int create)
154 {
155         obd_count        num_obdo = 1;
156         obd_count        bufs_per_obdo = 1;
157         struct obdo     *oa;
158         obd_size         count = PAGE_SIZE;
159         obd_off          offset = ((obd_off)page->index) << PAGE_SHIFT;
160         obd_flag         flags = create ? OBD_BRW_CREATE : 0;
161         int              err;
162
163         ENTRY;
164
165         oa = obdo_alloc();
166         if ( !oa ) {
167                 EXIT;
168                 return -ENOMEM;
169         }
170         oa->o_valid = OBD_MD_FLNOTOBD;
171         ll_oa_from_inode(oa, inode);
172
173         err = obd_brw(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
174                                &page, &count, &offset, &flags);
175         //if ( !err )
176         //      ll_to_inode(inode, oa); /* copy o_blocks to i_blocks */
177
178         obdo_free(oa);
179         EXIT;
180         return err;
181 } /* ll_brw */
182
183 extern void set_page_clean(struct page *);
184
185 /* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */
186 static int ll_commit_page(struct page *page, int create, int from, int to)
187 {
188         struct inode *inode = page->mapping->host;
189         obd_count        num_obdo = 1;
190         obd_count        bufs_per_obdo = 1;
191         struct obdo     *oa;
192         obd_size         count = to;
193         obd_off          offset = (((obd_off)page->index) << PAGE_SHIFT) + to;
194         obd_flag         flags = create ? OBD_BRW_CREATE : 0;
195         int              err;
196         struct iattr     iattr;
197
198         ENTRY;
199         oa = obdo_alloc();
200         if ( !oa ) {
201                 EXIT;
202                 return -ENOMEM;
203         }
204         oa->o_valid = OBD_MD_FLNOTOBD;
205         ll_oa_from_inode(oa, inode);
206
207         CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n", 
208                from, to, count);
209
210         err = obd_brw(OBD_BRW_WRITE, IID(inode), num_obdo, &oa, &bufs_per_obdo,
211                       &page, &count, &offset, &flags);
212         if ( !err ) {
213                 SetPageUptodate(page);
214                 set_page_clean(page);
215         }
216
217         if (offset > inode->i_size) {
218                 iattr.ia_valid = ATTR_SIZE;
219                 iattr.ia_size = offset;
220                 err = ll_inode_setattr(inode, &iattr);
221                 if (err) {
222                         printk("mds_inode_setattr failed; do something dramatic.\n");
223                         obdo_free(oa);
224                         EXIT;
225                         return -EIO;
226                 }
227         }
228
229         //if ( !err )
230         //      ll_to_inode(inode, oa); /* copy o_blocks to i_blocks */
231
232         obdo_free(oa);
233         EXIT;
234         return err;
235 } /* ll_brw */
236
237
238 /* returns the page unlocked, but with a reference */
239 int ll_readpage(struct file *file, struct page *page)
240 {
241         struct inode *inode = page->mapping->host;
242         int rc;
243
244         ENTRY;
245
246         if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) 
247              <= page->index) {
248                 memset(kmap(page), 0, PAGE_CACHE_SIZE);
249                 kunmap(page);
250                 goto readpage_out;
251         }
252
253         if (Page_Uptodate(page)) {
254                 EXIT;
255                 goto readpage_out;
256         }
257
258         rc = ll_brw(READ, inode, page, 0);
259         if ( rc ) {
260                 EXIT; 
261                 return rc;
262         } 
263         /* PDEBUG(page, "READ"); */
264
265  readpage_out:
266         SetPageUptodate(page);
267         obd_unlock_page(page);
268         EXIT;
269         return 0;
270 } /* ll_readpage */
271
272
273 int ll_dir_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
274 {
275         return 0;
276 }
277 /* returns the page unlocked, but with a reference */
278 int ll_dir_readpage(struct file *file, struct page *page)
279 {
280         struct inode *inode = page->mapping->host;
281         struct ll_sb_info *sbi =
282                 (struct ll_sb_info *)(&inode->i_sb->u.generic_sbp);
283         char *buf;
284         __u64 offset;
285         int rc = 0;
286         struct ptlrep_hdr *hdr;
287
288         ENTRY;
289
290         if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) 
291              <= page->index) {
292                 memset(kmap(page), 0, PAGE_CACHE_SIZE);
293                 kunmap(page);
294                 goto readpage_out;
295         }
296
297         if (Page_Uptodate(page)) {
298                 EXIT;
299                 goto readpage_out;
300         }
301
302         offset = page->index << PAGE_SHIFT; 
303         buf = kmap(page);
304         rc = mdc_readpage(sbi->ll_peer_ptr, inode->i_ino, S_IFDIR, offset, buf,
305                           NULL, &hdr);
306         kunmap(page); 
307         if ( rc ) {
308                 EXIT; 
309                 goto readpage_out;
310         } 
311
312         if ((rc = hdr->status)) {
313                 EXIT;
314                 goto readpage_out;
315         }
316
317         /* PDEBUG(page, "READ"); */
318
319         SetPageUptodate(page);
320  readpage_out:
321         obd_unlock_page(page);
322         EXIT;
323         return rc;
324 } /* ll_dir_readpage */
325
326 int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
327 {
328         struct inode *inode = page->mapping->host;
329         obd_off offset = ((obd_off)page->index) << PAGE_SHIFT;
330         int rc = 0;
331         ENTRY; 
332         
333         kmap(page);
334         if (Page_Uptodate(page)) { 
335                 EXIT;
336                 goto prepare_done;
337         }
338
339         if ( (from <= offset) && (to >= offset + PAGE_SIZE) ) {
340                 EXIT;
341                 return 0;
342         }
343         
344         rc = ll_brw(READ, inode, page, 0);
345         if ( !rc ) {
346                 SetPageUptodate(page);
347         } 
348
349  prepare_done:
350         set_page_dirty(page);
351         //SetPageDirty(page);
352         EXIT;
353         return rc;
354 }
355
356
357 /* select between SYNC and ASYNC I/O methods */
358 int ll_do_writepage(struct page *page, int sync)
359 {
360         struct inode *inode = page->mapping->host;
361         int err;
362
363         ENTRY;
364         /* PDEBUG(page, "WRITEPAGE"); */
365         /* XXX everything is synchronous now */
366         err = ll_brw(OBD_BRW_WRITE, inode, page, 1);
367
368         if ( !err ) {
369                 SetPageUptodate(page);
370                 set_page_clean(page);
371         }
372         /* PDEBUG(page,"WRITEPAGE"); */
373         EXIT;
374         return err;
375 } /* ll_do_writepage */
376
377
378
379 /* returns the page unlocked, but with a reference */
380 int ll_writepage(struct page *page)
381 {
382         int rc;
383         struct inode *inode = page->mapping->host;
384         ENTRY;
385         printk("---> writepage called ino %ld!\n", inode->i_ino);
386         rc = ll_do_writepage(page, 1);
387         if ( !rc ) {
388                 set_page_clean(page);
389         } else {
390                 CDEBUG(D_INODE, "--> GRR %d\n", rc);
391         }
392         EXIT;
393         return rc;
394 }
395
396 void write_inode_pages(struct inode *inode)
397 {
398         struct list_head *tmp = &inode->i_mapping->dirty_pages;
399         
400         while ( (tmp = tmp->next) != &inode->i_mapping->dirty_pages) { 
401                 struct page *page;
402                 page = list_entry(tmp, struct page, list);
403                 ll_writepage(page);
404         }
405 }
406
407
408 int ll_commit_write(struct file *file, struct page *page, unsigned from, unsigned to)
409 {
410         struct inode *inode = page->mapping->host;
411         int rc = 0;
412         loff_t len = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
413         ENTRY;
414         CDEBUG(D_INODE, "commit write ino %ld (end at %Ld) from %d to %d ,ind %ld\n",
415                inode->i_ino, len, from, to, page->index);
416
417         rc = ll_commit_page(page, 1, from, to);
418
419         if (len > inode->i_size) {
420                 ll_set_size(inode, len);
421         }
422
423         kunmap(page);
424         EXIT;
425         return rc;
426 }
427
428
429 /*
430  * This does the "real" work of the write. The generic routine has
431  * allocated the page, locked it, done all the page alignment stuff
432  * calculations etc. Now we should just copy the data from user
433  * space and write it back to the real medium..
434  *
435  * If the writer ends up delaying the write, the writer needs to
436  * increment the page use counts until he is done with the page.
437  *
438  * Return value is the number of bytes written.
439  */
440 int ll_write_one_page(struct file *file, struct page *page,
441                          unsigned long offset, unsigned long bytes,
442                          const char * buf)
443 {
444         struct inode *inode = file->f_dentry->d_inode;
445         int err;
446
447         ENTRY;
448         /* We check for complete page writes here, as we then don't have to
449          * get the page before writing over everything anyways.
450          */
451         if ( !Page_Uptodate(page) && (offset != 0 || bytes != PAGE_SIZE) ) {
452                 err = ll_brw(READ, inode, page, 0);
453                 if ( err )
454                         return err;
455                 SetPageUptodate(page);
456         }
457
458         if (copy_from_user((u8*)page_address(page) + offset, buf, bytes))
459                 return -EFAULT;
460
461         lock_kernel();
462         err = ll_writepage(page);
463         unlock_kernel();
464
465         return (err < 0 ? err : bytes);
466 } /* ll_write_one_page */
467
468 /* 
469  * return an up to date page:
470  *  - if locked is true then is returned locked
471  *  - if create is true the corresponding disk blocks are created 
472  *  - page is held, i.e. caller must release the page
473  *
474  * modeled on NFS code.
475  */
476 struct page *ll_getpage(struct inode *inode, unsigned long offset,
477                            int create, int locked)
478 {
479         struct page * page;
480         int index;
481         int err;
482
483         ENTRY;
484
485         offset = offset & PAGE_CACHE_MASK;
486         CDEBUG(D_INFO, "ino: %ld, offset %ld, create %d, locked %d\n",
487                inode->i_ino, offset, create, locked);
488         index = offset >> PAGE_CACHE_SHIFT;
489
490         page = grab_cache_page(&inode->i_data, index);
491
492         /* Yuck, no page */
493         if (! page) {
494             printk(KERN_WARNING " grab_cache_page says no dice ...\n");
495             EXIT;
496             return NULL;
497         }
498
499         /* PDEBUG(page, "GETPAGE: got page - before reading\n"); */
500         /* now check if the data in the page is up to date */
501         if ( Page_Uptodate(page)) { 
502                 if (!locked) {
503                         if (PageLocked(page))
504                                 obd_unlock_page(page);
505                 } else {
506                         printk("file %s, line %d: expecting locked page\n",
507                                __FILE__, __LINE__); 
508                 }
509                 EXIT;
510                 return page;
511         } 
512
513         err = ll_brw(READ, inode, page, create);
514
515         if ( err ) {
516                 SetPageError(page);
517                 obd_unlock_page(page);
518                 EXIT;
519                 return page;
520         }
521
522         if ( !locked )
523                 obd_unlock_page(page);
524         SetPageUptodate(page);
525         /* PDEBUG(page,"GETPAGE - after reading"); */
526         EXIT;
527         return page;
528 } /* ll_getpage */
529
530
531 void ll_truncate(struct inode *inode)
532 {
533         struct obdo *oa;
534         int err;
535         ENTRY;
536
537         //ll_dequeue_pages(inode);
538
539         oa = obdo_alloc();
540         if ( !oa ) {
541                 /* XXX This would give an inconsistent FS, so deal with it as
542                  * best we can for now - an obdo on the stack is not pretty.
543                  */
544                 struct obdo obdo;
545
546                 printk(__FUNCTION__ ": obdo_alloc failed - using stack!\n");
547
548                 obdo.o_valid = OBD_MD_FLNOTOBD;
549                 ll_oa_from_inode(&obdo, inode);
550
551                 err = obd_punch(IID(inode), &obdo, 0, obdo.o_size);
552         } else {
553                 oa->o_valid = OBD_MD_FLNOTOBD;
554                 ll_oa_from_inode(oa, inode);
555
556                 CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
557                        (long)oa->o_id, oa->o_size);
558                 err = obd_punch(IID(inode), oa, oa->o_size, 0);
559
560                 obdo_free(oa);
561         }
562
563         if (err) {
564                 printk(__FUNCTION__ ": obd_truncate fails (%d)\n", err);
565                 EXIT;
566                 return;
567         }
568         EXIT;
569 } /* ll_truncate */
570
571 struct address_space_operations ll_aops = {
572         readpage: ll_readpage,
573         writepage: ll_writepage,
574         sync_page: block_sync_page,
575         prepare_write: ll_prepare_write, 
576         commit_write: ll_commit_write,
577         bmap: NULL
578 };
579
580
581 struct address_space_operations ll_dir_aops = {
582         readpage: ll_dir_readpage,
583         prepare_write: ll_dir_prepare_write
584 };