⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ops_file.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * gfs2_mmap - * @file: The file to map * @vma: The VMA which described the mapping * * Returns: 0 or error code */static int gfs2_mmap(struct file *file, struct vm_area_struct *vma){	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);	struct gfs2_holder i_gh;	int error;	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);	error = gfs2_glock_nq_atime(&i_gh);	if (error) {		gfs2_holder_uninit(&i_gh);		return error;	}	/* This is VM_MAYWRITE instead of VM_WRITE because a call	   to mprotect() can turn on VM_WRITE later. */	if ((vma->vm_flags & (VM_MAYSHARE | VM_MAYWRITE)) ==	    (VM_MAYSHARE | VM_MAYWRITE))		vma->vm_ops = &gfs2_vm_ops_sharewrite;	else		vma->vm_ops = &gfs2_vm_ops_private;	gfs2_glock_dq_uninit(&i_gh);	return error;}/** * gfs2_open - open a file * @inode: the inode to open * @file: the struct file for this opening * * Returns: errno */static int gfs2_open(struct inode *inode, struct file *file){	struct gfs2_inode *ip = GFS2_I(inode);	struct gfs2_holder i_gh;	struct gfs2_file *fp;	int error;	fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL);	if (!fp)		return -ENOMEM;	mutex_init(&fp->f_fl_mutex);	gfs2_assert_warn(GFS2_SB(inode), !file->private_data);	file->private_data = fp;	if (S_ISREG(ip->i_inode.i_mode)) {		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,					   &i_gh);		if (error)			goto fail;		if (!(file->f_flags & O_LARGEFILE) &&		    ip->i_di.di_size > MAX_NON_LFS) {			error = -EOVERFLOW;			goto fail_gunlock;		}		/* Listen to the Direct I/O flag */		if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO)			file->f_flags |= O_DIRECT;		gfs2_glock_dq_uninit(&i_gh);	}	return 0;fail_gunlock:	gfs2_glock_dq_uninit(&i_gh);fail:	file->private_data = NULL;	kfree(fp);	return error;}/** * gfs2_close - called to close a struct file * @inode: the inode the struct file belongs to * @file: the struct file being closed * * Returns: errno */static int gfs2_close(struct inode *inode, struct file *file){	struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;	struct gfs2_file *fp;	fp = file->private_data;	file->private_data = NULL;	if (gfs2_assert_warn(sdp, fp))		return -EIO;	kfree(fp);	return 0;}/** * gfs2_fsync - sync the dirty data for a file (across the cluster) * @file: the file that points to the dentry (we ignore this) * @dentry: the dentry that points to the inode to sync * * The VFS will flush "normal" data for us. We only need to worry * about metadata here. For journaled data, we just do a log flush * as we can't avoid it. Otherwise we can just bale out if datasync * is set. For stuffed inodes we must flush the log in order to * ensure that all data is on disk. * * The call to write_inode_now() is there to write back metadata and * the inode itself. It does also try and write the data, but thats * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() * for us. * * Returns: errno */static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync){	struct inode *inode = dentry->d_inode;	int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC);	int ret = 0;	if (gfs2_is_jdata(GFS2_I(inode))) {		gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl);		return 0;	}	if (sync_state != 0) {		if (!datasync)			ret = write_inode_now(inode, 0);		if (gfs2_is_stuffed(GFS2_I(inode)))			gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl);	}	return ret;}/** * gfs2_setlease - acquire/release a file lease * @file: the file pointer * @arg: lease type * @fl: file lock * * Returns: errno */static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl){	struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);	/*	 * We don't currently have a way to enforce a lease across the whole	 * cluster; until we do, disable leases (by just returning -EINVAL),	 * unless the administrator has requested purely local locking.	 */	if (!sdp->sd_args.ar_localflocks)		return -EINVAL;	return generic_setlease(file, arg, fl);}/** * gfs2_lock - acquire/release a posix lock on a file * @file: the file pointer * @cmd: either modify or retrieve lock state, possibly wait * @fl: type and range of lock * * Returns: errno */static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl){	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);	struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);	struct lm_lockname name =		{ .ln_number = ip->i_no_addr,		  .ln_type = LM_TYPE_PLOCK };	if (!(fl->fl_flags & FL_POSIX))		return -ENOLCK;	if (__mandatory_lock(&ip->i_inode))		return -ENOLCK;	if (sdp->sd_args.ar_localflocks) {		if (IS_GETLK(cmd)) {			posix_test_lock(file, fl);			return 0;		} else {			return posix_lock_file_wait(file, fl);		}	}	if (cmd == F_CANCELLK) {		/* Hack: */		cmd = F_SETLK;		fl->fl_type = F_UNLCK;	}	if (IS_GETLK(cmd))		return gfs2_lm_plock_get(sdp, &name, file, fl);	else if (fl->fl_type == F_UNLCK)		return gfs2_lm_punlock(sdp, &name, file, fl);	else		return gfs2_lm_plock(sdp, &name, file, cmd, fl);}static int do_flock(struct file *file, int cmd, struct file_lock *fl){	struct gfs2_file *fp = file->private_data;	struct gfs2_holder *fl_gh = &fp->f_fl_gh;	struct gfs2_inode *ip = GFS2_I(file->f_path.dentry->d_inode);	struct gfs2_glock *gl;	unsigned int state;	int flags;	int error = 0;	state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED;	flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE 		| GL_FLOCK;	mutex_lock(&fp->f_fl_mutex);	gl = fl_gh->gh_gl;	if (gl) {		if (fl_gh->gh_state == state)			goto out;		flock_lock_file_wait(file,				     &(struct file_lock){.fl_type = F_UNLCK});		gfs2_glock_dq_wait(fl_gh);		gfs2_holder_reinit(state, flags, fl_gh);	} else {		error = gfs2_glock_get(GFS2_SB(&ip->i_inode),				      ip->i_no_addr, &gfs2_flock_glops,				      CREATE, &gl);		if (error)			goto out;		gfs2_holder_init(gl, state, flags, fl_gh);		gfs2_glock_put(gl);	}	error = gfs2_glock_nq(fl_gh);	if (error) {		gfs2_holder_uninit(fl_gh);		if (error == GLR_TRYFAILED)			error = -EAGAIN;	} else {		error = flock_lock_file_wait(file, fl);		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);	}out:	mutex_unlock(&fp->f_fl_mutex);	return error;}static void do_unflock(struct file *file, struct file_lock *fl){	struct gfs2_file *fp = file->private_data;	struct gfs2_holder *fl_gh = &fp->f_fl_gh;	mutex_lock(&fp->f_fl_mutex);	flock_lock_file_wait(file, fl);	if (fl_gh->gh_gl)		gfs2_glock_dq_uninit(fl_gh);	mutex_unlock(&fp->f_fl_mutex);}/** * gfs2_flock - acquire/release a flock lock on a file * @file: the file pointer * @cmd: either modify or retrieve lock state, possibly wait * @fl: type and range of lock * * Returns: errno */static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl){	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);	struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);	if (!(fl->fl_flags & FL_FLOCK))		return -ENOLCK;	if (__mandatory_lock(&ip->i_inode))		return -ENOLCK;	if (sdp->sd_args.ar_localflocks)		return flock_lock_file_wait(file, fl);	if (fl->fl_type == F_UNLCK) {		do_unflock(file, fl);		return 0;	} else {		return do_flock(file, cmd, fl);	}}const struct file_operations gfs2_file_fops = {	.llseek		= gfs2_llseek,	.read		= do_sync_read,	.aio_read	= generic_file_aio_read,	.write		= do_sync_write,	.aio_write	= generic_file_aio_write,	.unlocked_ioctl	= gfs2_ioctl,	.mmap		= gfs2_mmap,	.open		= gfs2_open,	.release	= gfs2_close,	.fsync		= gfs2_fsync,	.lock		= gfs2_lock,	.flock		= gfs2_flock,	.splice_read	= generic_file_splice_read,	.splice_write	= generic_file_splice_write,	.setlease	= gfs2_setlease,};const struct file_operations gfs2_dir_fops = {	.readdir	= gfs2_readdir,	.unlocked_ioctl	= gfs2_ioctl,	.open		= gfs2_open,	.release	= gfs2_close,	.fsync		= gfs2_fsync,	.lock		= gfs2_lock,	.flock		= gfs2_flock,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -