예제 #1
0
/* common functions to regular file and dir */
struct file *hidden_open(struct dentry *dentry, aufs_bindex_t bindex, int flags)
{
	struct dentry *hidden_dentry;
	struct inode *hidden_inode;
	struct super_block *sb;
	struct vfsmount *hidden_mnt;
	struct file *hidden_file;
	struct aufs_branch *br;
	loff_t old_size;
	int udba;

	LKTRTrace("%.*s, b%d, flags 0%o\n", DLNPair(dentry), bindex, flags);
	DEBUG_ON(!dentry);
	hidden_dentry = au_h_dptr_i(dentry, bindex);
	DEBUG_ON(!hidden_dentry);
	hidden_inode = hidden_dentry->d_inode;
	DEBUG_ON(!hidden_inode);

	sb = dentry->d_sb;
	udba = au_flag_test(sb, AuFlag_UDBA_INOTIFY);
	if (unlikely(udba)) {
		// test here?
	}

	br = stobr(sb, bindex);
	br_get(br);
	/* drop flags for writing */
	if (test_ro(sb, bindex, dentry->d_inode))
		flags = au_file_roflags(flags);
	flags &= ~O_CREAT;
	spin_lock(&hidden_inode->i_lock);
	old_size = i_size_read(hidden_inode);
	spin_unlock(&hidden_inode->i_lock);

	//DbgSleep(3);

	dget(hidden_dentry);
	hidden_mnt = mntget(br->br_mnt);
	hidden_file = dentry_open(hidden_dentry, hidden_mnt, flags);
	//if (LktrCond) {fput(hidden_file); hidden_file = ERR_PTR(-1);}

	if (!IS_ERR(hidden_file)) {
#if 0 // remove this
		if (/* old_size && */ (flags & O_TRUNC)) {
			au_direval_dec(dentry);
			if (!IS_ROOT(dentry))
				au_direval_dec(dentry->d_parent);
		}
#endif
		return hidden_file;
	}

