Read Only NTFS folder

I have a Pi4 with an external SSD HDD attached, the drive contains some current TV shows, some Movies and a folder which has sub folders of ‘Classic Movies’, ‘Classic TV’ and ‘Home Movies’.

I have a button mapped on my remote to delete files so we can delete films & TV shows once we’ve watched them.

The thing is, I want to make the Classics folder and all sub-folders read only, so files can’t be accidentally deleted.

The drive is formatted as NTFS as I’d like to be able to move it to my PC on occasion.

I also access the drive via SMB share and want this to have full access so I can add media as needed.

This sounds quite complicated, but I’m sure it’s relatively easy - I want the classics folder to be read only from withing OSMC only.

Thanks!

Well “complicated” is relative:

  1. You would need to have a filesystem that supports users/groups while it might work with NTFS I would not recommend it.
  2. You would need to create a different user/group for samba share than osmc/osmc which is the user Kodi uses.
  3. You would then need to give the group write rights. Or do it via the user depends of who and how the files are created.

I think I got really close to a perfect solution here but I got stuck on the reboot.

I have an NTFS formatted drive that mounts as “test” and it contains a folder called “Movies” with some files inside. I added to my fstab…

/media/test/Movie /mnt/MovieLocked/ none bind,ro

and to my advancedsettings.xml

	<pathsubstitution>
		<substitute>
			<from>/media/test/Movie/</from>
			<to>/mnt/MovieLocked/</to>
		</substitute>
	</pathsubstitution>

This worked as the OP desired as you could modify via samba but Kodi would silently fail on an attempted delete of a file. Unfortunately when I reboot the automount changes to “test_” which obviously breaks the setup. If I change the paths to add the underscore then it just remakes the automount with two trailing underscores. My Linux skills are a bit too weak to understand how to stop this shifting mount point behavior.

Would indicate that it is not properly unmounted during reboot. Could be that the automount tries to unmount while the fstab mount still busy. I think there was also a problem with the script that cleans up /media

I don’t think that is it. I manually unmount and checked to make sure there was no folder or mount point anymore then reboot, and it still shows up with the underscore. If I rem out that line in fstab and reboot then the auto-mount is back to the original name without the underscore. Since it works fine if I manually create the mount, or modify fstab and load the that after the fact then everything is good. I figure there must be something with when or how the auto-mount is being happening in relation to the bind mount.

Sounds like something is already mounted on test. When it mounts as test_ what does mount show?

osmc@VeroCave:~$ mount
devtmpfs on /dev type devtmpfs (rw,relatime,size=1015064k,nr_inodes=253766,mode=755)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /run type tmpfs (rw,relatime)
/dev/mapper/vero--nand-root on / type ext4 (rw,relatime,stripe=1024,data=ordered)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup/debug type cgroup (rw,nosuid,nodev,noexec,relatime,debug)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/schedtune type cgroup (rw,nosuid,nodev,noexec,relatime,schedtune)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime)
sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime)
mqueue on /dev/mqueue type mqueue (rw,relatime)
systemd-1 on /mnt/Video type autofs (rw,relatime,fd=41,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=283)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=42,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=301)
/dev/mapper/vero--nand-root on /mnt/MovieLocked type ext4 (ro,relatime,stripe=1024,data=ordered)
configfs on /sys/kernel/config type configfs (rw,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
/dev/sda1 on /media/test_ type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks)
/dev/mmcblk1p1 on /media/New Volume type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks)
//192.168.254.201/Video on /mnt/Video type cifs (rw,relatime,vers=3.0,sec=ntlmssp,cache=strict,username=John Paul,domain=SERVER,uid=1000,forceuid,gid=1000,forcegid,addr=192.168.254.201,file_mode=0770,dir_mode=0770,iocharset=utf8,nounix,serverino,mapposix,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1,x-systemd.automount)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=203728k,mode=700,uid=1000,gid=1000)
osmc@VeroCave:~$

It looks like it’s doing the bind first, so that causes test to be busy.

In your fstab, you probably have the last field as 0. Change the one for the bind to be 1 or higher. That controls what order the mounts will be processed.

I didn’t have anything after the mount options so it would have been 0. I changed this but unfortunately I still have the same situation…

osmc@VeroCave:~$ cat /etc/fstab
# rootfs is not mounted in fstab as we do it via initramfs. Uncomment for remount (slower boot)
#/dev/vero-nand/root  /    ext4      defaults,noatime    0   0
//192.168.254.201/Video /mnt/Video cifs x-systemd.automount,noauto,rw,iocharset=utf8,credentials=/home/osmc/.credentials,uid=osmc,gid=osmc,file_mode=0770,dir_mode=0770,vers=3.0 0 0
/media/test/Movie /mnt/MovieLocked/ none bind,ro 0 2
osmc@VeroCave:~$ mount
devtmpfs on /dev type devtmpfs (rw,relatime,size=1015064k,nr_inodes=253766,mode=755)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /run type tmpfs (rw,relatime)
/dev/mapper/vero--nand-root on / type ext4 (rw,relatime,stripe=1024,data=ordered)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/schedtune type cgroup (rw,nosuid,nodev,noexec,relatime,schedtune)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/debug type cgroup (rw,nosuid,nodev,noexec,relatime,debug)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
systemd-1 on /mnt/Video type autofs (rw,relatime,fd=25,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=13140)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=31,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=13152)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
mqueue on /dev/mqueue type mqueue (rw,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime)
sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime)
/dev/mapper/vero--nand-root on /mnt/MovieLocked type ext4 (ro,relatime,stripe=1024,data=ordered)
configfs on /sys/kernel/config type configfs (rw,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
/dev/sda1 on /media/test_ type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks)
/dev/mmcblk1p1 on /media/New Volume type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks)
//192.168.254.201/Video on /mnt/Video type cifs (rw,relatime,vers=3.0,sec=ntlmssp,cache=strict,username=John Paul,domain=SERVER,uid=1000,forceuid,gid=1000,forcegid,addr=192.168.254.201,file_mode=0770,dir_mode=0770,iocharset=utf8,nounix,serverino,mapposix,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1,x-systemd.automount)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=203728k,mode=700,uid=1000,gid=1000)
osmc@VeroCave:~$

Share your complete fstab please.

So the issue was that the auto mount was happening after fstab runs so the mount has to be made manually. Big thanks to @bmillham and @fzinken for figuring that out for me. So the complete solution is as follows.

Step one is to manually add a mount for the drive your wanting to tweak as well as a bind mount for the folder that you want to make read only. In this example I’m just going to use “test” as the name of my drive. You would want to make this the same as what your drive is currently being mounted as to not break your existing library. You will probably want to ssh to get terminal access and once your there…

sudo nano /etc/fstab

This will bring up the file in a text editor and you will need to add two lines like as follows but with the specifics of your situation…

# rootfs is not mounted in fstab as we do it via initramfs. Uncomment for remount (slower boot)
#/dev/vero-nand/root  /    ext4      defaults,noatime    0   0
LABEL=test /media/test auto rw,user,auto 0 0
/media/test/Movie /mnt/MovieLocked/ none bind,ro 0 2

The “LABEL” will likely be the name that shows up in Kodi currently as will the mount point in /media (ie where you see “test” above your going to change it to the name yours is using). In the last line the folder (/media/test/Movie) is the folder which you want to not allow deletion and the file path following it is arbitrary and just needs to match what you put in the advancedsettings.xml file. Keep in mind that Linux is case sensitive. Once you finish editing that file you can save and exit it by pressing ctrl+x, then y, then enter.

next you will need to either at the terminal

nano ~/.kodi/userdata/advancedsettings.xml

or make and edit that file over the network. You will need it to contain the following edited to match your file paths…

<?xml version="1.0" encoding="utf-8"?>
<advancedsettings>
	<pathsubstitution>
		<substitute>
			<from>/media/test/Movie/</from>
			<to>/mnt/MovieLocked/</to>
		</substitute>
	</pathsubstitution>
</advancedsettings>

If you did everything correct after a reboot your existing library should work exactly as it did before with the only difference being that anything in that substituted folder will no longer delete even when you tell it to in Kodi. Files in any other folder on the same drive still can be deleted. Everything worked flawless with my testing.

One final issue is that since we replaced the auto mount it also stopped the auto sharing via Samba. You will need to…

sudo nano /etc/samba/smb-shares.conf

and use something like the following to allow you to access the drive over the network from Windows again.

[test]
    browsable = yes
    read only = no
    valid users = osmc
    path = /media/test
1 Like

@darwindesign That is a very detailed post, and I thank you so much for the time & effort required. When I saw so many posts on this thread I thought I’d opened a can of worms!

I’ll have a go at setting this up at the weekend, I luckily export the library to .nfo files, so starting afresh is quite easy (and I like to be sure there’s nothing left over from previous settings to interfere!)

Thank you again for the detailed explanation.

Your welcome. There is no need to start over or redo any part of Kodi as I purposely shaped this solution around not causing a bunch of unnecessary work. The drive you have plugged in now is auto-mounting to /media/[something] and your Kodi is setup to point to this. What I proposed is that you take that path and manually mount it to the same place so Kodi doesn’t break. You are also adding a bind mount for just the folder you want to make read only somewhere else. Thus the folder you want to protect will then exist in two locations with one having full access and the other read only. The Kodi path substitution tells it any time it goes to access that particular folder go to the read only bind mount location instead. Samba is going to point to the regular mount so it still has write access like it previously did. You modify and create those three files in the OS and reboot and nothing else. No changes are made in Kodi at all and you can undo the changes without disruption as well if you wanted. You just need to make sure that your using the exact same mount point as what is currently in use.

Making a backup with the My OSMC add-on might be advisable before you start. The files your modifying are not particularly forgiving of typos and can cause your system to not fully boot if you make too much of a mistake.

Hopefully, this has all been solved already. I didn’t notice any clear “SOLVED” feedback …

The key to understanding NTFS storage mounts is that only mount options will control permissions and those permissions are set for the entire mount. If you want the same userid to have read-only access for 1 directory and read-write access to any others, then you’ll need to have 2 different mounts.

There are some crazy tricks that can be accomplished using some types of mounts to have a single mount appear like two mounts, each with different options. This can be problematic and confusing.

Now, if there are different users involved, it can be solved other ways.
And of course, the easiest solution is to use native Linux file systems which support full Unix permissions, so chown and chmod work as expected.

If kodi has a built-in method using different libraries to control delete access, that would be fine too, I suppose. I just have a trust problem with application software. I’ve been burned too many times over the decades by other software that had tiny mistakes, so I’m a little paranoid and don’t allow any media center software the ability to delete anything.

After a weekend refitting the bathroom (joy!) I finally got around to trying this out, and it worked flawlessly.

I was concerned about the trailing slash after MovieLocked on the 2nd line of fstab, but it worked fine in my version with it there, so I’ll leave it as is!

Thanks again for all your help. I’m much more confident now that the wife & daughter wont accidentally delete something they shouldn’t!

1 Like