From: adilger Date: Fri, 18 Oct 2002 23:20:52 +0000 (+0000) Subject: Remove ancient and entirely non-working obdfs code from the HEAD. X-Git-Tag: v1_7_100~4476 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=c4caec16afc480224b5ff96a578fb22d949c7400;p=fs%2Flustre-release.git Remove ancient and entirely non-working obdfs code from the HEAD. --- diff --git a/lustre/obdfs/Makefile.am b/lustre/obdfs/Makefile.am deleted file mode 100644 index 8470dc1..0000000 --- a/lustre/obdfs/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (C) 2001 Cluster File Systems, Inc. -# -# This code is issued under the GNU General Public License. -# See the file COPYING in this distribution - -DEFS= - -MODULE = obdfs -modulefs_DATA = obdfs.o -EXTRA_PROGRAMS = obdfs -obdfs_SOURCES = rw.c file.c dir.c sysctl.c super.c namei.c symlink.c - -include $(top_srcdir)/Rules diff --git a/lustre/obdfs/README b/lustre/obdfs/README deleted file mode 100644 index 12eb4d6..0000000 --- a/lustre/obdfs/README +++ /dev/null @@ -1,22 +0,0 @@ -OBDFS - v 0.001 - -This version can mount, list and set the attributes of the root -directory. - -1. configure the obd to use /dev/obd with a scratch file system - -2. make - -3. insmod obdfs - -4. mount -t obdfs -o device=/dev/obd0 /dev/obd0 /mnt/obd - -To verify: type mount (output: -/dev/obd on /mnt/obd type obdfs (rw)) - -5. ls -ld /mnt/obd - -6. chmod 711 /mnt/obd, ls -ld /mnt/obd - -7. chown disk /mnt/obd, ls -ld /mnt/obd - diff --git a/lustre/obdfs/dir.c b/lustre/obdfs/dir.c deleted file mode 100644 index 80ccd2e..0000000 --- a/lustre/obdfs/dir.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * linux/fs/ext2/dir.c - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/dir.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext2 directory handling functions - * - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - * - * All code that works with directory layout had been switched to pagecache - * and moved here. AV - */ - -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_OBDFS - -#include -#include - -typedef struct ext2_dir_entry_2 ext2_dirent; - -#define PageChecked(page) test_bit(PG_checked, &(page)->flags) -#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags) - -int waitfor_one_page(struct page *page) -{ - int error = 0; - struct buffer_head *bh, *head = page->buffers; - - bh = head; - do { - wait_on_buffer(bh); - if (buffer_req(bh) && !buffer_uptodate(bh)) - error = -EIO; - } while ((bh = bh->b_this_page) != head); - return error; -} - -/* - * ext2 uses block-sized chunks. Arguably, sector-sized ones would be - * more robust, but we have what we have - */ -static inline unsigned ext2_chunk_size(struct inode *inode) -{ - //return inode->i_sb->s_blocksize; - return PAGE_SIZE; -} - -static inline void ext2_put_page(struct page *page) -{ - kunmap(page); - page_cache_release(page); -} - -static inline unsigned long dir_pages(struct inode *inode) -{ - return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; -} - -static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) -{ - struct inode *dir = page->mapping->host; - int err = 0; - dir->i_version = ++event; - page->mapping->a_ops->commit_write(NULL, page, from, to); - if (IS_SYNC(dir)) - err = waitfor_one_page(page); - return err; -} - -static void ext2_check_page(struct page *page) -{ - struct inode *dir = page->mapping->host; - unsigned chunk_size = ext2_chunk_size(dir); - char *kaddr = page_address(page); - // u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count); - unsigned offs, rec_len; - unsigned limit = PAGE_CACHE_SIZE; - ext2_dirent *p; - char *error; - - if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) { - limit = dir->i_size & ~PAGE_CACHE_MASK; - if (limit & (chunk_size - 1)) - goto Ebadsize; - for (offs = limit; offsrec_len = cpu_to_le16(chunk_size); - } - if (!limit) - goto out; - } - for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) { - p = (ext2_dirent *)(kaddr + offs); - rec_len = le16_to_cpu(p->rec_len); - - if (rec_len < EXT2_DIR_REC_LEN(1)) - goto Eshort; - if (rec_len & 3) - goto Ealign; - if (rec_len < EXT2_DIR_REC_LEN(p->name_len)) - goto Enamelen; - if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1)) - goto Espan; - // if (le32_to_cpu(p->inode) > max_inumber) - //goto Einumber; - } - if (offs != limit) - goto Eend; -out: - SetPageChecked(page); - return; - - /* Too bad, we had an error */ - -Ebadsize: - CERROR("ext2_check_page" - "size of directory #%lu is not a multiple of chunk size", - dir->i_ino - ); - goto fail; -Eshort: - error = "rec_len is smaller than minimal"; - goto bad_entry; -Ealign: - error = "unaligned directory entry"; - goto bad_entry; -Enamelen: - error = "rec_len is too small for name_len"; - goto bad_entry; -Espan: - error = "directory entry across blocks"; - goto bad_entry; - //Einumber: - // error = "inode out of bounds"; -bad_entry: - CERROR("ext2_check_page" "bad entry in directory #%lu: %s - " - "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", - dir->i_ino, error, (page->index<inode), - rec_len, p->name_len); - goto fail; -Eend: - p = (ext2_dirent *)(kaddr + offs); - CERROR("ext2_check_page" - "entry in directory #%lu spans the page boundary" - "offset=%lu, inode=%lu", - dir->i_ino, (page->index<inode)); -fail: - SetPageChecked(page); - SetPageError(page); -} - -static struct page * ext2_get_page(struct inode *dir, unsigned long n) -{ - struct address_space *mapping = dir->i_mapping; - struct page *page = read_cache_page(mapping, n, - (filler_t*)mapping->a_ops->readpage, NULL); - if (!IS_ERR(page)) { - wait_on_page(page); - kmap(page); - if (!Page_Uptodate(page)) - goto fail; - if (!PageChecked(page)) - ext2_check_page(page); - if (PageError(page)) - goto fail; - } - return page; - -fail: - ext2_put_page(page); - return ERR_PTR(-EIO); -} - -/* - * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure. - * - * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller. - */ -static inline int ext2_match (int len, const char * const name, - struct ext2_dir_entry_2 * de) -{ - if (len != de->name_len) - return 0; - if (!de->inode) - return 0; - return !memcmp(name, de->name, len); -} - -/* - * p is at least 6 bytes before the end of page - */ -static inline ext2_dirent *ext2_next_entry(ext2_dirent *p) -{ - return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len)); -} - -static inline unsigned -ext2_validate_entry(char *base, unsigned offset, unsigned mask) -{ - ext2_dirent *de = (ext2_dirent*)(base + offset); - ext2_dirent *p = (ext2_dirent*)(base + (offset&mask)); - while ((char*)p < (char*)de) - p = ext2_next_entry(p); - return (char *)p - base; -} - -static unsigned char ext2_filetype_table[EXT2_FT_MAX] = { - [EXT2_FT_UNKNOWN] DT_UNKNOWN, - [EXT2_FT_REG_FILE] DT_REG, - [EXT2_FT_DIR] DT_DIR, - [EXT2_FT_CHRDEV] DT_CHR, - [EXT2_FT_BLKDEV] DT_BLK, - [EXT2_FT_FIFO] DT_FIFO, - [EXT2_FT_SOCK] DT_SOCK, - [EXT2_FT_SYMLINK] DT_LNK, -}; - -static unsigned int obdfs_dt2fmt[DT_WHT + 1] = { - [EXT2_FT_UNKNOWN] 0, - [EXT2_FT_REG_FILE] S_IFREG, - [EXT2_FT_DIR] S_IFDIR, - [EXT2_FT_CHRDEV] S_IFCHR, - [EXT2_FT_BLKDEV] S_IFBLK, - [EXT2_FT_FIFO] S_IFIFO, - [EXT2_FT_SOCK] S_IFSOCK, - [EXT2_FT_SYMLINK] S_IFLNK -}; - -#define S_SHIFT 12 -static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = { - [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE, - [S_IFDIR >> S_SHIFT] EXT2_FT_DIR, - [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV, - [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV, - [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO, - [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK, - [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK, -}; - -static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) -{ - mode_t mode = inode->i_mode; - de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; -} - -int -new_obdfs_readdir (struct file * filp, void * dirent, filldir_t filldir) -{ - loff_t pos = filp->f_pos; - struct inode *inode = filp->f_dentry->d_inode; - // XXX struct super_block *sb = inode->i_sb; - unsigned offset = pos & ~PAGE_CACHE_MASK; - unsigned long n = pos >> PAGE_CACHE_SHIFT; - unsigned long npages = dir_pages(inode); - unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); - unsigned char *types = NULL; - int need_revalidate = (filp->f_version != inode->i_version); - - if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) - goto done; - - types = ext2_filetype_table; - - for ( ; n < npages; n++, offset = 0) { - char *kaddr, *limit; - ext2_dirent *de; - struct page *page = ext2_get_page(inode, n); - - if (IS_ERR(page)) - continue; - kaddr = page_address(page); - if (need_revalidate) { - offset = ext2_validate_entry(kaddr, offset, chunk_mask); - need_revalidate = 0; - } - de = (ext2_dirent *)(kaddr+offset); - limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1); - for ( ;(char*)de <= limit; de = ext2_next_entry(de)) - if (de->inode) { - int over; - unsigned char d_type = DT_UNKNOWN; - - if (types && de->file_type < EXT2_FT_MAX) - d_type = types[de->file_type]; - - offset = (char *)de - kaddr; - over = filldir(dirent, de->name, de->name_len, - (n<inode), d_type); - if (over) { - ext2_put_page(page); - goto done; - } - } - ext2_put_page(page); - } - -done: - filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; - filp->f_version = inode->i_version; - UPDATE_ATIME(inode); - return 0; -} - -/* - * ext2_find_entry() - * - * finds an entry in the specified directory with the wanted name. It - * returns the page in which the entry was found, and the entry itself - * (as a parameter - res_dir). Page is returned mapped and unlocked. - * Entry is guaranteed to be valid. - */ -struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir, - struct dentry *dentry, struct page ** res_page) -{ - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - unsigned reclen = EXT2_DIR_REC_LEN(namelen); - unsigned long start, n; - unsigned long npages = dir_pages(dir); - struct page *page = NULL; - ext2_dirent * de; - - /* OFFSET_CACHE */ - *res_page = NULL; - - // start = dir->u.ext2_i.i_dir_start_lookup; - start = 0; - if (start >= npages) - start = 0; - n = start; - do { - char *kaddr; - page = ext2_get_page(dir, n); - if (!IS_ERR(page)) { - kaddr = page_address(page); - de = (ext2_dirent *) kaddr; - kaddr += PAGE_CACHE_SIZE - reclen; - while ((char *) de <= kaddr) { - if (ext2_match (namelen, name, de)) - goto found; - de = ext2_next_entry(de); - } - ext2_put_page(page); - } - if (++n >= npages) - n = 0; - } while (n != start); - return NULL; - -found: - *res_page = page; - // dir->u.ext2_i.i_dir_start_lookup = n; - return de; -} - -struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p) -{ - struct page *page = ext2_get_page(dir, 0); - ext2_dirent *de = NULL; - - if (!IS_ERR(page)) { - de = ext2_next_entry((ext2_dirent *) page_address(page)); - *p = page; - } - return de; -} - -ino_t obdfs_inode_by_name(struct inode * dir, struct dentry *dentry, int *type) -{ - ino_t res = 0; - struct ext2_dir_entry_2 * de; - struct page *page; - - de = ext2_find_entry (dir, dentry, &page); - if (de) { - res = le32_to_cpu(de->inode); - *type = obdfs_dt2fmt[de->file_type]; - kunmap(page); - page_cache_release(page); - } - return res; -} - -/* Releases the page */ -void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, - struct page *page, struct inode *inode) -{ - unsigned from = (char *) de - (char *) page_address(page); - unsigned to = from + le16_to_cpu(de->rec_len); - int err; - - lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - LBUG(); - de->inode = cpu_to_le32(inode->i_ino); - ext2_set_de_type (de, inode); - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - err = ext2_commit_chunk(page, from, to); - UnlockPage(page); - ext2_put_page(page); -} - -/* - * Parent is locked. - */ -int ext2_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; - unsigned reclen = EXT2_DIR_REC_LEN(namelen); - unsigned short rec_len, name_len; - struct page *page = NULL; - ext2_dirent * 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 = ext2_get_page(dir, n); - err = PTR_ERR(page); - if (IS_ERR(page)) - goto out; - kaddr = page_address(page); - de = (ext2_dirent *)kaddr; - kaddr += PAGE_CACHE_SIZE - reclen; - while ((char *)de <= kaddr) { - err = -EEXIST; - if (ext2_match (namelen, name, de)) - goto out_page; - name_len = EXT2_DIR_REC_LEN(de->name_len); - rec_len = le16_to_cpu(de->rec_len); - if ( n==npages && rec_len == 0) { - CERROR("Fatal dir behaviour\n"); - goto out_page; - } - if (!de->inode && rec_len >= reclen) - goto got_it; - if (rec_len >= name_len + reclen) - goto got_it; - de = (ext2_dirent *) ((char *) de + rec_len); - } - ext2_put_page(page); - } - LBUG(); - return -EINVAL; - -got_it: - from = (char*)de - (char*)page_address(page); - to = from + rec_len; - lock_page(page); - err = page->mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - goto out_unlock; - if (de->inode) { - ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len); - de1->rec_len = cpu_to_le16(rec_len - name_len); - de->rec_len = cpu_to_le16(name_len); - de = de1; - } - de->name_len = namelen; - memcpy (de->name, name, namelen); - de->inode = cpu_to_le32(inode->i_ino); - ext2_set_de_type (de, inode); - CDEBUG(D_INODE, "type set to %o\n", de->file_type); - dir->i_mtime = dir->i_ctime = CURRENT_TIME; - err = ext2_commit_chunk(page, from, to); - - // change_inode happens with the commit_chunk - // obdfs_change_inode(dir); - /* OFFSET_CACHE */ -out_unlock: - UnlockPage(page); -out_page: - ext2_put_page(page); -out: - return err; -} - -/* - * ext2_delete_entry deletes a directory entry by merging it with the - * previous entry. Page is up-to-date. Releases the page. - */ -int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) -{ - struct address_space *mapping = page->mapping; - struct inode *inode = mapping->host; - char *kaddr = page_address(page); - unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); - unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len); - ext2_dirent * pde = NULL; - ext2_dirent * de = (ext2_dirent *) (kaddr + from); - int err; - - while ((char*)de < (char*)dir) { - pde = de; - de = ext2_next_entry(de); - } - if (pde) - from = (char*)pde - (char*)page_address(page); - lock_page(page); - err = mapping->a_ops->prepare_write(NULL, page, from, to); - if (err) - LBUG(); - if (pde) - pde->rec_len = cpu_to_le16(to-from); - dir->inode = 0; - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - err = ext2_commit_chunk(page, from, to); - UnlockPage(page); - ext2_put_page(page); - return err; -} - -/* - * Set the first fragment of directory. - */ -int ext2_make_empty(struct inode *inode, struct inode *parent) -{ - struct address_space *mapping = inode->i_mapping; - struct page *page = grab_cache_page(mapping, 0); - unsigned chunk_size = ext2_chunk_size(inode); - struct ext2_dir_entry_2 * de; - char *base; - int err; - ENTRY; - - if (!page) - return -ENOMEM; - err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); - if (err) - goto fail; - - base = page_address(page); - - de = (struct ext2_dir_entry_2 *) base; - de->name_len = 1; - de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1)); - memcpy (de->name, ".\0\0", 4); - de->inode = cpu_to_le32(inode->i_ino); - ext2_set_de_type (de, inode); - - de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1)); - de->name_len = 2; - de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1)); - de->inode = cpu_to_le32(parent->i_ino); - memcpy (de->name, "..\0", 4); - ext2_set_de_type (de, inode); - - err = ext2_commit_chunk(page, 0, chunk_size); -fail: - UnlockPage(page); - page_cache_release(page); - ENTRY; - return err; -} - -/* - * routine to check that the specified directory is empty (for rmdir) - */ -int ext2_empty_dir (struct inode * inode) -{ - struct page *page = NULL; - unsigned long i, npages = dir_pages(inode); - - for (i = 0; i < npages; i++) { - char *kaddr; - ext2_dirent * de; - page = ext2_get_page(inode, i); - - if (IS_ERR(page)) - continue; - - kaddr = page_address(page); - de = (ext2_dirent *)kaddr; - kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1); - - while ((char *)de <= kaddr) { - if (de->inode != 0) { - /* check for . and .. */ - if (de->name[0] != '.') - goto not_empty; - if (de->name_len > 2) - goto not_empty; - if (de->name_len < 2) { - if (de->inode != - cpu_to_le32(inode->i_ino)) - goto not_empty; - } else if (de->name[1] != '.') - goto not_empty; - } - de = ext2_next_entry(de); - } - ext2_put_page(page); - } - return 1; - -not_empty: - ext2_put_page(page); - return 0; -} - -struct file_operations obdfs_dir_operations = { - read: generic_read_dir, - readdir: new_obdfs_readdir -}; diff --git a/lustre/obdfs/file.c b/lustre/obdfs/file.c deleted file mode 100644 index 45493d2..0000000 --- a/lustre/obdfs/file.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * linux/fs/ext2/file.c - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/file.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext2 fs regular file handling primitives - * - * 64-bit file support on 64-bit platforms by Jakub Jelinek - * (jj@sunsite.ms.mff.cuni.cz) - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_OBDFS - -#include -#include - -extern int obdfs_setattr(struct dentry *de, struct iattr *attr); -void obdfs_change_inode(struct inode *inode); - -static inline void obdfs_remove_suid(struct inode *inode) -{ - unsigned int mode; - - /* set S_IGID if S_IXGRP is set, and always set S_ISUID */ - mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID; - - /* was any of the uid bits set? */ - mode &= inode->i_mode; - if (mode && !capable(CAP_FSETID)) { - inode->i_mode &= ~mode; - // XXX careful here - we cannot change the size - //obdfs_change_inode(inode); - } -} - -/* - * Write to a file (through the page cache). - */ -static ssize_t -obdfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - ssize_t retval; - CDEBUG(D_INFO, "Writing inode %ld, %ld bytes, offset %Ld\n", - file->f_dentry->d_inode->i_ino, (long)count, *ppos); - - retval = generic_file_write(file, buf, count, ppos); - CDEBUG(D_INFO, "Wrote %ld\n", (long)retval); - - /* update mtime/ctime/atime here, NOT size */ - if (retval > 0) { - struct iattr attr; - attr.ia_valid = ATTR_MTIME | ATTR_CTIME | ATTR_ATIME; - attr.ia_mtime = attr.ia_ctime = attr.ia_atime = - CURRENT_TIME; - obdfs_setattr(file->f_dentry, &attr); - } - EXIT; - return retval; -} - - -/* XXX this does not need to do anything for data, it _does_ need to - call setattr */ -int obdfs_fsync(struct file *file, struct dentry *dentry, int data) -{ - return 0; -} - -struct file_operations obdfs_file_operations = { - read: generic_file_read, - write: obdfs_file_write, - mmap: generic_file_mmap, - fsync: NULL -}; - - -struct inode_operations obdfs_file_inode_operations = { - truncate: obdfs_truncate, - setattr: obdfs_setattr -}; - diff --git a/lustre/obdfs/flushd.c b/lustre/obdfs/flushd.c deleted file mode 100644 index 66c9f3d..0000000 --- a/lustre/obdfs/flushd.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * OBDFS Super operations - also used for Lustre file system - * - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1991, 1992 Linus Torvalds - * Copryright (C) 1999 Stelias Computing Inc. - * Copryright (C) 1999 Seagate Technology Inc. - * - */ -#define __NO_VERSION__ -#include -#include -#include - -#include -#include -#include - - -/* XXX temporary until the real function is available from kernel - * XXX set this to memory size in pages for max page cache size - */ -#define nr_free_buffer_pages() 32768 - -/* Defines for page buf daemon */ -struct pupd_prm { - int nfract; /* Percentage of buffer cache dirty to - activate bdflush */ - int ndirty; /* Maximum number of dirty blocks to write out per - wake-cycle */ - int nrefill; /* Number of clean buffers to try to obtain - each time we call refill */ - int nref_dirt; /* Dirty buffer threshold for activating bdflush - when trying to refill buffers. */ - int interval; /* jiffies delay between pupdate flushes */ - int age_buffer; /* Time for normal buffer to age before we flush it */ - int age_super; /* Time for superblock to age before we flush it */ -}; - - -static struct pupdated { - int active; - wait_queue_head_t waitq; - struct timer_list timer; - struct pupd_prm parms; -} pupdated = { - active: -1, - parms: {40, 1024, 64, 256, 1*HZ, 30*HZ, 5*HZ } -}; - - -/* Called with the superblock list lock held */ -static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo, - int nr_slots, struct page **pages, char **bufs, - obd_size *counts, obd_off *offsets, - obd_flag *flag, unsigned long check_time) -{ - struct list_head *page_list = obdfs_iplist(inode); - struct list_head *tmp; - int num = 0; - - ENTRY; - - tmp = page_list; - /* Traverse list in reverse order, so we do FIFO, not LIFO order */ - while ( (tmp = tmp->prev) != page_list && num < nr_slots ) { - struct obdfs_pgrq *req; - struct page *page; - - req = list_entry(tmp, struct obdfs_pgrq, rq_plist); - page = req->rq_page; - - - if (req->rq_jiffies > check_time) - break; /* pages are in chronological order */ - - /* Only allocate the obdo if we will actually do I/O here */ - if ( !*obdo ) { - OIDEBUG(inode); - *obdo = obdo_fromid(IID(inode), inode->i_ino, - OBD_MD_FLNOTOBD); - if ( IS_ERR(*obdo) ) { - int err = PTR_ERR(*obdo); - *obdo = NULL; - - EXIT; - return err; - } - - /* FIXME revisit fromid & from_inode */ - obdfs_from_inode(*obdo, inode); - *flag = OBD_BRW_CREATE; - } - - /* Remove request from list before write to avoid conflict. - * Note that obdfs_pgrq_del() also deletes the request. - */ - obdfs_pgrq_del(req); - if ( !page ) { - CDEBUG(D_CACHE, "no page \n"); - continue; - } - - bufs[num] = (char *)page_address(page); - pages[num] = page; - counts[num] = PAGE_SIZE; - offsets[num] = ((obd_off)page->index) << PAGE_SHIFT; - CDEBUG(D_INFO, "ENQ inode %ld, page %p addr %p to vector\n", - inode->i_ino, page, (char *)page_address(page)); - num++; - } - - if (!list_empty(page_list)) - CDEBUG(D_INFO, "inode %ld list not empty\n", inode->i_ino); - CDEBUG(D_INFO, "added %d page(s) to vector\n", num); - - EXIT; - return num; -} /* obdfs_enqueue_pages */ - -/* Dequeue cached pages for a dying inode without writing them to disk. */ -void obdfs_dequeue_pages(struct inode *inode) -{ - struct list_head *tmp; - - ENTRY; - obd_down(&obdfs_i2sbi(inode)->osi_list_mutex); - tmp = obdfs_islist(inode); - if ( list_empty(tmp) ) { - CDEBUG(D_INFO, "no dirty pages for inode %ld\n", inode->i_ino); - obd_up(&obdfs_i2sbi(inode)->osi_list_mutex); - EXIT; - return; - } - - /* take it out of the super list */ - list_del(tmp); - INIT_LIST_HEAD(obdfs_islist(inode)); - - tmp = obdfs_iplist(inode); - while ( (tmp = tmp->prev) != obdfs_iplist(inode) ) { - struct obdfs_pgrq *req; - struct page *page; - - req = list_entry(tmp, struct obdfs_pgrq, rq_plist); - page = req->rq_page; - /* take it out of the list and free */ - obdfs_pgrq_del(req); - /* now put the page away */ - put_page(page); - } - - obd_up(&obdfs_i2sbi(inode)->osi_list_mutex); - - /* decrement inode reference for page cache */ - atomic_dec(&inode->i_count); - EXIT; -} - -/* This value is not arbitrarily chosen. KIO_STATIC_PAGES from linux/iobuf.h */ -#define MAX_IOVEC (KIO_STATIC_PAGES - 1) - -/* Remove writeback requests for the superblock */ -int obdfs_flush_reqs(struct list_head *inode_list, unsigned long check_time) -{ - struct list_head *tmp; - unsigned long max_io, total_io = 0; - obd_count num_io; - obd_count num_obdos; - struct inode *inodes[MAX_IOVEC]; /* write data back to these */ - struct page *pages[MAX_IOVEC]; /* call put_page on these */ - struct obdo *obdos[MAX_IOVEC]; - char *bufs[MAX_IOVEC]; - obd_size counts[MAX_IOVEC]; - obd_off offsets[MAX_IOVEC]; - obd_flag flags[MAX_IOVEC]; - obd_count bufs_per_obdo[MAX_IOVEC]; - int err = 0; - struct obdfs_sb_info *sbi; - - ENTRY; - if (!inode_list) { - CDEBUG(D_INODE, "no list\n"); - EXIT; - return 0; - } - - sbi = list_entry(inode_list, struct obdfs_sb_info, osi_inodes); - - obd_down(&sbi->osi_list_mutex); - if ( list_empty(inode_list) ) { - CDEBUG(D_INFO, "list empty\n"); - obd_up(&sbi->osi_list_mutex); - EXIT; - return 0; - } - - /* If we are forcing a write, write out all dirty pages */ - max_io = check_time == ~0UL ? 1<<31 : pupdated.parms.ndirty; - CDEBUG(D_INFO, "max_io = %lu\n", max_io); - - /* Add each inode's dirty pages to a write vector, and write it. - * Traverse list in reverse order, so we do FIFO, not LIFO order - */ - again: - tmp = inode_list; - num_io = 0; - num_obdos = 0; - while ( (tmp = tmp->prev) != inode_list && total_io < max_io) { - struct obdfs_inode_info *ii; - struct inode *inode; - int res; - - ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes); - inode = list_entry(ii, struct inode, u); - inodes[num_obdos] = inode; - obdos[num_obdos] = NULL; - CDEBUG(D_INFO, "checking inode %ld pages\n", inode->i_ino); - - /* Make sure we reference "inode" and not "inodes[num_obdos]", - * as num_obdos will change after the loop is run. - */ - if (!list_empty(obdfs_iplist(inode))) { - res = obdfs_enqueue_pages(inode, &obdos[num_obdos], - MAX_IOVEC - num_io, - &pages[num_io], &bufs[num_io], - &counts[num_io], - &offsets[num_io], - &flags[num_obdos], - check_time); - CDEBUG(D_INFO, "FLUSH inode %ld, pages flushed: %d\n", - inode->i_ino, res); - if ( res < 0 ) { - CDEBUG(D_INODE, - "fatal: unable to enqueue inode %ld (err %d)\n", - inode->i_ino, res); - /* XXX Move bad inode to end of list so we can - * continue with flushing list. This is a - * temporary measure to avoid machine lockups. - * Maybe if we have -ENOENT, simply discard. - */ - list_del(tmp); - list_add(tmp, inode_list); - err = res; - EXIT; - goto BREAK; - } - if (res == 0) - continue; - - num_io += res; - total_io += res; - bufs_per_obdo[num_obdos] = res; - num_obdos++; - - if ( num_io == MAX_IOVEC ) { - obd_up(&sbi->osi_list_mutex); - err = obdfs_do_vec_wr(inodes, num_io, num_obdos, - obdos, bufs_per_obdo, - pages, bufs, counts, - offsets, flags); - if ( err ) { - CDEBUG(D_INODE, - "fatal: do_vec_wr err=%d\n", - err); - EXIT; - goto ERR; - } - obd_down(&sbi->osi_list_mutex); - goto again; - } - } - } - -BREAK: - obd_up(&sbi->osi_list_mutex); - - /* flush any remaining I/Os */ - if ( num_io ) { - err = obdfs_do_vec_wr(inodes, num_io, num_obdos, obdos, - bufs_per_obdo, pages, bufs, counts, - offsets, flags); - if (err) - CDEBUG(D_INODE, "fatal: unable to do vec_wr (err %d)\n", err); - num_io = 0; - num_obdos = 0; - } - - /* Remove inode from superblock dirty list when no more pages. - * Make sure we don't point at the current inode with tmp - * when we re-init the list on the inode, or we will loop. - */ - obd_down(&sbi->osi_list_mutex); - tmp = inode_list; - while ( (tmp = tmp->prev) != inode_list ) { - struct obdfs_inode_info *ii; - struct inode *inode; - - ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes); - inode = list_entry(ii, struct inode, u); - CDEBUG(D_INFO, "checking inode %ld empty\n", inode->i_ino); - if (list_empty(obdfs_iplist(inode))) { - CDEBUG(D_INFO, "remove inode %ld from dirty list\n", - inode->i_ino); - tmp = tmp->next; - list_del(obdfs_islist(inode)); - /* decrement inode reference for page cache */ - atomic_dec(&inode->i_count); - INIT_LIST_HEAD(obdfs_islist(inode)); - } - } - obd_up(&sbi->osi_list_mutex); - - CDEBUG(D_INFO, "flushed %ld pages in total\n", total_io); - EXIT; -ERR: - return err ? err : total_io; -} /* obdfs_flush_reqs */ - - -/* Walk all of the superblocks and write out blocks which are too old. - * Return the maximum number of blocks written for a single filesystem. - */ -int obdfs_flush_dirty_pages(unsigned long check_time) -{ - struct list_head *sl; - int max = 0; - - /* ENTRY; */ - sl = &obdfs_super_list; - while ( (sl = sl->prev) != &obdfs_super_list ) { - struct obdfs_sb_info *sbi = - list_entry(sl, struct obdfs_sb_info, osi_list); - int ret; - - /* walk write requests here, use the sb, check the time */ - ret = obdfs_flush_reqs(&sbi->osi_inodes, check_time); - /* XXX handle error? What to do with it? */ - - max = ret > max ? ret : max; - } - if (max) { EXIT; } - return max; -} /* obdfs_flush_dirty_pages */ - - -static void pupdate_wakeup(unsigned long l) -{ - wake_up(&pupdated.waitq); -} - - -static int pupdate(void *unused) -{ - u_long flags; - int interval = pupdated.parms.interval; - long age = pupdated.parms.age_buffer; - int wrote = 0; - - if (pupdated.active >= 0) { - CDEBUG(D_CACHE, "attempted to run multiple pupdates\n"); - return 1; - } - - init_timer(&pupdated.timer); - init_waitqueue_head(&pupdated.waitq); - pupdated.timer.function = pupdate_wakeup; - - exit_files(current); - exit_mm(current); - daemonize(); - - current->session = 1; - current->pgrp = 1; - strcpy(current->comm, "pupdated"); - - CDEBUG(D_CACHE, "pupdated activated...\n"); - pupdated.active = 1; - - spin_lock_irqsave(¤t->sigmask_lock, flags); - flush_signals(current); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irqrestore(¤t->sigmask_lock, flags); - - do { - long dirty_limit; - - /* update interval */ - if (pupdated.active == 1 && interval) { - mod_timer(&pupdated.timer, jiffies + interval); - interruptible_sleep_on(&pupdated.waitq); - } - if (pupdated.active == 0) { - del_timer(&pupdated.timer); - /* If stopped, we flush one last time... */ - } - - /* asynchronous setattr etc for the future ... - obdfs_flush_dirty_inodes(jiffies - pupdated.parms.age_super); - */ - dirty_limit = nr_free_buffer_pages() * pupdated.parms.nfract / 100; - - if (obdfs_cache_count > dirty_limit) { - interval = 0; - if (wrote < pupdated.parms.ndirty) - age >>= 1; - if (wrote) - CDEBUG(D_CACHE, "wrote %d, age %ld, interval %d\n", - wrote, age, interval); - } else { - if (wrote < pupdated.parms.ndirty >> 1 && - obdfs_cache_count < dirty_limit / 2) { - interval = pupdated.parms.interval; - age = pupdated.parms.age_buffer; - if (wrote) - CDEBUG(D_INFO, - "wrote %d, age %ld, interval %d\n", - wrote, age, interval); - } else if (obdfs_cache_count > dirty_limit / 2) { - interval >>= 1; - if (wrote < pupdated.parms.ndirty) - age >>= 1; - if (wrote) - CDEBUG(D_CACHE, - "wrote %d, age %ld, interval %d\n", - wrote, age, interval); - } - } - - wrote = obdfs_flush_dirty_pages(jiffies - age); - if (wrote) { - CDEBUG(D_CACHE, - "dirty_limit %ld, cache_count %ld, wrote %d\n", - dirty_limit, obdfs_cache_count, wrote); - run_task_queue(&tq_disk); - } - } while (pupdated.active == 1); - - CDEBUG(D_CACHE, "pupdated stopped...\n"); - pupdated.active = -1; - wake_up(&pupdated.waitq); - return 0; -} - - -int obdfs_flushd_init(void) -{ - /* - kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - */ - kernel_thread(pupdate, NULL, 0); - CDEBUG(D_PSDEV, "flushd inited\n"); - return 0; -} - -int obdfs_flushd_cleanup(void) -{ - ENTRY; - - /* Shut down pupdated. */ - if (pupdated.active > 0) { - CDEBUG(D_CACHE, "inform pupdated\n"); - pupdated.active = 0; - wake_up(&pupdated.waitq); - - CDEBUG(D_CACHE, "wait for pupdated\n"); - while (pupdated.active == 0) { - interruptible_sleep_on(&pupdated.waitq); - } - CDEBUG(D_CACHE, "done waiting for pupdated\n"); - } - - EXIT; - return 0; -} diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c deleted file mode 100644 index d5869bb..0000000 --- a/lustre/obdfs/namei.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * linux/fs/obdfs/namei.c - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/ext2/namei.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * Big-endian to little-endian byte-swapping/bitmaps by - * David S. Miller (davem@caip.rutgers.edu), 1995 - * Directory entry file type support and forward compatibility hooks - * for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998 - * - * Changes for use in OBDFS - * Copyright (c) 1999, Seagate Technology Inc. - * Copyright (C) 2001, Cluster File Systems, Inc. - * Rewritten based on recent ext2 page cache use. - * - */ - -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_OBDFS - -#include -#include -extern struct address_space_operations obdfs_aops; - -/* from super.c */ -extern void obdfs_change_inode(struct inode *inode); -extern int obdfs_setattr(struct dentry *de, struct iattr *attr); - -/* from dir.c */ -extern int ext2_add_link (struct dentry *dentry, struct inode *inode); -obd_id obdfs_inode_by_name(struct inode * dir, struct dentry *dentry, int *typ); -int ext2_make_empty(struct inode *inode, struct inode *parent); -struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir, - struct dentry *dentry, struct page ** res_page); -int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ); -int ext2_empty_dir (struct inode * inode); -struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p); -void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, - struct page *page, struct inode *inode); - -/* - * Couple of helper functions - make the code slightly cleaner. - */ -static inline void ext2_inc_count(struct inode *inode) -{ - inode->i_nlink++; - obdfs_change_inode(inode); -} - -/* postpone the disk update until the inode really goes away */ -static inline void ext2_dec_count(struct inode *inode) -{ - inode->i_nlink--; - if (inode->i_nlink > 0) - obdfs_change_inode(inode); -} - -static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) -{ - int err; - err = ext2_add_link(dentry, inode); - if (!err) { - d_instantiate(dentry, inode); - return 0; - } - ext2_dec_count(inode); - iput(inode); - return err; -} - -/* methods */ -static struct dentry *obdfs_lookup(struct inode * dir, struct dentry *dentry) -{ - struct obdo *oa; - struct inode * inode = NULL; - int type; - obd_id ino; - - ENTRY; - if (dentry->d_name.len > EXT2_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); - - ino = obdfs_inode_by_name(dir, dentry, &type); - if (!ino) - goto negative; - - oa = obdo_fromid(IID(dir), ino, type, - (__u32)(OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS)); - if ( IS_ERR(oa) ) { - CERROR("obdo_fromid failed\n"); - EXIT; - return ERR_PTR(-EACCES); - } - - inode = iget4(dir->i_sb, (ino_t)ino, NULL, oa); - obdo_free(oa); - - if (!inode) - return ERR_PTR(-EACCES); - - negative: - d_add(dentry, inode); - return NULL; -} - - -/* - * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure. - * - * `len <= EXT2_NAME_LEN' is guaranteed by caller. - * `de != NULL' is guaranteed by caller. - */ -static inline int ext2_match (int len, const char * const name, - struct ext2_dir_entry_2 * de) -{ - if (len != de->name_len) - return 0; - if (!de->inode) - return 0; - return !memcmp(name, de->name, len); -} - -static struct inode *obdfs_new_inode(struct inode *dir, int mode) -{ - struct obdo *oa; - struct inode *inode; - int err; - - ENTRY; - oa = obdo_alloc(); - if (!oa) { - EXIT; - return ERR_PTR(-ENOMEM); - } - - /* Send a hint to the create method on the type of file to create */ - oa->o_mode = mode; - oa->o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE; - CDEBUG(D_INODE, "\n"); - err = obd_create(IID(dir), oa, NULL); - CDEBUG(D_INODE, "\n"); - - if ( err ) { - CERROR("new_inode - fatal: err %d\n", err); - obdo_free(oa); - EXIT; - return ERR_PTR(err); - } - CDEBUG(D_INODE, "obdo mode %o\n", oa->o_mode); - - inode = iget4(dir->i_sb, (ino_t)oa->o_id, NULL, oa); - CDEBUG(D_INODE, "\n"); - - if (!inode) { - CERROR("new_inode -fatal: %ld\n", (long)oa->o_id); - obd_destroy(IID(dir), oa, NULL); - obdo_free(oa); - EXIT; - return ERR_PTR(-EIO); - } - obdo_free(oa); - - if (!list_empty(&inode->i_dentry)) { - CERROR("new_inode -fatal: aliases %ld, ct %d lnk %d\n", - (long)oa->o_id, - atomic_read(&inode->i_count), - inode->i_nlink); - obd_destroy(IID(dir), oa, NULL); - iput(inode); - EXIT; - return ERR_PTR(-EIO); - } - - EXIT; - return inode; -} /* obdfs_new_inode */ - - -/* - * By the time this is called, we already have created - * the directory cache entry for the new file, but it - * is so far negative - it has no inode. - * - * If the create succeeds, we fill in the inode information - * with d_instantiate(). - */ -static int obdfs_create (struct inode * dir, struct dentry * dentry, int mode) -{ - struct inode * inode = obdfs_new_inode (dir, mode); - int err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - inode->i_op = &obdfs_file_inode_operations; - inode->i_fop = &obdfs_file_operations; - inode->i_mapping->a_ops = &obdfs_aops; - err = ext2_add_nondir(dentry, inode); - } - return err; -} /* obdfs_create */ - - -static int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) -{ - struct inode * inode = obdfs_new_inode (dir, mode); - int err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); - obdfs_change_inode(inode); - err = ext2_add_nondir(dentry, inode); - } - return err; -} - -static int obdfs_symlink (struct inode * dir, struct dentry * dentry, - const char * symname) -{ - struct super_block * sb = dir->i_sb; - int err = -ENAMETOOLONG; - unsigned l = strlen(symname)+1; - struct inode * inode; - struct obdfs_inode_info *oinfo; - - if (l > sb->s_blocksize) - goto out; - - inode = obdfs_new_inode (dir, S_IFLNK | S_IRWXUGO); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out; - - oinfo = obdfs_i2info(inode); - if (l >= sizeof(oinfo->oi_inline)) { - /* slow symlink */ - inode->i_op = &page_symlink_inode_operations; - inode->i_mapping->a_ops = &obdfs_aops; - err = block_symlink(inode, symname, l); - if (err) - goto out_fail; - } else { - /* fast symlink */ - inode->i_op = &obdfs_fast_symlink_inode_operations; - memcpy(oinfo->oi_inline, symname, l); - inode->i_size = l-1; - } - obdfs_change_inode(inode); - - err = ext2_add_nondir(dentry, inode); -out: - return err; - -out_fail: - ext2_dec_count(inode); - iput (inode); - goto out; -} - - - -static int obdfs_link (struct dentry * old_dentry, struct inode * dir, - struct dentry *dentry) -{ - struct inode *inode = old_dentry->d_inode; - - if (S_ISDIR(inode->i_mode)) - return -EPERM; - - if (inode->i_nlink >= EXT2_LINK_MAX) - return -EMLINK; - - inode->i_ctime = CURRENT_TIME; - ext2_inc_count(inode); - atomic_inc(&inode->i_count); - - return ext2_add_nondir(dentry, inode); -} - - -static int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) -{ - struct inode * inode; - int err = -EMLINK; - ENTRY; - - if (dir->i_nlink >= EXT2_LINK_MAX) - goto out; - - ext2_inc_count(dir); - - inode = obdfs_new_inode (dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_dir; - - inode->i_op = &obdfs_dir_inode_operations; - inode->i_fop = &obdfs_dir_operations; - inode->i_mapping->a_ops = &obdfs_aops; - - ext2_inc_count(inode); - - err = ext2_make_empty(inode, dir); - if (err) - goto out_fail; - - err = ext2_add_link(dentry, inode); - if (err) - goto out_fail; - - d_instantiate(dentry, inode); -out: - EXIT; - return err; - -out_fail: - ext2_dec_count(inode); - ext2_dec_count(inode); - iput(inode); - EXIT; -out_dir: - ext2_dec_count(dir); - EXIT; - goto out; -} - -static int obdfs_unlink(struct inode * dir, struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - struct ext2_dir_entry_2 * de; - struct page * page; - int err = -ENOENT; - - de = ext2_find_entry (dir, dentry, &page); - if (!de) - goto out; - - err = ext2_delete_entry (de, page); - if (err) - goto out; - - inode->i_ctime = dir->i_ctime; - ext2_dec_count(inode); - err = 0; -out: - return err; -} - - -static int obdfs_rmdir (struct inode * dir, struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - int err = -ENOTEMPTY; - - if (ext2_empty_dir(inode)) { - err = obdfs_unlink(dir, dentry); - if (!err) { - inode->i_size = 0; - ext2_dec_count(inode); - ext2_dec_count(dir); - } - } - return err; -} - -static int obdfs_rename (struct inode * old_dir, struct dentry * old_dentry, - struct inode * new_dir, struct dentry * new_dentry ) -{ - struct inode * old_inode = old_dentry->d_inode; - struct inode * new_inode = new_dentry->d_inode; - struct page * dir_page = NULL; - struct ext2_dir_entry_2 * dir_de = NULL; - struct page * old_page; - struct ext2_dir_entry_2 * old_de; - int err = -ENOENT; - - old_de = ext2_find_entry (old_dir, old_dentry, &old_page); - if (!old_de) - goto out; - - if (S_ISDIR(old_inode->i_mode)) { - err = -EIO; - dir_de = ext2_dotdot(old_inode, &dir_page); - if (!dir_de) - goto out_old; - } - - if (new_inode) { - struct page *new_page; - struct ext2_dir_entry_2 *new_de; - - err = -ENOTEMPTY; - if (dir_de && !ext2_empty_dir (new_inode)) - goto out_dir; - - err = -ENOENT; - new_de = ext2_find_entry (new_dir, new_dentry, &new_page); - if (!new_de) - goto out_dir; - ext2_inc_count(old_inode); - ext2_set_link(new_dir, new_de, new_page, old_inode); - new_inode->i_ctime = CURRENT_TIME; - if (dir_de) - new_inode->i_nlink--; - ext2_dec_count(new_inode); - } else { - if (dir_de) { - err = -EMLINK; - if (new_dir->i_nlink >= EXT2_LINK_MAX) - goto out_dir; - } - ext2_inc_count(old_inode); - err = ext2_add_link(new_dentry, old_inode); - if (err) { - ext2_dec_count(old_inode); - goto out_dir; - } - if (dir_de) - ext2_inc_count(new_dir); - } - - ext2_delete_entry (old_de, old_page); - ext2_dec_count(old_inode); - - if (dir_de) { - ext2_set_link(old_inode, dir_de, dir_page, new_dir); - ext2_dec_count(old_dir); - } - return 0; - - -out_dir: - if (dir_de) { - kunmap(dir_page); - page_cache_release(dir_page); - } -out_old: - kunmap(old_page); - page_cache_release(old_page); -out: - return err; -} - -struct inode_operations obdfs_dir_inode_operations = { - create: obdfs_create, - lookup: obdfs_lookup, - link: obdfs_link, - unlink: obdfs_unlink, - symlink: obdfs_symlink, - mkdir: obdfs_mkdir, - rmdir: obdfs_rmdir, - mknod: obdfs_mknod, - rename: obdfs_rename, - setattr: obdfs_setattr -}; diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c deleted file mode 100644 index 1c94dc7..0000000 --- a/lustre/obdfs/rw.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * OBDFS Super operations - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1996, 1997, Olaf Kirch - * Copryright (C) 1999 Stelias Computing Inc, - * (author Peter J. Braam ) - * Copryright (C) 1999 Seagate Technology Inc. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_OBDFS - -#include -#include -#include - -void obdfs_change_inode(struct inode *inode); - -static int cache_writes = 0; - - -/* page cache support stuff */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) -/* - * Add a page to the dirty page list. - */ -void __set_page_dirty(struct page *page) -{ - struct address_space *mapping; - spinlock_t *pg_lock; - - pg_lock = PAGECACHE_LOCK(page); - spin_lock(pg_lock); - - mapping = page->mapping; - spin_lock(&mapping->page_lock); - - list_del(&page->list); - list_add(&page->list, &mapping->dirty_pages); - - spin_unlock(&mapping->page_lock); - spin_unlock(pg_lock); - - if (mapping->host) - mark_inode_dirty_pages(mapping->host); -} -/* - * Remove page from dirty list - */ -void __set_page_clean(struct page *page) -{ - struct address_space *mapping = page->mapping; - struct inode *inode; - - if (!mapping) - return; - - list_del(&page->list); - list_add(&page->list, &mapping->clean_pages); - - inode = mapping->host; - if (list_empty(&mapping->dirty_pages)) { - CDEBUG(D_INODE, "inode clean\n"); - inode->i_state &= ~I_DIRTY_PAGES; - } - EXIT; -} - -#else -/* - * Add a page to the dirty page list. - */ -void set_page_dirty(struct page *page) -{ - if (!test_and_set_bit(PG_dirty, &page->flags)) { - struct address_space *mapping = page->mapping; - - if (mapping) { - spin_lock(&pagecache_lock); - list_del(&page->list); - list_add(&page->list, &mapping->dirty_pages); - spin_unlock(&pagecache_lock); - - if (mapping->host) - mark_inode_dirty_pages(mapping->host); - } - } -} -/* - * Remove page from dirty list - */ -void __set_page_clean(struct page *page) -{ - struct address_space *mapping = page->mapping; - struct inode *inode; - - if (!mapping) - return; - - spin_lock(&pagecache_lock); - list_del(&page->list); - list_add(&page->list, &mapping->clean_pages); - - inode = mapping->host; - if (list_empty(&mapping->dirty_pages)) { - CDEBUG(D_INODE, "inode clean\n"); - inode->i_state &= ~I_DIRTY_PAGES; - } - spin_unlock(&pagecache_lock); - EXIT; -} - -#endif - - -inline void set_page_clean(struct page *page) -{ - if (PageDirty(page)) { - ClearPageDirty(page); - __set_page_clean(page); - } -} - -/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */ -static int obdfs_brw(int rw, struct inode *inode2, - struct page *page, int create) -{ - struct inode *inode = page->mapping->host; - struct ll_inode_info *lii = ll_i2info(inode); - obd_size count = PAGE_SIZE; - obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; - obd_flag flags = create ? OBD_BRW_CREATE : 0; - int err; - - ENTRY; - - CHECK_MOUNT_EPOCH(inode); - CHECK_MOUNT_EPOCH(inode2); - - err = obd_brw(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ, IID(inode), - md, 1, &page, &count, &offset, - &flags, NULL); - //if ( !err ) - // obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */ - - obdo_free(oa); - EXIT; - return err; -} /* obdfs_brw */ - -/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */ -static int obdfs_commit_page(struct page *page, int create, int from, int to) -{ - struct inode *inode = page->mapping->host; - obd_count num_obdo = 1; - obd_count bufs_per_obdo = 1; - struct obdo *oa; - obd_size count = to; - obd_off offset = (((obd_off)page->index) << PAGE_SHIFT); - obd_flag flags = create ? OBD_BRW_CREATE : 0; - int err; - - ENTRY; - - CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n", - from, to, (unsigned long long)count); - - err = obd_brw(OBD_BRW_WRITE, IID(inode), md, 1, - &page, &count, &offset, &flags, NULL); - if ( !err ) { - SetPageUptodate(page); - set_page_clean(page); - } - - //if ( !err ) - // obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */ - - obdo_free(oa); - EXIT; - return err; -} /* obdfs_brw */ - -/* returns the page unlocked, but with a reference */ -int obdfs_writepage(struct page *page) -{ - int rc; - struct inode *inode = page->mapping->host; - ENTRY; - CERROR("---> writepage called ino %ld!\n", inode->i_ino); - LBUG(); - rc = obdfs_brw(OBD_BRW_WRITE, inode, page, 1); - if ( !rc ) { - set_page_clean(page); - } else { - CDEBUG(D_INODE, "--> GRR %d\n", rc); - } - EXIT; - return rc; -} - - -void write_inode_pages(struct inode *inode) -{ - struct list_head *tmp = &inode->i_mapping->dirty_pages; - - while ( (tmp = tmp->next) != &inode->i_mapping->dirty_pages) { - struct page *page; - page = list_entry(tmp, struct page, list); - obdfs_writepage(page); - } -} - - -/* returns the page unlocked, but with a reference */ -int obdfs_readpage(struct file *file, struct page *page) -{ - struct inode *inode = page->mapping->host; - int rc; - - ENTRY; - - if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) - <= page->index) { - memset(kmap(page), 0, PAGE_CACHE_SIZE); - kunmap(page); - goto readpage_out; - } - - if (Page_Uptodate(page)) { - EXIT; - goto readpage_out; - } - - rc = obdfs_brw(OBD_BRW_READ, inode, page, 0); - if ( rc ) { - EXIT; - return rc; - } - - readpage_out: - SetPageUptodate(page); - UnlockPage(page); - EXIT; - return 0; -} /* obdfs_readpage */ - -int obdfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) -{ - struct inode *inode = page->mapping->host; - obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; - int rc = 0; - ENTRY; - - kmap(page); - if (Page_Uptodate(page)) { - EXIT; - goto prepare_done; - } - - if ( (from <= offset) && (to >= offset + PAGE_SIZE) ) { - EXIT; - return 0; - } - - rc = obdfs_brw(OBD_BRW_READ, inode, page, 0); - if (!rc) - SetPageUptodate(page); - - prepare_done: - set_page_dirty(page); - //SetPageDirty(page); - EXIT; - return rc; -} - - -#if 0 - - - -static kmem_cache_t *obdfs_pgrq_cachep = NULL; - -int obdfs_init_pgrqcache(void) -{ - ENTRY; - if (obdfs_pgrq_cachep == NULL) { - CDEBUG(D_CACHE, "allocating obdfs_pgrq_cache\n"); - obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq", - sizeof(struct obdfs_pgrq), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (obdfs_pgrq_cachep == NULL) { - EXIT; - return -ENOMEM; - } else { - CDEBUG(D_CACHE, "allocated cache at %p\n", - obdfs_pgrq_cachep); - } - } else { - CDEBUG(D_CACHE, "using existing cache at %p\n", - obdfs_pgrq_cachep); - } - EXIT; - return 0; -} /* obdfs_init_wreqcache */ - -inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq) -{ - --obdfs_cache_count; - CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n", - pgrq->rq_page, obdfs_cache_count); - list_del(&pgrq->rq_plist); - OBDClearCachePage(pgrq->rq_page); - kmem_cache_free(obdfs_pgrq_cachep, pgrq); -} - -void obdfs_cleanup_pgrqcache(void) -{ - ENTRY; - if (obdfs_pgrq_cachep != NULL) { - CDEBUG(D_CACHE, "destroying obdfs_pgrqcache at %p, count %ld\n", - obdfs_pgrq_cachep, obdfs_cache_count); - if (kmem_cache_destroy(obdfs_pgrq_cachep)) - CERROR("unable to free all of cache\n"); - obdfs_pgrq_cachep = NULL; - } else - CERROR("called with NULL pointer\n"); - - EXIT; -} /* obdfs_cleanup_wreqcache */ - - -/* called with the list lock held */ -static struct page *obdfs_find_page_index(struct inode *inode, - unsigned long index) -{ - struct list_head *page_list = obdfs_iplist(inode); - struct list_head *tmp; - struct page *page; - - ENTRY; - - CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n", - inode->i_ino, index); - OIDEBUG(inode); - - if (list_empty(page_list)) { - EXIT; - return NULL; - } - tmp = page_list; - while ( (tmp = tmp->next) != page_list ) { - struct obdfs_pgrq *pgrq; - - pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist); - page = pgrq->rq_page; - if (index == page->index) { - CDEBUG(D_INFO, - "INDEX SEARCH found page %p, index %ld\n", - page, index); - EXIT; - return page; - } - } - - EXIT; - return NULL; -} /* obdfs_find_page_index */ - - -/* call and free pages from Linux page cache: called with io lock on inodes */ -int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io, - obd_count num_obdos, struct obdo **obdos, - obd_count *oa_bufs, struct page **pages, char **bufs, - obd_size *counts, obd_off *offsets, obd_flag *flags) -{ - int err; - - ENTRY; - CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n", - num_io, num_obdos); - if (obd_debug_level & D_INFO) { /* DEBUGGING */ - int i; - printk("OBDOS: "); - for (i = 0; i < num_obdos; i++) - printk("%ld:0x%p ", (long)obdos[i]->o_id, obdos[i]); - - printk("\nPAGES: "); - for (i = 0; i < num_io; i++) - printk("0x%p ", pages[i]); - printk("\n"); - } - - err = obd_brw(OBD_BRW_WRITE, IID(inodes[0]), num_obdos, obdos, - oa_bufs, pages, counts, offsets, flags); - - CDEBUG(D_INFO, "BRW done\n"); - /* release the pages from the page cache */ - while (num_io-- > 0) { - CDEBUG(D_INFO, "calling put_page for %p, index %ld\n", - pages[num_io], pages[num_io]->index); - put_page(pages[num_io]); - } - CDEBUG(D_INFO, "put_page done\n"); - - while (num_obdos-- > 0) { - CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id); - /* copy o_blocks to i_blocks */ - obdfs_set_size (inodes[num_obdos], obdos[num_obdos]->o_size); - //obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]); - obdo_free(obdos[num_obdos]); - } - CDEBUG(D_INFO, "obdo_free done\n"); - EXIT; - return err; -} - - -/* - * Add a page to the write request cache list for later writing. - * ASYNCHRONOUS write method. - */ -static int obdfs_add_page_to_cache(struct inode *inode, struct page *page) -{ - int err = 0; - ENTRY; - - /* The PG_obdcache bit is cleared by obdfs_pgrq_del() BEFORE the page - * is written, so at worst we will write the page out twice. - * - * If the page has the PG_obdcache bit set, then the inode MUST be - * on the superblock dirty list so we don't need to check this. - * Dirty inodes are removed from the superblock list ONLY when they - * don't have any more cached pages. It is possible to have an inode - * with no dirty pages on the superblock list, but not possible to - * have an inode with dirty pages NOT on the superblock dirty list. - */ - if (!OBDAddCachePage(page)) { - struct obdfs_pgrq *pgrq; - pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL); - if (!pgrq) { - OBDClearCachePage(page); - EXIT; - return -ENOMEM; - } - /* not really necessary since we set all pgrq fields here - memset(pgrq, 0, sizeof(*pgrq)); - */ - - pgrq->rq_page = page; - pgrq->rq_jiffies = jiffies; - get_page(pgrq->rq_page); - - obd_down(&obdfs_i2sbi(inode)->osi_list_mutex); - list_add(&pgrq->rq_plist, obdfs_iplist(inode)); - obdfs_cache_count++; - //CERROR("-- count %d\n", obdfs_cache_count); - - /* If inode isn't already on superblock inodes list, add it. - * - * We increment the reference count on the inode to keep it - * from being freed from memory. This _should_ be an iget() - * with an iput() in both flush_reqs() and put_inode(), but - * since put_inode() is called from iput() we can't call iput() - * again there. Instead we just increment/decrement i_count, - * which is mostly what iget/iput do for an inode in memory. - */ - if ( list_empty(obdfs_islist(inode)) ) { - atomic_inc(&inode->i_count); - CDEBUG(D_INFO, - "adding inode %ld to superblock list %p\n", - inode->i_ino, obdfs_slist(inode)); - list_add(obdfs_islist(inode), obdfs_slist(inode)); - } - obd_up(&obdfs_i2sbi(inode)->osi_list_mutex); - - } - - /* XXX For testing purposes, we can write out the page here. - err = obdfs_flush_reqs(obdfs_slist(inode), ~0UL); - */ - - EXIT; - return err; -} /* obdfs_add_page_to_cache */ - -void rebalance(void) -{ - if (obdfs_cache_count > 60000) { - CERROR("-- count %ld\n", obdfs_cache_count); - //obdfs_flush_dirty_pages(~0UL); - CERROR("-- count %ld\n", obdfs_cache_count); - } -} - - - -/* select between SYNC and ASYNC I/O methods */ -int obdfs_do_writepage(struct page *page, int sync) -{ - struct inode *inode = page->mapping->host; - int err; - - ENTRY; - if ( sync ) - err = obdfs_brw(OBD_BRW_WRITE, inode, page, 1); - else { - err = obdfs_add_page_to_cache(inode, page); - CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n", - inode->i_ino, page, err, Page_Uptodate(page)); - } - - if ( !err ) { - SetPageUptodate(page); - set_page_clean(page); - } - EXIT; - return err; -} /* obdfs_do_writepage */ - - - - -#endif - -int obdfs_commit_write(struct file *file, struct page *page, unsigned from, unsigned to) -{ - struct inode *inode = page->mapping->host; - int rc = 0; - loff_t len = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; - ENTRY; - CDEBUG(D_INODE, "commit write ino %ld (end at %Ld) from %d to %d ,ind %ld\n", - inode->i_ino, len, from, to, page->index); - - - if (cache_writes == 0) { - rc = obdfs_commit_page(page, 1, from, to); - } - - if (len > inode->i_size) { - obdfs_set_size(inode, len); - } - - kunmap(page); - EXIT; - return rc; -} - - -/* - * This does the "real" work of the write. The generic routine has - * allocated the page, locked it, done all the page alignment stuff - * calculations etc. Now we should just copy the data from user - * space and write it back to the real medium.. - * - * If the writer ends up delaying the write, the writer needs to - * increment the page use counts until he is done with the page. - * - * Return value is the number of bytes written. - */ -int obdfs_write_one_page(struct file *file, struct page *page, - unsigned long offset, unsigned long bytes, - const char * buf) -{ - struct inode *inode = file->f_dentry->d_inode; - int err; - - ENTRY; - /* We check for complete page writes here, as we then don't have to - * get the page before writing over everything anyways. - */ - if (!Page_Uptodate(page) && (offset != 0 || bytes != PAGE_SIZE)) { - err = obdfs_brw(OBD_BRW_READ, inode, page, 0); - if ( err ) - return err; - SetPageUptodate(page); - } - - if (copy_from_user((u8*)page_address(page) + offset, buf, bytes)) - return -EFAULT; - - lock_kernel(); - err = obdfs_writepage(page); - unlock_kernel(); - - return (err < 0 ? err : bytes); -} /* obdfs_write_one_page */ - -/* - * return an up to date page: - * - if locked is true then is returned locked - * - if create is true the corresponding disk blocks are created - * - page is held, i.e. caller must release the page - * - * modeled on NFS code. - */ -struct page *obdfs_getpage(struct inode *inode, unsigned long offset, - int create, int locked) -{ - struct page * page; - int index; - int err; - - ENTRY; - - offset = offset & PAGE_CACHE_MASK; - CDEBUG(D_INFO, "ino: %ld, offset %ld, create %d, locked %d\n", - inode->i_ino, offset, create, locked); - index = offset >> PAGE_CACHE_SHIFT; - - page = grab_cache_page(&inode->i_data, index); - - /* Yuck, no page */ - if (! page) { - CERROR("grab_cache_page says no dice ...\n"); - EXIT; - return NULL; - } - - /* now check if the data in the page is up to date */ - if ( Page_Uptodate(page)) { - if (!locked) { - if (PageLocked(page)) - UnlockPage(page); - } else { - CERROR("expecting locked page\n"); - } - EXIT; - return page; - } - - err = obdfs_brw(OBD_BRW_READ, inode, page, create); - - if ( err ) { - SetPageError(page); - UnlockPage(page); - EXIT; - return page; - } - - if ( !locked ) - UnlockPage(page); - SetPageUptodate(page); - EXIT; - return page; -} /* obdfs_getpage */ - - -void obdfs_truncate(struct inode *inode) -{ - struct obdo *oa; - int err; - ENTRY; - - //obdfs_dequeue_pages(inode); - oa = obdo_alloc(); - if ( !oa ) { - err = -ENOMEM; - CERROR("obdo_alloc failed!\n"); - } else { - oa->o_valid = OBD_MD_FLNOTOBD; - obdfs_from_inode(oa, inode); - - CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n", - (long)oa->o_id, (unsigned long long)oa->o_size); - err = obd_punch(IID(inode), oa, oa->o_size, 0); - - obdo_free(oa); - } - - if (err) { - CERROR("obd_truncate fails (%d)\n", err); - EXIT; - return; - } - EXIT; -} /* obdfs_truncate */ - -struct address_space_operations obdfs_aops = { - readpage: obdfs_readpage, - writepage: obdfs_writepage, - sync_page: block_sync_page, - prepare_write: obdfs_prepare_write, - commit_write: obdfs_commit_write, - bmap: NULL -}; diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c deleted file mode 100644 index cbac1bd..0000000 --- a/lustre/obdfs/super.c +++ /dev/null @@ -1,516 +0,0 @@ - -/* - * OBDFS Super operations - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copryright (C) 1996 Peter J. Braam - * Copryright (C) 1999 Stelias Computing Inc. - * Copryright (C) 1999 Seagate Technology Inc. - * Copryright (C) 2001 Mountain View Data, Inc. - * Copryright (C) 2002 Cluster File Systems, Inc. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_OBDFS - -#include -#include -#include - -struct list_head obdfs_super_list; -extern struct address_space_operations obdfs_aops; -struct super_operations obdfs_super_operations; -long obdfs_cache_count = 0; -long obdfs_mutex_start = 0; - -static char *obdfs_read_opt(const char *opt, char *data) -{ - char *value; - char *retval; - - CDEBUG(D_INFO, "option: %s, data %s\n", opt, data); - if ( strncmp(opt, data, strlen(opt)) ) - return NULL; - - if ( (value = strchr(data, '=')) == NULL ) - return NULL; - - value++; - OBD_ALLOC(retval, strlen(value) + 1); - if ( !retval ) { - CERROR("out of memory!\n"); - return NULL; - } - - memcpy(retval, value, strlen(value)+1); - CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval); - return retval; -} - -static void obdfs_options(char *options, char **dev, char **vers) -{ - char *this_char; - - if (!options) - return; - - for (this_char = strtok (options, ","); - this_char != NULL; - this_char = strtok (NULL, ",")) { - CDEBUG(D_INFO, "this_char %s\n", this_char); - if ( (!*dev && (*dev = obdfs_read_opt("device", this_char)))|| - (!*vers && (*vers = obdfs_read_opt("version", this_char))) ) - continue; - - } -} - -static struct super_block * obdfs_read_super(struct super_block *sb, - void *data, int silent) -{ - struct inode *root = 0; - struct obdfs_sb_info *sbi = (struct obdfs_sb_info *)(&sb->u.generic_sbp); - struct obd_device *obddev; - char *device = NULL; - char *version = NULL; - int connected = 0; - int devno; - int err; - unsigned long blocksize; - unsigned long blocksize_bits; - obd_id root_ino; - int scratch; - struct obdo *oa; - - ENTRY; - MOD_INC_USE_COUNT; - - memset(sbi, 0, sizeof(*sbi)); - - CDEBUG(D_INFO, "\n"); - obdfs_options(data, &device, &version); - if (!device) { - CERROR("no device\n"); - EXIT; - goto ERR; - } - - devno = simple_strtoul(device, NULL, 0); - CDEBUG(D_INFO, "\n"); - if (devno >= MAX_OBD_DEVICES) { - CERROR("device of %s too high (%d)\n", device, devno); - EXIT; - goto ERR; - } - - CDEBUG(D_INFO, "\n"); - - obddev = &obd_dev[devno]; - sbi->osi_obd = obddev; - - err = obd_connect(&sbi->osi_conn, obddev); - if (err) { - CERROR("OBDFS: cannot connect to %s\n", device); - EXIT; - goto ERR; - } - - connected = 1; - CDEBUG(D_INFO, "\n"); - /* list of dirty inodes, and a mutex to hold while modifying it */ - INIT_LIST_HEAD(&sbi->osi_inodes); - init_MUTEX (&sbi->osi_list_mutex); - - CDEBUG(D_INFO, "\n"); - sbi->osi_super = sb; - - CDEBUG(D_INFO, "\n"); - err = obd_get_info(&sbi->osi_conn, strlen("blocksize"), - "blocksize", &scratch, - (void *)&blocksize); - if (err) { - CERROR("getinfo call to drive failed (blocksize)\n"); - EXIT; - goto ERR; - } - - CDEBUG(D_INFO, "\n"); - err = obd_get_info(&sbi->osi_conn, strlen("blocksize_bits"), - "blocksize_bits", &scratch, - (void *)&blocksize_bits); - if (err) { - CERROR("getinfo call to drive failed (blocksize_bits)\n"); - EXIT; - goto ERR; - } - - CDEBUG(D_INFO, "\n"); - err = obd_get_info(&sbi->osi_conn, strlen("root_ino"), - "root_ino", &scratch, (void *)&root_ino); - if (err) { - CERROR("getinfo call to drive failed (root_ino)\n"); - EXIT; - goto ERR; - } - - CDEBUG(D_INFO, "\n"); - sb->s_maxbytes = 1LL << 36; - CERROR("Max bytes: %Lx\n", sb->s_maxbytes); - sb->s_blocksize = PAGE_SIZE; - sb->s_blocksize_bits = (unsigned char)PAGE_SHIFT; - sb->s_magic = OBDFS_SUPER_MAGIC; - sb->s_op = &obdfs_super_operations; - - /* XXX how to get "sb->s_flags |= MS_RDONLY" here for snapshots? */ - - /* make root inode */ - CDEBUG(D_INFO, "\n"); - oa = obdo_fromid(&sbi->osi_conn, root_ino, S_IFDIR, - (__u32)(OBD_MD_FLNOTOBD | OBD_MD_FLBLOCKS)); - CDEBUG(D_INFO, "mode %o\n", oa->o_mode); - if (IS_ERR(oa)) { - CERROR("obdo_fromid failed\n"); - iput(root); - EXIT; - goto ERR; - } - CDEBUG(D_INFO, "\n"); - root = iget4(sb, (ino_t)root_ino, NULL, oa); - obdo_free(oa); - CDEBUG(D_INFO, "\n"); - if (!root) { - CERROR("OBDFS: bad iget4 for root\n"); - sb->s_dev = 0; - err = -ENOENT; - EXIT; - goto ERR; - } - - CDEBUG(D_INFO, "sbdev %d, rootino: %Ld, dev %s, " - "minor: %d, blocksize: %ld, blocksize bits %ld\n", - sb->s_dev, (long long)root_ino, device, MINOR(devno), - blocksize, blocksize_bits); - sb->s_root = d_alloc_root(root); - list_add(&sbi->osi_list, &obdfs_super_list); - OBD_FREE(device, strlen(device) + 1); - if (version) - OBD_FREE(version, strlen(version) + 1); - EXIT; - return sb; - -ERR: - MOD_DEC_USE_COUNT; - if (device) - OBD_FREE(device, strlen(device) + 1); - if (version) - OBD_FREE(version, strlen(version) + 1); - if (connected) - obd_disconnect(&sbi->osi_conn); - - if (sbi) { - sbi->osi_super = NULL; - } - if (root) { - iput(root); - } - sb->s_dev = 0; - return NULL; -} /* obdfs_read_super */ - - -static void obdfs_put_super(struct super_block *sb) -{ - struct obdfs_sb_info *sbi; - - ENTRY; - sb->s_dev = 0; - - sbi = (struct obdfs_sb_info *) &sb->u.generic_sbp; - //obdfs_flush_reqs(&sbi->osi_inodes, ~0UL); - - obd_disconnect(ID(sb)); - list_del(&sbi->osi_list); - - CERROR("OBDFS: Bye bye.\n"); - - MOD_DEC_USE_COUNT; - EXIT; -} /* obdfs_put_super */ - - -void obdfs_do_change_inode(struct inode *inode, int valid) -{ - struct obdo *oa; - int err; - - ENTRY; - oa = obdo_alloc(); - if ( !oa ) { - CERROR("obdo_alloc failed\n"); - EXIT; - return; - } - - oa->o_valid = OBD_MD_FLNOTOBD & (valid | OBD_MD_FLID); - obdfs_from_inode(oa, inode); - oa->o_mode = inode->i_mode; - err = obd_setattr(IID(inode), oa); - - if ( err ) - CERROR("obd_setattr fails (%d)\n", err); - - EXIT; - obdo_free(oa); -} /* obdfs_write_inode */ - -void obdfs_change_inode(struct inode *inode, int mask) -{ - return obdfs_do_change_inode(inode, OBD_MD_FLNLINK); -} - - -extern void write_inode_pages(struct inode *); -/* This routine is called from iput() (for each unlink on the inode). - * We can't put this call into delete_inode() since that is called only - * when i_count == 0, and we need to keep a reference on the inode while - * it is in the page cache, which means i_count > 0. Catch 22. - */ -static void obdfs_put_inode(struct inode *inode) -{ - ENTRY; - if (inode->i_nlink && (atomic_read(&inode->i_count) == 1)) { - write_inode_pages(inode); - EXIT; - return; - } - - //obdfs_dequeue_pages(inode); - EXIT; -} /* obdfs_put_inode */ - - -static void obdfs_delete_inode(struct inode *inode) -{ - obdfs_do_change_inode(inode, ~0); - clear_inode(inode); -} -#if 0 -{ - struct obdo *oa; - int err; - - ENTRY; - oa = obdo_alloc(); - if ( !oa ) { - CERROR("obdo_alloc failed\n"); - EXIT; - return; - } - oa->o_valid = OBD_MD_FLNOTOBD; - obdfs_from_inode(oa, inode); - - /* XXX how do we know that this inode is now clean? */ - CERROR("delete_inode ------> link %d\n", inode->i_nlink); - ODEBUG(oa); - err = obd_destroy(IID(inode), oa); - obdo_free(oa); - clear_inode(inode); - if (err) { - CERROR("obd_destroy fails (%d)\n", err); - EXIT; - return; - } - - EXIT; -} /* obdfs_delete_inode */ -#endif - - -static int obdfs_attr2inode(struct inode * inode, struct iattr * attr) -{ - unsigned int ia_valid = attr->ia_valid; - int error = 0; - - if (ia_valid & ATTR_SIZE) { - error = vmtruncate(inode, attr->ia_size); - if (error) - goto out; - } - - if (ia_valid & ATTR_UID) - inode->i_uid = attr->ia_uid; - if (ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; - if (ia_valid & ATTR_ATIME) - inode->i_atime = attr->ia_atime; - if (ia_valid & ATTR_MTIME) - inode->i_mtime = attr->ia_mtime; - if (ia_valid & ATTR_CTIME) - inode->i_ctime = attr->ia_ctime; - if (ia_valid & ATTR_MODE) { - inode->i_mode = attr->ia_mode; - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) - inode->i_mode &= ~S_ISGID; - } -out: - return error; -} - -int obdfs_setattr(struct dentry *de, struct iattr *attr) -{ - struct inode *inode = de->d_inode; - struct obdo *oa; - int err; - - ENTRY; - oa = obdo_alloc(); - if ( !oa ) { - CERROR("obdo_alloc failed\n"); - return -ENOMEM; - } - - obdfs_attr2inode(inode, attr); - oa->o_id = inode->i_ino; - oa->o_mode = inode->i_mode; - obdo_from_iattr(oa, attr); - err = obd_setattr(IID(inode), oa); - - if ( err ) - CERROR("obd_setattr fails (%d)\n", err); - - EXIT; - obdo_free(oa); - return err; -} /* obdfs_setattr */ - - - -static int obdfs_statfs(struct super_block *sb, struct statfs *sfs) -{ - int rc; - - ENTRY; - - rc = obd_statfs(ID(sb), sfs); - if (rc) - CERROR("obd_statfs fails: rc = %d\n", rc); - else - CDEBUG(D_SUPER, "statfs returns avail %ld\n", sfs->f_bavail); - - RETURN(rc); -} - -static inline void obdfs_read_inode2(struct inode *inode, void *opaque) -{ - struct obdo *oa = opaque; - - ENTRY; - obdfs_to_inode(inode, oa); - - INIT_LIST_HEAD(obdfs_iplist(inode)); /* list of dirty pages on inode */ - INIT_LIST_HEAD(obdfs_islist(inode)); /* list of inodes in superblock */ - - /* OIDEBUG(inode); */ - - if (S_ISREG(inode->i_mode)) { - inode->i_op = &obdfs_file_inode_operations; - inode->i_fop = &obdfs_file_operations; - inode->i_mapping->a_ops = &obdfs_aops; - EXIT; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &obdfs_dir_inode_operations; - inode->i_fop = &obdfs_dir_operations; - inode->i_mapping->a_ops = &obdfs_aops; - EXIT; - } else if (S_ISLNK(inode->i_mode)) { - if (inode->i_blocks) { - inode->i_op = &obdfs_symlink_inode_operations; - inode->i_mapping->a_ops = &obdfs_aops; - }else { - inode->i_op = &obdfs_fast_symlink_inode_operations; - } - EXIT; - } else { - init_special_inode(inode, inode->i_mode, - ((int *)obdfs_i2info(inode)->oi_inline)[0]); - } - - EXIT; - return; -} - -/* exported operations */ -struct super_operations obdfs_super_operations = -{ - read_inode2: obdfs_read_inode2, - put_inode: obdfs_put_inode, - delete_inode: obdfs_delete_inode, - put_super: obdfs_put_super, - statfs: obdfs_statfs -}; - - -struct file_system_type obdfs_fs_type = { - "obdfs", 0, obdfs_read_super, NULL -}; - -int init_obdfs(void) -{ - //int err; - - printk(KERN_INFO "OBDFS v0.1, info@clusterfs.com\n"); - - obdfs_sysctl_init(); - - INIT_LIST_HEAD(&obdfs_super_list); - //err = obdfs_init_pgrqcache(); - //if (err) - //return err; - - //obdfs_flushd_init(); - return register_filesystem(&obdfs_fs_type); -} - - - - -#ifdef MODULE -int init_module(void) -{ - return init_obdfs(); -} - -void cleanup_module(void) -{ - ENTRY; - - //obdfs_flushd_cleanup(); - obdfs_sysctl_clean(); - //obdfs_cleanup_pgrqcache(); - unregister_filesystem(&obdfs_fs_type); - CDEBUG(D_MALLOC, "OBDFS mem used %ld\n", obd_memory); - EXIT; -} - -#endif diff --git a/lustre/obdfs/symlink.c b/lustre/obdfs/symlink.c deleted file mode 100644 index c5c851b..0000000 --- a/lustre/obdfs/symlink.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * linux/fs/ext2/symlink.c - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/fs/minix/symlink.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * ext2 symlink handling code - * - * Modified for OBDFS. - * Re-written Oct 2001. - * - * Copyright (C) 2001 Cluster File Systems, Inc. (author: braam@clusterfs.com) - */ - -#include -#include -#include -#include - -#define DEBUG_SUBSYSTEM S_OBDFS - -#include /* for ENTRY and EXIT only */ -#include - -static int obdfs_fast_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - char *s = obdfs_i2info(dentry->d_inode)->oi_inline; - return vfs_readlink(dentry, buffer, buflen, s); -} - -static int obdfs_fast_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - char *s = obdfs_i2info(dentry->d_inode)->oi_inline; - return vfs_follow_link(nd, s); -} - -extern int obdfs_setattr(struct dentry *de, struct iattr *attr); -struct inode_operations obdfs_fast_symlink_inode_operations = { - readlink: obdfs_fast_readlink, - follow_link: obdfs_fast_follow_link, - setattr: obdfs_setattr -}; - -static int obdfs_readlink(struct dentry *dentry, char *buffer, int buflen) -{ - struct page *page = NULL; - int res; - - ENTRY; - page = obdfs_getpage(dentry->d_inode, 0, 0, 0); - if (!page) { - EXIT; - return 0; - } - res = vfs_readlink(dentry, buffer, buflen, (char *)page_address(page)); - page_cache_release(page); - EXIT; - return res; -} /* obdfs_readlink */ - -static int obdfs_follow_link(struct dentry * dentry, - struct nameidata *nd) -{ - struct page *page = NULL; - int res; - - ENTRY; - page = obdfs_getpage(dentry->d_inode, 0, 0, 0); - if (!page) { - dput(nd->dentry); - EXIT; - return -EIO; - } - res = vfs_follow_link(nd, (char *)page_address(page)); - page_cache_release(page); - EXIT; - return res; -} - -struct inode_operations obdfs_symlink_inode_operations = { - readlink: obdfs_readlink, - follow_link: obdfs_follow_link, - setattr: obdfs_setattr -}; diff --git a/lustre/obdfs/sysctl.c b/lustre/obdfs/sysctl.c deleted file mode 100644 index c03b0289..0000000 --- a/lustre/obdfs/sysctl.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2001 Cluster File Systems, Inc. - * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -struct ctl_table_header *obdfs_table_header = NULL; - -int obdfs_debug_level = 0; -int obdfs_print_entry = 1; - - -#define OBDFS_SYSCTL 1 - -#define OBDFS_DEBUG 1 /* control debugging */ -#define OBDFS_ENTRY 2 /* control enter/leave pattern */ -#define OBDFS_TIMEOUT 3 /* timeout on upcalls to become intrble */ -#define OBDFS_HARD 4 /* mount type "hard" or "soft" */ -#define OBDFS_VARS 5 -#define OBDFS_INDEX 6 -#define OBDFS_RESET 7 - -#define OBDFS_VARS_SLOT 2 - -static ctl_table obdfs_table[] = { - {OBDFS_DEBUG, "debug", &obdfs_debug_level, sizeof(int), 0644, NULL, &proc_dointvec}, - {OBDFS_ENTRY, "trace", &obdfs_print_entry, sizeof(int), 0644, NULL, &proc_dointvec}, - { 0 } -}; - -static ctl_table top_table[] = { - {OBDFS_SYSCTL, "obdfs", NULL, 0, 0555, obdfs_table}, - {0} -}; - -void obdfs_sysctl_init (void) -{ - -#ifdef CONFIG_SYSCTL - if ( !obdfs_table_header ) - obdfs_table_header = register_sysctl_table(top_table, 0); -#endif -} - -void obdfs_sysctl_clean (void) -{ -#ifdef CONFIG_SYSCTL - if ( obdfs_table_header ) - unregister_sysctl_table(obdfs_table_header); - obdfs_table_header = NULL; -#endif -}