Skip to content

Conversation

@jainakanksha-msft
Copy link
Collaborator

@jainakanksha-msft jainakanksha-msft commented Mar 7, 2025

Type of Change

  • Bug fix
  • New feature
  • Code quality improvement
  • Other (describe):

Description

This pull request introduces changes to add chown handling handling for adls account, and includes corresponding tests.

How Has This Been Tested?

image
image

Tested locally and with unit testing.
Still have to cover file_cache handling

Checklist

  • The purpose of this PR is explained in this or a referenced issue.
  • Tests are included and/or updated for code changes.
  • Documentation update required.
  • Updates to module CHANGELOG.md are included.
  • License headers are included in each file.

@vibhansa-msft vibhansa-msft added this to the v2-2.5.0 milestone Mar 12, 2025
@vibhansa-msft vibhansa-msft modified the milestones: v2-2.5.0, v2-2.6.0 Apr 22, 2025
@vibhansa-msft vibhansa-msft modified the milestones: v2-2.6.0, v2-2.5.0 May 1, 2025
@vibhansa-msft vibhansa-msft modified the milestones: v2-2.5.0, v2-2.6.0 Jun 30, 2025
@vibhansa-msft vibhansa-msft modified the milestones: v2-2.6.0, v2-2.5.1 Jul 29, 2025
Copilot AI review requested due to automatic review settings July 29, 2025 10:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request adds chown (change ownership) handling for ADLS accounts, building on existing framework to support file ownership operations. The implementation includes proper error handling, metadata management, and comprehensive test coverage.

  • Implements chown functionality for both ADLS and blob storage backends with proper owner/group metadata handling
  • Adds owner and group information tracking in file attributes with corresponding flags for detection
  • Extends libfuse handlers to properly route chown operations through the component chain with appropriate error mapping

