X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=sidebyside;f=lustre%2Fllite%2Ffile.c;h=740d4b9170a579f2701199aa91b1885527ccdc8f;hb=b5ac1ec791ec2b89f92382a2efa6772e1d03950d;hp=4fc5c81a0acea4d6fb700ce0bd64444df06f8173;hpb=dcbdb7dab02f7057df5d4957f62c0eeac95da617;p=fs%2Flustre-release.git diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 4fc5c81..740d4b9 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -30,29 +30,43 @@ int ll_inode_setattr(struct inode *inode, struct iattr *attr, int do_trunc); extern int ll_setattr(struct dentry *de, struct iattr *attr); -extern inline struct obdo * ll_oa_from_inode(struct inode *inode, - unsigned long valid); static int ll_file_open(struct inode *inode, struct file *file) { int rc; struct ptlrpc_request *req = NULL; struct ll_file_data *fd; - struct obdo *oa; + struct obdo *oa = NULL; struct ll_sb_info *sbi = ll_i2sbi(inode); + struct ll_inode_info *lli = ll_i2info(inode); ENTRY; if (file->private_data) LBUG(); + /* delayed create of object (intent created inode) */ + /* XXX object needs to be cleaned up if mdc_open fails */ + /* XXX error handling appropriate here? */ + if (lli->lli_obdo == NULL) { + struct inode * inode = file->f_dentry->d_inode; + + oa = lli->lli_obdo = obdo_alloc(); + oa->o_valid = OBD_MD_FLMODE; + oa->o_mode = S_IFREG | 0600; + rc = obd_create(ll_i2obdconn(inode), oa); + if (rc) + RETURN(rc); + lli->lli_flags &= ~OBD_FL_CREATEONOPEN; + } + fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL); if (!fd) GOTO(out, rc = -ENOMEM); memset(fd, 0, sizeof(*fd)); - rc = mdc_open(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino, - S_IFREG, file->f_flags, (__u64)(unsigned long)file, - &fd->fd_mdshandle, &req); + rc = mdc_open(&sbi->ll_mdc_conn, inode->i_ino, S_IFREG | inode->i_mode, + file->f_flags, + oa, (__u64)(unsigned long)file, &fd->fd_mdshandle, &req); fd->fd_req = req; ptlrpc_req_finished(req); if (rc) @@ -61,17 +75,18 @@ static int ll_file_open(struct inode *inode, struct file *file) CERROR("mdc_open didn't assign fd_mdshandle\n"); /* XXX handle this how, abort or is it non-fatal? */ } + if (!fd->fd_mdshandle) + CERROR("mdc_open didn't assign fd_mdshandle\n"); - oa = ll_oa_from_inode(inode, (OBD_MD_FLMODE | OBD_MD_FLID)); + oa = lli->lli_obdo; if (oa == NULL) { LBUG(); - GOTO(out_mdc, rc = -ENOMEM); + GOTO(out_mdc, rc = -EINVAL); } + rc = obd_open(ll_i2obdconn(inode), oa); - obdo_free(oa); - if (rc) { + if (rc) GOTO(out_mdc, rc = -abs(rc)); - } file->private_data = fd; @@ -79,7 +94,7 @@ static int ll_file_open(struct inode *inode, struct file *file) return 0; out_mdc: - mdc_close(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino, + mdc_close(&sbi->ll_mdc_conn, inode->i_ino, S_IFREG, fd->fd_mdshandle, &req); out_req: ptlrpc_free_req(req); @@ -106,18 +121,16 @@ static int ll_file_release(struct inode *inode, struct file *file) GOTO(out, rc = -EINVAL); } - oa = ll_oa_from_inode(inode, (OBD_MD_FLMODE | OBD_MD_FLID)); + oa = ll_i2info(inode)->lli_obdo; if (oa == NULL) { LBUG(); GOTO(out_fd, rc = -ENOENT); } rc = obd_close(ll_i2obdconn(inode), oa); - obdo_free(oa); - if (rc) { + if (rc) GOTO(out_fd, abs(rc)); - } - if (file->f_flags & O_WRONLY) { + if (file->f_mode & FMODE_WRITE) { struct iattr attr; attr.ia_valid = ATTR_MTIME | ATTR_CTIME | ATTR_ATIME | ATTR_SIZE; attr.ia_mtime = inode->i_mtime; @@ -133,11 +146,11 @@ static int ll_file_release(struct inode *inode, struct file *file) } } - rc = mdc_close(&sbi->ll_mds_client, sbi->ll_mds_conn, inode->i_ino, + rc = mdc_close(&sbi->ll_mdc_conn, inode->i_ino, S_IFREG, fd->fd_mdshandle, &req); ptlrpc_req_finished(req); - if (rc) { - if (rc > 0) + if (rc) { + if (rc > 0) rc = -rc; GOTO(out, rc); } @@ -183,6 +196,34 @@ static void ll_update_atime(struct inode *inode) ll_inode_setattr(inode, &attr, 0); } +static int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new, + void *data, __u32 data_len, + struct ptlrpc_request **reqp) +{ + struct inode *inode = lock->l_data; + ENTRY; + + if (new == NULL) { + /* Completion AST. Do nothing. */ + RETURN(0); + } + + if (data_len != sizeof(struct inode)) + LBUG(); + + /* FIXME: do something better than throwing away everything */ + if (inode == NULL) + LBUG(); + down(&inode->i_sem); + CDEBUG(D_INODE, "invalidating obdo/inode %ld\n", inode->i_ino); + invalidate_inode_pages(inode); + up(&inode->i_sem); + + if (ldlm_cli_cancel(lock->l_client, lock) < 0) + LBUG(); + RETURN(0); +} + static ssize_t ll_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos) { @@ -190,7 +231,7 @@ static ssize_t ll_file_read(struct file *filp, char *buf, size_t count, struct inode *inode = filp->f_dentry->d_inode; struct ll_sb_info *sbi = ll_i2sbi(inode); struct ldlm_extent extent; - struct ldlm_handle lockh; + struct lustre_handle lockh; __u64 res_id[RES_NAME_SIZE] = {inode->i_ino}; int flags = 0; ldlm_error_t err; @@ -203,9 +244,10 @@ static ssize_t ll_file_read(struct file *filp, char *buf, size_t count, CDEBUG(D_INFO, "Locking inode %ld, start %Lu end %Lu\n", inode->i_ino, extent.start, extent.end); - err = obd_enqueue(&sbi->ll_conn, sbi->ll_namespace, NULL, - res_id, LDLM_EXTENT, &extent, LCK_PR, &flags, - inode, sizeof(*inode), &lockh); + err = obd_enqueue(&sbi->ll_osc_conn, NULL, res_id, LDLM_EXTENT, + &extent, sizeof(extent), LCK_PR, &flags, + ll_lock_callback, inode, sizeof(*inode), + &lockh); if (err != ELDLM_OK) CERROR("lock enqueue: err: %d\n", err); ldlm_lock_dump((void *)(unsigned long)lockh.addr); @@ -214,11 +256,12 @@ static ssize_t ll_file_read(struct file *filp, char *buf, size_t count, CDEBUG(D_INFO, "Reading inode %ld, %d bytes, offset %Ld\n", inode->i_ino, count, *ppos); retval = generic_file_read(filp, buf, count, ppos); + if (retval > 0) ll_update_atime(inode); if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK)) { - err = obd_cancel(&sbi->ll_conn, LCK_PR, &lockh); + err = obd_cancel(&sbi->ll_osc_conn, LCK_PR, &lockh); if (err != ELDLM_OK) CERROR("lock cancel: err: %d\n", err); } @@ -236,7 +279,7 @@ ll_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) struct inode *inode = file->f_dentry->d_inode; struct ll_sb_info *sbi = ll_i2sbi(inode); struct ldlm_extent extent; - struct ldlm_handle lockh; + struct lustre_handle lockh; __u64 res_id[RES_NAME_SIZE] = {inode->i_ino}; int flags = 0; ldlm_error_t err; @@ -244,14 +287,17 @@ ll_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ENTRY; if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK)) { + /* FIXME: this should check whether O_APPEND is set and adjust + * extent.start accordingly */ extent.start = *ppos; extent.end = *ppos + count; CDEBUG(D_INFO, "Locking inode %ld, start %Lu end %Lu\n", inode->i_ino, extent.start, extent.end); - err = obd_enqueue(&sbi->ll_conn, sbi->ll_namespace, NULL, - res_id, LDLM_EXTENT, &extent, LCK_PW, &flags, - inode, sizeof(*inode), &lockh); + err = obd_enqueue(&sbi->ll_osc_conn, NULL, res_id, LDLM_EXTENT, + &extent, sizeof(extent), LCK_PW, &flags, + ll_lock_callback, inode, sizeof(*inode), + &lockh); if (err != ELDLM_OK) CERROR("lock enqueue: err: %d\n", err); ldlm_lock_dump((void *)(unsigned long)lockh.addr); @@ -263,7 +309,7 @@ ll_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) retval = generic_file_write(file, buf, count, ppos); if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK)) { - err = obd_cancel(&sbi->ll_conn, LCK_PW, &lockh); + err = obd_cancel(&sbi->ll_osc_conn, LCK_PW, &lockh); if (err != ELDLM_OK) CERROR("lock cancel: err: %d\n", err); }