From: Marko O. <d0...@us...> - 2010-01-11 15:48:10
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "kdfs". The branch, make_kdfs_compile has been updated via 159422433e1cbebdd6b3df6edc5e63a77eb17941 (commit) via a5960d10bd3d0e0b3f67f01a9d2bff5c4d9a76db (commit) via 6d804a59635d22cd8ccecc171681223bae641978 (commit) via 727feafdfdb67c56faf8936a555306ac12ba83bd (commit) via d922ea7c84da39b7ec2ae3d5b05f4e422f6c7495 (commit) via 42cfa16f195acdd55c4c99ab0ac577eabbf80823 (commit) via 9fee3b665950ede2d8d578add26530e5bb5a8249 (commit) via 5144e43b2e59b913bfe8012cf26dc612a6829091 (commit) via 59d4826cea6aa3f17f387cea83a045f4aaea1fd5 (commit) via 2e86087f0a4bd2f6e419803905f8cedb6311e81a (commit) via c61ed4f2effa24ddc2729d4a9a7b9b812ca73f8a (commit) via a87005035a822077ade4b96f7ae9afe09b6f2001 (commit) via 0ed4e289e003fb2353b318d21cf17060074e6f69 (commit) via 942cf87a46b58f3e096826d13ee7ad0ec64db17d (commit) via 9dedc3c491c2774afbed77d87864433a016080bb (commit) via 250cc5ac019298154f5712d8c227d7fc3aac99ba (commit) via 87111978622231b06aa57a74ad350c7cac7d9ac3 (commit) via e90089683d8d32255ee55e2d836225d72efe85f5 (commit) via baece1e8a982a096ab76e50547a104c4cfa98a72 (commit) via efa1df423b0d7917b4623e307b7d458dd1cd6a16 (commit) via 37068a1d0d9ae607cd5d197005a921c7ca8074d8 (commit) via eefb55fb51de2797a7901cd9827dedf8b9015d92 (commit) via 9e58211763497549cd2491d01bf3ae226bd48b19 (commit) via 5f7461ada88e462353da2d6d9a0b004b9fc4c1d1 (commit) via 37cccc92fa18c524639fecdacb7ebcd3ef4e65f4 (commit) via ba24f66901b5eb467f4fbfe1792f5a1665170bd4 (commit) via f329899adb892b045d703c40674913934b3b5f27 (commit) via 1bc38883c96886d363d1eedc872cd13f16cbaace (commit) via 6cbbb0ba9659c196903c16639aebd701adfbd9bf (commit) via b4b470948c5660cdf97fdc30085aa513c52ab621 (commit) via 39e80a793bb13a4da7d1c866e8c519a3dad3d167 (commit) via 9504d5ab452f80a69678619200b30fcb9c227ae3 (commit) via ceb929fe04b3a196bfb95616d4ad284baca59dde (commit) via cf03337d62107dc50ba0fee8cd3d1cb319b98a78 (commit) via 3dbf029c045785470ed2fc985ba563851725c6ec (commit) via bb7c19326702855ed79b16a6b3a13b3b2f2e2408 (commit) via 98ac1bcff92f547076665f707c31110cad6dadd3 (commit) via 7ca01d4cf4bc2c02bc6b6c762d9af56beb4c057d (commit) via 67bd421cadb556dcb80d09887ce9b6bd96f53997 (commit) via f2a919ceb695197498716cd7b9d29a1830dd8376 (commit) via 0a2de04bffac70353111356adb711a884bc5ecc4 (commit) via 82b023c1c4b768fdb0ce4e4641f8ee6034f53186 (commit) via 915b839a817d3749249ae9b49cf942a0e9cc6ac5 (commit) via 40e4e2dd556986c690b4425f12f4109655d9a501 (commit) via f131c539d3b9d262c1efd289aaab858545f53d32 (commit) via 5639be07865fd6c237874eef1550a1022f7fcf98 (commit) via aab7523efaf345acca2bb9ac68038d7e6eee4afe (commit) via bd0df69f9d0cd0b5708b0f133388bec4352d7e78 (commit) via ed553ed1642fca061c8faf52fbb7fbd0304587e1 (commit) via dfba7dd31a1d2936f3d31f9f6aa5a65a71e33cff (commit) via 6c9518db317a864602b29f422abbe796882de67b (commit) via 45e4c4413b119a3562580e5ac07acc7737315861 (commit) via 8f9cd865a569ec46d4c7b17bd9b59990e226337e (commit) via 9738e237e48df9380bb17ef5c6e040a6b6411bf2 (commit) via 4779fdd41e7bfde2bcf83a773df9b2435a95f43e (commit) via abf7345618946001d1387a72eb7b4a36ecd8e4e9 (commit) via 1e332338e807c6029efaa36f0c3f278e21b0d703 (commit) via 06ac5a2e0b4af128fe0f4813db265137e54f8d7a (commit) via 2f1ae9d763e324e7930b42fc323d36f6bc7489b3 (commit) via 370d01df6b87de28a27f0606fecad7a78bb17bbe (commit) via b626262af785cd78a5588cc9b63dc5cb00f2d28d (commit) via b108c31ff3d1c6864f68ef5279bd1a7ef2330ca8 (commit) via 0db65b9d5048affd827554ef0e7db2832af09090 (commit) via 63df3666207494718affeec7771bb627757f5cd1 (commit) via 9ac3afb145d2945df1003c9a7635bd87c20d20ed (commit) via 2acaee07836e7af9206a1776642f3b2160954b7a (commit) via 2f3101b827869104b0ab205138339c024e692ce6 (commit) via d5f4de9f6bccdbb23e2bcf2194d3bc32f9ac2a5e (commit) via 0dbbea8e5bb3bc8dd01d57ed015b3aa7fa6c9c3e (commit) via b73cea92154b23e44a9abea5f3ef5402abb931ee (commit) via 3aaf3034811c9912d2a494f26690c1240e6cdb4d (commit) via 42dc5601a2abbce78a6ad86649618a5fbbe34311 (commit) via eb638b4067d284578e3a3a03d3e0c9f2651a7d50 (commit) via 023396fb1effbba56068516a5a7d588e75e8e0d3 (commit) via 2ccfae7f9c42402047c7f424aeb93e22e8f31a62 (commit) via 6dd4ba6adaf244569f2c5c2b09343e8117f0cd76 (commit) via a5c9c1d1d706f6b36bdc0c4e5feae3cc8a7061bb (commit) via a27ff405db154e79db8e11297d5b066ec157f645 (commit) via e29bbca4dc3a29d04db063845df2342a1688ba28 (commit) via 7a8f3ef7b1f9842f6938a8ae235008a2859774a9 (commit) via 198c361c608a5c91ed99608fc3d770d4db0fe23d (commit) via 702b2a4e05236707bf00ced40d6223d4352f9bcb (commit) via c1aab557a7d2c321966e304a71f186fd7a755a8c (commit) via 9e44327b50b9419eba2bf05ff493fee084264440 (commit) via d63336d6d4ca02651034fa8a21cd9079762b0ded (commit) via d4a28a30cb46d5bd751bd9158a169dda9be03e92 (commit) via 044c8680cf7fa945b45d8191b63b1e17b53ff031 (commit) via 9e96b948a2a9a920be352ef6aba8390be302d14a (commit) via 16c9cb24b6089e99aa9ddbb70976fbdcc0742f74 (commit) via a179d799af7fdeda72121f7a1e65c22e9644859b (commit) via 5b6df576f5ae9f139e966cf61dd6a7467549b858 (commit) via 09e966b166aa6dfc76e9126ed7325177c9a32a6c (commit) via 70dcedd0b1b0deeeb9f17b74f6c82b943f13c33a (commit) via 6b7bbe01c3350e5dcabcee6f74e687e27cbe1c46 (commit) via f56392cfe4a8ccee7a151b40e149d6d67ba1110e (commit) via 2ba013bea1e10cb256a7cfe5a9cc2df8b90dcb17 (commit) via b4693639bc21d24b7351f426efcbb632d2e0d30d (commit) via b5239bf421973f62e18ce86ccf3ce70bc42f4274 (commit) via 045d080860edbab50ddc7847f696c55752fa866a (commit) via 15734ef1e1a7095ca10d64c40706f424661a7de0 (commit) via c15bf128d1ec4003c4ed610c5d687e5082bfcd01 (commit) via 5ea24637c229a94d5205ce6a9311f6d0b200999e (commit) via a5ff64bb765a024f14a075aa2b09ef9112f6b708 (commit) via 82e12755db2fe9b3b224df7b73e1aa2c6148af33 (commit) via 3ebcb76a2bdc73805959272a7f656890b7787b25 (commit) via b5be9b5aa21163b6f6c152ded431016f484eef69 (commit) via 7508c996d225b04183ca244fba3bdc8f43e7e19d (commit) via 09d750e1a6594fd8b15e37fe21273974631e6a63 (commit) via 3d259dbaa28735714e937479a81024a6b243ca44 (commit) via e54d0456066c3858c7e0186e696700cf64caebc0 (commit) via cec7be6ff86873ed6f7f06f7ad3cb8e13e0df4c7 (commit) via 19b005b5f89656739ae21d504389d0a11a9e6c76 (commit) via 33765dc75ea949f110da9354f7c64ab559a40840 (commit) via f6ede09de097d4e5653a90d231d3f2388a8f636f (commit) via 4e498cbe1327cba9f2dc15f4ee8daed98742ccea (commit) via 486f9e4cc88df7fb427a9605846e61238f6f037e (commit) via cd976597cd2e5778505b6f839eb274510e0c0f3e (commit) via 2aa2210b086ab0cf87d078f5a61b47d22ea8a18e (commit) via b3a5776b63ec50a7596c50b56580c74394388452 (commit) via fc6ea12288e121066006c9640cf4e474e8e99116 (commit) via 0b9683e293c0c28fb43e671344ef38b755c68a92 (commit) via d2ff0447ff7fe1262385de58fe62f8cba0253b25 (commit) via f5de4c7d2880b0e90baf9c70f3f65c05e4e4b59d (commit) via 5b645a5e874b24dc8d409d818290badf998e6c8c (commit) via a84a0ea3ab7264866ee62c6eadac0939044f7c43 (commit) from e9b2900ac5dcea18ed708cf4688628437606aacd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 159422433e1cbebdd6b3df6edc5e63a77eb17941 Merge: a5960d1 e9b2900 Author: Marko Obrovac <mar...@in...> Date: Mon Jan 11 15:44:43 2010 +0000 Resolve some merge conflicts with remote/make_kdfs_compile diff --cc fs/kdfs/debug_kdfs.h index f50a0b2,55b1623..bfc8446 --- a/fs/kdfs/debug_kdfs.h +++ b/fs/kdfs/debug_kdfs.h @@@ -41,9 -41,9 +41,10 @@@ # define DEBUG(level, format, args...) \ do { \ if (KDFS_DEBUG_LEVEL >= level || level == DBG_PANIC) { \ - printk("%s - (%s) - %d : ", KDFS_PART, __PRETTY_FUNCTION__, \ + /*pr_debug*/printk("%s - (%s) - %d : ", KDFS_PART, __PRETTY_FUNCTION__, \ current->pid) ; \ - printk(format, ## args) ; \ + /*pr_debug*/printk(format, ## args) ; \ ++>>>>>>> e9b2900ac5dcea18ed708cf4688628437606aacd } \ if(level == DBG_PANIC)\ BUG();\ commit a5960d10bd3d0e0b3f67f01a9d2bff5c4d9a76db Merge: ae83ede 6d804a5 Author: Marko Obrovac <mar...@in...> Date: Mon Jan 11 15:05:48 2010 +0000 Merge branch 'master' of git://mirrors.git.kernel.org/cluster/kerrighed/kernel into make_kdfs_compile Conflicts: include/kddm/io_linker.h include/kddm/kddm_set.h All conficts have been resolved. diff --cc fs/kdfs/address_space.c index 5b60704,0000000..27874db mode 100644,000000..100644 --- a/fs/kdfs/address_space.c +++ b/fs/kdfs/address_space.c @@@ -1,926 -1,0 +1,928 @@@ +/* + * KDDM File System - address space management + * + * @file address_space.h + * + * @author Adrien Lebre (2007-xxxx) + * @comment Based on the Renaud Lottiaux's kerfs proposal (2002-2005) + * + * @maintainer Adrien Lebre + * + * Copyright (C) 2006-2007, XtreemOS Consortium. + */ + +#include <linux/pagemap.h> + ++#include <net/krgrpc/rpcid.h> ++#include <net/krgrpc/rpc.h> +#include <kddm/kddm.h> + +#include "super.h" +#include "inode.h" +#include "address_space.h" +#include "physical_fs.h" + +#include "debug_kdfs.h" +#define KDFS_PART "KDFS - Address Space Management" + +int kdfs_content_readphyspage(struct content_iolinker_data *content_data, + char *page_addr, loff_t pos); +int kdfs_content_writephyspage(struct content_iolinker_data *content_data, + char *page_addr, loff_t from, loff_t to); +int kdfs_content_readphyspage_cow(struct content_iolinker_data *content_data, + char *page_addr, loff_t pos); +int kdfs_content_writephyspage_cow(struct content_iolinker_data *content_data, + char *page_addr, loff_t from, loff_t to); + +/*****************************************************************************/ +/* */ +/* INTERNAL ADDRESS SPACE OPERATIONS */ +/* */ +/*****************************************************************************/ + +int kdfs_content_writephyspage(struct content_iolinker_data *content_data, + char *page_addr, loff_t from, loff_t to) +{ + unsigned int objid = from / PAGE_CACHE_SIZE; + char *pos_addr = NULL; + loff_t file_pos; + size_t len; + + file_pos = from; + pos_addr = page_addr + (from - ((loff_t)objid * PAGE_CACHE_SIZE)); + len = to - from; + + kdfs_phys_write(content_data->phys_file, pos_addr, len, &file_pos); + + PRINT_FUNCTION_EXIT; + return 0; +} + + +/*****************************************************************************/ +/* */ +/* ADDRESS SPACE OPERATIONS */ +/* */ +/*****************************************************************************/ + + +/* + * Called by low VFS layer + * The page is locked. + */ +int kdfs_readpage(struct file *file, struct page *page) +{ + struct kdfs_page *k_page = NULL; + struct kdfs_inode *k_inode = NULL; + + + ASSERT(page != NULL); + k_inode=kdfs_ilocalfind(page->mapping->host->i_ino); + if (k_inode->content_setid == KDDM_SET_UNUSED) + DEBUG (DBG_PANIC, "No contentset associated.... looks really strange (inode %lu, name %s)\n", + k_inode->inode->i_ino, list_entry(k_inode->inode->i_dentry.next, struct dentry, d_alias)->d_name.name); + + /* TODO PRIORITY 2: test kdfs_get_page returned value */ + k_page = kdfs_get_page(k_inode->content_setid, page->index); + + DEBUG(DBG_INFO, " Readpage k_page->page : %p and page %p\n", k_page->page, page); + BUG_ON(k_page->page != page); + + SetPageUptodate(k_page->page); + unlock_page(k_page->page); + + _kdfs_put_page(k_page); + kdfs_iput(k_inode->inode->i_ino); + + PRINT_FUNCTION_EXIT; + return 0; +} + +/* TODO Suggested by Adrien for xxxx + * Priority : 3 + * Merge new kdfs_write_begin function with the older kdfs_prepare_write. + */ +/* + * page has been found or allocated from/in the page cache and locked + * However, the data should be pre-read from the storage + * Thus, one first-touch can happen. ISSUE, put data in the same page + */ +int __kdfs_prepare_write (struct file *file, struct page *page, + unsigned offset, unsigned _to) +{ + struct kdfs_page *k_page = NULL; + struct kdfs_inode *k_inode = NULL; + + DEBUG (DBG_INFO, "begin_write for file %s (ino %ld), page %ld from %d to %d (count = %d, mapping = %p)\n", + file->f_dentry->d_name.name, file->f_dentry->d_inode->i_ino, page->index, offset, _to, page_count(page), page->mapping); + + BUG_ON (page->mapping == NULL); + BUG_ON (!PageLocked(page)); + + k_inode=kdfs_ilocalfind(file->f_dentry->d_inode->i_ino); + if(k_inode->content_setid == KDDM_SET_UNUSED){ + DEBUG (DBG_PANIC, "No contentset associated.... looks really strange \n"); + } + + /* TODO PRIORITY 2: test kdfs_get_page returned value */ + k_page = kdfs_grab_page(k_inode->content_setid, page->index); + BUG_ON(k_page->page != page) ; + k_page->offset = offset; + k_page->to = _to; + + SetPageUptodate (k_page->page); + + kdfs_iput(k_inode->inode->i_ino); + PRINT_FUNCTION_EXIT; + return 0; +} + +int kdfs_write_begin (struct file *file, + struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + struct page *page; + pgoff_t index; + unsigned from; + + index = pos >> PAGE_CACHE_SHIFT; + from = pos & (PAGE_CACHE_SIZE - 1); + + page = grab_cache_page_write_begin(mapping, index, flags); + if (!page) + return -ENOMEM; + + *pagep = page; + return __kdfs_prepare_write(file, page, from, from+len); +} + + +/* TODO Suggested by Adrien for xxxx + * Priority : 3 + * Merge new kdfs_write_begin function with the older kdfs_prepare_write. + */ +/* TODO Suggested by Adrien for Adrien, + * an old TODO, ... probably just remove it ;) + * cf. http://www.mail-archive.com/git...@vg.../msg03083.html + */ +int __kdfs_commit_write(struct file *file, + struct page *page, + unsigned offset, + unsigned _to) +{ + struct kdfs_inode *k_inode = NULL; + + DEBUG(DBG_INFO, "commit_write for page %ld for file %s" + "(ino %lu) (from %u to %u) (count = %d)\n", + page->index, file->f_dentry->d_name.name, + file->f_dentry->d_inode->i_ino, offset, _to, + page_count(page)); + + k_inode = kdfs_ilocalfind(file->f_dentry->d_inode->i_ino); + if (k_inode->content_setid == KDDM_SET_UNUSED) + DEBUG(DBG_PANIC, "No contentset associated.... looks really strange \n"); + + if (((loff_t)page->index * PAGE_SIZE) + _to > k_inode->inode->i_size) + i_size_write(k_inode->inode, ((loff_t)page->index * PAGE_SIZE) + _to); + + /* + * From the local node point of view, we have to set DIRTY flag to the page: + * set_page_dirty(page); + * However, due to the write behind issue at such a distributed level, we have + * chosen to directly call the kDDM sync functions (write through) + */ + kdfs_mark_page_dirty(k_inode->content_setid, page->index); + __kdfs_put_page(k_inode->content_setid, page->index); + + kdfs_mark_inode_dirty(k_inode); + kdfs_iput(k_inode->inode->i_ino); + + PRINT_FUNCTION_EXIT; + return 0; +} + +int kdfs_write_end(struct file *file, + struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ + unsigned from = pos & (PAGE_CACHE_SIZE - 1); + + /* zero the stale part of the page if we did a short copy */ + if (copied < len) { + void *kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + from + copied, 0, len - copied); + flush_dcache_page(page); + kunmap_atomic(kaddr, KM_USER0); + } + + __kdfs_commit_write(file, page, from, from+copied); + + unlock_page(page); + page_cache_release(page); + + return copied; +} + + +int kdfs_writepage(struct page *page, struct writeback_control *wbc) +{ + + PRINT_FUNCTION_NAME; + /* TODO */ + BUG(); + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * Called by the VFS during a truncate operation. That is, when + * parts of the page are now deprecated. + */ +void kdfs_invalidatepage(struct page *page, unsigned long offset) +{ + struct kdfs_page *k_page; + + PRINT_FUNCTION_NAME; + ASSERT(page->mapping != NULL); + + k_page = (struct kdfs_page *) page->private; + if (offset == 0) { + /* The whole page is invalidated so it should be removed */ + kddm_remove_object(kddm_def_ns, k_page->set_id, k_page->obj_id); + ClearPagePrivate(page); + } + else { + /* Not sure about this */ + kdfs_grab_page(k_page->set_id, k_page->obj_id); + kddm_sync_frozen_object(kddm_def_ns, k_page->set_id, k_page->obj_id); + __kdfs_put_page(k_page->set_id, k_page->obj_id); + } + PRINT_FUNCTION_EXIT; +} + +/* + * Called when a page is released from the local page cache + * WARNING: Must return 1 for success, 0 otherwise! + */ +int kdfs_releasepage(struct page *page, gfp_t mask) +{ + struct kdfs_page *k_page; + kddm_obj_t *obj_entry; + kddm_set_t *associated_set; + + ASSERT (page->mapping != NULL); + PRINT_FUNCTION_NAME; + + k_page = (struct kdfs_page *) page->private; + associated_set = _find_get_kddm_set(kddm_def_ns, k_page->set_id); + obj_entry = __get_kddm_obj_entry(associated_set, k_page->obj_id); + if (OBJ_EXCLUSIVE2(COPYSET(obj_entry))) { + put_kddm_obj_entry(associated_set, obj_entry, k_page->obj_id); + put_kddm_set(associated_set); + kdfs_grab_page(k_page->set_id, k_page->obj_id); + kddm_remove_frozen_object(kddm_def_ns, k_page->set_id, k_page->obj_id); + } + else { + put_kddm_obj_entry(associated_set, obj_entry, k_page->obj_id); + put_kddm_set(associated_set); + kddm_flush_object(kddm_def_ns, k_page->set_id, k_page->obj_id, KERRIGHED_NODE_ID_NONE); + } + + ClearPagePrivate(page); + PRINT_FUNCTION_EXIT; + return 1; +} + +struct address_space_operations kdfs_aops = { + .write_begin = kdfs_write_begin, + .write_end = kdfs_write_end, + .invalidatepage = kdfs_invalidatepage, + .readpage = kdfs_readpage, + .releasepage = kdfs_releasepage, + .writepage = kdfs_writepage, +}; + + +/*****************************************************************************/ +/* */ +/* ADDRESS SPACE LINKER PART */ +/* */ +/*****************************************************************************/ + +struct kdfs_page *kdfs_get_page(kddm_set_id_t set_id, objid_t obj_id) +{ + DEBUG(DBG_INFO, "Get page %ld from set %ld\n", obj_id, set_id); + return kddm_get_object(kddm_def_ns, set_id, obj_id); +} + +struct kdfs_page *kdfs_grab_page(kddm_set_id_t set_id, objid_t obj_id) +{ + DEBUG(DBG_INFO, "Grab page %ld from set %ld\n", obj_id, set_id); + return kddm_grab_object(kddm_def_ns, set_id, obj_id); +} + +struct kdfs_page *kdfs_findlocal_page(kddm_set_id_t set_id, objid_t obj_id) +{ + DEBUG(DBG_INFO, "Grab page %ld from set %ld\n", obj_id, set_id); + return kddm_find_object(kddm_def_ns, set_id, obj_id); +} + +void __kdfs_put_page(kddm_set_id_t set_id, objid_t obj_id) +{ + kddm_put_object(kddm_def_ns, set_id, obj_id); +} + +void _kdfs_put_page(struct kdfs_page *k_page) +{ + DEBUG(DBG_INFO, "Put page %ld from set %ld\n", k_page->obj_id, k_page->set_id); + kddm_put_object(kddm_def_ns, k_page->set_id, k_page->obj_id); +} + +void kdfs_mark_page_dirty(kddm_set_id_t set_id, objid_t obj_id) +{ + DEBUG(DBG_INFO, "Sync page %ld from set %lu\n", obj_id, set_id); + kddm_sync_frozen_object(kddm_def_ns, set_id, obj_id); +} + +/* + * Create content kddm_set (internal function) + * @author Adrien Lebre + * + * @param set_id Id associated to the new set + * @param def_owner Kerrighed node id where meta-file is stored + * @param inode Inode associated with this new 'content' set + * @param type FILE_LINKER or DIR_LINKER + * @return a new container built from the inode + * + * Note: Actually, the new container is directly linked to a specific + * node However, we will maybe change to KDDM_SET_CUSTOM_LINKED flag + * since we will have to support replicas mechanisms even for + * meta-data informations. + */ + +kddm_set_t *__create_content_kddm_set(kddm_set_id_t set_id, + kerrighed_node_t def_owner, + struct kdfs_inode *k_inode, + iolinker_id_t type) +{ + struct content_iolinker_data *content_data; + kddm_set_t *kddm_set = NULL; + + PRINT_FUNCTION_NAME; + + /* Allocate space for the file_data structure */ + content_data = kmalloc(sizeof(struct content_iolinker_data), GFP_KERNEL); + ASSERT(content_data != NULL); + + /* Enpack the content IO linker data */ + content_data->ino = k_inode->inode->i_ino; /* Valid clusterwide */ + + kddm_set = _create_new_kddm_set(kddm_def_ns, set_id, type, + def_owner, sizeof(struct kdfs_page), + content_data, sizeof(struct content_iolinker_data), KDDM_FT_LINKED); + + if (IS_ERR(kddm_set)) + DEBUG(DBG_PANIC, "Can't create content kddm_set for inode %ld\n", k_inode->inode->i_ino); + + /* We can free all the memory allocated */ + kfree(content_data); + + PRINT_FUNCTION_EXIT; + return kddm_set; +} + +int __kddm_set_local_destroy(int nsid, int setid) +{ + struct kddm_ns *ns; + struct kddm_set *kddm_set; + + /* Remove the kddm set from the name space */ + ns = kddm_ns_get (nsid); + if (ns == NULL) + return -EINVAL; + + kddm_set = hashtable_remove(ns->kddm_set_table, setid); + kddm_ns_put (ns); + + if (kddm_set == NULL) + return -EINVAL; + + put_kddm_set(kddm_set); + return 0; +} + +/* + * Destroy the local instance of a content kddm_set (internal function) + * @author Adrien Lebre + * + * @param k_inode Inode associated with this 'content' set + * @return O if everything was ok + */ +int __local_destroy_content_kddm_set(struct kdfs_inode *k_inode) +{ + kddm_set_t *kddm_set = NULL; + + PRINT_FUNCTION_NAME; + + kddm_set = _local_get_kddm_set(kddm_def_ns, k_inode->content_setid); + if (!kddm_set) + DEBUG(DBG_INFO, "The associated kddm_set for inode %ld hasn't been instantiated\n", k_inode->inode->i_ino); + else{ + /* + * TODO PRIORITY 1, Adrien / (Renaud kDDM stuff) + * According to the function __handle_req_kddm_set_destroy + * http://lxr.kerlabs.com/kerrighed/source/modules/ctnr/kddm_set.c#650 + * I have to first remove the set from the local namespace and then + * free the kddm_set struct. + * Currently, I implemented the following function + * which is approximately a copy/paste of the __handle_req_kddm_set_destroy + * function. + */ + __kddm_set_local_destroy(KDDM_DEF_NS_ID, k_inode->content_setid); + + /* + * Free the kddm set structure (second call, count will reach 0 + * and the set structure will be freed) + */ + put_kddm_set(kddm_set); + } + PRINT_FUNCTION_EXIT; + return 0; +} + +/*****************************************************************************/ +/* */ +/* ADDRESS IO LINKER PART */ +/* (exploited for dir and file io-linkers) */ +/* */ +/*****************************************************************************/ + +/* + * Allocate a kdfs_page object + * @author Adrien Lebre + * + * @param objEntry Kddm page descriptor. + * @param set Kddm descriptor + * @param objid Id of the page to create. + * + * @return the new allocated kdfs_page. NULL otherwise. + */ +int kdfs_iol_page_alloc(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) +{ + struct kdfs_page *k_page = NULL; + struct address_space *k_mapping = NULL; + PRINT_FUNCTION_NAME; + + ASSERT(set->private_data != NULL); + k_mapping = ((struct content_iolinker_data *) set->private_data)->k_mapping; + ASSERT(k_mapping != NULL); + + k_page = kmalloc(sizeof(struct kdfs_page), GFP_KERNEL); + ASSERT(k_page); + + DEBUG(DBG_INFO, "Before Alloc new page %ld from set %lu \n", objid, set->id); + k_page->page = find_get_page(k_mapping, objid); + if (!k_page->page) { + DEBUG(DBG_ALERT, + "Can't find page for file/directory = %ld and page id = %ld, So created and locked\n", + k_mapping->host->i_ino, objid); + k_page->page = find_or_create_page(k_mapping, objid, mapping_gfp_mask(k_mapping) & ~__GFP_FS); + k_page->flags = K_PG_locked; + } else + k_page->flags = K_PG_ok; + + DEBUG(DBG_INFO, "After Alloc new page %ld from set %lu (page addr=%p count=%d)\n", objid, set->id, k_page->page, page_count(k_page->page)); + + k_page->set_id = set->id; + k_page->obj_id = objid; + + /* By default, the whole page is useful */ + k_page->offset = 0; + k_page->to = PAGE_SIZE; + + objEntry->object = k_page; + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * Handle a kdfs page first touch + * @author Adrien Lebre + * + * @param objEntry Kddm page descriptor. + * @param set Kddm descriptor + * @param objid Id of the page to create. + * @param flags Creation flag (useless in that case) + * + * @return 0 if everything is ok. Negative value otherwise. + */ +int kdfs_iol_page_first_touch(kddm_obj_t *objEntry, + kddm_set_t *set, + objid_t objid, int flags) +{ + + struct address_space *k_mapping; + struct content_iolinker_data *iolinker_data; + struct kdfs_page *k_page = NULL; + char *page_addr = NULL; + loff_t pos; + int res = 0; + + iolinker_data = (struct content_iolinker_data *) set->private_data; + + DEBUG(DBG_TRACE, "file/directory = %ld, pageid = %ld gonna to retrieve inode \n", iolinker_data->ino, objid); + + /* WARNING: quite ugly, we should not access to a local inode without locking the corresponding kddm object*/ + k_mapping = ((struct content_iolinker_data *) set->private_data)->k_mapping; + ASSERT(k_mapping); + + DEBUG(DBG_TRACE, "file/directory = %ld, pageid = %ld mapping = %p\n", iolinker_data->ino, objid, k_mapping); + + /* Allocate kdfs_page and retrieve page address */ + k_page = kmalloc(sizeof(struct kdfs_page), GFP_KERNEL); + + ASSERT(k_page != NULL); + k_page->set_id = set->id; + k_page->obj_id = objid; + + /* By default, the whole page is useful */ + k_page->offset = 0; + k_page->to = PAGE_SIZE; + k_page->page = NULL; + + ASSERT(k_mapping != NULL); + + k_page->page = find_get_page(k_mapping, objid); + if (!k_page->page) { + DEBUG(DBG_ALERT, "Can't find page for file/directory = %ld and page id = %ld, So created and locked\n", iolinker_data->ino, objid); + k_page->page = find_or_create_page(k_mapping, objid, (mapping_gfp_mask(k_mapping)|__GFP_ZERO) & ~__GFP_FS); + k_page->flags = K_PG_locked; + } else + k_page->flags = K_PG_ok; + + DEBUG(DBG_ALERT, "After find Page count=%d\n", page_count(k_page->page)); + + page_addr = (char *) kmap(k_page->page); + pos = (loff_t)objid * PAGE_SIZE; + + iolinker_data->content_readphyspage(iolinker_data, page_addr, pos); + + kunmap(k_page->page); + + if (!IS_ERR(k_page->page)) + DEBUG(DBG_ALERT, "Can't read page for file/directory = %ld and page id = %ld\n", iolinker_data->ino, objid); + + objEntry->object = (void *) k_page; + + /* TODO PRIORITY 2: should release in kdfs_put_page instead? */ + //page_cache_release(k_page->page); + + DEBUG(DBG_ALERT, "After read Page count=%d\n", page_count(k_page->page)); + + PRINT_FUNCTION_EXIT; + return res; +} + +/* + * Receive a fresh copy of kdfs_page. + * @author Adrien Lebre + * + * @param objEntry Descriptor of the page to insert. + * @param ctnr Container descriptor + * @param padeid Id of the page to insert. + */ +int kdfs_iol_page_insert(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) +{ + struct kdfs_page *k_page; + PRINT_FUNCTION_NAME; + + k_page = (struct kdfs_page *) objEntry->object; + DEBUG(DBG_ALERT, "Entering page count=%d\n", page_count(k_page->page)); + + /* + * Set the private field of the page to get callback when it is + * released from local cache. + */ + SetPagePrivate(k_page->page); + set_page_private(k_page->page, (unsigned long) k_page); + + /* + * if the page has been created by kDFS, we should unlock the page + * cf. find_or_create() in alloc and first touch + */ + if(k_page->flags == K_PG_locked) { + unlock_page(k_page->page); + k_page->flags=K_PG_ok; + } + page_cache_release(k_page->page); + + DEBUG(DBG_ALERT, "Exiting page count=%d\n", page_count(k_page->page)); + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * Export an object + * @author Adrien Lebre + * + * @param desc Network descriptor exploited by rpc_pack() + * @param objEntry The object to export data from. + * @param objid Object id of the object + */ +int kdfs_iol_page_export (struct rpc_desc *desc, + kddm_obj_t *objEntry) +{ + struct kdfs_page *k_page = (struct kdfs_page *)objEntry->object; + int res = 0; + char *page_addr = NULL; + PRINT_FUNCTION_NAME; + + page_addr = (char *) kmap_atomic(k_page->page, KM_USER0); + + res = rpc_pack(desc, 0, page_addr, PAGE_SIZE); + if (res < 0) + DEBUG(DBG_ALERT, "can't pack export page (res=%d)\n", res); + + kunmap_atomic(page_addr, KM_USER0); + + /* + * If the page has been created by kDFS, we should unlock the page + * cf. find_or_create() in first touch (in that case : first_touch + * and export functions are the only ones called, insert is bypassed + */ + if (k_page->flags == K_PG_locked) { + unlock_page(k_page->page); + k_page->flags = K_PG_ok; + } + + // TODO ADRIEN NOW: cache_page_release + + PRINT_FUNCTION_EXIT; + return res; +} + +int kdfs_iol_page_invalidate(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) +{ + struct kdfs_page *k_page = (struct kdfs_page *)objEntry->object; + PRINT_FUNCTION_NAME; + + trylock_page(k_page->page); + DEBUG(DBG_ALERT, "Page count before =%d\n", page_count(k_page->page)); + remove_from_page_cache(k_page->page); + ClearPagePrivate(k_page->page); + unlock_page(k_page->page); + page_cache_release(k_page->page); + DEBUG(DBG_ALERT, "Page after count=%d\n", page_count(k_page->page)); + /* + * TODO PRIORITY 2: Adrien + * Page Count should be probably decremented + */ + + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * Import an object + * @author Adrien Lebre + * + * @param object The object to import data in. + * @param desc Network descriptor exploited by rpc_pack() + */ +int kdfs_iol_page_import(kddm_obj_t *objEntry, struct rpc_desc *desc) +{ + int res = 0; + struct kdfs_page *kdfs_page = (struct kdfs_page*) objEntry->object; + char *page_addr = NULL ; + + PRINT_FUNCTION_NAME; + page_addr = (char *) kmap(kdfs_page->page); + + res = rpc_unpack(desc, 0, page_addr, PAGE_SIZE); + + kunmap(kdfs_page->page); + + PRINT_FUNCTION_EXIT; + return res; +} + +/* + * Sync a page on the right node + * @author Adrien Lebre + * + * @param objEntry Descriptor of the page to sync. + * @param set kddm descriptor + * @param objid page id. + * WARNING: Corresponding kdfs_inode should be grabbed ! + */ +int kdfs_iol_page_sync(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) +{ + struct kdfs_page *k_page = NULL; + char *page_addr = NULL; + char *pos_addr = NULL; + loff_t file_pos; + size_t len; + struct content_iolinker_data *iolinker_data = (struct content_iolinker_data*) set->private_data; + + ASSERT(objEntry != NULL); + k_page = objEntry->object; + ASSERT(k_page != NULL); + ASSERT(k_page->page != NULL); + + DEBUG(DBG_INFO, "Try to sync page %ld (page addr %p) of set %lu\n", objid, k_page->page, set->id); + + file_pos = ((loff_t)objid * PAGE_SIZE) + k_page->offset; + page_addr = (char *) kmap(k_page->page); + + pos_addr = page_addr + k_page->offset; + len = k_page->to - k_page->offset; + + iolinker_data->content_writephyspage(iolinker_data, page_addr, file_pos, file_pos + len); + + kunmap(k_page->page); + + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * Callback for kddm_put_object to unlock a page when we are the locker + * @author Pierre Riteau + * + * @param objEntry page to unlock + * @param set set containing the page + * @param objid object identifier of the page + */ +int kdfs_iol_page_put(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) +{ + struct kdfs_page* k_page; + + PRINT_FUNCTION_NAME; + ASSERT(objEntry != NULL); + k_page = (struct kdfs_page *)objEntry->object; + + DEBUG(DBG_ALERT, "Page count = %d\n", page_count(k_page->page)); + + //page_cache_release(k_page->page); + + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * I/O linker function called when a page is removed + * @author Pierre Riteau + * + * @param objEntry page to remove + * @param set set containing the page + * @param objid object identifier of the page + */ +int kdfs_iol_page_remove(void *object, struct kddm_set *set, objid_t objid) +{ + struct kdfs_page *k_page = (struct kdfs_page *) object; + PRINT_FUNCTION_NAME; + + if ((!PageLocked(k_page->page))) { + /* + * This is not the kernel trying to remove the page but the KDDMs, + * so we need to remove the page from the cache by hand, because + * we are not called by the VFS + */ + trylock_page(k_page->page); + DEBUG(DBG_ALERT, "Page count before =%d\n", page_count(k_page->page)); + remove_from_page_cache(k_page->page); + ClearPagePrivate(k_page->page); + unlock_page(k_page->page); + page_cache_release(k_page->page); + DEBUG(DBG_ALERT, "Page after count=%d\n", page_count(k_page->page)); + } + + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * Instantiate a container with a content linker. + * @author Adrien Lebre + * + * @param kddm_set kddm to instantiate + * @param private_data content_iolinker_data to access to physical file. + * + * @return error code or 0 if everything was ok. + */ +int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) +{ + struct content_iolinker_data *content_data = NULL; + struct inode *inode = NULL; + int result = 0; + char *phys_dirname; + struct file *filp; + + /* TODO NOW: Adrien */ + /* Ugly, we decided to forbid calling kddm grab/get functions + * at such level in order to avoid deadlock + */ + struct kdfs_super_block *k_sb = kdfs_getsb(kerrighed_node_id); + PRINT_FUNCTION_NAME; + ASSERT(k_sb != NULL); + + ASSERT(kddm_set != NULL); + ASSERT(kddm_set->private_data != NULL); + + content_data = (struct content_iolinker_data *) kddm_set->private_data; + DEBUG(DBG_INFO, "Instantiate kddm %ld with ino : %ld\n", kddm_set->id, content_data->ino); + + if (kddm_set->def_owner == kerrighed_node_id) { + content_data->phys_dirname = kmalloc(PATH_MAX, GFP_KERNEL); + ASSERT(content_data->phys_dirname != NULL); + + /* Retrieve local path corresponding to kfds inode number*/ + kdfs_getphysicalpath(k_sb, content_data->ino, content_data->phys_dirname); + + /* Try to open the physical associated file */ + phys_dirname = content_data->phys_dirname + strlen(content_data->phys_dirname); + snprintf(content_data->phys_dirname, PATH_MAX, "%s/.meta.index", content_data->phys_dirname); + filp = open_phys_file(content_data->phys_dirname, O_RDONLY, 0644, 0, 0); + *phys_dirname = '\0'; + if (IS_ERR(filp)) { + /* This file is not checkpointed, use the standard content file. */ + snprintf(content_data->phys_dirname, PATH_MAX, "%s/" KDFS_CONTENT_FILENAME, content_data->phys_dirname); + filp = open_phys_file(content_data->phys_dirname, O_CREAT|O_LARGEFILE|O_RDWR, 0644, 0,0); + BUG_ON(IS_ERR(filp)); + content_data->phys_file = filp; + *phys_dirname = '\0'; + + content_data->content_readphyspage = kdfs_content_readphyspage; + content_data->content_writephyspage = kdfs_content_writephyspage; + content_data->current_meta = NULL; + } + else { + /* This file is checkpointed, initialization will be done on the first read/write. */ + content_data->phys_file = NULL; + + content_data->content_readphyspage = kdfs_content_readphyspage_cow; + content_data->content_writephyspage = kdfs_content_writephyspage_cow; + content_data->current_meta = NULL; + } + } else { + DEBUG (DBG_INFO, "Nothing TODO, file is not on this node\n"); + content_data->phys_dirname = NULL; + content_data->phys_file = NULL; + } + + /* TODO PRIORITY 2, Adrien, we could have some issue if the kernel tries to remove the inode during this code */ + /* Retrieve the local ref to the k_mapping object */ + inode = ilookup(k_sb->sb, content_data->ino); + if (inode) { + DEBUG(DBG_INFO, "K_mapping from the cache\n"); + content_data->k_mapping = inode->i_mapping; + iput(inode); + } else { + DEBUG(DBG_INFO, "K_mapping will be retrieve from iget\n"); + inode = kdfs_getinode(k_sb->sb, content_data->ino); + content_data->k_mapping = inode->i_mapping; + } + if (!content_data->k_mapping) + DEBUG(DBG_PANIC, "k_mapping was not cleanly initialized\n"); + + __kdfs_putsb(k_sb); + PRINT_FUNCTION_EXIT; + return result; +} + +/* + * Uninstantiate a content container. + * @author Adrien Lebre + * + * @param kddm_set kddm_set to uninstantiate + */ +void content_uninstantiate(kddm_set_t *kddm_set, int destroy) +{ + struct content_iolinker_data *content_data; + PRINT_FUNCTION_NAME; + + ASSERT(kddm_set != NULL); + ASSERT(kddm_set->private_data != NULL); + content_data = (struct content_iolinker_data *) kddm_set->private_data; + + if (content_data->phys_dirname != NULL) + kfree(content_data->phys_dirname); + + if (content_data->phys_file != NULL) + close_phys_file(content_data->phys_file); + + PRINT_FUNCTION_EXIT; +} + +int kdfs_content_readphyspage(struct content_iolinker_data *content_data, + char *page_addr, loff_t pos) +{ + int res = 0; + + kdfs_phys_read(content_data->phys_file, page_addr, PAGE_CACHE_SIZE, &pos); + + PRINT_FUNCTION_EXIT; + return res; +} diff --cc fs/kdfs/debug_kdfs.h index a5a377c,0000000..f50a0b2 mode 100644,000000..100644 --- a/fs/kdfs/debug_kdfs.h +++ b/fs/kdfs/debug_kdfs.h @@@ -1,86 -1,0 +1,86 @@@ +/* + * KDDM File System file - debug macros + * + * @file debug_kdfs.h + * + * @author Adrien Lebre + * + * @maintainer Adrien Lebre + * + * Copyright (C) 2006-2007, XtreemOS Consortium. + */ + +#ifndef __KDFS_DEBUG__ +#define __KDFS_DEBUG__ + +/* Common headers */ +#include <asm-generic/bug.h> +#include <linux/err.h> +#include <linux/kernel.h> + +/* Kerrighed headers (dynamical debugging) */ +#include <kerrighed/debug.h> +//#include <kerrighed/debug_tools2.h> + +/* DEBUG Level */ +#define DBG_PANIC 0 +#define DBG_ALERT 1 +#define DBG_WARNING 2 +#define DBG_TRACE 3 +#define DBG_INFO 4 + +#define KDFS_DEBUG_LEVEL 4 + +#ifdef DEBUG +#undef DEBUG +#endif + +#ifdef NDEBUG +# define DEBUG(level, format, args...) do {} while(0) +#else +# define DEBUG(level, format, args...) \ +do { \ + if (KDFS_DEBUG_LEVEL >= level || level == DBG_PANIC) { \ - pr_debug("%s - (%s) - %d : ", KDFS_PART, __PRETTY_FUNCTION__, \ ++ printk("%s - (%s) - %d : ", KDFS_PART, __PRETTY_FUNCTION__, \ + current->pid) ; \ - pr_debug(format, ## args) ; \ ++ printk(format, ## args) ; \ + } \ + if(level == DBG_PANIC)\ + BUG();\ +} while (0) +#endif + +/* Adrien last check before matthieu */ +/* if ((KDFS_DEBUG_LEVEL>=level) && \ (type & (KDFS_DEBUG_MASK))) \ */ + + +/* FUNCTION NAME : ENTER and EXIT */ +// TODO: redefine the following macros to take into account debug level ! +#define PRINT_FUNCTION_NAME DEBUG(DBG_TRACE, "%s\n", __PRETTY_FUNCTION__) +#define PRINT_FUNCTION_EXIT DEBUG(DBG_TRACE, "%s exited\n", __PRETTY_FUNCTION__) + + +/* ASSERT and BUG ON */ + +#ifdef ASSERT +#undef ASSERT +#endif + +#ifdef NDEBUG +#define ASSERT(expr) do {} while(0) +#else +#define ASSERT(expr) \ +do {\ + if ( !(expr) ) {\ - pr_debug("PANIC : ASSERT " #expr " failed in %s \ ++ printk("PANIC : ASSERT " #expr " failed in %s \ + line %d\n", __PRETTY_FUNCTION__, __LINE__ ); \ + BUG(); \ + } \ +} while (0) +#endif + +/* Add __KDFS_PROCDIR_ feature - Pierre Riteau */ +#define __KDFS_PROCDIR_ 1 + + +#endif // __KDFS_DEBUG__ diff --cc fs/kdfs/file.c index a1707bc,0000000..d93dc51 mode 100644,000000..100644 --- a/fs/kdfs/file.c +++ b/fs/kdfs/file.c @@@ -1,304 -1,0 +1,306 @@@ +/* + * KDDM File System file - file content manamgement + * + * @file file.c + * + * @author Adrien Lebre (2007-xxx) + * @comment Based on the Renaud Lottiaux's kerfs proposal (2003-2005) + * + * @maintainer Adrien Lebre + * + * Copyright (C) 2006-2007, XtreemOS Consortium. + */ + +#include <linux/buffer_head.h> + ++#include <net/krgrpc/rpcid.h> ++#include <net/krgrpc/rpc.h> +#include <kddm/kddm.h> + +#include "super.h" +#include "inode.h" +#include "address_space.h" +#include "file.h" + +#include "debug_kdfs.h" +#define KDFS_PART "KDFS - File Content Management" + +/*****************************************************************************/ +/* */ +/* INTERNAL FILE OPERATIONS */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* */ +/* FILE OPERATIONS */ +/* */ +/*****************************************************************************/ + +loff_t kdfs_llseek(struct file *filp, loff_t offset, int origin) +{ + loff_t r; + + DEBUG(DBG_INFO, + "lseek on file %s at offset %lld current offset is %lld\n", + filp->f_dentry->d_name.name, offset, filp->f_pos); + + r = generic_file_llseek(filp, offset, origin); + + DEBUG(DBG_INFO, + "lseek on file %s offset is now %lld: done with err %lld\n", + filp->f_dentry->d_name.name, + filp->f_pos, r); + + return r; +} + +ssize_t kdfs_read(struct file *filp, char *buf, size_t count, loff_t *ppos) +{ + ssize_t r = 0; + struct kdfs_inode *kdfs_inode = NULL; + + DEBUG(DBG_INFO, + "read %zd bytes from file %s at offset %lld in buffer %p\n", + count, filp->f_dentry->d_name.name, *ppos, buf); + + kdfs_inode = kdfs_iget(filp->f_dentry->d_inode->i_ino); + if (kdfs_inode->content_setid == KDDM_SET_UNUSED) { + /* Create the associated kddm_set */ + create_file_kddm_set(kdfs_inode); + } + + r = do_sync_read(filp, buf, count, ppos); + + // TODO PRIORITY 2: FILE TIMESTAMP ? + + kdfs_iput(filp->f_dentry->d_inode->i_ino); + + DEBUG(DBG_INFO, "read of file %s at offset %lld: done\n", + filp->f_dentry->d_name.name, *ppos); + + return r; +} + +ssize_t kdfs_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) +{ + ssize_t r = 0; + struct kdfs_inode *kdfs_inode = NULL; + + DEBUG(DBG_INFO, + "write %zd bytes to file %s at offset %lld\n", + count, filp->f_dentry->d_name.name, *ppos); + + kdfs_inode = kdfs_igrab(filp->f_dentry->d_inode->i_ino); + if (kdfs_inode->content_setid == KDDM_SET_UNUSED) { + /* Create the associated kddm_set */ + create_file_kddm_set(kdfs_inode); + } + + /* Call generic_file_aio_write */ + r = do_sync_write(filp, buf, count, ppos); + + kdfs_iput(filp->f_dentry->d_inode->i_ino); + + DEBUG(DBG_INFO, + "write to file %s at offset %lld: " + "done with return value %zd\n", + filp->f_dentry->d_name.name, *ppos, r); + + return r; +} + +int kdfs_mmap(struct file *filp, struct vm_area_struct *vm) +{ + int ret = 0; + struct kdfs_inode *k_inode = NULL; + + DEBUG(DBG_INFO, "mmap file %s \n", filp->f_dentry->d_name.name); + + k_inode = kdfs_igrab(filp->f_dentry->d_inode->i_ino); + if (k_inode->content_setid == KDDM_SET_UNUSED) { + /* Create the associated kddm_set */ + create_file_kddm_set(k_inode); + } + + /* Call generic_file_map */ + ret = generic_file_mmap (filp, vm); + + kdfs_iput(filp->f_dentry->d_inode->i_ino); + + PRINT_FUNCTION_EXIT; + return ret; +} + +int kdfs_open(struct inode *inode, struct file *filp) +{ + struct kdfs_super_block *k_sb; + struct kdfs_cw_sb *k_cwsb; + struct kdfs_inode *k_inode; + int r = 0; + + DEBUG(DBG_INFO, "open file %s - inode %ld\n", + filp->f_dentry->d_name.name, inode->i_ino); + + k_cwsb = __kdfs_get_cwsb(); + if (!test_bit(inode_linked_node(inode->i_ino), (unsigned long *) k_cwsb->cw_bitmap->map)) { + r = -ENODEV; + __kdfs_put_cwsb(); + goto out; + } + __kdfs_put_cwsb(); + + if ((k_sb = kdfs_getsb(inode_linked_node(inode->i_ino))) == NULL) { + DEBUG(DBG_ALERT, "No kdfs super-block available\n"); + return -EFAULT; + } + + k_inode = kdfs_igrab(inode->i_ino); + r = generic_file_open (inode, filp); + atomic_inc(&k_inode->cw_count); + kdfs_iput(inode->i_ino); + __kdfs_putsb(k_sb); + +out: + DEBUG(DBG_INFO, "open file %s: inode %ld: done with error %d\n", + filp->f_dentry->d_name.name, inode->i_ino, r); + + return r; +} + +int kdfs_release(struct inode *inode, struct file *filp) +{ + struct kdfs_inode *k_inode; + + DEBUG(DBG_INFO, + "Release file %s (i_size %lld) (inode %p)\n", + filp->f_dentry->d_name.name, + filp->f_dentry->d_inode->i_size, + filp->f_dentry->d_inode); + + k_inode = kdfs_igrab(inode->i_ino); + atomic_dec(&k_inode->cw_count); + kdfs_iput(inode->i_ino); + + return 0; +} + +struct file_operations kdfs_file_fops = { + .aio_read = generic_file_aio_read, + .aio_write = generic_file_aio_write, + .fsync = file_fsync, + .llseek = kdfs_llseek, + .mmap = kdfs_mmap, + .open = kdfs_open, + .read = kdfs_read, + .release = kdfs_release, + .write = kdfs_write, +}; + +/*****************************************************************************/ +/* */ +/* FILE LINKER PART */ +/* */ +/*****************************************************************************/ + +/* + * Create file_kddm_set from file inode + * @author Adrien Lebre + * + * @param dir Reference to the associated kdfs_inode + * @return a new container built from the file + */ +kddm_set_t *create_file_kddm_set(struct kdfs_inode *k_inode) +{ + kddm_set_t *kddm_set = NULL; + + PRINT_FUNCTION_NAME; + + ASSERT(k_inode != NULL); + ASSERT(k_inode->inode != NULL); + +#if KDFS_FILE_STRIPING + kddm_set = __create_content_kddm_set(0, KDDM_SET_CUSTOM_LINKED, k_inode, FILE_LINKER); +#else + kddm_set = __create_content_kddm_set(0, inode_linked_node(k_inode->inode->i_ino), k_inode, FILE_LINKER); +#endif + if (!IS_ERR(kddm_set)) { + k_inode->content_setid=kddm_set->id; + DEBUG(DBG_INFO, "Create content kddm_set for file %s (inode %ld) with id %ld\n", + list_entry(k_inode->inode->i_dentry.next, struct dentry, d_alias)->d_name.name, + k_inode->inode->i_ino, k_inode->content_setid); + } else { + DEBUG(DBG_PANIC, "Can't create content kddm_set for file%s (inode %ld)\n", + list_entry(k_inode->inode->i_dentry.next, struct dentry, d_alias)->d_name.name, + k_inode->inode->i_ino); + } + + return kddm_set; +} + +/*****************************************************************************/ +/* */ +/* FILE IO LINKER PART */ +/* */ +/*****************************************************************************/ + +/* + * Determine the owner for a particular page. + * If the page has not been yet allocated, the page will be stored locally. + * @author Adrien Lebre + * + * @param kddm_set Container descriptor + * @param objid inode Id. + */ +kerrighed_node_t kdfs_iol_file_default_owner (kddm_set_t *kddm_set, objid_t objid) +{ + /* + * TODO NOW, Adrien + * Implement + */ + return KERRIGHED_NODE_ID_NONE; +} + +/* + * Instantiate a container with a file linker. + * @author Adrien Lebre + * + * @param kddm_set kddm to instantiate + * @param private_data file_iolinker_data to access to physical file. + * + * @return error code or 0 if everything was ok. + */ +int kdfs_iol_file_instantiate (kddm_set_t *kddm_set, void *private_data, int master) +{ + return content_instantiate(kddm_set, private_data, master); +} + +/** Uninstantiate a file container. + * @author Adrien Lebre + * + * @param kddm_set kddm_set to uninstantiate + */ +void kdfs_iol_file_uninstantiate (kddm_set_t *kddm_set, int destroy) +{ + content_uninstantiate(kddm_set, destroy); +} + +/* Init the file I/O linker */ +struct iolinker_struct file_io_linker = { + .alloc_object = kdfs_iol_page_alloc, +#if KDFS_FILE_STRIPING + .default_owner = kdfs_iol_file_default_owner, +#endif + .export_object = kdfs_iol_page_export, + .first_touch = kdfs_iol_page_first_touch, + .import_object = kdfs_iol_page_import, + .insert_object = kdfs_iol_page_insert, + .instantiate = kdfs_iol_file_instantiate, + .invalidate_object = kdfs_iol_page_invalidate, + .linker_name = "file", + .linker_id = FILE_LINKER, + .put_object = kdfs_iol_page_put, + .remove_object = kdfs_iol_page_remove, + .sync_object = kdfs_iol_page_sync, + .uninstantiate = kdfs_iol_file_uninstantiate, +}; diff --cc fs/kdfs/inode.c index f126cb8,0000000..4cce701 mode 100644,000000..100644 --- a/fs/kdfs/inode.c +++ b/fs/kdfs/inode.c @@@ -1,1407 -1,0 +1,1409 @@@ +/* + * KDDM File System file - inode management + * + * @file inode.c + * + * @author Adrien Lebre (2007-xxx) + * @comment Based on the Renaud Lottiaux's kerfs proposal (2003-2005) + * + * @maintainer Adrien Lebre + * + * Copyright (C) 2006-2007, XtreemOS Consortium. + */ + ++#include <net/krgrpc/rpcid.h> ++#include <net/krgrpc/rpc.h> +#include <kddm/kddm.h> + +#include "super.h" +#include "inode.h" +#include "dir.h" +#include "file.h" +#include "address_space.h" +#include "physical_fs.h" + +#include "debug_kdfs.h" +#define KDFS_PART "KDFS - Inode Management" + +/******************************** + * * + * SOME DEBUG FUNCTIONS * + * * + ********************************/ + +void print_inode_cont(struct inode *node) +{ + printk("\n\n\n=== INODE DUMP ===\n"); + printk(" i_ino: %ld\n", node->i_ino); + printk(" i_count: %d\n", node->i_count.counter); + printk(" i_nlink: %u\n", node->i_nlink); + printk(" i_uid: %u\n", node->i_uid); + printk(" i_gid: %u\n", node->i_gid); + printk("i_version: %llu\n", (unsigned long long)node->i_version); + printk(" i_mode: %x\n\n\n", node->i_mode); +} + +void print_dentry_cont(struct dentry *entry, int print_inode_info) +{ + printk("\n\n\n=== DENTRY DUMP ===\n"); + printk("d_count: %d\n", entry->d_count.counter); + printk("d_flags: %x\n", entry->d_flags); + printk(" d_name: %s\n", entry->d_name.name); + printk("d_iname: %s\n", entry->d_iname); + + if (print_inode_info != 0) { + if (IS_ERR(entry->d_inode)) + printk("DENTRY INODE NULL!!!\n"); + else + print_inode_cont(entry->d_inode); + } + + printk("\n\n"); +} + +/*****************************************************************************/ +/* */ +/* INODE INTERNAL FUNCTIONS */ +/* */ +/*****************************************************************************/ + +static inline void kdfs_export_kdfs_inode(struct kdfs_netinode *dest, struct kdfs_inode *src) +{ + /* export inode informations */ + dest->i_ino = src->inode->i_ino; + dest->i_size = src->inode->i_size; + dest->i_mode = src->inode->i_mode; + dest->i_nlink = src->inode->i_nlink; + dest->i_uid = src->inode->i_uid; + dest->i_gid = src->inode->i_gid; + dest->i_atime = src->inode->i_atime; + dest->i_mtime = src->inode->i_mtime; + dest->i_ctime = src->inode->i_ctime; + dest->i_version = src->inode->i_version; + dest->i_state = src->inode->i_state; + + atomic_set(&dest->cw_count, atomic_read(&src->cw_count)); + + /* export miscellaneous */ + dest->content_setid = src->content_setid; + dest->flags = src->flags; +} + +static inline void kdfs_import_kdfs_inode (struct kdfs_inode *dest, struct kdfs_netinode *src) +{ + /* import inode informations */ + dest->inode->i_ino=src->i_ino; + dest->inode->i_size = src->i_size; + dest->inode->i_mode = src->i_mode; + dest->inode->i_nlink = src->i_nlink; + dest->inode->i_uid = src->i_uid; + dest->inode->i_gid = src->i_gid; + dest->inode->i_atime = src->i_atime; + dest->inode->i_mtime = src->i_mtime; + dest->inode->i_ctime = src->i_ctime; + dest->inode->i_version = src->i_version; + dest->inode->i_state = src->i_state; + + atomic_set(&dest->cw_count, atomic_read(&src->cw_count)); + + /*export miscellaneous */ + dest->content_setid = src->content_setid; + dest->flags = src->flags; +} + +/* + * Internal kDFS mknod function + * @author Adrien Lebre + * + * @param k_pdir Directory to create the inode in. + * @param dentry Dentry of the file to create. + * @param mode Mode of the file to create. + * @param dev Device associated to the file. + * @comments kDFS dir inode has to be locked (grabded) + * If creation succeeded, new nod is returned locked + */ +struct kdfs_inode *__kdfs_mknod(struct kdfs_inode *k_pdir, + struct dentry *dentry, + int mode, + dev_t dev) +{ + ino_t ino = KDFS_BAD_INODEID; + struct kdfs_inode *k_nnod; + struct kdfs_super_block *k_sb; + + DEBUG(DBG_TRACE, + "Internal mknod %s (parent dir %ld ino)\n", + dentry->d_name.name, k_pdir->inode->i_ino); + + k_sb = kdfs_grabsb(kerrighed_node_id); + if (k_sb->s_mount_opt & KDFS_MOUNT_DISKLESS) { + kdfs_node_t linked_node; + linked_node = k_sb->root_nodeid; + __kdfs_putsb(k_sb); + k_sb = kdfs_grabsb(linked_node); + } + BUG_ON(k_sb == NULL); + + /* Get an inode ID */ + ino = kdfs_get_freeino(k_sb); + // TODO PRIORITY 2 Adrien put here or later + __kdfs_putsb(k_sb); + + k_nnod = kdfs_icreate(ino); /* get a kDFS inode from the kDDM set (k_inode is lock)*/ + if (IS_ERR(k_nnod)) { + DEBUG(DBG_ALERT, "Can't grab new file inode object (ino=%ld)\n", ino); + return k_nnod; + } + + k_nnod->inode->i_mode = mode; + switch (mode & S_IFMT) { + case S_IFREG: + k_nnod->inode->i_op = &kdfs_file_inode_operations; + k_nnod->inode->i_fop = &kdfs_file_fops; + k_nnod->inode->i_mapping->a_ops = &kdfs_aops ; + break; + case S_IFDIR: + k_nnod->inode->i_op = &kdfs_dir_inode_operations; + k_nnod->inode->i_fop = &kdfs_dir_fops; + k_nnod->inode->i_mapping->a_ops = &kdfs_aops ; + break; + case S_IFLNK: + k_nnod->inode->i_op = &kdfs_symlink_inode_operations; + k_nnod->inode->i_mapping->a_ops = &kdfs_aops ; + break; + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + case S_IFSOCK: + init_special_inode(k_nnod->inode, mode, dev); + break; + default: + BUG(); + break; + } + + k_nnod->inode->i_uid = current_fsuid(); + k_nnod->inode->i_gid = current_fsgid(); + + if (k_pdir->inode->i_mode & S_ISGID) { + k_nnod->inode->i_gid = k_pdir->inode->i_gid; + if (S_ISDIR(mode)) + k_nnod->inode->i_mode |= S_ISGID; + } + + k_nnod->inode->i_mtime = k_nnod->inode->i_atime = k_nnod->inode->i_ctime = CURRENT_TIME_SEC; + k_nnod->flags = K_INODE_OK; + + /* Sync kddm object to propagate change to the right partitions (clusterwide) */ + kdfs_mark_inode_dirty(k_nnod); + + // TODO PRIORITY 1: Test return value, test if kdfs_ndir->inode->i_ino == ino + kdfs_add_dir_entry(k_pdir, (char *) dentry->d_name.name, ino, mode); + + DEBUG(DBG_TRACE, "i_count before d_instantiate %d\n", atomic_read(&k_nnod->inode->i_count)); + d_instantiate(dentry, k_nnod->inode); + DEBUG(DBG_TRACE, "i_count after d_instantiate %d\n", atomic_read(&k_nnod->inode->i_count)); + DEBUG(DBG_TRACE, "New nod done (ino=%ld, size=%lld)\n", k_nnod->inode->i_ino, k_nnod->inode->i_size); + return k_nnod; +} + +/*****************************************************************************/ +/* */ +/* INODE VFS OPERATIONS */ +/* */ +/*****************************************************************************/ + +/* + * File system dependent mknod function called by the Linux + * and also by kdfs_create. + * @author Adrien Lebre + * + * @param dir Directory to create the inode in. + * @param dentry Dentry of the file to create. + * @param mode Mode of the file to create. + * @param dev Device associated to the file. + */ +int kdfs_mknod(struct inode *dir, + struct dentry *dentry, + int mode, + dev_t dev) +{ + struct kdfs_inode *k_pdir, *k_nnod; + + DEBUG(DBG_TRACE, + "New nod %s (parent dir %ld ino)\n", + dentry->d_name.name, dir->i_ino); + + /* Grab the parent directory */ + k_pdir = kdfs_igrab(dir->i_ino); + if (IS_ERR(k_pdir)) + return PTR_ERR(k_pdir); + + k_nnod = __kdfs_mknod(k_pdir, dentry, mode, dev); + if (k_nnod) { + kdfs_iput(k_nnod->inode->i_ino); + DEBUG(DBG_TRACE, + "New nod (ino=%ld, size=%lld)\n", + k_nnod->inode->i_ino,k_nnod->inode->i_size); + } else + // TODO PRIORITY 2, Adrien, if we got an error we should release the local inode if needed ! + DEBUG(DBG_TRACE,"New nod creation failed \n"); + + kdfs_iput(dir->i_ino); + PRINT_FUNCTION_EXIT; + return 0; +} + +/* + * File system dependent create function called by the Linux VFS. + * @author Adrien Lebre + * + * @param dir Directory to create the inode in. + * @param dentry Dentry of the file to create. + * @param mode Mode of the file to create. + * @param nd TODO comments + */ +int kdfs_create(struct inode *dir, struct dentry *dentry, + int mode, + struct nameidata *nd) +{ + int res = 0; + DEBUG(DBG_TRACE, + "create %s (parent dir %ld ino)\n", + dentry->d_name.name, dir->i_ino); + + res = kdfs_mknod(dir, dentry, mode|S_IFREG, 0); + + DEBUG(DBG_TRACE, + "create %s done: res = %d\n", + dentry->d_name.name, res); + return res; +} ... [truncated message content] |