Reviewed Changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
internal/attribute.go Adds owner/group fields and detection flags to ObjAttr structure
component/azstorage/datalake.go Implements actual chown functionality for ADLS using SetAccessControl API
component/azstorage/block_blob.go Implements chown for blob storage using metadata approach
component/libfuse/*.go Updates FUSE handlers to route chown operations and handle errors
test files Adds comprehensive test coverage for chown scenarios and error cases
Comments suppressed due to low confidence (2)

test/e2e_tests/file_test.go:677

  • The test function TestFileChown and TestFileChownADLS have identical implementations. Consider renaming one to clarify the difference or consolidating if they serve the same purpose.
func (suite *fileTestSuite) TestFileChown() {

Comment on lines +687 to +690
stat := info.Sys().(*syscall.Stat_t)
suite.Equal(nil, err)
suite.Equal(1000, stat.Uid)
suite.Equal(1000, stat.Gid)
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type assertion (*syscall.Stat_t) could panic if info.Sys() returns a different type. Consider using a safe type assertion with the comma ok idiom: stat, ok := info.Sys().(*syscall.Stat_t); if !ok { ... }

Suggested change
stat := info.Sys().(*syscall.Stat_t)
suite.Equal(nil, err)
suite.Equal(1000, stat.Uid)
suite.Equal(1000, stat.Gid)
stat, ok := info.Sys().(*syscall.Stat_t)
suite.True(ok, "info.Sys() did not return *syscall.Stat_t")
suite.Equal(nil, err)
if ok {
suite.Equal(1000, stat.Uid)
suite.Equal(1000, stat.Gid)
}

Copilot uses AI. Check for mistakes.
Comment on lines +706 to +707
stat := info.Sys().(*syscall.Stat_t)
suite.Equal(nil, err)
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type assertion (*syscall.Stat_t) could panic if info.Sys() returns a different type. Consider using a safe type assertion with the comma ok idiom: stat, ok := info.Sys().(*syscall.Stat_t); if !ok { ... }

Suggested change
stat := info.Sys().(*syscall.Stat_t)
suite.Equal(nil, err)
stat, ok := info.Sys().(*syscall.Stat_t)
suite.Equal(nil, err)
if !ok {
suite.Fail("Failed to assert type *syscall.Stat_t for file info.Sys()")
return
}

Copilot uses AI. Check for mistakes.
return attr.Flags.IsSet(PropFlagModeDefault)
}

// OwnerDetected :
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment // OwnerDetected : is incomplete and doesn't describe what the function does. Consider updating it to: // OwnerInfoFound returns true if owner information was found in the object attributes

Suggested change
// OwnerDetected :
// OwnerInfoFound returns true if owner information was found in the object attributes.

Copilot uses AI. Check for mistakes.
return attr.Flags.IsSet(PropFlagOwnerInfoFound)
}

// GroupDetected :
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment // GroupDetected : is incomplete and doesn't describe what the function does. Consider updating it to: // GroupInfoFound returns true if group information was found in the object attributes

Suggested change
// GroupDetected :
// GroupInfoFound returns true if group information was found in the object attributes

Copilot uses AI. Check for mistakes.
Comment on lines 613 to 620
var uidStr, gidStr string
if uid != -1 {
uidStr = fmt.Sprintf("%d", uid)
opts.Owner = &uidStr
}

if gid != -1 {
gidStr = fmt.Sprintf("%d", gid)
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The variables uidStr and gidStr are declared but gidStr is only used conditionally. Consider declaring them closer to their usage or within the conditional blocks to improve code clarity.

Suggested change
var uidStr, gidStr string
if uid != -1 {
uidStr = fmt.Sprintf("%d", uid)
opts.Owner = &uidStr
}
if gid != -1 {
gidStr = fmt.Sprintf("%d", gid)
var uidStr string
if uid != -1 {
uidStr = fmt.Sprintf("%d", uid)
opts.Owner = &uidStr
}
if gid != -1 {
gidStr := fmt.Sprintf("%d", gid)

Copilot uses AI. Check for mistakes.
Comment on lines +1644 to +1648
if uid != 0xffffffff {
// Update only if user has explicitly set the uid
updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10))
}
if gid != 0xffffffff {
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 0xffffffff is used to check for invalid UID/GID. Consider defining a constant like InvalidUID = 0xffffffff to make the code more readable and maintainable.

Suggested change
if uid != 0xffffffff {
// Update only if user has explicitly set the uid
updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10))
}
if gid != 0xffffffff {
if uid != InvalidUID {
// Update only if user has explicitly set the uid
updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10))
}
if gid != InvalidUID {

Copilot uses AI. Check for mistakes.
Comment on lines +1644 to +1648
if uid != 0xffffffff {
// Update only if user has explicitly set the uid
updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10))
}
if gid != 0xffffffff {
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 0xffffffff is used to check for invalid UID/GID. Consider defining a constant like InvalidGID = 0xffffffff to make the code more readable and maintainable.

Suggested change
if uid != 0xffffffff {
// Update only if user has explicitly set the uid
updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10))
}
if gid != 0xffffffff {
if uid != InvalidUIDGID {
// Update only if user has explicitly set the uid
updatedOwner = AddMetadata(prop.Metadata, common.POSIXOwnerMeta, strconv.FormatUint(uint64(uid), 10))
}
if gid != InvalidUIDGID {

Copilot uses AI. Check for mistakes.
Comment on lines 121 to 125
if owner != 0xffffffff {
value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr
}

if group != 0xffffffff {
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 0xffffffff is used to check for invalid owner. Consider defining a constant like InvalidOwner = 0xffffffff to make the code more readable and maintainable.

Suggested change
if owner != 0xffffffff {
value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr
}
if group != 0xffffffff {
if owner != InvalidOwner {
value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr
}
if group != InvalidOwner {

Copilot uses AI. Check for mistakes.
Comment on lines 121 to 125
if owner != 0xffffffff {
value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr
}

if group != 0xffffffff {
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 0xffffffff is used to check for invalid group. Consider defining a constant like InvalidGroup = 0xffffffff to make the code more readable and maintainable.

Suggested change
if owner != 0xffffffff {
value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr
}
if group != 0xffffffff {
if owner != InvalidGroup {
value.attr.Metadata[common.POSIXOwnerMeta] = &ownerStr
}
if group != InvalidGroup {

Copilot uses AI. Check for mistakes.
if err != nil {
return 0
}
return int(val)

Check failure

Code scanning / CodeQL

Incorrect conversion between integer types High

Incorrect conversion of an unsigned 32-bit integer from
strconv.ParseUint
to a lower bit size type int without an upper bound check.

Copilot Autofix

AI 11 days ago

General Fix:
Ensure that the converted value from ParseUint fits in the range of int (which is at least [0, math.MaxInt32] on 32-bit systems; could be up to math.MaxInt64 on 64 bit but safest is to restrict to math.MaxInt).

Detailed Fix:

  • After parsing, check whether val is less than or equal to math.MaxInt.
    • If so, safely convert to int(val) and return.
    • If not, return 0 or another sentinel value.
  • As math.MaxInt is available via the math package, ensure it's imported.
  • The code should look like:
val, err := strconv.ParseUint(s, 10, 32)
if err != nil {
    return 0
}
if val > uint64(math.MaxInt) {
    return 0
}
return int(val)

Region/lines to change:
Edit within the function ParseInt in common/util.go (lines 527–536).


Suggested changeset 1
common/util.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/common/util.go b/common/util.go
--- a/common/util.go
+++ b/common/util.go
@@ -44,6 +44,7 @@
 	"fmt"
 	"hash/crc64"
 	"io"
+	"math"
 	"os"
 	"os/exec"
 	"os/user"
@@ -532,6 +533,9 @@
 	if err != nil {
 		return 0
 	}
+	if val > uint64(math.MaxInt) {
+		return 0
+	}
 	return int(val)
 }
 
EOF
@@ -44,6 +44,7 @@
"fmt"
"hash/crc64"
"io"
"math"
"os"
"os/exec"
"os/user"
@@ -532,6 +533,9 @@
if err != nil {
return 0
}
if val > uint64(math.MaxInt) {
return 0
}
return int(val)
}

Copilot is powered by AI and may make mistakes. Always verify output.
@vibhansa-msft vibhansa-msft modified the milestones: v2-2.5.1, v2-2.5.2 Sep 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants