From 390e94b1eafeeafef096eff57f2436ef77d1f18c Mon Sep 17 00:00:00 2001 From: pschwan <pschwan> Date: Mon, 11 Mar 2002 14:58:49 +0000 Subject: [PATCH] - a few more header cleanups - removed some unused code - inserted many extra BUG()s to catch problems early - fixed a use of the incorrect inode, and fixed the directory bug - enabled mds_open/mds_close - fixed a small leak in an error case - removed an extra set_page_dirty() in the write path - added an open/write/close/open/unlink/read/truncate/write/read/close test --- lustre/include/linux/lustre_light.h | 84 ------------------- lustre/lib/page.c | 4 - lustre/llite/dir.c | 6 +- lustre/llite/file.c | 25 +++--- lustre/llite/namei.c | 4 +- lustre/llite/rw.c | 58 +++++++------ lustre/mds/handler.c | 14 +++- lustre/mds/mds_reint.c | 19 +++-- lustre/tests/Makefile.am | 3 +- lustre/tests/llmount.sh | 2 +- lustre/tests/openunlink.c | 122 ++++++++++++++++++++++++++++ 11 files changed, 203 insertions(+), 138 deletions(-) create mode 100644 lustre/tests/openunlink.c diff --git a/lustre/include/linux/lustre_light.h b/lustre/include/linux/lustre_light.h index 4ebe4dc17d..b4a2c23306 100644 --- a/lustre/include/linux/lustre_light.h +++ b/lustre/include/linux/lustre_light.h @@ -66,31 +66,7 @@ static inline struct obd_conn *ll_i2obdconn(struct inode *inode) 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; @@ -98,71 +74,11 @@ 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; diff --git a/lustre/lib/page.c b/lustre/lib/page.c index 50b559bd87..ecd00d37df 100644 --- a/lustre/lib/page.c +++ b/lustre/lib/page.c @@ -42,12 +42,8 @@ #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 diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 2a02a044c9..887cf115f9 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -73,6 +73,7 @@ static int ll_dir_readpage(struct file *file, struct page *page) } if (Page_Uptodate(page)) { + CERROR("Explain this please?\n"); EXIT; goto readpage_out; } @@ -83,11 +84,12 @@ static int ll_dir_readpage(struct file *file, struct page *page) 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 */ diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 0d5bb4fb44..f9bdb92930 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -40,6 +40,7 @@ #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) { @@ -47,7 +48,7 @@ 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; @@ -57,11 +58,11 @@ static int ll_file_open(struct inode *inode, struct file *file) 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; @@ -94,7 +95,7 @@ static int ll_file_release(struct inode *inode, struct file *file) 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; @@ -105,11 +106,11 @@ static int ll_file_release(struct inode *inode, struct file *file) 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; diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index aa33c808c2..0b9ba68bc4 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -101,6 +101,7 @@ static struct dentry *ll_lookup(struct inode * dir, struct dentry *dentry) OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, &request); if ( err ) { CERROR("obdo_fromid failed\n"); + ptlrpc_free_req(request); EXIT; return ERR_PTR(-abs(err)); } @@ -149,7 +150,6 @@ static struct inode *ll_create_node(struct inode *dir, const char *name, 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; @@ -168,6 +168,7 @@ static struct inode *ll_create_node(struct inode *dir, const char *name, if (IS_ERR(inode)) { CERROR("new_inode -fatal: %ld\n", PTR_ERR(inode)); inode = ERR_PTR(-EIO); + BUG(); EXIT; goto out; } @@ -177,6 +178,7 @@ static struct inode *ll_create_node(struct inode *dir, const char *name, rep->ino, atomic_read(&inode->i_count), inode->i_nlink); iput(inode); + BUG(); inode = ERR_PTR(-EIO); EXIT; goto out; diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 4a2eed27c7..71e78e3f1b 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -188,40 +188,43 @@ extern void set_page_clean(struct page *); /* 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; @@ -230,6 +233,9 @@ int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsign ENTRY; addr = kmap(page); + if (!PageLocked(page)) + BUG(); + if (Page_Uptodate(page)) { EXIT; goto prepare_done; @@ -238,40 +244,45 @@ int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsign 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; @@ -291,15 +302,16 @@ int ll_commit_write(struct file *file, struct page *page, 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) { diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 5e5a46a032..5aab7421fa 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -123,6 +123,7 @@ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, inode->i_nlink, atomic_read(&inode->i_count), inode->i_generation, generation); + BUG(); iput(inode); return ERR_PTR(-ESTALE); } @@ -239,8 +240,6 @@ int mds_open(struct ptlrpc_request *req) } rep->objid = (__u64) (unsigned long)file; - //mds_get_objid(inode, &rep->objid); - dput(de); return 0; } @@ -272,6 +271,7 @@ int mds_close(struct ptlrpc_request *req) } file = (struct file *)(unsigned long) req->rq_req.mds->objid; + req->rq_rephdr->status = filp_close(file, 0); dput(de); return 0; @@ -389,6 +389,16 @@ int mds_handle(struct obd_device *dev, struct ptlrpc_service *svc, 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); } diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 76523e6670..7bf85eac8d 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -102,6 +102,7 @@ static int mds_reint_create(struct mds_update_record *rec, 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; } @@ -113,6 +114,7 @@ static int mds_reint_create(struct mds_update_record *rec, CERROR("child lookup error %d\n", rc); dput(de); req->rq_rephdr->status = -ESTALE; + BUG(); EXIT; return 0; } @@ -122,6 +124,7 @@ static int mds_reint_create(struct mds_update_record *rec, de->d_inode->i_ino, rec->ur_name); dput(de); req->rq_rephdr->status = -EEXIST; + BUG(); EXIT; return 0; } @@ -129,7 +132,6 @@ static int mds_reint_create(struct mds_update_record *rec, switch (type) { case S_IFREG: { rc = vfs_create(de->d_inode, dchild, rec->ur_mode); - EXIT; break; } @@ -182,6 +184,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, 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; @@ -192,6 +195,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, rc = PTR_ERR(dchild); if (IS_ERR(dchild)) { CERROR("child lookup error %d\n", rc); + BUG(); dput(de); req->rq_rephdr->status = -ESTALE; EXIT; @@ -201,6 +205,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, 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; @@ -244,7 +249,6 @@ static int mds_reint_link(struct mds_update_record *rec, 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; } @@ -252,7 +256,7 @@ static int mds_reint_link(struct mds_update_record *rec, 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; } @@ -264,13 +268,13 @@ static int mds_reint_link(struct mds_update_record *rec, } 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; } @@ -294,7 +298,6 @@ static int mds_reint_rename(struct mds_update_record *rec, de_tgtdir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid2, NULL); if (IS_ERR(de_tgtdir)) { - rc = -ESTALE; EXIT; goto out_rename; } @@ -302,16 +305,19 @@ static int mds_reint_rename(struct mds_update_record *rec, 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; @@ -319,7 +325,6 @@ static int mds_reint_rename(struct mds_update_record *rec, l_dput(de_old); l_dput(de_tgtdir); l_dput(de_srcdir); - EXIT; return 0; } @@ -355,8 +360,6 @@ int mds_reint_rec(struct mds_update_record *rec, struct ptlrpc_request *req) req->rq_rephdr->xid = req->rq_reqhdr->xid; rc = reinters[rec->ur_opcode](rec, req); - req->rq_status = rc; - return rc; } diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am index fb9f04f31c..6995651756 100644 --- a/lustre/tests/Makefile.am +++ b/lustre/tests/Makefile.am @@ -2,8 +2,9 @@ CFLAGS:=-g -I. -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I../include -Wal 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 diff --git a/lustre/tests/llmount.sh b/lustre/tests/llmount.sh index 0fcaa83330..30a9286d97 100755 --- a/lustre/tests/llmount.sh +++ b/lustre/tests/llmount.sh @@ -20,7 +20,7 @@ mke2fs -b 4096 -F /tmp/ost 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 diff --git a/lustre/tests/openunlink.c b/lustre/tests/openunlink.c new file mode 100644 index 0000000000..dddf6a81b2 --- /dev/null +++ b/lustre/tests/openunlink.c @@ -0,0 +1,122 @@ +#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; +} -- GitLab