Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
Browse files Browse the repository at this point in the history
* 'for-linus' of git://git.open-osd.org/linux-open-osd:
  exofs: deprecate the commands pending counter
  exofs: Write sbi->s_nextid as part of the Create command
  exofs: Add option to mount by osdname
  exofs: Override read-ahead to align on stripe_size
  exofs: simple fsync race fix
  exofs: Optimize read_4_write
  exofs: Trivial: fix some indentation and debug prints
  exofs: Remove redundant unlikely()
  • Loading branch information
Linus Torvalds committed Mar 24, 2011
2 parents 4cc4d24 + a49fb4c commit 1b506cf
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 65 deletions.
10 changes: 9 additions & 1 deletion Documentation/filesystems/exofs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,15 @@ Where:
exofs specific options: Options are separated by commas (,)
pid=<integer> - The partition number to mount/create as
container of the filesystem.
This option is mandatory.
This option is mandatory. integer can be
Hex by pre-pending an 0x to the number.
osdname=<id> - Mount by a device's osdname.
osdname is usually a 36 character uuid of the
form "d2683732-c906-4ee1-9dbd-c10c27bb40df".
It is one of the device's uuid specified in the
mkfs.exofs format command.
If this option is specified then the /dev/osdX
above can be empty and is ignored.
to=<integer> - Timeout in ticks for a single command.
default is (60 * HZ) [for debugging only]

Expand Down
18 changes: 16 additions & 2 deletions fs/exofs/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@
#define EXOFS_ROOT_ID 0x10002 /* object ID for root directory */

/* exofs Application specific page/attribute */
/* Inode attrs */
# define EXOFS_APAGE_FS_DATA (OSD_APAGE_APP_DEFINED_FIRST + 3)
# define EXOFS_ATTR_INODE_DATA 1
# define EXOFS_ATTR_INODE_FILE_LAYOUT 2
# define EXOFS_ATTR_INODE_DIR_LAYOUT 3
/* Partition attrs */
# define EXOFS_APAGE_SB_DATA (0xF0000000U + 3)
# define EXOFS_ATTR_SB_STATS 1

/*
* The maximum number of files we can have is limited by the size of the
Expand Down Expand Up @@ -86,8 +90,8 @@ enum {
*/
enum {EXOFS_FSCB_VER = 1, EXOFS_DT_VER = 1};
struct exofs_fscb {
__le64 s_nextid; /* Highest object ID used */
__le64 s_numfiles; /* Number of files on fs */
__le64 s_nextid; /* Only used after mkfs */
__le64 s_numfiles; /* Only used after mkfs */
__le32 s_version; /* == EXOFS_FSCB_VER */
__le16 s_magic; /* Magic signature */
__le16 s_newfs; /* Non-zero if this is a new fs */
Expand All @@ -97,6 +101,16 @@ struct exofs_fscb {
__le64 s_dev_table_count; /* == 0 means no dev_table */
} __packed;

/*
* This struct is set on the FS partition's attributes.
* [EXOFS_APAGE_SB_DATA, EXOFS_ATTR_SB_STATS] and is written together
* with the create command, to atomically persist the sb writeable information.
*/
struct exofs_sb_stats {
__le64 s_nextid; /* Highest object ID used */
__le64 s_numfiles; /* Number of files on fs */
} __packed;

/*
* Describes the raid used in the FS. It is part of the device table.
* This here is taken from the pNFS-objects definition. In exofs we
Expand Down
33 changes: 18 additions & 15 deletions fs/exofs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static void exofs_check_page(struct page *page)

Ebadsize:
EXOFS_ERR("ERROR [exofs_check_page]: "
"size of directory #%lu is not a multiple of chunk size",
"size of directory(0x%lx) is not a multiple of chunk size\n",
dir->i_ino
);
goto fail;
Expand All @@ -142,17 +142,17 @@ static void exofs_check_page(struct page *page)
goto bad_entry;
bad_entry:
EXOFS_ERR(
"ERROR [exofs_check_page]: bad entry in directory #%lu: %s - "
"offset=%lu, inode=%llu, rec_len=%d, name_len=%d",
"ERROR [exofs_check_page]: bad entry in directory(0x%lx): %s - "
"offset=%lu, inode=0x%llu, rec_len=%d, name_len=%d\n",
dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
_LLU(le64_to_cpu(p->inode_no)),
rec_len, p->name_len);
goto fail;
Eend:
p = (struct exofs_dir_entry *)(kaddr + offs);
EXOFS_ERR("ERROR [exofs_check_page]: "
"entry in directory #%lu spans the page boundary"
"offset=%lu, inode=%llu",
"entry in directory(0x%lx) spans the page boundary"
"offset=%lu, inode=0x%llx\n",
dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
_LLU(le64_to_cpu(p->inode_no)));
fail:
Expand Down Expand Up @@ -261,9 +261,8 @@ exofs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct page *page = exofs_get_page(inode, n);

if (IS_ERR(page)) {
EXOFS_ERR("ERROR: "
"bad page in #%lu",
inode->i_ino);
EXOFS_ERR("ERROR: bad page in directory(0x%lx)\n",
inode->i_ino);
filp->f_pos += PAGE_CACHE_SIZE - offset;
return PTR_ERR(page);
}
Expand All @@ -283,7 +282,8 @@ exofs_readdir(struct file *filp, void *dirent, filldir_t filldir)
for (; (char *)de <= limit; de = exofs_next_entry(de)) {
if (de->rec_len == 0) {
EXOFS_ERR("ERROR: "
"zero-length directory entry");
"zero-length entry in directory(0x%lx)\n",
inode->i_ino);
exofs_put_page(page);
return -EIO;
}
Expand Down Expand Up @@ -342,9 +342,9 @@ struct exofs_dir_entry *exofs_find_entry(struct inode *dir,
kaddr += exofs_last_byte(dir, n) - reclen;
while ((char *) de <= kaddr) {
if (de->rec_len == 0) {
EXOFS_ERR(
"ERROR: exofs_find_entry: "
"zero-length directory entry");
EXOFS_ERR("ERROR: zero-length entry in "
"directory(0x%lx)\n",
dir->i_ino);
exofs_put_page(page);
goto out;
}
Expand Down Expand Up @@ -472,7 +472,8 @@ int exofs_add_link(struct dentry *dentry, struct inode *inode)
}
if (de->rec_len == 0) {
EXOFS_ERR("ERROR: exofs_add_link: "
"zero-length directory entry");
"zero-length entry in directory(0x%lx)\n",
inode->i_ino);
err = -EIO;
goto out_unlock;
}
Expand All @@ -491,7 +492,8 @@ int exofs_add_link(struct dentry *dentry, struct inode *inode)
exofs_put_page(page);
}

EXOFS_ERR("exofs_add_link: BAD dentry=%p or inode=%p", dentry, inode);
EXOFS_ERR("exofs_add_link: BAD dentry=%p or inode=0x%lx\n",
dentry, inode->i_ino);
return -EINVAL;

got_it:
Expand Down Expand Up @@ -542,7 +544,8 @@ int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page)
while (de < dir) {
if (de->rec_len == 0) {
EXOFS_ERR("ERROR: exofs_delete_entry:"
"zero-length directory entry");
"zero-length entry in directory(0x%lx)\n",
inode->i_ino);
err = -EIO;
goto out;
}
Expand Down
6 changes: 4 additions & 2 deletions fs/exofs/exofs.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct exofs_layout {
* our extension to the in-memory superblock
*/
struct exofs_sb_info {
struct exofs_fscb s_fscb; /* Written often, pre-allocate*/
struct exofs_sb_stats s_ess; /* Written often, pre-allocate*/
int s_timeout; /* timeout for OSD operations */
uint64_t s_nextid; /* highest object ID used */
uint32_t s_numfiles; /* number of files on fs */
Expand Down Expand Up @@ -256,6 +256,8 @@ static inline int exofs_oi_read(struct exofs_i_info *oi,
}

/* inode.c */
unsigned exofs_max_io_pages(struct exofs_layout *layout,
unsigned expected_pages);
int exofs_setattr(struct dentry *, struct iattr *);
int exofs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
Expand All @@ -279,7 +281,7 @@ int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *,
struct inode *);

/* super.c */
int exofs_sync_fs(struct super_block *sb, int wait);
int exofs_sbi_write_stats(struct exofs_sb_info *sbi);

/*********************
* operation vectors *
Expand Down
16 changes: 1 addition & 15 deletions fs/exofs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,8 @@ static int exofs_release_file(struct inode *inode, struct file *filp)
static int exofs_file_fsync(struct file *filp, int datasync)
{
int ret;
struct inode *inode = filp->f_mapping->host;
struct super_block *sb;

if (!(inode->i_state & I_DIRTY))
return 0;
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
return 0;

ret = sync_inode_metadata(inode, 1);

/* This is a good place to write the sb */
/* TODO: Sechedule an sb-sync on create */
sb = inode->i_sb;
if (sb->s_dirt)
exofs_sync_fs(sb, 1);

ret = sync_inode_metadata(filp->f_mapping->host, 1);
return ret;
}

Expand Down
51 changes: 42 additions & 9 deletions fs/exofs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ enum { BIO_MAX_PAGES_KMALLOC =
PAGE_SIZE / sizeof(struct page *),
};

unsigned exofs_max_io_pages(struct exofs_layout *layout,
unsigned expected_pages)
{
unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC);

/* TODO: easily support bio chaining */
pages = min_t(unsigned, pages,
layout->group_width * BIO_MAX_PAGES_KMALLOC);
return pages;
}

struct page_collect {
struct exofs_sb_info *sbi;
struct inode *inode;
Expand Down Expand Up @@ -97,8 +108,7 @@ static void _pcol_reset(struct page_collect *pcol)

static int pcol_try_alloc(struct page_collect *pcol)
{
unsigned pages = min_t(unsigned, pcol->expected_pages,
MAX_PAGES_KMALLOC);
unsigned pages;

if (!pcol->ios) { /* First time allocate io_state */
int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios);
Expand All @@ -108,8 +118,7 @@ static int pcol_try_alloc(struct page_collect *pcol)
}

/* TODO: easily support bio chaining */
pages = min_t(unsigned, pages,
pcol->sbi->layout.group_width * BIO_MAX_PAGES_KMALLOC);
pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages);

for (; pages; pages >>= 1) {
pcol->pages = kmalloc(pages * sizeof(struct page *),
Expand Down Expand Up @@ -350,8 +359,10 @@ static int readpage_strip(void *data, struct page *page)

if (!pcol->read_4_write)
unlock_page(page);
EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page,"
" splitting\n", inode->i_ino, page->index);
EXOFS_DBGMSG("readpage_strip(0x%lx) empty page len=%zx "
"read_4_write=%d index=0x%lx end_index=0x%lx "
"splitting\n", inode->i_ino, len,
pcol->read_4_write, page->index, end_index);

return read_exec(pcol);
}
Expand Down Expand Up @@ -722,11 +733,28 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,

/* read modify write */
if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) {
loff_t i_size = i_size_read(mapping->host);
pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
size_t rlen;

if (page->index < end_index)
rlen = PAGE_CACHE_SIZE;
else if (page->index == end_index)
rlen = i_size & ~PAGE_CACHE_MASK;
else
rlen = 0;

if (!rlen) {
clear_highpage(page);
SetPageUptodate(page);
goto out;
}

ret = _readpage(page, true);
if (ret) {
/*SetPageError was done by _readpage. Is it ok?*/
unlock_page(page);
EXOFS_DBGMSG("__readpage_filler failed\n");
EXOFS_DBGMSG("__readpage failed\n");
}
}
out:
Expand Down Expand Up @@ -1030,6 +1058,7 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino)
memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data));
}

inode->i_mapping->backing_dev_info = sb->s_bdi;
if (S_ISREG(inode->i_mode)) {
inode->i_op = &exofs_file_inode_operations;
inode->i_fop = &exofs_file_operations;
Expand Down Expand Up @@ -1073,6 +1102,7 @@ int __exofs_wait_obj_created(struct exofs_i_info *oi)
}
return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0;
}

/*
* Callback function from exofs_new_inode(). The important thing is that we
* set the obj_created flag so that other methods know that the object exists on
Expand Down Expand Up @@ -1130,7 +1160,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)

sbi = sb->s_fs_info;

sb->s_dirt = 1;
inode->i_mapping->backing_dev_info = sb->s_bdi;
inode_init_owner(inode, dir, mode);
inode->i_ino = sbi->s_nextid++;
inode->i_blkbits = EXOFS_BLKSHIFT;
Expand All @@ -1141,6 +1171,8 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)
spin_unlock(&sbi->s_next_gen_lock);
insert_inode_hash(inode);

exofs_sbi_write_stats(sbi); /* Make sure new sbi->s_nextid is on disk */

mark_inode_dirty(inode);

ret = exofs_get_io_state(&sbi->layout, &ios);
Expand Down Expand Up @@ -1271,7 +1303,8 @@ static int exofs_update_inode(struct inode *inode, int do_sync)

int exofs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
/* FIXME: fix fsync and use wbc->sync_mode == WB_SYNC_ALL */
return exofs_update_inode(inode, 1);
}

/*
Expand Down
Loading

0 comments on commit 1b506cf

Please sign in to comment.