diff options
| author | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
|---|---|---|
| committer | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
| commit | c74a7469f97c0f40b46e82ee979f9fb1bb6e847c (patch) | |
| tree | f2690a1a916b73ef94657fbf0e0141ae57701825 /fs/afs/dir.c | |
| parent | 6f15a7de86c8cf2dc09fc9e6d07047efa40ef809 (diff) | |
| parent | 500775074f88d9cf5416bed2ca19592812d62c41 (diff) | |
Merge drm/drm-next into drm-intel-next-queued
We need a backmerge to get DP_DPCD_REV_14 before we push other
i915 changes to dinq that could break compilation.
Signed-off-by: Rodrigo Vivi <[email protected]>
Diffstat (limited to 'fs/afs/dir.c')
| -rw-r--r-- | fs/afs/dir.c | 54 | 
1 files changed, 26 insertions, 28 deletions
| diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 5889f70d4d27..7d623008157f 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -180,6 +180,7 @@ static int afs_dir_open(struct inode *inode, struct file *file)   * get reclaimed during the iteration.   */  static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) +	__acquires(&dvnode->validate_lock)  {  	struct afs_read *req;  	loff_t i_size; @@ -261,18 +262,21 @@ retry:  	/* If we're going to reload, we need to lock all the pages to prevent  	 * races.  	 */ -	if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { -		ret = -ERESTARTSYS; -		for (i = 0; i < req->nr_pages; i++) -			if (lock_page_killable(req->pages[i]) < 0) -				goto error_unlock; +	ret = -ERESTARTSYS; +	if (down_read_killable(&dvnode->validate_lock) < 0) +		goto error; -		if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) -			goto success; +	if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) +		goto success; + +	up_read(&dvnode->validate_lock); +	if (down_write_killable(&dvnode->validate_lock) < 0) +		goto error; +	if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {  		ret = afs_fetch_data(dvnode, key, req);  		if (ret < 0) -			goto error_unlock_all; +			goto error_unlock;  		task_io_account_read(PAGE_SIZE * req->nr_pages); @@ -284,33 +288,26 @@ retry:  		for (i = 0; i < req->nr_pages; i++)  			if (!afs_dir_check_page(dvnode, req->pages[i],  						req->actual_len)) -				goto error_unlock_all; +				goto error_unlock;  		// TODO: Trim excess pages  		set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags);  	} +	downgrade_write(&dvnode->validate_lock);  success: -	i = req->nr_pages; -	while (i > 0) -		unlock_page(req->pages[--i]);  	return req; -error_unlock_all: -	i = req->nr_pages;  error_unlock: -	while (i > 0) -		unlock_page(req->pages[--i]); +	up_write(&dvnode->validate_lock);  error:  	afs_put_read(req);  	_leave(" = %d", ret);  	return ERR_PTR(ret);  content_has_grown: -	i = req->nr_pages; -	while (i > 0) -		unlock_page(req->pages[--i]); +	up_write(&dvnode->validate_lock);  	afs_put_read(req);  	goto retry;  } @@ -473,6 +470,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,  	}  out: +	up_read(&dvnode->validate_lock);  	afs_put_read(req);  	_leave(" = %d", ret);  	return ret; @@ -1143,7 +1141,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)  	ret = -ERESTARTSYS;  	if (afs_begin_vnode_operation(&fc, dvnode, key)) {  		while (afs_select_fileserver(&fc)) { -			fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; +			fc.cb_break = afs_calc_vnode_cb_break(dvnode);  			afs_fs_create(&fc, dentry->d_name.name, mode, data_version,  				      &newfid, &newstatus, &newcb);  		} @@ -1213,7 +1211,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)  	ret = -ERESTARTSYS;  	if (afs_begin_vnode_operation(&fc, dvnode, key)) {  		while (afs_select_fileserver(&fc)) { -			fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; +			fc.cb_break = afs_calc_vnode_cb_break(dvnode);  			afs_fs_remove(&fc, dentry->d_name.name, true,  				      data_version);  		} @@ -1316,7 +1314,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)  	ret = -ERESTARTSYS;  	if (afs_begin_vnode_operation(&fc, dvnode, key)) {  		while (afs_select_fileserver(&fc)) { -			fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; +			fc.cb_break = afs_calc_vnode_cb_break(dvnode);  			afs_fs_remove(&fc, dentry->d_name.name, false,  				      data_version);  		} @@ -1373,7 +1371,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,  	ret = -ERESTARTSYS;  	if (afs_begin_vnode_operation(&fc, dvnode, key)) {  		while (afs_select_fileserver(&fc)) { -			fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; +			fc.cb_break = afs_calc_vnode_cb_break(dvnode);  			afs_fs_create(&fc, dentry->d_name.name, mode, data_version,  				      &newfid, &newstatus, &newcb);  		} @@ -1443,8 +1441,8 @@ static int afs_link(struct dentry *from, struct inode *dir,  		}  		while (afs_select_fileserver(&fc)) { -			fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; -			fc.cb_break_2 = vnode->cb_break + vnode->cb_s_break; +			fc.cb_break = afs_calc_vnode_cb_break(dvnode); +			fc.cb_break_2 = afs_calc_vnode_cb_break(vnode);  			afs_fs_link(&fc, vnode, dentry->d_name.name, data_version);  		} @@ -1512,7 +1510,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,  	ret = -ERESTARTSYS;  	if (afs_begin_vnode_operation(&fc, dvnode, key)) {  		while (afs_select_fileserver(&fc)) { -			fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; +			fc.cb_break = afs_calc_vnode_cb_break(dvnode);  			afs_fs_symlink(&fc, dentry->d_name.name,  				       content, data_version,  				       &newfid, &newstatus); @@ -1588,8 +1586,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,  			}  		}  		while (afs_select_fileserver(&fc)) { -			fc.cb_break = orig_dvnode->cb_break + orig_dvnode->cb_s_break; -			fc.cb_break_2 = new_dvnode->cb_break + new_dvnode->cb_s_break; +			fc.cb_break = afs_calc_vnode_cb_break(orig_dvnode); +			fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode);  			afs_fs_rename(&fc, old_dentry->d_name.name,  				      new_dvnode, new_dentry->d_name.name,  				      orig_data_version, new_data_version); |