📄 super.c
字号:
OBD_MD_FLMTIME | OBD_MD_FLCTIME); oinfo.oi_oa = &oa; oinfo.oi_md = lsm; rc = obd_setattr_rqset(sbi->ll_osc_exp, &oinfo, NULL); if (rc) CERROR("obd_setattr_async fails: rc=%d\n", rc); } RETURN(rc);}/* here we simply act as a thin layer to glue it with * llu_setattr_raw(), which is copy from kernel */static int llu_iop_setattr(struct pnode *pno, struct inode *ino, unsigned mask, struct intnl_stat *stbuf){ struct iattr iattr; int rc; ENTRY; liblustre_wait_event(0); LASSERT(!(mask & ~(SETATTR_MTIME | SETATTR_ATIME | SETATTR_UID | SETATTR_GID | SETATTR_LEN | SETATTR_MODE))); memset(&iattr, 0, sizeof(iattr)); if (mask & SETATTR_MODE) { iattr.ia_mode = stbuf->st_mode; iattr.ia_valid |= ATTR_MODE; } if (mask & SETATTR_MTIME) { iattr.ia_mtime = stbuf->st_mtime; iattr.ia_valid |= ATTR_MTIME | ATTR_MTIME_SET; } if (mask & SETATTR_ATIME) { iattr.ia_atime = stbuf->st_atime; iattr.ia_valid |= ATTR_ATIME | ATTR_ATIME_SET; } if (mask & SETATTR_UID) { iattr.ia_uid = stbuf->st_uid; iattr.ia_valid |= ATTR_UID; } if (mask & SETATTR_GID) { iattr.ia_gid = stbuf->st_gid; iattr.ia_valid |= ATTR_GID; } if (mask & SETATTR_LEN) { iattr.ia_size = stbuf->st_size; /* XXX signed expansion problem */ iattr.ia_valid |= ATTR_SIZE; } iattr.ia_valid |= ATTR_RAW | ATTR_CTIME; iattr.ia_ctime = CURRENT_TIME; rc = llu_setattr_raw(ino, &iattr); liblustre_wait_idle(); RETURN(rc);}#define EXT2_LINK_MAX 32000static int llu_iop_symlink_raw(struct pnode *pno, const char *tgt){ struct inode *dir = pno->p_base->pb_parent->pb_ino; struct qstr *qstr = &pno->p_base->pb_name; const char *name = qstr->name; int len = qstr->len; struct ptlrpc_request *request = NULL; struct llu_sb_info *sbi = llu_i2sbi(dir); struct mdc_op_data op_data; int err = -EMLINK; ENTRY; liblustre_wait_event(0); if (llu_i2stat(dir)->st_nlink >= EXT2_LINK_MAX) RETURN(err); llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0); err = mdc_create(sbi->ll_mdc_exp, &op_data, tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO, current->fsuid, current->fsgid, current->cap_effective, 0, &request); ptlrpc_req_finished(request); liblustre_wait_event(0); RETURN(err);}static int llu_readlink_internal(struct inode *inode, struct ptlrpc_request **request, char **symname){ struct llu_inode_info *lli = llu_i2info(inode); struct llu_sb_info *sbi = llu_i2sbi(inode); struct ll_fid fid; struct mds_body *body; struct intnl_stat *st = llu_i2stat(inode); int rc, symlen = st->st_size + 1; ENTRY; *request = NULL; if (lli->lli_symlink_name) { *symname = lli->lli_symlink_name; CDEBUG(D_INODE, "using cached symlink %s\n", *symname); RETURN(0); } ll_inode2fid(&fid, inode); rc = mdc_getattr(sbi->ll_mdc_exp, &fid, OBD_MD_LINKNAME, symlen, request); if (rc) { CERROR("inode %llu: rc = %d\n", (long long)st->st_ino, rc); RETURN(rc); } body = lustre_msg_buf((*request)->rq_repmsg, REPLY_REC_OFF, sizeof(*body)); LASSERT(body != NULL); LASSERT(lustre_rep_swabbed(*request, REPLY_REC_OFF)); if ((body->valid & OBD_MD_LINKNAME) == 0) { CERROR ("OBD_MD_LINKNAME not set on reply\n"); GOTO (failed, rc = -EPROTO); } LASSERT(symlen != 0); if (body->eadatasize != symlen) { CERROR("inode %llu: symlink length %d not expected %d\n", (long long)st->st_ino, body->eadatasize - 1, symlen - 1); GOTO(failed, rc = -EPROTO); } *symname = lustre_msg_buf((*request)->rq_repmsg, REPLY_REC_OFF + 1, symlen); if (*symname == NULL || strnlen(*symname, symlen) != symlen - 1) { /* not full/NULL terminated */ CERROR("inode %llu: symlink not NULL terminated string" "of length %d\n", (long long)st->st_ino, symlen - 1); GOTO(failed, rc = -EPROTO); } OBD_ALLOC(lli->lli_symlink_name, symlen); /* do not return an error if we cannot cache the symlink locally */ if (lli->lli_symlink_name) memcpy(lli->lli_symlink_name, *symname, symlen); RETURN(0); failed: ptlrpc_req_finished (*request); RETURN (-EPROTO);}static int llu_iop_readlink(struct pnode *pno, char *data, size_t bufsize){ struct inode *inode = pno->p_base->pb_ino; struct ptlrpc_request *request; char *symname; int rc; ENTRY; liblustre_wait_event(0); rc = llu_readlink_internal(inode, &request, &symname); if (rc) GOTO(out, rc); LASSERT(symname); strncpy(data, symname, bufsize); rc = strlen(symname); ptlrpc_req_finished(request); out: liblustre_wait_event(0); RETURN(rc);}static int llu_iop_mknod_raw(struct pnode *pno, mode_t mode, dev_t dev){ struct ptlrpc_request *request = NULL; struct inode *dir = pno->p_parent->p_base->pb_ino; struct llu_sb_info *sbi = llu_i2sbi(dir); struct mdc_op_data op_data; int err = -EMLINK; ENTRY; liblustre_wait_event(0); CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%llu\n", (int)pno->p_base->pb_name.len, pno->p_base->pb_name.name, (long long)llu_i2stat(dir)->st_ino); if (llu_i2stat(dir)->st_nlink >= EXT2_LINK_MAX) RETURN(err); switch (mode & S_IFMT) { case 0: case S_IFREG: mode |= S_IFREG; /* for mode = 0 case, fallthrough */ case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: llu_prepare_mdc_op_data(&op_data, dir, NULL, pno->p_base->pb_name.name, pno->p_base->pb_name.len, 0); err = mdc_create(sbi->ll_mdc_exp, &op_data, NULL, 0, mode, current->fsuid, current->fsgid, current->cap_effective, dev, &request); ptlrpc_req_finished(request); break; case S_IFDIR: err = -EPERM; break; default: err = -EINVAL; } liblustre_wait_event(0); RETURN(err);}static int llu_iop_link_raw(struct pnode *old, struct pnode *new){ struct inode *src = old->p_base->pb_ino; struct inode *dir = new->p_parent->p_base->pb_ino; const char *name = new->p_base->pb_name.name; int namelen = new->p_base->pb_name.len; struct ptlrpc_request *request = NULL; struct mdc_op_data op_data; int rc; ENTRY; LASSERT(src); LASSERT(dir); liblustre_wait_event(0); llu_prepare_mdc_op_data(&op_data, src, dir, name, namelen, 0); rc = mdc_link(llu_i2sbi(src)->ll_mdc_exp, &op_data, &request); ptlrpc_req_finished(request); liblustre_wait_event(0); RETURN(rc);}/* * libsysio will clear the inode immediately after return */static int llu_iop_unlink_raw(struct pnode *pno){ struct inode *dir = pno->p_base->pb_parent->pb_ino; struct qstr *qstr = &pno->p_base->pb_name; const char *name = qstr->name; int len = qstr->len; struct inode *target = pno->p_base->pb_ino; struct ptlrpc_request *request = NULL; struct mdc_op_data op_data; int rc; ENTRY; LASSERT(target); liblustre_wait_event(0); llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0); rc = mdc_unlink(llu_i2sbi(dir)->ll_mdc_exp, &op_data, &request); if (!rc) rc = llu_objects_destroy(request, dir); ptlrpc_req_finished(request); liblustre_wait_idle(); RETURN(rc);}static int llu_iop_rename_raw(struct pnode *old, struct pnode *new){ struct inode *src = old->p_parent->p_base->pb_ino; struct inode *tgt = new->p_parent->p_base->pb_ino; const char *oldname = old->p_base->pb_name.name; int oldnamelen = old->p_base->pb_name.len; const char *newname = new->p_base->pb_name.name; int newnamelen = new->p_base->pb_name.len; struct ptlrpc_request *request = NULL; struct mdc_op_data op_data; int rc; ENTRY; LASSERT(src); LASSERT(tgt); liblustre_wait_event(0); llu_prepare_mdc_op_data(&op_data, src, tgt, NULL, 0, 0); rc = mdc_rename(llu_i2sbi(src)->ll_mdc_exp, &op_data, oldname, oldnamelen, newname, newnamelen, &request); if (!rc) { rc = llu_objects_destroy(request, src); } ptlrpc_req_finished(request); liblustre_wait_idle(); RETURN(rc);}#ifdef _HAVE_STATVFSstatic int llu_statfs_internal(struct llu_sb_info *sbi, struct obd_statfs *osfs, __u64 max_age){ struct obd_statfs obd_osfs; int rc; ENTRY; rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age, 0); if (rc) { CERROR("mdc_statfs fails: rc = %d\n", rc); RETURN(rc); } CDEBUG(D_SUPER, "MDC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n", osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files); rc = obd_statfs_rqset(class_exp2obd(sbi->ll_osc_exp), &obd_osfs, max_age, 0); if (rc) { CERROR("obd_statfs fails: rc = %d\n", rc); RETURN(rc); } CDEBUG(D_SUPER, "OSC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n", obd_osfs.os_bavail, obd_osfs.os_blocks, obd_osfs.os_ffree, obd_osfs.os_files); osfs->os_blocks = obd_osfs.os_blocks; osfs->os_bfree = obd_osfs.os_bfree; osfs->os_bavail = obd_osfs.os_bavail; /* If we don't have as many objects free on the OST as inodes * on the MDS, we reduce the total number of inodes to * compensate, so that the "inodes in use" number is correct. */ if (obd_osfs.os_ffree < osfs->os_ffree) { osfs->os_files = (osfs->os_files - osfs->os_ffree) + obd_osfs.os_ffree; osfs->os_ffree = obd_osfs.os_ffree; } RETURN(rc);}static int llu_statfs(struct llu_sb_info *sbi, struct statfs *sfs){ struct obd_statfs osfs; int rc; CDEBUG(D_VFSTRACE, "VFS Op:\n"); /* For now we will always get up-to-date statfs values, but in the * future we may allow some amount of caching on the client (e.g. * from QOS or lprocfs updates). */ rc = llu_statfs_internal(sbi, &osfs, cfs_time_current_64() - HZ); if (rc) return rc; statfs_unpack(sfs, &osfs); if (sizeof(sfs->f_blocks) == 4) { while (osfs.os_blocks > ~0UL) { sfs->f_bsize <<= 1; osfs.os_blocks >>= 1; osfs.os_bfree >>= 1; osfs.os_bavail >>= 1; } } sfs->f_blocks = osfs.os_blocks; sfs->f_bfree = osfs.os_bfree; sfs->f_bavail = osfs.os_bavail; return 0;}static int llu_iop_statvfs(struct pnode *pno, struct inode *ino, struct intnl_statvfs *buf){ struct statfs fs; int rc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -