return &(ll_i2sbi(inode))->ll_conn;
}
-
-
-
-
-/* super.c */
-struct ll_pgrq {
- struct list_head rq_plist; /* linked list of req's */
- unsigned long rq_jiffies;
- struct page *rq_page; /* page to be written */
-};
-
-extern struct list_head ll_super_list; /* list of all LL superblocks */
-
-
-
/* dir.c */
-#define EXT2_DIR_PAD 4
-#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
-#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
- ~EXT2_DIR_ROUND)
-#define EXT2_NAME_LEN 255
-
-int ll_check_dir_entry (const char * function, struct inode * dir,
- struct ext2_dir_entry_2 * de, struct page * page,
- unsigned long offset);
extern struct file_operations ll_dir_operations;
extern struct inode_operations ll_dir_inode_operations;
extern struct file_operations ll_file_operations;
extern struct inode_operations ll_file_inode_operations;
-/* flush.c */
-void ll_dequeue_pages(struct inode *inode);
-int ll_flushd_init(void);
-int ll_flushd_cleanup(void);
-int ll_flush_reqs(struct list_head *inode_list, unsigned long check_time);
-int ll_flush_dirty_pages(unsigned long check_time);
-
-/* namei.c */
-/*
- * Structure of the super block
- */
-
-
-#define EXT2_SB(sb) (&((sb)->u.ext2_sb))
-/*
- * Maximal count of links to a file
- */
-#define EXT2_LINK_MAX 32000
-/*
- * Ext2 directory file types. Only the low 3 bits are used. The
- * other bits are reserved for now.
- */
-#define EXT2_FT_UNKNOWN 0
-#define EXT2_FT_REG_FILE 1
-#define EXT2_FT_DIR 2
-#define EXT2_FT_CHRDEV 3
-#define EXT2_FT_BLKDEV 4
-#define EXT2_FT_FIFO 5
-#define EXT2_FT_SOCK 6
-#define EXT2_FT_SYMLINK 7
-
-#define EXT2_FT_MAX 8
-
-#define EXT2_BTREE_FL 0x00001000 /* btree format dir */
-#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
-#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
-#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
-#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
-
/* rw.c */
-int ll_do_writepage(struct page *, int sync);
-int ll_init_pgrqcache(void);
-void ll_cleanup_pgrqcache(void);
-inline void ll_pgrq_del(struct ll_pgrq *pgrq);
-int ll_readpage(struct file *file, struct page *page);
-int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to);
-int ll_commit_write(struct file *file, struct page *page, unsigned from, unsigned to);
-int ll_writepage(struct page *page);
struct page *ll_getpage(struct inode *inode, unsigned long offset,
int create, int locked);
-int ll_write_one_page(struct file *file, struct page *page,
- unsigned long offset, unsigned long bytes,
- const char * buf);
-int ll_do_vec_wr(struct inode **inodes, obd_count num_io, obd_count num_oa,
- struct obdo **obdos, obd_count *oa_bufs,
- struct page **pages, char **bufs, obd_size *counts,
- obd_off *offsets, obd_flag *flags);
void ll_truncate(struct inode *inode);
-/* super.c */
-extern long ll_cache_count;
-extern long ll_mutex_start;
-
/* symlink.c */
extern struct inode_operations ll_fast_symlink_inode_operations;
extern struct inode_operations ll_symlink_inode_operations;
#define DEBUG_SUBSYSTEM S_OST
-#include <linux/obd_support.h>
#include <linux/obd_class.h>
#include <linux/lustre_lib.h>
-#include <linux/lustre_idl.h>
-#include <linux/lustre_mds.h>
-#include <linux/lustre_light.h>
/*
* Remove page from dirty list
}
if (Page_Uptodate(page)) {
+ CERROR("Explain this please?\n");
EXIT;
goto readpage_out;
}
buf, &request);
kunmap(page);
ptlrpc_free_req(request);
+ EXIT;
+
+ readpage_out:
if ( !rc )
SetPageUptodate(page);
- EXIT;
- readpage_out:
UnlockPage(page);
return rc;
} /* ll_dir_readpage */
#include <linux/lustre_light.h>
extern int ll_setattr(struct dentry *de, struct iattr *attr);
+extern inline struct obdo * ll_oa_from_inode(struct inode *inode, int valid);
static int ll_file_open(struct inode *inode, struct file *file)
{
int flags = 0;
struct ptlrpc_request *req;
struct ll_file_data *fd;
- struct obdo oa;
+ struct obdo *oa;
struct ll_sb_info *sbi = ll_i2sbi(inode);
ENTRY;
goto out;
}
- memset(&oa, 0, sizeof(oa));
- oa.o_valid = OBD_MD_FLMODE | OBD_MD_FLID;
- oa.o_mode = inode->i_mode;
- oa.o_id = HTON__u64((__u64)inode->i_ino);
- rc = obd_open(ll_i2obdconn(inode), &oa);
+ oa = ll_oa_from_inode(inode, (OBD_MD_FLMODE | OBD_MD_FLID));
+ if (oa == NULL)
+ BUG();
+ rc = obd_open(ll_i2obdconn(inode), oa);
+ obdo_free(oa);
if (rc) {
if (rc > 0)
rc = -rc;
int rc;
struct ptlrpc_request *req;
struct ll_file_data *fd;
- struct obdo oa;
+ struct obdo *oa;
struct ll_sb_info *sbi = ll_i2sbi(inode);
ENTRY;
goto out;
}
- memset(&oa, 0, sizeof(oa));
- oa.o_valid = OBD_MD_FLMODE | OBD_MD_FLID;
- oa.o_mode = inode->i_mode;
- oa.o_id = HTON__u64((__u64)inode->i_ino);
- rc = obd_close(ll_i2obdconn(inode), &oa);
+ oa = ll_oa_from_inode(inode, (OBD_MD_FLMODE | OBD_MD_FLID));
+ if (oa == NULL)
+ BUG();
+ rc = obd_close(ll_i2obdconn(inode), oa);
+ obdo_free(oa);
if (rc) {
if (rc > 0)
rc = -rc;
OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, &request);
if ( err ) {
CERROR("obdo_fromid failed\n");
+ ptlrpc_free_req(request);
EXIT;
return ERR_PTR(-abs(err));
}
err = mdc_create(&sbi->ll_mds_client, dir, name, namelen, tgt, tgtlen,
mode, id, current->uid, current->gid, time, &request);
if (err) {
- ptlrpc_free_req(request);
inode = ERR_PTR(err);
EXIT;
goto out;
if (IS_ERR(inode)) {
CERROR("new_inode -fatal: %ld\n", PTR_ERR(inode));
inode = ERR_PTR(-EIO);
+ BUG();
EXIT;
goto out;
}
rep->ino, atomic_read(&inode->i_count),
inode->i_nlink);
iput(inode);
+ BUG();
inode = ERR_PTR(-EIO);
EXIT;
goto out;
/* returns the page unlocked, but with a reference */
-int ll_readpage(struct file *file, struct page *page)
+static int ll_readpage(struct file *file, struct page *page)
{
struct inode *inode = page->mapping->host;
- int rc;
+ int rc = 0;
ENTRY;
- if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
- <= page->index) {
+ if (!PageLocked(page))
+ BUG();
+
+ if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
+ <= page->index) {
memset(kmap(page), 0, PAGE_CACHE_SIZE);
kunmap(page);
+ EXIT;
goto readpage_out;
}
if (Page_Uptodate(page)) {
+ CERROR("Explain this please?\n");
EXIT;
goto readpage_out;
}
rc = ll_brw(OBD_BRW_READ, inode, page, 0);
- if ( rc ) {
- EXIT;
- return rc;
- }
+ EXIT;
readpage_out:
- SetPageUptodate(page);
+ if (!rc)
+ SetPageUptodate(page);
UnlockPage(page);
- EXIT;
return 0;
} /* ll_readpage */
-int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int ll_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;
ENTRY;
addr = kmap(page);
+ if (!PageLocked(page))
+ BUG();
+
if (Page_Uptodate(page)) {
EXIT;
goto prepare_done;
if ( offset + from >= inode->i_size ) {
memset(addr, 0, PAGE_SIZE);
EXIT;
- return 0;
+ goto prepare_done;
}
rc = ll_brw(OBD_BRW_READ, inode, page, 0);
- if ( !rc ) {
- SetPageUptodate(page);
- }
prepare_done:
- set_page_dirty(page);
+ if ( !rc )
+ SetPageUptodate(page);
+
EXIT;
return rc;
}
/* returns the page unlocked, but with a reference */
-int ll_writepage(struct page *page)
+static int ll_writepage(struct page *page)
{
struct inode *inode = page->mapping->host;
int err;
ENTRY;
+ BUG();
+
+ if (!PageLocked(page))
+ BUG();
+
err = ll_brw(OBD_BRW_WRITE, inode, page, 1);
if ( !err ) {
- SetPageUptodate(page);
+ //SetPageUptodate(page);
set_page_clean(page);
} else {
CERROR("ll_brw failure %d\n", err);
}
+ UnlockPage(page);
EXIT;
return err;
}
/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */
-int ll_commit_write(struct file *file, struct page *page,
+static int ll_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
int create = 1;
return -ENOMEM;
}
+ if (!PageLocked(page))
+ BUG();
+ if (!Page_Uptodate(page))
+ BUG();
+
CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n",
from, to, count);
err = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), num_obdo, &oa,
&bufs_per_obdo, &page, &count, &offset, &flags);
- if ( !err ) {
- SetPageUptodate(page);
- set_page_clean(page);
- }
kunmap(page);
if (offset + to > inode->i_size) {
inode->i_nlink, atomic_read(&inode->i_count),
inode->i_generation,
generation);
+ BUG();
iput(inode);
return ERR_PTR(-ESTALE);
}
}
rep->objid = (__u64) (unsigned long)file;
- //mds_get_objid(inode, &rep->objid);
- dput(de);
return 0;
}
}
file = (struct file *)(unsigned long) req->rq_req.mds->objid;
+
req->rq_rephdr->status = filp_close(file, 0);
dput(de);
return 0;
rc = mds_reint(req);
break;
+ case MDS_OPEN:
+ CDEBUG(D_INODE, "open\n");
+ rc = mds_open(req);
+ break;
+
+ case MDS_CLOSE:
+ CDEBUG(D_INODE, "close\n");
+ rc = mds_close(req);
+ break;
+
default:
return ptlrpc_error(dev, svc, req);
}
de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
if (IS_ERR(de)) {
req->rq_rephdr->status = -ESTALE;
+ BUG();
EXIT;
return 0;
}
CERROR("child lookup error %d\n", rc);
dput(de);
req->rq_rephdr->status = -ESTALE;
+ BUG();
EXIT;
return 0;
}
de->d_inode->i_ino, rec->ur_name);
dput(de);
req->rq_rephdr->status = -EEXIST;
+ BUG();
EXIT;
return 0;
}
switch (type) {
case S_IFREG: {
rc = vfs_create(de->d_inode, dchild, rec->ur_mode);
-
EXIT;
break;
}
de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
if (IS_ERR(de)) {
+ BUG();
req->rq_rephdr->status = -ESTALE;
EXIT;
return 0;
rc = PTR_ERR(dchild);
if (IS_ERR(dchild)) {
CERROR("child lookup error %d\n", rc);
+ BUG();
dput(de);
req->rq_rephdr->status = -ESTALE;
EXIT;
if (!dchild->d_inode) {
CERROR("child doesn't exist (dir %ld, name %s\n",
de->d_inode->i_ino, rec->ur_name);
+ BUG();
dput(de);
req->rq_rephdr->status = -ESTALE;
EXIT;
de_tgt_dir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid2, NULL);
if (IS_ERR(de_tgt_dir)) {
- rc = -ESTALE;
EXIT;
goto out_link;
}
dchild = lookup_one_len(rec->ur_name, de_tgt_dir, rec->ur_namelen - 1);
if (IS_ERR(dchild)) {
CERROR("child lookup error %d\n", rc);
- req->rq_rephdr->status = -ESTALE;
+ EXIT;
goto out_link;
}
}
rc = vfs_link(de_src, de_tgt_dir->d_inode, dchild);
+ EXIT;
out_link:
req->rq_rephdr->status = rc;
l_dput(de_src);
l_dput(de_tgt_dir);
l_dput(dchild);
- EXIT;
return 0;
}
de_tgtdir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid2, NULL);
if (IS_ERR(de_tgtdir)) {
- rc = -ESTALE;
EXIT;
goto out_rename;
}
de_old = lookup_one_len(rec->ur_name, de_srcdir, rec->ur_namelen - 1);
if (IS_ERR(de_old)) {
CERROR("child lookup error %d\n", rc);
+ EXIT;
goto out_rename;
}
de_new = lookup_one_len(rec->ur_tgt, de_tgtdir, rec->ur_tgtlen - 1);
if (IS_ERR(de_new)) {
CERROR("child lookup error %d\n", rc);
+ EXIT;
goto out_rename;
}
rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new);
+ EXIT;
out_rename:
req->rq_rephdr->status = rc;
l_dput(de_old);
l_dput(de_tgtdir);
l_dput(de_srcdir);
- EXIT;
return 0;
}
req->rq_rephdr->xid = req->rq_reqhdr->xid;
rc = reinters[rec->ur_opcode](rec, req);
- req->rq_status = rc;
-
return rc;
}
KFLAGS:=
CPPFLAGS :=
# LDADD := -lreadline -ltermcap # -lefence
-bin_PROGRAMS = testreq truncate
+bin_PROGRAMS = openunlink testreq truncate
testreq_SOURCES = testreq.c
truncate_SOURCES = truncate.c
+openunlink_SOURCES = openunlink.c
losetup ${LOOP}0 /tmp/ost || exit -1
dd if=/dev/zero of=/tmp/mds bs=1024 count=10000
-mke2fs -b 4096 -F /tmp/mds
+mke2fs -b 4096 -N 150000 -F /tmp/mds
losetup ${LOOP}1 /tmp/mds || exit -1
mknod /dev/obd c 10 241
--- /dev/null
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define T1 "write before unlink\n"
+#define T2 "write after unlink\n"
+char buf[128];
+
+int main(int argc, char **argv)
+{
+ int fd, rc;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s filename\n", argv[1]);
+ exit(1);
+ } else {
+ fprintf(stderr, "congratulations - program starting\n");
+ }
+
+ fprintf(stderr, "opening\n");
+ fd = open(argv[1], O_RDWR | O_TRUNC | O_CREAT, 0644);
+ if (fd == -1) {
+ fprintf(stderr, "open (before) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "writing\n");
+ rc = write(fd, T1, strlen(T1) + 1);
+ if (rc != strlen(T1) + 1) {
+ fprintf(stderr, "write (before) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "closing\n");
+ rc = close(fd);
+ if (rc ) {
+ fprintf(stderr, "close (before) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "opening again\n");
+ fd = open(argv[1], O_RDWR );
+ if (fd == -1) {
+ fprintf(stderr, "open (before) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "unlinking\n");
+ rc = unlink(argv[1]);
+ if (rc ) {
+ fprintf(stderr, "open %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "reading\n");
+ rc = read(fd, buf, strlen(T1) + 1);
+ if (rc != strlen(T1) + 1) {
+ fprintf(stderr, "read -after %s rc %d\n", strerror(errno), rc);
+ exit(1);
+ }
+
+ fprintf(stderr, "comparing data\n");
+ if (memcmp(buf, T1, strlen(T1) + 1) ) {
+ fprintf(stderr, "FAILURE: read wrong data after unlink\n");
+ exit(1);
+ }
+
+ fprintf(stderr, "truncating\n");
+ rc = ftruncate(fd, 0);
+ if (rc ) {
+ fprintf(stderr, "truncate -after unl %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "seeking\n");
+ rc = lseek(fd, 0, SEEK_SET);
+ if (rc != 0 ) {
+ fprintf(stderr, "seek (before write) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "writing again\n");
+ rc = write(fd, T2, strlen(T2) + 1);
+ if (rc != strlen(T2) + 1) {
+ fprintf(stderr, "write (before) %s (rc %d)\n", strerror(errno), rc);
+ exit(1);
+ }
+
+ fprintf(stderr, "seeking\n");
+ rc = lseek(fd, 0, SEEK_SET);
+ if (rc != 0 ) {
+ fprintf(stderr, "seek (before read) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "reading again\n");
+ rc = read(fd, buf, strlen(T2) + 1);
+ if (rc != strlen(T2) + 1) {
+ fprintf(stderr, "read (after trunc) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "comparing data again\n");
+ if (memcmp(buf, T2, strlen(T2) + 1) ) {
+ fprintf(stderr, "FAILURE: read wrong data after trunc\n");
+ exit(1);
+ }
+
+ fprintf(stderr, "closing again\n");
+ rc = close(fd);
+ if (rc ) {
+ fprintf(stderr, "close (before) %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fprintf(stderr, "SUCCESS - goto beer\n");
+ return 0;
+}