int sysv_make_empty(struct inode *inode, struct inode *dir) { struct address_space *mapping = inode->i_mapping; struct page *page = grab_cache_page(mapping, 0); struct sysv_dir_entry * de; char *base; int err; if (!page) return -ENOMEM; err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE, AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); if (err) { unlock_page(page); goto fail; } kmap(page); base = (char*)page_address(page); memset(base, 0, PAGE_CACHE_SIZE); de = (struct sysv_dir_entry *) base; de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); strcpy(de->name,"."); de++; de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino); strcpy(de->name,".."); kunmap(page); err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); fail: page_cache_release(page); return err; }
int sysv_make_empty(struct inode *inode, struct inode *dir) { struct page *page = grab_cache_page(inode->i_mapping, 0); struct sysv_dir_entry * de; char *base; int err; if (!page) return -ENOMEM; err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE); if (err) { unlock_page(page); goto fail; } kmap(page); base = (char*)page_address(page); memset(base, 0, PAGE_SIZE); de = (struct sysv_dir_entry *) base; de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); strcpy(de->name,"."); de++; de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino); strcpy(de->name,".."); kunmap(page); err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); fail: put_page(page); return err; }
int sysv_make_empty(struct inode *inode, struct inode *dir) { struct address_space *mapping = inode->i_mapping; struct page *page = grab_cache_page(mapping, 0); struct sysv_dir_entry * de; char *base; int err; if (!page) return -ENOMEM; err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * SYSV_DIRSIZE); if (err) goto fail; base = (char*)page_address(page); memset(base, 0, PAGE_CACHE_SIZE); de = (struct sysv_dir_entry *) base; de->inode = cpu_to_fs16(inode->i_sb, inode->i_ino); strcpy(de->name,"."); de++; de->inode = cpu_to_fs16(inode->i_sb, dir->i_ino); strcpy(de->name,".."); err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); fail: UnlockPage(page); page_cache_release(page); return err; }
int sysv_add_link(struct dentry *dentry, struct inode *inode) { struct inode *dir = dentry->d_parent->d_inode; const char * name = dentry->d_name.name; int namelen = dentry->d_name.len; struct page *page = NULL; struct sysv_dir_entry * de; unsigned long npages = dir_pages(dir); unsigned long n; char *kaddr; loff_t pos; int err; /* We take care of directory expansion in the same loop */ for (n = 0; n <= npages; n++) { page = dir_get_page(dir, n); err = PTR_ERR(page); if (IS_ERR(page)) goto out; kaddr = (char*)page_address(page); de = (struct sysv_dir_entry *)kaddr; kaddr += PAGE_CACHE_SIZE - SYSV_DIRSIZE; while ((char *)de <= kaddr) { if (!de->inode) goto got_it; err = -EEXIST; if (namecompare(namelen, SYSV_NAMELEN, name, de->name)) goto out_page; de++; } dir_put_page(page); } BUG(); return -EINVAL; got_it: pos = page_offset(page) + (char*)de - (char*)page_address(page); lock_page(page); err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE, AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); if (err) goto out_unlock; memcpy (de->name, name, namelen); memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); out_page: dir_put_page(page); out: return err; out_unlock: unlock_page(page); goto out_page; }
int sysv_add_link(struct dentry *dentry, struct inode *inode) { struct inode *dir = dentry->d_parent->d_inode; const char * name = dentry->d_name.name; int namelen = dentry->d_name.len; struct page *page = NULL; struct sysv_dir_entry * de; unsigned long npages = dir_pages(dir); unsigned long n; char *kaddr; unsigned from, to; int err; /* We take care of directory expansion in the same loop */ for (n = 0; n <= npages; n++) { page = dir_get_page(dir, n); err = PTR_ERR(page); if (IS_ERR(page)) goto out; kaddr = (char*)page_address(page); de = (struct sysv_dir_entry *)kaddr; kaddr += PAGE_CACHE_SIZE - SYSV_DIRSIZE; while ((char *)de <= kaddr) { if (!de->inode) goto got_it; err = -EEXIST; if (namecompare(namelen, SYSV_NAMELEN, name, de->name)) goto out_page; de++; } dir_put_page(page); } BUG(); return -EINVAL; got_it: from = (char*)de - (char*)page_address(page); to = from + SYSV_DIRSIZE; lock_page(page); err = page->mapping->a_ops->prepare_write(NULL, page, from, to); if (err) goto out_unlock; memcpy (de->name, name, namelen); memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2); de->inode = cpu_to_fs16(inode->i_sb, inode->i_ino); err = dir_commit_chunk(page, from, to); dir->i_mtime = dir->i_ctime = CURRENT_TIME; mark_inode_dirty(dir); out_unlock: UnlockPage(page); out_page: dir_put_page(page); out: return err; }
/* Releases the page */ void sysv_set_link(struct sysv_dir_entry *de, struct page *page, struct inode *inode) { struct inode *dir = (struct inode*)page->mapping->host; unsigned from = (char *)de-(char*)page_address(page); unsigned to = from + SYSV_DIRSIZE; int err; lock_page(page); err = page->mapping->a_ops->prepare_write(NULL, page, from, to); BUG_ON(err); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); err = dir_commit_chunk(page, from, to); dir_put_page(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); }
/* Releases the page */ void sysv_set_link(struct sysv_dir_entry *de, struct page *page, struct inode *inode) { struct inode *dir = page->mapping->host; loff_t pos = page_offset(page) + (char *)de-(char*)page_address(page); int err; lock_page(page); err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); BUG_ON(err); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); }
int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) { struct inode *inode = page->mapping->host; char *kaddr = (char*)page_address(page); loff_t pos = page_offset(page) + (char *)de - kaddr; int err; lock_page(page); err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE); BUG_ON(err); de->inode = 0; err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(inode); return err; }
/* Releases the page */ void sysv_set_link(struct sysv_dir_entry *de, struct page *page, struct inode *inode) { struct address_space *mapping = page->mapping; struct inode *dir = mapping->host; loff_t pos = page_offset(page) + (char *)de-(char*)page_address(page); int err; lock_page(page); err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); BUG_ON(err); de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(dir); }
int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) { struct address_space *mapping = page->mapping; struct inode *inode = (struct inode*)mapping->host; char *kaddr = (char*)page_address(page); loff_t pos = page_offset(page) + (char *)de - kaddr; int err; lock_page(page); err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE, AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); BUG_ON(err); de->inode = 0; err = dir_commit_chunk(page, pos, SYSV_DIRSIZE); dir_put_page(page); inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(inode); return err; }
int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page) { struct address_space *mapping = page->mapping; struct inode *inode = (struct inode*)mapping->host; char *kaddr = (char*)page_address(page); unsigned from = (char*)de - kaddr; unsigned to = from + SYSV_DIRSIZE; int err; lock_page(page); err = mapping->a_ops->prepare_write(NULL, page, from, to); BUG_ON(err); de->inode = 0; err = dir_commit_chunk(page, from, to); dir_put_page(page); inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(inode); return err; }