LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 08-12-2019, 08:00 AM   #1
sergs
LQ Newbie
 
Registered: Aug 2019
Posts: 1

Rep: Reputation: Disabled
Fail to un-mount a block device (for an mtd partition) within kernel space.


I'm trying to check if a file on a jffs2 fs exist from a kernel space. I have a Barrier Breaker OpenWrt with a 3.10.14 Linux kernel. (There's an MTD subsystem in use, so I have pseudo block devices for partitions on a NAND flash (/dev/mtdblock1, ...12).)

(I'm implementing some upgrading logic which requires keeping some state between reboots, to store this state, I use the file.)

To check a file existence I just try to open the file (without an O_CREAT flag) and make a decision based on a result of opening. I use the next article about opening a file from within kernel: Read/write files within a Linux kernel module.

I'm able to check a file existence using this approach, but this file is placed not on a rootfs partition, so I have to mount that partition before I can open the file on it. I'm able to mount the partition, open file (to check it existence) and close it, if it was opened, but failed to un-mount it: I got an error -16: EBUSY which, as I guess, means that someone else keep using this block device/mount point. So a question who can keep a reference on it?

I think it's a bad idea, but just to test, I tried to un-mount forcibly with an MNT_FORCE, but, as this article https://linux.die.net/man/2/umount states that this option only for NFS fs, nothing changed.

Here's a code:

Code:
/* lool at https://stackoverflow.com/questions/1184274/read-write-files-within-a-linux-kernel-module */
static struct file *file_open( const char *path, int flags, int rights )
{
  struct file *filp = NULL;
  mm_segment_t oldfs;
  int err = 0;

  oldfs = get_fs();
  set_fs( get_ds() );

  filp = filp_open( path, flags, rights );

  set_fs( oldfs );

  if( IS_ERR( filp ) )
  {
    err = PTR_ERR( filp );
    return NULL;
  }

  return filp;
}

bool need_to_switch_to_me_upgrade_mode( void )
{
  struct file* me_upgrade_finished_file;
  dev_t me_upgrade_dev;
  char full_name[256] = { 0 };
  bool result;
  int err;

  const char* me_upgrade_dir = "/me_upgrade";
  const char* me_upgrade_dev_name = "/dev/me_upgrade";

  const char* me_upgrade_finished_flag = "/etc/me_upgrade_finished";

  // /dev/mtdblock6
  const char* me_upgrade_finished_flag_partition = "/dev/mtdblock" str( RECOVERY_ROOTFS_DATA_MTD_PART_NUM ); 

  err = sys_mkdir( (const char __user __force *) me_upgrade_dir, 0700 );
  if( err < 0 )
    panic( "fail to mkdir %s\n", me_upgrade_dir );

  me_upgrade_dev = name_to_dev_t( me_upgrade_finished_flag_partition );
  err = create_dev( me_upgrade_dev_name, me_upgrade_dev );
  if( err < 0 )
    panic( "fail to create_dev %s\n", me_upgrade_dev_name );

  err = sys_mount( me_upgrade_dev_name, me_upgrade_dir, "jffs2", MS_SILENT, NULL );
  if( err < 0 )
    panic( "fail to mount %s on to %s, err: %d\n", me_upgrade_dev_name, me_upgrade_dir, err );

  strlcat( full_name, me_upgrade_dir, sizeof( full_name ) );
  strlcat( full_name, me_upgrade_finished_flag, sizeof( full_name ) );

  me_upgrade_finished_file = file_open( full_name, O_RDONLY, 0 );
  if( !me_upgrade_finished_file )
  {
    printk( "fail to open a %s file\n", full_name );
    result = true;
  }
  else
  {
    printk( "success to open a file\n" );
    result = false;
  }

  if( me_upgrade_finished_file )
  {
    err = filp_close( me_upgrade_finished_file, NULL );
    printk( "filp_close returned: %d\n", err );
  }

  err = sys_umount( me_upgrade_dir, MNT_DETACH );
  printk( "sys_umount returned: %d\n", err );

  sys_unlink( me_upgrade_dev_name );  // destroy_dev( me_upgrade_dev_name );
  sys_rmdir( me_upgrade_dir );

  return result;
}
This code is called from a kernel_init_freeable() function (init/main.c) after we have MTD subsystem initialized (after do_basic_setup() and before a rootfs gets mounted).

So the questions are:
  • who can keep using a block device/mount point after I closed a file?
  • is any other ways to check if file exist from within kernel?

I have a second option, just to place my state in a partition without any fs, and check it by performing a raw access to the flash memory, but this approach will require significant changes to user code I have now, so I'm trying to avoid it...

P.S. I tried to change a call to file_open/filp_close by sys_open/sys_close (with the same arguments), but nothing changed...
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
question: 'onclick' within 'onmouseover' within 'form' within 'table' - how is it possible? rblampain Programming 4 04-25-2017 08:49 PM
[SOLVED] if [[ -n "$1" ]]; then FAIL FAIL FAIL rbees Programming 7 03-25-2015 02:39 PM
Select Free MTD block gloridel Linux - Newbie 0 08-10-2011 01:33 AM
Mtd driver as block device and char device Linux_Kid_ Linux - Kernel 1 12-27-2009 12:17 PM
Does "mtd write" clear/erase the end of the mtd block by default? (no man page found) maddes.b Linux - Kernel 0 08-17-2009 03:07 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 03:58 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration