diff options
Diffstat (limited to 'fs/ocfs2/xattr.c')
| -rw-r--r-- | fs/ocfs2/xattr.c | 84 | 
1 files changed, 52 insertions, 32 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 6ce0686eab7..016f01df382 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -99,8 +99,8 @@ static struct ocfs2_xattr_def_value_root def_xv = {  const struct xattr_handler *ocfs2_xattr_handlers[] = {  	&ocfs2_xattr_user_handler, -	&ocfs2_xattr_acl_access_handler, -	&ocfs2_xattr_acl_default_handler, +	&posix_acl_access_xattr_handler, +	&posix_acl_default_xattr_handler,  	&ocfs2_xattr_trusted_handler,  	&ocfs2_xattr_security_handler,  	NULL @@ -109,9 +109,9 @@ const struct xattr_handler *ocfs2_xattr_handlers[] = {  static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {  	[OCFS2_XATTR_INDEX_USER]	= &ocfs2_xattr_user_handler,  	[OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] -					= &ocfs2_xattr_acl_access_handler, +					= &posix_acl_access_xattr_handler,  	[OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT] -					= &ocfs2_xattr_acl_default_handler, +					= &posix_acl_default_xattr_handler,  	[OCFS2_XATTR_INDEX_TRUSTED]	= &ocfs2_xattr_trusted_handler,  	[OCFS2_XATTR_INDEX_SECURITY]	= &ocfs2_xattr_security_handler,  }; @@ -369,7 +369,7 @@ static void ocfs2_xattr_bucket_free(struct ocfs2_xattr_bucket *bucket)   * them fully.   */  static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket, -				   u64 xb_blkno) +				   u64 xb_blkno, int new)  {  	int i, rc = 0; @@ -377,15 +377,22 @@ static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket,  		bucket->bu_bhs[i] = sb_getblk(bucket->bu_inode->i_sb,  					      xb_blkno + i);  		if (!bucket->bu_bhs[i]) { -			rc = -EIO; +			rc = -ENOMEM;  			mlog_errno(rc);  			break;  		}  		if (!ocfs2_buffer_uptodate(INODE_CACHE(bucket->bu_inode), -					   bucket->bu_bhs[i])) -			ocfs2_set_new_buffer_uptodate(INODE_CACHE(bucket->bu_inode), -						      bucket->bu_bhs[i]); +					   bucket->bu_bhs[i])) { +			if (new) +				ocfs2_set_new_buffer_uptodate(INODE_CACHE(bucket->bu_inode), +							      bucket->bu_bhs[i]); +			else { +				set_buffer_uptodate(bucket->bu_bhs[i]); +				ocfs2_set_buffer_uptodate(INODE_CACHE(bucket->bu_inode), +							  bucket->bu_bhs[i]); +			} +		}  	}  	if (rc) @@ -754,8 +761,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,  			BUG_ON(why == RESTART_META);  			credits = ocfs2_calc_extend_credits(inode->i_sb, -							    &vb->vb_xv->xr_list, -							    clusters_to_add); +							    &vb->vb_xv->xr_list);  			status = ocfs2_extend_trans(handle, credits);  			if (status < 0) {  				status = -ENOMEM; @@ -2603,6 +2609,7 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh)  	oi->ip_dyn_features &= ~(OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL);  	di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);  	spin_unlock(&oi->ip_lock); +	ocfs2_update_inode_fsync_trans(handle, inode, 0);  	ocfs2_journal_dirty(handle, di_bh);  out_commit: @@ -2865,6 +2872,12 @@ static int ocfs2_create_xattr_block(struct inode *inode,  	}  	new_bh = sb_getblk(inode->i_sb, first_blkno); +	if (!new_bh) { +		ret = -ENOMEM; +		mlog_errno(ret); +		goto end; +	} +  	ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh);  	ret = ocfs2_journal_access_xb(ctxt->handle, INODE_CACHE(inode), @@ -3040,8 +3053,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,  		if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) {  			clusters_add += new_clusters;  			credits += ocfs2_calc_extend_credits(inode->i_sb, -							&def_xv.xv.xr_list, -							new_clusters); +							&def_xv.xv.xr_list);  		}  		goto meta_guess; @@ -3106,8 +3118,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,  			if (!ocfs2_xattr_is_local(xe))  				credits += ocfs2_calc_extend_credits(  							inode->i_sb, -							&def_xv.xv.xr_list, -							new_clusters); +							&def_xv.xv.xr_list);  			goto out;  		}  	} @@ -3132,9 +3143,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,  			meta_add += ocfs2_extend_meta_needed(&xv->xr_list);  			clusters_add += new_clusters - old_clusters;  			credits += ocfs2_calc_extend_credits(inode->i_sb, -							     &xv->xr_list, -							     new_clusters - -							     old_clusters); +							     &xv->xr_list);  			if (value_size >= OCFS2_XATTR_ROOT_SIZE)  				goto out;  		} @@ -3180,7 +3189,7 @@ meta_guess:  				 &xb->xb_attrs.xb_root.xt_list;  			meta_add += ocfs2_extend_meta_needed(el);  			credits += ocfs2_calc_extend_credits(inode->i_sb, -							     el, 1); +							     el);  		} else  			credits += OCFS2_SUBALLOC_ALLOC + 1; @@ -3199,8 +3208,15 @@ meta_guess:  			clusters_add += 1;  		}  	} else { -		meta_add += 1;  		credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS; +		if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE) { +			struct ocfs2_extent_list *el = &def_xv.xv.xr_list; +			meta_add += ocfs2_extend_meta_needed(el); +			credits += ocfs2_calc_extend_credits(inode->i_sb, +							     el); +		} else { +			meta_add += 1; +		}  	}  out:  	if (clusters_need) @@ -3613,6 +3629,7 @@ int ocfs2_xattr_set(struct inode *inode,  	}  	ret = __ocfs2_xattr_set_handle(inode, di, &xi, &xis, &xbs, &ctxt); +	ocfs2_update_inode_fsync_trans(ctxt.handle, inode, 0);  	ocfs2_commit_trans(osb, ctxt.handle); @@ -4293,7 +4310,7 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,  	trace_ocfs2_xattr_create_index_block((unsigned long long)blkno); -	ret = ocfs2_init_xattr_bucket(xs->bucket, blkno); +	ret = ocfs2_init_xattr_bucket(xs->bucket, blkno, 1);  	if (ret) {  		mlog_errno(ret);  		goto out; @@ -4637,7 +4654,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,  	 * Even if !new_bucket_head, we're overwriting t_bucket.  Thus,  	 * there's no need to read it.  	 */ -	ret = ocfs2_init_xattr_bucket(t_bucket, new_blk); +	ret = ocfs2_init_xattr_bucket(t_bucket, new_blk, new_bucket_head);  	if (ret) {  		mlog_errno(ret);  		goto out; @@ -4803,7 +4820,7 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode,  	 * Even if !t_is_new, we're overwriting t_bucket.  Thus,  	 * there's no need to read it.  	 */ -	ret = ocfs2_init_xattr_bucket(t_bucket, t_blkno); +	ret = ocfs2_init_xattr_bucket(t_bucket, t_blkno, t_is_new);  	if (ret)  		goto out; @@ -5475,6 +5492,7 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,  	ret = ocfs2_truncate_log_append(osb, handle, blkno, len);  	if (ret)  		mlog_errno(ret); +	ocfs2_update_inode_fsync_trans(handle, inode, 0);  out_commit:  	ocfs2_commit_trans(osb, handle); @@ -6216,8 +6234,7 @@ static int ocfs2_value_metas_in_xattr_header(struct super_block *sb,  			  le16_to_cpu(xv->xr_list.l_next_free_rec);  		*credits += ocfs2_calc_extend_credits(sb, -						&def_xv.xv.xr_list, -						le32_to_cpu(xv->xr_clusters)); +						&def_xv.xv.xr_list);  		/*  		 * If the value is a tree with depth > 1, We don't go deep @@ -6782,7 +6799,7 @@ static int ocfs2_lock_reflink_xattr_rec_allocators(  		metas.num_metas += ocfs2_extend_meta_needed(xt_et->et_root_el);  	*credits += ocfs2_calc_extend_credits(osb->sb, -					      xt_et->et_root_el, len); +					      xt_et->et_root_el);  	if (metas.num_metas) {  		ret = ocfs2_reserve_new_metadata_blocks(osb, metas.num_metas, @@ -6830,7 +6847,7 @@ static int ocfs2_reflink_xattr_bucket(handle_t *handle,  			break;  		} -		ret = ocfs2_init_xattr_bucket(args->new_bucket, new_blkno); +		ret = ocfs2_init_xattr_bucket(args->new_bucket, new_blkno, 1);  		if (ret) {  			mlog_errno(ret);  			break; @@ -7190,10 +7207,12 @@ out:   */  int ocfs2_init_security_and_acl(struct inode *dir,  				struct inode *inode, -				const struct qstr *qstr) +				const struct qstr *qstr, +				struct posix_acl *default_acl, +				struct posix_acl *acl)  { -	int ret = 0;  	struct buffer_head *dir_bh = NULL; +	int ret = 0;  	ret = ocfs2_init_security_get(inode, dir, qstr, NULL);  	if (ret) { @@ -7207,9 +7226,10 @@ int ocfs2_init_security_and_acl(struct inode *dir,  		goto leave;  	} -	ret = ocfs2_init_acl(NULL, inode, dir, NULL, dir_bh, NULL, NULL); -	if (ret) -		mlog_errno(ret); +	if (!ret && default_acl) +		ret = ocfs2_iop_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); +	if (!ret && acl) +		ret = ocfs2_iop_set_acl(inode, acl, ACL_TYPE_ACCESS);  	ocfs2_inode_unlock(dir, 0);  	brelse(dir_bh);  | 
