X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Ffile.c;h=d8ba5c9e64149b43a4599d5113bf7a42fbac9681;hp=d25bc688fb100924f708c0450a76c57288c3ef5a;hb=bd12b1a4fc839c789630eea92fb816b453f2c503;hpb=17c7141d3e423ba903b0fec571b8afb7fca41c79 diff --git a/lustre/llite/file.c b/lustre/llite/file.c index d25bc68..d8ba5c9 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -46,7 +46,6 @@ #define DEBUG_SUBSYSTEM S_LLITE #include #include -#include #include #include #include "llite_internal.h" @@ -402,9 +401,8 @@ static int ll_intent_file_open(struct file *file, void *lmm, rc = ll_prep_inode(&file->f_dentry->d_inode, req, NULL); if (!rc && itp->d.lustre.it_lock_mode) - md_set_lock_data(sbi->ll_md_exp, - &itp->d.lustre.it_lock_handle, - file->f_dentry->d_inode, NULL); + ll_set_lock_data(sbi->ll_md_exp, file->f_dentry->d_inode, + itp, NULL); out: ptlrpc_req_finished(itp->d.lustre.it_data); @@ -521,8 +519,8 @@ int ll_file_open(struct inode *inode, struct file *file) fd->fd_file = file; if (S_ISDIR(inode->i_mode)) { cfs_spin_lock(&lli->lli_sa_lock); - if (lli->lli_opendir_key == NULL && lli->lli_opendir_pid == 0) { - LASSERT(lli->lli_sai == NULL); + if (lli->lli_opendir_key == NULL && lli->lli_opendir_pid == 0 && + lli->lli_sai == NULL) { lli->lli_opendir_key = fd; lli->lli_opendir_pid = cfs_curproc_pid(); opendir_set = 1; @@ -750,7 +748,7 @@ int ll_inode_getattr(struct inode *inode, struct obdo *obdo, if (rc == 0) { obdo_refresh_inode(inode, obdo, obdo->o_valid); CDEBUG(D_INODE, - "objid "LPX64" size %Lu, blocks %llu, blksize %lu\n", + "objid "LPX64" size %llu, blocks %llu, blksize %lu\n", lli->lli_smd->lsm_object_id, i_size_read(inode), (unsigned long long)inode->i_blocks, (unsigned long)ll_inode_blksize(inode)); @@ -1350,8 +1348,8 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, op_data = ll_prep_md_op_data(NULL, inode, NULL, filename, strlen(filename), lmmsize, LUSTRE_OPC_ANY, NULL); - if (op_data == NULL) - RETURN(-ENOMEM); + if (IS_ERR(op_data)) + RETURN(PTR_ERR(op_data)); op_data->op_valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA; rc = md_getattr_name(sbi->ll_md_exp, op_data, &req); @@ -1757,6 +1755,7 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, #endif struct ll_file_data *fd = LUSTRE_FPRIVATE(file); int flags; + ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p),cmd=%x\n", inode->i_ino, @@ -1835,7 +1834,6 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } case OBD_IOC_FID2PATH: RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg)); - case LL_IOC_GET_MDTIDX: { int mdtidx; @@ -1848,6 +1846,16 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, RETURN(0); } + case OBD_IOC_GETNAME: { + struct obd_device *obd = + class_exp2obd(ll_i2sbi(inode)->ll_dt_exp); + if (!obd) + RETURN(-EFAULT); + if (cfs_copy_to_user((void *)arg, obd->obd_name, + strlen(obd->obd_name) + 1)) + RETURN(-EFAULT); + RETURN(0); + } default: { int err; @@ -1869,7 +1877,7 @@ loff_t ll_file_seek(struct file *file, loff_t offset, int origin) ENTRY; retval = offset + ((origin == 2) ? i_size_read(inode) : (origin == 1) ? file->f_pos : 0); - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), to=%Lu=%#Lx(%s)\n", + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), to=%llu=%#llx(%s)\n", inode->i_ino, inode->i_generation, inode, retval, retval, origin == 2 ? "SEEK_END": origin == 1 ? "SEEK_CUR" : "SEEK_SET"); ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LLSEEK, 1); @@ -2127,14 +2135,25 @@ int ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock) RETURN(-ENOSYS); } -int ll_have_md_lock(struct inode *inode, __u64 bits, ldlm_mode_t l_req_mode) +/** + * test if some locks matching bits and l_req_mode are acquired + * - bits can be in different locks + * - if found clear the common lock bits in *bits + * - the bits not found, are kept in *bits + * \param inode [IN] + * \param bits [IN] searched lock bits [IN] + * \param l_req_mode [IN] searched lock mode + * \retval boolean, true iff all bits are found + */ +int ll_have_md_lock(struct inode *inode, __u64 *bits, ldlm_mode_t l_req_mode) { struct lustre_handle lockh; - ldlm_policy_data_t policy = { .l_inodebits = {bits}}; + ldlm_policy_data_t policy; ldlm_mode_t mode = (l_req_mode == LCK_MINMODE) ? (LCK_CR|LCK_CW|LCK_PR|LCK_PW) : l_req_mode; struct lu_fid *fid; int flags; + int i; ENTRY; if (!inode) @@ -2145,11 +2164,26 @@ int ll_have_md_lock(struct inode *inode, __u64 bits, ldlm_mode_t l_req_mode) ldlm_lockname[mode]); flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_CBPENDING | LDLM_FL_TEST_LOCK; - if (md_lock_match(ll_i2mdexp(inode), flags, fid, LDLM_IBITS, &policy, - mode, &lockh)) { - RETURN(1); + for (i = 0; i < MDS_INODELOCK_MAXSHIFT && *bits != 0; i++) { + policy.l_inodebits.bits = *bits & (1 << i); + if (policy.l_inodebits.bits == 0) + continue; + + if (md_lock_match(ll_i2mdexp(inode), flags, fid, LDLM_IBITS, + &policy, mode, &lockh)) { + struct ldlm_lock *lock; + + lock = ldlm_handle2lock(&lockh); + if (lock) { + *bits &= + ~(lock->l_policy_data.l_inodebits.bits); + LDLM_LOCK_PUT(lock); + } else { + *bits &= ~policy.l_inodebits.bits; + } + } } - RETURN(0); + RETURN(*bits == 0); } ldlm_mode_t ll_take_md_lock(struct inode *inode, __u64 bits, @@ -2261,7 +2295,7 @@ int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it, } ll_lookup_finish_locks(&oit, dentry); - } else if (!ll_have_md_lock(dentry->d_inode, ibits, LCK_MINMODE)) { + } else if (!ll_have_md_lock(dentry->d_inode, &ibits, LCK_MINMODE)) { struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode); obd_valid valid = OBD_MD_FLGETATTR; struct md_op_data *op_data; @@ -2277,8 +2311,8 @@ int __ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it, op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, ealen, LUSTRE_OPC_ANY, NULL); - if (op_data == NULL) - RETURN(-ENOMEM); + if (IS_ERR(op_data)) + RETURN(PTR_ERR(op_data)); op_data->op_valid = valid; /* Once OBD_CONNECT_ATTRFID is not supported, we can't find one @@ -2406,8 +2440,12 @@ int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, #endif -static -int lustre_check_acl(struct inode *inode, int mask) +static int +#ifdef HAVE_GENERIC_PERMISSION_4ARGS +lustre_check_acl(struct inode *inode, int mask, unsigned int flags) +#else +lustre_check_acl(struct inode *inode, int mask) +#endif { #ifdef CONFIG_FS_POSIX_ACL struct ll_inode_info *lli = ll_i2info(inode); @@ -2415,6 +2453,10 @@ int lustre_check_acl(struct inode *inode, int mask) int rc; ENTRY; +#ifdef HAVE_GENERIC_PERMISSION_4ARGS + if (flags & IPERM_FLAG_RCU) + return -ECHILD; +#endif cfs_spin_lock(&lli->lli_lock); acl = posix_acl_dup(lli->lli_posix_acl); cfs_spin_unlock(&lli->lli_lock); @@ -2431,11 +2473,14 @@ int lustre_check_acl(struct inode *inode, int mask) #endif } -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) -#ifndef HAVE_INODE_PERMISION_2ARGS -int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) +#ifdef HAVE_GENERIC_PERMISSION_4ARGS +int ll_inode_permission(struct inode *inode, int mask, unsigned int flags) #else +# ifdef HAVE_INODE_PERMISION_2ARGS int ll_inode_permission(struct inode *inode, int mask) +# else +int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) +# endif #endif { int rc = 0; @@ -2460,61 +2505,10 @@ int ll_inode_permission(struct inode *inode, int mask) return lustre_check_remote_perm(inode, mask); ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1); - rc = generic_permission(inode, mask, lustre_check_acl); + rc = ll_generic_permission(inode, mask, flags, lustre_check_acl); RETURN(rc); } -#else -int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd) -{ - int mode = inode->i_mode; - int rc; - - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), mask %o\n", - inode->i_ino, inode->i_generation, inode, mask); - - if (ll_i2sbi(inode)->ll_flags & LL_SBI_RMT_CLIENT) - return lustre_check_remote_perm(inode, mask); - - ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1); - - if ((mask & MAY_WRITE) && IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) - return -EACCES; - if (cfs_curproc_fsuid() == inode->i_uid) { - mode >>= 6; - } else if (1) { - if (((mode >> 3) & mask & S_IRWXO) != mask) - goto check_groups; - rc = lustre_check_acl(inode, mask); - if (rc == -EAGAIN) - goto check_groups; - if (rc == -EACCES) - goto check_capabilities; - return rc; - } else { -check_groups: - if (cfs_curproc_is_in_groups(inode->i_gid)) - mode >>= 3; - } - if ((mode & mask & S_IRWXO) == mask) - return 0; - -check_capabilities: - if (!(mask & MAY_EXEC) || - (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) - if (cfs_capable(CFS_CAP_DAC_OVERRIDE)) - return 0; - - if (cfs_capable(CFS_CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) || - (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))) - return 0; - - return -EACCES; -} -#endif #ifdef HAVE_FILE_READV #define READ_METHOD readv