	br_put(br);
	TraceErrPtr(hidden_file);
	return hidden_file;
}
예제 #2
0
int au_reopen_nondir(struct file *file)
{
	int err;
	struct dentry *dentry;
	aufs_bindex_t bstart, bindex, bend;
	struct file *hidden_file, *h_file_tmp;

	dentry = file->f_dentry;
	LKTRTrace("%.*s\n", DLNPair(dentry));
	DEBUG_ON(S_ISDIR(dentry->d_inode->i_mode)
		 || !au_h_dptr(dentry)->d_inode);
	bstart = dbstart(dentry);

	h_file_tmp = NULL;
	if (fbstart(file) == bstart) {
		hidden_file = au_h_fptr(file);
		if (file->f_mode == hidden_file->f_mode)
			return 0; /* success */
		h_file_tmp = hidden_file;
		get_file(h_file_tmp);
		set_h_fptr(file, bstart, NULL);
	}
	DEBUG_ON(fbstart(file) < bstart
		 || ftofi(file)->fi_hfile[0 + bstart].hf_file);

	hidden_file = hidden_open(dentry, bstart, file->f_flags & ~O_TRUNC);
	//if (LktrCond) {fput(hidden_file); br_put(stobr(dentry->d_sb, bstart));
	//hidden_file = ERR_PTR(-1);}
	err = PTR_ERR(hidden_file);
	if (IS_ERR(hidden_file))
		goto out; // close all?
	err = 0;
	//cpup_file_flags(hidden_file, file);
	set_fbstart(file, bstart);
	set_h_fptr(file, bstart, hidden_file);
	memcpy(&hidden_file->f_ra, &file->f_ra, sizeof(file->f_ra)); //??

	/* close lower files */
	bend = fbend(file);
	for (bindex = bstart + 1; bindex <= bend; bindex++)
		set_h_fptr(file, bindex, NULL);
	set_fbend(file, bstart);

 out:
	if (h_file_tmp)
		fput(h_file_tmp);
	TraceErr(err);
	return err;
}
예제 #3
0
static int calc_size(int namelen)
{
	int sz;

	sz = sizeof(struct aufs_de) + namelen;
	if (sizeof(ino_t) == sizeof(long)) {
		const int mask = sizeof(ino_t) - 1;
		if (sz & mask) {
			sz += sizeof(ino_t);
			sz &= ~mask;
		}
	} else {
#if 0 // remove
		BUG();
		// this block will be discarded by optimizer.
		int m;
		m = sz % sizeof(ino_t);
		if (m)
			sz += sizeof(ino_t) - m;
#endif
	}

	DEBUG_ON(sz % sizeof(ino_t));
	return sz;
}
예제 #4
0
static int do_coo(struct dentry *dentry, aufs_bindex_t bstart)
{
	int err;
	struct dentry *parent, *h_parent, *h_dentry;
	aufs_bindex_t bcpup;
	struct inode *h_dir, *h_inode, *dir;

	LKTRTrace("%.*s\n", DLNPair(dentry));
	DEBUG_ON(IS_ROOT(dentry));
	DiMustWriteLock(dentry);

	parent = dentry->d_parent; // dget_parent()
	di_write_lock_parent(parent);
	bcpup = err = find_rw_parent_br(dentry, bstart);
	//bcpup = err = find_rw_br(sb, bstart);
	if (unlikely(err < 0)) {
		err = 0; // stop copyup, it is not an error
		goto out;
	}
	err = 0;

	h_parent = au_h_dptr_i(parent, bcpup);
	if (!h_parent) {
		err = cpup_dirs(dentry, bcpup, NULL);
		if (unlikely(err))
			goto out;
		h_parent = au_h_dptr_i(parent, bcpup);
	}

	h_dir = h_parent->d_inode;
	h_dentry = au_h_dptr_i(dentry, bstart);
	h_inode = h_dentry->d_inode;
	dir = parent->d_inode;
	hdir_lock(h_dir, dir, bcpup);
	hi_lock_child(h_inode);
	DEBUG_ON(au_h_dptr_i(dentry, bcpup));
	err = sio_cpup_simple(dentry, bcpup, -1,
			      au_flags_cpup(CPUP_DTIME, parent));
	TraceErr(err);
	i_unlock(h_inode);
	hdir_unlock(h_dir, dir, bcpup);

 out:
	di_write_unlock(parent);
	TraceErr(err);
	return err;
}
예제 #5
0
interrupt
#else
#pragma code
#pragma interrupt InterruptHandlerHigh
#endif
void InterruptHandlerHigh() {
    // We need to check the interrupt flag of each enabled high-priority interrupt to
    // see which device generated this interrupt.  Then we can call the correct handler.

    // check to see if we have an I2C interrupt
    if (PIR1bits.SSPIF) {
        // clear the interrupt flag
        PIR1bits.SSPIF = 0;
        // call the handler
        DEBUG_ON(I2C_ISR);
        i2c_int_handler();
        DEBUG_OFF(I2C_ISR);
    }

    // check to see if we have an interrupt on timer 0
    if (INTCONbits.TMR0IF) {
        DEBUG_ON(TIMER0_ISR);
        INTCONbits.TMR0IF = 0; // clear this interrupt flag
        // call whatever handler you want (this is "user" defined)
        timer0_int_handler();
        DEBUG_OFF(TIMER0_ISR);
    }

    // here is where you would check other interrupt flags.
    if (PIR1bits.ADIF) {
        // clear the interrupt flag
        DEBUG_OFF(ADC_START);  
        PIR1bits.ADIF = 0;
        // call the handler
        //DEBUG_ON(ADC_START);
        adc_int_handler();
        //DEBUG_OFF(ADC_START);
    }

    // The *last* thing I do here is check to see if we can
    // allow the processor to go to sleep
    // This code *DEPENDS* on the code in messages.c being
    // initialized using "init_queues()" -- if you aren't using
    // this, then you shouldn't have this call here
    SleepIfOkay();
}
static void *pd_iter_first_de(struct exfat_parse_data *pd,
			      struct exfat_parse_iter_data *pd_iter)
{
	DEBUG_ON(pd->size < EXFAT_CHUNK_SIZE, "pd->size %lu\n", pd->size);
	pd_iter->left = pd->size - EXFAT_CHUNK_SIZE;
	pd_iter->bh_offset = pd->bh_offset;
	pd_iter->bh_index = 0;
	return pd_get_chunk(pd);
}
예제 #7
0
/** Resets the ZNP using hardware and retrieves the SYS_RESET_IND message. 
This method is used to restart the ZNP's internal state machine and apply changes to startup options, zigbee device type, etc.
@post znpResult contains the error code, or ZNP_SUCCESS if success.
@return a pointer to the beginning of the version structure, or a pointer to indeterminate data if error.
@see Interface Specification for order of fields
*/
unsigned char* znpReset()
{
    RADIO_OFF();
    DEBUG_OFF();
    delayMs(1);
    RADIO_ON(); 
    DEBUG_ON();
    znpResult = spiPoll();              //Note: this will be different if UART
    return (znpBuf+SRSP_PAYLOAD_START);  //the beginning of the reset indication string
}
void timer0_int_handler() {
    // Encoder count for motor 0.
    timer0Counter++;
    // Reset the timer
    WriteTimer0(0xCF);

    DEBUG_ON(TMR0_DBG);
    DEBUG_OFF(TMR0_DBG);

    if (ticks_flag) {
        // Reverse counter to prevent it from going a set distance.
        ticks0Counter++;
        // Going thru right hand turn
        if (ticks0Counter >= maxTickZero && postRight == 1) {
            postRight = 2;
            WriteUSART(0x00);
            // Turn right 90
            motorBuffer[0] = 0x01;
            motorBuffer[1] = 0x03;
            motorBuffer[2] = 0x04;
            motorBuffer[3] = 0x01;
            motorBuffer[4] = 0x0C;
            motorBuffer[5] = 0x09;

            ToMainHigh_sendmsg(MOTORLEN, MSGT_I2C_DATA, (void *) motorBuffer);
        } else if (ticks0Counter >= maxTickZero && postRight == 2) {
            // Move forward after right turn
            postRight = 0;

            motorBuffer[0] = 0x01;
            motorBuffer[1] = 0x03;
            motorBuffer[2] = 0x01;
            motorBuffer[3] = 0x01;
            motorBuffer[4] = 0x00;
            motorBuffer[5] = 0x00;

            ToMainHigh_sendmsg(MOTORLEN, MSGT_I2C_DATA, (void *) motorBuffer);
        } else if (ticks0Counter >= maxTickZero && postAlignFlag) {
            postAlignFlag = 0;
            motorBuffer[0] = 0x01;
            motorBuffer[1] = 0x03;
            motorBuffer[2] = 0x01;
            motorBuffer[3] = 0x01;
            motorBuffer[4] = 0x00;
            motorBuffer[5] = 0x00;

            ToMainHigh_sendmsg(MOTORLEN, MSGT_I2C_DATA, (void *) motorBuffer);
        } else if (ticks0Counter >= maxTickZero) {
            //Stops wheels after set number of ticks
            WriteUSART(0x00);
        }
    }
}
예제 #9
0
void main(void) {
    char c;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;
    uart_thread_struct uthread_data; // info for uart_lthread
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    timer0_thread_struct t0thread_data; // info for timer0_lthread

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
#ifdef __USE18F45J10
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on
#else
#ifdef __USE18F26J50
    OSCCON = 0xE0; // see datasheeet
    OSCTUNEbits.PLLEN = 1;
#else
#ifdef __USE18F46J50
    OSCCON = 0xE0; //see datasheet
    OSCTUNEbits.PLLEN = 1;

        //Initialize
    TRISEbits.TRISE0 = 0x0;
    LATEbits.LE0 = 0x0;
    LATEbits.LE0 = 0x1;

    TRISCbits.TRISC7 = 0x1; // input RX
    TRISCbits.TRISC6 = 0x0; // output TX

    SPBRGH1 = 0x00;
    SPBRG1 = 0xcf;

    TXSTA1bits.BRGH = 1;
    BAUDCON1bits.BRG16 = 1;
    TXSTA1bits.SYNC = 0;
    RCSTA1bits.SPEN = 0x1;
    TXSTA1bits.TXEN = 0x1;
#else
    Something is messed up.
    The PIC selected is not supported or the preprocessor directives are wrong.
#endif
#endif
#endif
#endif

    // initialize my uart recv handling code
    init_uart_recv(&uc);

    // initialize the i2c code
    init_i2c(&ic);

    // init the timer1 lthread
    init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

#ifndef __USE18F26J50
    // set direction for PORTB to output
    TRISB = 0x0;
    LATB = 0x0;
#endif



    // how to set up PORTA for input (for the V4 board with the PIC2680)
    /*
            PORTA = 0x0;	// clear the port
            LATA = 0x0;		// clear the output latch
            ADCON1 = 0x0F;	// turn off the A2D function on these pins
            // Only for 40-pin version of this chip CMCON = 0x07;	// turn the comparator off
            TRISA = 0x0F;	// set RA3-RA0 to inputs
     */

    //Initialize the ADC module
    ADC_Init();

    // initialize Timers
    OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_64);
    
#ifdef __USE18F26J50
    // MTJ added second argument for OpenTimer1()
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
#ifdef __USE18F46J50
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
    OpenTimer1(TIMER_INT_ON & T1_PS_1_8 & T1_16BIT_RW & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
    
#endif
#endif

    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high
    // Timer1 interrupt
    IPR1bits.TMR1IP = 0;
    // USART RX interrupt
    IPR1bits.RCIP = 0;
    // I2C interrupt
    IPR1bits.SSPIP = 1;

    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
#if 1
    // Note that the temperature sensor Address bits (A0, A1, A2) are also the
    // least significant bits of LATB -- take care when changing them
    // They *are* changed in the timer interrupt handlers if those timers are
    //   enabled.  They are just there to make the lights blink and can be
    //   disabled.
    i2c_configure_slave(0x9E);
#else
    // If I want to test the temperature sensor from the ARM, I just make
    // sure this PIC does not have the same address and configure the
    // temperature sensor address bits and then just stay in an infinite loop
    i2c_configure_slave(0x9A);
#ifdef __USE18F2680
    LATBbits.LATB1 = 1;
    LATBbits.LATB0 = 1;
    LATBbits.LATB2 = 1;
#endif
    for (;;);
#endif

    // must specifically enable the I2C interrupts
    PIE1bits.SSPIE = 1;

    // configure the hardware USART device
#ifdef __USE18F26J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
#ifdef __USE18F46J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
#endif
#endif

    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    /* Junk to force an I2C interrupt in the simulator (if you wanted to)
    PIR1bits.SSPIF = 1;
    _asm
    goto 0x08
    _endasm;
     */

    // printf() is available, but is not advisable.  It goes to the UART pin
    // on the PIC and then you must hook something up to that to view it.
    // It is also slow and is blocking, so it will perturb your code's operation
    // Here is how it looks: printf("Hello\r\n");

    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER0:
                {
                    DEBUG_ON(TIMER0_MSG_RCV);
                    timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                    DEBUG_OFF(TIMER0_MSG_RCV);
                    break;
                };
                case MSGT_I2C_DATA:
                case MSGT_I2C_DBG:
                {
                    // Here is where you could handle debugging, if you wanted
                    // keep track of the first byte received for later use (if desired)
                    last_reg_recvd = msgbuffer[0];
                    break;
                };
                case MSGT_I2C_RQST:
                {
                    // Generally, this is *NOT* how I recommend you handle an I2C slave request
                    // I recommend that you handle it completely inside the i2c interrupt handler
                    // by reading the data from a queue (i.e., you would not send a message, as is done
                    // now, from the i2c interrupt handler to main to ask for data).
                    //
                    // The last byte received is the "register" that is trying to be read
                    // The response is dependent on the register.
                    switch (last_reg_recvd) {
                        case 0xaa:
                        {
                            length = 2;
                            msgbuffer[0] = 0x55;
                            msgbuffer[1] = 0xAA;
                            break;
                        }
                        case 0xa8:
                        {
                            length = 1;
                            msgbuffer[0] = 0x3A;
                            break;
                        }
                        case 0xa9:
                        {
                            length = 1;
                            msgbuffer[0] = 0xA3;
                            break;
                        }
                    };
                    start_i2c_slave_reply(length, msgbuffer);
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } else {
            switch (msgtype) {
                case MSGT_TIMER1:
                {
                    timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                    break;
                };
                case MSGT_OVERRUN:
                case MSGT_UART_DATA:
                {
                    SensorData_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
                    unsigned int *msgval;
                    msgval = (unsigned int *) msgbuffer;
                    unsigned int val = *msgval;
                    uart_lthread(&uthread_data, msgtype, length, &val);

                    //unsigned char *msgbuf = msgbuffer;
                    //unsigned int* newval = (unsigned int *) msgbuf;
                    //*newval is the ADC result in hex format
                    //uart_lthread(&uthread_data, msgtype, length, msgbuffer);
                    break;
                };
                default:
                {
                    // Your code should handle this error
                    break;
                };
            };
        }
    }

}
예제 #10
0
파일: backnum.c 프로젝트: qiuqi/SysToolsLib
int main(int argc, char *argv[]) {
  char *pszMyFile = NULL;
  char szPath[_MAX_PATH];
  char szDrive[_MAX_DRIVE];
  char szDir[_MAX_DIR];
  char *pszDir = szDir;
  char szFname[_MAX_FNAME];
  char szExt[_MAX_EXT];
  char szBasename[_MAX_PATH];		/* Initial szFname + szExt */
  int err;
  int iOffset;
  int iMax;
  int i;
  char *pszExactCaseNameFound = NULL;
  char *pszOtherCaseNameFound = NULL;

  for (i=1 ; i<argc ; i++) {
    if (IsSwitch(argv[i])) {   		/* It's a switch */
      if (   streq(argv[i]+1, "?")
	  || streq(argv[i]+1, "h")
	  || streq(argv[i]+1, "-help")
	 ) {				/* -?: Help */
	usage();                        	/* Display help */
	return 0;
      }
#ifndef _MSDOS
      if (streq(argv[i]+1, "a")) {		/* -a: Append the extension */
	iAppend = TRUE;
	continue;
      }
      if (streq(argv[i]+1, "A")) {		/* -A: Replace the extension */
	iAppend = FALSE;
	continue;
      }
#endif
#ifdef _DEBUG
      if (streq(argv[i]+1, "d")) {	/* -d: Debug information */
	DEBUG_ON();
	continue;
      }
#endif
      if (streq(argv[i]+1, "q")) {		/* -q: Be quiet */
	iQuiet = TRUE;
	continue;
      }
#ifdef _DEBUG
      if (streq(argv[i]+1, "t")) {
	closedir(opendir(argv[i+1]));
	exit(0);
      }
#ifdef _MSDOS
      if (streq(argv[i]+1, "T")) {
	opendir("");
	for (i=0; i<_sys_nerr; i++) printf("errno=%d: %s\n", i, strerror(i));
	exit(0);
      }
#endif
#endif
      if (streq(argv[i]+1, "v")) {		/* -v: Verbose information */
	iVerbose = TRUE;
	continue;
      }
      if (streq(argv[i]+1, "V")) {		/* -V: Display the version */
	printf("%s\n", VERSION);
	exit(0);
      }
      if (streq(argv[i]+1, "X")) {		/* -X: Do not execute */
	iExec = FALSE;
	continue;
      }
      /* Unsupported switch! */
      fprintf(stderr, "Unsupported switch, ignored: %s", argv[i]);
      continue;
    }
    if (!pszMyFile) {
      pszMyFile = argv[i];
      continue;
    }
    /* Unsupported argument */
    fprintf(stderr, "Unsupported argument, ignored: %s", argv[i]);
  }

  if (!pszMyFile) {
    usage();
    exit(0);
  }

  /* Check if the specified file exists. */
  /* Note: The file name case matching is file system specific, _not_ OS specific.
	   Use the access() result as a proof of existence and readability,
	   whether the case matches or not, and independantly of the host OS. */
  if (access(pszMyFile, R_OK)) {
    fprintf(stderr, "Error: File %s: %s!\n", pszMyFile, strerror(errno));
    exit(1);
  }

  _splitpath(pszMyFile, szDrive, szDir, szFname, szExt);
  DEBUG_PRINTF(("\"%s\" \"%s\" \"%s\" \"%s\"\n", szDrive, szDir, szFname, szExt));
  _makepath(szBasename, NULL, NULL, szFname, szExt);
  DEBUG_PRINTF(("szBasename = \"%s\";\n", szBasename));
  if (iAppend && szExt[0]) {
   strcat(szFname, szExt); /* The period is already in szExt */
  }
  if (!szDir[0]) pszDir = ".";

  /* Now scan all existing backups, to find the largest backup number used. */
  _makepath(szPath, szDrive, pszDir, NULL, NULL);
  iOffset = (int)strlen(szFname) + 1;
  DEBUG_PRINTF(("iOffset = %d; // Backup suffix offset\n", iOffset));
  iMax = 0;

  {
    DIR *pDir;
    struct dirent *pDE;
    char szPattern[_MAX_PATH];

    pDir = opendir(szPath);
    if (!pDir) {
      fprintf(stderr, "Error: Directory %s: %s\n", szPath, strerror(errno));
      exit(1);
    }

    _makepath(szPattern, NULL, NULL, szFname, "*");

    while ((pDE = readdir(pDir))) {
      if (pDE->d_type != DT_REG) continue;	/* We want only files */

      /* Check the case of the base file */
      if (!_stricmp(szBasename, pDE->d_name)) {
      	if (!strcmp(szBasename, pDE->d_name)) { /* This can happen only once */
      	  pszExactCaseNameFound = strdup(pDE->d_name);
	  DEBUG_PRINTF(("// Found base name with exact case: \"%s\"\n", pszExactCaseNameFound));
      	} else if (!pszOtherCaseNameFound) {	/* Else can happen many times */
      	  pszOtherCaseNameFound = strdup(pDE->d_name);
	  DEBUG_PRINTF(("// Found base name with != case: \"%s\"\n", pszOtherCaseNameFound));
      	}
      }

      /* Check files that match the wildcard pattern */
      if (fnmatch(szPattern, pDE->d_name, FNM_CASEFOLD) == FNM_MATCH) {
	int i = 0;
	DEBUG_PRINTF(("// Found backup name: \"%s\"\n", pDE->d_name));
	sscanf(pDE->d_name + iOffset, "%03d", &i);
	if (i > iMax) iMax = i;
	DEBUG_PRINTF(("iMax = %d;\n", iMax));
      }
    }

    closedir(pDir);
  }

  /* Correct the file name case if needed */
  /* Note: Unix file systems are case dependant, Microsoft file systems are not.
     But Linux accessing a Microsoft file system across the network will _also_
     be case _independant_. "cat HeLlO.tXt" _will_ successfully read file hello.txt.
     So if the file passed the access() test above, then we _must_ correct the
     case now, for all operating systems _even_ for Unix. */
  strcpy(szPath, pszMyFile);
  if (pszOtherCaseNameFound && !pszExactCaseNameFound) {
    DEBUG_PRINTF(("// Correcting case: \"%s\"\n", pszOtherCaseNameFound));
    _splitpath(pszOtherCaseNameFound, NULL, NULL, szFname, szExt);
    _makepath(szPath, szDrive, szDir, szFname, szExt);
    if (iAppend && szExt[0]) {
     strcat(szFname, szExt); /* The period is already in szExt */
    }
  }
  if (iVerbose && !iQuiet) printf("Backing up %s\n", szPath);

  /* Generate the backup file name */
  sprintf(szExt, ".%03d", iMax+1);
  _makepath(szPath, szDrive, szDir, szFname, szExt);
  if (!iQuiet) printf("%s%s\n", iVerbose ? "        as " : "", szPath);

  /* Backup the file */
  err = 0;
  if (iExec) err = fcopy(szPath, pszMyFile);
  switch (err) {
    case 0: break; /* Success */
    case 1: fprintf(stderr, "Not enough memory.\n"); break;
    case 2: fprintf(stderr, "Error reading from %s.\n", argv[2]); break;
    case 3: fprintf(stderr, "Error writing to %s.\n", argv[3]); break;
    default: {
#if defined(_WIN32)
      LPVOID lpMsgBuf;
      if (FormatMessage(
	FORMAT_MESSAGE_ALLOCATE_BUFFER |
	FORMAT_MESSAGE_FROM_SYSTEM |
	FORMAT_MESSAGE_IGNORE_INSERTS,
	NULL,
	err,
	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
	(LPTSTR) &lpMsgBuf,
	0,
	NULL )) {
	fprintf(stderr, "Error. %s\n", lpMsgBuf);
	LocalFree( lpMsgBuf );     /* Free the buffer */
      } else {
	fprintf(stderr, "Unexpected return value: %d\n", err); break;
      }
#else
      fprintf(stderr, "Unexpected return value: %d\n", err); break;
#endif
      break;
    }
  }

  return err;
}
예제 #11
0
int main(int argc, char *argv[])
    {
    int i;
    char *f1arg = NULL;         /* File 1 name provided */
    char *f2arg = NULL;         /* File 2 name provided */
    char *name1;                /* File 1 name found */
    char *name2;                /* File 2 name found */
    dict_t *dict1;		/* File 1 sections dictionary */
    dict_t *dict2;		/* File 2 sections dictionary */

    for (i=1; i<argc; i++)
        {
        if (IsSwitch(argv[i])) /* It's a switch */
            {
            if (   streq(argv[i]+1, "help")
                || streq(argv[i]+1, "h")
                || streq(argv[i]+1, "?"))
                {
                usage();
                }
            if (streq(argv[i]+1, "b"))
                {
                compBlanks = TRUE;
                continue;
                }
            if (streq(argv[i]+1, "c"))
                {
                ignoreCase = FALSE;
                continue;
                }
            if (streq(argv[i]+1, "C"))
                {
                ignoreCase = TRUE;
                continue;
                }
            DEBUG_CODE(
            if (   streq(argv[i]+1, "debug")
                || streq(argv[i]+1, "d"))
                {
                DEBUG_ON();
                verbose = TRUE;
                continue;
                }
                )
            if (   streq(argv[i]+1, "verbose")
                || streq(argv[i]+1, "v"))
                {
                verbose = TRUE;
                continue;
                }
            if (   streq(argv[i]+1, "version")
                || streq(argv[i]+1, "V"))
                {
		puts(DETAILED_VERSION);
                exit(0);
                }
            printf("Unrecognized switch %s. Ignored.\n", argv[i]);
            continue;
            }
        if (!f1arg)
            {
            f1arg = argv[i];
            continue;
            }
        if (!f2arg)
            {
            f2arg = argv[i];
            continue;
            }
        printf("Unexpected argument: %s\nIgnored.\n", argv[i]);
        break;  /* Ignore other arguments */
        }
예제 #12
0
int main(int argc, char *argv[]) {
  int i;
  char *pszPath = NULL;
  ssize_t n = -1;
  char buf[FILENAME_MAX] = "";
  char absName[FILENAME_MAX];
  int bGetAbsName = TRUE;
  int bResolveLinks = TRUE;
  int bResolveShortNames = TRUE;

  for (i=1; i<argc; i++) {
    char *arg = argv[i];
    if (IsSwitch(arg)) {	/* It's a switch */
#ifdef _WIN32
      if (streq(arg+1, "A")) {	/* Force encoding output with the ANSI code page */
	cp = CP_ACP;
	continue;
      }
#endif
      DEBUG_CODE(
	if (streq(arg+1, "d")) {
	  DEBUG_ON();
	  continue;
	}
      )
      if (   streq(arg+1, "help")
	  || streq(arg+1, "-help")
	  || streq(arg+1, "h")
	  || streq(arg+1, "?")) {
	usage();
      }
      if (streq(arg+1, "l")) {	/* Resolve links */
	bResolveLinks = TRUE;
	continue;
      }
      if (streq(arg+1, "L")) {	/* Do not resolve links */
	bResolveLinks = FALSE;
	continue;
      }
#ifdef _WIN32
      if (streq(arg+1, "O")) {	/* Force encoding output with the OEM code page */
	cp = CP_OEMCP;
	continue;
      }
#endif
      if (streq(arg+1, "r")) {	/* Resolve relative paths = Get the absolute pathname */
	bGetAbsName = TRUE;
	continue;
      }
      if (streq(arg+1, "R")) {	/* Do not resolve relative paths = do not get the absolute pathname */
	bGetAbsName = FALSE;
	continue;
      }
      if (streq(arg+1, "s")) {	/* Resolve short names */
	bResolveShortNames = TRUE;
	continue;
      }
      if (streq(arg+1, "S")) {	/* Do not resolve short names */
	bResolveShortNames = FALSE;
	continue;
      }
#ifdef _WIN32
      if (streq(arg+1, "U")) {	/* Force encoding output with the UTF-8 code page */
	cp = CP_UTF8;
	continue;
      }
#endif
      if (streq(arg+1, "V")) {	/* Display version */
	printf("%s\n", version());
	exit(0);
      }
      printf("Unrecognized switch %s. Ignored.\n", arg);
      continue;
    } /* End if it's a switch */
    /* If it's an argument */
    if (!pszPath) {
      pszPath = arg;
      continue;
    }
    printf("Unexpected argument %s. Ignored.\n", arg);
    continue;
  }
예제 #13
0
파일: debugger.c 프로젝트: aunali1/exopc
void debugger(void)
{
    extern u_int history[3];
    extern int irq0_pending;
    static int in_debugger = 0;
    char buf[80], buf2[80], reg[4];
    u_int i, j, k;

    if (in_debugger)
	return;
    in_debugger ++;
    no_exceptions = 1;

#if 0
    char *textbuf;
    textbuf = (char*)malloc(TEXT_SIZE);
    if (!textbuf) {
	leaveemu(ERR_MEM);
    }
    memcpy(textbuf, SCR_STATE.virt_address, TEXT_SIZE);
#endif

    push_debug_flags();
    DEBUG_OFF();

    for(;;) {
	printf("\ndbg> ");
	if (fgets(buf, 80, stdin) == NULL)
	    leaveemu(0);
	buf[strlen(buf)-1] = 0;  /* kill \n */
	
	if (*buf==0) {
	    continue;
	} else if (!strcmp(buf, "help")) {
	    usage();
	} else if (!strcmp(buf, "r")) {
	    show_regs(0, 0);
	} else if (!strcmp(buf, "logue")) {
	    printf("prologue:  0x%08x\n", UAREA.u_entprologue);
	    printf("epilogue:  0x%08x\n", UAREA.u_entepilogue);
	} else if (!strcmp(buf, "exc")) {
	    printf("current exception:       #0x%x, 0x%x\n", vm86s.trapno, vm86s.err);
	    printf("pending guest exception: ");
	    if (vmstate.exc)
		printf("#0x%x, 0x%x\n", vmstate.exc_vect, vmstate.exc_erc);
	    else
		printf("none\n");
	} else if (!strcmp(buf, "cr")) {
	    show_cregs();
	} else if (!strcmp(buf, "g")) {
	    REG(eflags) &= ~TF_MASK;
	    break;
	} else if (!strcmp(buf, "q") || !strcmp(buf, "quit")) {
	    leaveemu(0);
	} else if (!strcmp(buf, "disks")) {
	    print_disks();
	} else if (!strcmp(buf, "ptmap")) {
	    /* everything is in k to avoid overflows */
	    u_int granularity = 4*1024;
	    u_int width = 64;
	    printf("granularity:  0x%08x\n", granularity*1024);

	    for (i=0; i < (4*1024*1024)/(width*granularity); i++) {
		u_int start = i*width*granularity;
		printf("0x%08x  ", start*1024);
		for (j=0; j<width; j++) {
		    int gp = 0, hp = 0;
		    for (k=0; k < granularity/NBPG; k++) {
			u_int pte, err=0;
			pte = sys_read_pte(k*NBPG + (j*granularity + i*width*granularity)*1024, 0, vmstate.eid, &err);
			if (err == -E_NOT_FOUND) {
			    err = pte = 0;
			}			    
			if (err == 0) {
			    if (pte&1) {
				if (pte & PG_GUEST)
				    gp = 1;
				else
				    hp = 1;
			    }
			}
		    }
		    if (!gp && !hp)
			printf("-");
		    else if (gp && hp)
			printf("+");
		    else if (gp && !hp)
			printf("g");
		    else
			printf("h");
		}
		printf("\n");
	    }
#if 0
	} else if (!strcmp(buf, "memmap")) {
	    memcheck_dump();
#endif
	} else if (sscanf(buf, "port %x", &i) == 1) {
	    print_port(i);
	} else if (sscanf(buf, "int %x", &i) == 1) {
	    pop_debug_flags();
	    push_debug_flags();
	    no_exceptions = 0;
	    do_int(i);
	    no_exceptions = 1;
	    DEBUG_OFF();
	} else if (sscanf(buf, "gdt %x", &i) == 1) {
	    struct descr *sd;
	    if (set_get_any(&vmstate.g_gdt_base, (u_int*)&sd)) {
		printf("no gdt is defined\n");
		continue;
	    }
	    print_dt_entry(i, sd);
	} else if (sscanf(buf, "idt %x", &i) == 1) {
	    print_dt_entry(i, (struct descr *)vmstate.g_idt_base);
	} else if (sscanf(buf, "ro %x", &i) == 1) {
	    protect_range(PGROUNDDOWN(i), NBPG);
	} else if (sscanf(buf, "rw %x", &i) == 1) {
	    unprotect_range(PGROUNDDOWN(i), NBPG);
	} else if (!strcmp(buf, "history")) {
	    printf("most recent trap eip:  %x  %x  %x\n", history[2], history[1], history[0]);
	} else if (!strcmp(buf, "irq")) {
	    struct gate_descr *sg = (struct gate_descr *)vmstate.g_idt_base + hardware_irq_number(0);
	    for (i=0; i<16; i++) {
		printf("irq %2d %s, handled by idt[%2d], function @ 0x%08x\n", i, irq_disabled(i) ? "disabled" : " enabled",
		       hardware_irq_number(i), GATE_OFFSET(sg+i));
	    }	    
	} else if (sscanf(buf, "dump %x:%x %x", &i, &j, &k) == 2) {
	    dump_memory((i<<4)+j, k);
	} else if (sscanf(buf, "dump %x:%x", &i, &j) == 2) {
	    dump_memory((i<<4)+j, 0x80);
	} else if (sscanf(buf, "dump %x %x", &i, &j) == 2) {
	    dump_memory(i, j);
	} else if (sscanf(buf, "dump %x", &i) == 1) {
	    dump_memory(i, 0x80);
	} else if (!strcmp(buf, "dump")) {
	    dump_memory(dump_offset, 0x80);
	} else if (sscanf(buf, "search %x %79s", &i, buf2) == 2) {
	    search_memory(i, buf2);
	} else if (!strcmp(buf, "debug on")) {
	    pop_debug_flags();
	    DEBUG_ON();
	    push_debug_flags();
	} else if (!strcmp(buf, "debug off")) {
	    pop_debug_flags();
	    DEBUG_OFF();
	    push_debug_flags();
	} else if (sscanf(buf, "pte %x", &i) == 1) {
	    Bit32u host_pte = 0;
	    
	    if (! (vmstate.cr[0] & PG_MASK)) {
	    	printf("guest paging not enabled\n");
		printf("guest_phys_to_host_phys(0x%08x) = 0x%08x\n", i, guest_phys_to_host_phys(i));
	    } else {
		Bit32u gpte = guest_pte(i);
		
		printf("guest cr3           0x%08x\n", vmstate.cr[3]);
		printf("guest 0x%08x -> 0x%08x\n", i, gpte);
		printf("guest_phys_to_host_phys(0x%08x) = 0x%08x\n", gpte & ~PGMASK, guest_phys_to_host_phys(gpte & ~PGMASK));
	    }
	    get_host_pte(i, &host_pte);
	    printf("host  0x%08x -> 0x%08x\n", i, host_pte);
	} else if (sscanf(buf, "gp2hp %x", &i) == 1) {
	    printf("&vmstate.gp2hp[0] = %p, 0x%x mappings\n", vmstate.gp2hp, vmstate.ppages);
	    if (i<vmstate.ppages)
		printf("gp2hp[%x] = 0x%08x\n", i, vmstate.gp2hp[i]);
	} else if (!strcmp(buf, "cr3")) {
	    u_int cr3;
	    Set *set = &vmstate.cr3;

	    printf("cr3 register:  0x%08x\n", vmstate.cr[3]);
	    printf("cr3 set     :  ");
	    for(set_iter_init(set); set_iter_get(set, &cr3); set_iter_next(set)) {
		printf("0x%08x ", cr3);
	    }
	    printf("\n");
	} else if (!strcmp(buf, "dt")) {
	    print_dt_mappings();
	    printf("h gdt base:lim  0x%08x:0x%04x\n", vmstate.h_gdt_base, vmstate.h_gdt_limit);
	    printf("h idt base:lim  0x%08x:0x%04x\n", vmstate.h_idt_base, vmstate.h_idt_limit);
	} else if (!strcmp(buf, "memory")) {
	    printf("0x%08x real physical pages (%3d megs)\n", PHYSICAL_PAGES, PHYSICAL_MEGS_RAM);
	    printf("0x%08x fake physical pages (%3d megs)\n", vmstate.ppages, config.phys_mem_size/1024);
#if 0
	    printf("Eavesdropping on Linux:\n");
	    printf("RAM               %dk\n",   *((Bit32u*)0x901e0));
	    printf("pointing device?  0x%x\n",  *((Bit16u*)0x901ff));
	    printf("APM?              0x%x\n",  *((Bit16u*)0x90040));
#endif
	    ASSERT(vmstate.ppages == config.phys_mem_size*1024/NBPG);
	} else if (sscanf(buf, "%2s=%x", reg, &i) == 2 || 
		   sscanf(buf, "%3s=%x", reg, &i) == 2) {
	    int r = reg_s2i(reg);
	    if (r == -1) {
		printf("unknown register\n");
	    } else if (r==14) {
		REG(eip) = i;
	    } else if (r<=REGNO_EDI) {
		set_reg(r, i, 4);  /* normal regs */
	    } else {
		set_reg(r, i, 2);  /* segment regs */
	    }
	} else {
	    printf("huh?\n");
	}
    }

    pop_debug_flags();

#if 0
    if (debug_flags == 0)
	memcpy(SCR_STATE.virt_address, textbuf, TEXT_SIZE);
    free(textbuf);
#endif

    REG(eflags) |= RF;

    in_debugger --;
    no_exceptions = 0;
    irq0_pending = 0;
}
예제 #14
0
int aufs_rmdir(struct inode *dir, struct dentry *dentry)
{
	int err, rmdir_later;
	struct inode *inode, *hidden_dir;
	struct dentry *parent, *wh_dentry, *hidden_dentry, *hidden_parent;
	struct dtime dt;
	aufs_bindex_t bwh, bindex, bstart;
	struct rmdir_whtmp_arg *arg;
	struct aufs_nhash *whlist;

	LKTRTrace("i%lu, %.*s\n", dir->i_ino, DLNPair(dentry));
	IMustLock(dir);
	inode = dentry->d_inode;
	if (unlikely(!inode))
		return -ENOENT; // possible?
	IMustLock(inode);

	whlist = nhash_new(GFP_KERNEL);
	err = PTR_ERR(whlist);
	if (IS_ERR(whlist))
		goto out;

	err = -ENOMEM;
	arg = kmalloc(sizeof(*arg), GFP_KERNEL);
	//arg = NULL;
	if (unlikely(!arg))
		goto out_whlist;

	aufs_read_lock(dentry, AUFS_D_WLOCK);
	parent = dentry->d_parent;
	di_write_lock_parent(parent);
	err = test_empty(dentry, whlist);
	//err = -1;
	if (unlikely(err))
		goto out_arg;

	bstart = dbstart(dentry);
	bwh = dbwh(dentry);
	bindex = -1;
	wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/ 1, &bindex, &dt);
	//wh_dentry = ERR_PTR(-1);
	err = PTR_ERR(wh_dentry);
	if (IS_ERR(wh_dentry))
		goto out_arg;

	hidden_dentry = au_h_dptr(dentry);
	dget(hidden_dentry);
	hidden_parent = hidden_dentry->d_parent;
	hidden_dir = hidden_parent->d_inode;

	rmdir_later = 0;
	if (bindex == bstart) {
		IMustLock(hidden_dir);
		err = renwh_and_rmdir(dentry, bstart, whlist, dir);
		//err = -1;
		if (err > 0) {
			rmdir_later = err;
			err = 0;
		}
	} else {
		DEBUG_ON(!wh_dentry);
		hidden_parent = wh_dentry->d_parent;
		DEBUG_ON(hidden_parent != au_h_dptr_i(parent, bindex));
		hidden_dir = hidden_parent->d_inode;
		IMustLock(hidden_dir);
		err = 0;
	}

	if (!err) {
		au_reset_hinotify(inode, /*flags*/0);
		inode->i_nlink = 0;
		set_dbdiropq(dentry, -1);
		epilog(dir, dentry, bindex);

		if (rmdir_later) {
			kick_rmdir_whtmp(hidden_dentry, whlist, bstart, dir,
					 inode, arg);
			arg = NULL;
		}

		goto out_unlock; /* success */
	}

	/* revert */
	LKTRLabel(revert);
	if (wh_dentry) {
		int rerr;
		rerr = do_revert(err, wh_dentry, dentry, bwh, &dt,
				 need_dlgt(dir->i_sb));
		if (rerr)
			err = rerr;
	}

 out_unlock:
	hdir_unlock(hidden_dir, dir, bindex);
	dput(wh_dentry);
	dput(hidden_dentry);
 out_arg:
	di_write_unlock(parent);
	aufs_read_unlock(dentry, AUFS_D_WLOCK);
	kfree(arg);
 out_whlist:
	nhash_del(whlist);
 out:
	TraceErr(err);
	return err;
}
예제 #15
0
/* returns,
 * 0: wh is unnecessary
 * plus: wh is necessary
 * minus: error
 */
int wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup,
		   struct dentry *locked)
{
	int need_wh, err;
	aufs_bindex_t bstart;
	struct dentry *hidden_dentry;
	struct super_block *sb;

	LKTRTrace("%.*s, isdir %d, *bcpup %d, locked %p\n",
		  DLNPair(dentry), isdir, *bcpup, locked);
	sb = dentry->d_sb;

	bstart = dbstart(dentry);
	LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart);
	hidden_dentry = au_h_dptr(dentry);
	if (*bcpup < 0) {
		*bcpup = bstart;
		if (test_ro(sb, bstart, dentry->d_inode)) {
			*bcpup = err = find_rw_parent_br(dentry, bstart);
			//*bcpup = err = find_rw_br(sb, bstart);
			//err = -1;
			if (unlikely(err < 0))
				goto out;
		}
	} else
		DEBUG_ON(bstart < *bcpup
			 || test_ro(sb, *bcpup, dentry->d_inode));
	LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart);

	if (*bcpup != bstart) {
		err = cpup_dirs(dentry, *bcpup, locked);
		//err = -1;
		if (unlikely(err))
			goto out;
		need_wh = 1;
	} else {
		//struct nameidata nd;
		aufs_bindex_t old_bend, new_bend, bdiropq = -1;
		old_bend = dbend(dentry);
		if (isdir) {
			bdiropq = dbdiropq(dentry);
			set_dbdiropq(dentry, -1);
		}
		err = need_wh = lkup_dentry(dentry, bstart + 1, /*type*/0);
		//err = -1;
		if (isdir)
			set_dbdiropq(dentry, bdiropq);
		if (unlikely(err < 0))
			goto out;
		new_bend = dbend(dentry);
		if (!need_wh && old_bend != new_bend) {
			set_h_dptr(dentry, new_bend, NULL);
			set_dbend(dentry, old_bend);
#if 0
		} else if (!au_h_dptr_i(dentry, new_bend)->d_inode) {
			LKTRTrace("negative\n");
			set_h_dptr(dentry, new_bend, NULL);
			set_dbend(dentry, old_bend);
			need_wh = 0;
#endif
		}
	}
	LKTRTrace("need_wh %d\n", need_wh);
	err = need_wh;

 out:
	TraceErr(err);
	return err;
}
예제 #16
0
int aufs_unlink(struct inode *dir, struct dentry *dentry)
{
	int err, dlgt;
	struct inode *inode, *hidden_dir;
	struct dentry *parent, *wh_dentry, *hidden_dentry, *hidden_parent;
	struct dtime dt;
	aufs_bindex_t bwh, bindex, bstart;

	LKTRTrace("i%lu, %.*s\n", dir->i_ino, DLNPair(dentry));
	IMustLock(dir);
	inode = dentry->d_inode;
	if (unlikely(!inode))
		return -ENOENT; // possible?
	IMustLock(inode);

	aufs_read_lock(dentry, AUFS_D_WLOCK);
	parent = dentry->d_parent;
	di_write_lock_parent(parent);

	bstart = dbstart(dentry);
	bwh = dbwh(dentry);
	bindex = -1;
	wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt);
	//wh_dentry = ERR_PTR(-1);
	err = PTR_ERR(wh_dentry);
	if (IS_ERR(wh_dentry))
		goto out;

	dlgt = need_dlgt(dir->i_sb);
	hidden_dentry = au_h_dptr(dentry);
	dget(hidden_dentry);
	hidden_parent = hidden_dentry->d_parent;
	hidden_dir = hidden_parent->d_inode;

	if (bindex == bstart) {
		err = vfsub_unlink(hidden_dir, hidden_dentry, dlgt);
		//err = -1;
	} else {
		DEBUG_ON(!wh_dentry);
		hidden_parent = wh_dentry->d_parent;
		DEBUG_ON(hidden_parent != au_h_dptr_i(parent, bindex));
		hidden_dir = hidden_parent->d_inode;
		IMustLock(hidden_dir);
		err = 0;
	}

	if (!err) {
		inode->i_nlink--;
		epilog(dir, dentry, bindex);
		goto out_unlock; /* success */
	}

	/* revert */
	if (wh_dentry) {
		int rerr;
		rerr = do_revert(err, wh_dentry, dentry, bwh, &dt, dlgt);
		if (rerr)
			err = rerr;
	}

 out_unlock:
	hdir_unlock(hidden_dir, dir, bindex);
	dput(wh_dentry);
	dput(hidden_dentry);
 out:
	di_write_unlock(parent);
	aufs_read_unlock(dentry, AUFS_D_WLOCK);
	TraceErr(err);
	return err;
}
예제 #17
0
/*
 * copyup the deleted file for writing.
 */
static int cpup_wh_file(struct file *file, aufs_bindex_t bdst, loff_t len)
{
	int err;
	struct dentry *dentry, *parent, *hidden_parent, *tmp_dentry;
	struct dentry *hidden_dentry_bstart, *hidden_dentry_bdst;
	struct inode *hidden_dir;
	aufs_bindex_t bstart;
	struct aufs_dinfo *dinfo;
	struct dtime dt;
	struct lkup_args lkup;
	struct super_block *sb;

	dentry = file->f_dentry;
	LKTRTrace("%.*s, bdst %d, len %Lu\n", DLNPair(dentry), bdst, len);
	DEBUG_ON(S_ISDIR(dentry->d_inode->i_mode)
		 || !(file->f_mode & FMODE_WRITE));
	DiMustWriteLock(dentry);
	parent = dentry->d_parent;
	IiMustAnyLock(parent->d_inode);
	hidden_parent = au_h_dptr_i(parent, bdst);
	DEBUG_ON(!hidden_parent);
	hidden_dir = hidden_parent->d_inode;
	DEBUG_ON(!hidden_dir);
	IMustLock(hidden_dir);

	sb = parent->d_sb;
	lkup.nfsmnt = au_nfsmnt(sb, bdst);
	lkup.dlgt = need_dlgt(sb);
	tmp_dentry = lkup_whtmp(hidden_parent, &dentry->d_name, &lkup);
	//if (LktrCond) {dput(tmp_dentry); tmp_dentry = ERR_PTR(-1);}
	err = PTR_ERR(tmp_dentry);
	if (IS_ERR(tmp_dentry))
		goto out;

	dtime_store(&dt, parent, hidden_parent);
	dinfo = dtodi(dentry);
	bstart = dinfo->di_bstart;
	hidden_dentry_bdst = dinfo->di_hdentry[0 + bdst].hd_dentry;
	hidden_dentry_bstart = dinfo->di_hdentry[0 + bstart].hd_dentry;
	dinfo->di_bstart = bdst;
	dinfo->di_hdentry[0 + bdst].hd_dentry = tmp_dentry;
	dinfo->di_hdentry[0 + bstart].hd_dentry = au_h_fptr(file)->f_dentry;
	err = cpup_single(dentry, bdst, bstart, len,
			  au_flags_cpup(!CPUP_DTIME, parent));
	//if (LktrCond) err = -1;
	if (!err)
		err = au_reopen_nondir(file);
		//err = -1;
	if (unlikely(err)) {
		dinfo->di_hdentry[0 + bstart].hd_dentry = hidden_dentry_bstart;
		dinfo->di_hdentry[0 + bdst].hd_dentry = hidden_dentry_bdst;
		dinfo->di_bstart = bstart;
		goto out_tmp;
	}

	DEBUG_ON(!d_unhashed(dentry));
	err = vfsub_unlink(hidden_dir, tmp_dentry, lkup.dlgt);
	//if (LktrCond) err = -1;
	if (unlikely(err)) {
		IOErr("failed remove copied-up tmp file %.*s(%d)\n",
		      DLNPair(tmp_dentry), err);
		err = -EIO;
	}
	dtime_revert(&dt, !CPUP_LOCKED_GHDIR);

 out_tmp:
	dput(tmp_dentry);
 out:
	TraceErr(err);
	return err;
}
예제 #18
0
/*
 * prepare the @file for writing.
 */
int au_ready_to_write(struct file *file, loff_t len)
{
	int err;
	struct dentry *dentry, *parent, *hidden_dentry, *hidden_parent;
	struct inode *hidden_inode, *hidden_dir, *inode, *dir;
	struct super_block *sb;
	aufs_bindex_t bstart, bcpup;

	dentry = file->f_dentry;
	LKTRTrace("%.*s, len %Ld\n", DLNPair(dentry), len);
	FiMustWriteLock(file);

	sb = dentry->d_sb;
	bstart = fbstart(file);
	DEBUG_ON(ftobr(file, bstart) != stobr(sb, bstart));

	inode = dentry->d_inode;
	ii_read_lock_child(inode);
	LKTRTrace("rdonly %d, bstart %d\n", test_ro(sb, bstart, inode), bstart);
	err = test_ro(sb, bstart, inode);
	ii_read_unlock(inode);
	if (!err && (au_h_fptr(file)->f_mode & FMODE_WRITE))
		return 0;

	/* need to cpup */
	parent = dentry->d_parent; // dget_parent()
	di_write_lock_child(dentry);
	di_write_lock_parent(parent);
	bcpup = err = find_rw_parent_br(dentry, bstart);
	//bcpup = err = find_rw_br(sb, bstart);
	if (unlikely(err < 0))
		goto out_unlock;
	err = 0;

	hidden_parent = au_h_dptr_i(parent, bcpup);
	if (!hidden_parent) {
		err = cpup_dirs(dentry, bcpup, NULL);
		//if (LktrCond) err = -1;
		if (unlikely(err))
			goto out_unlock;
		hidden_parent = au_h_dptr_i(parent, bcpup);
	}

	hidden_dir = hidden_parent->d_inode;
	hidden_dentry = au_h_fptr(file)->f_dentry;
	hidden_inode = hidden_dentry->d_inode;
	dir = parent->d_inode;
	hdir_lock(hidden_dir, dir, bcpup);
	hi_lock_child(hidden_inode);
	if (d_unhashed(dentry) || d_unhashed(hidden_dentry)
	    /* || !hidden_inode->i_nlink */) {
		if (!au_test_perm(hidden_dir, MAY_EXEC | MAY_WRITE,
				  need_dlgt(sb)))
			err = cpup_wh_file(file, bcpup, len);
		else {
			struct cpup_wh_file_args args = {
				.errp	= &err,
				.file	= file,
				.bdst	= bcpup,
				.len	= len
			};
			au_wkq_wait(call_cpup_wh_file, &args, /*dlgt*/0);
		}
		//if (LktrCond) err = -1;
		TraceErr(err);
	} else {
		if (!au_h_dptr_i(dentry, bcpup))